/*! For license information please see Main.js.LICENSE.txt */
import * as __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__ from "@minecraft/server-editor";

import * as __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__ from "@minecraft/server";

import * as __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_private_bindings_ae1d7ddf__ from "@minecraft/server-editor-private-bindings";

import * as __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_bindings_e2bf1028__ from "@minecraft/server-editor-bindings";

var __webpack_modules__ = {
    401: (__unused_webpack_module, exports) => {
        Object.defineProperty(exports, "__esModule", {
            value: true
        });
        exports.clampNumber = void 0;
        function clampNumber(val, min, max) {
            return Math.min(Math.max(val, min), max);
        }
        exports.clampNumber = clampNumber;
    },
    107: function(__unused_webpack_module, exports, __webpack_require__) {
        var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
            if (k2 === undefined) k2 = k;
            var desc = Object.getOwnPropertyDescriptor(m, k);
            if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
                desc = {
                    enumerable: true,
                    get: function() {
                        return m[k];
                    }
                };
            }
            Object.defineProperty(o, k2, desc);
        } : function(o, m, k, k2) {
            if (k2 === undefined) k2 = k;
            o[k2] = m[k];
        });
        var __exportStar = this && this.__exportStar || function(m, exports) {
            for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
        };
        Object.defineProperty(exports, "__esModule", {
            value: true
        });
        __exportStar(__webpack_require__(401), exports);
    },
    607: function(__unused_webpack_module, exports, __webpack_require__) {
        var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
            if (k2 === undefined) k2 = k;
            var desc = Object.getOwnPropertyDescriptor(m, k);
            if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
                desc = {
                    enumerable: true,
                    get: function() {
                        return m[k];
                    }
                };
            }
            Object.defineProperty(o, k2, desc);
        } : function(o, m, k, k2) {
            if (k2 === undefined) k2 = k;
            o[k2] = m[k];
        });
        var __exportStar = this && this.__exportStar || function(m, exports) {
            for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
        };
        Object.defineProperty(exports, "__esModule", {
            value: true
        });
        __exportStar(__webpack_require__(360), exports);
        __exportStar(__webpack_require__(107), exports);
    },
    419: (__unused_webpack_module, exports, __webpack_require__) => {
        Object.defineProperty(exports, "__esModule", {
            value: true
        });
        exports.VECTOR3_SOUTH = exports.VECTOR3_NORTH = exports.VECTOR3_EAST = exports.VECTOR3_WEST = exports.VECTOR3_ZERO = exports.VECTOR3_ONE = exports.VECTOR3_BACK = exports.VECTOR3_FORWARD = exports.VECTOR3_RIGHT = exports.VECTOR3_LEFT = exports.VECTOR3_DOWN = exports.VECTOR3_UP = exports.Vector2Utils = exports.Vector3Utils = void 0;
        const clamp_1 = __webpack_require__(401);
        class Vector3Utils {
            static equals(v1, v2) {
                return v1.x === v2.x && v1.y === v2.y && v1.z === v2.z;
            }
            static add(v1, v2) {
                return {
                    x: v1.x + v2.x,
                    y: v1.y + v2.y,
                    z: v1.z + v2.z
                };
            }
            static subtract(v1, v2) {
                return {
                    x: v1.x - v2.x,
                    y: v1.y - v2.y,
                    z: v1.z - v2.z
                };
            }
            static scale(v1, scale) {
                return {
                    x: v1.x * scale,
                    y: v1.y * scale,
                    z: v1.z * scale
                };
            }
            static dot(a, b) {
                return a.x * b.x + a.y * b.y + a.z * b.z;
            }
            static cross(a, b) {
                return {
                    x: a.y * b.z - a.z * b.y,
                    y: a.z * b.x - a.x * b.z,
                    z: a.x * b.y - a.y * b.x
                };
            }
            static magnitude(v) {
                return Math.sqrt(v.x ** 2 + v.y ** 2 + v.z ** 2);
            }
            static normalize(v) {
                const mag = Vector3Utils.magnitude(v);
                return {
                    x: v.x / mag,
                    y: v.y / mag,
                    z: v.z / mag
                };
            }
            static floor(v) {
                return {
                    x: Math.floor(v.x),
                    y: Math.floor(v.y),
                    z: Math.floor(v.z)
                };
            }
            static toString(v, options) {
                const decimals = options?.decimals ?? 2;
                const str = [ v.x.toFixed(decimals), v.y.toFixed(decimals), v.z.toFixed(decimals) ];
                return str.join(options?.delimiter ?? ", ");
            }
            static clamp(v, limits) {
                return {
                    x: (0, clamp_1.clampNumber)(v.x, limits?.min?.x ?? Number.MIN_SAFE_INTEGER, limits?.max?.x ?? Number.MAX_SAFE_INTEGER),
                    y: (0, clamp_1.clampNumber)(v.y, limits?.min?.y ?? Number.MIN_SAFE_INTEGER, limits?.max?.y ?? Number.MAX_SAFE_INTEGER),
                    z: (0, clamp_1.clampNumber)(v.z, limits?.min?.z ?? Number.MIN_SAFE_INTEGER, limits?.max?.z ?? Number.MAX_SAFE_INTEGER)
                };
            }
        }
        exports.Vector3Utils = Vector3Utils;
        class Vector2Utils {
            static toString(v, options) {
                const decimals = options?.decimals ?? 2;
                const str = [ v.x.toFixed(decimals), v.y.toFixed(decimals) ];
                return str.join(options?.delimiter ?? ", ");
            }
        }
        exports.Vector2Utils = Vector2Utils;
        exports.VECTOR3_UP = {
            x: 0,
            y: 1,
            z: 0
        };
        exports.VECTOR3_DOWN = {
            x: 0,
            y: -1,
            z: 0
        };
        exports.VECTOR3_LEFT = {
            x: -1,
            y: 0,
            z: 0
        };
        exports.VECTOR3_RIGHT = {
            x: 1,
            y: 0,
            z: 0
        };
        exports.VECTOR3_FORWARD = {
            x: 0,
            y: 0,
            z: 1
        };
        exports.VECTOR3_BACK = {
            x: 0,
            y: 0,
            z: -1
        };
        exports.VECTOR3_ONE = {
            x: 1,
            y: 1,
            z: 1
        };
        exports.VECTOR3_ZERO = {
            x: 0,
            y: 0,
            z: 0
        };
        exports.VECTOR3_WEST = {
            x: -1,
            y: 0,
            z: 0
        };
        exports.VECTOR3_EAST = {
            x: 1,
            y: 0,
            z: 0
        };
        exports.VECTOR3_NORTH = {
            x: 0,
            y: 0,
            z: 1
        };
        exports.VECTOR3_SOUTH = {
            x: 0,
            y: 0,
            z: -1
        };
    },
    360: function(__unused_webpack_module, exports, __webpack_require__) {
        var __createBinding = this && this.__createBinding || (Object.create ? function(o, m, k, k2) {
            if (k2 === undefined) k2 = k;
            var desc = Object.getOwnPropertyDescriptor(m, k);
            if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
                desc = {
                    enumerable: true,
                    get: function() {
                        return m[k];
                    }
                };
            }
            Object.defineProperty(o, k2, desc);
        } : function(o, m, k, k2) {
            if (k2 === undefined) k2 = k;
            o[k2] = m[k];
        });
        var __exportStar = this && this.__exportStar || function(m, exports) {
            for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
        };
        Object.defineProperty(exports, "__esModule", {
            value: true
        });
        __exportStar(__webpack_require__(419), exports);
        __exportStar(__webpack_require__(53), exports);
    },
    53: (__unused_webpack_module, exports, __webpack_require__) => {
        Object.defineProperty(exports, "__esModule", {
            value: true
        });
        exports.Vector2Builder = exports.Vector3Builder = void 0;
        const coreHelpers_1 = __webpack_require__(419);
        class Vector3Builder {
            constructor(first, y, z) {
                if (typeof first === "object") {
                    this.x = first.x;
                    this.y = first.y;
                    this.z = first.z;
                } else {
                    this.x = first;
                    this.y = y ?? 0;
                    this.z = z ?? 0;
                }
            }
            assign(vec) {
                this.x = vec.x;
                this.y = vec.y;
                this.z = vec.z;
                return this;
            }
            equals(v) {
                return coreHelpers_1.Vector3Utils.equals(this, v);
            }
            add(v) {
                return this.assign(coreHelpers_1.Vector3Utils.add(this, v));
            }
            subtract(v) {
                return this.assign(coreHelpers_1.Vector3Utils.subtract(this, v));
            }
            scale(val) {
                return this.assign(coreHelpers_1.Vector3Utils.scale(this, val));
            }
            dot(vec) {
                return coreHelpers_1.Vector3Utils.dot(this, vec);
            }
            cross(vec) {
                return this.assign(coreHelpers_1.Vector3Utils.cross(this, vec));
            }
            magnitude() {
                return coreHelpers_1.Vector3Utils.magnitude(this);
            }
            normalize() {
                return this.assign(coreHelpers_1.Vector3Utils.normalize(this));
            }
            floor() {
                return this.assign(coreHelpers_1.Vector3Utils.floor(this));
            }
            toString(options) {
                return coreHelpers_1.Vector3Utils.toString(this, options);
            }
            clamp(limits) {
                return this.assign(coreHelpers_1.Vector3Utils.clamp(this, limits));
            }
        }
        exports.Vector3Builder = Vector3Builder;
        class Vector2Builder {
            constructor(first, y) {
                if (typeof first === "object") {
                    this.x = first.x;
                    this.y = first.y;
                } else {
                    this.x = first;
                    this.y = y ?? 0;
                }
            }
            toString(options) {
                return coreHelpers_1.Vector2Utils.toString(this, options);
            }
        }
        exports.Vector2Builder = Vector2Builder;
    },
    796: (__unused_webpack_module, exports) => {
        exports.byteLength = byteLength;
        exports.toByteArray = toByteArray;
        exports.fromByteArray = fromByteArray;
        var lookup = [];
        var revLookup = [];
        var Arr = typeof Uint8Array !== "undefined" ? Uint8Array : Array;
        var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        for (var i = 0, len = code.length; i < len; ++i) {
            lookup[i] = code[i];
            revLookup[code.charCodeAt(i)] = i;
        }
        revLookup["-".charCodeAt(0)] = 62;
        revLookup["_".charCodeAt(0)] = 63;
        function getLens(b64) {
            var len = b64.length;
            if (len % 4 > 0) {
                throw new Error("Invalid string. Length must be a multiple of 4");
            }
            var validLen = b64.indexOf("=");
            if (validLen === -1) validLen = len;
            var placeHoldersLen = validLen === len ? 0 : 4 - validLen % 4;
            return [ validLen, placeHoldersLen ];
        }
        function byteLength(b64) {
            var lens = getLens(b64);
            var validLen = lens[0];
            var placeHoldersLen = lens[1];
            return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
        }
        function _byteLength(b64, validLen, placeHoldersLen) {
            return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
        }
        function toByteArray(b64) {
            var tmp;
            var lens = getLens(b64);
            var validLen = lens[0];
            var placeHoldersLen = lens[1];
            var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));
            var curByte = 0;
            var len = placeHoldersLen > 0 ? validLen - 4 : validLen;
            var i;
            for (i = 0; i < len; i += 4) {
                tmp = revLookup[b64.charCodeAt(i)] << 18 | revLookup[b64.charCodeAt(i + 1)] << 12 | revLookup[b64.charCodeAt(i + 2)] << 6 | revLookup[b64.charCodeAt(i + 3)];
                arr[curByte++] = tmp >> 16 & 255;
                arr[curByte++] = tmp >> 8 & 255;
                arr[curByte++] = tmp & 255;
            }
            if (placeHoldersLen === 2) {
                tmp = revLookup[b64.charCodeAt(i)] << 2 | revLookup[b64.charCodeAt(i + 1)] >> 4;
                arr[curByte++] = tmp & 255;
            }
            if (placeHoldersLen === 1) {
                tmp = revLookup[b64.charCodeAt(i)] << 10 | revLookup[b64.charCodeAt(i + 1)] << 4 | revLookup[b64.charCodeAt(i + 2)] >> 2;
                arr[curByte++] = tmp >> 8 & 255;
                arr[curByte++] = tmp & 255;
            }
            return arr;
        }
        function tripletToBase64(num) {
            return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];
        }
        function encodeChunk(uint8, start, end) {
            var tmp;
            var output = [];
            for (var i = start; i < end; i += 3) {
                tmp = (uint8[i] << 16 & 16711680) + (uint8[i + 1] << 8 & 65280) + (uint8[i + 2] & 255);
                output.push(tripletToBase64(tmp));
            }
            return output.join("");
        }
        function fromByteArray(uint8) {
            var tmp;
            var len = uint8.length;
            var extraBytes = len % 3;
            var parts = [];
            var maxChunkLength = 16383;
            for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
                parts.push(encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength));
            }
            if (extraBytes === 1) {
                tmp = uint8[len - 1];
                parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 63] + "==");
            } else if (extraBytes === 2) {
                tmp = (uint8[len - 2] << 8) + uint8[len - 1];
                parts.push(lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + "=");
            }
            return parts.join("");
        }
    },
    945: (__unused_webpack_module, exports, __webpack_require__) => {
        var __webpack_unused_export__;
        var base64 = __webpack_require__(796);
        var ieee754 = __webpack_require__(710);
        var customInspectSymbol = typeof Symbol === "function" && typeof Symbol["for"] === "function" ? Symbol["for"]("nodejs.util.inspect.custom") : null;
        exports.lW = Buffer;
        __webpack_unused_export__ = SlowBuffer;
        exports.h2 = 50;
        var K_MAX_LENGTH = 2147483647;
        __webpack_unused_export__ = K_MAX_LENGTH;
        Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport();
        if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== "undefined" && typeof console.error === "function") {
            console.error("This browser lacks typed array (Uint8Array) support which is required by " + "`buffer` v5.x. Use `buffer` v4.x if you require old browser support.");
        }
        function typedArraySupport() {
            try {
                var arr = new Uint8Array(1);
                var proto = {
                    foo: function() {
                        return 42;
                    }
                };
                Object.setPrototypeOf(proto, Uint8Array.prototype);
                Object.setPrototypeOf(arr, proto);
                return arr.foo() === 42;
            } catch (e) {
                return false;
            }
        }
        Object.defineProperty(Buffer.prototype, "parent", {
            enumerable: true,
            get: function() {
                if (!Buffer.isBuffer(this)) return undefined;
                return this.buffer;
            }
        });
        Object.defineProperty(Buffer.prototype, "offset", {
            enumerable: true,
            get: function() {
                if (!Buffer.isBuffer(this)) return undefined;
                return this.byteOffset;
            }
        });
        function createBuffer(length) {
            if (length > K_MAX_LENGTH) {
                throw new RangeError('The value "' + length + '" is invalid for option "size"');
            }
            var buf = new Uint8Array(length);
            Object.setPrototypeOf(buf, Buffer.prototype);
            return buf;
        }
        function Buffer(arg, encodingOrOffset, length) {
            if (typeof arg === "number") {
                if (typeof encodingOrOffset === "string") {
                    throw new TypeError('The "string" argument must be of type string. Received type number');
                }
                return allocUnsafe(arg);
            }
            return from(arg, encodingOrOffset, length);
        }
        Buffer.poolSize = 8192;
        function from(value, encodingOrOffset, length) {
            if (typeof value === "string") {
                return fromString(value, encodingOrOffset);
            }
            if (ArrayBuffer.isView(value)) {
                return fromArrayView(value);
            }
            if (value == null) {
                throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, " + "or Array-like Object. Received type " + typeof value);
            }
            if (isInstance(value, ArrayBuffer) || value && isInstance(value.buffer, ArrayBuffer)) {
                return fromArrayBuffer(value, encodingOrOffset, length);
            }
            if (typeof SharedArrayBuffer !== "undefined" && (isInstance(value, SharedArrayBuffer) || value && isInstance(value.buffer, SharedArrayBuffer))) {
                return fromArrayBuffer(value, encodingOrOffset, length);
            }
            if (typeof value === "number") {
                throw new TypeError('The "value" argument must not be of type number. Received type number');
            }
            var valueOf = value.valueOf && value.valueOf();
            if (valueOf != null && valueOf !== value) {
                return Buffer.from(valueOf, encodingOrOffset, length);
            }
            var b = fromObject(value);
            if (b) return b;
            if (typeof Symbol !== "undefined" && Symbol.toPrimitive != null && typeof value[Symbol.toPrimitive] === "function") {
                return Buffer.from(value[Symbol.toPrimitive]("string"), encodingOrOffset, length);
            }
            throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, " + "or Array-like Object. Received type " + typeof value);
        }
        Buffer.from = function(value, encodingOrOffset, length) {
            return from(value, encodingOrOffset, length);
        };
        Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype);
        Object.setPrototypeOf(Buffer, Uint8Array);
        function assertSize(size) {
            if (typeof size !== "number") {
                throw new TypeError('"size" argument must be of type number');
            } else if (size < 0) {
                throw new RangeError('The value "' + size + '" is invalid for option "size"');
            }
        }
        function alloc(size, fill, encoding) {
            assertSize(size);
            if (size <= 0) {
                return createBuffer(size);
            }
            if (fill !== undefined) {
                return typeof encoding === "string" ? createBuffer(size).fill(fill, encoding) : createBuffer(size).fill(fill);
            }
            return createBuffer(size);
        }
        Buffer.alloc = function(size, fill, encoding) {
            return alloc(size, fill, encoding);
        };
        function allocUnsafe(size) {
            assertSize(size);
            return createBuffer(size < 0 ? 0 : checked(size) | 0);
        }
        Buffer.allocUnsafe = function(size) {
            return allocUnsafe(size);
        };
        Buffer.allocUnsafeSlow = function(size) {
            return allocUnsafe(size);
        };
        function fromString(string, encoding) {
            if (typeof encoding !== "string" || encoding === "") {
                encoding = "utf8";
            }
            if (!Buffer.isEncoding(encoding)) {
                throw new TypeError("Unknown encoding: " + encoding);
            }
            var length = byteLength(string, encoding) | 0;
            var buf = createBuffer(length);
            var actual = buf.write(string, encoding);
            if (actual !== length) {
                buf = buf.slice(0, actual);
            }
            return buf;
        }
        function fromArrayLike(array) {
            var length = array.length < 0 ? 0 : checked(array.length) | 0;
            var buf = createBuffer(length);
            for (var i = 0; i < length; i += 1) {
                buf[i] = array[i] & 255;
            }
            return buf;
        }
        function fromArrayView(arrayView) {
            if (isInstance(arrayView, Uint8Array)) {
                var copy = new Uint8Array(arrayView);
                return fromArrayBuffer(copy.buffer, copy.byteOffset, copy.byteLength);
            }
            return fromArrayLike(arrayView);
        }
        function fromArrayBuffer(array, byteOffset, length) {
            if (byteOffset < 0 || array.byteLength < byteOffset) {
                throw new RangeError('"offset" is outside of buffer bounds');
            }
            if (array.byteLength < byteOffset + (length || 0)) {
                throw new RangeError('"length" is outside of buffer bounds');
            }
            var buf;
            if (byteOffset === undefined && length === undefined) {
                buf = new Uint8Array(array);
            } else if (length === undefined) {
                buf = new Uint8Array(array, byteOffset);
            } else {
                buf = new Uint8Array(array, byteOffset, length);
            }
            Object.setPrototypeOf(buf, Buffer.prototype);
            return buf;
        }
        function fromObject(obj) {
            if (Buffer.isBuffer(obj)) {
                var len = checked(obj.length) | 0;
                var buf = createBuffer(len);
                if (buf.length === 0) {
                    return buf;
                }
                obj.copy(buf, 0, 0, len);
                return buf;
            }
            if (obj.length !== undefined) {
                if (typeof obj.length !== "number" || numberIsNaN(obj.length)) {
                    return createBuffer(0);
                }
                return fromArrayLike(obj);
            }
            if (obj.type === "Buffer" && Array.isArray(obj.data)) {
                return fromArrayLike(obj.data);
            }
        }
        function checked(length) {
            if (length >= K_MAX_LENGTH) {
                throw new RangeError("Attempt to allocate Buffer larger than maximum " + "size: 0x" + K_MAX_LENGTH.toString(16) + " bytes");
            }
            return length | 0;
        }
        function SlowBuffer(length) {
            if (+length != length) {
                length = 0;
            }
            return Buffer.alloc(+length);
        }
        Buffer.isBuffer = function isBuffer(b) {
            return b != null && b._isBuffer === true && b !== Buffer.prototype;
        };
        Buffer.compare = function compare(a, b) {
            if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength);
            if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength);
            if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
                throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');
            }
            if (a === b) return 0;
            var x = a.length;
            var y = b.length;
            for (var i = 0, len = Math.min(x, y); i < len; ++i) {
                if (a[i] !== b[i]) {
                    x = a[i];
                    y = b[i];
                    break;
                }
            }
            if (x < y) return -1;
            if (y < x) return 1;
            return 0;
        };
        Buffer.isEncoding = function isEncoding(encoding) {
            switch (String(encoding).toLowerCase()) {
              case "hex":
              case "utf8":
              case "utf-8":
              case "ascii":
              case "latin1":
              case "binary":
              case "base64":
              case "ucs2":
              case "ucs-2":
              case "utf16le":
              case "utf-16le":
                return true;

              default:
                return false;
            }
        };
        Buffer.concat = function concat(list, length) {
            if (!Array.isArray(list)) {
                throw new TypeError('"list" argument must be an Array of Buffers');
            }
            if (list.length === 0) {
                return Buffer.alloc(0);
            }
            var i;
            if (length === undefined) {
                length = 0;
                for (i = 0; i < list.length; ++i) {
                    length += list[i].length;
                }
            }
            var buffer = Buffer.allocUnsafe(length);
            var pos = 0;
            for (i = 0; i < list.length; ++i) {
                var buf = list[i];
                if (isInstance(buf, Uint8Array)) {
                    if (pos + buf.length > buffer.length) {
                        Buffer.from(buf).copy(buffer, pos);
                    } else {
                        Uint8Array.prototype.set.call(buffer, buf, pos);
                    }
                } else if (!Buffer.isBuffer(buf)) {
                    throw new TypeError('"list" argument must be an Array of Buffers');
                } else {
                    buf.copy(buffer, pos);
                }
                pos += buf.length;
            }
            return buffer;
        };
        function byteLength(string, encoding) {
            if (Buffer.isBuffer(string)) {
                return string.length;
            }
            if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
                return string.byteLength;
            }
            if (typeof string !== "string") {
                throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' + "Received type " + typeof string);
            }
            var len = string.length;
            var mustMatch = arguments.length > 2 && arguments[2] === true;
            if (!mustMatch && len === 0) return 0;
            var loweredCase = false;
            for (;;) {
                switch (encoding) {
                  case "ascii":
                  case "latin1":
                  case "binary":
                    return len;

                  case "utf8":
                  case "utf-8":
                    return utf8ToBytes(string).length;

                  case "ucs2":
                  case "ucs-2":
                  case "utf16le":
                  case "utf-16le":
                    return len * 2;

                  case "hex":
                    return len >>> 1;

                  case "base64":
                    return base64ToBytes(string).length;

                  default:
                    if (loweredCase) {
                        return mustMatch ? -1 : utf8ToBytes(string).length;
                    }
                    encoding = ("" + encoding).toLowerCase();
                    loweredCase = true;
                }
            }
        }
        Buffer.byteLength = byteLength;
        function slowToString(encoding, start, end) {
            var loweredCase = false;
            if (start === undefined || start < 0) {
                start = 0;
            }
            if (start > this.length) {
                return "";
            }
            if (end === undefined || end > this.length) {
                end = this.length;
            }
            if (end <= 0) {
                return "";
            }
            end >>>= 0;
            start >>>= 0;
            if (end <= start) {
                return "";
            }
            if (!encoding) encoding = "utf8";
            while (true) {
                switch (encoding) {
                  case "hex":
                    return hexSlice(this, start, end);

                  case "utf8":
                  case "utf-8":
                    return utf8Slice(this, start, end);

                  case "ascii":
                    return asciiSlice(this, start, end);

                  case "latin1":
                  case "binary":
                    return latin1Slice(this, start, end);

                  case "base64":
                    return base64Slice(this, start, end);

                  case "ucs2":
                  case "ucs-2":
                  case "utf16le":
                  case "utf-16le":
                    return utf16leSlice(this, start, end);

                  default:
                    if (loweredCase) throw new TypeError("Unknown encoding: " + encoding);
                    encoding = (encoding + "").toLowerCase();
                    loweredCase = true;
                }
            }
        }
        Buffer.prototype._isBuffer = true;
        function swap(b, n, m) {
            var i = b[n];
            b[n] = b[m];
            b[m] = i;
        }
        Buffer.prototype.swap16 = function swap16() {
            var len = this.length;
            if (len % 2 !== 0) {
                throw new RangeError("Buffer size must be a multiple of 16-bits");
            }
            for (var i = 0; i < len; i += 2) {
                swap(this, i, i + 1);
            }
            return this;
        };
        Buffer.prototype.swap32 = function swap32() {
            var len = this.length;
            if (len % 4 !== 0) {
                throw new RangeError("Buffer size must be a multiple of 32-bits");
            }
            for (var i = 0; i < len; i += 4) {
                swap(this, i, i + 3);
                swap(this, i + 1, i + 2);
            }
            return this;
        };
        Buffer.prototype.swap64 = function swap64() {
            var len = this.length;
            if (len % 8 !== 0) {
                throw new RangeError("Buffer size must be a multiple of 64-bits");
            }
            for (var i = 0; i < len; i += 8) {
                swap(this, i, i + 7);
                swap(this, i + 1, i + 6);
                swap(this, i + 2, i + 5);
                swap(this, i + 3, i + 4);
            }
            return this;
        };
        Buffer.prototype.toString = function toString() {
            var length = this.length;
            if (length === 0) return "";
            if (arguments.length === 0) return utf8Slice(this, 0, length);
            return slowToString.apply(this, arguments);
        };
        Buffer.prototype.toLocaleString = Buffer.prototype.toString;
        Buffer.prototype.equals = function equals(b) {
            if (!Buffer.isBuffer(b)) throw new TypeError("Argument must be a Buffer");
            if (this === b) return true;
            return Buffer.compare(this, b) === 0;
        };
        Buffer.prototype.inspect = function inspect() {
            var str = "";
            var max = exports.h2;
            str = this.toString("hex", 0, max).replace(/(.{2})/g, "$1 ").trim();
            if (this.length > max) str += " ... ";
            return "<Buffer " + str + ">";
        };
        if (customInspectSymbol) {
            Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect;
        }
        Buffer.prototype.compare = function compare(target, start, end, thisStart, thisEnd) {
            if (isInstance(target, Uint8Array)) {
                target = Buffer.from(target, target.offset, target.byteLength);
            }
            if (!Buffer.isBuffer(target)) {
                throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. ' + "Received type " + typeof target);
            }
            if (start === undefined) {
                start = 0;
            }
            if (end === undefined) {
                end = target ? target.length : 0;
            }
            if (thisStart === undefined) {
                thisStart = 0;
            }
            if (thisEnd === undefined) {
                thisEnd = this.length;
            }
            if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
                throw new RangeError("out of range index");
            }
            if (thisStart >= thisEnd && start >= end) {
                return 0;
            }
            if (thisStart >= thisEnd) {
                return -1;
            }
            if (start >= end) {
                return 1;
            }
            start >>>= 0;
            end >>>= 0;
            thisStart >>>= 0;
            thisEnd >>>= 0;
            if (this === target) return 0;
            var x = thisEnd - thisStart;
            var y = end - start;
            var len = Math.min(x, y);
            var thisCopy = this.slice(thisStart, thisEnd);
            var targetCopy = target.slice(start, end);
            for (var i = 0; i < len; ++i) {
                if (thisCopy[i] !== targetCopy[i]) {
                    x = thisCopy[i];
                    y = targetCopy[i];
                    break;
                }
            }
            if (x < y) return -1;
            if (y < x) return 1;
            return 0;
        };
        function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
            if (buffer.length === 0) return -1;
            if (typeof byteOffset === "string") {
                encoding = byteOffset;
                byteOffset = 0;
            } else if (byteOffset > 2147483647) {
                byteOffset = 2147483647;
            } else if (byteOffset < -2147483648) {
                byteOffset = -2147483648;
            }
            byteOffset = +byteOffset;
            if (numberIsNaN(byteOffset)) {
                byteOffset = dir ? 0 : buffer.length - 1;
            }
            if (byteOffset < 0) byteOffset = buffer.length + byteOffset;
            if (byteOffset >= buffer.length) {
                if (dir) return -1; else byteOffset = buffer.length - 1;
            } else if (byteOffset < 0) {
                if (dir) byteOffset = 0; else return -1;
            }
            if (typeof val === "string") {
                val = Buffer.from(val, encoding);
            }
            if (Buffer.isBuffer(val)) {
                if (val.length === 0) {
                    return -1;
                }
                return arrayIndexOf(buffer, val, byteOffset, encoding, dir);
            } else if (typeof val === "number") {
                val = val & 255;
                if (typeof Uint8Array.prototype.indexOf === "function") {
                    if (dir) {
                        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset);
                    } else {
                        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset);
                    }
                }
                return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir);
            }
            throw new TypeError("val must be string, number or Buffer");
        }
        function arrayIndexOf(arr, val, byteOffset, encoding, dir) {
            var indexSize = 1;
            var arrLength = arr.length;
            var valLength = val.length;
            if (encoding !== undefined) {
                encoding = String(encoding).toLowerCase();
                if (encoding === "ucs2" || encoding === "ucs-2" || encoding === "utf16le" || encoding === "utf-16le") {
                    if (arr.length < 2 || val.length < 2) {
                        return -1;
                    }
                    indexSize = 2;
                    arrLength /= 2;
                    valLength /= 2;
                    byteOffset /= 2;
                }
            }
            function read(buf, i) {
                if (indexSize === 1) {
                    return buf[i];
                } else {
                    return buf.readUInt16BE(i * indexSize);
                }
            }
            var i;
            if (dir) {
                var foundIndex = -1;
                for (i = byteOffset; i < arrLength; i++) {
                    if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
                        if (foundIndex === -1) foundIndex = i;
                        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize;
                    } else {
                        if (foundIndex !== -1) i -= i - foundIndex;
                        foundIndex = -1;
                    }
                }
            } else {
                if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength;
                for (i = byteOffset; i >= 0; i--) {
                    var found = true;
                    for (var j = 0; j < valLength; j++) {
                        if (read(arr, i + j) !== read(val, j)) {
                            found = false;
                            break;
                        }
                    }
                    if (found) return i;
                }
            }
            return -1;
        }
        Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
            return this.indexOf(val, byteOffset, encoding) !== -1;
        };
        Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) {
            return bidirectionalIndexOf(this, val, byteOffset, encoding, true);
        };
        Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) {
            return bidirectionalIndexOf(this, val, byteOffset, encoding, false);
        };
        function hexWrite(buf, string, offset, length) {
            offset = Number(offset) || 0;
            var remaining = buf.length - offset;
            if (!length) {
                length = remaining;
            } else {
                length = Number(length);
                if (length > remaining) {
                    length = remaining;
                }
            }
            var strLen = string.length;
            if (length > strLen / 2) {
                length = strLen / 2;
            }
            for (var i = 0; i < length; ++i) {
                var parsed = parseInt(string.substr(i * 2, 2), 16);
                if (numberIsNaN(parsed)) return i;
                buf[offset + i] = parsed;
            }
            return i;
        }
        function utf8Write(buf, string, offset, length) {
            return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length);
        }
        function asciiWrite(buf, string, offset, length) {
            return blitBuffer(asciiToBytes(string), buf, offset, length);
        }
        function base64Write(buf, string, offset, length) {
            return blitBuffer(base64ToBytes(string), buf, offset, length);
        }
        function ucs2Write(buf, string, offset, length) {
            return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length);
        }
        Buffer.prototype.write = function write(string, offset, length, encoding) {
            if (offset === undefined) {
                encoding = "utf8";
                length = this.length;
                offset = 0;
            } else if (length === undefined && typeof offset === "string") {
                encoding = offset;
                length = this.length;
                offset = 0;
            } else if (isFinite(offset)) {
                offset = offset >>> 0;
                if (isFinite(length)) {
                    length = length >>> 0;
                    if (encoding === undefined) encoding = "utf8";
                } else {
                    encoding = length;
                    length = undefined;
                }
            } else {
                throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");
            }
            var remaining = this.length - offset;
            if (length === undefined || length > remaining) length = remaining;
            if (string.length > 0 && (length < 0 || offset < 0) || offset > this.length) {
                throw new RangeError("Attempt to write outside buffer bounds");
            }
            if (!encoding) encoding = "utf8";
            var loweredCase = false;
            for (;;) {
                switch (encoding) {
                  case "hex":
                    return hexWrite(this, string, offset, length);

                  case "utf8":
                  case "utf-8":
                    return utf8Write(this, string, offset, length);

                  case "ascii":
                  case "latin1":
                  case "binary":
                    return asciiWrite(this, string, offset, length);

                  case "base64":
                    return base64Write(this, string, offset, length);

                  case "ucs2":
                  case "ucs-2":
                  case "utf16le":
                  case "utf-16le":
                    return ucs2Write(this, string, offset, length);

                  default:
                    if (loweredCase) throw new TypeError("Unknown encoding: " + encoding);
                    encoding = ("" + encoding).toLowerCase();
                    loweredCase = true;
                }
            }
        };
        Buffer.prototype.toJSON = function toJSON() {
            return {
                type: "Buffer",
                data: Array.prototype.slice.call(this._arr || this, 0)
            };
        };
        function base64Slice(buf, start, end) {
            if (start === 0 && end === buf.length) {
                return base64.fromByteArray(buf);
            } else {
                return base64.fromByteArray(buf.slice(start, end));
            }
        }
        function utf8Slice(buf, start, end) {
            end = Math.min(buf.length, end);
            var res = [];
            var i = start;
            while (i < end) {
                var firstByte = buf[i];
                var codePoint = null;
                var bytesPerSequence = firstByte > 239 ? 4 : firstByte > 223 ? 3 : firstByte > 191 ? 2 : 1;
                if (i + bytesPerSequence <= end) {
                    var secondByte, thirdByte, fourthByte, tempCodePoint;
                    switch (bytesPerSequence) {
                      case 1:
                        if (firstByte < 128) {
                            codePoint = firstByte;
                        }
                        break;

                      case 2:
                        secondByte = buf[i + 1];
                        if ((secondByte & 192) === 128) {
                            tempCodePoint = (firstByte & 31) << 6 | secondByte & 63;
                            if (tempCodePoint > 127) {
                                codePoint = tempCodePoint;
                            }
                        }
                        break;

                      case 3:
                        secondByte = buf[i + 1];
                        thirdByte = buf[i + 2];
                        if ((secondByte & 192) === 128 && (thirdByte & 192) === 128) {
                            tempCodePoint = (firstByte & 15) << 12 | (secondByte & 63) << 6 | thirdByte & 63;
                            if (tempCodePoint > 2047 && (tempCodePoint < 55296 || tempCodePoint > 57343)) {
                                codePoint = tempCodePoint;
                            }
                        }
                        break;

                      case 4:
                        secondByte = buf[i + 1];
                        thirdByte = buf[i + 2];
                        fourthByte = buf[i + 3];
                        if ((secondByte & 192) === 128 && (thirdByte & 192) === 128 && (fourthByte & 192) === 128) {
                            tempCodePoint = (firstByte & 15) << 18 | (secondByte & 63) << 12 | (thirdByte & 63) << 6 | fourthByte & 63;
                            if (tempCodePoint > 65535 && tempCodePoint < 1114112) {
                                codePoint = tempCodePoint;
                            }
                        }
                    }
                }
                if (codePoint === null) {
                    codePoint = 65533;
                    bytesPerSequence = 1;
                } else if (codePoint > 65535) {
                    codePoint -= 65536;
                    res.push(codePoint >>> 10 & 1023 | 55296);
                    codePoint = 56320 | codePoint & 1023;
                }
                res.push(codePoint);
                i += bytesPerSequence;
            }
            return decodeCodePointsArray(res);
        }
        var MAX_ARGUMENTS_LENGTH = 4096;
        function decodeCodePointsArray(codePoints) {
            var len = codePoints.length;
            if (len <= MAX_ARGUMENTS_LENGTH) {
                return String.fromCharCode.apply(String, codePoints);
            }
            var res = "";
            var i = 0;
            while (i < len) {
                res += String.fromCharCode.apply(String, codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH));
            }
            return res;
        }
        function asciiSlice(buf, start, end) {
            var ret = "";
            end = Math.min(buf.length, end);
            for (var i = start; i < end; ++i) {
                ret += String.fromCharCode(buf[i] & 127);
            }
            return ret;
        }
        function latin1Slice(buf, start, end) {
            var ret = "";
            end = Math.min(buf.length, end);
            for (var i = start; i < end; ++i) {
                ret += String.fromCharCode(buf[i]);
            }
            return ret;
        }
        function hexSlice(buf, start, end) {
            var len = buf.length;
            if (!start || start < 0) start = 0;
            if (!end || end < 0 || end > len) end = len;
            var out = "";
            for (var i = start; i < end; ++i) {
                out += hexSliceLookupTable[buf[i]];
            }
            return out;
        }
        function utf16leSlice(buf, start, end) {
            var bytes = buf.slice(start, end);
            var res = "";
            for (var i = 0; i < bytes.length - 1; i += 2) {
                res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256);
            }
            return res;
        }
        Buffer.prototype.slice = function slice(start, end) {
            var len = this.length;
            start = ~~start;
            end = end === undefined ? len : ~~end;
            if (start < 0) {
                start += len;
                if (start < 0) start = 0;
            } else if (start > len) {
                start = len;
            }
            if (end < 0) {
                end += len;
                if (end < 0) end = 0;
            } else if (end > len) {
                end = len;
            }
            if (end < start) end = start;
            var newBuf = this.subarray(start, end);
            Object.setPrototypeOf(newBuf, Buffer.prototype);
            return newBuf;
        };
        function checkOffset(offset, ext, length) {
            if (offset % 1 !== 0 || offset < 0) throw new RangeError("offset is not uint");
            if (offset + ext > length) throw new RangeError("Trying to access beyond buffer length");
        }
        Buffer.prototype.readUintLE = Buffer.prototype.readUIntLE = function readUIntLE(offset, byteLength, noAssert) {
            offset = offset >>> 0;
            byteLength = byteLength >>> 0;
            if (!noAssert) checkOffset(offset, byteLength, this.length);
            var val = this[offset];
            var mul = 1;
            var i = 0;
            while (++i < byteLength && (mul *= 256)) {
                val += this[offset + i] * mul;
            }
            return val;
        };
        Buffer.prototype.readUintBE = Buffer.prototype.readUIntBE = function readUIntBE(offset, byteLength, noAssert) {
            offset = offset >>> 0;
            byteLength = byteLength >>> 0;
            if (!noAssert) {
                checkOffset(offset, byteLength, this.length);
            }
            var val = this[offset + --byteLength];
            var mul = 1;
            while (byteLength > 0 && (mul *= 256)) {
                val += this[offset + --byteLength] * mul;
            }
            return val;
        };
        Buffer.prototype.readUint8 = Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 1, this.length);
            return this[offset];
        };
        Buffer.prototype.readUint16LE = Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 2, this.length);
            return this[offset] | this[offset + 1] << 8;
        };
        Buffer.prototype.readUint16BE = Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 2, this.length);
            return this[offset] << 8 | this[offset + 1];
        };
        Buffer.prototype.readUint32LE = Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 4, this.length);
            return (this[offset] | this[offset + 1] << 8 | this[offset + 2] << 16) + this[offset + 3] * 16777216;
        };
        Buffer.prototype.readUint32BE = Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 4, this.length);
            return this[offset] * 16777216 + (this[offset + 1] << 16 | this[offset + 2] << 8 | this[offset + 3]);
        };
        Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) {
            offset = offset >>> 0;
            byteLength = byteLength >>> 0;
            if (!noAssert) checkOffset(offset, byteLength, this.length);
            var val = this[offset];
            var mul = 1;
            var i = 0;
            while (++i < byteLength && (mul *= 256)) {
                val += this[offset + i] * mul;
            }
            mul *= 128;
            if (val >= mul) val -= Math.pow(2, 8 * byteLength);
            return val;
        };
        Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) {
            offset = offset >>> 0;
            byteLength = byteLength >>> 0;
            if (!noAssert) checkOffset(offset, byteLength, this.length);
            var i = byteLength;
            var mul = 1;
            var val = this[offset + --i];
            while (i > 0 && (mul *= 256)) {
                val += this[offset + --i] * mul;
            }
            mul *= 128;
            if (val >= mul) val -= Math.pow(2, 8 * byteLength);
            return val;
        };
        Buffer.prototype.readInt8 = function readInt8(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 1, this.length);
            if (!(this[offset] & 128)) return this[offset];
            return (255 - this[offset] + 1) * -1;
        };
        Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 2, this.length);
            var val = this[offset] | this[offset + 1] << 8;
            return val & 32768 ? val | 4294901760 : val;
        };
        Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 2, this.length);
            var val = this[offset + 1] | this[offset] << 8;
            return val & 32768 ? val | 4294901760 : val;
        };
        Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 4, this.length);
            return this[offset] | this[offset + 1] << 8 | this[offset + 2] << 16 | this[offset + 3] << 24;
        };
        Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 4, this.length);
            return this[offset] << 24 | this[offset + 1] << 16 | this[offset + 2] << 8 | this[offset + 3];
        };
        Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 4, this.length);
            return ieee754.read(this, offset, true, 23, 4);
        };
        Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 4, this.length);
            return ieee754.read(this, offset, false, 23, 4);
        };
        Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 8, this.length);
            return ieee754.read(this, offset, true, 52, 8);
        };
        Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
            offset = offset >>> 0;
            if (!noAssert) checkOffset(offset, 8, this.length);
            return ieee754.read(this, offset, false, 52, 8);
        };
        function checkInt(buf, value, offset, ext, max, min) {
            if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance');
            if (value > max || value < min) throw new RangeError('"value" argument is out of bounds');
            if (offset + ext > buf.length) throw new RangeError("Index out of range");
        }
        Buffer.prototype.writeUintLE = Buffer.prototype.writeUIntLE = function writeUIntLE(value, offset, byteLength, noAssert) {
            value = +value;
            offset = offset >>> 0;
            byteLength = byteLength >>> 0;
            if (!noAssert) {
                var maxBytes = Math.pow(2, 8 * byteLength) - 1;
                checkInt(this, value, offset, byteLength, maxBytes, 0);
            }
            var mul = 1;
            var i = 0;
            this[offset] = value & 255;
            while (++i < byteLength && (mul *= 256)) {
                this[offset + i] = value / mul & 255;
            }
            return offset + byteLength;
        };
        Buffer.prototype.writeUintBE = Buffer.prototype.writeUIntBE = function writeUIntBE(value, offset, byteLength, noAssert) {
            value = +value;
            offset = offset >>> 0;
            byteLength = byteLength >>> 0;
            if (!noAssert) {
                var maxBytes = Math.pow(2, 8 * byteLength) - 1;
                checkInt(this, value, offset, byteLength, maxBytes, 0);
            }
            var i = byteLength - 1;
            var mul = 1;
            this[offset + i] = value & 255;
            while (--i >= 0 && (mul *= 256)) {
                this[offset + i] = value / mul & 255;
            }
            return offset + byteLength;
        };
        Buffer.prototype.writeUint8 = Buffer.prototype.writeUInt8 = function writeUInt8(value, offset, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) checkInt(this, value, offset, 1, 255, 0);
            this[offset] = value & 255;
            return offset + 1;
        };
        Buffer.prototype.writeUint16LE = Buffer.prototype.writeUInt16LE = function writeUInt16LE(value, offset, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) checkInt(this, value, offset, 2, 65535, 0);
            this[offset] = value & 255;
            this[offset + 1] = value >>> 8;
            return offset + 2;
        };
        Buffer.prototype.writeUint16BE = Buffer.prototype.writeUInt16BE = function writeUInt16BE(value, offset, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) checkInt(this, value, offset, 2, 65535, 0);
            this[offset] = value >>> 8;
            this[offset + 1] = value & 255;
            return offset + 2;
        };
        Buffer.prototype.writeUint32LE = Buffer.prototype.writeUInt32LE = function writeUInt32LE(value, offset, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) checkInt(this, value, offset, 4, 4294967295, 0);
            this[offset + 3] = value >>> 24;
            this[offset + 2] = value >>> 16;
            this[offset + 1] = value >>> 8;
            this[offset] = value & 255;
            return offset + 4;
        };
        Buffer.prototype.writeUint32BE = Buffer.prototype.writeUInt32BE = function writeUInt32BE(value, offset, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) checkInt(this, value, offset, 4, 4294967295, 0);
            this[offset] = value >>> 24;
            this[offset + 1] = value >>> 16;
            this[offset + 2] = value >>> 8;
            this[offset + 3] = value & 255;
            return offset + 4;
        };
        Buffer.prototype.writeIntLE = function writeIntLE(value, offset, byteLength, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) {
                var limit = Math.pow(2, 8 * byteLength - 1);
                checkInt(this, value, offset, byteLength, limit - 1, -limit);
            }
            var i = 0;
            var mul = 1;
            var sub = 0;
            this[offset] = value & 255;
            while (++i < byteLength && (mul *= 256)) {
                if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
                    sub = 1;
                }
                this[offset + i] = (value / mul >> 0) - sub & 255;
            }
            return offset + byteLength;
        };
        Buffer.prototype.writeIntBE = function writeIntBE(value, offset, byteLength, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) {
                var limit = Math.pow(2, 8 * byteLength - 1);
                checkInt(this, value, offset, byteLength, limit - 1, -limit);
            }
            var i = byteLength - 1;
            var mul = 1;
            var sub = 0;
            this[offset + i] = value & 255;
            while (--i >= 0 && (mul *= 256)) {
                if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
                    sub = 1;
                }
                this[offset + i] = (value / mul >> 0) - sub & 255;
            }
            return offset + byteLength;
        };
        Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) checkInt(this, value, offset, 1, 127, -128);
            if (value < 0) value = 255 + value + 1;
            this[offset] = value & 255;
            return offset + 1;
        };
        Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) checkInt(this, value, offset, 2, 32767, -32768);
            this[offset] = value & 255;
            this[offset + 1] = value >>> 8;
            return offset + 2;
        };
        Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) checkInt(this, value, offset, 2, 32767, -32768);
            this[offset] = value >>> 8;
            this[offset + 1] = value & 255;
            return offset + 2;
        };
        Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) checkInt(this, value, offset, 4, 2147483647, -2147483648);
            this[offset] = value & 255;
            this[offset + 1] = value >>> 8;
            this[offset + 2] = value >>> 16;
            this[offset + 3] = value >>> 24;
            return offset + 4;
        };
        Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) checkInt(this, value, offset, 4, 2147483647, -2147483648);
            if (value < 0) value = 4294967295 + value + 1;
            this[offset] = value >>> 24;
            this[offset + 1] = value >>> 16;
            this[offset + 2] = value >>> 8;
            this[offset + 3] = value & 255;
            return offset + 4;
        };
        function checkIEEE754(buf, value, offset, ext, max, min) {
            if (offset + ext > buf.length) throw new RangeError("Index out of range");
            if (offset < 0) throw new RangeError("Index out of range");
        }
        function writeFloat(buf, value, offset, littleEndian, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) {
                checkIEEE754(buf, value, offset, 4, 34028234663852886e22, -34028234663852886e22);
            }
            ieee754.write(buf, value, offset, littleEndian, 23, 4);
            return offset + 4;
        }
        Buffer.prototype.writeFloatLE = function writeFloatLE(value, offset, noAssert) {
            return writeFloat(this, value, offset, true, noAssert);
        };
        Buffer.prototype.writeFloatBE = function writeFloatBE(value, offset, noAssert) {
            return writeFloat(this, value, offset, false, noAssert);
        };
        function writeDouble(buf, value, offset, littleEndian, noAssert) {
            value = +value;
            offset = offset >>> 0;
            if (!noAssert) {
                checkIEEE754(buf, value, offset, 8, 17976931348623157e292, -17976931348623157e292);
            }
            ieee754.write(buf, value, offset, littleEndian, 52, 8);
            return offset + 8;
        }
        Buffer.prototype.writeDoubleLE = function writeDoubleLE(value, offset, noAssert) {
            return writeDouble(this, value, offset, true, noAssert);
        };
        Buffer.prototype.writeDoubleBE = function writeDoubleBE(value, offset, noAssert) {
            return writeDouble(this, value, offset, false, noAssert);
        };
        Buffer.prototype.copy = function copy(target, targetStart, start, end) {
            if (!Buffer.isBuffer(target)) throw new TypeError("argument should be a Buffer");
            if (!start) start = 0;
            if (!end && end !== 0) end = this.length;
            if (targetStart >= target.length) targetStart = target.length;
            if (!targetStart) targetStart = 0;
            if (end > 0 && end < start) end = start;
            if (end === start) return 0;
            if (target.length === 0 || this.length === 0) return 0;
            if (targetStart < 0) {
                throw new RangeError("targetStart out of bounds");
            }
            if (start < 0 || start >= this.length) throw new RangeError("Index out of range");
            if (end < 0) throw new RangeError("sourceEnd out of bounds");
            if (end > this.length) end = this.length;
            if (target.length - targetStart < end - start) {
                end = target.length - targetStart + start;
            }
            var len = end - start;
            if (this === target && typeof Uint8Array.prototype.copyWithin === "function") {
                this.copyWithin(targetStart, start, end);
            } else {
                Uint8Array.prototype.set.call(target, this.subarray(start, end), targetStart);
            }
            return len;
        };
        Buffer.prototype.fill = function fill(val, start, end, encoding) {
            if (typeof val === "string") {
                if (typeof start === "string") {
                    encoding = start;
                    start = 0;
                    end = this.length;
                } else if (typeof end === "string") {
                    encoding = end;
                    end = this.length;
                }
                if (encoding !== undefined && typeof encoding !== "string") {
                    throw new TypeError("encoding must be a string");
                }
                if (typeof encoding === "string" && !Buffer.isEncoding(encoding)) {
                    throw new TypeError("Unknown encoding: " + encoding);
                }
                if (val.length === 1) {
                    var code = val.charCodeAt(0);
                    if (encoding === "utf8" && code < 128 || encoding === "latin1") {
                        val = code;
                    }
                }
            } else if (typeof val === "number") {
                val = val & 255;
            } else if (typeof val === "boolean") {
                val = Number(val);
            }
            if (start < 0 || this.length < start || this.length < end) {
                throw new RangeError("Out of range index");
            }
            if (end <= start) {
                return this;
            }
            start = start >>> 0;
            end = end === undefined ? this.length : end >>> 0;
            if (!val) val = 0;
            var i;
            if (typeof val === "number") {
                for (i = start; i < end; ++i) {
                    this[i] = val;
                }
            } else {
                var bytes = Buffer.isBuffer(val) ? val : Buffer.from(val, encoding);
                var len = bytes.length;
                if (len === 0) {
                    throw new TypeError('The value "' + val + '" is invalid for argument "value"');
                }
                for (i = 0; i < end - start; ++i) {
                    this[i + start] = bytes[i % len];
                }
            }
            return this;
        };
        var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g;
        function base64clean(str) {
            str = str.split("=")[0];
            str = str.trim().replace(INVALID_BASE64_RE, "");
            if (str.length < 2) return "";
            while (str.length % 4 !== 0) {
                str = str + "=";
            }
            return str;
        }
        function utf8ToBytes(string, units) {
            units = units || Infinity;
            var codePoint;
            var length = string.length;
            var leadSurrogate = null;
            var bytes = [];
            for (var i = 0; i < length; ++i) {
                codePoint = string.charCodeAt(i);
                if (codePoint > 55295 && codePoint < 57344) {
                    if (!leadSurrogate) {
                        if (codePoint > 56319) {
                            if ((units -= 3) > -1) bytes.push(239, 191, 189);
                            continue;
                        } else if (i + 1 === length) {
                            if ((units -= 3) > -1) bytes.push(239, 191, 189);
                            continue;
                        }
                        leadSurrogate = codePoint;
                        continue;
                    }
                    if (codePoint < 56320) {
                        if ((units -= 3) > -1) bytes.push(239, 191, 189);
                        leadSurrogate = codePoint;
                        continue;
                    }
                    codePoint = (leadSurrogate - 55296 << 10 | codePoint - 56320) + 65536;
                } else if (leadSurrogate) {
                    if ((units -= 3) > -1) bytes.push(239, 191, 189);
                }
                leadSurrogate = null;
                if (codePoint < 128) {
                    if ((units -= 1) < 0) break;
                    bytes.push(codePoint);
                } else if (codePoint < 2048) {
                    if ((units -= 2) < 0) break;
                    bytes.push(codePoint >> 6 | 192, codePoint & 63 | 128);
                } else if (codePoint < 65536) {
                    if ((units -= 3) < 0) break;
                    bytes.push(codePoint >> 12 | 224, codePoint >> 6 & 63 | 128, codePoint & 63 | 128);
                } else if (codePoint < 1114112) {
                    if ((units -= 4) < 0) break;
                    bytes.push(codePoint >> 18 | 240, codePoint >> 12 & 63 | 128, codePoint >> 6 & 63 | 128, codePoint & 63 | 128);
                } else {
                    throw new Error("Invalid code point");
                }
            }
            return bytes;
        }
        function asciiToBytes(str) {
            var byteArray = [];
            for (var i = 0; i < str.length; ++i) {
                byteArray.push(str.charCodeAt(i) & 255);
            }
            return byteArray;
        }
        function utf16leToBytes(str, units) {
            var c, hi, lo;
            var byteArray = [];
            for (var i = 0; i < str.length; ++i) {
                if ((units -= 2) < 0) break;
                c = str.charCodeAt(i);
                hi = c >> 8;
                lo = c % 256;
                byteArray.push(lo);
                byteArray.push(hi);
            }
            return byteArray;
        }
        function base64ToBytes(str) {
            return base64.toByteArray(base64clean(str));
        }
        function blitBuffer(src, dst, offset, length) {
            for (var i = 0; i < length; ++i) {
                if (i + offset >= dst.length || i >= src.length) break;
                dst[i + offset] = src[i];
            }
            return i;
        }
        function isInstance(obj, type) {
            return obj instanceof type || obj != null && obj.constructor != null && obj.constructor.name != null && obj.constructor.name === type.name;
        }
        function numberIsNaN(obj) {
            return obj !== obj;
        }
        var hexSliceLookupTable = function() {
            var alphabet = "0123456789abcdef";
            var table = new Array(256);
            for (var i = 0; i < 16; ++i) {
                var i16 = i * 16;
                for (var j = 0; j < 16; ++j) {
                    table[i16 + j] = alphabet[i] + alphabet[j];
                }
            }
            return table;
        }();
    },
    710: (__unused_webpack_module, exports) => {
        exports.read = function(buffer, offset, isLE, mLen, nBytes) {
            var e, m;
            var eLen = nBytes * 8 - mLen - 1;
            var eMax = (1 << eLen) - 1;
            var eBias = eMax >> 1;
            var nBits = -7;
            var i = isLE ? nBytes - 1 : 0;
            var d = isLE ? -1 : 1;
            var s = buffer[offset + i];
            i += d;
            e = s & (1 << -nBits) - 1;
            s >>= -nBits;
            nBits += eLen;
            for (;nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
            m = e & (1 << -nBits) - 1;
            e >>= -nBits;
            nBits += mLen;
            for (;nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
            if (e === 0) {
                e = 1 - eBias;
            } else if (e === eMax) {
                return m ? NaN : (s ? -1 : 1) * Infinity;
            } else {
                m = m + Math.pow(2, mLen);
                e = e - eBias;
            }
            return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
        };
        exports.write = function(buffer, value, offset, isLE, mLen, nBytes) {
            var e, m, c;
            var eLen = nBytes * 8 - mLen - 1;
            var eMax = (1 << eLen) - 1;
            var eBias = eMax >> 1;
            var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0;
            var i = isLE ? 0 : nBytes - 1;
            var d = isLE ? 1 : -1;
            var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;
            value = Math.abs(value);
            if (isNaN(value) || value === Infinity) {
                m = isNaN(value) ? 1 : 0;
                e = eMax;
            } else {
                e = Math.floor(Math.log(value) / Math.LN2);
                if (value * (c = Math.pow(2, -e)) < 1) {
                    e--;
                    c *= 2;
                }
                if (e + eBias >= 1) {
                    value += rt / c;
                } else {
                    value += rt * Math.pow(2, 1 - eBias);
                }
                if (value * c >= 2) {
                    e++;
                    c /= 2;
                }
                if (e + eBias >= eMax) {
                    m = 0;
                    e = eMax;
                } else if (e + eBias >= 1) {
                    m = (value * c - 1) * Math.pow(2, mLen);
                    e = e + eBias;
                } else {
                    m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
                    e = 0;
                }
            }
            for (;mLen >= 8; buffer[offset + i] = m & 255, i += d, m /= 256, mLen -= 8) {}
            e = e << mLen | m;
            eLen += mLen;
            for (;eLen > 0; buffer[offset + i] = e & 255, i += d, e /= 256, eLen -= 8) {}
            buffer[offset + i - d] |= s * 128;
        };
    }
};

var __webpack_module_cache__ = {};

function __webpack_require__(moduleId) {
    var cachedModule = __webpack_module_cache__[moduleId];
    if (cachedModule !== undefined) {
        return cachedModule.exports;
    }
    var module = __webpack_module_cache__[moduleId] = {
        exports: {}
    };
    __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    return module.exports;
}

(() => {
    __webpack_require__.d = (exports, definition) => {
        for (var key in definition) {
            if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
                Object.defineProperty(exports, key, {
                    enumerable: true,
                    get: definition[key]
                });
            }
        }
    };
})();

(() => {
    __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
})();

var __webpack_exports__ = {};

(() => {
    var x = y => {
        var x = {};
        __webpack_require__.d(x, y);
        return x;
    };
    var y = x => () => x;
    const server_editor_namespaceObject = x({
        ["ActionTypes"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ActionTypes,
        ["AudioSettingsProperty"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.AudioSettingsProperty,
        ["Axis"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.Axis,
        ["BlockMaskListType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.BlockMaskListType,
        ["BlockPaletteItemType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.BlockPaletteItemType,
        ["BoolPropertyItemVariant"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.BoolPropertyItemVariant,
        ["BrushDirectionalPlacementMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.BrushDirectionalPlacementMode,
        ["BrushElevationMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.BrushElevationMode,
        ["ButtonVariant"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ButtonVariant,
        ["ColorPickerPropertyItemVariant"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ColorPickerPropertyItemVariant,
        ["ComboBoxPropertyItemDataType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ComboBoxPropertyItemDataType,
        ["ContinuousActionState"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ContinuousActionState,
        ["CoreActionBarItemType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.CoreActionBarItemType,
        ["CoreBrushShapeType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.CoreBrushShapeType,
        ["CoreMenuType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.CoreMenuType,
        ["CoreModalDialogType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.CoreModalDialogType,
        ["CuboidBrushShape"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.CuboidBrushShape,
        ["CursorControlMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.CursorControlMode,
        ["CursorTargetMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.CursorTargetMode,
        ["CylinderBrushShape"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.CylinderBrushShape,
        ["DataPickerModalDialogVariant"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.DataPickerModalDialogVariant,
        ["DaylightCycle"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.DaylightCycle,
        ["EditorInputContext"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.EditorInputContext,
        ["EditorMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.EditorMode,
        ["EllipsoidBrushShape"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.EllipsoidBrushShape,
        ["EntityOperationType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.EntityOperationType,
        ["ExportResult"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ExportResult,
        ["FlattenMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.FlattenMode,
        ["GamePublishSetting"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.GamePublishSetting,
        ["GraphicsSettingsProperty"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.GraphicsSettingsProperty,
        ["IBlockPaletteItem"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.IBlockPaletteItem,
        ["ImageResourceType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ImageResourceType,
        ["InputModifier"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.InputModifier,
        ["KeyProcessingState"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.KeyProcessingState,
        ["KeyboardKey"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.KeyboardKey,
        ["LayoutAlignment"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.LayoutAlignment,
        ["LayoutFlex"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.LayoutFlex,
        ["LayoutSizeType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.LayoutSizeType,
        ["ListPaneEntryType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ListPaneEntryType,
        ["ListPaneSlotVariant"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ListPaneSlotVariant,
        ["LogChannel"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.LogChannel,
        ["ModalDialogResponseType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ModalDialogResponseType,
        ["MouseActionType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.MouseActionType,
        ["MouseInputType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.MouseInputType,
        ["NumberPropertyItemVariant"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.NumberPropertyItemVariant,
        ["PaintCompletionState"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.PaintCompletionState,
        ["PaintMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.PaintMode,
        ["PaneLayoutType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.PaneLayoutType,
        ["PlaytestSessionResult"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.PlaytestSessionResult,
        ["ProgressIndicatorPropertyItemVariant"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ProgressIndicatorPropertyItemVariant,
        ["RelativeVolumeListBlockVolume"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.RelativeVolumeListBlockVolume,
        ["SelectionVolumeEventType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.SelectionVolumeEventType,
        ["SingleBlockBrushShape"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.SingleBlockBrushShape,
        ["SpeedSettingsProperty"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.SpeedSettingsProperty,
        ["SplineType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.SplineType,
        ["StatusBarAlignment"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.StatusBarAlignment,
        ["StructureSource"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.StructureSource,
        ["ThemeSettingsColorKey"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.ThemeSettingsColorKey,
        ["WidgetCollisionType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.WidgetCollisionType,
        ["WidgetComponentRenderPrimitiveTypeBox"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.WidgetComponentRenderPrimitiveTypeBox,
        ["WidgetComponentRenderPrimitiveTypeDisc"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.WidgetComponentRenderPrimitiveTypeDisc,
        ["WidgetComponentRenderPrimitiveTypeLine"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.WidgetComponentRenderPrimitiveTypeLine,
        ["WidgetGizmoEventType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.WidgetGizmoEventType,
        ["WidgetGroupSelectionMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.WidgetGroupSelectionMode,
        ["WidgetMouseButtonActionType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.WidgetMouseButtonActionType,
        ["WorldGeneratorType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.WorldGeneratorType,
        ["deserialize"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.deserialize,
        ["editor"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.editor,
        ["executeLargeOperationFromIterator"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.executeLargeOperationFromIterator,
        ["getDefaultBrushShapes"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.getDefaultBrushShapes,
        ["makeObservable"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.makeObservable,
        ["registerEditorExtension"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.registerEditorExtension,
        ["registerUserDefinedTransactionHandler"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.registerUserDefinedTransactionHandler,
        ["serialize"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.serialize,
        ["stringFromException"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_81aed4a5__.stringFromException
    });
    var server_x = y => {
        var x = {};
        __webpack_require__.d(x, y);
        return x;
    };
    var server_y = x => () => x;
    const server_namespaceObject = server_x({
        ["BiomeTypes"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BiomeTypes,
        ["BlockBoundingBoxUtils"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockBoundingBoxUtils,
        ["BlockComponentTypes"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockComponentTypes,
        ["BlockFluidContainerComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockFluidContainerComponent,
        ["BlockPermutation"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockPermutation,
        ["BlockPistonComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockPistonComponent,
        ["BlockRedstoneProducerComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockRedstoneProducerComponent,
        ["BlockSignComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockSignComponent,
        ["BlockStates"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockStates,
        ["BlockTypes"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockTypes,
        ["BlockVolume"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockVolume,
        ["BlockVolumeBase"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.BlockVolumeBase,
        ["CatmullRomSpline"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.CatmullRomSpline,
        ["Difficulty"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.Difficulty,
        ["Direction"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.Direction,
        ["EasingType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EasingType,
        ["EntityAddRiderComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityAddRiderComponent,
        ["EntityAgeableComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityAgeableComponent,
        ["EntityBreathableComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityBreathableComponent,
        ["EntityColorComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityColorComponent,
        ["EntityComponentTypes"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityComponentTypes,
        ["EntityEquippableComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityEquippableComponent,
        ["EntityFlyingSpeedComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityFlyingSpeedComponent,
        ["EntityFrictionModifierComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityFrictionModifierComponent,
        ["EntityHealableComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityHealableComponent,
        ["EntityInventoryComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityInventoryComponent,
        ["EntityLeashableComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityLeashableComponent,
        ["EntityMarkVariantComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityMarkVariantComponent,
        ["EntityNpcComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityNpcComponent,
        ["EntityOnFireComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityOnFireComponent,
        ["EntityProjectileComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityProjectileComponent,
        ["EntityPushThroughComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityPushThroughComponent,
        ["EntityRideableComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityRideableComponent,
        ["EntityScaleComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityScaleComponent,
        ["EntitySkinIdComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntitySkinIdComponent,
        ["EntityStrengthComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityStrengthComponent,
        ["EntityTameMountComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityTameMountComponent,
        ["EntityTameableComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityTameableComponent,
        ["EntityTypeFamilyComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityTypeFamilyComponent,
        ["EntityVariantComponent"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.EntityVariantComponent,
        ["GameMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.GameMode,
        ["GraphicsMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.GraphicsMode,
        ["ItemStack"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.ItemStack,
        ["ItemTypes"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.ItemTypes,
        ["LinearSpline"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.LinearSpline,
        ["LiquidType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.LiquidType,
        ["PlayerPermissionLevel"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.PlayerPermissionLevel,
        ["SignSide"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.SignSide,
        ["StructureMirrorAxis"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.StructureMirrorAxis,
        ["StructureRotation"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.StructureRotation,
        ["TicksPerSecond"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.TicksPerSecond,
        ["TimeOfDay"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.TimeOfDay,
        ["WeatherType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.WeatherType,
        ["system"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.system,
        ["world"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_fb7572af__.world
    });
    var MinecraftBiomeTypes = (MinecraftBiomeTypes2 => {
        MinecraftBiomeTypes2["BambooJungle"] = "minecraft:bamboo_jungle";
        MinecraftBiomeTypes2["BambooJungleHills"] = "minecraft:bamboo_jungle_hills";
        MinecraftBiomeTypes2["BasaltDeltas"] = "minecraft:basalt_deltas";
        MinecraftBiomeTypes2["Beach"] = "minecraft:beach";
        MinecraftBiomeTypes2["BirchForest"] = "minecraft:birch_forest";
        MinecraftBiomeTypes2["BirchForestHills"] = "minecraft:birch_forest_hills";
        MinecraftBiomeTypes2["BirchForestHillsMutated"] = "minecraft:birch_forest_hills_mutated";
        MinecraftBiomeTypes2["BirchForestMutated"] = "minecraft:birch_forest_mutated";
        MinecraftBiomeTypes2["CherryGrove"] = "minecraft:cherry_grove";
        MinecraftBiomeTypes2["ColdBeach"] = "minecraft:cold_beach";
        MinecraftBiomeTypes2["ColdOcean"] = "minecraft:cold_ocean";
        MinecraftBiomeTypes2["ColdTaiga"] = "minecraft:cold_taiga";
        MinecraftBiomeTypes2["ColdTaigaHills"] = "minecraft:cold_taiga_hills";
        MinecraftBiomeTypes2["ColdTaigaMutated"] = "minecraft:cold_taiga_mutated";
        MinecraftBiomeTypes2["CrimsonForest"] = "minecraft:crimson_forest";
        MinecraftBiomeTypes2["DeepColdOcean"] = "minecraft:deep_cold_ocean";
        MinecraftBiomeTypes2["DeepDark"] = "minecraft:deep_dark";
        MinecraftBiomeTypes2["DeepFrozenOcean"] = "minecraft:deep_frozen_ocean";
        MinecraftBiomeTypes2["DeepLukewarmOcean"] = "minecraft:deep_lukewarm_ocean";
        MinecraftBiomeTypes2["DeepOcean"] = "minecraft:deep_ocean";
        MinecraftBiomeTypes2["DeepWarmOcean"] = "minecraft:deep_warm_ocean";
        MinecraftBiomeTypes2["Desert"] = "minecraft:desert";
        MinecraftBiomeTypes2["DesertHills"] = "minecraft:desert_hills";
        MinecraftBiomeTypes2["DesertMutated"] = "minecraft:desert_mutated";
        MinecraftBiomeTypes2["DripstoneCaves"] = "minecraft:dripstone_caves";
        MinecraftBiomeTypes2["ExtremeHills"] = "minecraft:extreme_hills";
        MinecraftBiomeTypes2["ExtremeHillsEdge"] = "minecraft:extreme_hills_edge";
        MinecraftBiomeTypes2["ExtremeHillsMutated"] = "minecraft:extreme_hills_mutated";
        MinecraftBiomeTypes2["ExtremeHillsPlusTrees"] = "minecraft:extreme_hills_plus_trees";
        MinecraftBiomeTypes2["ExtremeHillsPlusTreesMutated"] = "minecraft:extreme_hills_plus_trees_mutated";
        MinecraftBiomeTypes2["FlowerForest"] = "minecraft:flower_forest";
        MinecraftBiomeTypes2["Forest"] = "minecraft:forest";
        MinecraftBiomeTypes2["ForestHills"] = "minecraft:forest_hills";
        MinecraftBiomeTypes2["FrozenOcean"] = "minecraft:frozen_ocean";
        MinecraftBiomeTypes2["FrozenPeaks"] = "minecraft:frozen_peaks";
        MinecraftBiomeTypes2["FrozenRiver"] = "minecraft:frozen_river";
        MinecraftBiomeTypes2["Grove"] = "minecraft:grove";
        MinecraftBiomeTypes2["Hell"] = "minecraft:hell";
        MinecraftBiomeTypes2["IceMountains"] = "minecraft:ice_mountains";
        MinecraftBiomeTypes2["IcePlains"] = "minecraft:ice_plains";
        MinecraftBiomeTypes2["IcePlainsSpikes"] = "minecraft:ice_plains_spikes";
        MinecraftBiomeTypes2["JaggedPeaks"] = "minecraft:jagged_peaks";
        MinecraftBiomeTypes2["Jungle"] = "minecraft:jungle";
        MinecraftBiomeTypes2["JungleEdge"] = "minecraft:jungle_edge";
        MinecraftBiomeTypes2["JungleEdgeMutated"] = "minecraft:jungle_edge_mutated";
        MinecraftBiomeTypes2["JungleHills"] = "minecraft:jungle_hills";
        MinecraftBiomeTypes2["JungleMutated"] = "minecraft:jungle_mutated";
        MinecraftBiomeTypes2["LegacyFrozenOcean"] = "minecraft:legacy_frozen_ocean";
        MinecraftBiomeTypes2["LukewarmOcean"] = "minecraft:lukewarm_ocean";
        MinecraftBiomeTypes2["LushCaves"] = "minecraft:lush_caves";
        MinecraftBiomeTypes2["MangroveSwamp"] = "minecraft:mangrove_swamp";
        MinecraftBiomeTypes2["Meadow"] = "minecraft:meadow";
        MinecraftBiomeTypes2["MegaTaiga"] = "minecraft:mega_taiga";
        MinecraftBiomeTypes2["MegaTaigaHills"] = "minecraft:mega_taiga_hills";
        MinecraftBiomeTypes2["Mesa"] = "minecraft:mesa";
        MinecraftBiomeTypes2["MesaBryce"] = "minecraft:mesa_bryce";
        MinecraftBiomeTypes2["MesaPlateau"] = "minecraft:mesa_plateau";
        MinecraftBiomeTypes2["MesaPlateauMutated"] = "minecraft:mesa_plateau_mutated";
        MinecraftBiomeTypes2["MesaPlateauStone"] = "minecraft:mesa_plateau_stone";
        MinecraftBiomeTypes2["MesaPlateauStoneMutated"] = "minecraft:mesa_plateau_stone_mutated";
        MinecraftBiomeTypes2["MushroomIsland"] = "minecraft:mushroom_island";
        MinecraftBiomeTypes2["MushroomIslandShore"] = "minecraft:mushroom_island_shore";
        MinecraftBiomeTypes2["Ocean"] = "minecraft:ocean";
        MinecraftBiomeTypes2["PaleGarden"] = "minecraft:pale_garden";
        MinecraftBiomeTypes2["Plains"] = "minecraft:plains";
        MinecraftBiomeTypes2["RedwoodTaigaHillsMutated"] = "minecraft:redwood_taiga_hills_mutated";
        MinecraftBiomeTypes2["RedwoodTaigaMutated"] = "minecraft:redwood_taiga_mutated";
        MinecraftBiomeTypes2["River"] = "minecraft:river";
        MinecraftBiomeTypes2["RoofedForest"] = "minecraft:roofed_forest";
        MinecraftBiomeTypes2["RoofedForestMutated"] = "minecraft:roofed_forest_mutated";
        MinecraftBiomeTypes2["Savanna"] = "minecraft:savanna";
        MinecraftBiomeTypes2["SavannaMutated"] = "minecraft:savanna_mutated";
        MinecraftBiomeTypes2["SavannaPlateau"] = "minecraft:savanna_plateau";
        MinecraftBiomeTypes2["SavannaPlateauMutated"] = "minecraft:savanna_plateau_mutated";
        MinecraftBiomeTypes2["SnowySlopes"] = "minecraft:snowy_slopes";
        MinecraftBiomeTypes2["SoulsandValley"] = "minecraft:soulsand_valley";
        MinecraftBiomeTypes2["StoneBeach"] = "minecraft:stone_beach";
        MinecraftBiomeTypes2["StonyPeaks"] = "minecraft:stony_peaks";
        MinecraftBiomeTypes2["SunflowerPlains"] = "minecraft:sunflower_plains";
        MinecraftBiomeTypes2["Swampland"] = "minecraft:swampland";
        MinecraftBiomeTypes2["SwamplandMutated"] = "minecraft:swampland_mutated";
        MinecraftBiomeTypes2["Taiga"] = "minecraft:taiga";
        MinecraftBiomeTypes2["TaigaHills"] = "minecraft:taiga_hills";
        MinecraftBiomeTypes2["TaigaMutated"] = "minecraft:taiga_mutated";
        MinecraftBiomeTypes2["TheEnd"] = "minecraft:the_end";
        MinecraftBiomeTypes2["WarmOcean"] = "minecraft:warm_ocean";
        MinecraftBiomeTypes2["WarpedForest"] = "minecraft:warped_forest";
        return MinecraftBiomeTypes2;
    })(MinecraftBiomeTypes || {});
    var lib_vanilla_MinecraftBlockTypes = (MinecraftBlockTypes2 => {
        MinecraftBlockTypes2["AcaciaButton"] = "minecraft:acacia_button";
        MinecraftBlockTypes2["AcaciaDoor"] = "minecraft:acacia_door";
        MinecraftBlockTypes2["AcaciaDoubleSlab"] = "minecraft:acacia_double_slab";
        MinecraftBlockTypes2["AcaciaFence"] = "minecraft:acacia_fence";
        MinecraftBlockTypes2["AcaciaFenceGate"] = "minecraft:acacia_fence_gate";
        MinecraftBlockTypes2["AcaciaHangingSign"] = "minecraft:acacia_hanging_sign";
        MinecraftBlockTypes2["AcaciaLeaves"] = "minecraft:acacia_leaves";
        MinecraftBlockTypes2["AcaciaLog"] = "minecraft:acacia_log";
        MinecraftBlockTypes2["AcaciaPlanks"] = "minecraft:acacia_planks";
        MinecraftBlockTypes2["AcaciaPressurePlate"] = "minecraft:acacia_pressure_plate";
        MinecraftBlockTypes2["AcaciaSapling"] = "minecraft:acacia_sapling";
        MinecraftBlockTypes2["AcaciaShelf"] = "minecraft:acacia_shelf";
        MinecraftBlockTypes2["AcaciaSlab"] = "minecraft:acacia_slab";
        MinecraftBlockTypes2["AcaciaStairs"] = "minecraft:acacia_stairs";
        MinecraftBlockTypes2["AcaciaStandingSign"] = "minecraft:acacia_standing_sign";
        MinecraftBlockTypes2["AcaciaTrapdoor"] = "minecraft:acacia_trapdoor";
        MinecraftBlockTypes2["AcaciaWallSign"] = "minecraft:acacia_wall_sign";
        MinecraftBlockTypes2["AcaciaWood"] = "minecraft:acacia_wood";
        MinecraftBlockTypes2["ActivatorRail"] = "minecraft:activator_rail";
        MinecraftBlockTypes2["Air"] = "minecraft:air";
        MinecraftBlockTypes2["Allium"] = "minecraft:allium";
        MinecraftBlockTypes2["Allow"] = "minecraft:allow";
        MinecraftBlockTypes2["AmethystBlock"] = "minecraft:amethyst_block";
        MinecraftBlockTypes2["AmethystCluster"] = "minecraft:amethyst_cluster";
        MinecraftBlockTypes2["AncientDebris"] = "minecraft:ancient_debris";
        MinecraftBlockTypes2["Andesite"] = "minecraft:andesite";
        MinecraftBlockTypes2["AndesiteDoubleSlab"] = "minecraft:andesite_double_slab";
        MinecraftBlockTypes2["AndesiteSlab"] = "minecraft:andesite_slab";
        MinecraftBlockTypes2["AndesiteStairs"] = "minecraft:andesite_stairs";
        MinecraftBlockTypes2["AndesiteWall"] = "minecraft:andesite_wall";
        MinecraftBlockTypes2["Anvil"] = "minecraft:anvil";
        MinecraftBlockTypes2["Azalea"] = "minecraft:azalea";
        MinecraftBlockTypes2["AzaleaLeaves"] = "minecraft:azalea_leaves";
        MinecraftBlockTypes2["AzaleaLeavesFlowered"] = "minecraft:azalea_leaves_flowered";
        MinecraftBlockTypes2["AzureBluet"] = "minecraft:azure_bluet";
        MinecraftBlockTypes2["Bamboo"] = "minecraft:bamboo";
        MinecraftBlockTypes2["BambooBlock"] = "minecraft:bamboo_block";
        MinecraftBlockTypes2["BambooButton"] = "minecraft:bamboo_button";
        MinecraftBlockTypes2["BambooDoor"] = "minecraft:bamboo_door";
        MinecraftBlockTypes2["BambooDoubleSlab"] = "minecraft:bamboo_double_slab";
        MinecraftBlockTypes2["BambooFence"] = "minecraft:bamboo_fence";
        MinecraftBlockTypes2["BambooFenceGate"] = "minecraft:bamboo_fence_gate";
        MinecraftBlockTypes2["BambooHangingSign"] = "minecraft:bamboo_hanging_sign";
        MinecraftBlockTypes2["BambooMosaic"] = "minecraft:bamboo_mosaic";
        MinecraftBlockTypes2["BambooMosaicDoubleSlab"] = "minecraft:bamboo_mosaic_double_slab";
        MinecraftBlockTypes2["BambooMosaicSlab"] = "minecraft:bamboo_mosaic_slab";
        MinecraftBlockTypes2["BambooMosaicStairs"] = "minecraft:bamboo_mosaic_stairs";
        MinecraftBlockTypes2["BambooPlanks"] = "minecraft:bamboo_planks";
        MinecraftBlockTypes2["BambooPressurePlate"] = "minecraft:bamboo_pressure_plate";
        MinecraftBlockTypes2["BambooSapling"] = "minecraft:bamboo_sapling";
        MinecraftBlockTypes2["BambooShelf"] = "minecraft:bamboo_shelf";
        MinecraftBlockTypes2["BambooSlab"] = "minecraft:bamboo_slab";
        MinecraftBlockTypes2["BambooStairs"] = "minecraft:bamboo_stairs";
        MinecraftBlockTypes2["BambooStandingSign"] = "minecraft:bamboo_standing_sign";
        MinecraftBlockTypes2["BambooTrapdoor"] = "minecraft:bamboo_trapdoor";
        MinecraftBlockTypes2["BambooWallSign"] = "minecraft:bamboo_wall_sign";
        MinecraftBlockTypes2["Barrel"] = "minecraft:barrel";
        MinecraftBlockTypes2["Barrier"] = "minecraft:barrier";
        MinecraftBlockTypes2["Basalt"] = "minecraft:basalt";
        MinecraftBlockTypes2["Beacon"] = "minecraft:beacon";
        MinecraftBlockTypes2["Bed"] = "minecraft:bed";
        MinecraftBlockTypes2["Bedrock"] = "minecraft:bedrock";
        MinecraftBlockTypes2["BeeNest"] = "minecraft:bee_nest";
        MinecraftBlockTypes2["Beehive"] = "minecraft:beehive";
        MinecraftBlockTypes2["Beetroot"] = "minecraft:beetroot";
        MinecraftBlockTypes2["Bell"] = "minecraft:bell";
        MinecraftBlockTypes2["BigDripleaf"] = "minecraft:big_dripleaf";
        MinecraftBlockTypes2["BirchButton"] = "minecraft:birch_button";
        MinecraftBlockTypes2["BirchDoor"] = "minecraft:birch_door";
        MinecraftBlockTypes2["BirchDoubleSlab"] = "minecraft:birch_double_slab";
        MinecraftBlockTypes2["BirchFence"] = "minecraft:birch_fence";
        MinecraftBlockTypes2["BirchFenceGate"] = "minecraft:birch_fence_gate";
        MinecraftBlockTypes2["BirchHangingSign"] = "minecraft:birch_hanging_sign";
        MinecraftBlockTypes2["BirchLeaves"] = "minecraft:birch_leaves";
        MinecraftBlockTypes2["BirchLog"] = "minecraft:birch_log";
        MinecraftBlockTypes2["BirchPlanks"] = "minecraft:birch_planks";
        MinecraftBlockTypes2["BirchPressurePlate"] = "minecraft:birch_pressure_plate";
        MinecraftBlockTypes2["BirchSapling"] = "minecraft:birch_sapling";
        MinecraftBlockTypes2["BirchShelf"] = "minecraft:birch_shelf";
        MinecraftBlockTypes2["BirchSlab"] = "minecraft:birch_slab";
        MinecraftBlockTypes2["BirchStairs"] = "minecraft:birch_stairs";
        MinecraftBlockTypes2["BirchStandingSign"] = "minecraft:birch_standing_sign";
        MinecraftBlockTypes2["BirchTrapdoor"] = "minecraft:birch_trapdoor";
        MinecraftBlockTypes2["BirchWallSign"] = "minecraft:birch_wall_sign";
        MinecraftBlockTypes2["BirchWood"] = "minecraft:birch_wood";
        MinecraftBlockTypes2["BlackCandle"] = "minecraft:black_candle";
        MinecraftBlockTypes2["BlackCandleCake"] = "minecraft:black_candle_cake";
        MinecraftBlockTypes2["BlackCarpet"] = "minecraft:black_carpet";
        MinecraftBlockTypes2["BlackConcrete"] = "minecraft:black_concrete";
        MinecraftBlockTypes2["BlackConcretePowder"] = "minecraft:black_concrete_powder";
        MinecraftBlockTypes2["BlackGlazedTerracotta"] = "minecraft:black_glazed_terracotta";
        MinecraftBlockTypes2["BlackShulkerBox"] = "minecraft:black_shulker_box";
        MinecraftBlockTypes2["BlackStainedGlass"] = "minecraft:black_stained_glass";
        MinecraftBlockTypes2["BlackStainedGlassPane"] = "minecraft:black_stained_glass_pane";
        MinecraftBlockTypes2["BlackTerracotta"] = "minecraft:black_terracotta";
        MinecraftBlockTypes2["BlackWool"] = "minecraft:black_wool";
        MinecraftBlockTypes2["Blackstone"] = "minecraft:blackstone";
        MinecraftBlockTypes2["BlackstoneDoubleSlab"] = "minecraft:blackstone_double_slab";
        MinecraftBlockTypes2["BlackstoneSlab"] = "minecraft:blackstone_slab";
        MinecraftBlockTypes2["BlackstoneStairs"] = "minecraft:blackstone_stairs";
        MinecraftBlockTypes2["BlackstoneWall"] = "minecraft:blackstone_wall";
        MinecraftBlockTypes2["BlastFurnace"] = "minecraft:blast_furnace";
        MinecraftBlockTypes2["BlueCandle"] = "minecraft:blue_candle";
        MinecraftBlockTypes2["BlueCandleCake"] = "minecraft:blue_candle_cake";
        MinecraftBlockTypes2["BlueCarpet"] = "minecraft:blue_carpet";
        MinecraftBlockTypes2["BlueConcrete"] = "minecraft:blue_concrete";
        MinecraftBlockTypes2["BlueConcretePowder"] = "minecraft:blue_concrete_powder";
        MinecraftBlockTypes2["BlueGlazedTerracotta"] = "minecraft:blue_glazed_terracotta";
        MinecraftBlockTypes2["BlueIce"] = "minecraft:blue_ice";
        MinecraftBlockTypes2["BlueOrchid"] = "minecraft:blue_orchid";
        MinecraftBlockTypes2["BlueShulkerBox"] = "minecraft:blue_shulker_box";
        MinecraftBlockTypes2["BlueStainedGlass"] = "minecraft:blue_stained_glass";
        MinecraftBlockTypes2["BlueStainedGlassPane"] = "minecraft:blue_stained_glass_pane";
        MinecraftBlockTypes2["BlueTerracotta"] = "minecraft:blue_terracotta";
        MinecraftBlockTypes2["BlueWool"] = "minecraft:blue_wool";
        MinecraftBlockTypes2["BoneBlock"] = "minecraft:bone_block";
        MinecraftBlockTypes2["Bookshelf"] = "minecraft:bookshelf";
        MinecraftBlockTypes2["BorderBlock"] = "minecraft:border_block";
        MinecraftBlockTypes2["BrainCoral"] = "minecraft:brain_coral";
        MinecraftBlockTypes2["BrainCoralBlock"] = "minecraft:brain_coral_block";
        MinecraftBlockTypes2["BrainCoralFan"] = "minecraft:brain_coral_fan";
        MinecraftBlockTypes2["BrainCoralWallFan"] = "minecraft:brain_coral_wall_fan";
        MinecraftBlockTypes2["BrewingStand"] = "minecraft:brewing_stand";
        MinecraftBlockTypes2["BrickBlock"] = "minecraft:brick_block";
        MinecraftBlockTypes2["BrickDoubleSlab"] = "minecraft:brick_double_slab";
        MinecraftBlockTypes2["BrickSlab"] = "minecraft:brick_slab";
        MinecraftBlockTypes2["BrickStairs"] = "minecraft:brick_stairs";
        MinecraftBlockTypes2["BrickWall"] = "minecraft:brick_wall";
        MinecraftBlockTypes2["BrownCandle"] = "minecraft:brown_candle";
        MinecraftBlockTypes2["BrownCandleCake"] = "minecraft:brown_candle_cake";
        MinecraftBlockTypes2["BrownCarpet"] = "minecraft:brown_carpet";
        MinecraftBlockTypes2["BrownConcrete"] = "minecraft:brown_concrete";
        MinecraftBlockTypes2["BrownConcretePowder"] = "minecraft:brown_concrete_powder";
        MinecraftBlockTypes2["BrownGlazedTerracotta"] = "minecraft:brown_glazed_terracotta";
        MinecraftBlockTypes2["BrownMushroom"] = "minecraft:brown_mushroom";
        MinecraftBlockTypes2["BrownMushroomBlock"] = "minecraft:brown_mushroom_block";
        MinecraftBlockTypes2["BrownShulkerBox"] = "minecraft:brown_shulker_box";
        MinecraftBlockTypes2["BrownStainedGlass"] = "minecraft:brown_stained_glass";
        MinecraftBlockTypes2["BrownStainedGlassPane"] = "minecraft:brown_stained_glass_pane";
        MinecraftBlockTypes2["BrownTerracotta"] = "minecraft:brown_terracotta";
        MinecraftBlockTypes2["BrownWool"] = "minecraft:brown_wool";
        MinecraftBlockTypes2["BubbleColumn"] = "minecraft:bubble_column";
        MinecraftBlockTypes2["BubbleCoral"] = "minecraft:bubble_coral";
        MinecraftBlockTypes2["BubbleCoralBlock"] = "minecraft:bubble_coral_block";
        MinecraftBlockTypes2["BubbleCoralFan"] = "minecraft:bubble_coral_fan";
        MinecraftBlockTypes2["BubbleCoralWallFan"] = "minecraft:bubble_coral_wall_fan";
        MinecraftBlockTypes2["BuddingAmethyst"] = "minecraft:budding_amethyst";
        MinecraftBlockTypes2["Bush"] = "minecraft:bush";
        MinecraftBlockTypes2["Cactus"] = "minecraft:cactus";
        MinecraftBlockTypes2["CactusFlower"] = "minecraft:cactus_flower";
        MinecraftBlockTypes2["Cake"] = "minecraft:cake";
        MinecraftBlockTypes2["Calcite"] = "minecraft:calcite";
        MinecraftBlockTypes2["CalibratedSculkSensor"] = "minecraft:calibrated_sculk_sensor";
        MinecraftBlockTypes2["Camera"] = "minecraft:camera";
        MinecraftBlockTypes2["Campfire"] = "minecraft:campfire";
        MinecraftBlockTypes2["Candle"] = "minecraft:candle";
        MinecraftBlockTypes2["CandleCake"] = "minecraft:candle_cake";
        MinecraftBlockTypes2["Carrots"] = "minecraft:carrots";
        MinecraftBlockTypes2["CartographyTable"] = "minecraft:cartography_table";
        MinecraftBlockTypes2["CarvedPumpkin"] = "minecraft:carved_pumpkin";
        MinecraftBlockTypes2["Cauldron"] = "minecraft:cauldron";
        MinecraftBlockTypes2["CaveVines"] = "minecraft:cave_vines";
        MinecraftBlockTypes2["CaveVinesBodyWithBerries"] = "minecraft:cave_vines_body_with_berries";
        MinecraftBlockTypes2["CaveVinesHeadWithBerries"] = "minecraft:cave_vines_head_with_berries";
        MinecraftBlockTypes2["ChainCommandBlock"] = "minecraft:chain_command_block";
        MinecraftBlockTypes2["ChemicalHeat"] = "minecraft:chemical_heat";
        MinecraftBlockTypes2["CherryButton"] = "minecraft:cherry_button";
        MinecraftBlockTypes2["CherryDoor"] = "minecraft:cherry_door";
        MinecraftBlockTypes2["CherryDoubleSlab"] = "minecraft:cherry_double_slab";
        MinecraftBlockTypes2["CherryFence"] = "minecraft:cherry_fence";
        MinecraftBlockTypes2["CherryFenceGate"] = "minecraft:cherry_fence_gate";
        MinecraftBlockTypes2["CherryHangingSign"] = "minecraft:cherry_hanging_sign";
        MinecraftBlockTypes2["CherryLeaves"] = "minecraft:cherry_leaves";
        MinecraftBlockTypes2["CherryLog"] = "minecraft:cherry_log";
        MinecraftBlockTypes2["CherryPlanks"] = "minecraft:cherry_planks";
        MinecraftBlockTypes2["CherryPressurePlate"] = "minecraft:cherry_pressure_plate";
        MinecraftBlockTypes2["CherrySapling"] = "minecraft:cherry_sapling";
        MinecraftBlockTypes2["CherryShelf"] = "minecraft:cherry_shelf";
        MinecraftBlockTypes2["CherrySlab"] = "minecraft:cherry_slab";
        MinecraftBlockTypes2["CherryStairs"] = "minecraft:cherry_stairs";
        MinecraftBlockTypes2["CherryStandingSign"] = "minecraft:cherry_standing_sign";
        MinecraftBlockTypes2["CherryTrapdoor"] = "minecraft:cherry_trapdoor";
        MinecraftBlockTypes2["CherryWallSign"] = "minecraft:cherry_wall_sign";
        MinecraftBlockTypes2["CherryWood"] = "minecraft:cherry_wood";
        MinecraftBlockTypes2["Chest"] = "minecraft:chest";
        MinecraftBlockTypes2["ChippedAnvil"] = "minecraft:chipped_anvil";
        MinecraftBlockTypes2["ChiseledBookshelf"] = "minecraft:chiseled_bookshelf";
        MinecraftBlockTypes2["ChiseledCopper"] = "minecraft:chiseled_copper";
        MinecraftBlockTypes2["ChiseledDeepslate"] = "minecraft:chiseled_deepslate";
        MinecraftBlockTypes2["ChiseledNetherBricks"] = "minecraft:chiseled_nether_bricks";
        MinecraftBlockTypes2["ChiseledPolishedBlackstone"] = "minecraft:chiseled_polished_blackstone";
        MinecraftBlockTypes2["ChiseledQuartzBlock"] = "minecraft:chiseled_quartz_block";
        MinecraftBlockTypes2["ChiseledRedSandstone"] = "minecraft:chiseled_red_sandstone";
        MinecraftBlockTypes2["ChiseledResinBricks"] = "minecraft:chiseled_resin_bricks";
        MinecraftBlockTypes2["ChiseledSandstone"] = "minecraft:chiseled_sandstone";
        MinecraftBlockTypes2["ChiseledStoneBricks"] = "minecraft:chiseled_stone_bricks";
        MinecraftBlockTypes2["ChiseledTuff"] = "minecraft:chiseled_tuff";
        MinecraftBlockTypes2["ChiseledTuffBricks"] = "minecraft:chiseled_tuff_bricks";
        MinecraftBlockTypes2["ChorusFlower"] = "minecraft:chorus_flower";
        MinecraftBlockTypes2["ChorusPlant"] = "minecraft:chorus_plant";
        MinecraftBlockTypes2["Clay"] = "minecraft:clay";
        MinecraftBlockTypes2["ClosedEyeblossom"] = "minecraft:closed_eyeblossom";
        MinecraftBlockTypes2["CoalBlock"] = "minecraft:coal_block";
        MinecraftBlockTypes2["CoalOre"] = "minecraft:coal_ore";
        MinecraftBlockTypes2["CoarseDirt"] = "minecraft:coarse_dirt";
        MinecraftBlockTypes2["CobbledDeepslate"] = "minecraft:cobbled_deepslate";
        MinecraftBlockTypes2["CobbledDeepslateDoubleSlab"] = "minecraft:cobbled_deepslate_double_slab";
        MinecraftBlockTypes2["CobbledDeepslateSlab"] = "minecraft:cobbled_deepslate_slab";
        MinecraftBlockTypes2["CobbledDeepslateStairs"] = "minecraft:cobbled_deepslate_stairs";
        MinecraftBlockTypes2["CobbledDeepslateWall"] = "minecraft:cobbled_deepslate_wall";
        MinecraftBlockTypes2["Cobblestone"] = "minecraft:cobblestone";
        MinecraftBlockTypes2["CobblestoneDoubleSlab"] = "minecraft:cobblestone_double_slab";
        MinecraftBlockTypes2["CobblestoneSlab"] = "minecraft:cobblestone_slab";
        MinecraftBlockTypes2["CobblestoneWall"] = "minecraft:cobblestone_wall";
        MinecraftBlockTypes2["Cocoa"] = "minecraft:cocoa";
        MinecraftBlockTypes2["ColoredTorchBlue"] = "minecraft:colored_torch_blue";
        MinecraftBlockTypes2["ColoredTorchGreen"] = "minecraft:colored_torch_green";
        MinecraftBlockTypes2["ColoredTorchPurple"] = "minecraft:colored_torch_purple";
        MinecraftBlockTypes2["ColoredTorchRed"] = "minecraft:colored_torch_red";
        MinecraftBlockTypes2["CommandBlock"] = "minecraft:command_block";
        MinecraftBlockTypes2["Composter"] = "minecraft:composter";
        MinecraftBlockTypes2["CompoundCreator"] = "minecraft:compound_creator";
        MinecraftBlockTypes2["Conduit"] = "minecraft:conduit";
        MinecraftBlockTypes2["CopperBars"] = "minecraft:copper_bars";
        MinecraftBlockTypes2["CopperBlock"] = "minecraft:copper_block";
        MinecraftBlockTypes2["CopperBulb"] = "minecraft:copper_bulb";
        MinecraftBlockTypes2["CopperChain"] = "minecraft:copper_chain";
        MinecraftBlockTypes2["CopperChest"] = "minecraft:copper_chest";
        MinecraftBlockTypes2["CopperDoor"] = "minecraft:copper_door";
        MinecraftBlockTypes2["CopperGolemStatue"] = "minecraft:copper_golem_statue";
        MinecraftBlockTypes2["CopperGrate"] = "minecraft:copper_grate";
        MinecraftBlockTypes2["CopperLantern"] = "minecraft:copper_lantern";
        MinecraftBlockTypes2["CopperOre"] = "minecraft:copper_ore";
        MinecraftBlockTypes2["CopperTorch"] = "minecraft:copper_torch";
        MinecraftBlockTypes2["CopperTrapdoor"] = "minecraft:copper_trapdoor";
        MinecraftBlockTypes2["Cornflower"] = "minecraft:cornflower";
        MinecraftBlockTypes2["CrackedDeepslateBricks"] = "minecraft:cracked_deepslate_bricks";
        MinecraftBlockTypes2["CrackedDeepslateTiles"] = "minecraft:cracked_deepslate_tiles";
        MinecraftBlockTypes2["CrackedNetherBricks"] = "minecraft:cracked_nether_bricks";
        MinecraftBlockTypes2["CrackedPolishedBlackstoneBricks"] = "minecraft:cracked_polished_blackstone_bricks";
        MinecraftBlockTypes2["CrackedStoneBricks"] = "minecraft:cracked_stone_bricks";
        MinecraftBlockTypes2["Crafter"] = "minecraft:crafter";
        MinecraftBlockTypes2["CraftingTable"] = "minecraft:crafting_table";
        MinecraftBlockTypes2["CreakingHeart"] = "minecraft:creaking_heart";
        MinecraftBlockTypes2["CreeperHead"] = "minecraft:creeper_head";
        MinecraftBlockTypes2["CrimsonButton"] = "minecraft:crimson_button";
        MinecraftBlockTypes2["CrimsonDoor"] = "minecraft:crimson_door";
        MinecraftBlockTypes2["CrimsonDoubleSlab"] = "minecraft:crimson_double_slab";
        MinecraftBlockTypes2["CrimsonFence"] = "minecraft:crimson_fence";
        MinecraftBlockTypes2["CrimsonFenceGate"] = "minecraft:crimson_fence_gate";
        MinecraftBlockTypes2["CrimsonFungus"] = "minecraft:crimson_fungus";
        MinecraftBlockTypes2["CrimsonHangingSign"] = "minecraft:crimson_hanging_sign";
        MinecraftBlockTypes2["CrimsonHyphae"] = "minecraft:crimson_hyphae";
        MinecraftBlockTypes2["CrimsonNylium"] = "minecraft:crimson_nylium";
        MinecraftBlockTypes2["CrimsonPlanks"] = "minecraft:crimson_planks";
        MinecraftBlockTypes2["CrimsonPressurePlate"] = "minecraft:crimson_pressure_plate";
        MinecraftBlockTypes2["CrimsonRoots"] = "minecraft:crimson_roots";
        MinecraftBlockTypes2["CrimsonShelf"] = "minecraft:crimson_shelf";
        MinecraftBlockTypes2["CrimsonSlab"] = "minecraft:crimson_slab";
        MinecraftBlockTypes2["CrimsonStairs"] = "minecraft:crimson_stairs";
        MinecraftBlockTypes2["CrimsonStandingSign"] = "minecraft:crimson_standing_sign";
        MinecraftBlockTypes2["CrimsonStem"] = "minecraft:crimson_stem";
        MinecraftBlockTypes2["CrimsonTrapdoor"] = "minecraft:crimson_trapdoor";
        MinecraftBlockTypes2["CrimsonWallSign"] = "minecraft:crimson_wall_sign";
        MinecraftBlockTypes2["CryingObsidian"] = "minecraft:crying_obsidian";
        MinecraftBlockTypes2["CutCopper"] = "minecraft:cut_copper";
        MinecraftBlockTypes2["CutCopperSlab"] = "minecraft:cut_copper_slab";
        MinecraftBlockTypes2["CutCopperStairs"] = "minecraft:cut_copper_stairs";
        MinecraftBlockTypes2["CutRedSandstone"] = "minecraft:cut_red_sandstone";
        MinecraftBlockTypes2["CutRedSandstoneDoubleSlab"] = "minecraft:cut_red_sandstone_double_slab";
        MinecraftBlockTypes2["CutRedSandstoneSlab"] = "minecraft:cut_red_sandstone_slab";
        MinecraftBlockTypes2["CutSandstone"] = "minecraft:cut_sandstone";
        MinecraftBlockTypes2["CutSandstoneDoubleSlab"] = "minecraft:cut_sandstone_double_slab";
        MinecraftBlockTypes2["CutSandstoneSlab"] = "minecraft:cut_sandstone_slab";
        MinecraftBlockTypes2["CyanCandle"] = "minecraft:cyan_candle";
        MinecraftBlockTypes2["CyanCandleCake"] = "minecraft:cyan_candle_cake";
        MinecraftBlockTypes2["CyanCarpet"] = "minecraft:cyan_carpet";
        MinecraftBlockTypes2["CyanConcrete"] = "minecraft:cyan_concrete";
        MinecraftBlockTypes2["CyanConcretePowder"] = "minecraft:cyan_concrete_powder";
        MinecraftBlockTypes2["CyanGlazedTerracotta"] = "minecraft:cyan_glazed_terracotta";
        MinecraftBlockTypes2["CyanShulkerBox"] = "minecraft:cyan_shulker_box";
        MinecraftBlockTypes2["CyanStainedGlass"] = "minecraft:cyan_stained_glass";
        MinecraftBlockTypes2["CyanStainedGlassPane"] = "minecraft:cyan_stained_glass_pane";
        MinecraftBlockTypes2["CyanTerracotta"] = "minecraft:cyan_terracotta";
        MinecraftBlockTypes2["CyanWool"] = "minecraft:cyan_wool";
        MinecraftBlockTypes2["DamagedAnvil"] = "minecraft:damaged_anvil";
        MinecraftBlockTypes2["Dandelion"] = "minecraft:dandelion";
        MinecraftBlockTypes2["DarkOakButton"] = "minecraft:dark_oak_button";
        MinecraftBlockTypes2["DarkOakDoor"] = "minecraft:dark_oak_door";
        MinecraftBlockTypes2["DarkOakDoubleSlab"] = "minecraft:dark_oak_double_slab";
        MinecraftBlockTypes2["DarkOakFence"] = "minecraft:dark_oak_fence";
        MinecraftBlockTypes2["DarkOakFenceGate"] = "minecraft:dark_oak_fence_gate";
        MinecraftBlockTypes2["DarkOakHangingSign"] = "minecraft:dark_oak_hanging_sign";
        MinecraftBlockTypes2["DarkOakLeaves"] = "minecraft:dark_oak_leaves";
        MinecraftBlockTypes2["DarkOakLog"] = "minecraft:dark_oak_log";
        MinecraftBlockTypes2["DarkOakPlanks"] = "minecraft:dark_oak_planks";
        MinecraftBlockTypes2["DarkOakPressurePlate"] = "minecraft:dark_oak_pressure_plate";
        MinecraftBlockTypes2["DarkOakSapling"] = "minecraft:dark_oak_sapling";
        MinecraftBlockTypes2["DarkOakShelf"] = "minecraft:dark_oak_shelf";
        MinecraftBlockTypes2["DarkOakSlab"] = "minecraft:dark_oak_slab";
        MinecraftBlockTypes2["DarkOakStairs"] = "minecraft:dark_oak_stairs";
        MinecraftBlockTypes2["DarkOakTrapdoor"] = "minecraft:dark_oak_trapdoor";
        MinecraftBlockTypes2["DarkOakWood"] = "minecraft:dark_oak_wood";
        MinecraftBlockTypes2["DarkPrismarine"] = "minecraft:dark_prismarine";
        MinecraftBlockTypes2["DarkPrismarineDoubleSlab"] = "minecraft:dark_prismarine_double_slab";
        MinecraftBlockTypes2["DarkPrismarineSlab"] = "minecraft:dark_prismarine_slab";
        MinecraftBlockTypes2["DarkPrismarineStairs"] = "minecraft:dark_prismarine_stairs";
        MinecraftBlockTypes2["DarkoakStandingSign"] = "minecraft:darkoak_standing_sign";
        MinecraftBlockTypes2["DarkoakWallSign"] = "minecraft:darkoak_wall_sign";
        MinecraftBlockTypes2["DaylightDetector"] = "minecraft:daylight_detector";
        MinecraftBlockTypes2["DaylightDetectorInverted"] = "minecraft:daylight_detector_inverted";
        MinecraftBlockTypes2["DeadBrainCoral"] = "minecraft:dead_brain_coral";
        MinecraftBlockTypes2["DeadBrainCoralBlock"] = "minecraft:dead_brain_coral_block";
        MinecraftBlockTypes2["DeadBrainCoralFan"] = "minecraft:dead_brain_coral_fan";
        MinecraftBlockTypes2["DeadBrainCoralWallFan"] = "minecraft:dead_brain_coral_wall_fan";
        MinecraftBlockTypes2["DeadBubbleCoral"] = "minecraft:dead_bubble_coral";
        MinecraftBlockTypes2["DeadBubbleCoralBlock"] = "minecraft:dead_bubble_coral_block";
        MinecraftBlockTypes2["DeadBubbleCoralFan"] = "minecraft:dead_bubble_coral_fan";
        MinecraftBlockTypes2["DeadBubbleCoralWallFan"] = "minecraft:dead_bubble_coral_wall_fan";
        MinecraftBlockTypes2["DeadFireCoral"] = "minecraft:dead_fire_coral";
        MinecraftBlockTypes2["DeadFireCoralBlock"] = "minecraft:dead_fire_coral_block";
        MinecraftBlockTypes2["DeadFireCoralFan"] = "minecraft:dead_fire_coral_fan";
        MinecraftBlockTypes2["DeadFireCoralWallFan"] = "minecraft:dead_fire_coral_wall_fan";
        MinecraftBlockTypes2["DeadHornCoral"] = "minecraft:dead_horn_coral";
        MinecraftBlockTypes2["DeadHornCoralBlock"] = "minecraft:dead_horn_coral_block";
        MinecraftBlockTypes2["DeadHornCoralFan"] = "minecraft:dead_horn_coral_fan";
        MinecraftBlockTypes2["DeadHornCoralWallFan"] = "minecraft:dead_horn_coral_wall_fan";
        MinecraftBlockTypes2["DeadTubeCoral"] = "minecraft:dead_tube_coral";
        MinecraftBlockTypes2["DeadTubeCoralBlock"] = "minecraft:dead_tube_coral_block";
        MinecraftBlockTypes2["DeadTubeCoralFan"] = "minecraft:dead_tube_coral_fan";
        MinecraftBlockTypes2["DeadTubeCoralWallFan"] = "minecraft:dead_tube_coral_wall_fan";
        MinecraftBlockTypes2["Deadbush"] = "minecraft:deadbush";
        MinecraftBlockTypes2["DecoratedPot"] = "minecraft:decorated_pot";
        MinecraftBlockTypes2["Deepslate"] = "minecraft:deepslate";
        MinecraftBlockTypes2["DeepslateBrickDoubleSlab"] = "minecraft:deepslate_brick_double_slab";
        MinecraftBlockTypes2["DeepslateBrickSlab"] = "minecraft:deepslate_brick_slab";
        MinecraftBlockTypes2["DeepslateBrickStairs"] = "minecraft:deepslate_brick_stairs";
        MinecraftBlockTypes2["DeepslateBrickWall"] = "minecraft:deepslate_brick_wall";
        MinecraftBlockTypes2["DeepslateBricks"] = "minecraft:deepslate_bricks";
        MinecraftBlockTypes2["DeepslateCoalOre"] = "minecraft:deepslate_coal_ore";
        MinecraftBlockTypes2["DeepslateCopperOre"] = "minecraft:deepslate_copper_ore";
        MinecraftBlockTypes2["DeepslateDiamondOre"] = "minecraft:deepslate_diamond_ore";
        MinecraftBlockTypes2["DeepslateEmeraldOre"] = "minecraft:deepslate_emerald_ore";
        MinecraftBlockTypes2["DeepslateGoldOre"] = "minecraft:deepslate_gold_ore";
        MinecraftBlockTypes2["DeepslateIronOre"] = "minecraft:deepslate_iron_ore";
        MinecraftBlockTypes2["DeepslateLapisOre"] = "minecraft:deepslate_lapis_ore";
        MinecraftBlockTypes2["DeepslateRedstoneOre"] = "minecraft:deepslate_redstone_ore";
        MinecraftBlockTypes2["DeepslateTileDoubleSlab"] = "minecraft:deepslate_tile_double_slab";
        MinecraftBlockTypes2["DeepslateTileSlab"] = "minecraft:deepslate_tile_slab";
        MinecraftBlockTypes2["DeepslateTileStairs"] = "minecraft:deepslate_tile_stairs";
        MinecraftBlockTypes2["DeepslateTileWall"] = "minecraft:deepslate_tile_wall";
        MinecraftBlockTypes2["DeepslateTiles"] = "minecraft:deepslate_tiles";
        MinecraftBlockTypes2["Deny"] = "minecraft:deny";
        MinecraftBlockTypes2["DetectorRail"] = "minecraft:detector_rail";
        MinecraftBlockTypes2["DiamondBlock"] = "minecraft:diamond_block";
        MinecraftBlockTypes2["DiamondOre"] = "minecraft:diamond_ore";
        MinecraftBlockTypes2["Diorite"] = "minecraft:diorite";
        MinecraftBlockTypes2["DioriteDoubleSlab"] = "minecraft:diorite_double_slab";
        MinecraftBlockTypes2["DioriteSlab"] = "minecraft:diorite_slab";
        MinecraftBlockTypes2["DioriteStairs"] = "minecraft:diorite_stairs";
        MinecraftBlockTypes2["DioriteWall"] = "minecraft:diorite_wall";
        MinecraftBlockTypes2["Dirt"] = "minecraft:dirt";
        MinecraftBlockTypes2["DirtWithRoots"] = "minecraft:dirt_with_roots";
        MinecraftBlockTypes2["Dispenser"] = "minecraft:dispenser";
        MinecraftBlockTypes2["DoubleCutCopperSlab"] = "minecraft:double_cut_copper_slab";
        MinecraftBlockTypes2["DragonEgg"] = "minecraft:dragon_egg";
        MinecraftBlockTypes2["DragonHead"] = "minecraft:dragon_head";
        MinecraftBlockTypes2["DriedGhast"] = "minecraft:dried_ghast";
        MinecraftBlockTypes2["DriedKelpBlock"] = "minecraft:dried_kelp_block";
        MinecraftBlockTypes2["DripstoneBlock"] = "minecraft:dripstone_block";
        MinecraftBlockTypes2["Dropper"] = "minecraft:dropper";
        MinecraftBlockTypes2["Element0"] = "minecraft:element_0";
        MinecraftBlockTypes2["Element1"] = "minecraft:element_1";
        MinecraftBlockTypes2["Element10"] = "minecraft:element_10";
        MinecraftBlockTypes2["Element100"] = "minecraft:element_100";
        MinecraftBlockTypes2["Element101"] = "minecraft:element_101";
        MinecraftBlockTypes2["Element102"] = "minecraft:element_102";
        MinecraftBlockTypes2["Element103"] = "minecraft:element_103";
        MinecraftBlockTypes2["Element104"] = "minecraft:element_104";
        MinecraftBlockTypes2["Element105"] = "minecraft:element_105";
        MinecraftBlockTypes2["Element106"] = "minecraft:element_106";
        MinecraftBlockTypes2["Element107"] = "minecraft:element_107";
        MinecraftBlockTypes2["Element108"] = "minecraft:element_108";
        MinecraftBlockTypes2["Element109"] = "minecraft:element_109";
        MinecraftBlockTypes2["Element11"] = "minecraft:element_11";
        MinecraftBlockTypes2["Element110"] = "minecraft:element_110";
        MinecraftBlockTypes2["Element111"] = "minecraft:element_111";
        MinecraftBlockTypes2["Element112"] = "minecraft:element_112";
        MinecraftBlockTypes2["Element113"] = "minecraft:element_113";
        MinecraftBlockTypes2["Element114"] = "minecraft:element_114";
        MinecraftBlockTypes2["Element115"] = "minecraft:element_115";
        MinecraftBlockTypes2["Element116"] = "minecraft:element_116";
        MinecraftBlockTypes2["Element117"] = "minecraft:element_117";
        MinecraftBlockTypes2["Element118"] = "minecraft:element_118";
        MinecraftBlockTypes2["Element12"] = "minecraft:element_12";
        MinecraftBlockTypes2["Element13"] = "minecraft:element_13";
        MinecraftBlockTypes2["Element14"] = "minecraft:element_14";
        MinecraftBlockTypes2["Element15"] = "minecraft:element_15";
        MinecraftBlockTypes2["Element16"] = "minecraft:element_16";
        MinecraftBlockTypes2["Element17"] = "minecraft:element_17";
        MinecraftBlockTypes2["Element18"] = "minecraft:element_18";
        MinecraftBlockTypes2["Element19"] = "minecraft:element_19";
        MinecraftBlockTypes2["Element2"] = "minecraft:element_2";
        MinecraftBlockTypes2["Element20"] = "minecraft:element_20";
        MinecraftBlockTypes2["Element21"] = "minecraft:element_21";
        MinecraftBlockTypes2["Element22"] = "minecraft:element_22";
        MinecraftBlockTypes2["Element23"] = "minecraft:element_23";
        MinecraftBlockTypes2["Element24"] = "minecraft:element_24";
        MinecraftBlockTypes2["Element25"] = "minecraft:element_25";
        MinecraftBlockTypes2["Element26"] = "minecraft:element_26";
        MinecraftBlockTypes2["Element27"] = "minecraft:element_27";
        MinecraftBlockTypes2["Element28"] = "minecraft:element_28";
        MinecraftBlockTypes2["Element29"] = "minecraft:element_29";
        MinecraftBlockTypes2["Element3"] = "minecraft:element_3";
        MinecraftBlockTypes2["Element30"] = "minecraft:element_30";
        MinecraftBlockTypes2["Element31"] = "minecraft:element_31";
        MinecraftBlockTypes2["Element32"] = "minecraft:element_32";
        MinecraftBlockTypes2["Element33"] = "minecraft:element_33";
        MinecraftBlockTypes2["Element34"] = "minecraft:element_34";
        MinecraftBlockTypes2["Element35"] = "minecraft:element_35";
        MinecraftBlockTypes2["Element36"] = "minecraft:element_36";
        MinecraftBlockTypes2["Element37"] = "minecraft:element_37";
        MinecraftBlockTypes2["Element38"] = "minecraft:element_38";
        MinecraftBlockTypes2["Element39"] = "minecraft:element_39";
        MinecraftBlockTypes2["Element4"] = "minecraft:element_4";
        MinecraftBlockTypes2["Element40"] = "minecraft:element_40";
        MinecraftBlockTypes2["Element41"] = "minecraft:element_41";
        MinecraftBlockTypes2["Element42"] = "minecraft:element_42";
        MinecraftBlockTypes2["Element43"] = "minecraft:element_43";
        MinecraftBlockTypes2["Element44"] = "minecraft:element_44";
        MinecraftBlockTypes2["Element45"] = "minecraft:element_45";
        MinecraftBlockTypes2["Element46"] = "minecraft:element_46";
        MinecraftBlockTypes2["Element47"] = "minecraft:element_47";
        MinecraftBlockTypes2["Element48"] = "minecraft:element_48";
        MinecraftBlockTypes2["Element49"] = "minecraft:element_49";
        MinecraftBlockTypes2["Element5"] = "minecraft:element_5";
        MinecraftBlockTypes2["Element50"] = "minecraft:element_50";
        MinecraftBlockTypes2["Element51"] = "minecraft:element_51";
        MinecraftBlockTypes2["Element52"] = "minecraft:element_52";
        MinecraftBlockTypes2["Element53"] = "minecraft:element_53";
        MinecraftBlockTypes2["Element54"] = "minecraft:element_54";
        MinecraftBlockTypes2["Element55"] = "minecraft:element_55";
        MinecraftBlockTypes2["Element56"] = "minecraft:element_56";
        MinecraftBlockTypes2["Element57"] = "minecraft:element_57";
        MinecraftBlockTypes2["Element58"] = "minecraft:element_58";
        MinecraftBlockTypes2["Element59"] = "minecraft:element_59";
        MinecraftBlockTypes2["Element6"] = "minecraft:element_6";
        MinecraftBlockTypes2["Element60"] = "minecraft:element_60";
        MinecraftBlockTypes2["Element61"] = "minecraft:element_61";
        MinecraftBlockTypes2["Element62"] = "minecraft:element_62";
        MinecraftBlockTypes2["Element63"] = "minecraft:element_63";
        MinecraftBlockTypes2["Element64"] = "minecraft:element_64";
        MinecraftBlockTypes2["Element65"] = "minecraft:element_65";
        MinecraftBlockTypes2["Element66"] = "minecraft:element_66";
        MinecraftBlockTypes2["Element67"] = "minecraft:element_67";
        MinecraftBlockTypes2["Element68"] = "minecraft:element_68";
        MinecraftBlockTypes2["Element69"] = "minecraft:element_69";
        MinecraftBlockTypes2["Element7"] = "minecraft:element_7";
        MinecraftBlockTypes2["Element70"] = "minecraft:element_70";
        MinecraftBlockTypes2["Element71"] = "minecraft:element_71";
        MinecraftBlockTypes2["Element72"] = "minecraft:element_72";
        MinecraftBlockTypes2["Element73"] = "minecraft:element_73";
        MinecraftBlockTypes2["Element74"] = "minecraft:element_74";
        MinecraftBlockTypes2["Element75"] = "minecraft:element_75";
        MinecraftBlockTypes2["Element76"] = "minecraft:element_76";
        MinecraftBlockTypes2["Element77"] = "minecraft:element_77";
        MinecraftBlockTypes2["Element78"] = "minecraft:element_78";
        MinecraftBlockTypes2["Element79"] = "minecraft:element_79";
        MinecraftBlockTypes2["Element8"] = "minecraft:element_8";
        MinecraftBlockTypes2["Element80"] = "minecraft:element_80";
        MinecraftBlockTypes2["Element81"] = "minecraft:element_81";
        MinecraftBlockTypes2["Element82"] = "minecraft:element_82";
        MinecraftBlockTypes2["Element83"] = "minecraft:element_83";
        MinecraftBlockTypes2["Element84"] = "minecraft:element_84";
        MinecraftBlockTypes2["Element85"] = "minecraft:element_85";
        MinecraftBlockTypes2["Element86"] = "minecraft:element_86";
        MinecraftBlockTypes2["Element87"] = "minecraft:element_87";
        MinecraftBlockTypes2["Element88"] = "minecraft:element_88";
        MinecraftBlockTypes2["Element89"] = "minecraft:element_89";
        MinecraftBlockTypes2["Element9"] = "minecraft:element_9";
        MinecraftBlockTypes2["Element90"] = "minecraft:element_90";
        MinecraftBlockTypes2["Element91"] = "minecraft:element_91";
        MinecraftBlockTypes2["Element92"] = "minecraft:element_92";
        MinecraftBlockTypes2["Element93"] = "minecraft:element_93";
        MinecraftBlockTypes2["Element94"] = "minecraft:element_94";
        MinecraftBlockTypes2["Element95"] = "minecraft:element_95";
        MinecraftBlockTypes2["Element96"] = "minecraft:element_96";
        MinecraftBlockTypes2["Element97"] = "minecraft:element_97";
        MinecraftBlockTypes2["Element98"] = "minecraft:element_98";
        MinecraftBlockTypes2["Element99"] = "minecraft:element_99";
        MinecraftBlockTypes2["ElementConstructor"] = "minecraft:element_constructor";
        MinecraftBlockTypes2["EmeraldBlock"] = "minecraft:emerald_block";
        MinecraftBlockTypes2["EmeraldOre"] = "minecraft:emerald_ore";
        MinecraftBlockTypes2["EnchantingTable"] = "minecraft:enchanting_table";
        MinecraftBlockTypes2["EndBrickStairs"] = "minecraft:end_brick_stairs";
        MinecraftBlockTypes2["EndBricks"] = "minecraft:end_bricks";
        MinecraftBlockTypes2["EndPortal"] = "minecraft:end_portal";
        MinecraftBlockTypes2["EndPortalFrame"] = "minecraft:end_portal_frame";
        MinecraftBlockTypes2["EndRod"] = "minecraft:end_rod";
        MinecraftBlockTypes2["EndStone"] = "minecraft:end_stone";
        MinecraftBlockTypes2["EndStoneBrickDoubleSlab"] = "minecraft:end_stone_brick_double_slab";
        MinecraftBlockTypes2["EndStoneBrickSlab"] = "minecraft:end_stone_brick_slab";
        MinecraftBlockTypes2["EndStoneBrickWall"] = "minecraft:end_stone_brick_wall";
        MinecraftBlockTypes2["EnderChest"] = "minecraft:ender_chest";
        MinecraftBlockTypes2["ExposedChiseledCopper"] = "minecraft:exposed_chiseled_copper";
        MinecraftBlockTypes2["ExposedCopper"] = "minecraft:exposed_copper";
        MinecraftBlockTypes2["ExposedCopperBars"] = "minecraft:exposed_copper_bars";
        MinecraftBlockTypes2["ExposedCopperBulb"] = "minecraft:exposed_copper_bulb";
        MinecraftBlockTypes2["ExposedCopperChain"] = "minecraft:exposed_copper_chain";
        MinecraftBlockTypes2["ExposedCopperChest"] = "minecraft:exposed_copper_chest";
        MinecraftBlockTypes2["ExposedCopperDoor"] = "minecraft:exposed_copper_door";
        MinecraftBlockTypes2["ExposedCopperGolemStatue"] = "minecraft:exposed_copper_golem_statue";
        MinecraftBlockTypes2["ExposedCopperGrate"] = "minecraft:exposed_copper_grate";
        MinecraftBlockTypes2["ExposedCopperLantern"] = "minecraft:exposed_copper_lantern";
        MinecraftBlockTypes2["ExposedCopperTrapdoor"] = "minecraft:exposed_copper_trapdoor";
        MinecraftBlockTypes2["ExposedCutCopper"] = "minecraft:exposed_cut_copper";
        MinecraftBlockTypes2["ExposedCutCopperSlab"] = "minecraft:exposed_cut_copper_slab";
        MinecraftBlockTypes2["ExposedCutCopperStairs"] = "minecraft:exposed_cut_copper_stairs";
        MinecraftBlockTypes2["ExposedDoubleCutCopperSlab"] = "minecraft:exposed_double_cut_copper_slab";
        MinecraftBlockTypes2["ExposedLightningRod"] = "minecraft:exposed_lightning_rod";
        MinecraftBlockTypes2["Farmland"] = "minecraft:farmland";
        MinecraftBlockTypes2["FenceGate"] = "minecraft:fence_gate";
        MinecraftBlockTypes2["Fern"] = "minecraft:fern";
        MinecraftBlockTypes2["Fire"] = "minecraft:fire";
        MinecraftBlockTypes2["FireCoral"] = "minecraft:fire_coral";
        MinecraftBlockTypes2["FireCoralBlock"] = "minecraft:fire_coral_block";
        MinecraftBlockTypes2["FireCoralFan"] = "minecraft:fire_coral_fan";
        MinecraftBlockTypes2["FireCoralWallFan"] = "minecraft:fire_coral_wall_fan";
        MinecraftBlockTypes2["FireflyBush"] = "minecraft:firefly_bush";
        MinecraftBlockTypes2["FletchingTable"] = "minecraft:fletching_table";
        MinecraftBlockTypes2["FlowerPot"] = "minecraft:flower_pot";
        MinecraftBlockTypes2["FloweringAzalea"] = "minecraft:flowering_azalea";
        MinecraftBlockTypes2["FlowingLava"] = "minecraft:flowing_lava";
        MinecraftBlockTypes2["FlowingWater"] = "minecraft:flowing_water";
        MinecraftBlockTypes2["Frame"] = "minecraft:frame";
        MinecraftBlockTypes2["FrogSpawn"] = "minecraft:frog_spawn";
        MinecraftBlockTypes2["FrostedIce"] = "minecraft:frosted_ice";
        MinecraftBlockTypes2["Furnace"] = "minecraft:furnace";
        MinecraftBlockTypes2["GildedBlackstone"] = "minecraft:gilded_blackstone";
        MinecraftBlockTypes2["Glass"] = "minecraft:glass";
        MinecraftBlockTypes2["GlassPane"] = "minecraft:glass_pane";
        MinecraftBlockTypes2["GlowFrame"] = "minecraft:glow_frame";
        MinecraftBlockTypes2["GlowLichen"] = "minecraft:glow_lichen";
        MinecraftBlockTypes2["Glowstone"] = "minecraft:glowstone";
        MinecraftBlockTypes2["GoldBlock"] = "minecraft:gold_block";
        MinecraftBlockTypes2["GoldOre"] = "minecraft:gold_ore";
        MinecraftBlockTypes2["GoldenRail"] = "minecraft:golden_rail";
        MinecraftBlockTypes2["Granite"] = "minecraft:granite";
        MinecraftBlockTypes2["GraniteDoubleSlab"] = "minecraft:granite_double_slab";
        MinecraftBlockTypes2["GraniteSlab"] = "minecraft:granite_slab";
        MinecraftBlockTypes2["GraniteStairs"] = "minecraft:granite_stairs";
        MinecraftBlockTypes2["GraniteWall"] = "minecraft:granite_wall";
        MinecraftBlockTypes2["GrassBlock"] = "minecraft:grass_block";
        MinecraftBlockTypes2["GrassPath"] = "minecraft:grass_path";
        MinecraftBlockTypes2["Gravel"] = "minecraft:gravel";
        MinecraftBlockTypes2["GrayCandle"] = "minecraft:gray_candle";
        MinecraftBlockTypes2["GrayCandleCake"] = "minecraft:gray_candle_cake";
        MinecraftBlockTypes2["GrayCarpet"] = "minecraft:gray_carpet";
        MinecraftBlockTypes2["GrayConcrete"] = "minecraft:gray_concrete";
        MinecraftBlockTypes2["GrayConcretePowder"] = "minecraft:gray_concrete_powder";
        MinecraftBlockTypes2["GrayGlazedTerracotta"] = "minecraft:gray_glazed_terracotta";
        MinecraftBlockTypes2["GrayShulkerBox"] = "minecraft:gray_shulker_box";
        MinecraftBlockTypes2["GrayStainedGlass"] = "minecraft:gray_stained_glass";
        MinecraftBlockTypes2["GrayStainedGlassPane"] = "minecraft:gray_stained_glass_pane";
        MinecraftBlockTypes2["GrayTerracotta"] = "minecraft:gray_terracotta";
        MinecraftBlockTypes2["GrayWool"] = "minecraft:gray_wool";
        MinecraftBlockTypes2["GreenCandle"] = "minecraft:green_candle";
        MinecraftBlockTypes2["GreenCandleCake"] = "minecraft:green_candle_cake";
        MinecraftBlockTypes2["GreenCarpet"] = "minecraft:green_carpet";
        MinecraftBlockTypes2["GreenConcrete"] = "minecraft:green_concrete";
        MinecraftBlockTypes2["GreenConcretePowder"] = "minecraft:green_concrete_powder";
        MinecraftBlockTypes2["GreenGlazedTerracotta"] = "minecraft:green_glazed_terracotta";
        MinecraftBlockTypes2["GreenShulkerBox"] = "minecraft:green_shulker_box";
        MinecraftBlockTypes2["GreenStainedGlass"] = "minecraft:green_stained_glass";
        MinecraftBlockTypes2["GreenStainedGlassPane"] = "minecraft:green_stained_glass_pane";
        MinecraftBlockTypes2["GreenTerracotta"] = "minecraft:green_terracotta";
        MinecraftBlockTypes2["GreenWool"] = "minecraft:green_wool";
        MinecraftBlockTypes2["Grindstone"] = "minecraft:grindstone";
        MinecraftBlockTypes2["HangingRoots"] = "minecraft:hanging_roots";
        MinecraftBlockTypes2["HardBlackStainedGlass"] = "minecraft:hard_black_stained_glass";
        MinecraftBlockTypes2["HardBlackStainedGlassPane"] = "minecraft:hard_black_stained_glass_pane";
        MinecraftBlockTypes2["HardBlueStainedGlass"] = "minecraft:hard_blue_stained_glass";
        MinecraftBlockTypes2["HardBlueStainedGlassPane"] = "minecraft:hard_blue_stained_glass_pane";
        MinecraftBlockTypes2["HardBrownStainedGlass"] = "minecraft:hard_brown_stained_glass";
        MinecraftBlockTypes2["HardBrownStainedGlassPane"] = "minecraft:hard_brown_stained_glass_pane";
        MinecraftBlockTypes2["HardCyanStainedGlass"] = "minecraft:hard_cyan_stained_glass";
        MinecraftBlockTypes2["HardCyanStainedGlassPane"] = "minecraft:hard_cyan_stained_glass_pane";
        MinecraftBlockTypes2["HardGlass"] = "minecraft:hard_glass";
        MinecraftBlockTypes2["HardGlassPane"] = "minecraft:hard_glass_pane";
        MinecraftBlockTypes2["HardGrayStainedGlass"] = "minecraft:hard_gray_stained_glass";
        MinecraftBlockTypes2["HardGrayStainedGlassPane"] = "minecraft:hard_gray_stained_glass_pane";
        MinecraftBlockTypes2["HardGreenStainedGlass"] = "minecraft:hard_green_stained_glass";
        MinecraftBlockTypes2["HardGreenStainedGlassPane"] = "minecraft:hard_green_stained_glass_pane";
        MinecraftBlockTypes2["HardLightBlueStainedGlass"] = "minecraft:hard_light_blue_stained_glass";
        MinecraftBlockTypes2["HardLightBlueStainedGlassPane"] = "minecraft:hard_light_blue_stained_glass_pane";
        MinecraftBlockTypes2["HardLightGrayStainedGlass"] = "minecraft:hard_light_gray_stained_glass";
        MinecraftBlockTypes2["HardLightGrayStainedGlassPane"] = "minecraft:hard_light_gray_stained_glass_pane";
        MinecraftBlockTypes2["HardLimeStainedGlass"] = "minecraft:hard_lime_stained_glass";
        MinecraftBlockTypes2["HardLimeStainedGlassPane"] = "minecraft:hard_lime_stained_glass_pane";
        MinecraftBlockTypes2["HardMagentaStainedGlass"] = "minecraft:hard_magenta_stained_glass";
        MinecraftBlockTypes2["HardMagentaStainedGlassPane"] = "minecraft:hard_magenta_stained_glass_pane";
        MinecraftBlockTypes2["HardOrangeStainedGlass"] = "minecraft:hard_orange_stained_glass";
        MinecraftBlockTypes2["HardOrangeStainedGlassPane"] = "minecraft:hard_orange_stained_glass_pane";
        MinecraftBlockTypes2["HardPinkStainedGlass"] = "minecraft:hard_pink_stained_glass";
        MinecraftBlockTypes2["HardPinkStainedGlassPane"] = "minecraft:hard_pink_stained_glass_pane";
        MinecraftBlockTypes2["HardPurpleStainedGlass"] = "minecraft:hard_purple_stained_glass";
        MinecraftBlockTypes2["HardPurpleStainedGlassPane"] = "minecraft:hard_purple_stained_glass_pane";
        MinecraftBlockTypes2["HardRedStainedGlass"] = "minecraft:hard_red_stained_glass";
        MinecraftBlockTypes2["HardRedStainedGlassPane"] = "minecraft:hard_red_stained_glass_pane";
        MinecraftBlockTypes2["HardWhiteStainedGlass"] = "minecraft:hard_white_stained_glass";
        MinecraftBlockTypes2["HardWhiteStainedGlassPane"] = "minecraft:hard_white_stained_glass_pane";
        MinecraftBlockTypes2["HardYellowStainedGlass"] = "minecraft:hard_yellow_stained_glass";
        MinecraftBlockTypes2["HardYellowStainedGlassPane"] = "minecraft:hard_yellow_stained_glass_pane";
        MinecraftBlockTypes2["HardenedClay"] = "minecraft:hardened_clay";
        MinecraftBlockTypes2["HayBlock"] = "minecraft:hay_block";
        MinecraftBlockTypes2["HeavyCore"] = "minecraft:heavy_core";
        MinecraftBlockTypes2["HeavyWeightedPressurePlate"] = "minecraft:heavy_weighted_pressure_plate";
        MinecraftBlockTypes2["HoneyBlock"] = "minecraft:honey_block";
        MinecraftBlockTypes2["HoneycombBlock"] = "minecraft:honeycomb_block";
        MinecraftBlockTypes2["Hopper"] = "minecraft:hopper";
        MinecraftBlockTypes2["HornCoral"] = "minecraft:horn_coral";
        MinecraftBlockTypes2["HornCoralBlock"] = "minecraft:horn_coral_block";
        MinecraftBlockTypes2["HornCoralFan"] = "minecraft:horn_coral_fan";
        MinecraftBlockTypes2["HornCoralWallFan"] = "minecraft:horn_coral_wall_fan";
        MinecraftBlockTypes2["Ice"] = "minecraft:ice";
        MinecraftBlockTypes2["InfestedChiseledStoneBricks"] = "minecraft:infested_chiseled_stone_bricks";
        MinecraftBlockTypes2["InfestedCobblestone"] = "minecraft:infested_cobblestone";
        MinecraftBlockTypes2["InfestedCrackedStoneBricks"] = "minecraft:infested_cracked_stone_bricks";
        MinecraftBlockTypes2["InfestedDeepslate"] = "minecraft:infested_deepslate";
        MinecraftBlockTypes2["InfestedMossyStoneBricks"] = "minecraft:infested_mossy_stone_bricks";
        MinecraftBlockTypes2["InfestedStone"] = "minecraft:infested_stone";
        MinecraftBlockTypes2["InfestedStoneBricks"] = "minecraft:infested_stone_bricks";
        MinecraftBlockTypes2["IronBars"] = "minecraft:iron_bars";
        MinecraftBlockTypes2["IronBlock"] = "minecraft:iron_block";
        MinecraftBlockTypes2["IronChain"] = "minecraft:iron_chain";
        MinecraftBlockTypes2["IronDoor"] = "minecraft:iron_door";
        MinecraftBlockTypes2["IronOre"] = "minecraft:iron_ore";
        MinecraftBlockTypes2["IronTrapdoor"] = "minecraft:iron_trapdoor";
        MinecraftBlockTypes2["Jigsaw"] = "minecraft:jigsaw";
        MinecraftBlockTypes2["Jukebox"] = "minecraft:jukebox";
        MinecraftBlockTypes2["JungleButton"] = "minecraft:jungle_button";
        MinecraftBlockTypes2["JungleDoor"] = "minecraft:jungle_door";
        MinecraftBlockTypes2["JungleDoubleSlab"] = "minecraft:jungle_double_slab";
        MinecraftBlockTypes2["JungleFence"] = "minecraft:jungle_fence";
        MinecraftBlockTypes2["JungleFenceGate"] = "minecraft:jungle_fence_gate";
        MinecraftBlockTypes2["JungleHangingSign"] = "minecraft:jungle_hanging_sign";
        MinecraftBlockTypes2["JungleLeaves"] = "minecraft:jungle_leaves";
        MinecraftBlockTypes2["JungleLog"] = "minecraft:jungle_log";
        MinecraftBlockTypes2["JunglePlanks"] = "minecraft:jungle_planks";
        MinecraftBlockTypes2["JunglePressurePlate"] = "minecraft:jungle_pressure_plate";
        MinecraftBlockTypes2["JungleSapling"] = "minecraft:jungle_sapling";
        MinecraftBlockTypes2["JungleShelf"] = "minecraft:jungle_shelf";
        MinecraftBlockTypes2["JungleSlab"] = "minecraft:jungle_slab";
        MinecraftBlockTypes2["JungleStairs"] = "minecraft:jungle_stairs";
        MinecraftBlockTypes2["JungleStandingSign"] = "minecraft:jungle_standing_sign";
        MinecraftBlockTypes2["JungleTrapdoor"] = "minecraft:jungle_trapdoor";
        MinecraftBlockTypes2["JungleWallSign"] = "minecraft:jungle_wall_sign";
        MinecraftBlockTypes2["JungleWood"] = "minecraft:jungle_wood";
        MinecraftBlockTypes2["Kelp"] = "minecraft:kelp";
        MinecraftBlockTypes2["LabTable"] = "minecraft:lab_table";
        MinecraftBlockTypes2["Ladder"] = "minecraft:ladder";
        MinecraftBlockTypes2["Lantern"] = "minecraft:lantern";
        MinecraftBlockTypes2["LapisBlock"] = "minecraft:lapis_block";
        MinecraftBlockTypes2["LapisOre"] = "minecraft:lapis_ore";
        MinecraftBlockTypes2["LargeAmethystBud"] = "minecraft:large_amethyst_bud";
        MinecraftBlockTypes2["LargeFern"] = "minecraft:large_fern";
        MinecraftBlockTypes2["Lava"] = "minecraft:lava";
        MinecraftBlockTypes2["LeafLitter"] = "minecraft:leaf_litter";
        MinecraftBlockTypes2["Lectern"] = "minecraft:lectern";
        MinecraftBlockTypes2["Lever"] = "minecraft:lever";
        MinecraftBlockTypes2["LightBlock0"] = "minecraft:light_block_0";
        MinecraftBlockTypes2["LightBlock1"] = "minecraft:light_block_1";
        MinecraftBlockTypes2["LightBlock10"] = "minecraft:light_block_10";
        MinecraftBlockTypes2["LightBlock11"] = "minecraft:light_block_11";
        MinecraftBlockTypes2["LightBlock12"] = "minecraft:light_block_12";
        MinecraftBlockTypes2["LightBlock13"] = "minecraft:light_block_13";
        MinecraftBlockTypes2["LightBlock14"] = "minecraft:light_block_14";
        MinecraftBlockTypes2["LightBlock15"] = "minecraft:light_block_15";
        MinecraftBlockTypes2["LightBlock2"] = "minecraft:light_block_2";
        MinecraftBlockTypes2["LightBlock3"] = "minecraft:light_block_3";
        MinecraftBlockTypes2["LightBlock4"] = "minecraft:light_block_4";
        MinecraftBlockTypes2["LightBlock5"] = "minecraft:light_block_5";
        MinecraftBlockTypes2["LightBlock6"] = "minecraft:light_block_6";
        MinecraftBlockTypes2["LightBlock7"] = "minecraft:light_block_7";
        MinecraftBlockTypes2["LightBlock8"] = "minecraft:light_block_8";
        MinecraftBlockTypes2["LightBlock9"] = "minecraft:light_block_9";
        MinecraftBlockTypes2["LightBlueCandle"] = "minecraft:light_blue_candle";
        MinecraftBlockTypes2["LightBlueCandleCake"] = "minecraft:light_blue_candle_cake";
        MinecraftBlockTypes2["LightBlueCarpet"] = "minecraft:light_blue_carpet";
        MinecraftBlockTypes2["LightBlueConcrete"] = "minecraft:light_blue_concrete";
        MinecraftBlockTypes2["LightBlueConcretePowder"] = "minecraft:light_blue_concrete_powder";
        MinecraftBlockTypes2["LightBlueGlazedTerracotta"] = "minecraft:light_blue_glazed_terracotta";
        MinecraftBlockTypes2["LightBlueShulkerBox"] = "minecraft:light_blue_shulker_box";
        MinecraftBlockTypes2["LightBlueStainedGlass"] = "minecraft:light_blue_stained_glass";
        MinecraftBlockTypes2["LightBlueStainedGlassPane"] = "minecraft:light_blue_stained_glass_pane";
        MinecraftBlockTypes2["LightBlueTerracotta"] = "minecraft:light_blue_terracotta";
        MinecraftBlockTypes2["LightBlueWool"] = "minecraft:light_blue_wool";
        MinecraftBlockTypes2["LightGrayCandle"] = "minecraft:light_gray_candle";
        MinecraftBlockTypes2["LightGrayCandleCake"] = "minecraft:light_gray_candle_cake";
        MinecraftBlockTypes2["LightGrayCarpet"] = "minecraft:light_gray_carpet";
        MinecraftBlockTypes2["LightGrayConcrete"] = "minecraft:light_gray_concrete";
        MinecraftBlockTypes2["LightGrayConcretePowder"] = "minecraft:light_gray_concrete_powder";
        MinecraftBlockTypes2["LightGrayShulkerBox"] = "minecraft:light_gray_shulker_box";
        MinecraftBlockTypes2["LightGrayStainedGlass"] = "minecraft:light_gray_stained_glass";
        MinecraftBlockTypes2["LightGrayStainedGlassPane"] = "minecraft:light_gray_stained_glass_pane";
        MinecraftBlockTypes2["LightGrayTerracotta"] = "minecraft:light_gray_terracotta";
        MinecraftBlockTypes2["LightGrayWool"] = "minecraft:light_gray_wool";
        MinecraftBlockTypes2["LightWeightedPressurePlate"] = "minecraft:light_weighted_pressure_plate";
        MinecraftBlockTypes2["LightningRod"] = "minecraft:lightning_rod";
        MinecraftBlockTypes2["Lilac"] = "minecraft:lilac";
        MinecraftBlockTypes2["LilyOfTheValley"] = "minecraft:lily_of_the_valley";
        MinecraftBlockTypes2["LimeCandle"] = "minecraft:lime_candle";
        MinecraftBlockTypes2["LimeCandleCake"] = "minecraft:lime_candle_cake";
        MinecraftBlockTypes2["LimeCarpet"] = "minecraft:lime_carpet";
        MinecraftBlockTypes2["LimeConcrete"] = "minecraft:lime_concrete";
        MinecraftBlockTypes2["LimeConcretePowder"] = "minecraft:lime_concrete_powder";
        MinecraftBlockTypes2["LimeGlazedTerracotta"] = "minecraft:lime_glazed_terracotta";
        MinecraftBlockTypes2["LimeShulkerBox"] = "minecraft:lime_shulker_box";
        MinecraftBlockTypes2["LimeStainedGlass"] = "minecraft:lime_stained_glass";
        MinecraftBlockTypes2["LimeStainedGlassPane"] = "minecraft:lime_stained_glass_pane";
        MinecraftBlockTypes2["LimeTerracotta"] = "minecraft:lime_terracotta";
        MinecraftBlockTypes2["LimeWool"] = "minecraft:lime_wool";
        MinecraftBlockTypes2["LitBlastFurnace"] = "minecraft:lit_blast_furnace";
        MinecraftBlockTypes2["LitDeepslateRedstoneOre"] = "minecraft:lit_deepslate_redstone_ore";
        MinecraftBlockTypes2["LitFurnace"] = "minecraft:lit_furnace";
        MinecraftBlockTypes2["LitPumpkin"] = "minecraft:lit_pumpkin";
        MinecraftBlockTypes2["LitRedstoneLamp"] = "minecraft:lit_redstone_lamp";
        MinecraftBlockTypes2["LitRedstoneOre"] = "minecraft:lit_redstone_ore";
        MinecraftBlockTypes2["LitSmoker"] = "minecraft:lit_smoker";
        MinecraftBlockTypes2["Lodestone"] = "minecraft:lodestone";
        MinecraftBlockTypes2["Loom"] = "minecraft:loom";
        MinecraftBlockTypes2["MagentaCandle"] = "minecraft:magenta_candle";
        MinecraftBlockTypes2["MagentaCandleCake"] = "minecraft:magenta_candle_cake";
        MinecraftBlockTypes2["MagentaCarpet"] = "minecraft:magenta_carpet";
        MinecraftBlockTypes2["MagentaConcrete"] = "minecraft:magenta_concrete";
        MinecraftBlockTypes2["MagentaConcretePowder"] = "minecraft:magenta_concrete_powder";
        MinecraftBlockTypes2["MagentaGlazedTerracotta"] = "minecraft:magenta_glazed_terracotta";
        MinecraftBlockTypes2["MagentaShulkerBox"] = "minecraft:magenta_shulker_box";
        MinecraftBlockTypes2["MagentaStainedGlass"] = "minecraft:magenta_stained_glass";
        MinecraftBlockTypes2["MagentaStainedGlassPane"] = "minecraft:magenta_stained_glass_pane";
        MinecraftBlockTypes2["MagentaTerracotta"] = "minecraft:magenta_terracotta";
        MinecraftBlockTypes2["MagentaWool"] = "minecraft:magenta_wool";
        MinecraftBlockTypes2["Magma"] = "minecraft:magma";
        MinecraftBlockTypes2["MangroveButton"] = "minecraft:mangrove_button";
        MinecraftBlockTypes2["MangroveDoor"] = "minecraft:mangrove_door";
        MinecraftBlockTypes2["MangroveDoubleSlab"] = "minecraft:mangrove_double_slab";
        MinecraftBlockTypes2["MangroveFence"] = "minecraft:mangrove_fence";
        MinecraftBlockTypes2["MangroveFenceGate"] = "minecraft:mangrove_fence_gate";
        MinecraftBlockTypes2["MangroveHangingSign"] = "minecraft:mangrove_hanging_sign";
        MinecraftBlockTypes2["MangroveLeaves"] = "minecraft:mangrove_leaves";
        MinecraftBlockTypes2["MangroveLog"] = "minecraft:mangrove_log";
        MinecraftBlockTypes2["MangrovePlanks"] = "minecraft:mangrove_planks";
        MinecraftBlockTypes2["MangrovePressurePlate"] = "minecraft:mangrove_pressure_plate";
        MinecraftBlockTypes2["MangrovePropagule"] = "minecraft:mangrove_propagule";
        MinecraftBlockTypes2["MangroveRoots"] = "minecraft:mangrove_roots";
        MinecraftBlockTypes2["MangroveShelf"] = "minecraft:mangrove_shelf";
        MinecraftBlockTypes2["MangroveSlab"] = "minecraft:mangrove_slab";
        MinecraftBlockTypes2["MangroveStairs"] = "minecraft:mangrove_stairs";
        MinecraftBlockTypes2["MangroveStandingSign"] = "minecraft:mangrove_standing_sign";
        MinecraftBlockTypes2["MangroveTrapdoor"] = "minecraft:mangrove_trapdoor";
        MinecraftBlockTypes2["MangroveWallSign"] = "minecraft:mangrove_wall_sign";
        MinecraftBlockTypes2["MangroveWood"] = "minecraft:mangrove_wood";
        MinecraftBlockTypes2["MaterialReducer"] = "minecraft:material_reducer";
        MinecraftBlockTypes2["MediumAmethystBud"] = "minecraft:medium_amethyst_bud";
        MinecraftBlockTypes2["MelonBlock"] = "minecraft:melon_block";
        MinecraftBlockTypes2["MelonStem"] = "minecraft:melon_stem";
        MinecraftBlockTypes2["MobSpawner"] = "minecraft:mob_spawner";
        MinecraftBlockTypes2["MossBlock"] = "minecraft:moss_block";
        MinecraftBlockTypes2["MossCarpet"] = "minecraft:moss_carpet";
        MinecraftBlockTypes2["MossyCobblestone"] = "minecraft:mossy_cobblestone";
        MinecraftBlockTypes2["MossyCobblestoneDoubleSlab"] = "minecraft:mossy_cobblestone_double_slab";
        MinecraftBlockTypes2["MossyCobblestoneSlab"] = "minecraft:mossy_cobblestone_slab";
        MinecraftBlockTypes2["MossyCobblestoneStairs"] = "minecraft:mossy_cobblestone_stairs";
        MinecraftBlockTypes2["MossyCobblestoneWall"] = "minecraft:mossy_cobblestone_wall";
        MinecraftBlockTypes2["MossyStoneBrickDoubleSlab"] = "minecraft:mossy_stone_brick_double_slab";
        MinecraftBlockTypes2["MossyStoneBrickSlab"] = "minecraft:mossy_stone_brick_slab";
        MinecraftBlockTypes2["MossyStoneBrickStairs"] = "minecraft:mossy_stone_brick_stairs";
        MinecraftBlockTypes2["MossyStoneBrickWall"] = "minecraft:mossy_stone_brick_wall";
        MinecraftBlockTypes2["MossyStoneBricks"] = "minecraft:mossy_stone_bricks";
        MinecraftBlockTypes2["Mud"] = "minecraft:mud";
        MinecraftBlockTypes2["MudBrickDoubleSlab"] = "minecraft:mud_brick_double_slab";
        MinecraftBlockTypes2["MudBrickSlab"] = "minecraft:mud_brick_slab";
        MinecraftBlockTypes2["MudBrickStairs"] = "minecraft:mud_brick_stairs";
        MinecraftBlockTypes2["MudBrickWall"] = "minecraft:mud_brick_wall";
        MinecraftBlockTypes2["MudBricks"] = "minecraft:mud_bricks";
        MinecraftBlockTypes2["MuddyMangroveRoots"] = "minecraft:muddy_mangrove_roots";
        MinecraftBlockTypes2["MushroomStem"] = "minecraft:mushroom_stem";
        MinecraftBlockTypes2["Mycelium"] = "minecraft:mycelium";
        MinecraftBlockTypes2["NetherBrick"] = "minecraft:nether_brick";
        MinecraftBlockTypes2["NetherBrickDoubleSlab"] = "minecraft:nether_brick_double_slab";
        MinecraftBlockTypes2["NetherBrickFence"] = "minecraft:nether_brick_fence";
        MinecraftBlockTypes2["NetherBrickSlab"] = "minecraft:nether_brick_slab";
        MinecraftBlockTypes2["NetherBrickStairs"] = "minecraft:nether_brick_stairs";
        MinecraftBlockTypes2["NetherBrickWall"] = "minecraft:nether_brick_wall";
        MinecraftBlockTypes2["NetherGoldOre"] = "minecraft:nether_gold_ore";
        MinecraftBlockTypes2["NetherSprouts"] = "minecraft:nether_sprouts";
        MinecraftBlockTypes2["NetherWart"] = "minecraft:nether_wart";
        MinecraftBlockTypes2["NetherWartBlock"] = "minecraft:nether_wart_block";
        MinecraftBlockTypes2["NetheriteBlock"] = "minecraft:netherite_block";
        MinecraftBlockTypes2["Netherrack"] = "minecraft:netherrack";
        MinecraftBlockTypes2["NormalStoneDoubleSlab"] = "minecraft:normal_stone_double_slab";
        MinecraftBlockTypes2["NormalStoneSlab"] = "minecraft:normal_stone_slab";
        MinecraftBlockTypes2["NormalStoneStairs"] = "minecraft:normal_stone_stairs";
        MinecraftBlockTypes2["Noteblock"] = "minecraft:noteblock";
        MinecraftBlockTypes2["OakDoubleSlab"] = "minecraft:oak_double_slab";
        MinecraftBlockTypes2["OakFence"] = "minecraft:oak_fence";
        MinecraftBlockTypes2["OakHangingSign"] = "minecraft:oak_hanging_sign";
        MinecraftBlockTypes2["OakLeaves"] = "minecraft:oak_leaves";
        MinecraftBlockTypes2["OakLog"] = "minecraft:oak_log";
        MinecraftBlockTypes2["OakPlanks"] = "minecraft:oak_planks";
        MinecraftBlockTypes2["OakSapling"] = "minecraft:oak_sapling";
        MinecraftBlockTypes2["OakShelf"] = "minecraft:oak_shelf";
        MinecraftBlockTypes2["OakSlab"] = "minecraft:oak_slab";
        MinecraftBlockTypes2["OakStairs"] = "minecraft:oak_stairs";
        MinecraftBlockTypes2["OakWood"] = "minecraft:oak_wood";
        MinecraftBlockTypes2["Observer"] = "minecraft:observer";
        MinecraftBlockTypes2["Obsidian"] = "minecraft:obsidian";
        MinecraftBlockTypes2["OchreFroglight"] = "minecraft:ochre_froglight";
        MinecraftBlockTypes2["OpenEyeblossom"] = "minecraft:open_eyeblossom";
        MinecraftBlockTypes2["OrangeCandle"] = "minecraft:orange_candle";
        MinecraftBlockTypes2["OrangeCandleCake"] = "minecraft:orange_candle_cake";
        MinecraftBlockTypes2["OrangeCarpet"] = "minecraft:orange_carpet";
        MinecraftBlockTypes2["OrangeConcrete"] = "minecraft:orange_concrete";
        MinecraftBlockTypes2["OrangeConcretePowder"] = "minecraft:orange_concrete_powder";
        MinecraftBlockTypes2["OrangeGlazedTerracotta"] = "minecraft:orange_glazed_terracotta";
        MinecraftBlockTypes2["OrangeShulkerBox"] = "minecraft:orange_shulker_box";
        MinecraftBlockTypes2["OrangeStainedGlass"] = "minecraft:orange_stained_glass";
        MinecraftBlockTypes2["OrangeStainedGlassPane"] = "minecraft:orange_stained_glass_pane";
        MinecraftBlockTypes2["OrangeTerracotta"] = "minecraft:orange_terracotta";
        MinecraftBlockTypes2["OrangeTulip"] = "minecraft:orange_tulip";
        MinecraftBlockTypes2["OrangeWool"] = "minecraft:orange_wool";
        MinecraftBlockTypes2["OxeyeDaisy"] = "minecraft:oxeye_daisy";
        MinecraftBlockTypes2["OxidizedChiseledCopper"] = "minecraft:oxidized_chiseled_copper";
        MinecraftBlockTypes2["OxidizedCopper"] = "minecraft:oxidized_copper";
        MinecraftBlockTypes2["OxidizedCopperBars"] = "minecraft:oxidized_copper_bars";
        MinecraftBlockTypes2["OxidizedCopperBulb"] = "minecraft:oxidized_copper_bulb";
        MinecraftBlockTypes2["OxidizedCopperChain"] = "minecraft:oxidized_copper_chain";
        MinecraftBlockTypes2["OxidizedCopperChest"] = "minecraft:oxidized_copper_chest";
        MinecraftBlockTypes2["OxidizedCopperDoor"] = "minecraft:oxidized_copper_door";
        MinecraftBlockTypes2["OxidizedCopperGolemStatue"] = "minecraft:oxidized_copper_golem_statue";
        MinecraftBlockTypes2["OxidizedCopperGrate"] = "minecraft:oxidized_copper_grate";
        MinecraftBlockTypes2["OxidizedCopperLantern"] = "minecraft:oxidized_copper_lantern";
        MinecraftBlockTypes2["OxidizedCopperTrapdoor"] = "minecraft:oxidized_copper_trapdoor";
        MinecraftBlockTypes2["OxidizedCutCopper"] = "minecraft:oxidized_cut_copper";
        MinecraftBlockTypes2["OxidizedCutCopperSlab"] = "minecraft:oxidized_cut_copper_slab";
        MinecraftBlockTypes2["OxidizedCutCopperStairs"] = "minecraft:oxidized_cut_copper_stairs";
        MinecraftBlockTypes2["OxidizedDoubleCutCopperSlab"] = "minecraft:oxidized_double_cut_copper_slab";
        MinecraftBlockTypes2["OxidizedLightningRod"] = "minecraft:oxidized_lightning_rod";
        MinecraftBlockTypes2["PackedIce"] = "minecraft:packed_ice";
        MinecraftBlockTypes2["PackedMud"] = "minecraft:packed_mud";
        MinecraftBlockTypes2["PaleHangingMoss"] = "minecraft:pale_hanging_moss";
        MinecraftBlockTypes2["PaleMossBlock"] = "minecraft:pale_moss_block";
        MinecraftBlockTypes2["PaleMossCarpet"] = "minecraft:pale_moss_carpet";
        MinecraftBlockTypes2["PaleOakButton"] = "minecraft:pale_oak_button";
        MinecraftBlockTypes2["PaleOakDoor"] = "minecraft:pale_oak_door";
        MinecraftBlockTypes2["PaleOakDoubleSlab"] = "minecraft:pale_oak_double_slab";
        MinecraftBlockTypes2["PaleOakFence"] = "minecraft:pale_oak_fence";
        MinecraftBlockTypes2["PaleOakFenceGate"] = "minecraft:pale_oak_fence_gate";
        MinecraftBlockTypes2["PaleOakHangingSign"] = "minecraft:pale_oak_hanging_sign";
        MinecraftBlockTypes2["PaleOakLeaves"] = "minecraft:pale_oak_leaves";
        MinecraftBlockTypes2["PaleOakLog"] = "minecraft:pale_oak_log";
        MinecraftBlockTypes2["PaleOakPlanks"] = "minecraft:pale_oak_planks";
        MinecraftBlockTypes2["PaleOakPressurePlate"] = "minecraft:pale_oak_pressure_plate";
        MinecraftBlockTypes2["PaleOakSapling"] = "minecraft:pale_oak_sapling";
        MinecraftBlockTypes2["PaleOakShelf"] = "minecraft:pale_oak_shelf";
        MinecraftBlockTypes2["PaleOakSlab"] = "minecraft:pale_oak_slab";
        MinecraftBlockTypes2["PaleOakStairs"] = "minecraft:pale_oak_stairs";
        MinecraftBlockTypes2["PaleOakStandingSign"] = "minecraft:pale_oak_standing_sign";
        MinecraftBlockTypes2["PaleOakTrapdoor"] = "minecraft:pale_oak_trapdoor";
        MinecraftBlockTypes2["PaleOakWallSign"] = "minecraft:pale_oak_wall_sign";
        MinecraftBlockTypes2["PaleOakWood"] = "minecraft:pale_oak_wood";
        MinecraftBlockTypes2["PearlescentFroglight"] = "minecraft:pearlescent_froglight";
        MinecraftBlockTypes2["Peony"] = "minecraft:peony";
        MinecraftBlockTypes2["PetrifiedOakDoubleSlab"] = "minecraft:petrified_oak_double_slab";
        MinecraftBlockTypes2["PetrifiedOakSlab"] = "minecraft:petrified_oak_slab";
        MinecraftBlockTypes2["PiglinHead"] = "minecraft:piglin_head";
        MinecraftBlockTypes2["PinkCandle"] = "minecraft:pink_candle";
        MinecraftBlockTypes2["PinkCandleCake"] = "minecraft:pink_candle_cake";
        MinecraftBlockTypes2["PinkCarpet"] = "minecraft:pink_carpet";
        MinecraftBlockTypes2["PinkConcrete"] = "minecraft:pink_concrete";
        MinecraftBlockTypes2["PinkConcretePowder"] = "minecraft:pink_concrete_powder";
        MinecraftBlockTypes2["PinkGlazedTerracotta"] = "minecraft:pink_glazed_terracotta";
        MinecraftBlockTypes2["PinkPetals"] = "minecraft:pink_petals";
        MinecraftBlockTypes2["PinkShulkerBox"] = "minecraft:pink_shulker_box";
        MinecraftBlockTypes2["PinkStainedGlass"] = "minecraft:pink_stained_glass";
        MinecraftBlockTypes2["PinkStainedGlassPane"] = "minecraft:pink_stained_glass_pane";
        MinecraftBlockTypes2["PinkTerracotta"] = "minecraft:pink_terracotta";
        MinecraftBlockTypes2["PinkTulip"] = "minecraft:pink_tulip";
        MinecraftBlockTypes2["PinkWool"] = "minecraft:pink_wool";
        MinecraftBlockTypes2["Piston"] = "minecraft:piston";
        MinecraftBlockTypes2["PistonArmCollision"] = "minecraft:piston_arm_collision";
        MinecraftBlockTypes2["PitcherCrop"] = "minecraft:pitcher_crop";
        MinecraftBlockTypes2["PitcherPlant"] = "minecraft:pitcher_plant";
        MinecraftBlockTypes2["PlayerHead"] = "minecraft:player_head";
        MinecraftBlockTypes2["Podzol"] = "minecraft:podzol";
        MinecraftBlockTypes2["PointedDripstone"] = "minecraft:pointed_dripstone";
        MinecraftBlockTypes2["PolishedAndesite"] = "minecraft:polished_andesite";
        MinecraftBlockTypes2["PolishedAndesiteDoubleSlab"] = "minecraft:polished_andesite_double_slab";
        MinecraftBlockTypes2["PolishedAndesiteSlab"] = "minecraft:polished_andesite_slab";
        MinecraftBlockTypes2["PolishedAndesiteStairs"] = "minecraft:polished_andesite_stairs";
        MinecraftBlockTypes2["PolishedBasalt"] = "minecraft:polished_basalt";
        MinecraftBlockTypes2["PolishedBlackstone"] = "minecraft:polished_blackstone";
        MinecraftBlockTypes2["PolishedBlackstoneBrickDoubleSlab"] = "minecraft:polished_blackstone_brick_double_slab";
        MinecraftBlockTypes2["PolishedBlackstoneBrickSlab"] = "minecraft:polished_blackstone_brick_slab";
        MinecraftBlockTypes2["PolishedBlackstoneBrickStairs"] = "minecraft:polished_blackstone_brick_stairs";
        MinecraftBlockTypes2["PolishedBlackstoneBrickWall"] = "minecraft:polished_blackstone_brick_wall";
        MinecraftBlockTypes2["PolishedBlackstoneBricks"] = "minecraft:polished_blackstone_bricks";
        MinecraftBlockTypes2["PolishedBlackstoneButton"] = "minecraft:polished_blackstone_button";
        MinecraftBlockTypes2["PolishedBlackstoneDoubleSlab"] = "minecraft:polished_blackstone_double_slab";
        MinecraftBlockTypes2["PolishedBlackstonePressurePlate"] = "minecraft:polished_blackstone_pressure_plate";
        MinecraftBlockTypes2["PolishedBlackstoneSlab"] = "minecraft:polished_blackstone_slab";
        MinecraftBlockTypes2["PolishedBlackstoneStairs"] = "minecraft:polished_blackstone_stairs";
        MinecraftBlockTypes2["PolishedBlackstoneWall"] = "minecraft:polished_blackstone_wall";
        MinecraftBlockTypes2["PolishedDeepslate"] = "minecraft:polished_deepslate";
        MinecraftBlockTypes2["PolishedDeepslateDoubleSlab"] = "minecraft:polished_deepslate_double_slab";
        MinecraftBlockTypes2["PolishedDeepslateSlab"] = "minecraft:polished_deepslate_slab";
        MinecraftBlockTypes2["PolishedDeepslateStairs"] = "minecraft:polished_deepslate_stairs";
        MinecraftBlockTypes2["PolishedDeepslateWall"] = "minecraft:polished_deepslate_wall";
        MinecraftBlockTypes2["PolishedDiorite"] = "minecraft:polished_diorite";
        MinecraftBlockTypes2["PolishedDioriteDoubleSlab"] = "minecraft:polished_diorite_double_slab";
        MinecraftBlockTypes2["PolishedDioriteSlab"] = "minecraft:polished_diorite_slab";
        MinecraftBlockTypes2["PolishedDioriteStairs"] = "minecraft:polished_diorite_stairs";
        MinecraftBlockTypes2["PolishedGranite"] = "minecraft:polished_granite";
        MinecraftBlockTypes2["PolishedGraniteDoubleSlab"] = "minecraft:polished_granite_double_slab";
        MinecraftBlockTypes2["PolishedGraniteSlab"] = "minecraft:polished_granite_slab";
        MinecraftBlockTypes2["PolishedGraniteStairs"] = "minecraft:polished_granite_stairs";
        MinecraftBlockTypes2["PolishedTuff"] = "minecraft:polished_tuff";
        MinecraftBlockTypes2["PolishedTuffDoubleSlab"] = "minecraft:polished_tuff_double_slab";
        MinecraftBlockTypes2["PolishedTuffSlab"] = "minecraft:polished_tuff_slab";
        MinecraftBlockTypes2["PolishedTuffStairs"] = "minecraft:polished_tuff_stairs";
        MinecraftBlockTypes2["PolishedTuffWall"] = "minecraft:polished_tuff_wall";
        MinecraftBlockTypes2["Poppy"] = "minecraft:poppy";
        MinecraftBlockTypes2["Portal"] = "minecraft:portal";
        MinecraftBlockTypes2["Potatoes"] = "minecraft:potatoes";
        MinecraftBlockTypes2["PowderSnow"] = "minecraft:powder_snow";
        MinecraftBlockTypes2["PoweredComparator"] = "minecraft:powered_comparator";
        MinecraftBlockTypes2["PoweredRepeater"] = "minecraft:powered_repeater";
        MinecraftBlockTypes2["Prismarine"] = "minecraft:prismarine";
        MinecraftBlockTypes2["PrismarineBrickDoubleSlab"] = "minecraft:prismarine_brick_double_slab";
        MinecraftBlockTypes2["PrismarineBrickSlab"] = "minecraft:prismarine_brick_slab";
        MinecraftBlockTypes2["PrismarineBricks"] = "minecraft:prismarine_bricks";
        MinecraftBlockTypes2["PrismarineBricksStairs"] = "minecraft:prismarine_bricks_stairs";
        MinecraftBlockTypes2["PrismarineDoubleSlab"] = "minecraft:prismarine_double_slab";
        MinecraftBlockTypes2["PrismarineSlab"] = "minecraft:prismarine_slab";
        MinecraftBlockTypes2["PrismarineStairs"] = "minecraft:prismarine_stairs";
        MinecraftBlockTypes2["PrismarineWall"] = "minecraft:prismarine_wall";
        MinecraftBlockTypes2["Pumpkin"] = "minecraft:pumpkin";
        MinecraftBlockTypes2["PumpkinStem"] = "minecraft:pumpkin_stem";
        MinecraftBlockTypes2["PurpleCandle"] = "minecraft:purple_candle";
        MinecraftBlockTypes2["PurpleCandleCake"] = "minecraft:purple_candle_cake";
        MinecraftBlockTypes2["PurpleCarpet"] = "minecraft:purple_carpet";
        MinecraftBlockTypes2["PurpleConcrete"] = "minecraft:purple_concrete";
        MinecraftBlockTypes2["PurpleConcretePowder"] = "minecraft:purple_concrete_powder";
        MinecraftBlockTypes2["PurpleGlazedTerracotta"] = "minecraft:purple_glazed_terracotta";
        MinecraftBlockTypes2["PurpleShulkerBox"] = "minecraft:purple_shulker_box";
        MinecraftBlockTypes2["PurpleStainedGlass"] = "minecraft:purple_stained_glass";
        MinecraftBlockTypes2["PurpleStainedGlassPane"] = "minecraft:purple_stained_glass_pane";
        MinecraftBlockTypes2["PurpleTerracotta"] = "minecraft:purple_terracotta";
        MinecraftBlockTypes2["PurpleWool"] = "minecraft:purple_wool";
        MinecraftBlockTypes2["PurpurBlock"] = "minecraft:purpur_block";
        MinecraftBlockTypes2["PurpurDoubleSlab"] = "minecraft:purpur_double_slab";
        MinecraftBlockTypes2["PurpurPillar"] = "minecraft:purpur_pillar";
        MinecraftBlockTypes2["PurpurSlab"] = "minecraft:purpur_slab";
        MinecraftBlockTypes2["PurpurStairs"] = "minecraft:purpur_stairs";
        MinecraftBlockTypes2["QuartzBlock"] = "minecraft:quartz_block";
        MinecraftBlockTypes2["QuartzBricks"] = "minecraft:quartz_bricks";
        MinecraftBlockTypes2["QuartzDoubleSlab"] = "minecraft:quartz_double_slab";
        MinecraftBlockTypes2["QuartzOre"] = "minecraft:quartz_ore";
        MinecraftBlockTypes2["QuartzPillar"] = "minecraft:quartz_pillar";
        MinecraftBlockTypes2["QuartzSlab"] = "minecraft:quartz_slab";
        MinecraftBlockTypes2["QuartzStairs"] = "minecraft:quartz_stairs";
        MinecraftBlockTypes2["Rail"] = "minecraft:rail";
        MinecraftBlockTypes2["RawCopperBlock"] = "minecraft:raw_copper_block";
        MinecraftBlockTypes2["RawGoldBlock"] = "minecraft:raw_gold_block";
        MinecraftBlockTypes2["RawIronBlock"] = "minecraft:raw_iron_block";
        MinecraftBlockTypes2["RedCandle"] = "minecraft:red_candle";
        MinecraftBlockTypes2["RedCandleCake"] = "minecraft:red_candle_cake";
        MinecraftBlockTypes2["RedCarpet"] = "minecraft:red_carpet";
        MinecraftBlockTypes2["RedConcrete"] = "minecraft:red_concrete";
        MinecraftBlockTypes2["RedConcretePowder"] = "minecraft:red_concrete_powder";
        MinecraftBlockTypes2["RedGlazedTerracotta"] = "minecraft:red_glazed_terracotta";
        MinecraftBlockTypes2["RedMushroom"] = "minecraft:red_mushroom";
        MinecraftBlockTypes2["RedMushroomBlock"] = "minecraft:red_mushroom_block";
        MinecraftBlockTypes2["RedNetherBrick"] = "minecraft:red_nether_brick";
        MinecraftBlockTypes2["RedNetherBrickDoubleSlab"] = "minecraft:red_nether_brick_double_slab";
        MinecraftBlockTypes2["RedNetherBrickSlab"] = "minecraft:red_nether_brick_slab";
        MinecraftBlockTypes2["RedNetherBrickStairs"] = "minecraft:red_nether_brick_stairs";
        MinecraftBlockTypes2["RedNetherBrickWall"] = "minecraft:red_nether_brick_wall";
        MinecraftBlockTypes2["RedSand"] = "minecraft:red_sand";
        MinecraftBlockTypes2["RedSandstone"] = "minecraft:red_sandstone";
        MinecraftBlockTypes2["RedSandstoneDoubleSlab"] = "minecraft:red_sandstone_double_slab";
        MinecraftBlockTypes2["RedSandstoneSlab"] = "minecraft:red_sandstone_slab";
        MinecraftBlockTypes2["RedSandstoneStairs"] = "minecraft:red_sandstone_stairs";
        MinecraftBlockTypes2["RedSandstoneWall"] = "minecraft:red_sandstone_wall";
        MinecraftBlockTypes2["RedShulkerBox"] = "minecraft:red_shulker_box";
        MinecraftBlockTypes2["RedStainedGlass"] = "minecraft:red_stained_glass";
        MinecraftBlockTypes2["RedStainedGlassPane"] = "minecraft:red_stained_glass_pane";
        MinecraftBlockTypes2["RedTerracotta"] = "minecraft:red_terracotta";
        MinecraftBlockTypes2["RedTulip"] = "minecraft:red_tulip";
        MinecraftBlockTypes2["RedWool"] = "minecraft:red_wool";
        MinecraftBlockTypes2["RedstoneBlock"] = "minecraft:redstone_block";
        MinecraftBlockTypes2["RedstoneLamp"] = "minecraft:redstone_lamp";
        MinecraftBlockTypes2["RedstoneOre"] = "minecraft:redstone_ore";
        MinecraftBlockTypes2["RedstoneTorch"] = "minecraft:redstone_torch";
        MinecraftBlockTypes2["RedstoneWire"] = "minecraft:redstone_wire";
        MinecraftBlockTypes2["Reeds"] = "minecraft:reeds";
        MinecraftBlockTypes2["ReinforcedDeepslate"] = "minecraft:reinforced_deepslate";
        MinecraftBlockTypes2["RepeatingCommandBlock"] = "minecraft:repeating_command_block";
        MinecraftBlockTypes2["ResinBlock"] = "minecraft:resin_block";
        MinecraftBlockTypes2["ResinBrickDoubleSlab"] = "minecraft:resin_brick_double_slab";
        MinecraftBlockTypes2["ResinBrickSlab"] = "minecraft:resin_brick_slab";
        MinecraftBlockTypes2["ResinBrickStairs"] = "minecraft:resin_brick_stairs";
        MinecraftBlockTypes2["ResinBrickWall"] = "minecraft:resin_brick_wall";
        MinecraftBlockTypes2["ResinBricks"] = "minecraft:resin_bricks";
        MinecraftBlockTypes2["ResinClump"] = "minecraft:resin_clump";
        MinecraftBlockTypes2["RespawnAnchor"] = "minecraft:respawn_anchor";
        MinecraftBlockTypes2["RoseBush"] = "minecraft:rose_bush";
        MinecraftBlockTypes2["Sand"] = "minecraft:sand";
        MinecraftBlockTypes2["Sandstone"] = "minecraft:sandstone";
        MinecraftBlockTypes2["SandstoneDoubleSlab"] = "minecraft:sandstone_double_slab";
        MinecraftBlockTypes2["SandstoneSlab"] = "minecraft:sandstone_slab";
        MinecraftBlockTypes2["SandstoneStairs"] = "minecraft:sandstone_stairs";
        MinecraftBlockTypes2["SandstoneWall"] = "minecraft:sandstone_wall";
        MinecraftBlockTypes2["Scaffolding"] = "minecraft:scaffolding";
        MinecraftBlockTypes2["Sculk"] = "minecraft:sculk";
        MinecraftBlockTypes2["SculkCatalyst"] = "minecraft:sculk_catalyst";
        MinecraftBlockTypes2["SculkSensor"] = "minecraft:sculk_sensor";
        MinecraftBlockTypes2["SculkShrieker"] = "minecraft:sculk_shrieker";
        MinecraftBlockTypes2["SculkVein"] = "minecraft:sculk_vein";
        MinecraftBlockTypes2["SeaLantern"] = "minecraft:sea_lantern";
        MinecraftBlockTypes2["SeaPickle"] = "minecraft:sea_pickle";
        MinecraftBlockTypes2["Seagrass"] = "minecraft:seagrass";
        MinecraftBlockTypes2["ShortDryGrass"] = "minecraft:short_dry_grass";
        MinecraftBlockTypes2["ShortGrass"] = "minecraft:short_grass";
        MinecraftBlockTypes2["Shroomlight"] = "minecraft:shroomlight";
        MinecraftBlockTypes2["SilverGlazedTerracotta"] = "minecraft:silver_glazed_terracotta";
        MinecraftBlockTypes2["SkeletonSkull"] = "minecraft:skeleton_skull";
        MinecraftBlockTypes2["Slime"] = "minecraft:slime";
        MinecraftBlockTypes2["SmallAmethystBud"] = "minecraft:small_amethyst_bud";
        MinecraftBlockTypes2["SmallDripleafBlock"] = "minecraft:small_dripleaf_block";
        MinecraftBlockTypes2["SmithingTable"] = "minecraft:smithing_table";
        MinecraftBlockTypes2["Smoker"] = "minecraft:smoker";
        MinecraftBlockTypes2["SmoothBasalt"] = "minecraft:smooth_basalt";
        MinecraftBlockTypes2["SmoothQuartz"] = "minecraft:smooth_quartz";
        MinecraftBlockTypes2["SmoothQuartzDoubleSlab"] = "minecraft:smooth_quartz_double_slab";
        MinecraftBlockTypes2["SmoothQuartzSlab"] = "minecraft:smooth_quartz_slab";
        MinecraftBlockTypes2["SmoothQuartzStairs"] = "minecraft:smooth_quartz_stairs";
        MinecraftBlockTypes2["SmoothRedSandstone"] = "minecraft:smooth_red_sandstone";
        MinecraftBlockTypes2["SmoothRedSandstoneDoubleSlab"] = "minecraft:smooth_red_sandstone_double_slab";
        MinecraftBlockTypes2["SmoothRedSandstoneSlab"] = "minecraft:smooth_red_sandstone_slab";
        MinecraftBlockTypes2["SmoothRedSandstoneStairs"] = "minecraft:smooth_red_sandstone_stairs";
        MinecraftBlockTypes2["SmoothSandstone"] = "minecraft:smooth_sandstone";
        MinecraftBlockTypes2["SmoothSandstoneDoubleSlab"] = "minecraft:smooth_sandstone_double_slab";
        MinecraftBlockTypes2["SmoothSandstoneSlab"] = "minecraft:smooth_sandstone_slab";
        MinecraftBlockTypes2["SmoothSandstoneStairs"] = "minecraft:smooth_sandstone_stairs";
        MinecraftBlockTypes2["SmoothStone"] = "minecraft:smooth_stone";
        MinecraftBlockTypes2["SmoothStoneDoubleSlab"] = "minecraft:smooth_stone_double_slab";
        MinecraftBlockTypes2["SmoothStoneSlab"] = "minecraft:smooth_stone_slab";
        MinecraftBlockTypes2["SnifferEgg"] = "minecraft:sniffer_egg";
        MinecraftBlockTypes2["Snow"] = "minecraft:snow";
        MinecraftBlockTypes2["SnowLayer"] = "minecraft:snow_layer";
        MinecraftBlockTypes2["SoulCampfire"] = "minecraft:soul_campfire";
        MinecraftBlockTypes2["SoulFire"] = "minecraft:soul_fire";
        MinecraftBlockTypes2["SoulLantern"] = "minecraft:soul_lantern";
        MinecraftBlockTypes2["SoulSand"] = "minecraft:soul_sand";
        MinecraftBlockTypes2["SoulSoil"] = "minecraft:soul_soil";
        MinecraftBlockTypes2["SoulTorch"] = "minecraft:soul_torch";
        MinecraftBlockTypes2["Sponge"] = "minecraft:sponge";
        MinecraftBlockTypes2["SporeBlossom"] = "minecraft:spore_blossom";
        MinecraftBlockTypes2["SpruceButton"] = "minecraft:spruce_button";
        MinecraftBlockTypes2["SpruceDoor"] = "minecraft:spruce_door";
        MinecraftBlockTypes2["SpruceDoubleSlab"] = "minecraft:spruce_double_slab";
        MinecraftBlockTypes2["SpruceFence"] = "minecraft:spruce_fence";
        MinecraftBlockTypes2["SpruceFenceGate"] = "minecraft:spruce_fence_gate";
        MinecraftBlockTypes2["SpruceHangingSign"] = "minecraft:spruce_hanging_sign";
        MinecraftBlockTypes2["SpruceLeaves"] = "minecraft:spruce_leaves";
        MinecraftBlockTypes2["SpruceLog"] = "minecraft:spruce_log";
        MinecraftBlockTypes2["SprucePlanks"] = "minecraft:spruce_planks";
        MinecraftBlockTypes2["SprucePressurePlate"] = "minecraft:spruce_pressure_plate";
        MinecraftBlockTypes2["SpruceSapling"] = "minecraft:spruce_sapling";
        MinecraftBlockTypes2["SpruceShelf"] = "minecraft:spruce_shelf";
        MinecraftBlockTypes2["SpruceSlab"] = "minecraft:spruce_slab";
        MinecraftBlockTypes2["SpruceStairs"] = "minecraft:spruce_stairs";
        MinecraftBlockTypes2["SpruceStandingSign"] = "minecraft:spruce_standing_sign";
        MinecraftBlockTypes2["SpruceTrapdoor"] = "minecraft:spruce_trapdoor";
        MinecraftBlockTypes2["SpruceWallSign"] = "minecraft:spruce_wall_sign";
        MinecraftBlockTypes2["SpruceWood"] = "minecraft:spruce_wood";
        MinecraftBlockTypes2["StandingBanner"] = "minecraft:standing_banner";
        MinecraftBlockTypes2["StandingSign"] = "minecraft:standing_sign";
        MinecraftBlockTypes2["StickyPiston"] = "minecraft:sticky_piston";
        MinecraftBlockTypes2["StickyPistonArmCollision"] = "minecraft:sticky_piston_arm_collision";
        MinecraftBlockTypes2["Stone"] = "minecraft:stone";
        MinecraftBlockTypes2["StoneBrickDoubleSlab"] = "minecraft:stone_brick_double_slab";
        MinecraftBlockTypes2["StoneBrickSlab"] = "minecraft:stone_brick_slab";
        MinecraftBlockTypes2["StoneBrickStairs"] = "minecraft:stone_brick_stairs";
        MinecraftBlockTypes2["StoneBrickWall"] = "minecraft:stone_brick_wall";
        MinecraftBlockTypes2["StoneBricks"] = "minecraft:stone_bricks";
        MinecraftBlockTypes2["StoneButton"] = "minecraft:stone_button";
        MinecraftBlockTypes2["StonePressurePlate"] = "minecraft:stone_pressure_plate";
        MinecraftBlockTypes2["StoneStairs"] = "minecraft:stone_stairs";
        MinecraftBlockTypes2["StonecutterBlock"] = "minecraft:stonecutter_block";
        MinecraftBlockTypes2["StrippedAcaciaLog"] = "minecraft:stripped_acacia_log";
        MinecraftBlockTypes2["StrippedAcaciaWood"] = "minecraft:stripped_acacia_wood";
        MinecraftBlockTypes2["StrippedBambooBlock"] = "minecraft:stripped_bamboo_block";
        MinecraftBlockTypes2["StrippedBirchLog"] = "minecraft:stripped_birch_log";
        MinecraftBlockTypes2["StrippedBirchWood"] = "minecraft:stripped_birch_wood";
        MinecraftBlockTypes2["StrippedCherryLog"] = "minecraft:stripped_cherry_log";
        MinecraftBlockTypes2["StrippedCherryWood"] = "minecraft:stripped_cherry_wood";
        MinecraftBlockTypes2["StrippedCrimsonHyphae"] = "minecraft:stripped_crimson_hyphae";
        MinecraftBlockTypes2["StrippedCrimsonStem"] = "minecraft:stripped_crimson_stem";
        MinecraftBlockTypes2["StrippedDarkOakLog"] = "minecraft:stripped_dark_oak_log";
        MinecraftBlockTypes2["StrippedDarkOakWood"] = "minecraft:stripped_dark_oak_wood";
        MinecraftBlockTypes2["StrippedJungleLog"] = "minecraft:stripped_jungle_log";
        MinecraftBlockTypes2["StrippedJungleWood"] = "minecraft:stripped_jungle_wood";
        MinecraftBlockTypes2["StrippedMangroveLog"] = "minecraft:stripped_mangrove_log";
        MinecraftBlockTypes2["StrippedMangroveWood"] = "minecraft:stripped_mangrove_wood";
        MinecraftBlockTypes2["StrippedOakLog"] = "minecraft:stripped_oak_log";
        MinecraftBlockTypes2["StrippedOakWood"] = "minecraft:stripped_oak_wood";
        MinecraftBlockTypes2["StrippedPaleOakLog"] = "minecraft:stripped_pale_oak_log";
        MinecraftBlockTypes2["StrippedPaleOakWood"] = "minecraft:stripped_pale_oak_wood";
        MinecraftBlockTypes2["StrippedSpruceLog"] = "minecraft:stripped_spruce_log";
        MinecraftBlockTypes2["StrippedSpruceWood"] = "minecraft:stripped_spruce_wood";
        MinecraftBlockTypes2["StrippedWarpedHyphae"] = "minecraft:stripped_warped_hyphae";
        MinecraftBlockTypes2["StrippedWarpedStem"] = "minecraft:stripped_warped_stem";
        MinecraftBlockTypes2["StructureBlock"] = "minecraft:structure_block";
        MinecraftBlockTypes2["StructureVoid"] = "minecraft:structure_void";
        MinecraftBlockTypes2["Sunflower"] = "minecraft:sunflower";
        MinecraftBlockTypes2["SuspiciousGravel"] = "minecraft:suspicious_gravel";
        MinecraftBlockTypes2["SuspiciousSand"] = "minecraft:suspicious_sand";
        MinecraftBlockTypes2["SweetBerryBush"] = "minecraft:sweet_berry_bush";
        MinecraftBlockTypes2["TallDryGrass"] = "minecraft:tall_dry_grass";
        MinecraftBlockTypes2["TallGrass"] = "minecraft:tall_grass";
        MinecraftBlockTypes2["Target"] = "minecraft:target";
        MinecraftBlockTypes2["TintedGlass"] = "minecraft:tinted_glass";
        MinecraftBlockTypes2["Tnt"] = "minecraft:tnt";
        MinecraftBlockTypes2["Torch"] = "minecraft:torch";
        MinecraftBlockTypes2["Torchflower"] = "minecraft:torchflower";
        MinecraftBlockTypes2["TorchflowerCrop"] = "minecraft:torchflower_crop";
        MinecraftBlockTypes2["Trapdoor"] = "minecraft:trapdoor";
        MinecraftBlockTypes2["TrappedChest"] = "minecraft:trapped_chest";
        MinecraftBlockTypes2["TrialSpawner"] = "minecraft:trial_spawner";
        MinecraftBlockTypes2["TripWire"] = "minecraft:trip_wire";
        MinecraftBlockTypes2["TripwireHook"] = "minecraft:tripwire_hook";
        MinecraftBlockTypes2["TubeCoral"] = "minecraft:tube_coral";
        MinecraftBlockTypes2["TubeCoralBlock"] = "minecraft:tube_coral_block";
        MinecraftBlockTypes2["TubeCoralFan"] = "minecraft:tube_coral_fan";
        MinecraftBlockTypes2["TubeCoralWallFan"] = "minecraft:tube_coral_wall_fan";
        MinecraftBlockTypes2["Tuff"] = "minecraft:tuff";
        MinecraftBlockTypes2["TuffBrickDoubleSlab"] = "minecraft:tuff_brick_double_slab";
        MinecraftBlockTypes2["TuffBrickSlab"] = "minecraft:tuff_brick_slab";
        MinecraftBlockTypes2["TuffBrickStairs"] = "minecraft:tuff_brick_stairs";
        MinecraftBlockTypes2["TuffBrickWall"] = "minecraft:tuff_brick_wall";
        MinecraftBlockTypes2["TuffBricks"] = "minecraft:tuff_bricks";
        MinecraftBlockTypes2["TuffDoubleSlab"] = "minecraft:tuff_double_slab";
        MinecraftBlockTypes2["TuffSlab"] = "minecraft:tuff_slab";
        MinecraftBlockTypes2["TuffStairs"] = "minecraft:tuff_stairs";
        MinecraftBlockTypes2["TuffWall"] = "minecraft:tuff_wall";
        MinecraftBlockTypes2["TurtleEgg"] = "minecraft:turtle_egg";
        MinecraftBlockTypes2["TwistingVines"] = "minecraft:twisting_vines";
        MinecraftBlockTypes2["UnderwaterTnt"] = "minecraft:underwater_tnt";
        MinecraftBlockTypes2["UnderwaterTorch"] = "minecraft:underwater_torch";
        MinecraftBlockTypes2["UndyedShulkerBox"] = "minecraft:undyed_shulker_box";
        MinecraftBlockTypes2["Unknown"] = "minecraft:unknown";
        MinecraftBlockTypes2["UnlitRedstoneTorch"] = "minecraft:unlit_redstone_torch";
        MinecraftBlockTypes2["UnpoweredComparator"] = "minecraft:unpowered_comparator";
        MinecraftBlockTypes2["UnpoweredRepeater"] = "minecraft:unpowered_repeater";
        MinecraftBlockTypes2["Vault"] = "minecraft:vault";
        MinecraftBlockTypes2["VerdantFroglight"] = "minecraft:verdant_froglight";
        MinecraftBlockTypes2["Vine"] = "minecraft:vine";
        MinecraftBlockTypes2["WallBanner"] = "minecraft:wall_banner";
        MinecraftBlockTypes2["WallSign"] = "minecraft:wall_sign";
        MinecraftBlockTypes2["WarpedButton"] = "minecraft:warped_button";
        MinecraftBlockTypes2["WarpedDoor"] = "minecraft:warped_door";
        MinecraftBlockTypes2["WarpedDoubleSlab"] = "minecraft:warped_double_slab";
        MinecraftBlockTypes2["WarpedFence"] = "minecraft:warped_fence";
        MinecraftBlockTypes2["WarpedFenceGate"] = "minecraft:warped_fence_gate";
        MinecraftBlockTypes2["WarpedFungus"] = "minecraft:warped_fungus";
        MinecraftBlockTypes2["WarpedHangingSign"] = "minecraft:warped_hanging_sign";
        MinecraftBlockTypes2["WarpedHyphae"] = "minecraft:warped_hyphae";
        MinecraftBlockTypes2["WarpedNylium"] = "minecraft:warped_nylium";
        MinecraftBlockTypes2["WarpedPlanks"] = "minecraft:warped_planks";
        MinecraftBlockTypes2["WarpedPressurePlate"] = "minecraft:warped_pressure_plate";
        MinecraftBlockTypes2["WarpedRoots"] = "minecraft:warped_roots";
        MinecraftBlockTypes2["WarpedShelf"] = "minecraft:warped_shelf";
        MinecraftBlockTypes2["WarpedSlab"] = "minecraft:warped_slab";
        MinecraftBlockTypes2["WarpedStairs"] = "minecraft:warped_stairs";
        MinecraftBlockTypes2["WarpedStandingSign"] = "minecraft:warped_standing_sign";
        MinecraftBlockTypes2["WarpedStem"] = "minecraft:warped_stem";
        MinecraftBlockTypes2["WarpedTrapdoor"] = "minecraft:warped_trapdoor";
        MinecraftBlockTypes2["WarpedWallSign"] = "minecraft:warped_wall_sign";
        MinecraftBlockTypes2["WarpedWartBlock"] = "minecraft:warped_wart_block";
        MinecraftBlockTypes2["Water"] = "minecraft:water";
        MinecraftBlockTypes2["Waterlily"] = "minecraft:waterlily";
        MinecraftBlockTypes2["WaxedChiseledCopper"] = "minecraft:waxed_chiseled_copper";
        MinecraftBlockTypes2["WaxedCopper"] = "minecraft:waxed_copper";
        MinecraftBlockTypes2["WaxedCopperBars"] = "minecraft:waxed_copper_bars";
        MinecraftBlockTypes2["WaxedCopperBulb"] = "minecraft:waxed_copper_bulb";
        MinecraftBlockTypes2["WaxedCopperChain"] = "minecraft:waxed_copper_chain";
        MinecraftBlockTypes2["WaxedCopperChest"] = "minecraft:waxed_copper_chest";
        MinecraftBlockTypes2["WaxedCopperDoor"] = "minecraft:waxed_copper_door";
        MinecraftBlockTypes2["WaxedCopperGolemStatue"] = "minecraft:waxed_copper_golem_statue";
        MinecraftBlockTypes2["WaxedCopperGrate"] = "minecraft:waxed_copper_grate";
        MinecraftBlockTypes2["WaxedCopperLantern"] = "minecraft:waxed_copper_lantern";
        MinecraftBlockTypes2["WaxedCopperTrapdoor"] = "minecraft:waxed_copper_trapdoor";
        MinecraftBlockTypes2["WaxedCutCopper"] = "minecraft:waxed_cut_copper";
        MinecraftBlockTypes2["WaxedCutCopperSlab"] = "minecraft:waxed_cut_copper_slab";
        MinecraftBlockTypes2["WaxedCutCopperStairs"] = "minecraft:waxed_cut_copper_stairs";
        MinecraftBlockTypes2["WaxedDoubleCutCopperSlab"] = "minecraft:waxed_double_cut_copper_slab";
        MinecraftBlockTypes2["WaxedExposedChiseledCopper"] = "minecraft:waxed_exposed_chiseled_copper";
        MinecraftBlockTypes2["WaxedExposedCopper"] = "minecraft:waxed_exposed_copper";
        MinecraftBlockTypes2["WaxedExposedCopperBars"] = "minecraft:waxed_exposed_copper_bars";
        MinecraftBlockTypes2["WaxedExposedCopperBulb"] = "minecraft:waxed_exposed_copper_bulb";
        MinecraftBlockTypes2["WaxedExposedCopperChain"] = "minecraft:waxed_exposed_copper_chain";
        MinecraftBlockTypes2["WaxedExposedCopperChest"] = "minecraft:waxed_exposed_copper_chest";
        MinecraftBlockTypes2["WaxedExposedCopperDoor"] = "minecraft:waxed_exposed_copper_door";
        MinecraftBlockTypes2["WaxedExposedCopperGolemStatue"] = "minecraft:waxed_exposed_copper_golem_statue";
        MinecraftBlockTypes2["WaxedExposedCopperGrate"] = "minecraft:waxed_exposed_copper_grate";
        MinecraftBlockTypes2["WaxedExposedCopperLantern"] = "minecraft:waxed_exposed_copper_lantern";
        MinecraftBlockTypes2["WaxedExposedCopperTrapdoor"] = "minecraft:waxed_exposed_copper_trapdoor";
        MinecraftBlockTypes2["WaxedExposedCutCopper"] = "minecraft:waxed_exposed_cut_copper";
        MinecraftBlockTypes2["WaxedExposedCutCopperSlab"] = "minecraft:waxed_exposed_cut_copper_slab";
        MinecraftBlockTypes2["WaxedExposedCutCopperStairs"] = "minecraft:waxed_exposed_cut_copper_stairs";
        MinecraftBlockTypes2["WaxedExposedDoubleCutCopperSlab"] = "minecraft:waxed_exposed_double_cut_copper_slab";
        MinecraftBlockTypes2["WaxedExposedLightningRod"] = "minecraft:waxed_exposed_lightning_rod";
        MinecraftBlockTypes2["WaxedLightningRod"] = "minecraft:waxed_lightning_rod";
        MinecraftBlockTypes2["WaxedOxidizedChiseledCopper"] = "minecraft:waxed_oxidized_chiseled_copper";
        MinecraftBlockTypes2["WaxedOxidizedCopper"] = "minecraft:waxed_oxidized_copper";
        MinecraftBlockTypes2["WaxedOxidizedCopperBars"] = "minecraft:waxed_oxidized_copper_bars";
        MinecraftBlockTypes2["WaxedOxidizedCopperBulb"] = "minecraft:waxed_oxidized_copper_bulb";
        MinecraftBlockTypes2["WaxedOxidizedCopperChain"] = "minecraft:waxed_oxidized_copper_chain";
        MinecraftBlockTypes2["WaxedOxidizedCopperChest"] = "minecraft:waxed_oxidized_copper_chest";
        MinecraftBlockTypes2["WaxedOxidizedCopperDoor"] = "minecraft:waxed_oxidized_copper_door";
        MinecraftBlockTypes2["WaxedOxidizedCopperGolemStatue"] = "minecraft:waxed_oxidized_copper_golem_statue";
        MinecraftBlockTypes2["WaxedOxidizedCopperGrate"] = "minecraft:waxed_oxidized_copper_grate";
        MinecraftBlockTypes2["WaxedOxidizedCopperLantern"] = "minecraft:waxed_oxidized_copper_lantern";
        MinecraftBlockTypes2["WaxedOxidizedCopperTrapdoor"] = "minecraft:waxed_oxidized_copper_trapdoor";
        MinecraftBlockTypes2["WaxedOxidizedCutCopper"] = "minecraft:waxed_oxidized_cut_copper";
        MinecraftBlockTypes2["WaxedOxidizedCutCopperSlab"] = "minecraft:waxed_oxidized_cut_copper_slab";
        MinecraftBlockTypes2["WaxedOxidizedCutCopperStairs"] = "minecraft:waxed_oxidized_cut_copper_stairs";
        MinecraftBlockTypes2["WaxedOxidizedDoubleCutCopperSlab"] = "minecraft:waxed_oxidized_double_cut_copper_slab";
        MinecraftBlockTypes2["WaxedOxidizedLightningRod"] = "minecraft:waxed_oxidized_lightning_rod";
        MinecraftBlockTypes2["WaxedWeatheredChiseledCopper"] = "minecraft:waxed_weathered_chiseled_copper";
        MinecraftBlockTypes2["WaxedWeatheredCopper"] = "minecraft:waxed_weathered_copper";
        MinecraftBlockTypes2["WaxedWeatheredCopperBars"] = "minecraft:waxed_weathered_copper_bars";
        MinecraftBlockTypes2["WaxedWeatheredCopperBulb"] = "minecraft:waxed_weathered_copper_bulb";
        MinecraftBlockTypes2["WaxedWeatheredCopperChain"] = "minecraft:waxed_weathered_copper_chain";
        MinecraftBlockTypes2["WaxedWeatheredCopperChest"] = "minecraft:waxed_weathered_copper_chest";
        MinecraftBlockTypes2["WaxedWeatheredCopperDoor"] = "minecraft:waxed_weathered_copper_door";
        MinecraftBlockTypes2["WaxedWeatheredCopperGolemStatue"] = "minecraft:waxed_weathered_copper_golem_statue";
        MinecraftBlockTypes2["WaxedWeatheredCopperGrate"] = "minecraft:waxed_weathered_copper_grate";
        MinecraftBlockTypes2["WaxedWeatheredCopperLantern"] = "minecraft:waxed_weathered_copper_lantern";
        MinecraftBlockTypes2["WaxedWeatheredCopperTrapdoor"] = "minecraft:waxed_weathered_copper_trapdoor";
        MinecraftBlockTypes2["WaxedWeatheredCutCopper"] = "minecraft:waxed_weathered_cut_copper";
        MinecraftBlockTypes2["WaxedWeatheredCutCopperSlab"] = "minecraft:waxed_weathered_cut_copper_slab";
        MinecraftBlockTypes2["WaxedWeatheredCutCopperStairs"] = "minecraft:waxed_weathered_cut_copper_stairs";
        MinecraftBlockTypes2["WaxedWeatheredDoubleCutCopperSlab"] = "minecraft:waxed_weathered_double_cut_copper_slab";
        MinecraftBlockTypes2["WaxedWeatheredLightningRod"] = "minecraft:waxed_weathered_lightning_rod";
        MinecraftBlockTypes2["WeatheredChiseledCopper"] = "minecraft:weathered_chiseled_copper";
        MinecraftBlockTypes2["WeatheredCopper"] = "minecraft:weathered_copper";
        MinecraftBlockTypes2["WeatheredCopperBars"] = "minecraft:weathered_copper_bars";
        MinecraftBlockTypes2["WeatheredCopperBulb"] = "minecraft:weathered_copper_bulb";
        MinecraftBlockTypes2["WeatheredCopperChain"] = "minecraft:weathered_copper_chain";
        MinecraftBlockTypes2["WeatheredCopperChest"] = "minecraft:weathered_copper_chest";
        MinecraftBlockTypes2["WeatheredCopperDoor"] = "minecraft:weathered_copper_door";
        MinecraftBlockTypes2["WeatheredCopperGolemStatue"] = "minecraft:weathered_copper_golem_statue";
        MinecraftBlockTypes2["WeatheredCopperGrate"] = "minecraft:weathered_copper_grate";
        MinecraftBlockTypes2["WeatheredCopperLantern"] = "minecraft:weathered_copper_lantern";
        MinecraftBlockTypes2["WeatheredCopperTrapdoor"] = "minecraft:weathered_copper_trapdoor";
        MinecraftBlockTypes2["WeatheredCutCopper"] = "minecraft:weathered_cut_copper";
        MinecraftBlockTypes2["WeatheredCutCopperSlab"] = "minecraft:weathered_cut_copper_slab";
        MinecraftBlockTypes2["WeatheredCutCopperStairs"] = "minecraft:weathered_cut_copper_stairs";
        MinecraftBlockTypes2["WeatheredDoubleCutCopperSlab"] = "minecraft:weathered_double_cut_copper_slab";
        MinecraftBlockTypes2["WeatheredLightningRod"] = "minecraft:weathered_lightning_rod";
        MinecraftBlockTypes2["Web"] = "minecraft:web";
        MinecraftBlockTypes2["WeepingVines"] = "minecraft:weeping_vines";
        MinecraftBlockTypes2["WetSponge"] = "minecraft:wet_sponge";
        MinecraftBlockTypes2["Wheat"] = "minecraft:wheat";
        MinecraftBlockTypes2["WhiteCandle"] = "minecraft:white_candle";
        MinecraftBlockTypes2["WhiteCandleCake"] = "minecraft:white_candle_cake";
        MinecraftBlockTypes2["WhiteCarpet"] = "minecraft:white_carpet";
        MinecraftBlockTypes2["WhiteConcrete"] = "minecraft:white_concrete";
        MinecraftBlockTypes2["WhiteConcretePowder"] = "minecraft:white_concrete_powder";
        MinecraftBlockTypes2["WhiteGlazedTerracotta"] = "minecraft:white_glazed_terracotta";
        MinecraftBlockTypes2["WhiteShulkerBox"] = "minecraft:white_shulker_box";
        MinecraftBlockTypes2["WhiteStainedGlass"] = "minecraft:white_stained_glass";
        MinecraftBlockTypes2["WhiteStainedGlassPane"] = "minecraft:white_stained_glass_pane";
        MinecraftBlockTypes2["WhiteTerracotta"] = "minecraft:white_terracotta";
        MinecraftBlockTypes2["WhiteTulip"] = "minecraft:white_tulip";
        MinecraftBlockTypes2["WhiteWool"] = "minecraft:white_wool";
        MinecraftBlockTypes2["Wildflowers"] = "minecraft:wildflowers";
        MinecraftBlockTypes2["WitherRose"] = "minecraft:wither_rose";
        MinecraftBlockTypes2["WitherSkeletonSkull"] = "minecraft:wither_skeleton_skull";
        MinecraftBlockTypes2["WoodenButton"] = "minecraft:wooden_button";
        MinecraftBlockTypes2["WoodenDoor"] = "minecraft:wooden_door";
        MinecraftBlockTypes2["WoodenPressurePlate"] = "minecraft:wooden_pressure_plate";
        MinecraftBlockTypes2["YellowCandle"] = "minecraft:yellow_candle";
        MinecraftBlockTypes2["YellowCandleCake"] = "minecraft:yellow_candle_cake";
        MinecraftBlockTypes2["YellowCarpet"] = "minecraft:yellow_carpet";
        MinecraftBlockTypes2["YellowConcrete"] = "minecraft:yellow_concrete";
        MinecraftBlockTypes2["YellowConcretePowder"] = "minecraft:yellow_concrete_powder";
        MinecraftBlockTypes2["YellowGlazedTerracotta"] = "minecraft:yellow_glazed_terracotta";
        MinecraftBlockTypes2["YellowShulkerBox"] = "minecraft:yellow_shulker_box";
        MinecraftBlockTypes2["YellowStainedGlass"] = "minecraft:yellow_stained_glass";
        MinecraftBlockTypes2["YellowStainedGlassPane"] = "minecraft:yellow_stained_glass_pane";
        MinecraftBlockTypes2["YellowTerracotta"] = "minecraft:yellow_terracotta";
        MinecraftBlockTypes2["YellowWool"] = "minecraft:yellow_wool";
        MinecraftBlockTypes2["ZombieHead"] = "minecraft:zombie_head";
        return MinecraftBlockTypes2;
    })(lib_vanilla_MinecraftBlockTypes || {});
    var MinecraftCameraPresetsTypes = (MinecraftCameraPresetsTypes2 => {
        MinecraftCameraPresetsTypes2["ControlSchemeCamera"] = "minecraft:control_scheme_camera";
        MinecraftCameraPresetsTypes2["FirstPerson"] = "minecraft:first_person";
        MinecraftCameraPresetsTypes2["FixedBoom"] = "minecraft:fixed_boom";
        MinecraftCameraPresetsTypes2["FollowOrbit"] = "minecraft:follow_orbit";
        MinecraftCameraPresetsTypes2["Free"] = "minecraft:free";
        MinecraftCameraPresetsTypes2["ThirdPerson"] = "minecraft:third_person";
        MinecraftCameraPresetsTypes2["ThirdPersonFront"] = "minecraft:third_person_front";
        return MinecraftCameraPresetsTypes2;
    })(MinecraftCameraPresetsTypes || {});
    var MinecraftCooldownCategoryTypes = (MinecraftCooldownCategoryTypes2 => {
        MinecraftCooldownCategoryTypes2["Chorusfruit"] = "minecraft:chorusfruit";
        MinecraftCooldownCategoryTypes2["EnderPearl"] = "minecraft:ender_pearl";
        MinecraftCooldownCategoryTypes2["GoatHorn"] = "minecraft:goat_horn";
        MinecraftCooldownCategoryTypes2["Shield"] = "minecraft:shield";
        MinecraftCooldownCategoryTypes2["Spear"] = "minecraft:spear";
        MinecraftCooldownCategoryTypes2["WindCharge"] = "minecraft:wind_charge";
        return MinecraftCooldownCategoryTypes2;
    })(MinecraftCooldownCategoryTypes || {});
    var MinecraftDimensionTypes = (MinecraftDimensionTypes2 => {
        MinecraftDimensionTypes2["Nether"] = "minecraft:nether";
        MinecraftDimensionTypes2["Overworld"] = "minecraft:overworld";
        MinecraftDimensionTypes2["TheEnd"] = "minecraft:the_end";
        return MinecraftDimensionTypes2;
    })(MinecraftDimensionTypes || {});
    var MinecraftEffectTypes = (MinecraftEffectTypes2 => {
        MinecraftEffectTypes2["Absorption"] = "minecraft:absorption";
        MinecraftEffectTypes2["BadOmen"] = "minecraft:bad_omen";
        MinecraftEffectTypes2["Blindness"] = "minecraft:blindness";
        MinecraftEffectTypes2["BreathOfTheNautilus"] = "minecraft:breath_of_the_nautilus";
        MinecraftEffectTypes2["ConduitPower"] = "minecraft:conduit_power";
        MinecraftEffectTypes2["Darkness"] = "minecraft:darkness";
        MinecraftEffectTypes2["FatalPoison"] = "minecraft:fatal_poison";
        MinecraftEffectTypes2["FireResistance"] = "minecraft:fire_resistance";
        MinecraftEffectTypes2["Haste"] = "minecraft:haste";
        MinecraftEffectTypes2["HealthBoost"] = "minecraft:health_boost";
        MinecraftEffectTypes2["Hunger"] = "minecraft:hunger";
        MinecraftEffectTypes2["Infested"] = "minecraft:infested";
        MinecraftEffectTypes2["InstantDamage"] = "minecraft:instant_damage";
        MinecraftEffectTypes2["InstantHealth"] = "minecraft:instant_health";
        MinecraftEffectTypes2["Invisibility"] = "minecraft:invisibility";
        MinecraftEffectTypes2["JumpBoost"] = "minecraft:jump_boost";
        MinecraftEffectTypes2["Levitation"] = "minecraft:levitation";
        MinecraftEffectTypes2["MiningFatigue"] = "minecraft:mining_fatigue";
        MinecraftEffectTypes2["Nausea"] = "minecraft:nausea";
        MinecraftEffectTypes2["NightVision"] = "minecraft:night_vision";
        MinecraftEffectTypes2["Oozing"] = "minecraft:oozing";
        MinecraftEffectTypes2["Poison"] = "minecraft:poison";
        MinecraftEffectTypes2["RaidOmen"] = "minecraft:raid_omen";
        MinecraftEffectTypes2["Regeneration"] = "minecraft:regeneration";
        MinecraftEffectTypes2["Resistance"] = "minecraft:resistance";
        MinecraftEffectTypes2["Saturation"] = "minecraft:saturation";
        MinecraftEffectTypes2["SlowFalling"] = "minecraft:slow_falling";
        MinecraftEffectTypes2["Slowness"] = "minecraft:slowness";
        MinecraftEffectTypes2["Speed"] = "minecraft:speed";
        MinecraftEffectTypes2["Strength"] = "minecraft:strength";
        MinecraftEffectTypes2["TrialOmen"] = "minecraft:trial_omen";
        MinecraftEffectTypes2["VillageHero"] = "minecraft:village_hero";
        MinecraftEffectTypes2["WaterBreathing"] = "minecraft:water_breathing";
        MinecraftEffectTypes2["Weakness"] = "minecraft:weakness";
        MinecraftEffectTypes2["Weaving"] = "minecraft:weaving";
        MinecraftEffectTypes2["WindCharged"] = "minecraft:wind_charged";
        MinecraftEffectTypes2["Wither"] = "minecraft:wither";
        return MinecraftEffectTypes2;
    })(MinecraftEffectTypes || {});
    var MinecraftEnchantmentTypes = (MinecraftEnchantmentTypes2 => {
        MinecraftEnchantmentTypes2["AquaAffinity"] = "minecraft:aqua_affinity";
        MinecraftEnchantmentTypes2["BaneOfArthropods"] = "minecraft:bane_of_arthropods";
        MinecraftEnchantmentTypes2["Binding"] = "minecraft:binding";
        MinecraftEnchantmentTypes2["BlastProtection"] = "minecraft:blast_protection";
        MinecraftEnchantmentTypes2["BowInfinity"] = "minecraft:infinity";
        MinecraftEnchantmentTypes2["Breach"] = "minecraft:breach";
        MinecraftEnchantmentTypes2["Channeling"] = "minecraft:channeling";
        MinecraftEnchantmentTypes2["Density"] = "minecraft:density";
        MinecraftEnchantmentTypes2["DepthStrider"] = "minecraft:depth_strider";
        MinecraftEnchantmentTypes2["Efficiency"] = "minecraft:efficiency";
        MinecraftEnchantmentTypes2["FeatherFalling"] = "minecraft:feather_falling";
        MinecraftEnchantmentTypes2["FireAspect"] = "minecraft:fire_aspect";
        MinecraftEnchantmentTypes2["FireProtection"] = "minecraft:fire_protection";
        MinecraftEnchantmentTypes2["Flame"] = "minecraft:flame";
        MinecraftEnchantmentTypes2["Fortune"] = "minecraft:fortune";
        MinecraftEnchantmentTypes2["FrostWalker"] = "minecraft:frost_walker";
        MinecraftEnchantmentTypes2["Impaling"] = "minecraft:impaling";
        MinecraftEnchantmentTypes2["Knockback"] = "minecraft:knockback";
        MinecraftEnchantmentTypes2["Looting"] = "minecraft:looting";
        MinecraftEnchantmentTypes2["Loyalty"] = "minecraft:loyalty";
        MinecraftEnchantmentTypes2["LuckOfTheSea"] = "minecraft:luck_of_the_sea";
        MinecraftEnchantmentTypes2["Lunge"] = "minecraft:lunge";
        MinecraftEnchantmentTypes2["Lure"] = "minecraft:lure";
        MinecraftEnchantmentTypes2["Mending"] = "minecraft:mending";
        MinecraftEnchantmentTypes2["Multishot"] = "minecraft:multishot";
        MinecraftEnchantmentTypes2["Piercing"] = "minecraft:piercing";
        MinecraftEnchantmentTypes2["Power"] = "minecraft:power";
        MinecraftEnchantmentTypes2["ProjectileProtection"] = "minecraft:projectile_protection";
        MinecraftEnchantmentTypes2["Protection"] = "minecraft:protection";
        MinecraftEnchantmentTypes2["Punch"] = "minecraft:punch";
        MinecraftEnchantmentTypes2["QuickCharge"] = "minecraft:quick_charge";
        MinecraftEnchantmentTypes2["Respiration"] = "minecraft:respiration";
        MinecraftEnchantmentTypes2["Riptide"] = "minecraft:riptide";
        MinecraftEnchantmentTypes2["Sharpness"] = "minecraft:sharpness";
        MinecraftEnchantmentTypes2["SilkTouch"] = "minecraft:silk_touch";
        MinecraftEnchantmentTypes2["Smite"] = "minecraft:smite";
        MinecraftEnchantmentTypes2["SoulSpeed"] = "minecraft:soul_speed";
        MinecraftEnchantmentTypes2["SwiftSneak"] = "minecraft:swift_sneak";
        MinecraftEnchantmentTypes2["Thorns"] = "minecraft:thorns";
        MinecraftEnchantmentTypes2["Unbreaking"] = "minecraft:unbreaking";
        MinecraftEnchantmentTypes2["Vanishing"] = "minecraft:vanishing";
        MinecraftEnchantmentTypes2["WindBurst"] = "minecraft:wind_burst";
        return MinecraftEnchantmentTypes2;
    })(MinecraftEnchantmentTypes || {});
    var MinecraftEntityTypes = (MinecraftEntityTypes2 => {
        MinecraftEntityTypes2["Agent"] = "minecraft:agent";
        MinecraftEntityTypes2["Allay"] = "minecraft:allay";
        MinecraftEntityTypes2["AreaEffectCloud"] = "minecraft:area_effect_cloud";
        MinecraftEntityTypes2["Armadillo"] = "minecraft:armadillo";
        MinecraftEntityTypes2["ArmorStand"] = "minecraft:armor_stand";
        MinecraftEntityTypes2["Arrow"] = "minecraft:arrow";
        MinecraftEntityTypes2["Axolotl"] = "minecraft:axolotl";
        MinecraftEntityTypes2["Bat"] = "minecraft:bat";
        MinecraftEntityTypes2["Bee"] = "minecraft:bee";
        MinecraftEntityTypes2["Blaze"] = "minecraft:blaze";
        MinecraftEntityTypes2["Boat"] = "minecraft:boat";
        MinecraftEntityTypes2["Bogged"] = "minecraft:bogged";
        MinecraftEntityTypes2["Breeze"] = "minecraft:breeze";
        MinecraftEntityTypes2["BreezeWindChargeProjectile"] = "minecraft:breeze_wind_charge_projectile";
        MinecraftEntityTypes2["Camel"] = "minecraft:camel";
        MinecraftEntityTypes2["CamelHusk"] = "minecraft:camel_husk";
        MinecraftEntityTypes2["Cat"] = "minecraft:cat";
        MinecraftEntityTypes2["CaveSpider"] = "minecraft:cave_spider";
        MinecraftEntityTypes2["ChestBoat"] = "minecraft:chest_boat";
        MinecraftEntityTypes2["ChestMinecart"] = "minecraft:chest_minecart";
        MinecraftEntityTypes2["Chicken"] = "minecraft:chicken";
        MinecraftEntityTypes2["Cod"] = "minecraft:cod";
        MinecraftEntityTypes2["CommandBlockMinecart"] = "minecraft:command_block_minecart";
        MinecraftEntityTypes2["CopperGolem"] = "minecraft:copper_golem";
        MinecraftEntityTypes2["Cow"] = "minecraft:cow";
        MinecraftEntityTypes2["Creaking"] = "minecraft:creaking";
        MinecraftEntityTypes2["Creeper"] = "minecraft:creeper";
        MinecraftEntityTypes2["Dolphin"] = "minecraft:dolphin";
        MinecraftEntityTypes2["Donkey"] = "minecraft:donkey";
        MinecraftEntityTypes2["DragonFireball"] = "minecraft:dragon_fireball";
        MinecraftEntityTypes2["Drowned"] = "minecraft:drowned";
        MinecraftEntityTypes2["Egg"] = "minecraft:egg";
        MinecraftEntityTypes2["ElderGuardian"] = "minecraft:elder_guardian";
        MinecraftEntityTypes2["EnderCrystal"] = "minecraft:ender_crystal";
        MinecraftEntityTypes2["EnderDragon"] = "minecraft:ender_dragon";
        MinecraftEntityTypes2["EnderPearl"] = "minecraft:ender_pearl";
        MinecraftEntityTypes2["Enderman"] = "minecraft:enderman";
        MinecraftEntityTypes2["Endermite"] = "minecraft:endermite";
        MinecraftEntityTypes2["EvocationIllager"] = "minecraft:evocation_illager";
        MinecraftEntityTypes2["EyeOfEnderSignal"] = "minecraft:eye_of_ender_signal";
        MinecraftEntityTypes2["Fireball"] = "minecraft:fireball";
        MinecraftEntityTypes2["FireworksRocket"] = "minecraft:fireworks_rocket";
        MinecraftEntityTypes2["FishingHook"] = "minecraft:fishing_hook";
        MinecraftEntityTypes2["Fox"] = "minecraft:fox";
        MinecraftEntityTypes2["Frog"] = "minecraft:frog";
        MinecraftEntityTypes2["Ghast"] = "minecraft:ghast";
        MinecraftEntityTypes2["GlowSquid"] = "minecraft:glow_squid";
        MinecraftEntityTypes2["Goat"] = "minecraft:goat";
        MinecraftEntityTypes2["Guardian"] = "minecraft:guardian";
        MinecraftEntityTypes2["HappyGhast"] = "minecraft:happy_ghast";
        MinecraftEntityTypes2["Hoglin"] = "minecraft:hoglin";
        MinecraftEntityTypes2["HopperMinecart"] = "minecraft:hopper_minecart";
        MinecraftEntityTypes2["Horse"] = "minecraft:horse";
        MinecraftEntityTypes2["Husk"] = "minecraft:husk";
        MinecraftEntityTypes2["IronGolem"] = "minecraft:iron_golem";
        MinecraftEntityTypes2["LightningBolt"] = "minecraft:lightning_bolt";
        MinecraftEntityTypes2["LingeringPotion"] = "minecraft:lingering_potion";
        MinecraftEntityTypes2["Llama"] = "minecraft:llama";
        MinecraftEntityTypes2["LlamaSpit"] = "minecraft:llama_spit";
        MinecraftEntityTypes2["MagmaCube"] = "minecraft:magma_cube";
        MinecraftEntityTypes2["Minecart"] = "minecraft:minecart";
        MinecraftEntityTypes2["Mooshroom"] = "minecraft:mooshroom";
        MinecraftEntityTypes2["Mule"] = "minecraft:mule";
        MinecraftEntityTypes2["Nautilus"] = "minecraft:nautilus";
        MinecraftEntityTypes2["Npc"] = "minecraft:npc";
        MinecraftEntityTypes2["Ocelot"] = "minecraft:ocelot";
        MinecraftEntityTypes2["OminousItemSpawner"] = "minecraft:ominous_item_spawner";
        MinecraftEntityTypes2["Panda"] = "minecraft:panda";
        MinecraftEntityTypes2["Parched"] = "minecraft:parched";
        MinecraftEntityTypes2["Parrot"] = "minecraft:parrot";
        MinecraftEntityTypes2["Phantom"] = "minecraft:phantom";
        MinecraftEntityTypes2["Pig"] = "minecraft:pig";
        MinecraftEntityTypes2["Piglin"] = "minecraft:piglin";
        MinecraftEntityTypes2["PiglinBrute"] = "minecraft:piglin_brute";
        MinecraftEntityTypes2["Pillager"] = "minecraft:pillager";
        MinecraftEntityTypes2["Player"] = "minecraft:player";
        MinecraftEntityTypes2["PolarBear"] = "minecraft:polar_bear";
        MinecraftEntityTypes2["Pufferfish"] = "minecraft:pufferfish";
        MinecraftEntityTypes2["Rabbit"] = "minecraft:rabbit";
        MinecraftEntityTypes2["Ravager"] = "minecraft:ravager";
        MinecraftEntityTypes2["Salmon"] = "minecraft:salmon";
        MinecraftEntityTypes2["Sheep"] = "minecraft:sheep";
        MinecraftEntityTypes2["Shulker"] = "minecraft:shulker";
        MinecraftEntityTypes2["ShulkerBullet"] = "minecraft:shulker_bullet";
        MinecraftEntityTypes2["Silverfish"] = "minecraft:silverfish";
        MinecraftEntityTypes2["Skeleton"] = "minecraft:skeleton";
        MinecraftEntityTypes2["SkeletonHorse"] = "minecraft:skeleton_horse";
        MinecraftEntityTypes2["Slime"] = "minecraft:slime";
        MinecraftEntityTypes2["SmallFireball"] = "minecraft:small_fireball";
        MinecraftEntityTypes2["Sniffer"] = "minecraft:sniffer";
        MinecraftEntityTypes2["SnowGolem"] = "minecraft:snow_golem";
        MinecraftEntityTypes2["Snowball"] = "minecraft:snowball";
        MinecraftEntityTypes2["Spider"] = "minecraft:spider";
        MinecraftEntityTypes2["SplashPotion"] = "minecraft:splash_potion";
        MinecraftEntityTypes2["Squid"] = "minecraft:squid";
        MinecraftEntityTypes2["Stray"] = "minecraft:stray";
        MinecraftEntityTypes2["Strider"] = "minecraft:strider";
        MinecraftEntityTypes2["Tadpole"] = "minecraft:tadpole";
        MinecraftEntityTypes2["ThrownTrident"] = "minecraft:thrown_trident";
        MinecraftEntityTypes2["Tnt"] = "minecraft:tnt";
        MinecraftEntityTypes2["TntMinecart"] = "minecraft:tnt_minecart";
        MinecraftEntityTypes2["TraderLlama"] = "minecraft:trader_llama";
        MinecraftEntityTypes2["TripodCamera"] = "minecraft:tripod_camera";
        MinecraftEntityTypes2["Tropicalfish"] = "minecraft:tropicalfish";
        MinecraftEntityTypes2["Turtle"] = "minecraft:turtle";
        MinecraftEntityTypes2["Vex"] = "minecraft:vex";
        MinecraftEntityTypes2["Villager"] = "minecraft:villager";
        MinecraftEntityTypes2["VillagerV2"] = "minecraft:villager_v2";
        MinecraftEntityTypes2["Vindicator"] = "minecraft:vindicator";
        MinecraftEntityTypes2["WanderingTrader"] = "minecraft:wandering_trader";
        MinecraftEntityTypes2["Warden"] = "minecraft:warden";
        MinecraftEntityTypes2["WindChargeProjectile"] = "minecraft:wind_charge_projectile";
        MinecraftEntityTypes2["Witch"] = "minecraft:witch";
        MinecraftEntityTypes2["Wither"] = "minecraft:wither";
        MinecraftEntityTypes2["WitherSkeleton"] = "minecraft:wither_skeleton";
        MinecraftEntityTypes2["WitherSkull"] = "minecraft:wither_skull";
        MinecraftEntityTypes2["WitherSkullDangerous"] = "minecraft:wither_skull_dangerous";
        MinecraftEntityTypes2["Wolf"] = "minecraft:wolf";
        MinecraftEntityTypes2["XpBottle"] = "minecraft:xp_bottle";
        MinecraftEntityTypes2["XpOrb"] = "minecraft:xp_orb";
        MinecraftEntityTypes2["Zoglin"] = "minecraft:zoglin";
        MinecraftEntityTypes2["Zombie"] = "minecraft:zombie";
        MinecraftEntityTypes2["ZombieHorse"] = "minecraft:zombie_horse";
        MinecraftEntityTypes2["ZombieNautilus"] = "minecraft:zombie_nautilus";
        MinecraftEntityTypes2["ZombiePigman"] = "minecraft:zombie_pigman";
        MinecraftEntityTypes2["ZombieVillager"] = "minecraft:zombie_villager";
        MinecraftEntityTypes2["ZombieVillagerV2"] = "minecraft:zombie_villager_v2";
        return MinecraftEntityTypes2;
    })(MinecraftEntityTypes || {});
    var MinecraftFeatureTypes = (MinecraftFeatureTypes2 => {
        MinecraftFeatureTypes2["AncientCity"] = "minecraft:ancient_city";
        MinecraftFeatureTypes2["BastionRemnant"] = "minecraft:bastion_remnant";
        MinecraftFeatureTypes2["BuriedTreasure"] = "minecraft:buried_treasure";
        MinecraftFeatureTypes2["EndCity"] = "minecraft:end_city";
        MinecraftFeatureTypes2["Fortress"] = "minecraft:fortress";
        MinecraftFeatureTypes2["Mansion"] = "minecraft:mansion";
        MinecraftFeatureTypes2["Mineshaft"] = "minecraft:mineshaft";
        MinecraftFeatureTypes2["Monument"] = "minecraft:monument";
        MinecraftFeatureTypes2["PillagerOutpost"] = "minecraft:pillager_outpost";
        MinecraftFeatureTypes2["RuinedPortal"] = "minecraft:ruined_portal";
        MinecraftFeatureTypes2["Ruins"] = "minecraft:ruins";
        MinecraftFeatureTypes2["Shipwreck"] = "minecraft:shipwreck";
        MinecraftFeatureTypes2["Stronghold"] = "minecraft:stronghold";
        MinecraftFeatureTypes2["Temple"] = "minecraft:temple";
        MinecraftFeatureTypes2["TrailRuins"] = "minecraft:trail_ruins";
        MinecraftFeatureTypes2["TrialChambers"] = "minecraft:trial_chambers";
        MinecraftFeatureTypes2["Village"] = "minecraft:village";
        return MinecraftFeatureTypes2;
    })(MinecraftFeatureTypes || {});
    var MinecraftItemTypes = (MinecraftItemTypes2 => {
        MinecraftItemTypes2["AcaciaBoat"] = "minecraft:acacia_boat";
        MinecraftItemTypes2["AcaciaButton"] = "minecraft:acacia_button";
        MinecraftItemTypes2["AcaciaChestBoat"] = "minecraft:acacia_chest_boat";
        MinecraftItemTypes2["AcaciaDoor"] = "minecraft:acacia_door";
        MinecraftItemTypes2["AcaciaFence"] = "minecraft:acacia_fence";
        MinecraftItemTypes2["AcaciaFenceGate"] = "minecraft:acacia_fence_gate";
        MinecraftItemTypes2["AcaciaHangingSign"] = "minecraft:acacia_hanging_sign";
        MinecraftItemTypes2["AcaciaLeaves"] = "minecraft:acacia_leaves";
        MinecraftItemTypes2["AcaciaLog"] = "minecraft:acacia_log";
        MinecraftItemTypes2["AcaciaPlanks"] = "minecraft:acacia_planks";
        MinecraftItemTypes2["AcaciaPressurePlate"] = "minecraft:acacia_pressure_plate";
        MinecraftItemTypes2["AcaciaSapling"] = "minecraft:acacia_sapling";
        MinecraftItemTypes2["AcaciaShelf"] = "minecraft:acacia_shelf";
        MinecraftItemTypes2["AcaciaSign"] = "minecraft:acacia_sign";
        MinecraftItemTypes2["AcaciaSlab"] = "minecraft:acacia_slab";
        MinecraftItemTypes2["AcaciaStairs"] = "minecraft:acacia_stairs";
        MinecraftItemTypes2["AcaciaTrapdoor"] = "minecraft:acacia_trapdoor";
        MinecraftItemTypes2["AcaciaWood"] = "minecraft:acacia_wood";
        MinecraftItemTypes2["ActivatorRail"] = "minecraft:activator_rail";
        MinecraftItemTypes2["AllaySpawnEgg"] = "minecraft:allay_spawn_egg";
        MinecraftItemTypes2["Allium"] = "minecraft:allium";
        MinecraftItemTypes2["Allow"] = "minecraft:allow";
        MinecraftItemTypes2["AmethystBlock"] = "minecraft:amethyst_block";
        MinecraftItemTypes2["AmethystCluster"] = "minecraft:amethyst_cluster";
        MinecraftItemTypes2["AmethystShard"] = "minecraft:amethyst_shard";
        MinecraftItemTypes2["AncientDebris"] = "minecraft:ancient_debris";
        MinecraftItemTypes2["Andesite"] = "minecraft:andesite";
        MinecraftItemTypes2["AndesiteSlab"] = "minecraft:andesite_slab";
        MinecraftItemTypes2["AndesiteStairs"] = "minecraft:andesite_stairs";
        MinecraftItemTypes2["AndesiteWall"] = "minecraft:andesite_wall";
        MinecraftItemTypes2["AnglerPotterySherd"] = "minecraft:angler_pottery_sherd";
        MinecraftItemTypes2["Anvil"] = "minecraft:anvil";
        MinecraftItemTypes2["Apple"] = "minecraft:apple";
        MinecraftItemTypes2["ArcherPotterySherd"] = "minecraft:archer_pottery_sherd";
        MinecraftItemTypes2["ArmadilloScute"] = "minecraft:armadillo_scute";
        MinecraftItemTypes2["ArmadilloSpawnEgg"] = "minecraft:armadillo_spawn_egg";
        MinecraftItemTypes2["ArmorStand"] = "minecraft:armor_stand";
        MinecraftItemTypes2["ArmsUpPotterySherd"] = "minecraft:arms_up_pottery_sherd";
        MinecraftItemTypes2["Arrow"] = "minecraft:arrow";
        MinecraftItemTypes2["AxolotlBucket"] = "minecraft:axolotl_bucket";
        MinecraftItemTypes2["AxolotlSpawnEgg"] = "minecraft:axolotl_spawn_egg";
        MinecraftItemTypes2["Azalea"] = "minecraft:azalea";
        MinecraftItemTypes2["AzaleaLeaves"] = "minecraft:azalea_leaves";
        MinecraftItemTypes2["AzaleaLeavesFlowered"] = "minecraft:azalea_leaves_flowered";
        MinecraftItemTypes2["AzureBluet"] = "minecraft:azure_bluet";
        MinecraftItemTypes2["BakedPotato"] = "minecraft:baked_potato";
        MinecraftItemTypes2["Bamboo"] = "minecraft:bamboo";
        MinecraftItemTypes2["BambooBlock"] = "minecraft:bamboo_block";
        MinecraftItemTypes2["BambooButton"] = "minecraft:bamboo_button";
        MinecraftItemTypes2["BambooChestRaft"] = "minecraft:bamboo_chest_raft";
        MinecraftItemTypes2["BambooDoor"] = "minecraft:bamboo_door";
        MinecraftItemTypes2["BambooFence"] = "minecraft:bamboo_fence";
        MinecraftItemTypes2["BambooFenceGate"] = "minecraft:bamboo_fence_gate";
        MinecraftItemTypes2["BambooHangingSign"] = "minecraft:bamboo_hanging_sign";
        MinecraftItemTypes2["BambooMosaic"] = "minecraft:bamboo_mosaic";
        MinecraftItemTypes2["BambooMosaicSlab"] = "minecraft:bamboo_mosaic_slab";
        MinecraftItemTypes2["BambooMosaicStairs"] = "minecraft:bamboo_mosaic_stairs";
        MinecraftItemTypes2["BambooPlanks"] = "minecraft:bamboo_planks";
        MinecraftItemTypes2["BambooPressurePlate"] = "minecraft:bamboo_pressure_plate";
        MinecraftItemTypes2["BambooRaft"] = "minecraft:bamboo_raft";
        MinecraftItemTypes2["BambooShelf"] = "minecraft:bamboo_shelf";
        MinecraftItemTypes2["BambooSign"] = "minecraft:bamboo_sign";
        MinecraftItemTypes2["BambooSlab"] = "minecraft:bamboo_slab";
        MinecraftItemTypes2["BambooStairs"] = "minecraft:bamboo_stairs";
        MinecraftItemTypes2["BambooTrapdoor"] = "minecraft:bamboo_trapdoor";
        MinecraftItemTypes2["Banner"] = "minecraft:banner";
        MinecraftItemTypes2["Barrel"] = "minecraft:barrel";
        MinecraftItemTypes2["Barrier"] = "minecraft:barrier";
        MinecraftItemTypes2["Basalt"] = "minecraft:basalt";
        MinecraftItemTypes2["BatSpawnEgg"] = "minecraft:bat_spawn_egg";
        MinecraftItemTypes2["Beacon"] = "minecraft:beacon";
        MinecraftItemTypes2["Bed"] = "minecraft:bed";
        MinecraftItemTypes2["Bedrock"] = "minecraft:bedrock";
        MinecraftItemTypes2["BeeNest"] = "minecraft:bee_nest";
        MinecraftItemTypes2["BeeSpawnEgg"] = "minecraft:bee_spawn_egg";
        MinecraftItemTypes2["Beef"] = "minecraft:beef";
        MinecraftItemTypes2["Beehive"] = "minecraft:beehive";
        MinecraftItemTypes2["Beetroot"] = "minecraft:beetroot";
        MinecraftItemTypes2["BeetrootSeeds"] = "minecraft:beetroot_seeds";
        MinecraftItemTypes2["BeetrootSoup"] = "minecraft:beetroot_soup";
        MinecraftItemTypes2["Bell"] = "minecraft:bell";
        MinecraftItemTypes2["BigDripleaf"] = "minecraft:big_dripleaf";
        MinecraftItemTypes2["BirchBoat"] = "minecraft:birch_boat";
        MinecraftItemTypes2["BirchButton"] = "minecraft:birch_button";
        MinecraftItemTypes2["BirchChestBoat"] = "minecraft:birch_chest_boat";
        MinecraftItemTypes2["BirchDoor"] = "minecraft:birch_door";
        MinecraftItemTypes2["BirchFence"] = "minecraft:birch_fence";
        MinecraftItemTypes2["BirchFenceGate"] = "minecraft:birch_fence_gate";
        MinecraftItemTypes2["BirchHangingSign"] = "minecraft:birch_hanging_sign";
        MinecraftItemTypes2["BirchLeaves"] = "minecraft:birch_leaves";
        MinecraftItemTypes2["BirchLog"] = "minecraft:birch_log";
        MinecraftItemTypes2["BirchPlanks"] = "minecraft:birch_planks";
        MinecraftItemTypes2["BirchPressurePlate"] = "minecraft:birch_pressure_plate";
        MinecraftItemTypes2["BirchSapling"] = "minecraft:birch_sapling";
        MinecraftItemTypes2["BirchShelf"] = "minecraft:birch_shelf";
        MinecraftItemTypes2["BirchSign"] = "minecraft:birch_sign";
        MinecraftItemTypes2["BirchSlab"] = "minecraft:birch_slab";
        MinecraftItemTypes2["BirchStairs"] = "minecraft:birch_stairs";
        MinecraftItemTypes2["BirchTrapdoor"] = "minecraft:birch_trapdoor";
        MinecraftItemTypes2["BirchWood"] = "minecraft:birch_wood";
        MinecraftItemTypes2["BlackBundle"] = "minecraft:black_bundle";
        MinecraftItemTypes2["BlackCandle"] = "minecraft:black_candle";
        MinecraftItemTypes2["BlackCarpet"] = "minecraft:black_carpet";
        MinecraftItemTypes2["BlackConcrete"] = "minecraft:black_concrete";
        MinecraftItemTypes2["BlackConcretePowder"] = "minecraft:black_concrete_powder";
        MinecraftItemTypes2["BlackDye"] = "minecraft:black_dye";
        MinecraftItemTypes2["BlackGlazedTerracotta"] = "minecraft:black_glazed_terracotta";
        MinecraftItemTypes2["BlackHarness"] = "minecraft:black_harness";
        MinecraftItemTypes2["BlackShulkerBox"] = "minecraft:black_shulker_box";
        MinecraftItemTypes2["BlackStainedGlass"] = "minecraft:black_stained_glass";
        MinecraftItemTypes2["BlackStainedGlassPane"] = "minecraft:black_stained_glass_pane";
        MinecraftItemTypes2["BlackTerracotta"] = "minecraft:black_terracotta";
        MinecraftItemTypes2["BlackWool"] = "minecraft:black_wool";
        MinecraftItemTypes2["Blackstone"] = "minecraft:blackstone";
        MinecraftItemTypes2["BlackstoneSlab"] = "minecraft:blackstone_slab";
        MinecraftItemTypes2["BlackstoneStairs"] = "minecraft:blackstone_stairs";
        MinecraftItemTypes2["BlackstoneWall"] = "minecraft:blackstone_wall";
        MinecraftItemTypes2["BladePotterySherd"] = "minecraft:blade_pottery_sherd";
        MinecraftItemTypes2["BlastFurnace"] = "minecraft:blast_furnace";
        MinecraftItemTypes2["BlazePowder"] = "minecraft:blaze_powder";
        MinecraftItemTypes2["BlazeRod"] = "minecraft:blaze_rod";
        MinecraftItemTypes2["BlazeSpawnEgg"] = "minecraft:blaze_spawn_egg";
        MinecraftItemTypes2["BlueBundle"] = "minecraft:blue_bundle";
        MinecraftItemTypes2["BlueCandle"] = "minecraft:blue_candle";
        MinecraftItemTypes2["BlueCarpet"] = "minecraft:blue_carpet";
        MinecraftItemTypes2["BlueConcrete"] = "minecraft:blue_concrete";
        MinecraftItemTypes2["BlueConcretePowder"] = "minecraft:blue_concrete_powder";
        MinecraftItemTypes2["BlueDye"] = "minecraft:blue_dye";
        MinecraftItemTypes2["BlueEgg"] = "minecraft:blue_egg";
        MinecraftItemTypes2["BlueGlazedTerracotta"] = "minecraft:blue_glazed_terracotta";
        MinecraftItemTypes2["BlueHarness"] = "minecraft:blue_harness";
        MinecraftItemTypes2["BlueIce"] = "minecraft:blue_ice";
        MinecraftItemTypes2["BlueOrchid"] = "minecraft:blue_orchid";
        MinecraftItemTypes2["BlueShulkerBox"] = "minecraft:blue_shulker_box";
        MinecraftItemTypes2["BlueStainedGlass"] = "minecraft:blue_stained_glass";
        MinecraftItemTypes2["BlueStainedGlassPane"] = "minecraft:blue_stained_glass_pane";
        MinecraftItemTypes2["BlueTerracotta"] = "minecraft:blue_terracotta";
        MinecraftItemTypes2["BlueWool"] = "minecraft:blue_wool";
        MinecraftItemTypes2["BoggedSpawnEgg"] = "minecraft:bogged_spawn_egg";
        MinecraftItemTypes2["BoltArmorTrimSmithingTemplate"] = "minecraft:bolt_armor_trim_smithing_template";
        MinecraftItemTypes2["Bone"] = "minecraft:bone";
        MinecraftItemTypes2["BoneBlock"] = "minecraft:bone_block";
        MinecraftItemTypes2["BoneMeal"] = "minecraft:bone_meal";
        MinecraftItemTypes2["Book"] = "minecraft:book";
        MinecraftItemTypes2["Bookshelf"] = "minecraft:bookshelf";
        MinecraftItemTypes2["BorderBlock"] = "minecraft:border_block";
        MinecraftItemTypes2["BordureIndentedBannerPattern"] = "minecraft:bordure_indented_banner_pattern";
        MinecraftItemTypes2["Bow"] = "minecraft:bow";
        MinecraftItemTypes2["Bowl"] = "minecraft:bowl";
        MinecraftItemTypes2["BrainCoral"] = "minecraft:brain_coral";
        MinecraftItemTypes2["BrainCoralBlock"] = "minecraft:brain_coral_block";
        MinecraftItemTypes2["BrainCoralFan"] = "minecraft:brain_coral_fan";
        MinecraftItemTypes2["Bread"] = "minecraft:bread";
        MinecraftItemTypes2["BreezeRod"] = "minecraft:breeze_rod";
        MinecraftItemTypes2["BreezeSpawnEgg"] = "minecraft:breeze_spawn_egg";
        MinecraftItemTypes2["BrewerPotterySherd"] = "minecraft:brewer_pottery_sherd";
        MinecraftItemTypes2["BrewingStand"] = "minecraft:brewing_stand";
        MinecraftItemTypes2["Brick"] = "minecraft:brick";
        MinecraftItemTypes2["BrickBlock"] = "minecraft:brick_block";
        MinecraftItemTypes2["BrickSlab"] = "minecraft:brick_slab";
        MinecraftItemTypes2["BrickStairs"] = "minecraft:brick_stairs";
        MinecraftItemTypes2["BrickWall"] = "minecraft:brick_wall";
        MinecraftItemTypes2["BrownBundle"] = "minecraft:brown_bundle";
        MinecraftItemTypes2["BrownCandle"] = "minecraft:brown_candle";
        MinecraftItemTypes2["BrownCarpet"] = "minecraft:brown_carpet";
        MinecraftItemTypes2["BrownConcrete"] = "minecraft:brown_concrete";
        MinecraftItemTypes2["BrownConcretePowder"] = "minecraft:brown_concrete_powder";
        MinecraftItemTypes2["BrownDye"] = "minecraft:brown_dye";
        MinecraftItemTypes2["BrownEgg"] = "minecraft:brown_egg";
        MinecraftItemTypes2["BrownGlazedTerracotta"] = "minecraft:brown_glazed_terracotta";
        MinecraftItemTypes2["BrownHarness"] = "minecraft:brown_harness";
        MinecraftItemTypes2["BrownMushroom"] = "minecraft:brown_mushroom";
        MinecraftItemTypes2["BrownMushroomBlock"] = "minecraft:brown_mushroom_block";
        MinecraftItemTypes2["BrownShulkerBox"] = "minecraft:brown_shulker_box";
        MinecraftItemTypes2["BrownStainedGlass"] = "minecraft:brown_stained_glass";
        MinecraftItemTypes2["BrownStainedGlassPane"] = "minecraft:brown_stained_glass_pane";
        MinecraftItemTypes2["BrownTerracotta"] = "minecraft:brown_terracotta";
        MinecraftItemTypes2["BrownWool"] = "minecraft:brown_wool";
        MinecraftItemTypes2["Brush"] = "minecraft:brush";
        MinecraftItemTypes2["BubbleCoral"] = "minecraft:bubble_coral";
        MinecraftItemTypes2["BubbleCoralBlock"] = "minecraft:bubble_coral_block";
        MinecraftItemTypes2["BubbleCoralFan"] = "minecraft:bubble_coral_fan";
        MinecraftItemTypes2["Bucket"] = "minecraft:bucket";
        MinecraftItemTypes2["BuddingAmethyst"] = "minecraft:budding_amethyst";
        MinecraftItemTypes2["Bundle"] = "minecraft:bundle";
        MinecraftItemTypes2["BurnPotterySherd"] = "minecraft:burn_pottery_sherd";
        MinecraftItemTypes2["Bush"] = "minecraft:bush";
        MinecraftItemTypes2["Cactus"] = "minecraft:cactus";
        MinecraftItemTypes2["CactusFlower"] = "minecraft:cactus_flower";
        MinecraftItemTypes2["Cake"] = "minecraft:cake";
        MinecraftItemTypes2["Calcite"] = "minecraft:calcite";
        MinecraftItemTypes2["CalibratedSculkSensor"] = "minecraft:calibrated_sculk_sensor";
        MinecraftItemTypes2["CamelHuskSpawnEgg"] = "minecraft:camel_husk_spawn_egg";
        MinecraftItemTypes2["CamelSpawnEgg"] = "minecraft:camel_spawn_egg";
        MinecraftItemTypes2["Campfire"] = "minecraft:campfire";
        MinecraftItemTypes2["Candle"] = "minecraft:candle";
        MinecraftItemTypes2["Carrot"] = "minecraft:carrot";
        MinecraftItemTypes2["CarrotOnAStick"] = "minecraft:carrot_on_a_stick";
        MinecraftItemTypes2["CartographyTable"] = "minecraft:cartography_table";
        MinecraftItemTypes2["CarvedPumpkin"] = "minecraft:carved_pumpkin";
        MinecraftItemTypes2["CatSpawnEgg"] = "minecraft:cat_spawn_egg";
        MinecraftItemTypes2["Cauldron"] = "minecraft:cauldron";
        MinecraftItemTypes2["CaveSpiderSpawnEgg"] = "minecraft:cave_spider_spawn_egg";
        MinecraftItemTypes2["ChainCommandBlock"] = "minecraft:chain_command_block";
        MinecraftItemTypes2["ChainmailBoots"] = "minecraft:chainmail_boots";
        MinecraftItemTypes2["ChainmailChestplate"] = "minecraft:chainmail_chestplate";
        MinecraftItemTypes2["ChainmailHelmet"] = "minecraft:chainmail_helmet";
        MinecraftItemTypes2["ChainmailLeggings"] = "minecraft:chainmail_leggings";
        MinecraftItemTypes2["Charcoal"] = "minecraft:charcoal";
        MinecraftItemTypes2["CherryBoat"] = "minecraft:cherry_boat";
        MinecraftItemTypes2["CherryButton"] = "minecraft:cherry_button";
        MinecraftItemTypes2["CherryChestBoat"] = "minecraft:cherry_chest_boat";
        MinecraftItemTypes2["CherryDoor"] = "minecraft:cherry_door";
        MinecraftItemTypes2["CherryFence"] = "minecraft:cherry_fence";
        MinecraftItemTypes2["CherryFenceGate"] = "minecraft:cherry_fence_gate";
        MinecraftItemTypes2["CherryHangingSign"] = "minecraft:cherry_hanging_sign";
        MinecraftItemTypes2["CherryLeaves"] = "minecraft:cherry_leaves";
        MinecraftItemTypes2["CherryLog"] = "minecraft:cherry_log";
        MinecraftItemTypes2["CherryPlanks"] = "minecraft:cherry_planks";
        MinecraftItemTypes2["CherryPressurePlate"] = "minecraft:cherry_pressure_plate";
        MinecraftItemTypes2["CherrySapling"] = "minecraft:cherry_sapling";
        MinecraftItemTypes2["CherryShelf"] = "minecraft:cherry_shelf";
        MinecraftItemTypes2["CherrySign"] = "minecraft:cherry_sign";
        MinecraftItemTypes2["CherrySlab"] = "minecraft:cherry_slab";
        MinecraftItemTypes2["CherryStairs"] = "minecraft:cherry_stairs";
        MinecraftItemTypes2["CherryTrapdoor"] = "minecraft:cherry_trapdoor";
        MinecraftItemTypes2["CherryWood"] = "minecraft:cherry_wood";
        MinecraftItemTypes2["Chest"] = "minecraft:chest";
        MinecraftItemTypes2["ChestMinecart"] = "minecraft:chest_minecart";
        MinecraftItemTypes2["Chicken"] = "minecraft:chicken";
        MinecraftItemTypes2["ChickenSpawnEgg"] = "minecraft:chicken_spawn_egg";
        MinecraftItemTypes2["ChippedAnvil"] = "minecraft:chipped_anvil";
        MinecraftItemTypes2["ChiseledBookshelf"] = "minecraft:chiseled_bookshelf";
        MinecraftItemTypes2["ChiseledCopper"] = "minecraft:chiseled_copper";
        MinecraftItemTypes2["ChiseledDeepslate"] = "minecraft:chiseled_deepslate";
        MinecraftItemTypes2["ChiseledNetherBricks"] = "minecraft:chiseled_nether_bricks";
        MinecraftItemTypes2["ChiseledPolishedBlackstone"] = "minecraft:chiseled_polished_blackstone";
        MinecraftItemTypes2["ChiseledQuartzBlock"] = "minecraft:chiseled_quartz_block";
        MinecraftItemTypes2["ChiseledRedSandstone"] = "minecraft:chiseled_red_sandstone";
        MinecraftItemTypes2["ChiseledResinBricks"] = "minecraft:chiseled_resin_bricks";
        MinecraftItemTypes2["ChiseledSandstone"] = "minecraft:chiseled_sandstone";
        MinecraftItemTypes2["ChiseledStoneBricks"] = "minecraft:chiseled_stone_bricks";
        MinecraftItemTypes2["ChiseledTuff"] = "minecraft:chiseled_tuff";
        MinecraftItemTypes2["ChiseledTuffBricks"] = "minecraft:chiseled_tuff_bricks";
        MinecraftItemTypes2["ChorusFlower"] = "minecraft:chorus_flower";
        MinecraftItemTypes2["ChorusFruit"] = "minecraft:chorus_fruit";
        MinecraftItemTypes2["ChorusPlant"] = "minecraft:chorus_plant";
        MinecraftItemTypes2["Clay"] = "minecraft:clay";
        MinecraftItemTypes2["ClayBall"] = "minecraft:clay_ball";
        MinecraftItemTypes2["Clock"] = "minecraft:clock";
        MinecraftItemTypes2["ClosedEyeblossom"] = "minecraft:closed_eyeblossom";
        MinecraftItemTypes2["Coal"] = "minecraft:coal";
        MinecraftItemTypes2["CoalBlock"] = "minecraft:coal_block";
        MinecraftItemTypes2["CoalOre"] = "minecraft:coal_ore";
        MinecraftItemTypes2["CoarseDirt"] = "minecraft:coarse_dirt";
        MinecraftItemTypes2["CoastArmorTrimSmithingTemplate"] = "minecraft:coast_armor_trim_smithing_template";
        MinecraftItemTypes2["CobbledDeepslate"] = "minecraft:cobbled_deepslate";
        MinecraftItemTypes2["CobbledDeepslateSlab"] = "minecraft:cobbled_deepslate_slab";
        MinecraftItemTypes2["CobbledDeepslateStairs"] = "minecraft:cobbled_deepslate_stairs";
        MinecraftItemTypes2["CobbledDeepslateWall"] = "minecraft:cobbled_deepslate_wall";
        MinecraftItemTypes2["Cobblestone"] = "minecraft:cobblestone";
        MinecraftItemTypes2["CobblestoneSlab"] = "minecraft:cobblestone_slab";
        MinecraftItemTypes2["CobblestoneWall"] = "minecraft:cobblestone_wall";
        MinecraftItemTypes2["CocoaBeans"] = "minecraft:cocoa_beans";
        MinecraftItemTypes2["Cod"] = "minecraft:cod";
        MinecraftItemTypes2["CodBucket"] = "minecraft:cod_bucket";
        MinecraftItemTypes2["CodSpawnEgg"] = "minecraft:cod_spawn_egg";
        MinecraftItemTypes2["CommandBlock"] = "minecraft:command_block";
        MinecraftItemTypes2["CommandBlockMinecart"] = "minecraft:command_block_minecart";
        MinecraftItemTypes2["Comparator"] = "minecraft:comparator";
        MinecraftItemTypes2["Compass"] = "minecraft:compass";
        MinecraftItemTypes2["Composter"] = "minecraft:composter";
        MinecraftItemTypes2["Conduit"] = "minecraft:conduit";
        MinecraftItemTypes2["CookedBeef"] = "minecraft:cooked_beef";
        MinecraftItemTypes2["CookedChicken"] = "minecraft:cooked_chicken";
        MinecraftItemTypes2["CookedCod"] = "minecraft:cooked_cod";
        MinecraftItemTypes2["CookedMutton"] = "minecraft:cooked_mutton";
        MinecraftItemTypes2["CookedPorkchop"] = "minecraft:cooked_porkchop";
        MinecraftItemTypes2["CookedRabbit"] = "minecraft:cooked_rabbit";
        MinecraftItemTypes2["CookedSalmon"] = "minecraft:cooked_salmon";
        MinecraftItemTypes2["Cookie"] = "minecraft:cookie";
        MinecraftItemTypes2["CopperAxe"] = "minecraft:copper_axe";
        MinecraftItemTypes2["CopperBars"] = "minecraft:copper_bars";
        MinecraftItemTypes2["CopperBlock"] = "minecraft:copper_block";
        MinecraftItemTypes2["CopperBoots"] = "minecraft:copper_boots";
        MinecraftItemTypes2["CopperBulb"] = "minecraft:copper_bulb";
        MinecraftItemTypes2["CopperChain"] = "minecraft:copper_chain";
        MinecraftItemTypes2["CopperChest"] = "minecraft:copper_chest";
        MinecraftItemTypes2["CopperChestplate"] = "minecraft:copper_chestplate";
        MinecraftItemTypes2["CopperDoor"] = "minecraft:copper_door";
        MinecraftItemTypes2["CopperGolemSpawnEgg"] = "minecraft:copper_golem_spawn_egg";
        MinecraftItemTypes2["CopperGolemStatue"] = "minecraft:copper_golem_statue";
        MinecraftItemTypes2["CopperGrate"] = "minecraft:copper_grate";
        MinecraftItemTypes2["CopperHelmet"] = "minecraft:copper_helmet";
        MinecraftItemTypes2["CopperHoe"] = "minecraft:copper_hoe";
        MinecraftItemTypes2["CopperHorseArmor"] = "minecraft:copper_horse_armor";
        MinecraftItemTypes2["CopperIngot"] = "minecraft:copper_ingot";
        MinecraftItemTypes2["CopperLantern"] = "minecraft:copper_lantern";
        MinecraftItemTypes2["CopperLeggings"] = "minecraft:copper_leggings";
        MinecraftItemTypes2["CopperNautilusArmor"] = "minecraft:copper_nautilus_armor";
        MinecraftItemTypes2["CopperNugget"] = "minecraft:copper_nugget";
        MinecraftItemTypes2["CopperOre"] = "minecraft:copper_ore";
        MinecraftItemTypes2["CopperPickaxe"] = "minecraft:copper_pickaxe";
        MinecraftItemTypes2["CopperShovel"] = "minecraft:copper_shovel";
        MinecraftItemTypes2["CopperSpear"] = "minecraft:copper_spear";
        MinecraftItemTypes2["CopperSword"] = "minecraft:copper_sword";
        MinecraftItemTypes2["CopperTorch"] = "minecraft:copper_torch";
        MinecraftItemTypes2["CopperTrapdoor"] = "minecraft:copper_trapdoor";
        MinecraftItemTypes2["Cornflower"] = "minecraft:cornflower";
        MinecraftItemTypes2["CowSpawnEgg"] = "minecraft:cow_spawn_egg";
        MinecraftItemTypes2["CrackedDeepslateBricks"] = "minecraft:cracked_deepslate_bricks";
        MinecraftItemTypes2["CrackedDeepslateTiles"] = "minecraft:cracked_deepslate_tiles";
        MinecraftItemTypes2["CrackedNetherBricks"] = "minecraft:cracked_nether_bricks";
        MinecraftItemTypes2["CrackedPolishedBlackstoneBricks"] = "minecraft:cracked_polished_blackstone_bricks";
        MinecraftItemTypes2["CrackedStoneBricks"] = "minecraft:cracked_stone_bricks";
        MinecraftItemTypes2["Crafter"] = "minecraft:crafter";
        MinecraftItemTypes2["CraftingTable"] = "minecraft:crafting_table";
        MinecraftItemTypes2["CreakingHeart"] = "minecraft:creaking_heart";
        MinecraftItemTypes2["CreakingSpawnEgg"] = "minecraft:creaking_spawn_egg";
        MinecraftItemTypes2["CreeperBannerPattern"] = "minecraft:creeper_banner_pattern";
        MinecraftItemTypes2["CreeperHead"] = "minecraft:creeper_head";
        MinecraftItemTypes2["CreeperSpawnEgg"] = "minecraft:creeper_spawn_egg";
        MinecraftItemTypes2["CrimsonButton"] = "minecraft:crimson_button";
        MinecraftItemTypes2["CrimsonDoor"] = "minecraft:crimson_door";
        MinecraftItemTypes2["CrimsonFence"] = "minecraft:crimson_fence";
        MinecraftItemTypes2["CrimsonFenceGate"] = "minecraft:crimson_fence_gate";
        MinecraftItemTypes2["CrimsonFungus"] = "minecraft:crimson_fungus";
        MinecraftItemTypes2["CrimsonHangingSign"] = "minecraft:crimson_hanging_sign";
        MinecraftItemTypes2["CrimsonHyphae"] = "minecraft:crimson_hyphae";
        MinecraftItemTypes2["CrimsonNylium"] = "minecraft:crimson_nylium";
        MinecraftItemTypes2["CrimsonPlanks"] = "minecraft:crimson_planks";
        MinecraftItemTypes2["CrimsonPressurePlate"] = "minecraft:crimson_pressure_plate";
        MinecraftItemTypes2["CrimsonRoots"] = "minecraft:crimson_roots";
        MinecraftItemTypes2["CrimsonShelf"] = "minecraft:crimson_shelf";
        MinecraftItemTypes2["CrimsonSign"] = "minecraft:crimson_sign";
        MinecraftItemTypes2["CrimsonSlab"] = "minecraft:crimson_slab";
        MinecraftItemTypes2["CrimsonStairs"] = "minecraft:crimson_stairs";
        MinecraftItemTypes2["CrimsonStem"] = "minecraft:crimson_stem";
        MinecraftItemTypes2["CrimsonTrapdoor"] = "minecraft:crimson_trapdoor";
        MinecraftItemTypes2["Crossbow"] = "minecraft:crossbow";
        MinecraftItemTypes2["CryingObsidian"] = "minecraft:crying_obsidian";
        MinecraftItemTypes2["CutCopper"] = "minecraft:cut_copper";
        MinecraftItemTypes2["CutCopperSlab"] = "minecraft:cut_copper_slab";
        MinecraftItemTypes2["CutCopperStairs"] = "minecraft:cut_copper_stairs";
        MinecraftItemTypes2["CutRedSandstone"] = "minecraft:cut_red_sandstone";
        MinecraftItemTypes2["CutRedSandstoneSlab"] = "minecraft:cut_red_sandstone_slab";
        MinecraftItemTypes2["CutSandstone"] = "minecraft:cut_sandstone";
        MinecraftItemTypes2["CutSandstoneSlab"] = "minecraft:cut_sandstone_slab";
        MinecraftItemTypes2["CyanBundle"] = "minecraft:cyan_bundle";
        MinecraftItemTypes2["CyanCandle"] = "minecraft:cyan_candle";
        MinecraftItemTypes2["CyanCarpet"] = "minecraft:cyan_carpet";
        MinecraftItemTypes2["CyanConcrete"] = "minecraft:cyan_concrete";
        MinecraftItemTypes2["CyanConcretePowder"] = "minecraft:cyan_concrete_powder";
        MinecraftItemTypes2["CyanDye"] = "minecraft:cyan_dye";
        MinecraftItemTypes2["CyanGlazedTerracotta"] = "minecraft:cyan_glazed_terracotta";
        MinecraftItemTypes2["CyanHarness"] = "minecraft:cyan_harness";
        MinecraftItemTypes2["CyanShulkerBox"] = "minecraft:cyan_shulker_box";
        MinecraftItemTypes2["CyanStainedGlass"] = "minecraft:cyan_stained_glass";
        MinecraftItemTypes2["CyanStainedGlassPane"] = "minecraft:cyan_stained_glass_pane";
        MinecraftItemTypes2["CyanTerracotta"] = "minecraft:cyan_terracotta";
        MinecraftItemTypes2["CyanWool"] = "minecraft:cyan_wool";
        MinecraftItemTypes2["DamagedAnvil"] = "minecraft:damaged_anvil";
        MinecraftItemTypes2["Dandelion"] = "minecraft:dandelion";
        MinecraftItemTypes2["DangerPotterySherd"] = "minecraft:danger_pottery_sherd";
        MinecraftItemTypes2["DarkOakBoat"] = "minecraft:dark_oak_boat";
        MinecraftItemTypes2["DarkOakButton"] = "minecraft:dark_oak_button";
        MinecraftItemTypes2["DarkOakChestBoat"] = "minecraft:dark_oak_chest_boat";
        MinecraftItemTypes2["DarkOakDoor"] = "minecraft:dark_oak_door";
        MinecraftItemTypes2["DarkOakFence"] = "minecraft:dark_oak_fence";
        MinecraftItemTypes2["DarkOakFenceGate"] = "minecraft:dark_oak_fence_gate";
        MinecraftItemTypes2["DarkOakHangingSign"] = "minecraft:dark_oak_hanging_sign";
        MinecraftItemTypes2["DarkOakLeaves"] = "minecraft:dark_oak_leaves";
        MinecraftItemTypes2["DarkOakLog"] = "minecraft:dark_oak_log";
        MinecraftItemTypes2["DarkOakPlanks"] = "minecraft:dark_oak_planks";
        MinecraftItemTypes2["DarkOakPressurePlate"] = "minecraft:dark_oak_pressure_plate";
        MinecraftItemTypes2["DarkOakSapling"] = "minecraft:dark_oak_sapling";
        MinecraftItemTypes2["DarkOakShelf"] = "minecraft:dark_oak_shelf";
        MinecraftItemTypes2["DarkOakSign"] = "minecraft:dark_oak_sign";
        MinecraftItemTypes2["DarkOakSlab"] = "minecraft:dark_oak_slab";
        MinecraftItemTypes2["DarkOakStairs"] = "minecraft:dark_oak_stairs";
        MinecraftItemTypes2["DarkOakTrapdoor"] = "minecraft:dark_oak_trapdoor";
        MinecraftItemTypes2["DarkOakWood"] = "minecraft:dark_oak_wood";
        MinecraftItemTypes2["DarkPrismarine"] = "minecraft:dark_prismarine";
        MinecraftItemTypes2["DarkPrismarineSlab"] = "minecraft:dark_prismarine_slab";
        MinecraftItemTypes2["DarkPrismarineStairs"] = "minecraft:dark_prismarine_stairs";
        MinecraftItemTypes2["DaylightDetector"] = "minecraft:daylight_detector";
        MinecraftItemTypes2["DeadBrainCoral"] = "minecraft:dead_brain_coral";
        MinecraftItemTypes2["DeadBrainCoralBlock"] = "minecraft:dead_brain_coral_block";
        MinecraftItemTypes2["DeadBrainCoralFan"] = "minecraft:dead_brain_coral_fan";
        MinecraftItemTypes2["DeadBubbleCoral"] = "minecraft:dead_bubble_coral";
        MinecraftItemTypes2["DeadBubbleCoralBlock"] = "minecraft:dead_bubble_coral_block";
        MinecraftItemTypes2["DeadBubbleCoralFan"] = "minecraft:dead_bubble_coral_fan";
        MinecraftItemTypes2["DeadFireCoral"] = "minecraft:dead_fire_coral";
        MinecraftItemTypes2["DeadFireCoralBlock"] = "minecraft:dead_fire_coral_block";
        MinecraftItemTypes2["DeadFireCoralFan"] = "minecraft:dead_fire_coral_fan";
        MinecraftItemTypes2["DeadHornCoral"] = "minecraft:dead_horn_coral";
        MinecraftItemTypes2["DeadHornCoralBlock"] = "minecraft:dead_horn_coral_block";
        MinecraftItemTypes2["DeadHornCoralFan"] = "minecraft:dead_horn_coral_fan";
        MinecraftItemTypes2["DeadTubeCoral"] = "minecraft:dead_tube_coral";
        MinecraftItemTypes2["DeadTubeCoralBlock"] = "minecraft:dead_tube_coral_block";
        MinecraftItemTypes2["DeadTubeCoralFan"] = "minecraft:dead_tube_coral_fan";
        MinecraftItemTypes2["Deadbush"] = "minecraft:deadbush";
        MinecraftItemTypes2["DebugStick"] = "minecraft:debug_stick";
        MinecraftItemTypes2["DecoratedPot"] = "minecraft:decorated_pot";
        MinecraftItemTypes2["Deepslate"] = "minecraft:deepslate";
        MinecraftItemTypes2["DeepslateBrickSlab"] = "minecraft:deepslate_brick_slab";
        MinecraftItemTypes2["DeepslateBrickStairs"] = "minecraft:deepslate_brick_stairs";
        MinecraftItemTypes2["DeepslateBrickWall"] = "minecraft:deepslate_brick_wall";
        MinecraftItemTypes2["DeepslateBricks"] = "minecraft:deepslate_bricks";
        MinecraftItemTypes2["DeepslateCoalOre"] = "minecraft:deepslate_coal_ore";
        MinecraftItemTypes2["DeepslateCopperOre"] = "minecraft:deepslate_copper_ore";
        MinecraftItemTypes2["DeepslateDiamondOre"] = "minecraft:deepslate_diamond_ore";
        MinecraftItemTypes2["DeepslateEmeraldOre"] = "minecraft:deepslate_emerald_ore";
        MinecraftItemTypes2["DeepslateGoldOre"] = "minecraft:deepslate_gold_ore";
        MinecraftItemTypes2["DeepslateIronOre"] = "minecraft:deepslate_iron_ore";
        MinecraftItemTypes2["DeepslateLapisOre"] = "minecraft:deepslate_lapis_ore";
        MinecraftItemTypes2["DeepslateRedstoneOre"] = "minecraft:deepslate_redstone_ore";
        MinecraftItemTypes2["DeepslateTileSlab"] = "minecraft:deepslate_tile_slab";
        MinecraftItemTypes2["DeepslateTileStairs"] = "minecraft:deepslate_tile_stairs";
        MinecraftItemTypes2["DeepslateTileWall"] = "minecraft:deepslate_tile_wall";
        MinecraftItemTypes2["DeepslateTiles"] = "minecraft:deepslate_tiles";
        MinecraftItemTypes2["Deny"] = "minecraft:deny";
        MinecraftItemTypes2["DetectorRail"] = "minecraft:detector_rail";
        MinecraftItemTypes2["Diamond"] = "minecraft:diamond";
        MinecraftItemTypes2["DiamondAxe"] = "minecraft:diamond_axe";
        MinecraftItemTypes2["DiamondBlock"] = "minecraft:diamond_block";
        MinecraftItemTypes2["DiamondBoots"] = "minecraft:diamond_boots";
        MinecraftItemTypes2["DiamondChestplate"] = "minecraft:diamond_chestplate";
        MinecraftItemTypes2["DiamondHelmet"] = "minecraft:diamond_helmet";
        MinecraftItemTypes2["DiamondHoe"] = "minecraft:diamond_hoe";
        MinecraftItemTypes2["DiamondHorseArmor"] = "minecraft:diamond_horse_armor";
        MinecraftItemTypes2["DiamondLeggings"] = "minecraft:diamond_leggings";
        MinecraftItemTypes2["DiamondNautilusArmor"] = "minecraft:diamond_nautilus_armor";
        MinecraftItemTypes2["DiamondOre"] = "minecraft:diamond_ore";
        MinecraftItemTypes2["DiamondPickaxe"] = "minecraft:diamond_pickaxe";
        MinecraftItemTypes2["DiamondShovel"] = "minecraft:diamond_shovel";
        MinecraftItemTypes2["DiamondSpear"] = "minecraft:diamond_spear";
        MinecraftItemTypes2["DiamondSword"] = "minecraft:diamond_sword";
        MinecraftItemTypes2["Diorite"] = "minecraft:diorite";
        MinecraftItemTypes2["DioriteSlab"] = "minecraft:diorite_slab";
        MinecraftItemTypes2["DioriteStairs"] = "minecraft:diorite_stairs";
        MinecraftItemTypes2["DioriteWall"] = "minecraft:diorite_wall";
        MinecraftItemTypes2["Dirt"] = "minecraft:dirt";
        MinecraftItemTypes2["DirtWithRoots"] = "minecraft:dirt_with_roots";
        MinecraftItemTypes2["DiscFragment5"] = "minecraft:disc_fragment_5";
        MinecraftItemTypes2["Dispenser"] = "minecraft:dispenser";
        MinecraftItemTypes2["DolphinSpawnEgg"] = "minecraft:dolphin_spawn_egg";
        MinecraftItemTypes2["DonkeySpawnEgg"] = "minecraft:donkey_spawn_egg";
        MinecraftItemTypes2["DragonBreath"] = "minecraft:dragon_breath";
        MinecraftItemTypes2["DragonEgg"] = "minecraft:dragon_egg";
        MinecraftItemTypes2["DragonHead"] = "minecraft:dragon_head";
        MinecraftItemTypes2["DriedGhast"] = "minecraft:dried_ghast";
        MinecraftItemTypes2["DriedKelp"] = "minecraft:dried_kelp";
        MinecraftItemTypes2["DriedKelpBlock"] = "minecraft:dried_kelp_block";
        MinecraftItemTypes2["DripstoneBlock"] = "minecraft:dripstone_block";
        MinecraftItemTypes2["Dropper"] = "minecraft:dropper";
        MinecraftItemTypes2["DrownedSpawnEgg"] = "minecraft:drowned_spawn_egg";
        MinecraftItemTypes2["DuneArmorTrimSmithingTemplate"] = "minecraft:dune_armor_trim_smithing_template";
        MinecraftItemTypes2["EchoShard"] = "minecraft:echo_shard";
        MinecraftItemTypes2["Egg"] = "minecraft:egg";
        MinecraftItemTypes2["ElderGuardianSpawnEgg"] = "minecraft:elder_guardian_spawn_egg";
        MinecraftItemTypes2["Elytra"] = "minecraft:elytra";
        MinecraftItemTypes2["Emerald"] = "minecraft:emerald";
        MinecraftItemTypes2["EmeraldBlock"] = "minecraft:emerald_block";
        MinecraftItemTypes2["EmeraldOre"] = "minecraft:emerald_ore";
        MinecraftItemTypes2["EmptyMap"] = "minecraft:empty_map";
        MinecraftItemTypes2["EnchantedBook"] = "minecraft:enchanted_book";
        MinecraftItemTypes2["EnchantedGoldenApple"] = "minecraft:enchanted_golden_apple";
        MinecraftItemTypes2["EnchantingTable"] = "minecraft:enchanting_table";
        MinecraftItemTypes2["EndBrickStairs"] = "minecraft:end_brick_stairs";
        MinecraftItemTypes2["EndBricks"] = "minecraft:end_bricks";
        MinecraftItemTypes2["EndCrystal"] = "minecraft:end_crystal";
        MinecraftItemTypes2["EndPortalFrame"] = "minecraft:end_portal_frame";
        MinecraftItemTypes2["EndRod"] = "minecraft:end_rod";
        MinecraftItemTypes2["EndStone"] = "minecraft:end_stone";
        MinecraftItemTypes2["EndStoneBrickSlab"] = "minecraft:end_stone_brick_slab";
        MinecraftItemTypes2["EndStoneBrickWall"] = "minecraft:end_stone_brick_wall";
        MinecraftItemTypes2["EnderChest"] = "minecraft:ender_chest";
        MinecraftItemTypes2["EnderDragonSpawnEgg"] = "minecraft:ender_dragon_spawn_egg";
        MinecraftItemTypes2["EnderEye"] = "minecraft:ender_eye";
        MinecraftItemTypes2["EnderPearl"] = "minecraft:ender_pearl";
        MinecraftItemTypes2["EndermanSpawnEgg"] = "minecraft:enderman_spawn_egg";
        MinecraftItemTypes2["EndermiteSpawnEgg"] = "minecraft:endermite_spawn_egg";
        MinecraftItemTypes2["EvokerSpawnEgg"] = "minecraft:evoker_spawn_egg";
        MinecraftItemTypes2["ExperienceBottle"] = "minecraft:experience_bottle";
        MinecraftItemTypes2["ExplorerPotterySherd"] = "minecraft:explorer_pottery_sherd";
        MinecraftItemTypes2["ExposedChiseledCopper"] = "minecraft:exposed_chiseled_copper";
        MinecraftItemTypes2["ExposedCopper"] = "minecraft:exposed_copper";
        MinecraftItemTypes2["ExposedCopperBars"] = "minecraft:exposed_copper_bars";
        MinecraftItemTypes2["ExposedCopperBulb"] = "minecraft:exposed_copper_bulb";
        MinecraftItemTypes2["ExposedCopperChain"] = "minecraft:exposed_copper_chain";
        MinecraftItemTypes2["ExposedCopperChest"] = "minecraft:exposed_copper_chest";
        MinecraftItemTypes2["ExposedCopperDoor"] = "minecraft:exposed_copper_door";
        MinecraftItemTypes2["ExposedCopperGolemStatue"] = "minecraft:exposed_copper_golem_statue";
        MinecraftItemTypes2["ExposedCopperGrate"] = "minecraft:exposed_copper_grate";
        MinecraftItemTypes2["ExposedCopperLantern"] = "minecraft:exposed_copper_lantern";
        MinecraftItemTypes2["ExposedCopperTrapdoor"] = "minecraft:exposed_copper_trapdoor";
        MinecraftItemTypes2["ExposedCutCopper"] = "minecraft:exposed_cut_copper";
        MinecraftItemTypes2["ExposedCutCopperSlab"] = "minecraft:exposed_cut_copper_slab";
        MinecraftItemTypes2["ExposedCutCopperStairs"] = "minecraft:exposed_cut_copper_stairs";
        MinecraftItemTypes2["ExposedLightningRod"] = "minecraft:exposed_lightning_rod";
        MinecraftItemTypes2["EyeArmorTrimSmithingTemplate"] = "minecraft:eye_armor_trim_smithing_template";
        MinecraftItemTypes2["Farmland"] = "minecraft:farmland";
        MinecraftItemTypes2["Feather"] = "minecraft:feather";
        MinecraftItemTypes2["FenceGate"] = "minecraft:fence_gate";
        MinecraftItemTypes2["FermentedSpiderEye"] = "minecraft:fermented_spider_eye";
        MinecraftItemTypes2["Fern"] = "minecraft:fern";
        MinecraftItemTypes2["FieldMasonedBannerPattern"] = "minecraft:field_masoned_banner_pattern";
        MinecraftItemTypes2["FilledMap"] = "minecraft:filled_map";
        MinecraftItemTypes2["FireCharge"] = "minecraft:fire_charge";
        MinecraftItemTypes2["FireCoral"] = "minecraft:fire_coral";
        MinecraftItemTypes2["FireCoralBlock"] = "minecraft:fire_coral_block";
        MinecraftItemTypes2["FireCoralFan"] = "minecraft:fire_coral_fan";
        MinecraftItemTypes2["FireflyBush"] = "minecraft:firefly_bush";
        MinecraftItemTypes2["FireworkRocket"] = "minecraft:firework_rocket";
        MinecraftItemTypes2["FireworkStar"] = "minecraft:firework_star";
        MinecraftItemTypes2["FishingRod"] = "minecraft:fishing_rod";
        MinecraftItemTypes2["FletchingTable"] = "minecraft:fletching_table";
        MinecraftItemTypes2["Flint"] = "minecraft:flint";
        MinecraftItemTypes2["FlintAndSteel"] = "minecraft:flint_and_steel";
        MinecraftItemTypes2["FlowArmorTrimSmithingTemplate"] = "minecraft:flow_armor_trim_smithing_template";
        MinecraftItemTypes2["FlowBannerPattern"] = "minecraft:flow_banner_pattern";
        MinecraftItemTypes2["FlowPotterySherd"] = "minecraft:flow_pottery_sherd";
        MinecraftItemTypes2["FlowerBannerPattern"] = "minecraft:flower_banner_pattern";
        MinecraftItemTypes2["FlowerPot"] = "minecraft:flower_pot";
        MinecraftItemTypes2["FloweringAzalea"] = "minecraft:flowering_azalea";
        MinecraftItemTypes2["FoxSpawnEgg"] = "minecraft:fox_spawn_egg";
        MinecraftItemTypes2["Frame"] = "minecraft:frame";
        MinecraftItemTypes2["FriendPotterySherd"] = "minecraft:friend_pottery_sherd";
        MinecraftItemTypes2["FrogSpawn"] = "minecraft:frog_spawn";
        MinecraftItemTypes2["FrogSpawnEgg"] = "minecraft:frog_spawn_egg";
        MinecraftItemTypes2["FrostedIce"] = "minecraft:frosted_ice";
        MinecraftItemTypes2["Furnace"] = "minecraft:furnace";
        MinecraftItemTypes2["GhastSpawnEgg"] = "minecraft:ghast_spawn_egg";
        MinecraftItemTypes2["GhastTear"] = "minecraft:ghast_tear";
        MinecraftItemTypes2["GildedBlackstone"] = "minecraft:gilded_blackstone";
        MinecraftItemTypes2["Glass"] = "minecraft:glass";
        MinecraftItemTypes2["GlassBottle"] = "minecraft:glass_bottle";
        MinecraftItemTypes2["GlassPane"] = "minecraft:glass_pane";
        MinecraftItemTypes2["GlisteringMelonSlice"] = "minecraft:glistering_melon_slice";
        MinecraftItemTypes2["GlobeBannerPattern"] = "minecraft:globe_banner_pattern";
        MinecraftItemTypes2["GlowBerries"] = "minecraft:glow_berries";
        MinecraftItemTypes2["GlowFrame"] = "minecraft:glow_frame";
        MinecraftItemTypes2["GlowInkSac"] = "minecraft:glow_ink_sac";
        MinecraftItemTypes2["GlowLichen"] = "minecraft:glow_lichen";
        MinecraftItemTypes2["GlowSquidSpawnEgg"] = "minecraft:glow_squid_spawn_egg";
        MinecraftItemTypes2["Glowstone"] = "minecraft:glowstone";
        MinecraftItemTypes2["GlowstoneDust"] = "minecraft:glowstone_dust";
        MinecraftItemTypes2["GoatHorn"] = "minecraft:goat_horn";
        MinecraftItemTypes2["GoatSpawnEgg"] = "minecraft:goat_spawn_egg";
        MinecraftItemTypes2["GoldBlock"] = "minecraft:gold_block";
        MinecraftItemTypes2["GoldIngot"] = "minecraft:gold_ingot";
        MinecraftItemTypes2["GoldNugget"] = "minecraft:gold_nugget";
        MinecraftItemTypes2["GoldOre"] = "minecraft:gold_ore";
        MinecraftItemTypes2["GoldenApple"] = "minecraft:golden_apple";
        MinecraftItemTypes2["GoldenAxe"] = "minecraft:golden_axe";
        MinecraftItemTypes2["GoldenBoots"] = "minecraft:golden_boots";
        MinecraftItemTypes2["GoldenCarrot"] = "minecraft:golden_carrot";
        MinecraftItemTypes2["GoldenChestplate"] = "minecraft:golden_chestplate";
        MinecraftItemTypes2["GoldenHelmet"] = "minecraft:golden_helmet";
        MinecraftItemTypes2["GoldenHoe"] = "minecraft:golden_hoe";
        MinecraftItemTypes2["GoldenHorseArmor"] = "minecraft:golden_horse_armor";
        MinecraftItemTypes2["GoldenLeggings"] = "minecraft:golden_leggings";
        MinecraftItemTypes2["GoldenNautilusArmor"] = "minecraft:golden_nautilus_armor";
        MinecraftItemTypes2["GoldenPickaxe"] = "minecraft:golden_pickaxe";
        MinecraftItemTypes2["GoldenRail"] = "minecraft:golden_rail";
        MinecraftItemTypes2["GoldenShovel"] = "minecraft:golden_shovel";
        MinecraftItemTypes2["GoldenSpear"] = "minecraft:golden_spear";
        MinecraftItemTypes2["GoldenSword"] = "minecraft:golden_sword";
        MinecraftItemTypes2["Granite"] = "minecraft:granite";
        MinecraftItemTypes2["GraniteSlab"] = "minecraft:granite_slab";
        MinecraftItemTypes2["GraniteStairs"] = "minecraft:granite_stairs";
        MinecraftItemTypes2["GraniteWall"] = "minecraft:granite_wall";
        MinecraftItemTypes2["GrassBlock"] = "minecraft:grass_block";
        MinecraftItemTypes2["GrassPath"] = "minecraft:grass_path";
        MinecraftItemTypes2["Gravel"] = "minecraft:gravel";
        MinecraftItemTypes2["GrayBundle"] = "minecraft:gray_bundle";
        MinecraftItemTypes2["GrayCandle"] = "minecraft:gray_candle";
        MinecraftItemTypes2["GrayCarpet"] = "minecraft:gray_carpet";
        MinecraftItemTypes2["GrayConcrete"] = "minecraft:gray_concrete";
        MinecraftItemTypes2["GrayConcretePowder"] = "minecraft:gray_concrete_powder";
        MinecraftItemTypes2["GrayDye"] = "minecraft:gray_dye";
        MinecraftItemTypes2["GrayGlazedTerracotta"] = "minecraft:gray_glazed_terracotta";
        MinecraftItemTypes2["GrayHarness"] = "minecraft:gray_harness";
        MinecraftItemTypes2["GrayShulkerBox"] = "minecraft:gray_shulker_box";
        MinecraftItemTypes2["GrayStainedGlass"] = "minecraft:gray_stained_glass";
        MinecraftItemTypes2["GrayStainedGlassPane"] = "minecraft:gray_stained_glass_pane";
        MinecraftItemTypes2["GrayTerracotta"] = "minecraft:gray_terracotta";
        MinecraftItemTypes2["GrayWool"] = "minecraft:gray_wool";
        MinecraftItemTypes2["GreenBundle"] = "minecraft:green_bundle";
        MinecraftItemTypes2["GreenCandle"] = "minecraft:green_candle";
        MinecraftItemTypes2["GreenCarpet"] = "minecraft:green_carpet";
        MinecraftItemTypes2["GreenConcrete"] = "minecraft:green_concrete";
        MinecraftItemTypes2["GreenConcretePowder"] = "minecraft:green_concrete_powder";
        MinecraftItemTypes2["GreenDye"] = "minecraft:green_dye";
        MinecraftItemTypes2["GreenGlazedTerracotta"] = "minecraft:green_glazed_terracotta";
        MinecraftItemTypes2["GreenHarness"] = "minecraft:green_harness";
        MinecraftItemTypes2["GreenShulkerBox"] = "minecraft:green_shulker_box";
        MinecraftItemTypes2["GreenStainedGlass"] = "minecraft:green_stained_glass";
        MinecraftItemTypes2["GreenStainedGlassPane"] = "minecraft:green_stained_glass_pane";
        MinecraftItemTypes2["GreenTerracotta"] = "minecraft:green_terracotta";
        MinecraftItemTypes2["GreenWool"] = "minecraft:green_wool";
        MinecraftItemTypes2["Grindstone"] = "minecraft:grindstone";
        MinecraftItemTypes2["GuardianSpawnEgg"] = "minecraft:guardian_spawn_egg";
        MinecraftItemTypes2["Gunpowder"] = "minecraft:gunpowder";
        MinecraftItemTypes2["GusterBannerPattern"] = "minecraft:guster_banner_pattern";
        MinecraftItemTypes2["GusterPotterySherd"] = "minecraft:guster_pottery_sherd";
        MinecraftItemTypes2["HangingRoots"] = "minecraft:hanging_roots";
        MinecraftItemTypes2["HappyGhastSpawnEgg"] = "minecraft:happy_ghast_spawn_egg";
        MinecraftItemTypes2["HardenedClay"] = "minecraft:hardened_clay";
        MinecraftItemTypes2["HayBlock"] = "minecraft:hay_block";
        MinecraftItemTypes2["HeartOfTheSea"] = "minecraft:heart_of_the_sea";
        MinecraftItemTypes2["HeartPotterySherd"] = "minecraft:heart_pottery_sherd";
        MinecraftItemTypes2["HeartbreakPotterySherd"] = "minecraft:heartbreak_pottery_sherd";
        MinecraftItemTypes2["HeavyCore"] = "minecraft:heavy_core";
        MinecraftItemTypes2["HeavyWeightedPressurePlate"] = "minecraft:heavy_weighted_pressure_plate";
        MinecraftItemTypes2["HoglinSpawnEgg"] = "minecraft:hoglin_spawn_egg";
        MinecraftItemTypes2["HoneyBlock"] = "minecraft:honey_block";
        MinecraftItemTypes2["HoneyBottle"] = "minecraft:honey_bottle";
        MinecraftItemTypes2["Honeycomb"] = "minecraft:honeycomb";
        MinecraftItemTypes2["HoneycombBlock"] = "minecraft:honeycomb_block";
        MinecraftItemTypes2["Hopper"] = "minecraft:hopper";
        MinecraftItemTypes2["HopperMinecart"] = "minecraft:hopper_minecart";
        MinecraftItemTypes2["HornCoral"] = "minecraft:horn_coral";
        MinecraftItemTypes2["HornCoralBlock"] = "minecraft:horn_coral_block";
        MinecraftItemTypes2["HornCoralFan"] = "minecraft:horn_coral_fan";
        MinecraftItemTypes2["HorseSpawnEgg"] = "minecraft:horse_spawn_egg";
        MinecraftItemTypes2["HostArmorTrimSmithingTemplate"] = "minecraft:host_armor_trim_smithing_template";
        MinecraftItemTypes2["HowlPotterySherd"] = "minecraft:howl_pottery_sherd";
        MinecraftItemTypes2["HuskSpawnEgg"] = "minecraft:husk_spawn_egg";
        MinecraftItemTypes2["Ice"] = "minecraft:ice";
        MinecraftItemTypes2["InfestedChiseledStoneBricks"] = "minecraft:infested_chiseled_stone_bricks";
        MinecraftItemTypes2["InfestedCobblestone"] = "minecraft:infested_cobblestone";
        MinecraftItemTypes2["InfestedCrackedStoneBricks"] = "minecraft:infested_cracked_stone_bricks";
        MinecraftItemTypes2["InfestedDeepslate"] = "minecraft:infested_deepslate";
        MinecraftItemTypes2["InfestedMossyStoneBricks"] = "minecraft:infested_mossy_stone_bricks";
        MinecraftItemTypes2["InfestedStone"] = "minecraft:infested_stone";
        MinecraftItemTypes2["InfestedStoneBricks"] = "minecraft:infested_stone_bricks";
        MinecraftItemTypes2["InkSac"] = "minecraft:ink_sac";
        MinecraftItemTypes2["IronAxe"] = "minecraft:iron_axe";
        MinecraftItemTypes2["IronBars"] = "minecraft:iron_bars";
        MinecraftItemTypes2["IronBlock"] = "minecraft:iron_block";
        MinecraftItemTypes2["IronBoots"] = "minecraft:iron_boots";
        MinecraftItemTypes2["IronChain"] = "minecraft:iron_chain";
        MinecraftItemTypes2["IronChestplate"] = "minecraft:iron_chestplate";
        MinecraftItemTypes2["IronDoor"] = "minecraft:iron_door";
        MinecraftItemTypes2["IronGolemSpawnEgg"] = "minecraft:iron_golem_spawn_egg";
        MinecraftItemTypes2["IronHelmet"] = "minecraft:iron_helmet";
        MinecraftItemTypes2["IronHoe"] = "minecraft:iron_hoe";
        MinecraftItemTypes2["IronHorseArmor"] = "minecraft:iron_horse_armor";
        MinecraftItemTypes2["IronIngot"] = "minecraft:iron_ingot";
        MinecraftItemTypes2["IronLeggings"] = "minecraft:iron_leggings";
        MinecraftItemTypes2["IronNautilusArmor"] = "minecraft:iron_nautilus_armor";
        MinecraftItemTypes2["IronNugget"] = "minecraft:iron_nugget";
        MinecraftItemTypes2["IronOre"] = "minecraft:iron_ore";
        MinecraftItemTypes2["IronPickaxe"] = "minecraft:iron_pickaxe";
        MinecraftItemTypes2["IronShovel"] = "minecraft:iron_shovel";
        MinecraftItemTypes2["IronSpear"] = "minecraft:iron_spear";
        MinecraftItemTypes2["IronSword"] = "minecraft:iron_sword";
        MinecraftItemTypes2["IronTrapdoor"] = "minecraft:iron_trapdoor";
        MinecraftItemTypes2["Jigsaw"] = "minecraft:jigsaw";
        MinecraftItemTypes2["Jukebox"] = "minecraft:jukebox";
        MinecraftItemTypes2["JungleBoat"] = "minecraft:jungle_boat";
        MinecraftItemTypes2["JungleButton"] = "minecraft:jungle_button";
        MinecraftItemTypes2["JungleChestBoat"] = "minecraft:jungle_chest_boat";
        MinecraftItemTypes2["JungleDoor"] = "minecraft:jungle_door";
        MinecraftItemTypes2["JungleFence"] = "minecraft:jungle_fence";
        MinecraftItemTypes2["JungleFenceGate"] = "minecraft:jungle_fence_gate";
        MinecraftItemTypes2["JungleHangingSign"] = "minecraft:jungle_hanging_sign";
        MinecraftItemTypes2["JungleLeaves"] = "minecraft:jungle_leaves";
        MinecraftItemTypes2["JungleLog"] = "minecraft:jungle_log";
        MinecraftItemTypes2["JunglePlanks"] = "minecraft:jungle_planks";
        MinecraftItemTypes2["JunglePressurePlate"] = "minecraft:jungle_pressure_plate";
        MinecraftItemTypes2["JungleSapling"] = "minecraft:jungle_sapling";
        MinecraftItemTypes2["JungleShelf"] = "minecraft:jungle_shelf";
        MinecraftItemTypes2["JungleSign"] = "minecraft:jungle_sign";
        MinecraftItemTypes2["JungleSlab"] = "minecraft:jungle_slab";
        MinecraftItemTypes2["JungleStairs"] = "minecraft:jungle_stairs";
        MinecraftItemTypes2["JungleTrapdoor"] = "minecraft:jungle_trapdoor";
        MinecraftItemTypes2["JungleWood"] = "minecraft:jungle_wood";
        MinecraftItemTypes2["Kelp"] = "minecraft:kelp";
        MinecraftItemTypes2["Ladder"] = "minecraft:ladder";
        MinecraftItemTypes2["Lantern"] = "minecraft:lantern";
        MinecraftItemTypes2["LapisBlock"] = "minecraft:lapis_block";
        MinecraftItemTypes2["LapisLazuli"] = "minecraft:lapis_lazuli";
        MinecraftItemTypes2["LapisOre"] = "minecraft:lapis_ore";
        MinecraftItemTypes2["LargeAmethystBud"] = "minecraft:large_amethyst_bud";
        MinecraftItemTypes2["LargeFern"] = "minecraft:large_fern";
        MinecraftItemTypes2["LavaBucket"] = "minecraft:lava_bucket";
        MinecraftItemTypes2["Lead"] = "minecraft:lead";
        MinecraftItemTypes2["LeafLitter"] = "minecraft:leaf_litter";
        MinecraftItemTypes2["Leather"] = "minecraft:leather";
        MinecraftItemTypes2["LeatherBoots"] = "minecraft:leather_boots";
        MinecraftItemTypes2["LeatherChestplate"] = "minecraft:leather_chestplate";
        MinecraftItemTypes2["LeatherHelmet"] = "minecraft:leather_helmet";
        MinecraftItemTypes2["LeatherHorseArmor"] = "minecraft:leather_horse_armor";
        MinecraftItemTypes2["LeatherLeggings"] = "minecraft:leather_leggings";
        MinecraftItemTypes2["Lectern"] = "minecraft:lectern";
        MinecraftItemTypes2["Lever"] = "minecraft:lever";
        MinecraftItemTypes2["LightBlock0"] = "minecraft:light_block_0";
        MinecraftItemTypes2["LightBlock1"] = "minecraft:light_block_1";
        MinecraftItemTypes2["LightBlock10"] = "minecraft:light_block_10";
        MinecraftItemTypes2["LightBlock11"] = "minecraft:light_block_11";
        MinecraftItemTypes2["LightBlock12"] = "minecraft:light_block_12";
        MinecraftItemTypes2["LightBlock13"] = "minecraft:light_block_13";
        MinecraftItemTypes2["LightBlock14"] = "minecraft:light_block_14";
        MinecraftItemTypes2["LightBlock15"] = "minecraft:light_block_15";
        MinecraftItemTypes2["LightBlock2"] = "minecraft:light_block_2";
        MinecraftItemTypes2["LightBlock3"] = "minecraft:light_block_3";
        MinecraftItemTypes2["LightBlock4"] = "minecraft:light_block_4";
        MinecraftItemTypes2["LightBlock5"] = "minecraft:light_block_5";
        MinecraftItemTypes2["LightBlock6"] = "minecraft:light_block_6";
        MinecraftItemTypes2["LightBlock7"] = "minecraft:light_block_7";
        MinecraftItemTypes2["LightBlock8"] = "minecraft:light_block_8";
        MinecraftItemTypes2["LightBlock9"] = "minecraft:light_block_9";
        MinecraftItemTypes2["LightBlueBundle"] = "minecraft:light_blue_bundle";
        MinecraftItemTypes2["LightBlueCandle"] = "minecraft:light_blue_candle";
        MinecraftItemTypes2["LightBlueCarpet"] = "minecraft:light_blue_carpet";
        MinecraftItemTypes2["LightBlueConcrete"] = "minecraft:light_blue_concrete";
        MinecraftItemTypes2["LightBlueConcretePowder"] = "minecraft:light_blue_concrete_powder";
        MinecraftItemTypes2["LightBlueDye"] = "minecraft:light_blue_dye";
        MinecraftItemTypes2["LightBlueGlazedTerracotta"] = "minecraft:light_blue_glazed_terracotta";
        MinecraftItemTypes2["LightBlueHarness"] = "minecraft:light_blue_harness";
        MinecraftItemTypes2["LightBlueShulkerBox"] = "minecraft:light_blue_shulker_box";
        MinecraftItemTypes2["LightBlueStainedGlass"] = "minecraft:light_blue_stained_glass";
        MinecraftItemTypes2["LightBlueStainedGlassPane"] = "minecraft:light_blue_stained_glass_pane";
        MinecraftItemTypes2["LightBlueTerracotta"] = "minecraft:light_blue_terracotta";
        MinecraftItemTypes2["LightBlueWool"] = "minecraft:light_blue_wool";
        MinecraftItemTypes2["LightGrayBundle"] = "minecraft:light_gray_bundle";
        MinecraftItemTypes2["LightGrayCandle"] = "minecraft:light_gray_candle";
        MinecraftItemTypes2["LightGrayCarpet"] = "minecraft:light_gray_carpet";
        MinecraftItemTypes2["LightGrayConcrete"] = "minecraft:light_gray_concrete";
        MinecraftItemTypes2["LightGrayConcretePowder"] = "minecraft:light_gray_concrete_powder";
        MinecraftItemTypes2["LightGrayDye"] = "minecraft:light_gray_dye";
        MinecraftItemTypes2["LightGrayHarness"] = "minecraft:light_gray_harness";
        MinecraftItemTypes2["LightGrayShulkerBox"] = "minecraft:light_gray_shulker_box";
        MinecraftItemTypes2["LightGrayStainedGlass"] = "minecraft:light_gray_stained_glass";
        MinecraftItemTypes2["LightGrayStainedGlassPane"] = "minecraft:light_gray_stained_glass_pane";
        MinecraftItemTypes2["LightGrayTerracotta"] = "minecraft:light_gray_terracotta";
        MinecraftItemTypes2["LightGrayWool"] = "minecraft:light_gray_wool";
        MinecraftItemTypes2["LightWeightedPressurePlate"] = "minecraft:light_weighted_pressure_plate";
        MinecraftItemTypes2["LightningRod"] = "minecraft:lightning_rod";
        MinecraftItemTypes2["Lilac"] = "minecraft:lilac";
        MinecraftItemTypes2["LilyOfTheValley"] = "minecraft:lily_of_the_valley";
        MinecraftItemTypes2["LimeBundle"] = "minecraft:lime_bundle";
        MinecraftItemTypes2["LimeCandle"] = "minecraft:lime_candle";
        MinecraftItemTypes2["LimeCarpet"] = "minecraft:lime_carpet";
        MinecraftItemTypes2["LimeConcrete"] = "minecraft:lime_concrete";
        MinecraftItemTypes2["LimeConcretePowder"] = "minecraft:lime_concrete_powder";
        MinecraftItemTypes2["LimeDye"] = "minecraft:lime_dye";
        MinecraftItemTypes2["LimeGlazedTerracotta"] = "minecraft:lime_glazed_terracotta";
        MinecraftItemTypes2["LimeHarness"] = "minecraft:lime_harness";
        MinecraftItemTypes2["LimeShulkerBox"] = "minecraft:lime_shulker_box";
        MinecraftItemTypes2["LimeStainedGlass"] = "minecraft:lime_stained_glass";
        MinecraftItemTypes2["LimeStainedGlassPane"] = "minecraft:lime_stained_glass_pane";
        MinecraftItemTypes2["LimeTerracotta"] = "minecraft:lime_terracotta";
        MinecraftItemTypes2["LimeWool"] = "minecraft:lime_wool";
        MinecraftItemTypes2["LingeringPotion"] = "minecraft:lingering_potion";
        MinecraftItemTypes2["LitPumpkin"] = "minecraft:lit_pumpkin";
        MinecraftItemTypes2["LlamaSpawnEgg"] = "minecraft:llama_spawn_egg";
        MinecraftItemTypes2["Lodestone"] = "minecraft:lodestone";
        MinecraftItemTypes2["LodestoneCompass"] = "minecraft:lodestone_compass";
        MinecraftItemTypes2["Loom"] = "minecraft:loom";
        MinecraftItemTypes2["Mace"] = "minecraft:mace";
        MinecraftItemTypes2["MagentaBundle"] = "minecraft:magenta_bundle";
        MinecraftItemTypes2["MagentaCandle"] = "minecraft:magenta_candle";
        MinecraftItemTypes2["MagentaCarpet"] = "minecraft:magenta_carpet";
        MinecraftItemTypes2["MagentaConcrete"] = "minecraft:magenta_concrete";
        MinecraftItemTypes2["MagentaConcretePowder"] = "minecraft:magenta_concrete_powder";
        MinecraftItemTypes2["MagentaDye"] = "minecraft:magenta_dye";
        MinecraftItemTypes2["MagentaGlazedTerracotta"] = "minecraft:magenta_glazed_terracotta";
        MinecraftItemTypes2["MagentaHarness"] = "minecraft:magenta_harness";
        MinecraftItemTypes2["MagentaShulkerBox"] = "minecraft:magenta_shulker_box";
        MinecraftItemTypes2["MagentaStainedGlass"] = "minecraft:magenta_stained_glass";
        MinecraftItemTypes2["MagentaStainedGlassPane"] = "minecraft:magenta_stained_glass_pane";
        MinecraftItemTypes2["MagentaTerracotta"] = "minecraft:magenta_terracotta";
        MinecraftItemTypes2["MagentaWool"] = "minecraft:magenta_wool";
        MinecraftItemTypes2["Magma"] = "minecraft:magma";
        MinecraftItemTypes2["MagmaCream"] = "minecraft:magma_cream";
        MinecraftItemTypes2["MagmaCubeSpawnEgg"] = "minecraft:magma_cube_spawn_egg";
        MinecraftItemTypes2["MangroveBoat"] = "minecraft:mangrove_boat";
        MinecraftItemTypes2["MangroveButton"] = "minecraft:mangrove_button";
        MinecraftItemTypes2["MangroveChestBoat"] = "minecraft:mangrove_chest_boat";
        MinecraftItemTypes2["MangroveDoor"] = "minecraft:mangrove_door";
        MinecraftItemTypes2["MangroveFence"] = "minecraft:mangrove_fence";
        MinecraftItemTypes2["MangroveFenceGate"] = "minecraft:mangrove_fence_gate";
        MinecraftItemTypes2["MangroveHangingSign"] = "minecraft:mangrove_hanging_sign";
        MinecraftItemTypes2["MangroveLeaves"] = "minecraft:mangrove_leaves";
        MinecraftItemTypes2["MangroveLog"] = "minecraft:mangrove_log";
        MinecraftItemTypes2["MangrovePlanks"] = "minecraft:mangrove_planks";
        MinecraftItemTypes2["MangrovePressurePlate"] = "minecraft:mangrove_pressure_plate";
        MinecraftItemTypes2["MangrovePropagule"] = "minecraft:mangrove_propagule";
        MinecraftItemTypes2["MangroveRoots"] = "minecraft:mangrove_roots";
        MinecraftItemTypes2["MangroveShelf"] = "minecraft:mangrove_shelf";
        MinecraftItemTypes2["MangroveSign"] = "minecraft:mangrove_sign";
        MinecraftItemTypes2["MangroveSlab"] = "minecraft:mangrove_slab";
        MinecraftItemTypes2["MangroveStairs"] = "minecraft:mangrove_stairs";
        MinecraftItemTypes2["MangroveTrapdoor"] = "minecraft:mangrove_trapdoor";
        MinecraftItemTypes2["MangroveWood"] = "minecraft:mangrove_wood";
        MinecraftItemTypes2["MediumAmethystBud"] = "minecraft:medium_amethyst_bud";
        MinecraftItemTypes2["MelonBlock"] = "minecraft:melon_block";
        MinecraftItemTypes2["MelonSeeds"] = "minecraft:melon_seeds";
        MinecraftItemTypes2["MelonSlice"] = "minecraft:melon_slice";
        MinecraftItemTypes2["MilkBucket"] = "minecraft:milk_bucket";
        MinecraftItemTypes2["Minecart"] = "minecraft:minecart";
        MinecraftItemTypes2["MinerPotterySherd"] = "minecraft:miner_pottery_sherd";
        MinecraftItemTypes2["MobSpawner"] = "minecraft:mob_spawner";
        MinecraftItemTypes2["MojangBannerPattern"] = "minecraft:mojang_banner_pattern";
        MinecraftItemTypes2["MooshroomSpawnEgg"] = "minecraft:mooshroom_spawn_egg";
        MinecraftItemTypes2["MossBlock"] = "minecraft:moss_block";
        MinecraftItemTypes2["MossCarpet"] = "minecraft:moss_carpet";
        MinecraftItemTypes2["MossyCobblestone"] = "minecraft:mossy_cobblestone";
        MinecraftItemTypes2["MossyCobblestoneSlab"] = "minecraft:mossy_cobblestone_slab";
        MinecraftItemTypes2["MossyCobblestoneStairs"] = "minecraft:mossy_cobblestone_stairs";
        MinecraftItemTypes2["MossyCobblestoneWall"] = "minecraft:mossy_cobblestone_wall";
        MinecraftItemTypes2["MossyStoneBrickSlab"] = "minecraft:mossy_stone_brick_slab";
        MinecraftItemTypes2["MossyStoneBrickStairs"] = "minecraft:mossy_stone_brick_stairs";
        MinecraftItemTypes2["MossyStoneBrickWall"] = "minecraft:mossy_stone_brick_wall";
        MinecraftItemTypes2["MossyStoneBricks"] = "minecraft:mossy_stone_bricks";
        MinecraftItemTypes2["MournerPotterySherd"] = "minecraft:mourner_pottery_sherd";
        MinecraftItemTypes2["Mud"] = "minecraft:mud";
        MinecraftItemTypes2["MudBrickSlab"] = "minecraft:mud_brick_slab";
        MinecraftItemTypes2["MudBrickStairs"] = "minecraft:mud_brick_stairs";
        MinecraftItemTypes2["MudBrickWall"] = "minecraft:mud_brick_wall";
        MinecraftItemTypes2["MudBricks"] = "minecraft:mud_bricks";
        MinecraftItemTypes2["MuddyMangroveRoots"] = "minecraft:muddy_mangrove_roots";
        MinecraftItemTypes2["MuleSpawnEgg"] = "minecraft:mule_spawn_egg";
        MinecraftItemTypes2["MushroomStem"] = "minecraft:mushroom_stem";
        MinecraftItemTypes2["MushroomStew"] = "minecraft:mushroom_stew";
        MinecraftItemTypes2["MusicDisc11"] = "minecraft:music_disc_11";
        MinecraftItemTypes2["MusicDisc13"] = "minecraft:music_disc_13";
        MinecraftItemTypes2["MusicDisc5"] = "minecraft:music_disc_5";
        MinecraftItemTypes2["MusicDiscBlocks"] = "minecraft:music_disc_blocks";
        MinecraftItemTypes2["MusicDiscCat"] = "minecraft:music_disc_cat";
        MinecraftItemTypes2["MusicDiscChirp"] = "minecraft:music_disc_chirp";
        MinecraftItemTypes2["MusicDiscCreator"] = "minecraft:music_disc_creator";
        MinecraftItemTypes2["MusicDiscCreatorMusicBox"] = "minecraft:music_disc_creator_music_box";
        MinecraftItemTypes2["MusicDiscFar"] = "minecraft:music_disc_far";
        MinecraftItemTypes2["MusicDiscLavaChicken"] = "minecraft:music_disc_lava_chicken";
        MinecraftItemTypes2["MusicDiscMall"] = "minecraft:music_disc_mall";
        MinecraftItemTypes2["MusicDiscMellohi"] = "minecraft:music_disc_mellohi";
        MinecraftItemTypes2["MusicDiscOtherside"] = "minecraft:music_disc_otherside";
        MinecraftItemTypes2["MusicDiscPigstep"] = "minecraft:music_disc_pigstep";
        MinecraftItemTypes2["MusicDiscPrecipice"] = "minecraft:music_disc_precipice";
        MinecraftItemTypes2["MusicDiscRelic"] = "minecraft:music_disc_relic";
        MinecraftItemTypes2["MusicDiscStal"] = "minecraft:music_disc_stal";
        MinecraftItemTypes2["MusicDiscStrad"] = "minecraft:music_disc_strad";
        MinecraftItemTypes2["MusicDiscTears"] = "minecraft:music_disc_tears";
        MinecraftItemTypes2["MusicDiscWait"] = "minecraft:music_disc_wait";
        MinecraftItemTypes2["MusicDiscWard"] = "minecraft:music_disc_ward";
        MinecraftItemTypes2["Mutton"] = "minecraft:mutton";
        MinecraftItemTypes2["Mycelium"] = "minecraft:mycelium";
        MinecraftItemTypes2["NameTag"] = "minecraft:name_tag";
        MinecraftItemTypes2["NautilusShell"] = "minecraft:nautilus_shell";
        MinecraftItemTypes2["NautilusSpawnEgg"] = "minecraft:nautilus_spawn_egg";
        MinecraftItemTypes2["NetherBrick"] = "minecraft:nether_brick";
        MinecraftItemTypes2["NetherBrickFence"] = "minecraft:nether_brick_fence";
        MinecraftItemTypes2["NetherBrickSlab"] = "minecraft:nether_brick_slab";
        MinecraftItemTypes2["NetherBrickStairs"] = "minecraft:nether_brick_stairs";
        MinecraftItemTypes2["NetherBrickWall"] = "minecraft:nether_brick_wall";
        MinecraftItemTypes2["NetherGoldOre"] = "minecraft:nether_gold_ore";
        MinecraftItemTypes2["NetherSprouts"] = "minecraft:nether_sprouts";
        MinecraftItemTypes2["NetherStar"] = "minecraft:nether_star";
        MinecraftItemTypes2["NetherWart"] = "minecraft:nether_wart";
        MinecraftItemTypes2["NetherWartBlock"] = "minecraft:nether_wart_block";
        MinecraftItemTypes2["Netherbrick"] = "minecraft:netherbrick";
        MinecraftItemTypes2["NetheriteAxe"] = "minecraft:netherite_axe";
        MinecraftItemTypes2["NetheriteBlock"] = "minecraft:netherite_block";
        MinecraftItemTypes2["NetheriteBoots"] = "minecraft:netherite_boots";
        MinecraftItemTypes2["NetheriteChestplate"] = "minecraft:netherite_chestplate";
        MinecraftItemTypes2["NetheriteHelmet"] = "minecraft:netherite_helmet";
        MinecraftItemTypes2["NetheriteHoe"] = "minecraft:netherite_hoe";
        MinecraftItemTypes2["NetheriteIngot"] = "minecraft:netherite_ingot";
        MinecraftItemTypes2["NetheriteLeggings"] = "minecraft:netherite_leggings";
        MinecraftItemTypes2["NetheriteNautilusArmor"] = "minecraft:netherite_nautilus_armor";
        MinecraftItemTypes2["NetheritePickaxe"] = "minecraft:netherite_pickaxe";
        MinecraftItemTypes2["NetheriteScrap"] = "minecraft:netherite_scrap";
        MinecraftItemTypes2["NetheriteShovel"] = "minecraft:netherite_shovel";
        MinecraftItemTypes2["NetheriteSpear"] = "minecraft:netherite_spear";
        MinecraftItemTypes2["NetheriteSword"] = "minecraft:netherite_sword";
        MinecraftItemTypes2["NetheriteUpgradeSmithingTemplate"] = "minecraft:netherite_upgrade_smithing_template";
        MinecraftItemTypes2["Netherrack"] = "minecraft:netherrack";
        MinecraftItemTypes2["NormalStoneSlab"] = "minecraft:normal_stone_slab";
        MinecraftItemTypes2["NormalStoneStairs"] = "minecraft:normal_stone_stairs";
        MinecraftItemTypes2["Noteblock"] = "minecraft:noteblock";
        MinecraftItemTypes2["OakBoat"] = "minecraft:oak_boat";
        MinecraftItemTypes2["OakChestBoat"] = "minecraft:oak_chest_boat";
        MinecraftItemTypes2["OakFence"] = "minecraft:oak_fence";
        MinecraftItemTypes2["OakHangingSign"] = "minecraft:oak_hanging_sign";
        MinecraftItemTypes2["OakLeaves"] = "minecraft:oak_leaves";
        MinecraftItemTypes2["OakLog"] = "minecraft:oak_log";
        MinecraftItemTypes2["OakPlanks"] = "minecraft:oak_planks";
        MinecraftItemTypes2["OakSapling"] = "minecraft:oak_sapling";
        MinecraftItemTypes2["OakShelf"] = "minecraft:oak_shelf";
        MinecraftItemTypes2["OakSign"] = "minecraft:oak_sign";
        MinecraftItemTypes2["OakSlab"] = "minecraft:oak_slab";
        MinecraftItemTypes2["OakStairs"] = "minecraft:oak_stairs";
        MinecraftItemTypes2["OakWood"] = "minecraft:oak_wood";
        MinecraftItemTypes2["Observer"] = "minecraft:observer";
        MinecraftItemTypes2["Obsidian"] = "minecraft:obsidian";
        MinecraftItemTypes2["OcelotSpawnEgg"] = "minecraft:ocelot_spawn_egg";
        MinecraftItemTypes2["OchreFroglight"] = "minecraft:ochre_froglight";
        MinecraftItemTypes2["OminousBottle"] = "minecraft:ominous_bottle";
        MinecraftItemTypes2["OminousTrialKey"] = "minecraft:ominous_trial_key";
        MinecraftItemTypes2["OpenEyeblossom"] = "minecraft:open_eyeblossom";
        MinecraftItemTypes2["OrangeBundle"] = "minecraft:orange_bundle";
        MinecraftItemTypes2["OrangeCandle"] = "minecraft:orange_candle";
        MinecraftItemTypes2["OrangeCarpet"] = "minecraft:orange_carpet";
        MinecraftItemTypes2["OrangeConcrete"] = "minecraft:orange_concrete";
        MinecraftItemTypes2["OrangeConcretePowder"] = "minecraft:orange_concrete_powder";
        MinecraftItemTypes2["OrangeDye"] = "minecraft:orange_dye";
        MinecraftItemTypes2["OrangeGlazedTerracotta"] = "minecraft:orange_glazed_terracotta";
        MinecraftItemTypes2["OrangeHarness"] = "minecraft:orange_harness";
        MinecraftItemTypes2["OrangeShulkerBox"] = "minecraft:orange_shulker_box";
        MinecraftItemTypes2["OrangeStainedGlass"] = "minecraft:orange_stained_glass";
        MinecraftItemTypes2["OrangeStainedGlassPane"] = "minecraft:orange_stained_glass_pane";
        MinecraftItemTypes2["OrangeTerracotta"] = "minecraft:orange_terracotta";
        MinecraftItemTypes2["OrangeTulip"] = "minecraft:orange_tulip";
        MinecraftItemTypes2["OrangeWool"] = "minecraft:orange_wool";
        MinecraftItemTypes2["OxeyeDaisy"] = "minecraft:oxeye_daisy";
        MinecraftItemTypes2["OxidizedChiseledCopper"] = "minecraft:oxidized_chiseled_copper";
        MinecraftItemTypes2["OxidizedCopper"] = "minecraft:oxidized_copper";
        MinecraftItemTypes2["OxidizedCopperBars"] = "minecraft:oxidized_copper_bars";
        MinecraftItemTypes2["OxidizedCopperBulb"] = "minecraft:oxidized_copper_bulb";
        MinecraftItemTypes2["OxidizedCopperChain"] = "minecraft:oxidized_copper_chain";
        MinecraftItemTypes2["OxidizedCopperChest"] = "minecraft:oxidized_copper_chest";
        MinecraftItemTypes2["OxidizedCopperDoor"] = "minecraft:oxidized_copper_door";
        MinecraftItemTypes2["OxidizedCopperGolemStatue"] = "minecraft:oxidized_copper_golem_statue";
        MinecraftItemTypes2["OxidizedCopperGrate"] = "minecraft:oxidized_copper_grate";
        MinecraftItemTypes2["OxidizedCopperLantern"] = "minecraft:oxidized_copper_lantern";
        MinecraftItemTypes2["OxidizedCopperTrapdoor"] = "minecraft:oxidized_copper_trapdoor";
        MinecraftItemTypes2["OxidizedCutCopper"] = "minecraft:oxidized_cut_copper";
        MinecraftItemTypes2["OxidizedCutCopperSlab"] = "minecraft:oxidized_cut_copper_slab";
        MinecraftItemTypes2["OxidizedCutCopperStairs"] = "minecraft:oxidized_cut_copper_stairs";
        MinecraftItemTypes2["OxidizedLightningRod"] = "minecraft:oxidized_lightning_rod";
        MinecraftItemTypes2["PackedIce"] = "minecraft:packed_ice";
        MinecraftItemTypes2["PackedMud"] = "minecraft:packed_mud";
        MinecraftItemTypes2["Painting"] = "minecraft:painting";
        MinecraftItemTypes2["PaleHangingMoss"] = "minecraft:pale_hanging_moss";
        MinecraftItemTypes2["PaleMossBlock"] = "minecraft:pale_moss_block";
        MinecraftItemTypes2["PaleMossCarpet"] = "minecraft:pale_moss_carpet";
        MinecraftItemTypes2["PaleOakBoat"] = "minecraft:pale_oak_boat";
        MinecraftItemTypes2["PaleOakButton"] = "minecraft:pale_oak_button";
        MinecraftItemTypes2["PaleOakChestBoat"] = "minecraft:pale_oak_chest_boat";
        MinecraftItemTypes2["PaleOakDoor"] = "minecraft:pale_oak_door";
        MinecraftItemTypes2["PaleOakFence"] = "minecraft:pale_oak_fence";
        MinecraftItemTypes2["PaleOakFenceGate"] = "minecraft:pale_oak_fence_gate";
        MinecraftItemTypes2["PaleOakHangingSign"] = "minecraft:pale_oak_hanging_sign";
        MinecraftItemTypes2["PaleOakLeaves"] = "minecraft:pale_oak_leaves";
        MinecraftItemTypes2["PaleOakLog"] = "minecraft:pale_oak_log";
        MinecraftItemTypes2["PaleOakPlanks"] = "minecraft:pale_oak_planks";
        MinecraftItemTypes2["PaleOakPressurePlate"] = "minecraft:pale_oak_pressure_plate";
        MinecraftItemTypes2["PaleOakSapling"] = "minecraft:pale_oak_sapling";
        MinecraftItemTypes2["PaleOakShelf"] = "minecraft:pale_oak_shelf";
        MinecraftItemTypes2["PaleOakSign"] = "minecraft:pale_oak_sign";
        MinecraftItemTypes2["PaleOakSlab"] = "minecraft:pale_oak_slab";
        MinecraftItemTypes2["PaleOakStairs"] = "minecraft:pale_oak_stairs";
        MinecraftItemTypes2["PaleOakTrapdoor"] = "minecraft:pale_oak_trapdoor";
        MinecraftItemTypes2["PaleOakWood"] = "minecraft:pale_oak_wood";
        MinecraftItemTypes2["PandaSpawnEgg"] = "minecraft:panda_spawn_egg";
        MinecraftItemTypes2["Paper"] = "minecraft:paper";
        MinecraftItemTypes2["ParchedSpawnEgg"] = "minecraft:parched_spawn_egg";
        MinecraftItemTypes2["ParrotSpawnEgg"] = "minecraft:parrot_spawn_egg";
        MinecraftItemTypes2["PearlescentFroglight"] = "minecraft:pearlescent_froglight";
        MinecraftItemTypes2["Peony"] = "minecraft:peony";
        MinecraftItemTypes2["PetrifiedOakSlab"] = "minecraft:petrified_oak_slab";
        MinecraftItemTypes2["PhantomMembrane"] = "minecraft:phantom_membrane";
        MinecraftItemTypes2["PhantomSpawnEgg"] = "minecraft:phantom_spawn_egg";
        MinecraftItemTypes2["PigSpawnEgg"] = "minecraft:pig_spawn_egg";
        MinecraftItemTypes2["PiglinBannerPattern"] = "minecraft:piglin_banner_pattern";
        MinecraftItemTypes2["PiglinBruteSpawnEgg"] = "minecraft:piglin_brute_spawn_egg";
        MinecraftItemTypes2["PiglinHead"] = "minecraft:piglin_head";
        MinecraftItemTypes2["PiglinSpawnEgg"] = "minecraft:piglin_spawn_egg";
        MinecraftItemTypes2["PillagerSpawnEgg"] = "minecraft:pillager_spawn_egg";
        MinecraftItemTypes2["PinkBundle"] = "minecraft:pink_bundle";
        MinecraftItemTypes2["PinkCandle"] = "minecraft:pink_candle";
        MinecraftItemTypes2["PinkCarpet"] = "minecraft:pink_carpet";
        MinecraftItemTypes2["PinkConcrete"] = "minecraft:pink_concrete";
        MinecraftItemTypes2["PinkConcretePowder"] = "minecraft:pink_concrete_powder";
        MinecraftItemTypes2["PinkDye"] = "minecraft:pink_dye";
        MinecraftItemTypes2["PinkGlazedTerracotta"] = "minecraft:pink_glazed_terracotta";
        MinecraftItemTypes2["PinkHarness"] = "minecraft:pink_harness";
        MinecraftItemTypes2["PinkPetals"] = "minecraft:pink_petals";
        MinecraftItemTypes2["PinkShulkerBox"] = "minecraft:pink_shulker_box";
        MinecraftItemTypes2["PinkStainedGlass"] = "minecraft:pink_stained_glass";
        MinecraftItemTypes2["PinkStainedGlassPane"] = "minecraft:pink_stained_glass_pane";
        MinecraftItemTypes2["PinkTerracotta"] = "minecraft:pink_terracotta";
        MinecraftItemTypes2["PinkTulip"] = "minecraft:pink_tulip";
        MinecraftItemTypes2["PinkWool"] = "minecraft:pink_wool";
        MinecraftItemTypes2["Piston"] = "minecraft:piston";
        MinecraftItemTypes2["PitcherPlant"] = "minecraft:pitcher_plant";
        MinecraftItemTypes2["PitcherPod"] = "minecraft:pitcher_pod";
        MinecraftItemTypes2["PlayerHead"] = "minecraft:player_head";
        MinecraftItemTypes2["PlentyPotterySherd"] = "minecraft:plenty_pottery_sherd";
        MinecraftItemTypes2["Podzol"] = "minecraft:podzol";
        MinecraftItemTypes2["PointedDripstone"] = "minecraft:pointed_dripstone";
        MinecraftItemTypes2["PoisonousPotato"] = "minecraft:poisonous_potato";
        MinecraftItemTypes2["PolarBearSpawnEgg"] = "minecraft:polar_bear_spawn_egg";
        MinecraftItemTypes2["PolishedAndesite"] = "minecraft:polished_andesite";
        MinecraftItemTypes2["PolishedAndesiteSlab"] = "minecraft:polished_andesite_slab";
        MinecraftItemTypes2["PolishedAndesiteStairs"] = "minecraft:polished_andesite_stairs";
        MinecraftItemTypes2["PolishedBasalt"] = "minecraft:polished_basalt";
        MinecraftItemTypes2["PolishedBlackstone"] = "minecraft:polished_blackstone";
        MinecraftItemTypes2["PolishedBlackstoneBrickSlab"] = "minecraft:polished_blackstone_brick_slab";
        MinecraftItemTypes2["PolishedBlackstoneBrickStairs"] = "minecraft:polished_blackstone_brick_stairs";
        MinecraftItemTypes2["PolishedBlackstoneBrickWall"] = "minecraft:polished_blackstone_brick_wall";
        MinecraftItemTypes2["PolishedBlackstoneBricks"] = "minecraft:polished_blackstone_bricks";
        MinecraftItemTypes2["PolishedBlackstoneButton"] = "minecraft:polished_blackstone_button";
        MinecraftItemTypes2["PolishedBlackstonePressurePlate"] = "minecraft:polished_blackstone_pressure_plate";
        MinecraftItemTypes2["PolishedBlackstoneSlab"] = "minecraft:polished_blackstone_slab";
        MinecraftItemTypes2["PolishedBlackstoneStairs"] = "minecraft:polished_blackstone_stairs";
        MinecraftItemTypes2["PolishedBlackstoneWall"] = "minecraft:polished_blackstone_wall";
        MinecraftItemTypes2["PolishedDeepslate"] = "minecraft:polished_deepslate";
        MinecraftItemTypes2["PolishedDeepslateSlab"] = "minecraft:polished_deepslate_slab";
        MinecraftItemTypes2["PolishedDeepslateStairs"] = "minecraft:polished_deepslate_stairs";
        MinecraftItemTypes2["PolishedDeepslateWall"] = "minecraft:polished_deepslate_wall";
        MinecraftItemTypes2["PolishedDiorite"] = "minecraft:polished_diorite";
        MinecraftItemTypes2["PolishedDioriteSlab"] = "minecraft:polished_diorite_slab";
        MinecraftItemTypes2["PolishedDioriteStairs"] = "minecraft:polished_diorite_stairs";
        MinecraftItemTypes2["PolishedGranite"] = "minecraft:polished_granite";
        MinecraftItemTypes2["PolishedGraniteSlab"] = "minecraft:polished_granite_slab";
        MinecraftItemTypes2["PolishedGraniteStairs"] = "minecraft:polished_granite_stairs";
        MinecraftItemTypes2["PolishedTuff"] = "minecraft:polished_tuff";
        MinecraftItemTypes2["PolishedTuffSlab"] = "minecraft:polished_tuff_slab";
        MinecraftItemTypes2["PolishedTuffStairs"] = "minecraft:polished_tuff_stairs";
        MinecraftItemTypes2["PolishedTuffWall"] = "minecraft:polished_tuff_wall";
        MinecraftItemTypes2["PoppedChorusFruit"] = "minecraft:popped_chorus_fruit";
        MinecraftItemTypes2["Poppy"] = "minecraft:poppy";
        MinecraftItemTypes2["Porkchop"] = "minecraft:porkchop";
        MinecraftItemTypes2["Potato"] = "minecraft:potato";
        MinecraftItemTypes2["Potion"] = "minecraft:potion";
        MinecraftItemTypes2["PowderSnowBucket"] = "minecraft:powder_snow_bucket";
        MinecraftItemTypes2["Prismarine"] = "minecraft:prismarine";
        MinecraftItemTypes2["PrismarineBrickSlab"] = "minecraft:prismarine_brick_slab";
        MinecraftItemTypes2["PrismarineBricks"] = "minecraft:prismarine_bricks";
        MinecraftItemTypes2["PrismarineBricksStairs"] = "minecraft:prismarine_bricks_stairs";
        MinecraftItemTypes2["PrismarineCrystals"] = "minecraft:prismarine_crystals";
        MinecraftItemTypes2["PrismarineShard"] = "minecraft:prismarine_shard";
        MinecraftItemTypes2["PrismarineSlab"] = "minecraft:prismarine_slab";
        MinecraftItemTypes2["PrismarineStairs"] = "minecraft:prismarine_stairs";
        MinecraftItemTypes2["PrismarineWall"] = "minecraft:prismarine_wall";
        MinecraftItemTypes2["PrizePotterySherd"] = "minecraft:prize_pottery_sherd";
        MinecraftItemTypes2["Pufferfish"] = "minecraft:pufferfish";
        MinecraftItemTypes2["PufferfishBucket"] = "minecraft:pufferfish_bucket";
        MinecraftItemTypes2["PufferfishSpawnEgg"] = "minecraft:pufferfish_spawn_egg";
        MinecraftItemTypes2["Pumpkin"] = "minecraft:pumpkin";
        MinecraftItemTypes2["PumpkinPie"] = "minecraft:pumpkin_pie";
        MinecraftItemTypes2["PumpkinSeeds"] = "minecraft:pumpkin_seeds";
        MinecraftItemTypes2["PurpleBundle"] = "minecraft:purple_bundle";
        MinecraftItemTypes2["PurpleCandle"] = "minecraft:purple_candle";
        MinecraftItemTypes2["PurpleCarpet"] = "minecraft:purple_carpet";
        MinecraftItemTypes2["PurpleConcrete"] = "minecraft:purple_concrete";
        MinecraftItemTypes2["PurpleConcretePowder"] = "minecraft:purple_concrete_powder";
        MinecraftItemTypes2["PurpleDye"] = "minecraft:purple_dye";
        MinecraftItemTypes2["PurpleGlazedTerracotta"] = "minecraft:purple_glazed_terracotta";
        MinecraftItemTypes2["PurpleHarness"] = "minecraft:purple_harness";
        MinecraftItemTypes2["PurpleShulkerBox"] = "minecraft:purple_shulker_box";
        MinecraftItemTypes2["PurpleStainedGlass"] = "minecraft:purple_stained_glass";
        MinecraftItemTypes2["PurpleStainedGlassPane"] = "minecraft:purple_stained_glass_pane";
        MinecraftItemTypes2["PurpleTerracotta"] = "minecraft:purple_terracotta";
        MinecraftItemTypes2["PurpleWool"] = "minecraft:purple_wool";
        MinecraftItemTypes2["PurpurBlock"] = "minecraft:purpur_block";
        MinecraftItemTypes2["PurpurPillar"] = "minecraft:purpur_pillar";
        MinecraftItemTypes2["PurpurSlab"] = "minecraft:purpur_slab";
        MinecraftItemTypes2["PurpurStairs"] = "minecraft:purpur_stairs";
        MinecraftItemTypes2["Quartz"] = "minecraft:quartz";
        MinecraftItemTypes2["QuartzBlock"] = "minecraft:quartz_block";
        MinecraftItemTypes2["QuartzBricks"] = "minecraft:quartz_bricks";
        MinecraftItemTypes2["QuartzOre"] = "minecraft:quartz_ore";
        MinecraftItemTypes2["QuartzPillar"] = "minecraft:quartz_pillar";
        MinecraftItemTypes2["QuartzSlab"] = "minecraft:quartz_slab";
        MinecraftItemTypes2["QuartzStairs"] = "minecraft:quartz_stairs";
        MinecraftItemTypes2["Rabbit"] = "minecraft:rabbit";
        MinecraftItemTypes2["RabbitFoot"] = "minecraft:rabbit_foot";
        MinecraftItemTypes2["RabbitHide"] = "minecraft:rabbit_hide";
        MinecraftItemTypes2["RabbitSpawnEgg"] = "minecraft:rabbit_spawn_egg";
        MinecraftItemTypes2["RabbitStew"] = "minecraft:rabbit_stew";
        MinecraftItemTypes2["Rail"] = "minecraft:rail";
        MinecraftItemTypes2["RaiserArmorTrimSmithingTemplate"] = "minecraft:raiser_armor_trim_smithing_template";
        MinecraftItemTypes2["RavagerSpawnEgg"] = "minecraft:ravager_spawn_egg";
        MinecraftItemTypes2["RawCopper"] = "minecraft:raw_copper";
        MinecraftItemTypes2["RawCopperBlock"] = "minecraft:raw_copper_block";
        MinecraftItemTypes2["RawGold"] = "minecraft:raw_gold";
        MinecraftItemTypes2["RawGoldBlock"] = "minecraft:raw_gold_block";
        MinecraftItemTypes2["RawIron"] = "minecraft:raw_iron";
        MinecraftItemTypes2["RawIronBlock"] = "minecraft:raw_iron_block";
        MinecraftItemTypes2["RecoveryCompass"] = "minecraft:recovery_compass";
        MinecraftItemTypes2["RedBundle"] = "minecraft:red_bundle";
        MinecraftItemTypes2["RedCandle"] = "minecraft:red_candle";
        MinecraftItemTypes2["RedCarpet"] = "minecraft:red_carpet";
        MinecraftItemTypes2["RedConcrete"] = "minecraft:red_concrete";
        MinecraftItemTypes2["RedConcretePowder"] = "minecraft:red_concrete_powder";
        MinecraftItemTypes2["RedDye"] = "minecraft:red_dye";
        MinecraftItemTypes2["RedGlazedTerracotta"] = "minecraft:red_glazed_terracotta";
        MinecraftItemTypes2["RedHarness"] = "minecraft:red_harness";
        MinecraftItemTypes2["RedMushroom"] = "minecraft:red_mushroom";
        MinecraftItemTypes2["RedMushroomBlock"] = "minecraft:red_mushroom_block";
        MinecraftItemTypes2["RedNetherBrick"] = "minecraft:red_nether_brick";
        MinecraftItemTypes2["RedNetherBrickSlab"] = "minecraft:red_nether_brick_slab";
        MinecraftItemTypes2["RedNetherBrickStairs"] = "minecraft:red_nether_brick_stairs";
        MinecraftItemTypes2["RedNetherBrickWall"] = "minecraft:red_nether_brick_wall";
        MinecraftItemTypes2["RedSand"] = "minecraft:red_sand";
        MinecraftItemTypes2["RedSandstone"] = "minecraft:red_sandstone";
        MinecraftItemTypes2["RedSandstoneSlab"] = "minecraft:red_sandstone_slab";
        MinecraftItemTypes2["RedSandstoneStairs"] = "minecraft:red_sandstone_stairs";
        MinecraftItemTypes2["RedSandstoneWall"] = "minecraft:red_sandstone_wall";
        MinecraftItemTypes2["RedShulkerBox"] = "minecraft:red_shulker_box";
        MinecraftItemTypes2["RedStainedGlass"] = "minecraft:red_stained_glass";
        MinecraftItemTypes2["RedStainedGlassPane"] = "minecraft:red_stained_glass_pane";
        MinecraftItemTypes2["RedTerracotta"] = "minecraft:red_terracotta";
        MinecraftItemTypes2["RedTulip"] = "minecraft:red_tulip";
        MinecraftItemTypes2["RedWool"] = "minecraft:red_wool";
        MinecraftItemTypes2["Redstone"] = "minecraft:redstone";
        MinecraftItemTypes2["RedstoneBlock"] = "minecraft:redstone_block";
        MinecraftItemTypes2["RedstoneLamp"] = "minecraft:redstone_lamp";
        MinecraftItemTypes2["RedstoneOre"] = "minecraft:redstone_ore";
        MinecraftItemTypes2["RedstoneTorch"] = "minecraft:redstone_torch";
        MinecraftItemTypes2["ReinforcedDeepslate"] = "minecraft:reinforced_deepslate";
        MinecraftItemTypes2["Repeater"] = "minecraft:repeater";
        MinecraftItemTypes2["RepeatingCommandBlock"] = "minecraft:repeating_command_block";
        MinecraftItemTypes2["ResinBlock"] = "minecraft:resin_block";
        MinecraftItemTypes2["ResinBrick"] = "minecraft:resin_brick";
        MinecraftItemTypes2["ResinBrickSlab"] = "minecraft:resin_brick_slab";
        MinecraftItemTypes2["ResinBrickStairs"] = "minecraft:resin_brick_stairs";
        MinecraftItemTypes2["ResinBrickWall"] = "minecraft:resin_brick_wall";
        MinecraftItemTypes2["ResinBricks"] = "minecraft:resin_bricks";
        MinecraftItemTypes2["ResinClump"] = "minecraft:resin_clump";
        MinecraftItemTypes2["RespawnAnchor"] = "minecraft:respawn_anchor";
        MinecraftItemTypes2["RibArmorTrimSmithingTemplate"] = "minecraft:rib_armor_trim_smithing_template";
        MinecraftItemTypes2["RoseBush"] = "minecraft:rose_bush";
        MinecraftItemTypes2["RottenFlesh"] = "minecraft:rotten_flesh";
        MinecraftItemTypes2["Saddle"] = "minecraft:saddle";
        MinecraftItemTypes2["Salmon"] = "minecraft:salmon";
        MinecraftItemTypes2["SalmonBucket"] = "minecraft:salmon_bucket";
        MinecraftItemTypes2["SalmonSpawnEgg"] = "minecraft:salmon_spawn_egg";
        MinecraftItemTypes2["Sand"] = "minecraft:sand";
        MinecraftItemTypes2["Sandstone"] = "minecraft:sandstone";
        MinecraftItemTypes2["SandstoneSlab"] = "minecraft:sandstone_slab";
        MinecraftItemTypes2["SandstoneStairs"] = "minecraft:sandstone_stairs";
        MinecraftItemTypes2["SandstoneWall"] = "minecraft:sandstone_wall";
        MinecraftItemTypes2["Scaffolding"] = "minecraft:scaffolding";
        MinecraftItemTypes2["ScrapePotterySherd"] = "minecraft:scrape_pottery_sherd";
        MinecraftItemTypes2["Sculk"] = "minecraft:sculk";
        MinecraftItemTypes2["SculkCatalyst"] = "minecraft:sculk_catalyst";
        MinecraftItemTypes2["SculkSensor"] = "minecraft:sculk_sensor";
        MinecraftItemTypes2["SculkShrieker"] = "minecraft:sculk_shrieker";
        MinecraftItemTypes2["SculkVein"] = "minecraft:sculk_vein";
        MinecraftItemTypes2["SeaLantern"] = "minecraft:sea_lantern";
        MinecraftItemTypes2["SeaPickle"] = "minecraft:sea_pickle";
        MinecraftItemTypes2["Seagrass"] = "minecraft:seagrass";
        MinecraftItemTypes2["SentryArmorTrimSmithingTemplate"] = "minecraft:sentry_armor_trim_smithing_template";
        MinecraftItemTypes2["ShaperArmorTrimSmithingTemplate"] = "minecraft:shaper_armor_trim_smithing_template";
        MinecraftItemTypes2["SheafPotterySherd"] = "minecraft:sheaf_pottery_sherd";
        MinecraftItemTypes2["Shears"] = "minecraft:shears";
        MinecraftItemTypes2["SheepSpawnEgg"] = "minecraft:sheep_spawn_egg";
        MinecraftItemTypes2["ShelterPotterySherd"] = "minecraft:shelter_pottery_sherd";
        MinecraftItemTypes2["Shield"] = "minecraft:shield";
        MinecraftItemTypes2["ShortDryGrass"] = "minecraft:short_dry_grass";
        MinecraftItemTypes2["ShortGrass"] = "minecraft:short_grass";
        MinecraftItemTypes2["Shroomlight"] = "minecraft:shroomlight";
        MinecraftItemTypes2["ShulkerShell"] = "minecraft:shulker_shell";
        MinecraftItemTypes2["ShulkerSpawnEgg"] = "minecraft:shulker_spawn_egg";
        MinecraftItemTypes2["SilenceArmorTrimSmithingTemplate"] = "minecraft:silence_armor_trim_smithing_template";
        MinecraftItemTypes2["SilverGlazedTerracotta"] = "minecraft:silver_glazed_terracotta";
        MinecraftItemTypes2["SilverfishSpawnEgg"] = "minecraft:silverfish_spawn_egg";
        MinecraftItemTypes2["SkeletonHorseSpawnEgg"] = "minecraft:skeleton_horse_spawn_egg";
        MinecraftItemTypes2["SkeletonSkull"] = "minecraft:skeleton_skull";
        MinecraftItemTypes2["SkeletonSpawnEgg"] = "minecraft:skeleton_spawn_egg";
        MinecraftItemTypes2["SkullBannerPattern"] = "minecraft:skull_banner_pattern";
        MinecraftItemTypes2["SkullPotterySherd"] = "minecraft:skull_pottery_sherd";
        MinecraftItemTypes2["Slime"] = "minecraft:slime";
        MinecraftItemTypes2["SlimeBall"] = "minecraft:slime_ball";
        MinecraftItemTypes2["SlimeSpawnEgg"] = "minecraft:slime_spawn_egg";
        MinecraftItemTypes2["SmallAmethystBud"] = "minecraft:small_amethyst_bud";
        MinecraftItemTypes2["SmallDripleafBlock"] = "minecraft:small_dripleaf_block";
        MinecraftItemTypes2["SmithingTable"] = "minecraft:smithing_table";
        MinecraftItemTypes2["Smoker"] = "minecraft:smoker";
        MinecraftItemTypes2["SmoothBasalt"] = "minecraft:smooth_basalt";
        MinecraftItemTypes2["SmoothQuartz"] = "minecraft:smooth_quartz";
        MinecraftItemTypes2["SmoothQuartzSlab"] = "minecraft:smooth_quartz_slab";
        MinecraftItemTypes2["SmoothQuartzStairs"] = "minecraft:smooth_quartz_stairs";
        MinecraftItemTypes2["SmoothRedSandstone"] = "minecraft:smooth_red_sandstone";
        MinecraftItemTypes2["SmoothRedSandstoneSlab"] = "minecraft:smooth_red_sandstone_slab";
        MinecraftItemTypes2["SmoothRedSandstoneStairs"] = "minecraft:smooth_red_sandstone_stairs";
        MinecraftItemTypes2["SmoothSandstone"] = "minecraft:smooth_sandstone";
        MinecraftItemTypes2["SmoothSandstoneSlab"] = "minecraft:smooth_sandstone_slab";
        MinecraftItemTypes2["SmoothSandstoneStairs"] = "minecraft:smooth_sandstone_stairs";
        MinecraftItemTypes2["SmoothStone"] = "minecraft:smooth_stone";
        MinecraftItemTypes2["SmoothStoneSlab"] = "minecraft:smooth_stone_slab";
        MinecraftItemTypes2["SnifferEgg"] = "minecraft:sniffer_egg";
        MinecraftItemTypes2["SnifferSpawnEgg"] = "minecraft:sniffer_spawn_egg";
        MinecraftItemTypes2["SnortPotterySherd"] = "minecraft:snort_pottery_sherd";
        MinecraftItemTypes2["SnoutArmorTrimSmithingTemplate"] = "minecraft:snout_armor_trim_smithing_template";
        MinecraftItemTypes2["Snow"] = "minecraft:snow";
        MinecraftItemTypes2["SnowGolemSpawnEgg"] = "minecraft:snow_golem_spawn_egg";
        MinecraftItemTypes2["SnowLayer"] = "minecraft:snow_layer";
        MinecraftItemTypes2["Snowball"] = "minecraft:snowball";
        MinecraftItemTypes2["SoulCampfire"] = "minecraft:soul_campfire";
        MinecraftItemTypes2["SoulLantern"] = "minecraft:soul_lantern";
        MinecraftItemTypes2["SoulSand"] = "minecraft:soul_sand";
        MinecraftItemTypes2["SoulSoil"] = "minecraft:soul_soil";
        MinecraftItemTypes2["SoulTorch"] = "minecraft:soul_torch";
        MinecraftItemTypes2["SpiderEye"] = "minecraft:spider_eye";
        MinecraftItemTypes2["SpiderSpawnEgg"] = "minecraft:spider_spawn_egg";
        MinecraftItemTypes2["SpireArmorTrimSmithingTemplate"] = "minecraft:spire_armor_trim_smithing_template";
        MinecraftItemTypes2["SplashPotion"] = "minecraft:splash_potion";
        MinecraftItemTypes2["Sponge"] = "minecraft:sponge";
        MinecraftItemTypes2["SporeBlossom"] = "minecraft:spore_blossom";
        MinecraftItemTypes2["SpruceBoat"] = "minecraft:spruce_boat";
        MinecraftItemTypes2["SpruceButton"] = "minecraft:spruce_button";
        MinecraftItemTypes2["SpruceChestBoat"] = "minecraft:spruce_chest_boat";
        MinecraftItemTypes2["SpruceDoor"] = "minecraft:spruce_door";
        MinecraftItemTypes2["SpruceFence"] = "minecraft:spruce_fence";
        MinecraftItemTypes2["SpruceFenceGate"] = "minecraft:spruce_fence_gate";
        MinecraftItemTypes2["SpruceHangingSign"] = "minecraft:spruce_hanging_sign";
        MinecraftItemTypes2["SpruceLeaves"] = "minecraft:spruce_leaves";
        MinecraftItemTypes2["SpruceLog"] = "minecraft:spruce_log";
        MinecraftItemTypes2["SprucePlanks"] = "minecraft:spruce_planks";
        MinecraftItemTypes2["SprucePressurePlate"] = "minecraft:spruce_pressure_plate";
        MinecraftItemTypes2["SpruceSapling"] = "minecraft:spruce_sapling";
        MinecraftItemTypes2["SpruceShelf"] = "minecraft:spruce_shelf";
        MinecraftItemTypes2["SpruceSign"] = "minecraft:spruce_sign";
        MinecraftItemTypes2["SpruceSlab"] = "minecraft:spruce_slab";
        MinecraftItemTypes2["SpruceStairs"] = "minecraft:spruce_stairs";
        MinecraftItemTypes2["SpruceTrapdoor"] = "minecraft:spruce_trapdoor";
        MinecraftItemTypes2["SpruceWood"] = "minecraft:spruce_wood";
        MinecraftItemTypes2["Spyglass"] = "minecraft:spyglass";
        MinecraftItemTypes2["SquidSpawnEgg"] = "minecraft:squid_spawn_egg";
        MinecraftItemTypes2["Stick"] = "minecraft:stick";
        MinecraftItemTypes2["StickyPiston"] = "minecraft:sticky_piston";
        MinecraftItemTypes2["Stone"] = "minecraft:stone";
        MinecraftItemTypes2["StoneAxe"] = "minecraft:stone_axe";
        MinecraftItemTypes2["StoneBrickSlab"] = "minecraft:stone_brick_slab";
        MinecraftItemTypes2["StoneBrickStairs"] = "minecraft:stone_brick_stairs";
        MinecraftItemTypes2["StoneBrickWall"] = "minecraft:stone_brick_wall";
        MinecraftItemTypes2["StoneBricks"] = "minecraft:stone_bricks";
        MinecraftItemTypes2["StoneButton"] = "minecraft:stone_button";
        MinecraftItemTypes2["StoneHoe"] = "minecraft:stone_hoe";
        MinecraftItemTypes2["StonePickaxe"] = "minecraft:stone_pickaxe";
        MinecraftItemTypes2["StonePressurePlate"] = "minecraft:stone_pressure_plate";
        MinecraftItemTypes2["StoneShovel"] = "minecraft:stone_shovel";
        MinecraftItemTypes2["StoneSpear"] = "minecraft:stone_spear";
        MinecraftItemTypes2["StoneStairs"] = "minecraft:stone_stairs";
        MinecraftItemTypes2["StoneSword"] = "minecraft:stone_sword";
        MinecraftItemTypes2["StonecutterBlock"] = "minecraft:stonecutter_block";
        MinecraftItemTypes2["StraySpawnEgg"] = "minecraft:stray_spawn_egg";
        MinecraftItemTypes2["StriderSpawnEgg"] = "minecraft:strider_spawn_egg";
        MinecraftItemTypes2["String"] = "minecraft:string";
        MinecraftItemTypes2["StrippedAcaciaLog"] = "minecraft:stripped_acacia_log";
        MinecraftItemTypes2["StrippedAcaciaWood"] = "minecraft:stripped_acacia_wood";
        MinecraftItemTypes2["StrippedBambooBlock"] = "minecraft:stripped_bamboo_block";
        MinecraftItemTypes2["StrippedBirchLog"] = "minecraft:stripped_birch_log";
        MinecraftItemTypes2["StrippedBirchWood"] = "minecraft:stripped_birch_wood";
        MinecraftItemTypes2["StrippedCherryLog"] = "minecraft:stripped_cherry_log";
        MinecraftItemTypes2["StrippedCherryWood"] = "minecraft:stripped_cherry_wood";
        MinecraftItemTypes2["StrippedCrimsonHyphae"] = "minecraft:stripped_crimson_hyphae";
        MinecraftItemTypes2["StrippedCrimsonStem"] = "minecraft:stripped_crimson_stem";
        MinecraftItemTypes2["StrippedDarkOakLog"] = "minecraft:stripped_dark_oak_log";
        MinecraftItemTypes2["StrippedDarkOakWood"] = "minecraft:stripped_dark_oak_wood";
        MinecraftItemTypes2["StrippedJungleLog"] = "minecraft:stripped_jungle_log";
        MinecraftItemTypes2["StrippedJungleWood"] = "minecraft:stripped_jungle_wood";
        MinecraftItemTypes2["StrippedMangroveLog"] = "minecraft:stripped_mangrove_log";
        MinecraftItemTypes2["StrippedMangroveWood"] = "minecraft:stripped_mangrove_wood";
        MinecraftItemTypes2["StrippedOakLog"] = "minecraft:stripped_oak_log";
        MinecraftItemTypes2["StrippedOakWood"] = "minecraft:stripped_oak_wood";
        MinecraftItemTypes2["StrippedPaleOakLog"] = "minecraft:stripped_pale_oak_log";
        MinecraftItemTypes2["StrippedPaleOakWood"] = "minecraft:stripped_pale_oak_wood";
        MinecraftItemTypes2["StrippedSpruceLog"] = "minecraft:stripped_spruce_log";
        MinecraftItemTypes2["StrippedSpruceWood"] = "minecraft:stripped_spruce_wood";
        MinecraftItemTypes2["StrippedWarpedHyphae"] = "minecraft:stripped_warped_hyphae";
        MinecraftItemTypes2["StrippedWarpedStem"] = "minecraft:stripped_warped_stem";
        MinecraftItemTypes2["StructureBlock"] = "minecraft:structure_block";
        MinecraftItemTypes2["StructureVoid"] = "minecraft:structure_void";
        MinecraftItemTypes2["Sugar"] = "minecraft:sugar";
        MinecraftItemTypes2["SugarCane"] = "minecraft:sugar_cane";
        MinecraftItemTypes2["Sunflower"] = "minecraft:sunflower";
        MinecraftItemTypes2["SuspiciousGravel"] = "minecraft:suspicious_gravel";
        MinecraftItemTypes2["SuspiciousSand"] = "minecraft:suspicious_sand";
        MinecraftItemTypes2["SuspiciousStew"] = "minecraft:suspicious_stew";
        MinecraftItemTypes2["SweetBerries"] = "minecraft:sweet_berries";
        MinecraftItemTypes2["TadpoleBucket"] = "minecraft:tadpole_bucket";
        MinecraftItemTypes2["TadpoleSpawnEgg"] = "minecraft:tadpole_spawn_egg";
        MinecraftItemTypes2["TallDryGrass"] = "minecraft:tall_dry_grass";
        MinecraftItemTypes2["TallGrass"] = "minecraft:tall_grass";
        MinecraftItemTypes2["Target"] = "minecraft:target";
        MinecraftItemTypes2["TideArmorTrimSmithingTemplate"] = "minecraft:tide_armor_trim_smithing_template";
        MinecraftItemTypes2["TintedGlass"] = "minecraft:tinted_glass";
        MinecraftItemTypes2["Tnt"] = "minecraft:tnt";
        MinecraftItemTypes2["TntMinecart"] = "minecraft:tnt_minecart";
        MinecraftItemTypes2["Torch"] = "minecraft:torch";
        MinecraftItemTypes2["Torchflower"] = "minecraft:torchflower";
        MinecraftItemTypes2["TorchflowerSeeds"] = "minecraft:torchflower_seeds";
        MinecraftItemTypes2["TotemOfUndying"] = "minecraft:totem_of_undying";
        MinecraftItemTypes2["TraderLlamaSpawnEgg"] = "minecraft:trader_llama_spawn_egg";
        MinecraftItemTypes2["Trapdoor"] = "minecraft:trapdoor";
        MinecraftItemTypes2["TrappedChest"] = "minecraft:trapped_chest";
        MinecraftItemTypes2["TrialKey"] = "minecraft:trial_key";
        MinecraftItemTypes2["TrialSpawner"] = "minecraft:trial_spawner";
        MinecraftItemTypes2["Trident"] = "minecraft:trident";
        MinecraftItemTypes2["TripwireHook"] = "minecraft:tripwire_hook";
        MinecraftItemTypes2["TropicalFish"] = "minecraft:tropical_fish";
        MinecraftItemTypes2["TropicalFishBucket"] = "minecraft:tropical_fish_bucket";
        MinecraftItemTypes2["TropicalFishSpawnEgg"] = "minecraft:tropical_fish_spawn_egg";
        MinecraftItemTypes2["TubeCoral"] = "minecraft:tube_coral";
        MinecraftItemTypes2["TubeCoralBlock"] = "minecraft:tube_coral_block";
        MinecraftItemTypes2["TubeCoralFan"] = "minecraft:tube_coral_fan";
        MinecraftItemTypes2["Tuff"] = "minecraft:tuff";
        MinecraftItemTypes2["TuffBrickSlab"] = "minecraft:tuff_brick_slab";
        MinecraftItemTypes2["TuffBrickStairs"] = "minecraft:tuff_brick_stairs";
        MinecraftItemTypes2["TuffBrickWall"] = "minecraft:tuff_brick_wall";
        MinecraftItemTypes2["TuffBricks"] = "minecraft:tuff_bricks";
        MinecraftItemTypes2["TuffSlab"] = "minecraft:tuff_slab";
        MinecraftItemTypes2["TuffStairs"] = "minecraft:tuff_stairs";
        MinecraftItemTypes2["TuffWall"] = "minecraft:tuff_wall";
        MinecraftItemTypes2["TurtleEgg"] = "minecraft:turtle_egg";
        MinecraftItemTypes2["TurtleHelmet"] = "minecraft:turtle_helmet";
        MinecraftItemTypes2["TurtleScute"] = "minecraft:turtle_scute";
        MinecraftItemTypes2["TurtleSpawnEgg"] = "minecraft:turtle_spawn_egg";
        MinecraftItemTypes2["TwistingVines"] = "minecraft:twisting_vines";
        MinecraftItemTypes2["UndyedShulkerBox"] = "minecraft:undyed_shulker_box";
        MinecraftItemTypes2["Vault"] = "minecraft:vault";
        MinecraftItemTypes2["VerdantFroglight"] = "minecraft:verdant_froglight";
        MinecraftItemTypes2["VexArmorTrimSmithingTemplate"] = "minecraft:vex_armor_trim_smithing_template";
        MinecraftItemTypes2["VexSpawnEgg"] = "minecraft:vex_spawn_egg";
        MinecraftItemTypes2["VillagerSpawnEgg"] = "minecraft:villager_spawn_egg";
        MinecraftItemTypes2["VindicatorSpawnEgg"] = "minecraft:vindicator_spawn_egg";
        MinecraftItemTypes2["Vine"] = "minecraft:vine";
        MinecraftItemTypes2["WanderingTraderSpawnEgg"] = "minecraft:wandering_trader_spawn_egg";
        MinecraftItemTypes2["WardArmorTrimSmithingTemplate"] = "minecraft:ward_armor_trim_smithing_template";
        MinecraftItemTypes2["WardenSpawnEgg"] = "minecraft:warden_spawn_egg";
        MinecraftItemTypes2["WarpedButton"] = "minecraft:warped_button";
        MinecraftItemTypes2["WarpedDoor"] = "minecraft:warped_door";
        MinecraftItemTypes2["WarpedFence"] = "minecraft:warped_fence";
        MinecraftItemTypes2["WarpedFenceGate"] = "minecraft:warped_fence_gate";
        MinecraftItemTypes2["WarpedFungus"] = "minecraft:warped_fungus";
        MinecraftItemTypes2["WarpedFungusOnAStick"] = "minecraft:warped_fungus_on_a_stick";
        MinecraftItemTypes2["WarpedHangingSign"] = "minecraft:warped_hanging_sign";
        MinecraftItemTypes2["WarpedHyphae"] = "minecraft:warped_hyphae";
        MinecraftItemTypes2["WarpedNylium"] = "minecraft:warped_nylium";
        MinecraftItemTypes2["WarpedPlanks"] = "minecraft:warped_planks";
        MinecraftItemTypes2["WarpedPressurePlate"] = "minecraft:warped_pressure_plate";
        MinecraftItemTypes2["WarpedRoots"] = "minecraft:warped_roots";
        MinecraftItemTypes2["WarpedShelf"] = "minecraft:warped_shelf";
        MinecraftItemTypes2["WarpedSign"] = "minecraft:warped_sign";
        MinecraftItemTypes2["WarpedSlab"] = "minecraft:warped_slab";
        MinecraftItemTypes2["WarpedStairs"] = "minecraft:warped_stairs";
        MinecraftItemTypes2["WarpedStem"] = "minecraft:warped_stem";
        MinecraftItemTypes2["WarpedTrapdoor"] = "minecraft:warped_trapdoor";
        MinecraftItemTypes2["WarpedWartBlock"] = "minecraft:warped_wart_block";
        MinecraftItemTypes2["WaterBucket"] = "minecraft:water_bucket";
        MinecraftItemTypes2["Waterlily"] = "minecraft:waterlily";
        MinecraftItemTypes2["WaxedChiseledCopper"] = "minecraft:waxed_chiseled_copper";
        MinecraftItemTypes2["WaxedCopper"] = "minecraft:waxed_copper";
        MinecraftItemTypes2["WaxedCopperBars"] = "minecraft:waxed_copper_bars";
        MinecraftItemTypes2["WaxedCopperBulb"] = "minecraft:waxed_copper_bulb";
        MinecraftItemTypes2["WaxedCopperChain"] = "minecraft:waxed_copper_chain";
        MinecraftItemTypes2["WaxedCopperChest"] = "minecraft:waxed_copper_chest";
        MinecraftItemTypes2["WaxedCopperDoor"] = "minecraft:waxed_copper_door";
        MinecraftItemTypes2["WaxedCopperGolemStatue"] = "minecraft:waxed_copper_golem_statue";
        MinecraftItemTypes2["WaxedCopperGrate"] = "minecraft:waxed_copper_grate";
        MinecraftItemTypes2["WaxedCopperLantern"] = "minecraft:waxed_copper_lantern";
        MinecraftItemTypes2["WaxedCopperTrapdoor"] = "minecraft:waxed_copper_trapdoor";
        MinecraftItemTypes2["WaxedCutCopper"] = "minecraft:waxed_cut_copper";
        MinecraftItemTypes2["WaxedCutCopperSlab"] = "minecraft:waxed_cut_copper_slab";
        MinecraftItemTypes2["WaxedCutCopperStairs"] = "minecraft:waxed_cut_copper_stairs";
        MinecraftItemTypes2["WaxedExposedChiseledCopper"] = "minecraft:waxed_exposed_chiseled_copper";
        MinecraftItemTypes2["WaxedExposedCopper"] = "minecraft:waxed_exposed_copper";
        MinecraftItemTypes2["WaxedExposedCopperBars"] = "minecraft:waxed_exposed_copper_bars";
        MinecraftItemTypes2["WaxedExposedCopperBulb"] = "minecraft:waxed_exposed_copper_bulb";
        MinecraftItemTypes2["WaxedExposedCopperChain"] = "minecraft:waxed_exposed_copper_chain";
        MinecraftItemTypes2["WaxedExposedCopperChest"] = "minecraft:waxed_exposed_copper_chest";
        MinecraftItemTypes2["WaxedExposedCopperDoor"] = "minecraft:waxed_exposed_copper_door";
        MinecraftItemTypes2["WaxedExposedCopperGolemStatue"] = "minecraft:waxed_exposed_copper_golem_statue";
        MinecraftItemTypes2["WaxedExposedCopperGrate"] = "minecraft:waxed_exposed_copper_grate";
        MinecraftItemTypes2["WaxedExposedCopperLantern"] = "minecraft:waxed_exposed_copper_lantern";
        MinecraftItemTypes2["WaxedExposedCopperTrapdoor"] = "minecraft:waxed_exposed_copper_trapdoor";
        MinecraftItemTypes2["WaxedExposedCutCopper"] = "minecraft:waxed_exposed_cut_copper";
        MinecraftItemTypes2["WaxedExposedCutCopperSlab"] = "minecraft:waxed_exposed_cut_copper_slab";
        MinecraftItemTypes2["WaxedExposedCutCopperStairs"] = "minecraft:waxed_exposed_cut_copper_stairs";
        MinecraftItemTypes2["WaxedExposedLightningRod"] = "minecraft:waxed_exposed_lightning_rod";
        MinecraftItemTypes2["WaxedLightningRod"] = "minecraft:waxed_lightning_rod";
        MinecraftItemTypes2["WaxedOxidizedChiseledCopper"] = "minecraft:waxed_oxidized_chiseled_copper";
        MinecraftItemTypes2["WaxedOxidizedCopper"] = "minecraft:waxed_oxidized_copper";
        MinecraftItemTypes2["WaxedOxidizedCopperBars"] = "minecraft:waxed_oxidized_copper_bars";
        MinecraftItemTypes2["WaxedOxidizedCopperBulb"] = "minecraft:waxed_oxidized_copper_bulb";
        MinecraftItemTypes2["WaxedOxidizedCopperChain"] = "minecraft:waxed_oxidized_copper_chain";
        MinecraftItemTypes2["WaxedOxidizedCopperChest"] = "minecraft:waxed_oxidized_copper_chest";
        MinecraftItemTypes2["WaxedOxidizedCopperDoor"] = "minecraft:waxed_oxidized_copper_door";
        MinecraftItemTypes2["WaxedOxidizedCopperGolemStatue"] = "minecraft:waxed_oxidized_copper_golem_statue";
        MinecraftItemTypes2["WaxedOxidizedCopperGrate"] = "minecraft:waxed_oxidized_copper_grate";
        MinecraftItemTypes2["WaxedOxidizedCopperLantern"] = "minecraft:waxed_oxidized_copper_lantern";
        MinecraftItemTypes2["WaxedOxidizedCopperTrapdoor"] = "minecraft:waxed_oxidized_copper_trapdoor";
        MinecraftItemTypes2["WaxedOxidizedCutCopper"] = "minecraft:waxed_oxidized_cut_copper";
        MinecraftItemTypes2["WaxedOxidizedCutCopperSlab"] = "minecraft:waxed_oxidized_cut_copper_slab";
        MinecraftItemTypes2["WaxedOxidizedCutCopperStairs"] = "minecraft:waxed_oxidized_cut_copper_stairs";
        MinecraftItemTypes2["WaxedOxidizedLightningRod"] = "minecraft:waxed_oxidized_lightning_rod";
        MinecraftItemTypes2["WaxedWeatheredChiseledCopper"] = "minecraft:waxed_weathered_chiseled_copper";
        MinecraftItemTypes2["WaxedWeatheredCopper"] = "minecraft:waxed_weathered_copper";
        MinecraftItemTypes2["WaxedWeatheredCopperBars"] = "minecraft:waxed_weathered_copper_bars";
        MinecraftItemTypes2["WaxedWeatheredCopperBulb"] = "minecraft:waxed_weathered_copper_bulb";
        MinecraftItemTypes2["WaxedWeatheredCopperChain"] = "minecraft:waxed_weathered_copper_chain";
        MinecraftItemTypes2["WaxedWeatheredCopperChest"] = "minecraft:waxed_weathered_copper_chest";
        MinecraftItemTypes2["WaxedWeatheredCopperDoor"] = "minecraft:waxed_weathered_copper_door";
        MinecraftItemTypes2["WaxedWeatheredCopperGolemStatue"] = "minecraft:waxed_weathered_copper_golem_statue";
        MinecraftItemTypes2["WaxedWeatheredCopperGrate"] = "minecraft:waxed_weathered_copper_grate";
        MinecraftItemTypes2["WaxedWeatheredCopperLantern"] = "minecraft:waxed_weathered_copper_lantern";
        MinecraftItemTypes2["WaxedWeatheredCopperTrapdoor"] = "minecraft:waxed_weathered_copper_trapdoor";
        MinecraftItemTypes2["WaxedWeatheredCutCopper"] = "minecraft:waxed_weathered_cut_copper";
        MinecraftItemTypes2["WaxedWeatheredCutCopperSlab"] = "minecraft:waxed_weathered_cut_copper_slab";
        MinecraftItemTypes2["WaxedWeatheredCutCopperStairs"] = "minecraft:waxed_weathered_cut_copper_stairs";
        MinecraftItemTypes2["WaxedWeatheredLightningRod"] = "minecraft:waxed_weathered_lightning_rod";
        MinecraftItemTypes2["WayfinderArmorTrimSmithingTemplate"] = "minecraft:wayfinder_armor_trim_smithing_template";
        MinecraftItemTypes2["WeatheredChiseledCopper"] = "minecraft:weathered_chiseled_copper";
        MinecraftItemTypes2["WeatheredCopper"] = "minecraft:weathered_copper";
        MinecraftItemTypes2["WeatheredCopperBars"] = "minecraft:weathered_copper_bars";
        MinecraftItemTypes2["WeatheredCopperBulb"] = "minecraft:weathered_copper_bulb";
        MinecraftItemTypes2["WeatheredCopperChain"] = "minecraft:weathered_copper_chain";
        MinecraftItemTypes2["WeatheredCopperChest"] = "minecraft:weathered_copper_chest";
        MinecraftItemTypes2["WeatheredCopperDoor"] = "minecraft:weathered_copper_door";
        MinecraftItemTypes2["WeatheredCopperGolemStatue"] = "minecraft:weathered_copper_golem_statue";
        MinecraftItemTypes2["WeatheredCopperGrate"] = "minecraft:weathered_copper_grate";
        MinecraftItemTypes2["WeatheredCopperLantern"] = "minecraft:weathered_copper_lantern";
        MinecraftItemTypes2["WeatheredCopperTrapdoor"] = "minecraft:weathered_copper_trapdoor";
        MinecraftItemTypes2["WeatheredCutCopper"] = "minecraft:weathered_cut_copper";
        MinecraftItemTypes2["WeatheredCutCopperSlab"] = "minecraft:weathered_cut_copper_slab";
        MinecraftItemTypes2["WeatheredCutCopperStairs"] = "minecraft:weathered_cut_copper_stairs";
        MinecraftItemTypes2["WeatheredLightningRod"] = "minecraft:weathered_lightning_rod";
        MinecraftItemTypes2["Web"] = "minecraft:web";
        MinecraftItemTypes2["WeepingVines"] = "minecraft:weeping_vines";
        MinecraftItemTypes2["WetSponge"] = "minecraft:wet_sponge";
        MinecraftItemTypes2["Wheat"] = "minecraft:wheat";
        MinecraftItemTypes2["WheatSeeds"] = "minecraft:wheat_seeds";
        MinecraftItemTypes2["WhiteBundle"] = "minecraft:white_bundle";
        MinecraftItemTypes2["WhiteCandle"] = "minecraft:white_candle";
        MinecraftItemTypes2["WhiteCarpet"] = "minecraft:white_carpet";
        MinecraftItemTypes2["WhiteConcrete"] = "minecraft:white_concrete";
        MinecraftItemTypes2["WhiteConcretePowder"] = "minecraft:white_concrete_powder";
        MinecraftItemTypes2["WhiteDye"] = "minecraft:white_dye";
        MinecraftItemTypes2["WhiteGlazedTerracotta"] = "minecraft:white_glazed_terracotta";
        MinecraftItemTypes2["WhiteHarness"] = "minecraft:white_harness";
        MinecraftItemTypes2["WhiteShulkerBox"] = "minecraft:white_shulker_box";
        MinecraftItemTypes2["WhiteStainedGlass"] = "minecraft:white_stained_glass";
        MinecraftItemTypes2["WhiteStainedGlassPane"] = "minecraft:white_stained_glass_pane";
        MinecraftItemTypes2["WhiteTerracotta"] = "minecraft:white_terracotta";
        MinecraftItemTypes2["WhiteTulip"] = "minecraft:white_tulip";
        MinecraftItemTypes2["WhiteWool"] = "minecraft:white_wool";
        MinecraftItemTypes2["WildArmorTrimSmithingTemplate"] = "minecraft:wild_armor_trim_smithing_template";
        MinecraftItemTypes2["Wildflowers"] = "minecraft:wildflowers";
        MinecraftItemTypes2["WindCharge"] = "minecraft:wind_charge";
        MinecraftItemTypes2["WitchSpawnEgg"] = "minecraft:witch_spawn_egg";
        MinecraftItemTypes2["WitherRose"] = "minecraft:wither_rose";
        MinecraftItemTypes2["WitherSkeletonSkull"] = "minecraft:wither_skeleton_skull";
        MinecraftItemTypes2["WitherSkeletonSpawnEgg"] = "minecraft:wither_skeleton_spawn_egg";
        MinecraftItemTypes2["WitherSpawnEgg"] = "minecraft:wither_spawn_egg";
        MinecraftItemTypes2["WolfArmor"] = "minecraft:wolf_armor";
        MinecraftItemTypes2["WolfSpawnEgg"] = "minecraft:wolf_spawn_egg";
        MinecraftItemTypes2["WoodenAxe"] = "minecraft:wooden_axe";
        MinecraftItemTypes2["WoodenButton"] = "minecraft:wooden_button";
        MinecraftItemTypes2["WoodenDoor"] = "minecraft:wooden_door";
        MinecraftItemTypes2["WoodenHoe"] = "minecraft:wooden_hoe";
        MinecraftItemTypes2["WoodenPickaxe"] = "minecraft:wooden_pickaxe";
        MinecraftItemTypes2["WoodenPressurePlate"] = "minecraft:wooden_pressure_plate";
        MinecraftItemTypes2["WoodenShovel"] = "minecraft:wooden_shovel";
        MinecraftItemTypes2["WoodenSpear"] = "minecraft:wooden_spear";
        MinecraftItemTypes2["WoodenSword"] = "minecraft:wooden_sword";
        MinecraftItemTypes2["WritableBook"] = "minecraft:writable_book";
        MinecraftItemTypes2["YellowBundle"] = "minecraft:yellow_bundle";
        MinecraftItemTypes2["YellowCandle"] = "minecraft:yellow_candle";
        MinecraftItemTypes2["YellowCarpet"] = "minecraft:yellow_carpet";
        MinecraftItemTypes2["YellowConcrete"] = "minecraft:yellow_concrete";
        MinecraftItemTypes2["YellowConcretePowder"] = "minecraft:yellow_concrete_powder";
        MinecraftItemTypes2["YellowDye"] = "minecraft:yellow_dye";
        MinecraftItemTypes2["YellowGlazedTerracotta"] = "minecraft:yellow_glazed_terracotta";
        MinecraftItemTypes2["YellowHarness"] = "minecraft:yellow_harness";
        MinecraftItemTypes2["YellowShulkerBox"] = "minecraft:yellow_shulker_box";
        MinecraftItemTypes2["YellowStainedGlass"] = "minecraft:yellow_stained_glass";
        MinecraftItemTypes2["YellowStainedGlassPane"] = "minecraft:yellow_stained_glass_pane";
        MinecraftItemTypes2["YellowTerracotta"] = "minecraft:yellow_terracotta";
        MinecraftItemTypes2["YellowWool"] = "minecraft:yellow_wool";
        MinecraftItemTypes2["ZoglinSpawnEgg"] = "minecraft:zoglin_spawn_egg";
        MinecraftItemTypes2["ZombieHead"] = "minecraft:zombie_head";
        MinecraftItemTypes2["ZombieHorseSpawnEgg"] = "minecraft:zombie_horse_spawn_egg";
        MinecraftItemTypes2["ZombieNautilusSpawnEgg"] = "minecraft:zombie_nautilus_spawn_egg";
        MinecraftItemTypes2["ZombiePigmanSpawnEgg"] = "minecraft:zombie_pigman_spawn_egg";
        MinecraftItemTypes2["ZombieSpawnEgg"] = "minecraft:zombie_spawn_egg";
        MinecraftItemTypes2["ZombieVillagerSpawnEgg"] = "minecraft:zombie_villager_spawn_egg";
        return MinecraftItemTypes2;
    })(MinecraftItemTypes || {});
    var MinecraftPotionDeliveryTypes = (MinecraftPotionDeliveryTypes2 => {
        MinecraftPotionDeliveryTypes2["Consume"] = "Consume";
        MinecraftPotionDeliveryTypes2["ThrownLingering"] = "ThrownLingering";
        MinecraftPotionDeliveryTypes2["ThrownSplash"] = "ThrownSplash";
        return MinecraftPotionDeliveryTypes2;
    })(MinecraftPotionDeliveryTypes || {});
    var MinecraftPotionEffectTypes = (MinecraftPotionEffectTypes2 => {
        MinecraftPotionEffectTypes2["Awkward"] = "minecraft:awkward";
        MinecraftPotionEffectTypes2["FireResistance"] = "minecraft:fire_resistance";
        MinecraftPotionEffectTypes2["Harming"] = "minecraft:harming";
        MinecraftPotionEffectTypes2["Healing"] = "minecraft:healing";
        MinecraftPotionEffectTypes2["Infested"] = "minecraft:infested";
        MinecraftPotionEffectTypes2["Invisibility"] = "minecraft:invisibility";
        MinecraftPotionEffectTypes2["Leaping"] = "minecraft:leaping";
        MinecraftPotionEffectTypes2["LongFireResistance"] = "minecraft:long_fire_resistance";
        MinecraftPotionEffectTypes2["LongInvisibility"] = "minecraft:long_invisibility";
        MinecraftPotionEffectTypes2["LongLeaping"] = "minecraft:long_leaping";
        MinecraftPotionEffectTypes2["LongMundane"] = "minecraft:long_mundane";
        MinecraftPotionEffectTypes2["LongNightvision"] = "minecraft:long_nightvision";
        MinecraftPotionEffectTypes2["LongPoison"] = "minecraft:long_poison";
        MinecraftPotionEffectTypes2["LongRegeneration"] = "minecraft:long_regeneration";
        MinecraftPotionEffectTypes2["LongSlowFalling"] = "minecraft:long_slow_falling";
        MinecraftPotionEffectTypes2["LongSlowness"] = "minecraft:long_slowness";
        MinecraftPotionEffectTypes2["LongStrength"] = "minecraft:long_strength";
        MinecraftPotionEffectTypes2["LongSwiftness"] = "minecraft:long_swiftness";
        MinecraftPotionEffectTypes2["LongTurtleMaster"] = "minecraft:long_turtle_master";
        MinecraftPotionEffectTypes2["LongWaterBreathing"] = "minecraft:long_water_breathing";
        MinecraftPotionEffectTypes2["LongWeakness"] = "minecraft:long_weakness";
        MinecraftPotionEffectTypes2["Mundane"] = "minecraft:mundane";
        MinecraftPotionEffectTypes2["Nightvision"] = "minecraft:nightvision";
        MinecraftPotionEffectTypes2["Oozing"] = "minecraft:oozing";
        MinecraftPotionEffectTypes2["Poison"] = "minecraft:poison";
        MinecraftPotionEffectTypes2["Regeneration"] = "minecraft:regeneration";
        MinecraftPotionEffectTypes2["SlowFalling"] = "minecraft:slow_falling";
        MinecraftPotionEffectTypes2["Slowness"] = "minecraft:slowness";
        MinecraftPotionEffectTypes2["Strength"] = "minecraft:strength";
        MinecraftPotionEffectTypes2["StrongHarming"] = "minecraft:strong_harming";
        MinecraftPotionEffectTypes2["StrongHealing"] = "minecraft:strong_healing";
        MinecraftPotionEffectTypes2["StrongLeaping"] = "minecraft:strong_leaping";
        MinecraftPotionEffectTypes2["StrongPoison"] = "minecraft:strong_poison";
        MinecraftPotionEffectTypes2["StrongRegeneration"] = "minecraft:strong_regeneration";
        MinecraftPotionEffectTypes2["StrongSlowness"] = "minecraft:strong_slowness";
        MinecraftPotionEffectTypes2["StrongStrength"] = "minecraft:strong_strength";
        MinecraftPotionEffectTypes2["StrongSwiftness"] = "minecraft:strong_swiftness";
        MinecraftPotionEffectTypes2["StrongTurtleMaster"] = "minecraft:strong_turtle_master";
        MinecraftPotionEffectTypes2["Swiftness"] = "minecraft:swiftness";
        MinecraftPotionEffectTypes2["Thick"] = "minecraft:thick";
        MinecraftPotionEffectTypes2["TurtleMaster"] = "minecraft:turtle_master";
        MinecraftPotionEffectTypes2["Water"] = "minecraft:water";
        MinecraftPotionEffectTypes2["WaterBreathing"] = "minecraft:water_breathing";
        MinecraftPotionEffectTypes2["Weakness"] = "minecraft:weakness";
        MinecraftPotionEffectTypes2["Weaving"] = "minecraft:weaving";
        MinecraftPotionEffectTypes2["WindCharged"] = "minecraft:wind_charged";
        MinecraftPotionEffectTypes2["Wither"] = "minecraft:wither";
        return MinecraftPotionEffectTypes2;
    })(MinecraftPotionEffectTypes || {});
    function guid() {
        const s4 = () => Math.floor((1 + Math.random()) * 65536).toString(16).substring(1);
        return s4() + s4() + "-" + s4() + "-" + s4() + "-" + s4() + "-" + s4() + s4() + s4();
    }
    const EDITOR_PREFIX = "editor::";
    function UniqueIdUtils_createUniqueEditorString(name) {
        if (name.startsWith(EDITOR_PREFIX)) {
            return name;
        }
        return EDITOR_PREFIX + name + "::" + guid();
    }
    var lib = __webpack_require__(607);
    function _calcDiagonalMaxVolume(newSize, maxBlockVolume) {
        const dirVector = lib.Vector3Utils.normalize(newSize);
        const magnitude = Math.cbrt(maxBlockVolume / (dirVector.x * dirVector.y * dirVector.z));
        return {
            x: magnitude * dirVector.x,
            y: magnitude * dirVector.y,
            z: magnitude * dirVector.z
        };
    }
    function _clampVolumeAlongDiagonal(newSize, maxBlockVolume) {
        const maxVolume = _calcDiagonalMaxVolume(newSize, maxBlockVolume);
        return {
            x: Math.floor(Math.max(1, Math.min(newSize.x, maxVolume.x))),
            y: Math.floor(Math.max(1, Math.min(newSize.y, maxVolume.y))),
            z: Math.floor(Math.max(1, Math.min(newSize.z, maxVolume.z)))
        };
    }
    function clampVolumeAlongAxis(oldSize, newSize, maxBlockVolume) {
        const xChanged = oldSize.x !== newSize.x;
        const yChanged = oldSize.y !== newSize.y;
        const zChanged = oldSize.z !== newSize.z;
        if (!xChanged && !yChanged && !zChanged) {
            return oldSize;
        }
        if (xChanged && !yChanged && !zChanged) {
            return {
                x: Math.floor(Math.max(1, Math.min(newSize.x, maxBlockVolume / (newSize.y * newSize.z)))),
                y: newSize.y,
                z: newSize.z
            };
        }
        if (yChanged && !xChanged && !zChanged) {
            return {
                x: newSize.x,
                y: Math.floor(Math.max(1, Math.min(newSize.y, maxBlockVolume / (newSize.x * newSize.z)))),
                z: newSize.z
            };
        }
        if (zChanged && !xChanged && !yChanged) {
            return {
                x: newSize.x,
                y: newSize.y,
                z: Math.floor(Math.max(1, Math.min(newSize.z, maxBlockVolume / (newSize.x * newSize.y))))
            };
        }
        return _clampVolumeAlongDiagonal(newSize, maxBlockVolume);
    }
    function isWithinLimits(newSize, maxBlockVolume) {
        const maxPosition = _calcDiagonalMaxVolume(newSize, maxBlockVolume);
        return lib.Vector3Utils.magnitude(newSize) <= lib.Vector3Utils.magnitude(maxPosition);
    }
    var server_editor_private_bindings_x = y => {
        var x = {};
        __webpack_require__.d(x, y);
        return x;
    };
    var server_editor_private_bindings_y = x => () => x;
    const server_editor_private_bindings_namespaceObject = server_editor_private_bindings_x({
        ["EditorRealmsServiceAvailability"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_private_bindings_ae1d7ddf__.EditorRealmsServiceAvailability,
        ["JigsawJointType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_private_bindings_ae1d7ddf__.JigsawJointType,
        ["JigsawJsonType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_private_bindings_ae1d7ddf__.JigsawJsonType,
        ["PersistenceGroupType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_private_bindings_ae1d7ddf__.PersistenceGroupType,
        ["PersistenceScope"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_private_bindings_ae1d7ddf__.PersistenceScope,
        ["PrefabInstanceInteractionEventType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_private_bindings_ae1d7ddf__.PrefabInstanceInteractionEventType,
        ["ProjectRegionAvailabilityMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_private_bindings_ae1d7ddf__.ProjectRegionAvailabilityMode,
        ["RealmsWorldUploadResult"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_private_bindings_ae1d7ddf__.RealmsWorldUploadResult,
        ["editorInternal"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_private_bindings_ae1d7ddf__.editorInternal
    });
    function stringFromException(e) {
        if (typeof e === "string") {
            return e;
        } else if (typeof e === "object" && e !== null && "message" in e) {
            return e.message;
        }
        return "Unknown exception";
    }
    async function executeTickSafeOperation(context, logger, bounds, operation) {
        await RegionOperationHelper_executeTickSafeAsyncOperation(context, logger, bounds, operation);
    }
    async function RegionOperationHelper_executeTickSafeAsyncOperation(context, logger, bounds, operation) {
        if (!server_namespaceObject.BlockBoundingBoxUtils.isValid(bounds)) {
            throw new Error(`Invalid operation region bounds: ${JSON.stringify(bounds)}`);
        }
        let region = undefined;
        try {
            const regionManager = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(context.player).regionManager;
            region = regionManager.leaseRegion({
                extentX: {
                    min: bounds.min.x,
                    max: bounds.max.x
                },
                extentZ: {
                    min: bounds.min.z,
                    max: bounds.max.z
                },
                availabilityMode: server_editor_private_bindings_namespaceObject.ProjectRegionAvailabilityMode.Ticking
            });
            await region.waitUntilAvailable();
            const result = operation();
            if (result instanceof Promise) {
                await result;
            }
        } catch (e) {
            logger.error(`Failed to execute operation: ${stringFromException(e)}`);
        } finally {
            if (region) {
                region.dispose();
            }
        }
    }
    async function executeLargeOperationWithTransactionAndTicking(context, logger, transactionString, operation) {
        transactionString = createUniqueEditorString(transactionString);
        const selectionVolume = context.selectionManager.volume.get();
        const bounds = selectionVolume.getBoundingBox();
        if (!context.transactionManager.openTransaction(transactionString)) {
            throw Error("Failed to open transaction");
        }
        try {
            context.transactionManager.trackBlockChangeArea(bounds.min, bounds.max);
        } catch (e) {
            context.transactionManager.discardOpenTransaction();
            throw e;
        }
        await executeTickSafeAsyncOperation(context, logger, bounds, (async () => {
            await executeLargeOperation(selectionVolume, operation);
        })).catch((e => {
            context.transactionManager.discardOpenTransaction();
            throw e;
        })).then((() => {
            if (!context.transactionManager.commitOpenTransaction()) {
                throw Error("Failed to commit transaction");
            }
        }));
    }
    async function executeLargeOperationFromIteratorWithTransactionAndTicking(context, logger, bounds, blockLocationIterator, transactionString, operation) {
        transactionString = UniqueIdUtils_createUniqueEditorString(transactionString);
        if (!context.transactionManager.openTransaction(transactionString)) {
            throw Error("Failed to open transaction");
        }
        try {
            context.transactionManager.trackBlockChangeArea(bounds.min, bounds.max);
        } catch (e) {
            context.transactionManager.discardOpenTransaction();
            throw Error((0, server_editor_namespaceObject.stringFromException)(e));
        }
        await RegionOperationHelper_executeTickSafeAsyncOperation(context, logger, bounds, (async () => {
            await (0, server_editor_namespaceObject.executeLargeOperationFromIterator)(blockLocationIterator, operation).catch((e => {
                context.transactionManager.discardOpenTransaction();
                throw e;
            })).then((() => {
                if (!context.transactionManager.commitOpenTransaction()) {
                    throw Error("Failed to commit transaction");
                }
            }));
        }));
    }
    async function executeFunctionWithTransactionAndTicking(context, logger, volume, transactionString, operation) {
        transactionString = UniqueIdUtils_createUniqueEditorString(transactionString);
        let bounds;
        if (volume instanceof server_editor_namespaceObject.RelativeVolumeListBlockVolume) {
            bounds = volume.getBoundingBox();
        } else if (volume instanceof server_namespaceObject.BlockVolumeBase) {
            bounds = volume.getBoundingBox();
        } else {
            throw new Error("Invalid volume type");
        }
        if (!context.transactionManager.openTransaction(transactionString)) {
            throw Error("Failed to open transaction");
        }
        try {
            context.transactionManager.trackBlockChangeArea(bounds.min, bounds.max);
        } catch (e) {
            context.transactionManager.discardOpenTransaction();
            throw e;
        }
        await executeTickSafeOperation(context, logger, bounds, operation).catch((e => {
            context.transactionManager.discardOpenTransaction();
            throw e;
        })).then((() => {
            if (!context.transactionManager.commitOpenTransaction()) {
                throw Error("Failed to commit transaction");
            }
        }));
    }
    var direction_Direction;
    (function(Direction) {
        Direction[Direction["Forward"] = 0] = "Forward";
        Direction[Direction["Right"] = 1] = "Right";
        Direction[Direction["Back"] = 2] = "Back";
        Direction[Direction["Left"] = 3] = "Left";
        Direction[Direction["Up"] = 4] = "Up";
        Direction[Direction["Down"] = 5] = "Down";
    })(direction_Direction || (direction_Direction = {}));
    const directionLookup = {
        [direction_Direction.Forward]: lib.VECTOR3_FORWARD,
        [direction_Direction.Right]: lib.VECTOR3_LEFT,
        [direction_Direction.Back]: lib.VECTOR3_BACK,
        [direction_Direction.Left]: lib.VECTOR3_RIGHT,
        [direction_Direction.Up]: lib.VECTOR3_UP,
        [direction_Direction.Down]: lib.VECTOR3_DOWN
    };
    function direction_getRotationCorrectedDirection(rotationY, realDirection) {
        if (realDirection === direction_Direction.Up || realDirection === direction_Direction.Down) {
            return realDirection;
        }
        const directionQuadrant = Math.floor((rotationY + 405 + realDirection * 90) % 360 / 90);
        return directionQuadrant;
    }
    function getRotationCorrectedDirectionVector(rotationY, realDirection) {
        const relativeDirection = direction_getRotationCorrectedDirection(rotationY, realDirection);
        return directionLookup[relativeDirection];
    }
    function getDirectionVector(direction) {
        return directionLookup[direction];
    }
    function getScaledDirectionVector(direction, scaleValue) {
        const vec = Vector3Utils.scale(getDirectionVector(direction), scaleValue);
        return vec;
    }
    function shrinkVolumeAlongAbsoluteAxis(volume, direction, amount, worldBounds) {
        const bounds = volume.getBoundingBox();
        const size = server_namespaceObject.BlockBoundingBoxUtils.getSpan(bounds);
        const min = bounds.min;
        const max = bounds.max;
        switch (direction) {
          case direction_Direction.Up:
            {
                const span = size.y;
                if (span > 1) {
                    const clampAmount = Math.min(amount, span - 1);
                    const limit = worldBounds?.max.y ?? Infinity;
                    max.y = Math.min(max.y - clampAmount, limit);
                }
                break;
            }

          case direction_Direction.Down:
            {
                const span = size.y;
                if (span > 1) {
                    const clampAmount = Math.min(amount, span - 1);
                    const limit = worldBounds?.min.y ?? -Infinity;
                    min.y = Math.max(min.y + clampAmount, limit);
                }
                break;
            }

          case direction_Direction.Forward:
            {
                const span = size.z;
                if (span > 1) {
                    const clampAmount = Math.min(amount, span - 1);
                    const limit = worldBounds?.max.z ?? Infinity;
                    max.z = Math.min(max.z - clampAmount, limit);
                }
                break;
            }

          case direction_Direction.Back:
            {
                const span = size.z;
                if (span > 1) {
                    const clampAmount = Math.min(amount, span - 1);
                    const limit = worldBounds?.min.z ?? -Infinity;
                    min.z = Math.max(min.z + clampAmount, limit);
                }
                break;
            }

          case direction_Direction.Left:
            {
                const span = size.x;
                if (span > 1) {
                    const clampAmount = Math.min(amount, span - 1);
                    const limit = worldBounds?.max.x ?? Infinity;
                    max.x = Math.min(max.x - clampAmount, limit);
                }
                break;
            }

          case direction_Direction.Right:
            {
                const span = size.x;
                if (span > 1) {
                    const clampAmount = Math.min(amount, span - 1);
                    const limit = worldBounds?.min.x ?? -Infinity;
                    min.x = Math.max(min.x + clampAmount, limit);
                }
                break;
            }
        }
        return new server_namespaceObject.BlockVolume(min, max);
    }
    function shrinkVolumeAlongViewAxis(volume, rotationY, direction, amount, worldBounds) {
        const relativeDirection = direction_getRotationCorrectedDirection(rotationY, direction);
        return shrinkVolumeAlongAbsoluteAxis(volume, relativeDirection, amount, worldBounds);
    }
    function growVolumeAlongAbsoluteAxis(volume, direction, amount, worldBounds) {
        const bounds = volume.getBoundingBox();
        const size = server_namespaceObject.BlockBoundingBoxUtils.getSpan(bounds);
        const min = bounds.min;
        const max = bounds.max;
        const maxSize = server_editor_namespaceObject.editor.constants.maxSelectionSize;
        switch (direction) {
          case direction_Direction.Up:
            {
                const span = size.y;
                const maxAllowed = maxSize.y - span;
                const boundLimit = (worldBounds?.max.y ?? Infinity) - max.y;
                max.y += Math.min(amount, maxAllowed, boundLimit);
                break;
            }

          case direction_Direction.Down:
            {
                const span = size.y;
                const maxAllowed = maxSize.y - span;
                const boundLimit = min.y - (worldBounds?.min.y ?? -Infinity);
                min.y -= Math.min(amount, maxAllowed, boundLimit);
                break;
            }

          case direction_Direction.Forward:
            {
                const span = size.z;
                const maxAllowed = maxSize.z - span;
                const boundLimit = (worldBounds?.max.z ?? Infinity) - max.z;
                max.z += Math.min(amount, maxAllowed, boundLimit);
                break;
            }

          case direction_Direction.Back:
            {
                const span = size.z;
                const maxAllowed = maxSize.z - span;
                const boundLimit = min.z - (worldBounds?.min.z ?? -Infinity);
                min.z -= Math.min(amount, maxAllowed, boundLimit);
                break;
            }

          case direction_Direction.Left:
            {
                const span = size.x;
                const maxAllowed = maxSize.x - span;
                const boundLimit = (worldBounds?.max.x ?? Infinity) - max.x;
                max.x += Math.min(amount, maxAllowed, boundLimit);
                break;
            }

          case direction_Direction.Right:
            {
                const span = size.x;
                const maxAllowed = maxSize.x - span;
                const boundLimit = min.x - (worldBounds?.min.x ?? -Infinity);
                min.x -= Math.min(amount, maxAllowed, boundLimit);
                break;
            }
        }
        return new server_namespaceObject.BlockVolume(min, max);
    }
    function growVolumeAlongViewAxis(volume, rotationY, direction, amount, worldBounds) {
        const relativeDirection = direction_getRotationCorrectedDirection(rotationY, direction);
        return growVolumeAlongAbsoluteAxis(volume, relativeDirection, amount, worldBounds);
    }
    var AxisPlanes;
    (function(AxisPlanes) {
        AxisPlanes[AxisPlanes["XZ"] = 0] = "XZ";
        AxisPlanes[AxisPlanes["XY"] = 1] = "XY";
        AxisPlanes[AxisPlanes["YZ"] = 2] = "YZ";
    })(AxisPlanes || (AxisPlanes = {}));
    const axisNormalLookup = {
        [AxisPlanes.XZ]: lib.VECTOR3_UP,
        [AxisPlanes.XY]: lib.VECTOR3_FORWARD,
        [AxisPlanes.YZ]: lib.VECTOR3_LEFT
    };
    function getAxisNormal(axis) {
        return axisNormalLookup[axis];
    }
    function getRelativeXYAxisAsNormal(rotation) {
        const direction = getRotationCorrectedDirection(rotation, Direction.Forward);
        switch (direction) {
          case Direction.Forward:
          case Direction.Back:
            return axisNormalLookup[AxisPlanes.XY];

          case Direction.Right:
          case Direction.Left:
            return axisNormalLookup[AxisPlanes.YZ];

          default:
            throw new Error("Invalid quadrant");
        }
    }
    function intersectRayPlane(rayLocation, rayDirection, planeNormal, planeDistance) {
        const denominator = Vector3Utils.dot(rayDirection, planeNormal);
        if (denominator !== 0) {
            const t = -(Vector3Utils.dot(rayLocation, planeNormal) + planeDistance) / denominator;
            if (t < 0) {
                return undefined;
            }
            const scaledDirection = Vector3Utils.scale(rayDirection, t);
            const result = Vector3Utils.add(rayLocation, scaledDirection);
            return result;
        } else if (Vector3Utils.dot(planeNormal, rayLocation) + planeDistance === 0) {
            return rayLocation;
        }
        return undefined;
    }
    function calculateClosestPointOnSecondLine(origin1, ray1, origin2, ray2) {
        const originDiff = lib.Vector3Utils.subtract(origin2, origin1);
        const a = lib.Vector3Utils.dot(ray1, originDiff);
        const c = -lib.Vector3Utils.dot(ray2, originDiff);
        const b = lib.Vector3Utils.dot(ray1, ray2);
        const denom = 1 - b * b;
        if (nearEqual(denom, 0)) {
            return undefined;
        }
        const t2 = (c + a * b) / denom;
        const rayProjection = lib.Vector3Utils.scale(ray2, t2);
        return lib.Vector3Utils.add(origin2, rayProjection);
    }
    function nearEqual(a, b) {
        return Math.abs(a - b) < .001;
    }
    function calculateYPlaneIntersection(pointOnPlane, rayOrigin, rayDirection) {
        const normal = lib.VECTOR3_UP;
        const dotProduct = lib.Vector3Utils.dot(rayDirection, normal);
        if (nearEqual(dotProduct, 0)) {
            return undefined;
        }
        const popMinusRayO = lib.Vector3Utils.subtract(pointOnPlane, rayOrigin);
        const t = lib.Vector3Utils.dot(popMinusRayO, normal) / dotProduct;
        const rayProjection = lib.Vector3Utils.scale(rayDirection, t);
        const rawIntersection = lib.Vector3Utils.add(rayOrigin, rayProjection);
        return lib.Vector3Utils.floor(rawIntersection);
    }
    class Vector3Map {
        constructor(initialItems) {
            this._vector3Map = new Map;
            if (initialItems !== undefined) {
                for (let i = 0; i < initialItems.length; i++) {
                    this._vector3Map.set(`${initialItems[i].x},${initialItems[i].y},${initialItems[i].z}`, initialItems[i]);
                }
            }
        }
        add(newVec) {
            const key = `${newVec.x},${newVec.y},${newVec.z}`;
            if (!this._vector3Map.has(key)) {
                this._vector3Map.set(key, newVec);
            }
        }
        has(vec) {
            return this._vector3Map.has(`${vec.x},${vec.y},${vec.z}`);
        }
        remove(vec) {
            this._vector3Map.delete(`${vec.x},${vec.y},${vec.z}`);
        }
        get length() {
            return this._vector3Map.size;
        }
        get keys() {
            return this._vector3Map.keys();
        }
        get values() {
            return this._vector3Map.values();
        }
        get entries() {
            return this._vector3Map.entries();
        }
    }
    var BlockPointType;
    (function(BlockPointType) {
        BlockPointType[BlockPointType["Normal"] = 0] = "Normal";
        BlockPointType[BlockPointType["Contour"] = 1] = "Contour";
    })(BlockPointType || (BlockPointType = {}));
    class BlockPoint {
        constructor(location, requestCursorTargetMode, requestGroundLevelAtLocation, blockPointOptions) {
            this._location = location;
            this._requestCursorTargetMode = requestCursorTargetMode;
            this._requestGroundLevelAtLocation = requestGroundLevelAtLocation;
            this._horizontalWeight = blockPointOptions?.horizontalWeight ?? 1;
            this._verticalWeight = blockPointOptions?.verticalWeight ?? 1;
            this._blockPointType = blockPointOptions?.blockPointType ?? BlockPointType.Normal;
            this._plot = {
                x: this._location.x,
                y: this._location.y,
                z: this._location.z
            };
            this._pointData = new Vector3Map;
            this.generatePoint();
        }
        get location() {
            return this._location;
        }
        get horizontalWeight() {
            return this._horizontalWeight;
        }
        get verticalWeight() {
            return this._verticalWeight;
        }
        get blockPointType() {
            return this._blockPointType;
        }
        get lineDataIterator() {
            return this._pointData.values;
        }
        movePoint(targetLocation) {
            if (!lib.Vector3Utils.equals(this._location, targetLocation)) {
                this._location = targetLocation;
                return this.generatePoint();
            }
            return {
                pointsAdded: [],
                pointsRemoved: []
            };
        }
        setWeights(newHorizontalWeight, newVerticalWeight) {
            let changed = false;
            if (newHorizontalWeight !== this._horizontalWeight) {
                this._horizontalWeight = newHorizontalWeight;
                changed = true;
            }
            if (newVerticalWeight !== this._verticalWeight) {
                this._verticalWeight = newVerticalWeight;
                changed = true;
            }
            if (changed) {
                return this.generatePoint();
            }
            return {
                pointsAdded: [],
                pointsRemoved: []
            };
        }
        setBlockPointType(newBlockPointType) {
            if (newBlockPointType !== this._blockPointType) {
                this._blockPointType = newBlockPointType;
                return this.generatePoint();
            }
            return {
                pointsAdded: [],
                pointsRemoved: []
            };
        }
        generatePoint() {
            this.updatePlot();
            return this.applyThickness();
        }
        updatePlot() {
            switch (this._blockPointType) {
              case BlockPointType.Normal:
                {
                    this._plot = {
                        x: this._location.x,
                        y: this._location.y,
                        z: this._location.z
                    };
                    break;
                }

              case BlockPointType.Contour:
                {
                    this.applySurfaceContour();
                    break;
                }

              default:
                break;
            }
        }
        applySurfaceContour() {
            const targetMode = this._requestCursorTargetMode();
            const offset = targetMode === server_editor_namespaceObject.CursorTargetMode.Block ? 0 : 1;
            const elevation = this._requestGroundLevelAtLocation(this._location);
            if (elevation !== Infinity) {
                this._plot = {
                    x: this._location.x,
                    y: elevation + offset,
                    z: this._location.z
                };
            }
        }
        applyThickness() {
            return this.updateData([ this._plot ]);
        }
        applyVerticalThickness() {
            const newPoints = new Vector3Map([ this._plot ]);
            if (this._blockPointType === BlockPointType.Contour) {
                for (let i = 1; i < this._verticalWeight; i++) {
                    const newPt = {
                        x: this._plot.x,
                        y: this._plot.y + i,
                        z: this._plot.z
                    };
                    if (!newPoints.has(newPt)) {
                        newPoints.add(newPt);
                    }
                }
            } else {
                for (let i = 2; i <= this._verticalWeight; i++) {
                    const offset = i % 2 === 0 ? i / 2 : -(i - 1) / 2;
                    const newPt = {
                        x: this._plot.x,
                        y: this._plot.y + offset,
                        z: this._plot.z
                    };
                    if (!newPoints.has(newPt)) {
                        newPoints.add(newPt);
                    }
                }
            }
            return newPoints;
        }
        applyHorizontalThicknessToVerticalResults(verticalResults) {
            const newXPoints = new Vector3Map;
            const newZPoints = new Vector3Map;
            for (const pt of verticalResults.values) {
                let newPt = pt;
                let off;
                if (!newXPoints.has(pt)) {
                    newXPoints.add(pt);
                }
                for (let i = 2; i <= this._horizontalWeight; i++) {
                    off = i % 2 === 0 ? i / 2 : -(i - 1) / 2;
                    newPt = {
                        x: pt.x + off,
                        y: pt.y,
                        z: pt.z
                    };
                    if (!newXPoints.has(newPt) && !verticalResults.has(newPt)) {
                        newXPoints.add(newPt);
                    }
                }
            }
            for (const pt of newXPoints.values) {
                let newPt;
                let off;
                for (let i = 2; i <= this._horizontalWeight; i++) {
                    off = i % 2 === 0 ? i / 2 : -(i - 1) / 2;
                    newPt = {
                        x: pt.x,
                        y: pt.y,
                        z: pt.z + off
                    };
                    if (!newXPoints.has(newPt) && !newZPoints.has(newPt) && !verticalResults.has(newPt)) {
                        newZPoints.add(newPt);
                    }
                }
            }
            return [ ...newXPoints.values, ...newZPoints.values ];
        }
        updateData(newData) {
            const toAdd = [];
            const toRemove = [];
            const newKeys = new Set;
            for (let i = 0; i < newData.length; i++) {
                if (!this._pointData.has(newData[i])) {
                    toAdd.push(newData[i]);
                }
                newKeys.add(`${newData[i].x},${newData[i].y},${newData[i].z}`);
            }
            for (const [dataKey, dataPoint] of this._pointData.entries) {
                if (!newKeys.has(dataKey)) {
                    toRemove.push(dataPoint);
                }
            }
            for (let i = 0; i < toRemove.length; i++) {
                this._pointData.remove(toRemove[i]);
            }
            for (let i = 0; i < toAdd.length; i++) {
                this._pointData.add(toAdd[i]);
            }
            return {
                pointsAdded: toAdd,
                pointsRemoved: toRemove
            };
        }
    }
    var BlockLineType;
    (function(BlockLineType) {
        BlockLineType[BlockLineType["Direct"] = 0] = "Direct";
        BlockLineType[BlockLineType["Staggered"] = 1] = "Staggered";
    })(BlockLineType || (BlockLineType = {}));
    class BlockCurve {
        constructor(start, end, requestCursorTargetMode, requestGroundLevelAtLocation, blockCurveCreationOptions) {
            this._start = start;
            this._end = end;
            this._startData = blockCurveCreationOptions?.startData;
            this._endData = blockCurveCreationOptions?.endData;
            this._requestCursorTargetMode = requestCursorTargetMode;
            this._requestGroundLevelAtLocation = requestGroundLevelAtLocation;
            this._horizontalWeight = blockCurveCreationOptions?.horizontalWeight ?? 1;
            this._verticalWeight = blockCurveCreationOptions?.verticalWeight ?? 1;
            this._contour = blockCurveCreationOptions?.contour ?? false;
            this._curvePlot = [];
            this._contourPlot = [];
            this._curveData = new Vector3Map;
            void this.generateCurve();
        }
        get start() {
            return this._start;
        }
        get end() {
            return this._end;
        }
        get horizontalWeight() {
            return this._horizontalWeight;
        }
        get verticalWeight() {
            return this._verticalWeight;
        }
        get curveDataIterator() {
            return this._curveData.values;
        }
        get curvePlot() {
            return this._curvePlot;
        }
        updateCurvePlot(points) {
            this._curvePlot = points;
            return Promise.resolve(this.generateCurve());
        }
        async setStart(newStart, startData = undefined) {
            if (!lib.Vector3Utils.equals(this._start, newStart) || this._startData !== startData) {
                this._start = newStart;
                this._startData = startData;
                return this.generateCurve();
            }
            return {
                pointsAdded: [],
                pointsRemoved: []
            };
        }
        async setEnd(newEnd, endData = undefined) {
            if (!lib.Vector3Utils.equals(this._end, newEnd) || this._endData !== endData) {
                this._end = newEnd;
                this._endData = endData;
                return this.generateCurve();
            }
            return {
                pointsAdded: [],
                pointsRemoved: []
            };
        }
        async translatePoints(translationVector) {
            let changed = false;
            const newStart = lib.Vector3Utils.add(this._start, translationVector);
            const newEnd = lib.Vector3Utils.add(this._end, translationVector);
            if (!lib.Vector3Utils.equals(this._start, newStart)) {
                this._start = newStart;
                changed = true;
            }
            if (!lib.Vector3Utils.equals(this._end, newEnd)) {
                this._end = newEnd;
                changed = true;
            }
            if (changed) {
                return this.generateCurve();
            }
            return {
                pointsAdded: [],
                pointsRemoved: []
            };
        }
        async setWeights(newHorizontalWeight, newVerticalWeight) {
            let changed = false;
            if (newHorizontalWeight !== this._horizontalWeight) {
                this._horizontalWeight = newHorizontalWeight;
                changed = true;
            }
            if (newVerticalWeight !== this._verticalWeight) {
                this._verticalWeight = newVerticalWeight;
                changed = true;
            }
            if (changed) {
                return this.generateCurve();
            }
            return {
                pointsAdded: [],
                pointsRemoved: []
            };
        }
        async generateCurve() {
            this.updatePlot();
            return await this.applyThickness();
        }
        updatePlot() {
            if (this._contour) {
                this.applySurfaceContour();
            }
        }
        async setOptions(newOptions) {
            if (newOptions.curveOptions?.contour !== this._contour) {
                this._contour = newOptions.curveOptions?.contour ?? false;
                return this.generateCurve();
            }
            return {
                pointsAdded: [],
                pointsRemoved: []
            };
        }
        applySurfaceContour() {
            const contourResults = [];
            const visited = new Set;
            const targetMode = this._requestCursorTargetMode();
            const offset = targetMode === server_editor_namespaceObject.CursorTargetMode.Block ? 0 : 1;
            for (let i = 0; i < this._curvePlot.length; i++) {
                const key = `${this._curvePlot[i].x},${this._curvePlot[i].z}`;
                if (!visited.has(key)) {
                    const elevation = this._requestGroundLevelAtLocation(this._curvePlot[i]);
                    if (elevation !== Infinity) {
                        contourResults.push({
                            x: this._curvePlot[i].x,
                            y: elevation + offset,
                            z: this._curvePlot[i].z
                        });
                        visited.add(key);
                    }
                }
            }
            this._contourPlot.length = 0;
            this._contourPlot.push(...contourResults);
        }
        updateData(newData) {
            const toAdd = [];
            const toRemove = [];
            const newKeys = new Set;
            for (let i = 0; i < newData.length; i++) {
                if (!this._curveData.has(newData[i])) {
                    toAdd.push(newData[i]);
                }
                newKeys.add(`${newData[i].x},${newData[i].y},${newData[i].z}`);
            }
            for (const [dataKey, dataPoint] of this._curveData.entries) {
                if (!newKeys.has(dataKey)) {
                    toRemove.push(dataPoint);
                }
            }
            for (let i = 0; i < toRemove.length; i++) {
                this._curveData.remove(toRemove[i]);
            }
            for (let i = 0; i < toAdd.length; i++) {
                this._curveData.add(toAdd[i]);
            }
            return {
                pointsAdded: toAdd,
                pointsRemoved: toRemove
            };
        }
        getMidPoint() {
            return this._curvePlot.at(this._curvePlot.length / 2);
        }
        async applyThickness() {
            if (this._horizontalWeight === 1 && this._verticalWeight === 1 && !this._startData && !this._endData) {
                let plot = this._curvePlot;
                if (this._contour) {
                    plot = this._contourPlot;
                }
                return this.updateData(plot);
            }
            const [verticalResults, horizontalWeightMap] = await this.applyVerticalThickness();
            const horizontalAndVerticalResults = await this.applyHorizontalThicknessToVerticalResults(verticalResults, horizontalWeightMap);
            return this.updateData(horizontalAndVerticalResults);
        }
        async applyVerticalThickness() {
            let plot = this._curvePlot;
            if (this._contour) {
                plot = this._contourPlot;
            }
            const newPoints = new Vector3Map(plot);
            const pointHorizontalWeightMap = new Map;
            const contourOperation = (index, blockPos) => {
                const [verticalWeight, horizontalWeight] = this.getWeightFromPointInLengthLinear(index);
                if (!pointHorizontalWeightMap.has(blockPos)) {
                    pointHorizontalWeightMap.set(blockPos, horizontalWeight);
                }
                for (let j = 1; j < verticalWeight; j++) {
                    const newPt = {
                        x: blockPos.x,
                        y: blockPos.y + j,
                        z: blockPos.z
                    };
                    if (!newPoints.has(newPt)) {
                        newPoints.add(newPt);
                    }
                    if (!pointHorizontalWeightMap.has(newPt)) {
                        pointHorizontalWeightMap.set(newPt, horizontalWeight);
                    }
                }
            };
            const nonContourOperation = (index, blockPos) => {
                const [verticalWeight, horizontalWeight] = this.getWeightFromPointInLengthLinear(index);
                if (!pointHorizontalWeightMap.has(blockPos)) {
                    pointHorizontalWeightMap.set(blockPos, horizontalWeight);
                }
                for (let j = 2; j <= verticalWeight; j++) {
                    const offset = j % 2 === 0 ? j / 2 : -(j - 1) / 2;
                    const newPt = {
                        x: blockPos.x,
                        y: blockPos.y + offset,
                        z: blockPos.z
                    };
                    if (!newPoints.has(newPt)) {
                        newPoints.add(newPt);
                    }
                    if (!pointHorizontalWeightMap.has(newPt)) {
                        pointHorizontalWeightMap.set(newPt, horizontalWeight);
                    }
                }
            };
            if (this._contour) {
                await new Promise(((resolve, reject) => {
                    if (this._applyWeightsJobHandle) {
                        server_namespaceObject.system.clearJob(this._applyWeightsJobHandle);
                    }
                    this._applyWeightsJobHandle = server_namespaceObject.system.runJob(workerGeneratorLine(resolve, reject, this._curvePlot, contourOperation));
                }));
            } else {
                await new Promise(((resolve, reject) => {
                    if (this._applyWeightsJobHandle) {
                        server_namespaceObject.system.clearJob(this._applyWeightsJobHandle);
                    }
                    this._applyWeightsJobHandle = server_namespaceObject.system.runJob(workerGeneratorLine(resolve, reject, this._curvePlot, nonContourOperation));
                }));
            }
            return [ newPoints, pointHorizontalWeightMap ];
        }
        getWeightFromPointInLengthLinear(pos) {
            let verticalWeight = this._verticalWeight;
            const startVertWeight = this._startData?.verticalWeight ?? this._verticalWeight;
            const endVertWeight = this._endData?.verticalWeight ?? this._verticalWeight;
            let horizontalWeight = this._horizontalWeight;
            const startHoriWeight = this._startData?.horizontalWeight ?? this._horizontalWeight;
            const endHoriWeight = this._endData?.horizontalWeight ?? this._horizontalWeight;
            if (this._startData || this._endData) {
                if (endVertWeight === startVertWeight) {
                    verticalWeight = startVertWeight;
                } else {
                    const vertSteps = Math.abs(startVertWeight - endVertWeight) + 1;
                    const vertStep = Math.floor(pos / this._curvePlot.length * vertSteps);
                    verticalWeight = startVertWeight < endVertWeight ? startVertWeight + vertStep : startVertWeight - vertStep;
                }
                if (endHoriWeight === startHoriWeight) {
                    horizontalWeight = startHoriWeight;
                } else {
                    const horiSteps = Math.abs(startHoriWeight - endHoriWeight) + 1;
                    const horiStep = Math.floor(pos / this._curvePlot.length * horiSteps);
                    horizontalWeight = startHoriWeight < endHoriWeight ? startHoriWeight + horiStep : startHoriWeight - horiStep;
                }
            }
            return [ verticalWeight, horizontalWeight ];
        }
        async applyHorizontalThicknessToVerticalResults(verticalResults, horizontalWeightMap) {
            const newPoints = new Vector3Map;
            const dx = this._end.x - this._start.x;
            const dz = this._end.z - this._start.z;
            const absDx = Math.abs(dx);
            const absDz = Math.abs(dz);
            if (absDx !== absDz) {
                if (absDz > absDx) {
                    const operation = pt => {
                        let newPt;
                        let off;
                        const horizontalWeightEntry = horizontalWeightMap.get(pt);
                        const horizontalWeight = horizontalWeightEntry ? horizontalWeightEntry : 1;
                        for (let i = 2; i <= horizontalWeight; i++) {
                            off = i % 2 === 0 ? i / 2 : -(i - 1) / 2;
                            newPt = {
                                x: pt.x + off,
                                y: pt.y,
                                z: pt.z
                            };
                            if (!newPoints.has(newPt) && !verticalResults.has(newPt)) {
                                newPoints.add(newPt);
                            }
                        }
                    };
                    if (this._applyHorizontalWeightsJobHandle) {
                        server_namespaceObject.system.clearJob(this._applyHorizontalWeightsJobHandle);
                    }
                    await new Promise(((resolve, reject) => {
                        this._applyHorizontalWeightsJobHandle = server_namespaceObject.system.runJob(workerGeneratorMap(resolve, reject, verticalResults, operation));
                    }));
                } else {
                    const operation = pt => {
                        let newPt;
                        let off;
                        const horizontalWeightEntry = horizontalWeightMap.get(pt);
                        const horizontalWeight = horizontalWeightEntry ? horizontalWeightEntry : 1;
                        for (let i = 2; i <= horizontalWeight; i++) {
                            off = i % 2 === 0 ? i / 2 : -(i - 1) / 2;
                            newPt = {
                                x: pt.x,
                                y: pt.y,
                                z: pt.z + off
                            };
                            if (!newPoints.has(newPt) && !verticalResults.has(newPt)) {
                                newPoints.add(newPt);
                            }
                        }
                    };
                    if (this._applyHorizontalWeightsJobHandle) {
                        server_namespaceObject.system.clearJob(this._applyHorizontalWeightsJobHandle);
                    }
                    await new Promise(((resolve, reject) => {
                        this._applyHorizontalWeightsJobHandle = server_namespaceObject.system.runJob(workerGeneratorMap(resolve, reject, verticalResults, operation));
                    }));
                }
            } else {
                const sameSigns = dx < 0 && dz < 0 || dx >= 0 && dz >= 0;
                if (sameSigns) {
                    const operation = pt => {
                        let newPt;
                        let offX = 1;
                        let offZ = 0;
                        const horizontalWeightEntry = horizontalWeightMap.get(pt);
                        const horizontalWeight = horizontalWeightEntry ? horizontalWeightEntry : 1;
                        for (let i = 2; i <= horizontalWeight; i++) {
                            newPt = {
                                x: pt.x + offX,
                                y: pt.y,
                                z: pt.z + offZ
                            };
                            if (!newPoints.has(newPt) && !verticalResults.has(newPt)) {
                                newPoints.add(newPt);
                            }
                            newPt = {
                                x: pt.x + offZ,
                                y: pt.y,
                                z: pt.z + offX
                            };
                            if (!newPoints.has(newPt) && !verticalResults.has(newPt)) {
                                newPoints.add(newPt);
                            }
                            i % 2 === 0 ? offZ-- : offX++;
                        }
                    };
                    if (this._applyHorizontalWeightsJobHandle) {
                        server_namespaceObject.system.clearJob(this._applyHorizontalWeightsJobHandle);
                    }
                    await new Promise(((resolve, reject) => {
                        this._applyHorizontalWeightsJobHandle = server_namespaceObject.system.runJob(workerGeneratorMap(resolve, reject, verticalResults, operation));
                    }));
                } else {
                    const operation = pt => {
                        let newPt;
                        let isEven;
                        let offX = 0;
                        let offZ = 1;
                        const horizontalWeightEntry = horizontalWeightMap.get(pt);
                        const horizontalWeight = horizontalWeightEntry ? horizontalWeightEntry : 1;
                        for (let i = 2; i <= horizontalWeight; i++) {
                            isEven = i % 2 === 0;
                            newPt = {
                                x: isEven ? pt.x + offX : pt.x - offX,
                                y: pt.y,
                                z: isEven ? pt.z + offZ : pt.z - offZ
                            };
                            if (!newPoints.has(newPt) && !verticalResults.has(newPt)) {
                                newPoints.add(newPt);
                            }
                            newPt = {
                                x: isEven ? pt.x + offZ : pt.x - offZ,
                                y: pt.y,
                                z: isEven ? pt.z + offZ : pt.z - offZ
                            };
                            if (!newPoints.has(newPt) && !verticalResults.has(newPt)) {
                                newPoints.add(newPt);
                            }
                            if (!isEven) {
                                offX++;
                                offZ++;
                            }
                        }
                    };
                    if (this._applyHorizontalWeightsJobHandle) {
                        server_namespaceObject.system.clearJob(this._applyHorizontalWeightsJobHandle);
                    }
                    await new Promise(((resolve, reject) => {
                        this._applyHorizontalWeightsJobHandle = server_namespaceObject.system.runJob(workerGeneratorMap(resolve, reject, verticalResults, operation));
                    }));
                }
            }
            return [ ...verticalResults.values, ...newPoints.values ];
        }
        teardown() {
            if (this._applyWeightsJobHandle !== undefined) {
                server_namespaceObject.system.clearJob(this._applyWeightsJobHandle);
            }
            if (this._applyHorizontalWeightsJobHandle !== undefined) {
                server_namespaceObject.system.clearJob(this._applyHorizontalWeightsJobHandle);
            }
        }
    }
    class BlockLine extends BlockCurve {
        constructor(start, end, requestCursorTargetMode, requestGroundLevelAtLocation, blockLineCreationOptions) {
            super(start, end, requestCursorTargetMode, requestGroundLevelAtLocation, blockLineCreationOptions?.curveOptions);
            this._blockLineType = blockLineCreationOptions?.blockLineType ?? BlockLineType.Direct;
            void this.generateCurve();
        }
        get blockLineType() {
            return this._blockLineType;
        }
        async setOptions(newOptions) {
            if (newOptions.blockLineType !== this._blockLineType) {
                this._blockLineType = newOptions.blockLineType;
                return await super.setOptions(newOptions);
            }
            return {
                pointsAdded: [],
                pointsRemoved: []
            };
        }
        updatePlot() {
            switch (this._blockLineType) {
              case BlockLineType.Direct:
                {
                    this.plotBresenhamLine3D();
                    super.updatePlot();
                    break;
                }

              case BlockLineType.Staggered:
                {
                    this.plotManhattanLine3D();
                    super.updatePlot();
                    break;
                }

              default:
                break;
            }
        }
        plotBresenhamLine3D() {
            this._curvePlot.length = 0;
            this._curvePlot.push({
                x: this._start.x,
                y: this._start.y,
                z: this._start.z
            });
            const dx = Math.abs(this._end.x - this._start.x);
            const dy = Math.abs(this._end.y - this._start.y);
            const dz = Math.abs(this._end.z - this._start.z);
            const xs = this._end.x > this._start.x ? 1 : -1;
            const ys = this._end.y > this._start.y ? 1 : -1;
            const zs = this._end.z > this._start.z ? 1 : -1;
            if (dx >= dy && dx >= dz) {
                let p0 = 2 * dy - dx;
                let p1 = 2 * dz - dx;
                let x0 = this._start.x;
                let y0 = this._start.y;
                let z0 = this._start.z;
                while (x0 !== this._end.x) {
                    x0 += xs;
                    if (p0 >= 0) {
                        y0 += ys;
                        p0 -= 2 * dx;
                    }
                    if (p1 >= 0) {
                        z0 += zs;
                        p1 -= 2 * dx;
                    }
                    p0 += 2 * dy;
                    p1 += 2 * dz;
                    this._curvePlot.push({
                        x: x0,
                        y: y0,
                        z: z0
                    });
                }
            } else if (dy >= dx && dy >= dz) {
                let p0 = 2 * dx - dy;
                let p1 = 2 * dz - dy;
                let y0 = this._start.y;
                let x0 = this._start.x;
                let z0 = this._start.z;
                while (y0 !== this._end.y) {
                    y0 += ys;
                    if (p0 >= 0) {
                        x0 += xs;
                        p0 -= 2 * dy;
                    }
                    if (p1 >= 0) {
                        z0 += zs;
                        p1 -= 2 * dy;
                    }
                    p0 += 2 * dx;
                    p1 += 2 * dz;
                    this._curvePlot.push({
                        x: x0,
                        y: y0,
                        z: z0
                    });
                }
            } else {
                let p0 = 2 * dy - dz;
                let p1 = 2 * dx - dz;
                let z0 = this._start.z;
                let x0 = this._start.x;
                let y0 = this._start.y;
                while (z0 !== this._end.z) {
                    z0 += zs;
                    if (p0 >= 0) {
                        y0 += ys;
                        p0 -= 2 * dz;
                    }
                    if (p1 >= 0) {
                        x0 += xs;
                        p1 -= 2 * dz;
                    }
                    p0 += 2 * dy;
                    p1 += 2 * dx;
                    this._curvePlot.push({
                        x: x0,
                        y: y0,
                        z: z0
                    });
                }
            }
        }
        plotManhattanLine3D() {
            this._curvePlot.length = 0;
            let x = this._start.x;
            let y = this._start.y;
            let z = this._start.z;
            this._curvePlot.push({
                x: this._start.x,
                y: this._start.y,
                z: this._start.z
            });
            while (x !== this._end.x || y !== this._end.y || z !== this._end.z) {
                if (x < this._end.x) {
                    x++;
                    this._curvePlot.push({
                        x,
                        y,
                        z
                    });
                } else if (x > this._end.x) {
                    x--;
                    this._curvePlot.push({
                        x,
                        y,
                        z
                    });
                }
                if (y < this._end.y) {
                    y++;
                    this._curvePlot.push({
                        x,
                        y,
                        z
                    });
                } else if (y > this._end.y) {
                    y--;
                    this._curvePlot.push({
                        x,
                        y,
                        z
                    });
                }
                if (z < this._end.z) {
                    z++;
                    this._curvePlot.push({
                        x,
                        y,
                        z
                    });
                } else if (z > this._end.z) {
                    z--;
                    this._curvePlot.push({
                        x,
                        y,
                        z
                    });
                }
            }
        }
    }
    const MAX_WORKER_OPERATIONS = 1e3;
    function* workerGeneratorLine(jobCompleted, jobFailed, line, operation) {
        try {
            let opCount = 0;
            for (let i = 0; i < line.length; ++i) {
                operation(i, line[i]);
                ++opCount;
                if (opCount > MAX_WORKER_OPERATIONS) {
                    opCount = 0;
                    yield;
                }
            }
        } catch (e) {
            jobFailed(e);
        }
        jobCompleted();
    }
    function* workerGeneratorMap(jobCompleted, jobFailed, map, operation) {
        try {
            let opCount = 0;
            for (const pt of map.values) {
                operation(pt);
                ++opCount;
                if (opCount > MAX_WORKER_OPERATIONS) {
                    opCount = 0;
                    yield;
                }
            }
        } catch (e) {
            jobFailed(e);
        }
        jobCompleted();
    }
    class SimpleStateSelector {
        constructor(initialState) {
            this.state = initialState;
        }
        changeState(next, action, state, predicate) {
            if (state === undefined) {
                this.state = next;
                action();
                return true;
            }
            if (predicate === undefined) {
                throw Error("All optional arguments must be provided");
            }
            if (predicate && this.state === state) {
                action();
                this.state = next;
                return true;
            }
            return false;
        }
        getState() {
            return this.state;
        }
        resetState(initialState) {
            this.state = initialState;
        }
    }
    function calculateClipboardNormalizedAnchorValue(item, absolute) {
        const itemSize = item.size;
        if (itemSize.x < 1 || itemSize.y < 1 || itemSize.z < 1) {
            return lib.VECTOR3_ZERO;
        }
        const clamped = lib.Vector3Utils.clamp(absolute, {
            min: lib.VECTOR3_ZERO,
            max: lib.Vector3Utils.subtract(itemSize, lib.VECTOR3_ONE)
        });
        const x = itemSize.x <= 1 ? 0 : clamped.x * 2 / (itemSize.x - 1) - 1;
        const y = itemSize.y <= 1 ? 0 : clamped.y * 2 / (itemSize.y - 1) - 1;
        const z = itemSize.z <= 1 ? 0 : clamped.z * 2 / (itemSize.z - 1) - 1;
        return new lib.Vector3Builder(x, y, z);
    }
    function calculateClipboardAbsoluteAnchorValue(item) {
        const itemSize = item.size;
        const normalizedOrigin = item.normalizedOrigin;
        const x = Math.round((normalizedOrigin.x + 1) * ((itemSize.x - 1) / 2));
        const y = Math.round((normalizedOrigin.y + 1) * ((itemSize.y - 1) / 2));
        const z = Math.round((normalizedOrigin.z + 1) * ((itemSize.z - 1) / 2));
        return new lib.Vector3Builder(x, y, z);
    }
    var node_modules_buffer = __webpack_require__(945);
    function CreateBase64ImageFromRGB(rgbValues, width, height) {
        const HEADER_SIZE = 54;
        const DIB_HEADER_SIZE = 40;
        const PIXELS_PER_METER = 2835;
        const fileSize = HEADER_SIZE + 3 * width * height;
        const buffer = node_modules_buffer.lW.alloc(fileSize);
        buffer.write("BM");
        buffer.writeUInt32LE(fileSize, 2);
        buffer.writeUInt32LE(HEADER_SIZE, 10);
        buffer.writeUInt32LE(DIB_HEADER_SIZE, 14);
        buffer.writeInt32LE(width, 18);
        buffer.writeInt32LE(height, 22);
        buffer.writeUInt16LE(1, 26);
        buffer.writeUInt16LE(24, 28);
        buffer.writeUInt32LE(0, 30);
        buffer.writeUInt32LE(3 * width * height, 34);
        buffer.writeInt32LE(PIXELS_PER_METER, 38);
        buffer.writeInt32LE(PIXELS_PER_METER, 42);
        let offset = HEADER_SIZE;
        for (let y = height - 1; y >= 0; y--) {
            for (let x = 0; x < width; x++) {
                const idx = y * width + x;
                if (idx < rgbValues.length) {
                    const {r, g, b} = rgbValues[idx];
                    buffer.writeUInt8(b, offset);
                    buffer.writeUInt8(g, offset + 1);
                    buffer.writeUInt8(r, offset + 2);
                }
                offset += 3;
            }
        }
        return `data:image/bmp;base64,${buffer.toString("base64")}`;
    }
    function getMapValueFromKey(map, key) {
        const value = map.get(key);
        if (value === undefined) {
            throw new Error(`Key ${String(key)} not found in map`);
        }
        return value;
    }
    function getMapKeyFromValue(map, value) {
        for (const [key, val] of map.entries()) {
            if (val === value) {
                return key;
            }
        }
        throw new Error(`Value ${String(value)} not found in map`);
    }
    function getEnumKeyByEnumValue(myEnum, enumValue) {
        const keys = Object.keys(myEnum);
        for (const key of keys) {
            if (myEnum[key] === enumValue) {
                return key;
            }
        }
        return "";
    }
    function capitalizeAndSpaceEnumName(currentString) {
        if (!currentString) {
            return "";
        }
        const isUpperCase = char => char === char.toUpperCase() && char !== char.toLowerCase();
        let result = currentString.charAt(0).toUpperCase();
        for (let i = 1; i < currentString.length; i++) {
            if (isUpperCase(currentString.charAt(i))) {
                result = result + " ";
            }
            result += currentString.charAt(i).toLowerCase();
        }
        return result;
    }
    function toBase64(input) {
        const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        let str = "";
        let i = 0;
        while (i < input.length) {
            const c1 = input.charCodeAt(i++);
            const c2 = input.charCodeAt(i++);
            const c3 = input.charCodeAt(i++);
            const e1 = c1 >> 2;
            const e2 = (c1 & 3) << 4 | c2 >> 4;
            const e3 = (c2 & 15) << 2 | c3 >> 6;
            const e4 = c3 & 63;
            if (isNaN(c2)) {
                str += chars.charAt(e1) + chars.charAt(e2) + "==";
            } else if (isNaN(c3)) {
                str += chars.charAt(e1) + chars.charAt(e2) + chars.charAt(e3) + "=";
            } else {
                str += chars.charAt(e1) + chars.charAt(e2) + chars.charAt(e3) + chars.charAt(e4);
            }
        }
        return str;
    }
    function validateIdentifierString(name) {
        if (!name || name.trim() === "") {
            return {
                valid: false,
                message: "Template name cannot be empty"
            };
        }
        if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
            return {
                valid: false,
                message: "Identifier name must start with a letter or underscore and contain only alphanumeric characters and underscores"
            };
        }
        return {
            valid: true,
            message: ""
        };
    }
    class CustomSet {
        constructor(hashFunction) {
            this.values = new Map;
            this.hashFunction = hashFunction;
        }
        add(value) {
            const hash = this.hashFunction(value);
            this.values.set(hash, value);
        }
        contains(value) {
            const hash = this.hashFunction(value);
            return this.values.has(hash);
        }
        delete(value) {
            const hash = this.hashFunction(value);
            this.values.delete(hash);
        }
        get size() {
            return this.values.size;
        }
        value(hash) {
            return this.values.get(hash);
        }
        forEach(callback) {
            this.values.forEach(callback);
        }
        clear() {
            this.values.clear();
        }
        get isEmpty() {
            return this.values.size === 0;
        }
        generateKey(value) {
            return this.hashFunction(value);
        }
    }
    const vec3HashFunction = v => {
        const prime1 = 73856093;
        const prime2 = 19349663;
        const prime3 = 83492791;
        return v.x * prime1 ^ v.y * prime2 ^ v.z * prime3;
    };
    class Vector3Set extends CustomSet {
        constructor() {
            super(vec3HashFunction);
        }
    }
    var ClockType;
    (function(ClockType) {
        ClockType[ClockType["CLOCK_24HR"] = 0] = "CLOCK_24HR";
        ClockType[ClockType["CLOCK_12HR"] = 1] = "CLOCK_12HR";
        ClockType[ClockType["MINECRAFT_CLOCK"] = 2] = "MINECRAFT_CLOCK";
    })(ClockType || (ClockType = {}));
    var TODDropDown;
    (function(TODDropDown) {
        TODDropDown[TODDropDown["Day"] = 1e3] = "Day";
        TODDropDown[TODDropDown["Noon"] = 6e3] = "Noon";
        TODDropDown[TODDropDown["Sunset"] = 12e3] = "Sunset";
        TODDropDown[TODDropDown["Night"] = 13e3] = "Night";
        TODDropDown[TODDropDown["Midnight"] = 18e3] = "Midnight";
        TODDropDown[TODDropDown["Sunrise"] = 23e3] = "Sunrise";
        TODDropDown[TODDropDown["None"] = 100001] = "None";
    })(TODDropDown || (TODDropDown = {}));
    const clockValues = [ {
        stringId: "resourcePack.editor.timeOfDay.24hrClock",
        index: ClockType.CLOCK_24HR
    }, {
        stringId: "resourcePack.editor.timeOfDay.12hrClock",
        index: ClockType.CLOCK_12HR
    }, {
        stringId: "resourcePack.editor.timeOfDay.minecraftClock",
        index: ClockType.MINECRAFT_CLOCK
    } ];
    const validPresets = [ {
        stringId: "resourcePack.editor.timeOfDay.dropDown.none",
        time: TODDropDown.None
    }, {
        stringId: "resourcePack.editor.timeOfDay.dropDown.day",
        time: TODDropDown.Day
    }, {
        stringId: "resourcePack.editor.timeOfDay.dropDown.noon",
        time: TODDropDown.Noon
    }, {
        stringId: "resourcePack.editor.timeOfDay.dropDown.sunset",
        time: TODDropDown.Sunset
    }, {
        stringId: "resourcePack.editor.timeOfDay.dropDown.night",
        time: TODDropDown.Night
    }, {
        stringId: "resourcePack.editor.timeOfDay.dropDown.midnight",
        time: TODDropDown.Midnight
    }, {
        stringId: "resourcePack.editor.timeOfDay.dropDown.sunrise",
        time: TODDropDown.Sunrise
    } ];
    const mcHoursPerTick = 1e3;
    const mcMinsPerTick = 16.6667;
    function convertTODToTime(timeOfDay, use24HrClock) {
        const _amStr = "A.M.";
        const _pmStr = "P.M.";
        let ampm = "";
        const isPM = timeOfDay >= server_namespaceObject.TimeOfDay.Noon && timeOfDay < server_namespaceObject.TimeOfDay.Midnight;
        if (!use24HrClock) {
            if (isPM) {
                ampm = " " + _pmStr;
            } else {
                ampm = " " + _amStr;
            }
        }
        let hours = (6 + Math.floor(timeOfDay / mcHoursPerTick)) % 24;
        let numZeroes = 2;
        if (!use24HrClock) {
            hours = hours % 12;
            hours = hours === 0 ? 12 : hours;
            numZeroes = 1;
        }
        const hourStr = hours.toString().padStart(numZeroes, "0");
        timeOfDay %= mcHoursPerTick;
        const minutes = Math.floor(timeOfDay / mcMinsPerTick);
        const minuteStr = minutes.toString().padStart(2, "0");
        return `${hourStr}:${minuteStr}${ampm}`;
    }
    function convertToTOD(hours, minutes) {
        hours -= 6;
        if (hours < 0) {
            hours = 24 - (6 + hours);
        }
        return hours * mcHoursPerTick + minutes * mcMinsPerTick;
    }
    function getInputMarkup(id, props) {
        let markupStart = "[~*input|$id=" + id;
        if (props?.showUnset) {
            markupStart = markupStart.concat("|showUnset");
        }
        if (!props || !props.ignoreFormat) {
            markupStart = markupStart.concat("|$format=", props?.prefix ?? "[", "*input");
            markupStart = markupStart.concat(props?.prefix ?? "]");
        }
        if (props?.contextId) {
            markupStart = markupStart.concat("|$contextId=", props.contextId);
        }
        return markupStart.concat("~]");
    }
    const newLineMarkup = "[~*newLine~]";
    class SharedControlImpl {
        constructor(session, parentTool, parentPropertyPane, controlName, localizationPrefix) {
            this._session = session;
            this._parentTool = parentTool;
            this._parentPropertyPane = parentPropertyPane;
            this._controlName = controlName;
            this._isActive = false;
            this._isInitialized = false;
            this._localizationPrefix = localizationPrefix;
        }
        initialize() {
            this._isInitialized = true;
        }
        shutdown() {
            this._isInitialized = false;
        }
        activateControl() {
            if (!this._isInitialized) {
                throw new Error("Control must be initialized before it can be activated");
            }
            if (this._isActive) {
                throw new Error("Control is already active");
            }
            this._isActive = true;
        }
        deactivateControl() {
            if (!this._isActive) {
                throw new Error("Control is not active");
            }
            this._isActive = false;
        }
        registerToolKeyBinding(action, binding, tag) {
            this._parentTool.registerKeyBinding(action, binding, {
                uniqueId: this.getToolKeyBindingId(tag),
                label: `${this._localizationPrefix}.keybinding.${tag}.title`,
                tooltip: `${this._localizationPrefix}.keybinding.${tag}.tooltip`
            });
        }
        getToolKeyBindingId(tag) {
            return `${this._parentTool.id}:${this._controlName}Keybinding:${tag}`;
        }
        localize(key) {
            return `${this.localizationPrefix}.${key}`;
        }
        get session() {
            return this._session;
        }
        get propertyPane() {
            return this._parentPropertyPane;
        }
        get controlName() {
            return this._controlName;
        }
        get tool() {
            return this._parentTool;
        }
        get isActive() {
            return this._isActive;
        }
        get isInitialized() {
            return this._isInitialized;
        }
        get localizationPrefix() {
            return this._localizationPrefix;
        }
    }
    var ContiguousSelectionUtils_ContiguousSelectionType;
    (function(ContiguousSelectionType) {
        ContiguousSelectionType[ContiguousSelectionType["SameBlock"] = 0] = "SameBlock";
        ContiguousSelectionType[ContiguousSelectionType["BlockStates"] = 1] = "BlockStates";
        ContiguousSelectionType[ContiguousSelectionType["SolidBlock"] = 2] = "SolidBlock";
        ContiguousSelectionType[ContiguousSelectionType["AllBlocks"] = 3] = "AllBlocks";
        ContiguousSelectionType[ContiguousSelectionType["Custom"] = 4] = "Custom";
    })(ContiguousSelectionUtils_ContiguousSelectionType || (ContiguousSelectionUtils_ContiguousSelectionType = {}));
    function getBoundsForContiguousSelection(initialLocation, selectionDirection, size, isFace) {
        const faceSize = (size - 1) / 2;
        const from = {
            x: initialLocation.x - faceSize,
            y: initialLocation.y - faceSize,
            z: initialLocation.z - faceSize
        };
        const to = {
            x: initialLocation.x + faceSize,
            y: initialLocation.y + faceSize,
            z: initialLocation.z + faceSize
        };
        if (isFace) {
            switch (selectionDirection) {
              case Direction.Up:
              case Direction.Down:
                from.y = initialLocation.y;
                to.y = initialLocation.y;
                break;

              case Direction.North:
              case Direction.South:
                from.z = initialLocation.z;
                to.z = initialLocation.z;
                break;

              case Direction.East:
              case Direction.West:
                from.x = initialLocation.x;
                to.x = initialLocation.x;
                break;
            }
        } else {
            switch (selectionDirection) {
              case Direction.Up:
                from.y = initialLocation.y;
                to.y = initialLocation.y - (size - 1);
                break;

              case Direction.Down:
                from.y = initialLocation.y;
                to.y = initialLocation.y + (size - 1);
                break;

              case Direction.North:
                from.z = initialLocation.z;
                to.z = initialLocation.z + (size - 1);
                break;

              case Direction.South:
                from.z = initialLocation.z;
                to.z = initialLocation.z - (size - 1);
                break;

              case Direction.East:
                from.x = initialLocation.x;
                to.x = initialLocation.x - (size - 1);
                break;

              case Direction.West:
                from.x = initialLocation.x;
                to.x = initialLocation.x + (size - 1);
                break;
            }
        }
        return {
            from,
            to
        };
    }
    function isBlockExposedInDirection(dimension, targetLocation, direction) {
        const ExtrusionDirection = {
            x: 0,
            y: 0,
            z: 0
        };
        switch (direction) {
          case Direction.Up:
            ExtrusionDirection.y = 1;
            break;

          case Direction.Down:
            ExtrusionDirection.y = -1;
            break;

          case Direction.North:
            ExtrusionDirection.z = -1;
            break;

          case Direction.South:
            ExtrusionDirection.z = 1;
            break;

          case Direction.East:
            ExtrusionDirection.x = 1;
            break;

          case Direction.West:
            ExtrusionDirection.x = -1;
            break;
        }
        const blockToCheck = dimension.getBlock(Vector3Utils.add(targetLocation, ExtrusionDirection));
        if (blockToCheck === undefined) {
            return false;
        }
        switch (blockToCheck.typeId) {
          case MinecraftBlockTypes.Air.toString():
          case MinecraftBlockTypes.FlowingWater.toString():
          case MinecraftBlockTypes.Water.toString():
          case MinecraftBlockTypes.FlowingLava.toString():
          case MinecraftBlockTypes.Lava.toString():
            return true;

          default:
            return false;
        }
    }
    function getPositionKey(loc) {
        return [ loc.x, loc.y, loc.z ].join(",");
    }
    function getContiguousSelection(size, selectionDirection, block, isFace, fullSelectionToleranceLevel, checkForAdjacentFaceBlocks, contiguousSelectionType, contiguousSelectionBlockList) {
        const blockSelection = new Map;
        if (isFace && checkForAdjacentFaceBlocks === undefined) {
            return blockSelection;
        }
        if (!isFace && fullSelectionToleranceLevel === undefined) {
            return blockSelection;
        }
        if (contiguousSelectionType === ContiguousSelectionUtils_ContiguousSelectionType.Custom && contiguousSelectionBlockList === undefined) {
            return blockSelection;
        }
        if (block) {
            const limits = getBoundsForContiguousSelection(block.location, selectionDirection, size, isFace);
            const from = limits.from;
            const to = limits.to;
            let bounds = new BlockVolume(from, to);
            let furthestUp = block.location.y;
            let furthestDown = block.location.y;
            let furthestWest = block.location.x;
            let furthestEast = block.location.x;
            let furthestNorth = block.location.z;
            let furthestSouth = block.location.z;
            const searchOffsets = [];
            searchOffsets.push({
                x: 0,
                y: 0,
                z: 0
            });
            for (let x = -1; x <= 1; x += 2) {
                searchOffsets.push({
                    x,
                    y: 0,
                    z: 0
                });
            }
            for (let y = -1; y <= 1; y += 2) {
                searchOffsets.push({
                    x: 0,
                    y,
                    z: 0
                });
            }
            for (let z = -1; z <= 1; z += 2) {
                searchOffsets.push({
                    x: 0,
                    y: 0,
                    z
                });
            }
            const dimension = block.dimension;
            let fillStack = [];
            let hasAdjustedBounds = false;
            const outOfBoundsBlocks = [];
            const visitedBlocks = new Map;
            let initialTolerance = 0;
            if (isFace && checkForAdjacentFaceBlocks) {
                initialTolerance = 1;
            } else if (!isFace && fullSelectionToleranceLevel !== undefined) {
                initialTolerance = fullSelectionToleranceLevel - 1;
            }
            fillStack.push({
                position: block.location,
                tolerance: initialTolerance
            });
            visitedBlocks.set(getPositionKey(block.location), {
                checked: true,
                tolerance: initialTolerance
            });
            while (fillStack.length > 0 || !hasAdjustedBounds && isFace) {
                if (fillStack.length <= 0) {
                    if (furthestUp < Math.floor(to.y) && furthestDown === Math.floor(from.y)) {
                        from.y = furthestUp - (to.y - from.y);
                    } else if (furthestUp === Math.floor(to.y) && furthestDown > Math.floor(from.y)) {
                        to.y = furthestDown + (to.y - from.y);
                    }
                    if (furthestEast < Math.floor(to.x) && furthestWest === Math.floor(from.x)) {
                        from.x = furthestEast - (to.x - from.x);
                    } else if (furthestEast === Math.floor(to.x) && furthestWest > Math.floor(from.x)) {
                        to.x = furthestWest + (to.x - from.x);
                    }
                    if (furthestSouth === Math.floor(to.z) && furthestNorth > Math.floor(from.z)) {
                        to.z = furthestNorth + (to.z - from.z);
                    } else if (furthestSouth < Math.floor(to.z) && furthestNorth === Math.floor(from.z)) {
                        from.z = furthestSouth - (to.z - from.z);
                    }
                    fillStack = outOfBoundsBlocks;
                    bounds = new BlockVolume(from, to);
                    hasAdjustedBounds = true;
                }
                const checkBlock = fillStack.pop();
                if (checkBlock !== undefined) {
                    const loc = checkBlock.position;
                    visitedBlocks.set(getPositionKey(loc), {
                        checked: true,
                        tolerance: checkBlock.tolerance
                    });
                    if (loc === undefined || !bounds.isInside(loc)) continue;
                    let isContiguous = true;
                    try {
                        const blockAtLoc = dimension.getBlock(loc);
                        if (blockAtLoc !== undefined) {
                            if (!areBlocksContiguous(contiguousSelectionType, blockAtLoc, block, contiguousSelectionBlockList)) {
                                isContiguous = false;
                                if (checkBlock.tolerance <= 0) {
                                    continue;
                                }
                            }
                            if (isFace && !isBlockExposedInDirection(dimension, loc, selectionDirection)) {
                                isContiguous = false;
                                if (checkBlock.tolerance <= 0) {
                                    continue;
                                }
                            }
                        } else {
                            continue;
                        }
                    } catch {
                        continue;
                    }
                    let remainingTolerance = checkBlock.tolerance - 1;
                    if (isContiguous) {
                        if (loc.x < furthestWest) {
                            furthestWest = loc.x;
                        }
                        if (loc.x > furthestEast) {
                            furthestEast = loc.x;
                        }
                        if (loc.z < furthestNorth) {
                            furthestNorth = loc.z;
                        }
                        if (loc.z > furthestSouth) {
                            furthestSouth = loc.z;
                        }
                        if (loc.y < furthestDown) {
                            furthestDown = loc.y;
                        }
                        if (loc.y > furthestUp) {
                            furthestUp = loc.y;
                        }
                        blockSelection.set(Vector3Utils.toString(loc), loc);
                        remainingTolerance = initialTolerance;
                    }
                    for (const offset of searchOffsets) {
                        const offsetLoc = {
                            x: loc.x + offset.x,
                            y: loc.y + offset.y,
                            z: loc.z + offset.z
                        };
                        if (!bounds.isInside(offsetLoc)) {
                            outOfBoundsBlocks.push({
                                position: offsetLoc,
                                tolerance: remainingTolerance
                            });
                            continue;
                        }
                        const visitedBlock = visitedBlocks.get(getPositionKey(offsetLoc));
                        if (visitedBlock !== undefined) {
                            if (visitedBlock.tolerance >= remainingTolerance && visitedBlock.checked) {
                                continue;
                            }
                        }
                        fillStack.push({
                            position: offsetLoc,
                            tolerance: remainingTolerance
                        });
                        visitedBlocks.set(getPositionKey(offsetLoc), {
                            checked: false,
                            tolerance: remainingTolerance
                        });
                    }
                }
            }
        }
        return blockSelection;
    }
    function BlockUtils_areBlocksContiguous(contiguousSelectionType, blockToTest, blockToFollow, allowList) {
        switch (contiguousSelectionType) {
          case ContiguousSelectionType.SameBlock:
            if (blockToFollow !== undefined) {
                return isSameBlockType(blockToFollow, blockToTest);
            }
            break;

          case ContiguousSelectionType.BlockStates:
            if (blockToFollow !== undefined) {
                return isSameBlockAndProperties(blockToFollow, blockToTest);
            }
            break;

          case ContiguousSelectionType.SolidBlock:
            return isBlockSolid(blockToTest);

          case ContiguousSelectionType.AllBlocks:
            return isBlockNotAir(blockToTest);

          case ContiguousSelectionType.Custom:
            if (allowList !== undefined) {
                return isBlockTypeInSelectionList(blockToTest, allowList);
            }
            break;
        }
        return false;
    }
    function arraysAreEqual(a, b) {
        if (a === undefined || b === undefined) {
            return a === b;
        }
        return a.length === b.length && a.every(((value, index) => value === b[index]));
    }
    function convertBlockStringsToBlockType(blockString) {
        const blockTypes = [];
        for (let blockStringElement of blockString) {
            if (!blockStringElement.includes(":")) {
                blockStringElement = "minecraft:" + blockStringElement;
            }
            const blockType = server_namespaceObject.BlockTypes.get(blockStringElement);
            if (blockType) {
                blockTypes.push(blockType);
            }
        }
        return blockTypes;
    }
    function convertBlockStringsToSetOfBlockType(blockString) {
        const blockTypes = new Set;
        for (let blockStringElement of blockString) {
            if (!blockStringElement.includes(":")) {
                blockStringElement = "minecraft:" + blockStringElement;
            }
            const blockType = BlockTypes.get(blockStringElement);
            if (blockType) {
                blockTypes.add(blockType);
            }
        }
        return blockTypes;
    }
    function convertBlockTypesToBlockStrings(blockTypes) {
        const blockStrings = [];
        for (const blockType of blockTypes) {
            let blockName = blockType.id;
            if (blockName.startsWith("minecraft:")) {
                blockName = blockName.substring(10);
            }
            blockStrings.push(blockName);
        }
        return blockStrings;
    }
    function isBlockNotAir(block) {
        return block.typeId !== lib_vanilla_MinecraftBlockTypes.Air;
    }
    function isBlockSolid(block) {
        return block.isSolid;
    }
    function isSameBlockAndProperties(BlockA, BlockB) {
        if (!isSameBlockType(BlockA, BlockB)) {
            return false;
        }
        const BlockAPermutationProperties = BlockA.permutation.getAllStates();
        const BlockBPermutationProperties = BlockB.permutation.getAllStates();
        return JSON.stringify(BlockAPermutationProperties) === JSON.stringify(BlockBPermutationProperties);
    }
    function isSameBlockType(BlockA, BlockB) {
        return BlockA.typeId === BlockB.typeId;
    }
    function isBlockTypeInSelectionList(block, allowList) {
        if (allowList === undefined || allowList.size === 0) {
            return false;
        }
        const blockType = block.type;
        if (blockType === undefined) {
            return false;
        }
        for (const type of allowList) {
            if (type === blockType) {
                return true;
            }
        }
        return false;
    }
    class PersistenceGroupItemImpl {
        constructor(groupItem) {
            this._persistenceGroupItem = groupItem;
        }
        get key() {
            return this._persistenceGroupItem.getKey();
        }
        setValue(value) {
            this._persistenceGroupItem.setValue(value);
            this._persistenceGroupItem.commit();
        }
        getValue() {
            return this._persistenceGroupItem.getAsJSON();
        }
        get value() {
            if (this.valueObj === undefined) {
                try {
                    this.valueObj = JSON.parse(this._persistenceGroupItem.getAsJSON());
                } catch {
                    return undefined;
                }
            }
            return this.valueObj;
        }
        set value(itemValue) {
            this.valueObj = itemValue;
        }
        commit() {
            if (this.valueObj === undefined) {
                return;
            }
            const itemValue = ConvertValueToString(this.valueObj);
            this._persistenceGroupItem.setValue(itemValue);
            this._persistenceGroupItem.commit();
        }
    }
    class PersistenceGroupImpl {
        constructor(group) {
            this._persistenceGroup = group;
        }
        createItem(key, item) {
            const itemValue = ConvertValueToString(item);
            const newItem = this._persistenceGroup.createItem(key, itemValue);
            const itemImpl = new PersistenceGroupItemImpl(newItem);
            itemImpl.value = item;
            return itemImpl;
        }
        deleteItem(key) {
            this._persistenceGroup.deleteItem(key);
        }
        getOrCreateItem(key, item) {
            const itemValue = ConvertValueToString(item);
            const newItem = this._persistenceGroup.getOrCreateItem(key, itemValue);
            const itemImpl = new PersistenceGroupItemImpl(newItem);
            itemImpl.value = item;
            return itemImpl;
        }
        fetchItem(key) {
            const item = this._persistenceGroup.fetchItem(key);
            if (!item) {
                return undefined;
            }
            return new PersistenceGroupItemImpl(item);
        }
        listItemNames() {
            return this._persistenceGroup.listItems();
        }
        dispose() {
            return this._persistenceGroup.dispose();
        }
    }
    class PersistenceManager {
        constructor(persistenceManager) {
            this._internal = persistenceManager;
        }
        createGroup(namespaceName, options) {
            return new PersistenceGroupImpl(this._internal.createGroup(namespaceName, options));
        }
        getOrCreateGroup(namespaceName, options) {
            return new PersistenceGroupImpl(this._internal.getOrCreateGroup(namespaceName, options));
        }
        deleteGroup(namespaceName, options) {
            return this._internal.deleteGroup(namespaceName, options);
        }
        getGroup(namespaceName, options) {
            const group = this._internal.getGroup(namespaceName, options);
            if (group) {
                return new PersistenceGroupImpl(group);
            }
            return undefined;
        }
        getGroups(options) {
            const groups = this._internal.fetchGroups(options);
            const persistenceGroupList = [];
            for (const group of groups) {
                persistenceGroupList.push(new PersistenceGroupImpl(group));
            }
            return persistenceGroupList;
        }
        requestClientGroup(namespacedName, options, callback) {
            const handleResult = persistenceGroup => {
                if (persistenceGroup) {
                    const group = new PersistenceGroupImpl(persistenceGroup);
                    callback(group);
                } else {
                    callback(undefined);
                }
            };
            this._internal.requestClientGroup(namespacedName, options, handleResult);
        }
        disposeAllGroups() {
            this._internal.disposeAllGroups();
        }
    }
    function ConvertValueToString(value) {
        if (typeof value === "object" && value !== undefined || Array.isArray(value)) {
            return JSON.stringify(value);
        }
        if (typeof value === "number" || typeof value === "boolean") {
            return value.toString();
        }
        return value;
    }
    function getPersistenceManager(player) {
        const persistenceManager = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(player).internalPersistenceManager;
        return new PersistenceManager(persistenceManager);
    }
    const PERSISTENCE_GROUP_NAME = "editor:brushpaint";
    const PERSISTENCE_GROUPITEM_SETTINGS = "settings";
    const PROPERTY_BRUSHPAINTCONTROL_NAME = "BrushPaintControl";
    const PROPERTY_BRUSHPAINTCONTROL_LOCALIZATION_PREFIX = `resourcePack.editor.${PROPERTY_BRUSHPAINTCONTROL_NAME}`;
    var InternalMaskType;
    (function(InternalMaskType) {
        InternalMaskType[InternalMaskType["Disabled"] = 0] = "Disabled";
        InternalMaskType[InternalMaskType["Mask"] = 1] = "Mask";
        InternalMaskType[InternalMaskType["Replace"] = 2] = "Replace";
    })(InternalMaskType || (InternalMaskType = {}));
    var BrushPaintControlStringKeys;
    (function(BrushPaintControlStringKeys) {
        BrushPaintControlStringKeys["RootPaneTitle"] = "rootPane.title";
        BrushPaintControlStringKeys["RootPaneTooltip"] = "brushSettings.tooltip";
        BrushPaintControlStringKeys["BrushShapeSelectionTitle"] = "brush.title";
        BrushPaintControlStringKeys["BrushShapeSelectionTooltip"] = "brush.tooltip";
        BrushPaintControlStringKeys["OffsetTitle"] = "offset.title";
        BrushPaintControlStringKeys["OffsetTooltip"] = "offset.tooltip";
        BrushPaintControlStringKeys["BrushShapeSettingsTitle"] = "shapeSettings.title";
        BrushPaintControlStringKeys["BrushShapeSettingsTooltip"] = "shapeSettings.tooltip";
        BrushPaintControlStringKeys["FillConstraintsTitle"] = "fillConstraints.title";
        BrushPaintControlStringKeys["FillConstraintsTooltip"] = "fillConstraints.tooltip";
        BrushPaintControlStringKeys["MaskModeTitle"] = "fillConstraints.maskMode.title";
        BrushPaintControlStringKeys["MaskModeTooltip"] = "fillConstraints.maskMode.tooltip";
    })(BrushPaintControlStringKeys || (BrushPaintControlStringKeys = {}));
    class BrushPaintSharedControl extends SharedControlImpl {
        get isUIConstructed() {
            return this._brushSettingsSubPane !== undefined;
        }
        get selectedBrushShape() {
            return this._getSelectedBrushShape();
        }
        get brushShapeOffset() {
            return this._brushShapeOffset.value;
        }
        constructor(session, parentTool, parentPropertyPane, _brushSettings, _brushShapes, _options) {
            super(session, parentTool, parentPropertyPane, PROPERTY_BRUSHPAINTCONTROL_NAME, PROPERTY_BRUSHPAINTCONTROL_LOCALIZATION_PREFIX);
            this._brushShapes = _brushShapes;
            this._options = _options;
            this._selectedBrushIndex = (0, server_editor_namespaceObject.makeObservable)(0);
            this._internalMaskType = (0, server_editor_namespaceObject.makeObservable)(InternalMaskType.Disabled);
            this._brushSettingsCollection = [];
            this._brushShapeOffset = (0, server_editor_namespaceObject.makeObservable)({
                x: 0,
                y: 0,
                z: 0
            });
            this._brushControlRootPane = undefined;
            this._brushSettingsSubPane = undefined;
            this._customSettingsSubPane = undefined;
            this._fillConstraintsSubPane = undefined;
            this._fillReplaceSubPane = undefined;
            this._fillMaskSubPane = undefined;
            this._blockListReplaceIds = (0, server_editor_namespaceObject.makeObservable)([]);
            this._blockListReplace = [];
            this._blockListMaskIds = (0, server_editor_namespaceObject.makeObservable)([]);
            this._blockListMask = [];
            this._updateSettingsOperations = [];
            this._updateSettingsOperationTickHandle = undefined;
            this._editorMode = server_editor_namespaceObject.EditorMode.Tool;
            this._needsRefresh = false;
            this._blockMaskKey = `${this.tool.id}_BlockMask_Mask`;
            this._blockReplaceKey = `${this.tool.id}_BlockMask_Replace`;
            this._persistenceManager = getPersistenceManager(session.extensionContext.player);
            this._brushSettings = _brushSettings;
            if (this._options?.locOverride) {
                this._locFunction = key => this._options?.locOverride?.get(key) ?? this.localize(key);
            } else {
                this._locFunction = key => this.localize(key);
            }
            this._loadBrushSettings();
        }
        initialize() {
            super.initialize();
            this._blockListMask = this._loadBlockMask(this._blockMaskKey, convertBlockStringsToBlockType([ "air" ]));
            this._blockListReplace = this._loadBlockMask(this._blockReplaceKey, convertBlockStringsToBlockType([ "air" ]));
            if (!this.tool) {
                throw new Error("SharedControl tool is not set");
            }
            const offsetNudgeUpAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._nudgeOffset(lib.VECTOR3_UP);
                }
            });
            const offsetNudgeDownAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._nudgeOffset(lib.VECTOR3_DOWN);
                }
            });
            const offsetNudgeForwardAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Forward);
                    this._nudgeOffset(nudgeVector);
                }
            });
            const offsetNudgeBackAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Back);
                    this._nudgeOffset(nudgeVector);
                }
            });
            const offsetNudgeLeftAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Left);
                    this._nudgeOffset(nudgeVector);
                }
            });
            const offsetNudgeRightAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Right);
                    this._nudgeOffset(nudgeVector);
                }
            });
            this.registerToolKeyBinding(offsetNudgeUpAction, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_UP,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetUp");
            this.registerToolKeyBinding(offsetNudgeDownAction, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_DOWN,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetDown");
            this.registerToolKeyBinding(offsetNudgeForwardAction, {
                key: server_editor_namespaceObject.KeyboardKey.UP,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetForward");
            this.registerToolKeyBinding(offsetNudgeBackAction, {
                key: server_editor_namespaceObject.KeyboardKey.DOWN,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetBack");
            this.registerToolKeyBinding(offsetNudgeLeftAction, {
                key: server_editor_namespaceObject.KeyboardKey.LEFT,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetLeft");
            this.registerToolKeyBinding(offsetNudgeRightAction, {
                key: server_editor_namespaceObject.KeyboardKey.RIGHT,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetRight");
            const cycleMaskAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    switch (this._internalMaskType.value) {
                      case InternalMaskType.Mask:
                        this._internalMaskType.set(InternalMaskType.Replace);
                        break;

                      case InternalMaskType.Disabled:
                        this._internalMaskType.set(InternalMaskType.Mask);
                        break;

                      case InternalMaskType.Replace:
                      default:
                        this._internalMaskType.set(InternalMaskType.Disabled);
                    }
                    this._switchBrushMaskPanes();
                    this._setBrushMask();
                }
            });
            this.registerToolKeyBinding(cycleMaskAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_M
            }, "maskMask");
        }
        shutdown() {
            super.shutdown();
            this._brushControlRootPane = undefined;
            this._brushSettingsSubPane = undefined;
            this._customSettingsSubPane = undefined;
            this._fillConstraintsSubPane = undefined;
            this._fillReplaceSubPane = undefined;
            this._fillMaskSubPane = undefined;
        }
        activateControl() {
            if (this.isActive) {
                this.session.log.error("Cannot activate already active Brush Control");
                return;
            }
            super.activateControl();
            this._brushShapeOffset.set(this.session.extensionContext.brushShapeManager.getBrushShapeOffset());
            this._constructControlUI();
            this._setupBrushModeAndType();
            this._updateSettingsOperationTickHandle = server_namespaceObject.system.runInterval((() => {
                this._runUpdateOperation();
            }), 20);
            this._brushControlRootPane?.show();
            this._setBrushVolume();
            this.activateVisualization();
        }
        deactivateControl() {
            if (!this.isActive) {
                this.session.log.error("Cannot deactivate inactive Brush Control");
                return;
            }
            super.deactivateControl();
            this._needsRefresh = false;
            this.deactivateVisualization();
            this._destroyControlUI();
            if (this._updateSettingsOperationTickHandle !== undefined) {
                server_namespaceObject.system.clearRun(this._updateSettingsOperationTickHandle);
            }
            this._brushControlRootPane?.hide();
        }
        activateVisualization() {
            if (this.isActive) {
                this.session.extensionContext.brushShapeManager.activateBrushTool();
                this._setBrushVolume();
                this._setBrushMask();
                this._switchBrushMaskPanes();
            }
        }
        showVisualization() {
            this.session.extensionContext.brushShapeManager.setBrushShapeVisible(true);
        }
        deactivateVisualization() {
            this.session.extensionContext.brushShapeManager.deactivateBrushTool();
        }
        hideVisualization() {
            this.session.extensionContext.brushShapeManager.setBrushShapeVisible(false);
        }
        switchBrushPaintMode(paintMode) {
            this._brushSettings.paintMode = paintMode;
            this.session.extensionContext.brushShapeManager.switchBrushPaintMode(paintMode);
        }
        updateBrushShapes(shapes) {
            this._brushShapes = shapes;
            if (this._brushShapeDropdown) {
                this._brushShapeDropdown.updateEntries(this._getBrushShapeDropdownEntries());
            }
            if (this.isActive) {
                this._setBrushVolume();
            }
        }
        _setupBrushModeAndType() {
            const paintMode = this._brushSettings.paintMode;
            this.session.extensionContext.brushShapeManager.switchBrushPaintMode(paintMode);
        }
        _destroyControlUI() {
            if (this._brushControlRootPane) {
                this.propertyPane.removeSubPane(this._brushControlRootPane);
                this._brushControlRootPane = undefined;
            }
        }
        _constructControlUI() {
            if (this._brushShapes.length === 0) {
                throw new Error(`${this.controlName} - No brush shapes found`);
            }
            if (this._brushControlRootPane) {
                this._destroyControlUI();
            }
            this._brushControlRootPane = this.propertyPane.createSubPane({
                title: this._locFunction(BrushPaintControlStringKeys.RootPaneTitle),
                infoTooltip: {
                    title: this._locFunction(BrushPaintControlStringKeys.RootPaneTitle),
                    description: [ this._locFunction(BrushPaintControlStringKeys.RootPaneTooltip) ]
                },
                hasMargins: this._options?.hasPaneMargins
            });
            {
                if (this._brushShapes.length > 1) {
                    this._brushShapeDropdown = this._brushControlRootPane.addDropdown(this._selectedBrushIndex, {
                        title: this._locFunction(BrushPaintControlStringKeys.BrushShapeSelectionTitle),
                        tooltip: this._locFunction(BrushPaintControlStringKeys.BrushShapeSelectionTooltip),
                        entries: this._getBrushShapeDropdownEntries(),
                        onChange: () => {
                            this._setBrushVolume();
                            this._updateSettingsSubPane();
                            this._options?.onShapeChange?.(this._getSelectedBrushShape());
                        }
                    });
                } else {
                    this._brushShapeDropdown = undefined;
                }
                this._brushShapeOffset.set(this.session.extensionContext.brushShapeManager.getBrushShapeOffset());
                this._brushControlRootPane.addVector3(this._brushShapeOffset, {
                    title: this._locFunction(BrushPaintControlStringKeys.OffsetTitle),
                    tooltip: this._locFunction(BrushPaintControlStringKeys.OffsetTooltip),
                    isInteger: true,
                    min: BrushPaintSharedControl.MIN_OFFSET,
                    max: BrushPaintSharedControl.MAX_OFFSET,
                    onChange: newValue => {
                        this.session.extensionContext.brushShapeManager.setBrushShapeOffset(newValue);
                    }
                });
            }
            this._brushSettingsSubPane = this._brushControlRootPane.createSubPane({
                title: this._locFunction(BrushPaintControlStringKeys.BrushShapeSettingsTitle),
                infoTooltip: {
                    title: this._locFunction(BrushPaintControlStringKeys.BrushShapeSettingsTitle),
                    description: [ this._locFunction(BrushPaintControlStringKeys.BrushShapeSettingsTooltip) ]
                }
            });
            this._updateSettingsSubPane();
            if (!this._options?.hideFillConstraints) {
                this._fillConstraintsSubPane = this._brushControlRootPane.createSubPane({
                    title: this._locFunction(BrushPaintControlStringKeys.FillConstraintsTitle),
                    infoTooltip: {
                        title: this._locFunction(BrushPaintControlStringKeys.FillConstraintsTitle),
                        description: [ this._locFunction(BrushPaintControlStringKeys.FillConstraintsTooltip) ]
                    }
                });
                this._fillConstraintsSubPane.addToggleGroup(this._internalMaskType, {
                    title: this._locFunction(BrushPaintControlStringKeys.MaskModeTitle),
                    tooltip: this._locFunction(BrushPaintControlStringKeys.MaskModeTooltip),
                    entries: [ {
                        value: InternalMaskType.Disabled,
                        icon: "squareIcon",
                        tooltip: {
                            title: {
                                id: this.localize("fillConstraints.maskMode.disabled"),
                                props: [ getInputMarkup(this.getToolKeyBindingId("maskMask")) ]
                            },
                            description: {
                                id: this.localize("fillConstraints.maskMode.disabled.tooltip"),
                                props: [ newLineMarkup + newLineMarkup, getInputMarkup(this.getToolKeyBindingId("maskMask")) ]
                            }
                        }
                    }, {
                        label: {
                            id: this.localize("fillConstraints.maskMode.mask"),
                            props: [ getInputMarkup(this.getToolKeyBindingId("maskMask")) ]
                        },
                        value: InternalMaskType.Mask,
                        icon: "pack://textures/editor/mask.png",
                        tooltip: {
                            id: this.localize("fillConstraints.maskMode.mask.tooltip"),
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup(this.getToolKeyBindingId("maskMask")) ]
                        }
                    }, {
                        label: {
                            id: this.localize("fillConstraints.maskMode.replace"),
                            props: [ getInputMarkup(this.getToolKeyBindingId("maskMask")) ]
                        },
                        value: InternalMaskType.Replace,
                        icon: "pack://textures/editor/replace.png",
                        tooltip: {
                            id: this.localize("fillConstraints.replace.tooltip"),
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup(this.getToolKeyBindingId("maskMask")) ]
                        }
                    } ],
                    onChange: () => {
                        this._switchBrushMaskPanes();
                        this._setBrushMask();
                    }
                });
                {
                    this._fillReplaceSubPane = this._fillConstraintsSubPane.createSubPane({
                        title: this.localize("fillConstraints.replace.title")
                    });
                    this._blockListReplaceIds.set(convertBlockTypesToBlockStrings(this._blockListReplace));
                    this._fillReplaceSubPane?.addBlockList(this._blockListReplaceIds, {
                        onChange: newVal => {
                            this._blockListReplace = convertBlockStringsToBlockType(newVal);
                            this._setBrushMask();
                            this._saveBlockMasks();
                        }
                    });
                    this._fillReplaceSubPane.hide();
                }
                {
                    this._fillMaskSubPane = this._fillConstraintsSubPane.createSubPane({
                        title: this.localize("fillConstraints.mask.title")
                    });
                    this._blockListMaskIds.set(convertBlockTypesToBlockStrings(this._blockListMask));
                    this._fillMaskSubPane?.addBlockList(this._blockListMaskIds, {
                        onChange: newVal => {
                            this._blockListMask = convertBlockStringsToBlockType(newVal);
                            this._setBrushMask();
                            this._saveBlockMasks();
                        }
                    });
                    this._fillMaskSubPane.hide();
                }
            }
        }
        _getBlockMaskListTypeFromInternalMaskType(internalMaskType) {
            switch (internalMaskType) {
              case InternalMaskType.Mask:
                return server_editor_namespaceObject.BlockMaskListType.Mask;

              case InternalMaskType.Replace:
                return server_editor_namespaceObject.BlockMaskListType.Replace;

              case InternalMaskType.Disabled:
                return server_editor_namespaceObject.BlockMaskListType.Disabled;

              default:
                throw new Error("Invalid internal mask type");
            }
        }
        _getInternalMaskTypeFromBlockMaskListType(blockMaskListType) {
            switch (blockMaskListType) {
              case server_editor_namespaceObject.BlockMaskListType.Mask:
                return InternalMaskType.Mask;

              case server_editor_namespaceObject.BlockMaskListType.Replace:
                return InternalMaskType.Replace;

              case server_editor_namespaceObject.BlockMaskListType.Disabled:
                return InternalMaskType.Disabled;

              default:
                throw new Error("Invalid block mask list type");
            }
        }
        _setBrushMask(mask) {
            if (mask === undefined) {
                mask = {
                    maskType: this._getBlockMaskListTypeFromInternalMaskType(this._internalMaskType.value),
                    blockList: this._internalMaskType.value === InternalMaskType.Mask ? this._blockListMask : this._blockListReplace
                };
            }
            this.session.extensionContext.brushShapeManager.setBrushMask(mask);
        }
        _switchBrushMaskPanes() {
            switch (this._internalMaskType.value) {
              case InternalMaskType.Replace:
                {
                    this._fillConstraintsSubPane?.toggleSubPaneVisibility(this._fillReplaceSubPane?.id);
                    break;
                }

              case InternalMaskType.Mask:
                {
                    this._fillConstraintsSubPane?.toggleSubPaneVisibility(this._fillMaskSubPane?.id);
                    break;
                }

              case InternalMaskType.Disabled:
                {
                    this._fillConstraintsSubPane?.toggleSubPaneVisibility(undefined);
                    break;
                }
            }
        }
        _getSelectedBrushShape() {
            const currentBrushIndex = this._selectedBrushIndex.value;
            if (currentBrushIndex < 0 || currentBrushIndex >= this._brushShapes.length) {
                throw new Error("Invalid brush index");
            }
            return this._brushShapes[currentBrushIndex];
        }
        _clampToMaxBlockVolume(brushShape, maxBlockVolume) {
            const currentBlockCount = brushShape.estimateBlockCount();
            if (currentBlockCount <= maxBlockVolume) {
                return;
            }
            const settings = brushShape.getSettings();
            if (!settings) {
                return;
            }
            const SAFETY_MARGIN = .95;
            const scaleFactor = Math.cbrt(maxBlockVolume / currentBlockCount) * SAFETY_MARGIN;
            const clampDimension = value => Math.max(1, Math.floor(value * scaleFactor));
            const clampedSettings = {
                ...settings
            };
            if ("width" in clampedSettings && typeof clampedSettings.width === "number") {
                clampedSettings.width = clampDimension(clampedSettings.width);
            }
            if ("height" in clampedSettings && typeof clampedSettings.height === "number") {
                clampedSettings.height = clampDimension(clampedSettings.height);
            }
            if ("depth" in clampedSettings && typeof clampedSettings.depth === "number") {
                clampedSettings.depth = clampDimension(clampedSettings.depth);
            }
            if ("radius" in clampedSettings && typeof clampedSettings.radius === "number") {
                clampedSettings.radius = clampDimension(clampedSettings.radius);
            }
            brushShape.applySetting(clampedSettings);
            this._needsRefresh = true;
            const newBlockCount = brushShape.estimateBlockCount();
            this._options?.onVolumeClamped?.(newBlockCount, maxBlockVolume);
        }
        _setBrushVolume() {
            try {
                const brush = this._getSelectedBrushShape();
                this.session.extensionContext.brushShapeManager.setBrushShape(brush.createShape());
            } catch (e) {
                this.session.log.error(`Error updating brush: ${stringFromException(e)}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
        }
        _updateSettingsSubPane() {
            if (!this._brushControlRootPane) {
                this.session.log.debug(`No settings pane`);
                return;
            }
            if (!this._brushSettingsSubPane) {
                this.session.log.debug(`No custom settings pane`);
                return;
            }
            this._brushControlRootPane.hide();
            if (this._customSettingsSubPane) {
                this._brushSettingsSubPane.removeSubPane(this._customSettingsSubPane);
            }
            const brushShape = this._getSelectedBrushShape();
            this._customSettingsSubPane = brushShape.createSettingsPane(this._brushSettingsSubPane, (() => {
                this._needsRefresh = true;
                this._saveBrushSettings();
                if (this._options?.maxBlockVolume) {
                    const currentBlockCount = brushShape.estimateBlockCount();
                    if (currentBlockCount > this._options.maxBlockVolume) {
                        this._clampToMaxBlockVolume(brushShape, this._options.maxBlockVolume);
                    }
                }
                this._options?.onSettingsChange?.(brushShape);
            }));
            this._customSettingsSubPane?.show();
            if (this._customSettingsSubPane) {
                this._brushSettingsSubPane.show();
            } else {
                this._brushSettingsSubPane.hide();
            }
            this._brushControlRootPane.show();
        }
        _runUpdateOperation() {
            if (this.isActive && this._needsRefresh) {
                this._setBrushVolume();
                this._needsRefresh = false;
            }
        }
        _saveBlockMasks() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject
            };
            const group = this._persistenceManager.getOrCreateGroup(PERSISTENCE_GROUP_NAME, option);
            const errorMsg = "Fail to store block mask";
            if (!group) {
                this.session.log.error(errorMsg);
                return;
            } else {
                const maskList = convertBlockTypesToBlockStrings(this._blockListMask);
                const maskListItem = group.getOrCreateItem(this._blockMaskKey, maskList);
                if (maskListItem && maskListItem.value) {
                    maskListItem.commit();
                }
                const replaceList = convertBlockTypesToBlockStrings(this._blockListReplace);
                const replaceListItem = group.getOrCreateItem(this._blockReplaceKey, replaceList);
                if (replaceListItem && replaceListItem.value) {
                    replaceListItem.commit();
                }
                group.dispose();
            }
        }
        _loadBlockMask(key, defaultList) {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject
            };
            const group = this._persistenceManager.getGroup(PERSISTENCE_GROUP_NAME, option);
            const errorMsg = "No stored block mask found";
            if (!group) {
                this.session.log.info(errorMsg);
            } else {
                const storeItem = group.fetchItem(key);
                if (storeItem && storeItem.value) {
                    const blockList = convertBlockStringsToBlockType(storeItem.value);
                    if (blockList.length > 0) {
                        return blockList;
                    }
                }
                group.dispose();
            }
            return defaultList;
        }
        _getRelativeNudgeDirection(direction) {
            const rotationY = this.session.extensionContext.player.getRotation().y;
            const rotationCorrectedVector = getRotationCorrectedDirectionVector(rotationY, direction);
            return rotationCorrectedVector;
        }
        _nudgeOffset(nudgeVector) {
            let update = lib.Vector3Utils.add(this._brushShapeOffset.value, nudgeVector);
            update = lib.Vector3Utils.clamp(update, {
                min: BrushPaintSharedControl.MIN_OFFSET,
                max: BrushPaintSharedControl.MAX_OFFSET
            });
            this._brushShapeOffset.set(update);
            this.session.extensionContext.brushShapeManager.setBrushShapeOffset(update);
        }
        _getBrushShapeDropdownEntries() {
            return this._brushShapes.map(((brush, index) => {
                const item = {
                    label: brush.displayName,
                    value: index,
                    imageData: {
                        path: brush.icon,
                        type: server_editor_namespaceObject.ImageResourceType.Icon
                    }
                };
                return item;
            }));
        }
        _loadBrushSettings() {
            this._brushShapes.map((brushShape => {
                const option = {
                    scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject
                };
                const group = this._persistenceManager.getGroup(PERSISTENCE_GROUP_NAME, option);
                if (!group) {
                    return;
                }
                const key = `${this.tool.id}.${brushShape.id}.${PERSISTENCE_GROUPITEM_SETTINGS}`;
                try {
                    switch (brushShape.id) {
                      case server_editor_namespaceObject.CoreBrushShapeType.Cone:
                        {
                            const item = group.fetchItem(key);
                            if (item && item.value) {
                                brushShape.applySetting(item.value);
                            }
                        }
                        break;

                      case server_editor_namespaceObject.CoreBrushShapeType.Cuboid:
                        {
                            const item = group.fetchItem(key);
                            if (item && item.value) {
                                brushShape.applySetting(item.value);
                            }
                        }
                        break;

                      case server_editor_namespaceObject.CoreBrushShapeType.Cylinder:
                        {
                            const item = group.fetchItem(key);
                            if (item && item.value) {
                                brushShape.applySetting(item.value);
                            }
                        }
                        break;

                      case server_editor_namespaceObject.CoreBrushShapeType.Ellipsoid:
                        {
                            const item = group.fetchItem(key);
                            if (item && item.value) {
                                brushShape.applySetting(item.value);
                            }
                        }
                        break;

                      case server_editor_namespaceObject.CoreBrushShapeType.Pyramid:
                        {
                            const item = group.fetchItem(key);
                            if (item && item.value) {
                                brushShape.applySetting(item.value);
                            }
                        }
                        break;

                      case server_editor_namespaceObject.CoreBrushShapeType.SingleBlock:
                        break;
                    }
                } catch (e) {
                    this.session.log.error(`Failed to load brush settings, ${stringFromException(e)}`);
                }
                group.dispose();
            }));
        }
        _saveBrushSettings() {
            const brushShape = this._getSelectedBrushShape();
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject
            };
            const group = this._persistenceManager.getOrCreateGroup(PERSISTENCE_GROUP_NAME, option);
            if (!group) {
                this.session.log.error(`Failed to save brush settings of ${brushShape.displayName}`);
                return;
            }
            const key = `${this.tool.id}.${brushShape.id}.${PERSISTENCE_GROUPITEM_SETTINGS}`;
            const item = group.getOrCreateItem(key, brushShape.getSettings());
            if (item && item.value) {
                item.commit();
            }
            group.dispose();
        }
    }
    BrushPaintSharedControl.DEFAULT_NUMBER_MIN = 1;
    BrushPaintSharedControl.DEFAULT_NUMBER_MAX = 6;
    BrushPaintSharedControl.MIN_OFFSET = {
        x: -20,
        y: -20,
        z: -20
    };
    BrushPaintSharedControl.MAX_OFFSET = {
        x: 20,
        y: 20,
        z: 20
    };
    const CursorModeControl_PERSISTENCE_GROUP_NAME = "editor:cursor";
    const PERSISTENCE_GROUPITEM_NAME = "cursor_settings";
    const PROPERTY_CURSORMODECONTROL_NAME = "CursorModeControl";
    const PROPERTY_CURSORMODECONTROL_LOCALIZATION_PREFIX = `resourcePack.editor.${PROPERTY_CURSORMODECONTROL_NAME}`;
    const KEY_REPEAT_DELAY = 5;
    const KEY_REPEAT_INTERVAL = 1;
    class CursorModeControl extends SharedControlImpl {
        get cursorProperties() {
            const props = {
                ...this._overrideCursorProperties,
                controlMode: this._mouseControlMode.value,
                targetMode: this._cursorTargetMode.value,
                fixedModeDistance: this._fixedDistanceCursor.value
            };
            return props;
        }
        constructor(_session, _parentTool, _parentPropertyPane, _bindManualInput, _overrideCursorProperties, _options) {
            super(_session, _parentTool, _parentPropertyPane, PROPERTY_CURSORMODECONTROL_NAME, PROPERTY_CURSORMODECONTROL_LOCALIZATION_PREFIX);
            this._options = _options;
            this._controlRootPane = undefined;
            this._mouseControlMode = (0, server_editor_namespaceObject.makeObservable)(server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse);
            this._cursorTargetMode = (0, server_editor_namespaceObject.makeObservable)(server_editor_namespaceObject.CursorTargetMode.Block);
            this._projectThroughWater = (0, server_editor_namespaceObject.makeObservable)(true);
            this._fixedDistanceCursor = (0, server_editor_namespaceObject.makeObservable)(5);
            this._canMoveManually = () => true;
            this._updateCursorProperties = (session, isActivationUpdate, cursorControlMode, cursorTargetMode, fixedDistanceValue, fixedDistanceSliderControl, isSaveSettings = true) => {
                const cursorProperties = {
                    ...this._overrideCursorProperties,
                    controlMode: cursorControlMode,
                    targetMode: cursorTargetMode,
                    fixedModeDistance: fixedDistanceValue
                };
                if (fixedDistanceSliderControl) {
                    fixedDistanceSliderControl.visible = cursorControlMode === server_editor_namespaceObject.CursorControlMode.Fixed;
                }
                if (cursorControlMode === server_editor_namespaceObject.CursorControlMode.Keyboard) {
                    this.session.toolRail.focusToolInputContext();
                }
                if (this._projectThroughWaterCheckbox) {
                    this._projectThroughWaterCheckbox.visible = cursorControlMode === server_editor_namespaceObject.CursorControlMode.Mouse || cursorControlMode === server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse;
                }
                if (isActivationUpdate) {
                    session.extensionContext.cursor.pushPropertiesById(cursorProperties, this.tool.id);
                } else {
                    session.extensionContext.cursor.updatePropertiesById(cursorProperties, this.tool.id);
                }
                this._cachedCursorProperties = cursorProperties;
                if (isSaveSettings) {
                    this._saveSettings(cursorProperties);
                }
            };
            this._persistenceManager = getPersistenceManager(_session.extensionContext.player);
            this._bindManualInput = _bindManualInput ?? true;
            const savedCursorProperties = this._loadSettings();
            this._overrideCursorProperties = {
                ..._overrideCursorProperties
            };
            this._cachedCursorProperties = this._overrideCursorProperties;
            if (savedCursorProperties) {
                delete savedCursorProperties.projectThroughLiquid;
                this._cachedCursorProperties = savedCursorProperties;
            }
            const currentCursorProperties = _overrideCursorProperties ?? this.session.extensionContext.cursor.getDefaultProperties();
            this._projectThroughWater.set(currentCursorProperties.projectThroughLiquid ?? true);
            this._mouseControlMode.set(this._cachedCursorProperties.controlMode ?? server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse);
            this._cursorTargetMode.set(this._cachedCursorProperties.targetMode ?? server_editor_namespaceObject.CursorTargetMode.Block);
            this._fixedDistanceCursor.set(this._cachedCursorProperties.fixedModeDistance ?? 5);
            currentCursorProperties.visible = true;
        }
        bindMovementFunctions(canMove, moveForward, moveBack, moveLeft, moveRight, moveUp, moveDown) {
            this._canMoveManually = canMove ?? this._canMoveManually;
            this._moveForward = moveForward;
            this._moveBack = moveBack;
            this._moveLeft = moveLeft;
            this._moveRight = moveRight;
            this._moveUp = moveUp;
            this._moveDown = moveDown;
        }
        initialize() {
            super.initialize();
            this.tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    const savedCursorProperties = this._cachedCursorProperties;
                    if (savedCursorProperties) {
                        if (savedCursorProperties.controlMode) {
                            this._mouseControlMode.set(savedCursorProperties.controlMode);
                        }
                        if (savedCursorProperties.targetMode) {
                            this._cursorTargetMode.set(savedCursorProperties.targetMode);
                        }
                        if (savedCursorProperties.fixedModeDistance) {
                            this._fixedDistanceCursor.set(savedCursorProperties.fixedModeDistance);
                        }
                    }
                    this._updateCursorProperties(this.session, true, this._mouseControlMode.value, this._cursorTargetMode.value, this._fixedDistanceCursor.value, this._fixedDistanceSliderControl, false);
                } else {
                    this.session.extensionContext.cursor.popPropertiesById(this.tool.id);
                }
            }));
            if (this._bindManualInput) {
                const _moveBlockCursorManually = (_session, _direction) => {
                    const rotationY = _session.extensionContext.player.getRotation().y;
                    const rotationCorrectedVector = getRotationCorrectedDirectionVector(rotationY, _direction);
                    _session.extensionContext.cursor.moveBy(rotationCorrectedVector);
                };
                const keyUpAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            return;
                        }
                        if (this._canMoveManually()) {
                            this.session.extensionContext.cursor.moveBy(lib.VECTOR3_UP);
                            if (this._moveUp) {
                                this._moveUp();
                            }
                        }
                    },
                    repeatInterval: KEY_REPEAT_INTERVAL,
                    repeatDelay: KEY_REPEAT_DELAY
                });
                const keyDownAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            return;
                        }
                        if (this._canMoveManually()) {
                            this.session.extensionContext.cursor.moveBy(lib.VECTOR3_DOWN);
                            if (this._moveDown) {
                                this._moveDown();
                            }
                        }
                    },
                    repeatInterval: KEY_REPEAT_INTERVAL,
                    repeatDelay: KEY_REPEAT_DELAY
                });
                const keyLeftAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            return;
                        }
                        if (this._canMoveManually()) {
                            _moveBlockCursorManually(this.session, direction_Direction.Left);
                            if (this._moveLeft) {
                                this._moveLeft();
                            }
                        }
                    },
                    repeatInterval: KEY_REPEAT_INTERVAL,
                    repeatDelay: KEY_REPEAT_DELAY
                });
                const keyRightAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            return;
                        }
                        if (this._canMoveManually()) {
                            _moveBlockCursorManually(this.session, direction_Direction.Right);
                            if (this._moveRight) {
                                this._moveRight();
                            }
                        }
                    },
                    repeatInterval: KEY_REPEAT_INTERVAL,
                    repeatDelay: KEY_REPEAT_DELAY
                });
                const keyForwardAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            return;
                        }
                        if (this._canMoveManually()) {
                            _moveBlockCursorManually(this.session, direction_Direction.Forward);
                            if (this._moveForward) {
                                this._moveForward();
                            }
                        }
                    },
                    repeatInterval: KEY_REPEAT_INTERVAL,
                    repeatDelay: KEY_REPEAT_DELAY
                });
                const keyBackAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            return;
                        }
                        if (this._canMoveManually()) {
                            _moveBlockCursorManually(this.session, direction_Direction.Back);
                            if (this._moveBack) {
                                this._moveBack();
                            }
                        }
                    },
                    repeatInterval: KEY_REPEAT_INTERVAL,
                    repeatDelay: KEY_REPEAT_DELAY
                });
                this.registerToolKeyBinding(keyForwardAction, {
                    key: server_editor_namespaceObject.KeyboardKey.UP
                }, "moveCursorForward");
                this.registerToolKeyBinding(keyBackAction, {
                    key: server_editor_namespaceObject.KeyboardKey.DOWN
                }, "moveCursorBack");
                this.registerToolKeyBinding(keyLeftAction, {
                    key: server_editor_namespaceObject.KeyboardKey.LEFT
                }, "moveCursorLeft");
                this.registerToolKeyBinding(keyRightAction, {
                    key: server_editor_namespaceObject.KeyboardKey.RIGHT
                }, "moveCursorRight");
                this.registerToolKeyBinding(keyUpAction, {
                    key: server_editor_namespaceObject.KeyboardKey.PAGE_UP
                }, "moveCursorUp");
                this.registerToolKeyBinding(keyDownAction, {
                    key: server_editor_namespaceObject.KeyboardKey.PAGE_DOWN
                }, "moveCursorDown");
                {
                    const keyToggleMouseControlModeAction = this.session.actionManager.createAction({
                        actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                        onExecute: () => {
                            const currentMode = this._mouseControlMode.value;
                            let newMode = server_editor_namespaceObject.CursorControlMode.Fixed;
                            switch (currentMode) {
                              case server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse:
                                newMode = server_editor_namespaceObject.CursorControlMode.Fixed;
                                break;

                              case server_editor_namespaceObject.CursorControlMode.Fixed:
                                newMode = server_editor_namespaceObject.CursorControlMode.Keyboard;
                                break;

                              case server_editor_namespaceObject.CursorControlMode.Keyboard:
                              default:
                                newMode = server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse;
                            }
                            this._mouseControlMode.set(newMode);
                            this._updateCursorProperties(this.session, false, this._mouseControlMode.value, this._cursorTargetMode.value, this._fixedDistanceCursor.value, this._fixedDistanceSliderControl);
                        }
                    });
                    this.registerToolKeyBinding(keyToggleMouseControlModeAction, {
                        key: server_editor_namespaceObject.KeyboardKey.KEY_T
                    }, "toggleMouseTracking");
                }
                const mouseWheelAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                    onExecute: (mouseRay, mouseProps) => {
                        if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.WheelOut && mouseProps.modifiers.shift) {
                            if (this._mouseControlMode.value === server_editor_namespaceObject.CursorControlMode.Fixed) {
                                let currentDistance = this._fixedDistanceCursor.value;
                                if (mouseProps.modifiers.shift) {
                                    currentDistance += 5;
                                } else {
                                    currentDistance += 1;
                                }
                                if (currentDistance > CursorModeControl.MAX_FIXED_DISTANCE) {
                                    currentDistance = CursorModeControl.MAX_FIXED_DISTANCE;
                                }
                                this._fixedDistanceCursor.set(currentDistance);
                                this._updateCursorProperties(this.session, false, this._mouseControlMode.value, this._cursorTargetMode.value, this._fixedDistanceCursor.value, this._fixedDistanceSliderControl);
                            }
                        } else if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.WheelIn && mouseProps.modifiers.shift) {
                            if (this._mouseControlMode.value === server_editor_namespaceObject.CursorControlMode.Fixed) {
                                let currentDistance = this._fixedDistanceCursor.value;
                                if (mouseProps.modifiers.shift) {
                                    currentDistance -= 5;
                                } else {
                                    currentDistance -= 1;
                                }
                                if (currentDistance < CursorModeControl.MIN_FIXED_DISTANCE) {
                                    currentDistance = CursorModeControl.MIN_FIXED_DISTANCE;
                                }
                                this._fixedDistanceCursor.set(currentDistance);
                                this._updateCursorProperties(this.session, false, this._mouseControlMode.value, this._cursorTargetMode.value, this._fixedDistanceCursor.value, this._fixedDistanceSliderControl);
                            }
                        }
                    }
                });
                this.tool.registerMouseWheelBinding(mouseWheelAction);
            }
            {
                const keyToggleTargetModeAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        const currentMode = this._cursorTargetMode.value;
                        const newMode = currentMode === server_editor_namespaceObject.CursorTargetMode.Block ? server_editor_namespaceObject.CursorTargetMode.Face : server_editor_namespaceObject.CursorTargetMode.Block;
                        this._cursorTargetMode.set(newMode);
                        this._updateCursorProperties(this.session, false, this._mouseControlMode.value, this._cursorTargetMode.value, this._fixedDistanceCursor.value, this._fixedDistanceSliderControl);
                    }
                });
                this.registerToolKeyBinding(keyToggleTargetModeAction, {
                    key: server_editor_namespaceObject.KeyboardKey.KEY_B
                }, "toggleBlockTargetMode");
            }
        }
        shutdown() {
            super.shutdown();
            if (this._cursorPropertyEventSub) {
                this.session.extensionContext.afterEvents.cursorPropertyChange.unsubscribe(this._cursorPropertyEventSub);
            }
        }
        activateControl() {
            super.activateControl();
            this._constructControlUI();
        }
        deactivateControl() {
            super.deactivateControl();
            this._destroyControlUI();
        }
        forceTargetMode(value) {
            this._cursorTargetMode.set(value);
            this._updateCursorProperties(this.session, false, this._mouseControlMode.value, value, this._fixedDistanceCursor.value, this._fixedDistanceSliderControl);
        }
        _destroyControlUI() {
            if (this._controlRootPane) {
                this.propertyPane.removeSubPane(this._controlRootPane);
                this._controlRootPane = undefined;
            }
        }
        _constructControlUI() {
            if (this._controlRootPane) {
                this._destroyControlUI();
            }
            this._controlRootPane = this.propertyPane.createSubPane({
                title: this.localize("rootPane.title"),
                infoTooltip: {
                    title: this.localize("rootPane.title"),
                    description: [ this.localize("rootPane.tooltip") ]
                },
                hasMargins: this._options?.hasPaneMargins
            });
            {
                this._controlRootPane.addDropdown(this._mouseControlMode, {
                    title: this.localize("mouseControlMode.title"),
                    tooltip: {
                        title: {
                            id: this.localize("mouseControlMode.tooltip.title"),
                            props: [ getInputMarkup(this.getToolKeyBindingId("toggleMouseTracking")) ]
                        },
                        description: {
                            id: this.localize("mouseControlMode.tooltip"),
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup(this.getToolKeyBindingId("toggleMouseTracking")) ]
                        }
                    },
                    entries: [ {
                        label: this.localize("mouseControlMode.keyboard"),
                        value: server_editor_namespaceObject.CursorControlMode.Keyboard
                    }, {
                        label: this.localize("mouseControlMode.keyboardAndMouse"),
                        value: server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse
                    }, {
                        label: this.localize("mouseControlMode.fixed"),
                        value: server_editor_namespaceObject.CursorControlMode.Fixed
                    } ],
                    onChange: () => {
                        this._updateCursorProperties(this.session, false, this._mouseControlMode.value, this._cursorTargetMode.value, this._fixedDistanceCursor.value, this._fixedDistanceSliderControl);
                    }
                });
                this._mouseControlMode.set(this._cachedCursorProperties.controlMode ?? server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse);
                this._cursorTargetMode.set(this._cachedCursorProperties.targetMode ?? server_editor_namespaceObject.CursorTargetMode.Block);
                this._fixedDistanceCursor.set(this._cachedCursorProperties.fixedModeDistance ?? 5);
                const fixedDistanceSliderVisible = this._cachedCursorProperties.controlMode === server_editor_namespaceObject.CursorControlMode.Fixed;
                this._fixedDistanceSliderControl = this._controlRootPane.addNumber(this._fixedDistanceCursor, {
                    visible: fixedDistanceSliderVisible,
                    isInteger: true,
                    min: CursorModeControl.MIN_FIXED_DISTANCE,
                    max: CursorModeControl.MAX_FIXED_DISTANCE,
                    title: this.localize("fixedDistance.slider.title"),
                    tooltip: this.localize("fixedDistance.slider.tooltip"),
                    variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                    onChange: () => {
                        this._updateCursorProperties(this.session, false, this._mouseControlMode.value, this._cursorTargetMode.value, this._fixedDistanceCursor.value, this._fixedDistanceSliderControl);
                    }
                });
                this.session.extensionContext.afterEvents.cursorPropertyChange.subscribe((_event => {
                    if (_event.properties.fixedModeDistance !== undefined && _event.properties.fixedModeDistance !== this._fixedDistanceCursor.value) {
                        this._fixedDistanceCursor.set(_event.properties.fixedModeDistance);
                    }
                }));
            }
            {
                this._controlRootPane.addToggleGroup(this._cursorTargetMode, {
                    title: this.localize("cursorTargetMode.title"),
                    tooltip: {
                        title: {
                            id: this.localize("cursorTargetMode.tooltip.title"),
                            props: [ getInputMarkup(this.getToolKeyBindingId("toggleBlockTargetMode")) ]
                        },
                        description: {
                            id: this.localize("cursorTargetMode.tooltip"),
                            props: [ getInputMarkup(this.getToolKeyBindingId("toggleBlockTargetMode")) ]
                        }
                    },
                    entries: [ {
                        tooltip: {
                            title: {
                                id: this.localize("cursorTargetMode.block"),
                                props: [ getInputMarkup(this.getToolKeyBindingId("toggleBlockTargetMode")) ]
                            },
                            description: {
                                id: this.localize("cursorTargetMode.block.tooltip"),
                                props: [ newLineMarkup + newLineMarkup, getInputMarkup(this.getToolKeyBindingId("toggleBlockTargetMode")) ]
                            }
                        },
                        value: server_editor_namespaceObject.CursorTargetMode.Block,
                        icon: "pack://textures/editor/block-mode.png"
                    }, {
                        tooltip: {
                            title: {
                                id: this.localize("cursorTargetMode.face"),
                                props: [ getInputMarkup(this.getToolKeyBindingId("toggleBlockTargetMode")) ]
                            },
                            description: {
                                id: this.localize("cursorTargetMode.face.tooltip"),
                                props: [ newLineMarkup + newLineMarkup, getInputMarkup(this.getToolKeyBindingId("toggleBlockTargetMode")) ]
                            }
                        },
                        value: server_editor_namespaceObject.CursorTargetMode.Face,
                        icon: "pack://textures/editor/face-mode.png"
                    } ],
                    onChange: () => {
                        this._updateCursorProperties(this.session, false, this._mouseControlMode.value, this._cursorTargetMode.value, this._fixedDistanceCursor.value, this._fixedDistanceSliderControl);
                    }
                });
            }
            {
                this._projectThroughWaterCheckbox = this._controlRootPane.addBool(this._projectThroughWater, {
                    title: this.localize("projectThroughWater.title"),
                    tooltip: this.localize("projectThroughWater.tooltip"),
                    visible: this._mouseControlMode.value === server_editor_namespaceObject.CursorControlMode.Mouse || this._mouseControlMode.value === server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse,
                    onChange: () => {
                        const cursorProperties = {
                            projectThroughLiquid: this._projectThroughWater.value
                        };
                        this.session.extensionContext.cursor.updatePropertiesById(cursorProperties, this.tool.id);
                    }
                });
                this._cursorPropertyEventSub = this.session.extensionContext.afterEvents.cursorPropertyChange.subscribe((event => {
                    if (event.properties.projectThroughLiquid !== undefined) {
                        this._projectThroughWater.set(event.properties.projectThroughLiquid);
                    }
                }));
            }
        }
        _loadSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(CursorModeControl_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const key = `${this.tool.id}_${PERSISTENCE_GROUPITEM_NAME}`;
                const storeItem = group.fetchItem(key);
                if (storeItem && storeItem.value) {
                    return storeItem.value;
                }
                group.dispose();
            }
            return undefined;
        }
        _saveSettings(settings) {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(CursorModeControl_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const key = `${this.tool.id}_${PERSISTENCE_GROUPITEM_NAME}`;
                const storeItem = group.getOrCreateItem(key, settings);
                if (storeItem) {
                    storeItem.commit();
                }
                group.dispose();
                return;
            }
        }
    }
    CursorModeControl.MAX_FIXED_DISTANCE = 32;
    CursorModeControl.MIN_FIXED_DISTANCE = 1;
    const gameModeLookUpIndex = {
        Survival: 0,
        Creative: 1,
        Adventure: 2,
        Spectator: 6
    };
    const difficultyLookUpIndex = {
        [server_namespaceObject.Difficulty.Peaceful]: 0,
        [server_namespaceObject.Difficulty.Easy]: 1,
        [server_namespaceObject.Difficulty.Normal]: 2,
        [server_namespaceObject.Difficulty.Hard]: 3
    };
    function getDifficultyByValue(value) {
        return Object.keys(difficultyLookUpIndex).find((key => difficultyLookUpIndex[key] === value));
    }
    const gameModeDropDownItems = [ {
        label: "resourcePack.editor.exportProject.gameMode.survival",
        value: gameModeLookUpIndex[server_namespaceObject.GameMode.Survival]
    }, {
        label: "resourcePack.editor.exportProject.gameMode.creative",
        value: gameModeLookUpIndex[server_namespaceObject.GameMode.Creative]
    }, {
        label: "resourcePack.editor.exportProject.gameMode.adventure",
        value: gameModeLookUpIndex[server_namespaceObject.GameMode.Adventure]
    } ];
    const validGameModes = [ server_namespaceObject.GameMode.Survival, server_namespaceObject.GameMode.Creative, server_namespaceObject.GameMode.Adventure ];
    const difficultyLocalization = {
        [server_namespaceObject.Difficulty.Peaceful]: "resourcePack.editor.exportProject.difficulty.peaceful",
        [server_namespaceObject.Difficulty.Easy]: "resourcePack.editor.exportProject.difficulty.easy",
        [server_namespaceObject.Difficulty.Normal]: "resourcePack.editor.exportProject.difficulty.normal",
        [server_namespaceObject.Difficulty.Hard]: "resourcePack.editor.exportProject.difficulty.hard"
    };
    const difficultyDropDownItems = [ {
        label: difficultyLocalization[server_namespaceObject.Difficulty.Peaceful],
        value: difficultyLookUpIndex[server_namespaceObject.Difficulty.Peaceful]
    }, {
        label: difficultyLocalization[server_namespaceObject.Difficulty.Easy],
        value: difficultyLookUpIndex[server_namespaceObject.Difficulty.Easy]
    }, {
        label: difficultyLocalization[server_namespaceObject.Difficulty.Normal],
        value: difficultyLookUpIndex[server_namespaceObject.Difficulty.Normal]
    }, {
        label: difficultyLocalization[server_namespaceObject.Difficulty.Hard],
        value: difficultyLookUpIndex[server_namespaceObject.Difficulty.Hard]
    } ];
    var Weather;
    (function(Weather) {
        Weather[Weather["Default"] = -1] = "Default";
        Weather[Weather["Clear"] = 0] = "Clear";
        Weather[Weather["Rain"] = 1] = "Rain";
        Weather[Weather["Thunder"] = 2] = "Thunder";
    })(Weather || (Weather = {}));
    const weatherDropdownItems = [ {
        label: "resourcePack.editor.exportProject.weather.default",
        value: Weather.Default
    }, {
        label: "resourcePack.editor.exportProject.weather.clear",
        value: Weather.Clear
    }, {
        label: "resourcePack.editor.exportProject.weather.rain",
        value: Weather.Rain
    }, {
        label: "resourcePack.editor.exportProject.weather.thunder",
        value: Weather.Thunder
    } ];
    const validPlayerAccess = [ server_editor_namespaceObject.GamePublishSetting.InviteOnly, server_editor_namespaceObject.GamePublishSetting.FriendsOnly, server_editor_namespaceObject.GamePublishSetting.FriendsOfFriends ];
    const playerAccessLocalization = {
        [server_editor_namespaceObject.GamePublishSetting.FriendsOfFriends]: "resourcePack.editor.exportProject.multiplayerSettings.playerAccess.friendsOfFriends",
        [server_editor_namespaceObject.GamePublishSetting.FriendsOnly]: "resourcePack.editor.exportProject.multiplayerSettings.playerAccess.friendsOnly",
        [server_editor_namespaceObject.GamePublishSetting.InviteOnly]: "resourcePack.editor.exportProject.multiplayerSettings.playerAccess.inviteOnly",
        [server_editor_namespaceObject.GamePublishSetting.Public]: "Public",
        [server_editor_namespaceObject.GamePublishSetting.NoMultiPlay]: "NoMultiPlay"
    };
    const validPlayerPermissionLevels = [ server_namespaceObject.PlayerPermissionLevel.Visitor, server_namespaceObject.PlayerPermissionLevel.Member, server_namespaceObject.PlayerPermissionLevel.Operator, server_namespaceObject.PlayerPermissionLevel.Custom ];
    const playerPermissionLocalization = {
        [server_namespaceObject.PlayerPermissionLevel.Visitor]: "resourcePack.editor.exportProject.multiplayerSettings.playerPermissions.visitor",
        [server_namespaceObject.PlayerPermissionLevel.Member]: "resourcePack.editor.exportProject.multiplayerSettings.playerPermissions.member",
        [server_namespaceObject.PlayerPermissionLevel.Operator]: "resourcePack.editor.exportProject.multiplayerSettings.playerPermissions.operator",
        [server_namespaceObject.PlayerPermissionLevel.Custom]: "resourcePack.editor.exportProject.multiplayerSettings.playerPermissions.custom"
    };
    const validDaylightCycle = [ server_editor_namespaceObject.DaylightCycle.Normal, server_editor_namespaceObject.DaylightCycle.AlwaysDay, server_editor_namespaceObject.DaylightCycle.LockTime ];
    const daylightCycleLocalization = {
        [server_editor_namespaceObject.DaylightCycle.AlwaysDay]: "resourcePack.editor.exportProject.cheatsSettings.daylightCycle.alwaysDay",
        [server_editor_namespaceObject.DaylightCycle.LockTime]: "resourcePack.editor.exportProject.cheatsSettings.daylightCycle.lockTime",
        [server_editor_namespaceObject.DaylightCycle.Normal]: "resourcePack.editor.exportProject.cheatsSettings.daylightCycle.normal"
    };
    const MAX_ACTOR_COMMAND_COORDINATE = 3e7;
    class WorldSettingsPane {
        constructor(_uiSession, parentPane, includeMultiplayer, exportOnly = true) {
            this._uiSession = _uiSession;
            this._clockType = (0, server_editor_namespaceObject.makeObservable)(ClockType.MINECRAFT_CLOCK);
            this._currentStartTime = (0, server_editor_namespaceObject.makeObservable)(TODDropDown.None);
            this._timeOfDayTimeString = (0, server_editor_namespaceObject.makeObservable)(convertTODToTime(0, false));
            this._cheatItems = new Map;
            this._multiplayerPropertyItems = [];
            this._nonHardCorePropertyItems = [];
            this._lastCheatsValues = new Map;
            this._includeMultiplayer = includeMultiplayer;
            this._exportOnly = exportOnly;
            const gameOptions = this._uiSession.extensionContext.exportManager.getGameOptions();
            this._defaultGameOptions = this._uiSession.extensionContext.exportManager.getGameOptions(true);
            this._defaultGameOptions.worldName = gameOptions.worldName;
            this._defaultGameOptions.spawnPosition = gameOptions.spawnPosition;
            this._worldSettingsPaneData = Object.entries(gameOptions).reduce(((data, [key, value]) => {
                const optKey = key;
                switch (optKey) {
                  case "gameMode":
                    data["gameMode"] = (0, server_editor_namespaceObject.makeObservable)(gameModeLookUpIndex[gameOptions["gameMode"]]);
                    break;

                  case "difficulty":
                    data["difficulty"] = (0, server_editor_namespaceObject.makeObservable)(difficultyLookUpIndex[gameOptions["difficulty"]]);
                    break;

                  default:
                    data[optKey] = (0, server_editor_namespaceObject.makeObservable)(value);
                }
                return data;
            }), {});
            this._currentGameModeDropdownItems = this._getGameModeDropdownItems(gameOptions.hardcore);
            this._currentDifficultyDropDownItems = this._getDifficultyDropdownItems(gameOptions.hardcore);
            this._lastDifficultyIndex = !gameOptions.hardcore ? difficultyLookUpIndex[gameOptions.difficulty] : 0;
            this._lastGameModeIndex = gameModeLookUpIndex[gameOptions.gameMode];
            this._lastStartingMap = this._worldSettingsPaneData.startingMap.value;
            this._lastBonusChest = this._worldSettingsPaneData.bonusChest.value;
            this._lastCheatsEnabled = this._worldSettingsPaneData.cheats.value;
            this._parentPane = parentPane;
            this._spawnPosition = this._worldSettingsPaneData.spawnPosition.value;
            this._weatherIndex = this._worldSettingsPaneData.weather.value;
            this._uiSession.eventSubscriptionCache.subscribeToBedrockEvent("playerDimensionChange", (event => {
                if (this._usePlayerAsSpawnPointPropItem && event.player.id === this._uiSession.extensionContext.player.id) {
                    this._usePlayerAsSpawnPointPropItem.enable = this._isPlayerAsSpawnPointPropItemEnabled(event.toDimension);
                }
            }));
        }
        setToDefaultGameOptions() {
            const prevHardcore = this._worldSettingsPaneData.hardcore.value;
            Object.entries(this._defaultGameOptions).forEach((([key, value]) => {
                const optKey = key;
                switch (optKey) {
                  case "gameMode":
                    this._worldSettingsPaneData["gameMode"].set(gameModeLookUpIndex[this._defaultGameOptions["gameMode"]]);
                    break;

                  case "difficulty":
                    this._worldSettingsPaneData["difficulty"].set(difficultyLookUpIndex[this._defaultGameOptions["difficulty"]]);
                    break;

                  default:
                    this._worldSettingsPaneData[optKey].set(value);
                }
            }));
            this._setToDefaultInitialPayOptions();
            this._setToDefaultCheatOptions(this._defaultGameOptions.cheats);
            if (this._includeMultiplayer) {
                this._setMultiplayerOptionsEnableState(this._defaultGameOptions.multiplayerGame);
            }
            if (prevHardcore !== this._defaultGameOptions.hardcore) {
                this._onHardcoreChanged(this._defaultGameOptions.hardcore, this._worldSettingsPaneData.gameMode.value, difficultyLookUpIndex[this._defaultGameOptions.difficulty]);
            }
            if (this._sleepSkipPercentPropItem) {
                this._sleepSkipPercentPropItem.enable = this._worldSettingsPaneData.bedsWork.value;
                this._sleepSkipPercentPropItem.setTitle(`Required Sleeping players (${this._worldSettingsPaneData.sleepSkipPercent.value}%%)`);
            }
        }
        getGameOptions() {
            const options = Object.entries(this._worldSettingsPaneData).reduce(((data, [key, observable]) => {
                const optKey = key;
                switch (optKey) {
                  case "gameMode":
                    data["gameMode"] = validGameModes[this._worldSettingsPaneData["gameMode"].value];
                    break;

                  case "disableWeather":
                    data["disableWeather"] = !this._worldSettingsPaneData["disableWeather"].value;
                    break;

                  case "difficulty":
                    data["difficulty"] = getDifficultyByValue(this._worldSettingsPaneData["difficulty"].value);
                    break;

                  case "weather":
                    if (this._worldSettingsPaneData["weather"].value === Weather.Default) {
                        const overworldWeather = server_namespaceObject.world.getDimension(MinecraftDimensionTypes.Overworld).getWeather();
                        data["weather"] = Weather[overworldWeather];
                    } else {
                        data["weather"] = this._worldSettingsPaneData["weather"].value;
                    }
                    break;

                  default:
                    data[key] = observable.value;
                }
                return data;
            }), {});
            return options;
        }
        getObservablePaneElements() {
            return this._worldSettingsPaneData;
        }
        BuildPropertyPane() {
            this._buildGeneralSectionOfPane();
            this._buildInitialPlaySectionOfPane();
            this._buildAdvancedSectionOfPane();
            if (this._includeMultiplayer) {
                this._buildMultiplayerSectionOfPane();
            }
            this._buildCheatSectionOfPane();
        }
        _buildGeneralSectionOfPane() {
            const generalSettingsPane = this._parentPane.createSubPane({
                title: `resourcePack.editor.exportProject.generalSettings`,
                collapsed: true,
                infoTooltip: {
                    title: `resourcePack.editor.exportProject.generalSettings`,
                    description: [ "resourcePack.editor.exportProject.generalSettings.tooltip" ]
                }
            });
            generalSettingsPane.beginConstruct();
            generalSettingsPane.addString(this._worldSettingsPaneData.worldName, {
                title: `resourcePack.editor.exportProject.generalSettings.worldName`,
                tooltip: `resourcePack.editor.exportProject.generalSettings.worldName.tooltip`
            });
            this._gameModePropertyItem = generalSettingsPane.addDropdown(this._worldSettingsPaneData.gameMode, {
                title: "resourcePack.editor.exportProject.generalSettings.gameMode",
                tooltip: "resourcePack.editor.exportProject.generalSettings.gameMode.tooltip",
                entries: this._currentGameModeDropdownItems
            });
            this._difficultyPropertyItem = generalSettingsPane.addDropdown(this._worldSettingsPaneData.difficulty, {
                title: "resourcePack.editor.exportProject.generalSettings.difficulty",
                tooltip: "resourcePack.editor.exportProject.generalSettings.difficulty.tooltip",
                entries: this._currentDifficultyDropDownItems
            });
            generalSettingsPane.addBool(this._worldSettingsPaneData.hardcore, {
                title: "resourcePack.editor.exportProject.generalSettings.hardcore",
                tooltip: "resourcePack.editor.exportProject.generalSettings.hardcore.tooltip",
                onChange: isHardCore => {
                    if (isHardCore) {
                        this._lastDifficultyIndex = this._worldSettingsPaneData.difficulty.value;
                        this._lastGameModeIndex = this._worldSettingsPaneData.gameMode.value;
                        this._lastBonusChest = this._worldSettingsPaneData.bonusChest.value;
                        this._lastStartingMap = this._worldSettingsPaneData.startingMap.value;
                        this._lastCheatsEnabled = this._worldSettingsPaneData.cheats.value;
                        this._worldSettingsPaneData.startingMap.set(this._defaultGameOptions.startingMap);
                        this._worldSettingsPaneData.bonusChest.set(this._defaultGameOptions.bonusChest);
                        this._worldSettingsPaneData.cheats.set(this._defaultGameOptions.cheats);
                        this._storeLastCheatValues();
                        this._setToDefaultCheatOptions(this._worldSettingsPaneData.cheats.value);
                    } else {
                        this._worldSettingsPaneData.startingMap.set(this._lastStartingMap);
                        this._worldSettingsPaneData.bonusChest.set(this._lastBonusChest);
                        this._worldSettingsPaneData.cheats.set(this._lastCheatsEnabled);
                        this._setCheatsToLastValues(this._worldSettingsPaneData.cheats.value);
                    }
                    this._onHardcoreChanged(isHardCore, this._lastGameModeIndex, this._lastDifficultyIndex);
                }
            });
            generalSettingsPane.endConstruct();
        }
        _buildInitialPlaySectionOfPane() {
            const generalSettingsPane = this._parentPane.createSubPane({
                title: `resourcePack.editor.exportProject.initialPlaySettings`,
                infoTooltip: {
                    title: `resourcePack.editor.exportProject.initialPlaySettings`,
                    description: [ `resourcePack.editor.exportProject.initialPlaySettings.tooltip` ]
                },
                collapsed: true
            });
            generalSettingsPane.beginConstruct();
            generalSettingsPane.addVector3(this._worldSettingsPaneData.spawnPosition, {
                title: `resourcePack.editor.exportProject.initialPlaySettings.spawnPosition`,
                tooltip: `resourcePack.editor.exportProject.initialPlaySettings.spawnPosition.tooltip`,
                min: {
                    x: -MAX_ACTOR_COMMAND_COORDINATE,
                    y: -MAX_ACTOR_COMMAND_COORDINATE,
                    z: -MAX_ACTOR_COMMAND_COORDINATE
                },
                max: {
                    x: MAX_ACTOR_COMMAND_COORDINATE,
                    y: MAX_ACTOR_COMMAND_COORDINATE,
                    z: MAX_ACTOR_COMMAND_COORDINATE
                },
                isInteger: true
            });
            this._usePlayerAsSpawnPointPropItem = generalSettingsPane.addButton((() => {
                const player = this._uiSession.extensionContext.player;
                if (player.dimension.id === MinecraftDimensionTypes.Overworld) {
                    this._worldSettingsPaneData.spawnPosition.set(lib.Vector3Utils.floor(player.location));
                }
            }), {
                title: "resourcePack.editor.exportProject.initialPlaySettings.usePlayerAsSpawnPoint",
                tooltip: "resourcePack.editor.exportProject.initialPlaySettings.usePlayerAsSpawnPoint.tooltip",
                enable: this._isPlayerAsSpawnPointPropItemEnabled(this._uiSession.extensionContext.player.dimension)
            });
            generalSettingsPane.addBool(this._worldSettingsPaneData.keepPlayerData, {
                title: "resourcePack.editor.exportProject.initialPlaySettings.keepPlayerData",
                tooltip: "resourcePack.editor.exportProject.initialPlaySettings.keepPlayerData.tooltip"
            });
            const timeItems = this._getTimeItemDropdownItems();
            this._timeOfDayPropItem = generalSettingsPane.addDropdown(this._currentStartTime, {
                title: "resourcePack.editor.exportProject.initialPlaySettings.startTime",
                tooltip: "resourcePack.editor.exportProject.initialPlaySettings.startTime.tooltip",
                entries: timeItems,
                onChange: newValue => {
                    if (newValue === TODDropDown.None) {
                        clockTypePropItem.visible = true;
                        customTimePropItem.visible = true;
                        dayTimePropItem.visible = true;
                    } else {
                        this._worldSettingsPaneData.timeOfDay.set(newValue);
                        clockTypePropItem.visible = false;
                        customTimePropItem.visible = false;
                        dayTimePropItem.visible = false;
                    }
                }
            });
            const clockItems = this._getClockTypeDropdownItems();
            const clockTypePropItem = generalSettingsPane.addDropdown(this._clockType, {
                title: "resourcePack.editor.timeOfDay.clockType",
                tooltip: "resourcePack.editor.timeOfDay.clockType.tooltip",
                enable: true,
                entries: clockItems,
                onChange: newValue => {
                    if (newValue !== ClockType.MINECRAFT_CLOCK) {
                        dayTimePropItem.visible = true;
                        const is24HrClock = this._clockType.value === ClockType.CLOCK_24HR ? true : false;
                        this._timeOfDayTimeString.set(convertTODToTime(this._worldSettingsPaneData.timeOfDay.value, is24HrClock));
                    } else {
                        dayTimePropItem.visible = false;
                    }
                }
            });
            this._clockTypePropItem = clockTypePropItem;
            const dayTimePropItem = generalSettingsPane.addString(this._timeOfDayTimeString, {
                title: "resourcePack.editor.timeOfDay.customTime",
                tooltip: "resourcePack.editor.timeOfDay.customTime.tooltip",
                enable: false,
                visible: false
            });
            const customTimePropItem = generalSettingsPane.addNumber(this._worldSettingsPaneData.timeOfDay, {
                title: "resourcePack.editor.timeOfDay.customTime",
                tooltip: "resourcePack.editor.timeOfDay.customTime.tooltip",
                min: 0,
                max: 24 * mcHoursPerTick - 1,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                onChange: newValue => {
                    const is24HrClock = this._clockType.value === ClockType.CLOCK_24HR ? true : false;
                    this._timeOfDayTimeString.set(convertTODToTime(newValue, is24HrClock));
                }
            });
            this._weatherPropItem = generalSettingsPane.addDropdown(this._weatherIndex, {
                title: `resourcePack.editor.exportProject.initialPlaySettings.weather`,
                tooltip: `resourcePack.editor.exportProject.initialPlaySettings.weather.tooltip`,
                entries: weatherDropdownItems,
                onChange: newValue => {
                    this._worldSettingsPaneData.weather.set(newValue);
                }
            });
            generalSettingsPane.endConstruct();
        }
        _buildAdvancedSectionOfPane() {
            const advancedSettingsPane = this._parentPane.createSubPane({
                title: `resourcePack.editor.exportProject.advancedSettings`,
                collapsed: true,
                infoTooltip: {
                    title: `resourcePack.editor.exportProject.advancedSettings`,
                    description: [ `resourcePack.editor.exportProject.advancedSettings.tooltip` ]
                }
            });
            advancedSettingsPane.beginConstruct();
            const startingMapPropItem = advancedSettingsPane.addBool(this._worldSettingsPaneData.startingMap, {
                title: "resourcePack.editor.exportProject.advancedSettings.startingMap",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.startingMap.tooltip"
            });
            this._nonHardCorePropertyItems.push(startingMapPropItem);
            if (this._exportOnly) {
                const bonusChestPropItem = advancedSettingsPane.addBool(this._worldSettingsPaneData.bonusChest, {
                    title: "resourcePack.editor.exportProject.advancedSettings.bonusChest",
                    tooltip: "resourcePack.editor.exportProject.advancedSettings.bonusChest.tooltip"
                });
                this._nonHardCorePropertyItems.push(bonusChestPropItem);
            }
            advancedSettingsPane.addBool(this._worldSettingsPaneData.showCoordinates, {
                title: "resourcePack.editor.exportProject.advancedSettings.showCoordinates",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.showCoordinates.tooltip"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.locatorBar, {
                title: "resourcePack.editor.exportProject.advancedSettings.showLocatorBar"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.showDaysPlayed, {
                title: "resourcePack.editor.exportProject.advancedSettings.showDaysPlayed",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.showDaysPlayed.tooltip"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.recipeUnlocking, {
                title: "resourcePack.editor.exportProject.advancedSettings.recipeUnlocking",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.recipeUnlocking.tooltip"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.limitedCrafting, {
                title: "resourcePack.editor.exportProject.advancedSettings.limitedCrafting",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.limitedCrafting.tooltip"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.fireSpreads, {
                title: "resourcePack.editor.exportProject.advancedSettings.fireSpreads",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.fireSpreads.tooltip"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.tntExplodes, {
                title: "resourcePack.editor.exportProject.advancedSettings.tntExplodes",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.tntExplodes.tooltip"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.respawnBlocksExplode, {
                title: "resourcePack.editor.exportProject.advancedSettings.resawnBlocksExplode",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.resawnBlocksExplode.tooltip"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.mobLoot, {
                title: "resourcePack.editor.exportProject.advancedSettings.mobLoot",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.mobLoot.tooltip"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.naturalRegeneration, {
                title: "resourcePack.editor.exportProject.advancedSettings.naturalRegeneration",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.naturalRegeneration.tooltip"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.tileDrops, {
                title: "resourcePack.editor.exportProject.advancedSettings.tileDrops",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.tileDrops.tooltip"
            });
            const oneSleepingPlayerMessage = {
                id: "resourcePack.editor.exportProject.advancedSettings.requiredSleepingPlayers.onePlayerMessage"
            };
            const initialTitlePercentMessage = this._worldSettingsPaneData.sleepSkipPercent.value <= 0 ? oneSleepingPlayerMessage.id : this._worldSettingsPaneData.sleepSkipPercent.value >= 101 ? `${100}` + `%%` : `${this._worldSettingsPaneData.sleepSkipPercent.value}` + `%%`;
            const localizedPercentTitle = {
                id: "resourcePack.editor.exportProject.advancedSettings.requiredSleepingPlayers",
                props: [ `${initialTitlePercentMessage}` ]
            };
            advancedSettingsPane.addBool(this._worldSettingsPaneData.bedsWork, {
                title: "resourcePack.editor.exportProject.advancedSettings.bedsWork",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.bedsWork.tooltip",
                variant: server_editor_namespaceObject.BoolPropertyItemVariant.Checkbox,
                onChange: newValue => {
                    if (this._sleepSkipPercentPropItem) {
                        this._sleepSkipPercentPropItem.enable = newValue;
                        if (newValue) {
                            this._worldSettingsPaneData.sleepSkipPercent.set(this._defaultGameOptions.sleepSkipPercent);
                        } else {
                            const sleepDisabledValue = this._defaultGameOptions.sleepSkipPercent + 1;
                            this._worldSettingsPaneData.sleepSkipPercent.set(sleepDisabledValue);
                            if (localizedPercentTitle.props) {
                                localizedPercentTitle.props = [ `${this._worldSettingsPaneData.sleepSkipPercent.value}%%` ];
                            }
                            this._sleepSkipPercentPropItem.setTitle(localizedPercentTitle);
                        }
                    }
                }
            });
            this._sleepSkipPercentPropItem = advancedSettingsPane.addNumber(this._worldSettingsPaneData.sleepSkipPercent, {
                title: localizedPercentTitle,
                tooltip: "resourcePack.editor.exportProject.advancedSettings.requiredSleepingPlayers.tooltip",
                min: 0,
                max: 100,
                isInteger: true,
                enable: this._worldSettingsPaneData.bedsWork.value,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    if (localizedPercentTitle.props && newValue > 0) {
                        localizedPercentTitle.props = [ `${newValue}%%` ];
                    } else {
                        localizedPercentTitle.props = [ oneSleepingPlayerMessage.id ];
                    }
                    this._sleepSkipPercentPropItem?.setTitle(localizedPercentTitle);
                }
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.immediateRespawn, {
                title: "resourcePack.editor.exportProject.advancedSettings.immediateRespawn",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.immediateRespawn.tooltip"
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.showDeathMessage, {
                title: "resourcePack.editor.exportProject.advancedSettings.showDeathMessage",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.showDeathMessage.tooltip"
            });
            advancedSettingsPane.addNumber(this._worldSettingsPaneData.respawnRadius, {
                title: `resourcePack.editor.exportProject.advancedSettings.respawnRadius`,
                tooltip: `resourcePack.editor.exportProject.advancedSettings.respawnRadius.tooltip`,
                min: 0,
                max: 128
            });
            advancedSettingsPane.addNumber(this._worldSettingsPaneData.simulationDistance, {
                title: `resourcePack.editor.exportProject.advancedSettings.simulationDistance`,
                tooltip: `resourcePack.editor.exportProject.advancedSettings.simulationDistance.tooltip`,
                min: 4,
                max: 12
            });
            advancedSettingsPane.addBool(this._worldSettingsPaneData.showItemTags, {
                title: "resourcePack.editor.exportProject.advancedSettings.showItemTags",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.showItemTags.tooltip"
            });
            advancedSettingsPane.endConstruct();
        }
        _buildMultiplayerSectionOfPane() {
            const multiplayerSettingsPane = this._parentPane.createSubPane({
                title: `resourcePack.editor.exportProject.multiplayerSettings`,
                collapsed: true,
                infoTooltip: {
                    title: `resourcePack.editor.exportProject.multiplayerSettings`,
                    description: [ `resourcePack.editor.exportProject.multiplayerSettings.tooltip` ]
                }
            });
            multiplayerSettingsPane.beginConstruct();
            const isMultiplayerEnabled = this._worldSettingsPaneData.multiplayerGame.value;
            multiplayerSettingsPane.addBool(this._worldSettingsPaneData.multiplayerGame, {
                title: "resourcePack.editor.exportProject.multiplayerSettings.multiplayerGame",
                tooltip: "resourcePack.editor.exportProject.multiplayerSettings.multiplayerGame.tooltip",
                onChange: newValue => {
                    this._setMultiplayerOptionsEnableState(newValue);
                }
            });
            const playerAccessItems = validPlayerAccess.map((v => {
                const item = {
                    label: playerAccessLocalization[v],
                    value: v
                };
                return item;
            }));
            const playerAccessPropItem = multiplayerSettingsPane.addDropdown(this._worldSettingsPaneData.playerAccess, {
                title: "resourcePack.editor.exportProject.multiplayerSettings.playerAccess",
                tooltip: "resourcePack.editor.exportProject.multiplayerSettings.playerAccess.tooltip",
                entries: playerAccessItems,
                enable: isMultiplayerEnabled
            });
            this._multiplayerPropertyItems.push(playerAccessPropItem);
            const playerPermissionLevelItems = validPlayerPermissionLevels.map((v => {
                const item = {
                    label: playerPermissionLocalization[v],
                    value: v
                };
                return item;
            }));
            const playerPermissionsPropItem = multiplayerSettingsPane.addDropdown(this._worldSettingsPaneData.playerPermissions, {
                title: "resourcePack.editor.exportProject.multiplayerSettings.playerPermissions",
                tooltip: "resourcePack.editor.exportProject.multiplayerSettings.playerPermissions.tooltip",
                entries: playerPermissionLevelItems,
                enable: isMultiplayerEnabled
            });
            this._multiplayerPropertyItems.push(playerPermissionsPropItem);
            const lanVisibilityPropItem = multiplayerSettingsPane.addBool(this._worldSettingsPaneData.lanVisibility, {
                title: "resourcePack.editor.exportProject.multiplayerSettings.visibleToLAN",
                tooltip: "resourcePack.editor.exportProject.multiplayerSettings.visibleToLAN.tooltip",
                enable: isMultiplayerEnabled
            });
            this._multiplayerPropertyItems.push(lanVisibilityPropItem);
            const friendlyFirePropItem = multiplayerSettingsPane.addBool(this._worldSettingsPaneData.friendlyFire, {
                title: "resourcePack.editor.exportProject.multiplayerSettings.friendlyFire",
                tooltip: "resourcePack.editor.exportProject.multiplayerSettings.friendlyFire.tooltip",
                enable: isMultiplayerEnabled
            });
            this._multiplayerPropertyItems.push(friendlyFirePropItem);
            multiplayerSettingsPane.endConstruct();
        }
        _buildCheatSectionOfPane() {
            const cheatsSettingsPane = this._parentPane.createSubPane({
                title: `resourcePack.editor.exportProject.cheatsSettings`,
                collapsed: true,
                infoTooltip: {
                    title: `resourcePack.editor.exportProject.cheatsSettings`,
                    description: [ `resourcePack.editor.exportProject.cheatsSettings.tooltip` ]
                }
            });
            cheatsSettingsPane.beginConstruct();
            const cheatsPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.cheats, {
                title: `resourcePack.editor.exportProject.cheatsSettings.cheats`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.cheats.tooltip`,
                onChange: newValue => {
                    this._setToDefaultCheatOptions(newValue);
                }
            });
            this._nonHardCorePropertyItems.push(cheatsPropItem);
            const daylightCycleItems = validDaylightCycle.map((v => {
                const item = {
                    label: daylightCycleLocalization[v],
                    value: v
                };
                return item;
            }));
            const daylightCyclePropItem = cheatsSettingsPane.addDropdown(this._worldSettingsPaneData.daylightCycle, {
                title: `resourcePack.editor.exportProject.cheatsSettings.daylightCycle`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.daylightCycle.tooltip`,
                enable: cheatsPropItem.value,
                entries: daylightCycleItems
            });
            this._cheatItems.set("daylightCycle", {
                item: daylightCyclePropItem,
                observable: this._worldSettingsPaneData.daylightCycle
            });
            const keepInventoryPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.keepInventory, {
                title: `resourcePack.editor.exportProject.cheatsSettings.keepInventory`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.keepInventory.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("keepInventory", {
                item: keepInventoryPropItem,
                observable: this._worldSettingsPaneData.keepInventory
            });
            const mobSpawningPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.mobSpawning, {
                title: `resourcePack.editor.exportProject.cheatsSettings.mobSpawning`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.mobSpawning.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("mobSpawning", {
                item: mobSpawningPropItem,
                observable: this._worldSettingsPaneData.mobSpawning
            });
            const mobGriefingPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.mobGriefing, {
                title: `resourcePack.editor.exportProject.cheatsSettings.mobGriefing`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.mobGriefing.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("mobGriefing", {
                item: mobGriefingPropItem,
                observable: this._worldSettingsPaneData.mobGriefing
            });
            const entitiesDropLootPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.entitiesDropLoot, {
                title: `resourcePack.editor.exportProject.cheatsSettings.entitiesDropLoot`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.entitiesDropLoot.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("entitiesDropLoot", {
                item: entitiesDropLootPropItem,
                observable: this._worldSettingsPaneData.entitiesDropLoot
            });
            const disableWeatherPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.disableWeather, {
                title: `resourcePack.editor.exportProject.cheatsSettings.weatherCycle`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.weatherCycle.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("disableWeather", {
                item: disableWeatherPropItem,
                observable: this._worldSettingsPaneData.disableWeather
            });
            const commandBlockEnabledPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.commandBlockEnabled, {
                title: `resourcePack.editor.exportProject.cheatsSettings.commandBlocks`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.commandBlocks.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("commandBlockEnabled", {
                item: commandBlockEnabledPropItem,
                observable: this._worldSettingsPaneData.commandBlockEnabled
            });
            const commandBlockOutputPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.commandBlockOutput, {
                title: `resourcePack.editor.exportProject.cheatsSettings.commandBlockOutput`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.commandBlockOutput.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("commandBlockOutput", {
                item: commandBlockOutputPropItem,
                observable: this._worldSettingsPaneData.commandBlockOutput
            });
            const sendCommandFeedbackPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.sendCommandFeedback, {
                title: `resourcePack.editor.exportProject.cheatsSettings.sendCommandFeedback`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.sendCommandFeedback.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("sendCommandFeedback", {
                item: sendCommandFeedbackPropItem,
                observable: this._worldSettingsPaneData.sendCommandFeedback
            });
            const maxCommandChainLengthPropItem = cheatsSettingsPane.addNumber(this._worldSettingsPaneData.maxCommandChainLength, {
                title: `resourcePack.editor.exportProject.cheatsSettings.maxCommandChainLength`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.maxCommandChainLength.tooltip`,
                enable: cheatsPropItem.value,
                min: 0,
                max: 2147483647
            });
            this._cheatItems.set("maxCommandChainLength", {
                item: maxCommandChainLengthPropItem,
                observable: this._worldSettingsPaneData.maxCommandChainLength
            });
            const fireDamagePropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.fireDamage, {
                title: `resourcePack.editor.exportProject.cheatsSettings.fireDamage`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.fireDamage.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("fireDamage", {
                item: fireDamagePropItem,
                observable: this._worldSettingsPaneData.fireDamage
            });
            const freezeDamagePropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.freezeDamage, {
                title: `resourcePack.editor.exportProject.cheatsSettings.freezeDamage`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.freezeDamage.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("freezeDamage", {
                item: freezeDamagePropItem,
                observable: this._worldSettingsPaneData.freezeDamage
            });
            const fallDamagePropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.fallDamage, {
                title: `resourcePack.editor.exportProject.cheatsSettings.fallDamage`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.fallDamage.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("fallDamage", {
                item: fallDamagePropItem,
                observable: this._worldSettingsPaneData.fallDamage
            });
            const drowningDamagePropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.drowningDamage, {
                title: `resourcePack.editor.exportProject.cheatsSettings.drowningDamage`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("drowningDamage", {
                item: drowningDamagePropItem,
                observable: this._worldSettingsPaneData.drowningDamage
            });
            const insomniaPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.insomnia, {
                title: `resourcePack.editor.exportProject.cheatsSettings.insomnia`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.insomnia.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("insomnia", {
                item: insomniaPropItem,
                observable: this._worldSettingsPaneData.insomnia
            });
            const showBorderEffectPropItem = cheatsSettingsPane.addBool(this._worldSettingsPaneData.showBorderEffect, {
                title: `resourcePack.editor.exportProject.cheatsSettings.showBorderEffect`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.showBorderEffect.tooltip`,
                enable: cheatsPropItem.value
            });
            this._cheatItems.set("showBorderEffect", {
                item: showBorderEffectPropItem,
                observable: this._worldSettingsPaneData.showBorderEffect
            });
            const functionCommandLimitPropItem = cheatsSettingsPane.addNumber(this._worldSettingsPaneData.functionCommandLimit, {
                title: `resourcePack.editor.exportProject.cheatsSettings.functionCommandLimit`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.functionCommandLimit.tooltip`,
                enable: cheatsPropItem.value,
                min: 0,
                max: 1e4
            });
            this._cheatItems.set("functionCommandLimit", {
                item: functionCommandLimitPropItem,
                observable: this._worldSettingsPaneData.functionCommandLimit
            });
            cheatsSettingsPane.addBool(this._worldSettingsPaneData.educationEdition, {
                title: "resourcePack.editor.exportProject.cheatsSettings.educationFeatures",
                tooltip: "resourcePack.editor.exportProject.cheatsSettings.educationFeatures.tooltip",
                enable: false
            });
            const randomTickSpeedPropItem = cheatsSettingsPane.addNumber(this._worldSettingsPaneData.randomTickSpeed, {
                title: `resourcePack.editor.exportProject.cheatsSettings.randomTickSpeed`,
                tooltip: `resourcePack.editor.exportProject.cheatsSettings.randomTickSpeed.tooltip`,
                enable: cheatsPropItem.value,
                min: 0,
                max: 4096
            });
            this._cheatItems.set("randomTickSpeed", {
                item: randomTickSpeedPropItem,
                observable: this._worldSettingsPaneData.randomTickSpeed
            });
            cheatsSettingsPane.endConstruct();
        }
        _setMultiplayerOptionsEnableState(isMultiplayerOptionEnabled) {
            this._multiplayerPropertyItems.forEach((propItem => {
                propItem.enable = isMultiplayerOptionEnabled;
            }));
        }
        _onHardcoreChanged(isHardCore, gameModeIndex, difficultyIndex) {
            this._currentGameModeDropdownItems = this._getGameModeDropdownItems(isHardCore);
            this._currentDifficultyDropDownItems = this._getDifficultyDropdownItems(isHardCore);
            this._gameModePropertyItem.updateEntries(this._currentGameModeDropdownItems, this._currentGameModeDropdownItems[isHardCore ? 0 : gameModeIndex].value);
            this._difficultyPropertyItem.updateEntries(this._currentDifficultyDropDownItems, this._currentDifficultyDropDownItems[isHardCore ? 0 : difficultyIndex].value);
            this._nonHardCorePropertyItems.forEach((item => {
                item.enable = !isHardCore;
            }));
        }
        _setToDefaultCheatOptions(isCheatsOptionEnabled) {
            this._cheatItems.forEach(((prop, key) => {
                prop.item.enable = isCheatsOptionEnabled;
                if (!isCheatsOptionEnabled) {
                    prop.observable.set(this._defaultGameOptions[key]);
                }
            }));
        }
        _setToDefaultInitialPayOptions() {
            const timeItems = this._getTimeItemDropdownItems();
            this._timeOfDayPropItem?.updateEntries(timeItems, TODDropDown.None);
            const clockItems = this._getClockTypeDropdownItems();
            this._clockTypePropItem?.updateEntries(clockItems, ClockType.MINECRAFT_CLOCK);
            this._weatherPropItem?.updateEntries(weatherDropdownItems, this._defaultGameOptions.weather);
        }
        _getTimeItemDropdownItems() {
            const timeItem = validPresets.map((v => {
                if (v.time === TODDropDown.None) {
                    const item = {
                        label: "resourcePack.editor.timeOfDay.dropDown.custom",
                        value: v.time
                    };
                    return item;
                }
                const item = {
                    label: v.stringId,
                    value: v.time
                };
                return item;
            }));
            return timeItem;
        }
        _getClockTypeDropdownItems() {
            return clockValues.map((v => {
                const item = {
                    label: v.stringId,
                    value: v.index
                };
                return item;
            }));
        }
        _getGameModeDropdownItems(hardcore) {
            if (hardcore) {
                return gameModeDropDownItems.filter((dropDownItem => dropDownItem.value !== gameModeLookUpIndex[server_namespaceObject.GameMode.Creative]));
            }
            return gameModeDropDownItems;
        }
        _getDifficultyDropdownItems(hardcore) {
            if (hardcore) {
                const hardcoreDifficultyItem = {
                    label: difficultyLocalization[server_namespaceObject.Difficulty.Hard],
                    value: difficultyLookUpIndex[server_namespaceObject.Difficulty.Hard]
                };
                return [ hardcoreDifficultyItem ];
            }
            return difficultyDropDownItems;
        }
        _isPlayerAsSpawnPointPropItemEnabled(dimension) {
            return MinecraftDimensionTypes.Overworld === dimension.id;
        }
        _storeLastCheatValues() {
            this._cheatItems.forEach(((prop, key) => {
                if (this._lastCheatsValues) {
                    this._lastCheatsValues.set(key, prop.observable.value);
                }
            }));
        }
        _setCheatsToLastValues(cheatsEnabled) {
            if (this._lastCheatsValues) {
                this._cheatItems.forEach(((prop, key) => {
                    const lastVal = this._lastCheatsValues.get(key);
                    if (lastVal !== undefined) {
                        prop.observable.set(lastVal);
                    }
                    prop.item.enable = cheatsEnabled;
                }));
            }
        }
        teardown() {}
    }
    const SHOULD_LOG_TELEMETRY = false;
    var TelemetrySource;
    (function(TelemetrySource) {
        TelemetrySource["Selection"] = "SELECTION";
        TelemetrySource["PastePreview"] = "PASTE_PREVIEW";
        TelemetrySource["Line"] = "LINE";
        TelemetrySource["Summon"] = "SUMMON";
        TelemetrySource["Ruler"] = "RULER";
        TelemetrySource["Brush"] = "BRUSH";
        TelemetrySource["Flatten"] = "FLATTEN";
        TelemetrySource["SmartFill"] = "SMART_FILL";
        TelemetrySource["Terrain"] = "TERRAIN";
        TelemetrySource["Extrude"] = "EXTRUDE";
        TelemetrySource["Repeater"] = "REPEATER";
        TelemetrySource["Farm"] = "FARM";
        TelemetrySource["Grapple"] = "GRAPPLE";
        TelemetrySource["DeferredLighting"] = "DEFERRED_LIGHTING";
        TelemetrySource["TimeOfDay"] = "TIME_OF_DAY";
        TelemetrySource["Export"] = "EXPORT";
        TelemetrySource["TestWorld"] = "TEST_WORLD";
        TelemetrySource["Settings"] = "SETTINGS";
        TelemetrySource["Locate"] = "LOCATE";
        TelemetrySource["Navigation"] = "NAVIGATION";
        TelemetrySource["BlockInspector"] = "BLOCK_INSPECTOR";
        TelemetrySource["EntityInspector"] = "ENTITY_INSPECTOR";
        TelemetrySource["Workbench"] = "WORKBENCH";
        TelemetrySource["RealmsUpload"] = "REALMS_UPLOAD";
        TelemetrySource["Pencil"] = "PENCIL";
        TelemetrySource["Scale"] = "SCALE";
        TelemetrySource["Jigsaw"] = "JIGSAW";
        TelemetrySource["ChunkManagement"] = "CHUNK_MANAGEMENT";
        TelemetrySource["FloodTool"] = "FLOOD_TOOL";
    })(TelemetrySource || (TelemetrySource = {}));
    function fireTelemetryEvent(player, source, eventName, properties = {}) {
        if (SHOULD_LOG_TELEMETRY) {
            server_editor_namespaceObject.editor.log.debug(`${source}::${eventName}::${JSON.stringify(properties)}`, {
                player,
                tags: [ "Telemetry" ]
            });
        }
        server_editor_private_bindings_namespaceObject.editorInternal.fireTelemetryEvent(player, source, eventName, JSON.stringify(properties));
    }
    class TelemetryManager {
        constructor(player, telemetrySource) {
            this._player = player;
            this._source = telemetrySource;
        }
        fireTelemetryEvent(eventName, properties = {}, shouldFire = true) {
            if (!shouldFire) {
                return;
            }
            fireTelemetryEvent(this._player, this._source, eventName, properties);
        }
    }
    class ModalDialogConfirmation {
        constructor(session, parentPane) {
            this._message = (0, server_editor_namespaceObject.makeObservable)("");
            this._session = session;
            this._parentPane = parentPane;
            this._pane = this._parentPane.createModalOverlayPane({
                title: "editor.sharedUtils.modaldialogconfirmation.title"
            });
            this._pane.contentPane.addText(this._message, {
                alignment: server_editor_namespaceObject.LayoutAlignment.Center
            });
            this._pane.contentPane.addText("", {
                border: false,
                alignment: server_editor_namespaceObject.LayoutAlignment.Center
            });
            this._pane.contentPane.addDivider();
            this._pane.contentPane.addButton((() => {
                this._pane.hide();
                this._parentPane.setActiveModalOverlay("");
                this._resolve?.();
                this._reject = undefined;
                this._resolve = undefined;
            }), {
                title: "editor.sharedUtils.modaldialogconfirmation.yes",
                variant: server_editor_namespaceObject.ButtonVariant.Destructive
            });
            this._pane.contentPane.addButton((() => {
                this._pane.hide();
                this._parentPane.setActiveModalOverlay("");
                this._reject?.(new Error("Cancelled"));
                this._reject = undefined;
                this._resolve = undefined;
            }), {
                title: "editor.sharedUtils.modaldialogconfirmation.cancel"
            });
            this._parentPane.onPropertyPaneVisibilityUpdated.subscribe((eventData => {
                if (this._resolve !== undefined || this._reject !== undefined) {
                    if (eventData.isVisible) {
                        throw new Error("Something went wrong - dialog is being activated while promises are still pending");
                    } else {
                        if (this._resolve !== undefined || this._reject !== undefined) {
                            this._reject?.(new Error("Parent pane closed while dialog was active"));
                            this._reject = undefined;
                            this._resolve = undefined;
                        }
                        this._pane.hide();
                        this._parentPane.setActiveModalOverlay("");
                    }
                }
            }));
        }
        async activate(message) {
            if (this._parentPane.getActiveModalOverlayId() !== undefined) {
                this._pane.hide();
                throw new Error("Another modal overlay is already active");
            }
            this._message.set(message);
            this._parentPane.setActiveModalOverlay(this._pane.id);
            this._pane.show();
            return new Promise(((resolve, reject) => {
                this._resolve = resolve;
                this._reject = reject;
            }));
        }
    }
    class ModalDialogStringInput {
        get name() {
            return this._name;
        }
        constructor(session, parentPane, validate) {
            this._name = (0, server_editor_namespaceObject.makeObservable)("");
            this._message = (0, server_editor_namespaceObject.makeObservable)("");
            this._session = session;
            this._parentPane = parentPane;
            this._name.set("");
            this._message.set("");
            this._validate = validate;
            this._pane = this._parentPane.createModalOverlayPane({});
            this._pane.contentPane.addText(this._message);
            this._pane.contentPane.addString(this._name, {
                hiddenLabel: true
            });
            this._pane.contentPane.addText("", {
                border: false,
                alignment: server_editor_namespaceObject.LayoutAlignment.Center
            });
            this._pane.contentPane.addDivider();
            this._pane.contentPane.addButton((() => {
                if (this._validate && !this._validate(this._name.value)) {
                    this._session.log.error("Invalid name provided");
                    return;
                }
                this._pane.hide();
                this._parentPane.setActiveModalOverlay("");
                this._resolve?.(this._name.value);
                this._reject = undefined;
                this._resolve = undefined;
            }), {
                title: "editor.sharedUtils.modaldialogstringinput.ok"
            });
            this._pane.contentPane.addButton((() => {
                this._pane.hide();
                this._parentPane.setActiveModalOverlay("");
                this._reject?.(new Error("Cancelled"));
                this._reject = undefined;
                this._resolve = undefined;
            }), {
                title: "editor.sharedUtils.modaldialogstringinput.cancel"
            });
            this._parentPane.onPropertyPaneVisibilityUpdated.subscribe((eventData => {
                if (this._resolve !== undefined || this._reject !== undefined) {
                    if (eventData.isVisible) {
                        throw new Error("Something went wrong - dialog is being activated while promises are still pending");
                    } else {
                        if (this._resolve !== undefined || this._reject !== undefined) {
                            this._reject?.(new Error("Parent pane closed while dialog was active"));
                            this._parentPane.setActiveModalOverlay("");
                            this._reject = undefined;
                            this._resolve = undefined;
                        }
                        this._pane.hide();
                    }
                }
            }));
        }
        async activate(initialInputString, title, message) {
            if (this._parentPane.getActiveModalOverlayId() !== undefined) {
                this._pane.hide();
                throw new Error("Another modal overlay is already active");
            }
            this._name.set(initialInputString);
            this._message.set(message);
            this._pane.contentPane.setTitle(title);
            this._parentPane.setActiveModalOverlay(this._pane.id);
            this._pane.show();
            return new Promise(((resolve, reject) => {
                this._resolve = resolve;
                this._reject = reject;
            }));
        }
    }
    class ModalMultiStringInputFieldImp {
        get data() {
            return this._values;
        }
        get currentValue() {
            return this._value.value;
        }
        constructor(session, pane, field) {
            this._value = (0, server_editor_namespaceObject.makeObservable)("");
            this._values = field;
            this._value.set(field.initialValue);
            this._stringUI = pane.addString(this._value, {
                title: field.title,
                tooltip: field.tooltip,
                hiddenLabel: false
            });
        }
        teardown() {}
    }
    class ModalDialogMultiStringInput {
        constructor(session, parentPane) {
            this._titleMessage = (0, server_editor_namespaceObject.makeObservable)("");
            this._fields = [];
            this._fieldImps = [];
            this._session = session;
            this._parentPane = parentPane;
            this._titleMessage.set("");
            this._pane = this._parentPane.createModalOverlayPane({});
            this._pane.contentPane.addText(this._titleMessage);
            this._subPane = this._pane.contentPane.createSubPane({});
            this._parentPane.onPropertyPaneVisibilityUpdated.subscribe((eventData => {
                if (this._resolve !== undefined || this._reject !== undefined) {
                    if (eventData.isVisible) {
                        throw new Error("Something went wrong - dialog is being activated while promises are still pending");
                    } else {
                        if (this._resolve !== undefined || this._reject !== undefined) {
                            this._reject?.(new Error("Parent pane closed while dialog was active"));
                            this._parentPane.setActiveModalOverlay("");
                            this._reject = undefined;
                            this._resolve = undefined;
                        }
                        this._pane.hide();
                    }
                }
            }));
        }
        _constructUI() {
            if (this._fields.length === 0) {
                throw new Error("No fields defined for ModalMultiStringInputDialog");
            }
            this._pane.hide();
            this._pane.contentPane.beginConstruct();
            if (this._subPane !== undefined) {
                this._pane.contentPane.removeSubPane(this._subPane);
                for (const fieldImp of this._fieldImps) {
                    fieldImp.teardown();
                }
                this._fieldImps = [];
            }
            this._pane.contentPane.setTitle(this._titleMessage.value);
            this._subPane = this._pane.contentPane.createSubPane({
                hasExpander: false,
                collapsed: false
            });
            for (const field of this._fields) {
                const fieldImp = new ModalMultiStringInputFieldImp(this._session, this._subPane, field);
                this._fieldImps.push(fieldImp);
            }
            this._subPane.addText("", {
                border: false,
                alignment: server_editor_namespaceObject.LayoutAlignment.Center
            });
            this._subPane.addDivider();
            this._subPane.addButton((() => {
                let allValid = true;
                const resultValues = [];
                for (const field of this._fieldImps) {
                    const currentValue = field.currentValue;
                    const validationResult = field.data.validator(currentValue);
                    if (!validationResult.valid) {
                        let failedValidationMessage = typeof field.data.failedValidationMessage === "string" ? field.data.failedValidationMessage : field.data.failedValidationMessage.id;
                        if (validationResult.message?.length) {
                            failedValidationMessage = validationResult.message;
                        }
                        this._session.log.error(failedValidationMessage, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        allValid = false;
                    }
                    resultValues.push(currentValue);
                }
                if (!allValid) {
                    return;
                }
                this._pane.hide();
                this._parentPane.setActiveModalOverlay("");
                this._resolve?.(resultValues);
                this._reject = undefined;
                this._resolve = undefined;
            }), {
                title: "editor.sharedUtils.modaldialogstringinput.ok"
            });
            this._subPane.addButton((() => {
                this._pane.hide();
                this._parentPane.setActiveModalOverlay("");
                this._reject?.(new Error("Cancelled"));
                this._reject = undefined;
                this._resolve = undefined;
            }), {
                title: "editor.sharedUtils.modaldialogstringinput.cancel"
            });
            this._pane.contentPane.endConstruct();
            this._pane.show();
        }
        async activate(titleMessage, fields) {
            if (this._parentPane.getActiveModalOverlayId() !== undefined) {
                this._pane.hide();
                throw new Error("Another modal overlay is already active");
            }
            if (fields.length === 0) {
                this._pane.hide();
                throw new Error("No fields provided to ModalMultiStringInputDialog");
            }
            this._titleMessage.set(titleMessage);
            this._fields = fields;
            this._constructUI();
            this._parentPane.setActiveModalOverlay(this._pane.id);
            return new Promise(((resolve, reject) => {
                this._resolve = resolve;
                this._reject = reject;
            }));
        }
    }
    const weatherChangeListeners = new Map;
    const WeatherExtensionChangeEventPayloadId = "editor::core::WeatherChangeRequest";
    var WeatherChangeMessageType;
    (function(WeatherChangeMessageType) {
        WeatherChangeMessageType[WeatherChangeMessageType["Change"] = 0] = "Change";
        WeatherChangeMessageType[WeatherChangeMessageType["Restore"] = 1] = "Restore";
    })(WeatherChangeMessageType || (WeatherChangeMessageType = {}));
    function requestWeatherChange(uniqueId, weatherType) {
        const payload = {
            type: WeatherChangeMessageType.Change,
            uniqueId,
            WeatherType: weatherType
        };
        server_namespaceObject.system.sendScriptEvent(WeatherExtensionChangeEventPayloadId, JSON.stringify(payload));
    }
    function restoreWeatherChange(uniqueId) {
        const payload = {
            type: WeatherChangeMessageType.Restore,
            uniqueId
        };
        server_namespaceObject.system.sendScriptEvent(WeatherExtensionChangeEventPayloadId, JSON.stringify(payload));
    }
    function subscribeWeatherChangeMessages(change, restore) {
        const handle = guid();
        const subscription = server_namespaceObject.system.afterEvents.scriptEventReceive.subscribe((e => {
            if (e.id === WeatherExtensionChangeEventPayloadId) {
                const payloadObject = JSON.parse(e.message);
                if (payloadObject.type === WeatherChangeMessageType.Change) {
                    change(payloadObject.uniqueId, payloadObject.WeatherType);
                } else if (payloadObject.type === WeatherChangeMessageType.Restore) {
                    restore(payloadObject.uniqueId);
                }
            }
        }));
        weatherChangeListeners.set(handle, subscription);
        return handle;
    }
    function unsubscribeWeatherChangeMessages(handle) {
        const subscription = weatherChangeListeners.get(handle);
        if (subscription) {
            system.afterEvents.scriptEventReceive.unsubscribe(subscription);
            weatherChangeListeners.delete(handle);
        }
    }
    const timeChangeListeners = new Map;
    const TimeOfDayExtensionChangeEventPayloadId = "editor::core::TimeOfDayChangeRequest";
    var TimeOfDayChangeMessageType;
    (function(TimeOfDayChangeMessageType) {
        TimeOfDayChangeMessageType[TimeOfDayChangeMessageType["Change"] = 0] = "Change";
        TimeOfDayChangeMessageType[TimeOfDayChangeMessageType["Restore"] = 1] = "Restore";
    })(TimeOfDayChangeMessageType || (TimeOfDayChangeMessageType = {}));
    function requestTimeOfDayChange(uniqueId, timeOfDay) {
        const payload = {
            type: TimeOfDayChangeMessageType.Change,
            uniqueId,
            timeOfDay
        };
        server_namespaceObject.system.sendScriptEvent(TimeOfDayExtensionChangeEventPayloadId, JSON.stringify(payload));
    }
    function restoreTimeOfDayChange(uniqueId) {
        const payload = {
            type: TimeOfDayChangeMessageType.Restore,
            uniqueId
        };
        server_namespaceObject.system.sendScriptEvent(TimeOfDayExtensionChangeEventPayloadId, JSON.stringify(payload));
    }
    function subscribeTimeOfDayChangeMessages(change, restore) {
        const handle = guid();
        const subscription = server_namespaceObject.system.afterEvents.scriptEventReceive.subscribe((e => {
            if (e.id === TimeOfDayExtensionChangeEventPayloadId) {
                const payloadObject = JSON.parse(e.message);
                if (payloadObject.type === TimeOfDayChangeMessageType.Change) {
                    change(payloadObject.uniqueId, payloadObject.timeOfDay);
                } else if (payloadObject.type === TimeOfDayChangeMessageType.Restore) {
                    restore(payloadObject.uniqueId);
                }
            }
        }));
        timeChangeListeners.set(handle, subscription);
        return handle;
    }
    function unsubscribeTimeOfDayChangeMessages(handle) {
        const subscription = timeChangeListeners.get(handle);
        if (subscription) {
            server_namespaceObject.system.afterEvents.scriptEventReceive.unsubscribe(subscription);
            timeChangeListeners.delete(handle);
        }
    }
    class Vector3Pool {
        constructor() {
            this.width = 0;
            this.height = 0;
            this.depth = 0;
            this.count = 0;
            this.min = lib.VECTOR3_ZERO;
            this.max = lib.VECTOR3_ZERO;
            this.bitmap = new Uint8Array(0);
        }
        init(min, max) {
            let size = lib.Vector3Utils.subtract(max, min);
            size = {
                x: Math.ceil(size.x + 1),
                y: Math.ceil(size.y + 1),
                z: Math.ceil(size.z + 1)
            };
            this.width = size.x;
            this.height = size.y;
            this.depth = size.z;
            this.min = min;
            this.max = max;
            const totalBits = this.width * this.height * this.depth;
            this.bitmap = new Uint8Array(Math.ceil(totalBits / 8));
            this.count = 0;
        }
        reset() {
            this.width = 0;
            this.height = 0;
            this.depth = 0;
            this.count = 0;
            this.min = lib.VECTOR3_ZERO;
            this.max = lib.VECTOR3_ZERO;
            this.bitmap = new Uint8Array(0);
        }
        _index(x, y, z) {
            const ox = x - this.min.x;
            const oy = y - this.min.y;
            const oz = z - this.min.z;
            return ox + oy * this.width + oz * this.width * this.height;
        }
        add(v) {
            if (v.x < this.min.x || v.x > this.max.x || v.y < this.min.y || v.y > this.max.y || v.z < this.min.z || v.z > this.max.z) {
                return false;
            }
            const idx = this._index(v.x, v.y, v.z);
            const byteIndex = idx >> 3;
            const bitOffset = idx & 7;
            const mask = 1 << bitOffset;
            if ((this.bitmap[byteIndex] & mask) === 0) {
                this.bitmap[byteIndex] |= mask;
                this.count++;
                return true;
            }
            return false;
        }
        size() {
            return this.count;
        }
        isEmpty() {
            return this.count === 0;
        }
        contains(v) {
            if (v.x < this.min.x || v.x > this.max.x || v.y < this.min.y || v.y > this.max.y || v.z < this.min.z || v.z > this.max.z) {
                return false;
            }
            const idx = this._index(v.x, v.y, v.z);
            const byteIndex = idx >> 3;
            const bitOffset = idx & 7;
            const result = (this.bitmap[byteIndex] & 1 << bitOffset) !== 0;
            return result;
        }
    }
    function isNear(n1, n2) {
        return Math.abs(n1 - n2) < 1e-12;
    }
    class logInterface {
        debug(_m) {
            if (this._debug) this._debug(_m);
        }
        error(_m) {
            if (this._error) this._error(_m);
        }
        onStep(_path, _key, _type, _data, _properties) {
            if (this._onStep) {
                this._onStep(_path, _key, _type, _data, _properties);
            }
        }
    }
    var OpNodeSourceType;
    (function(OpNodeSourceType) {
        OpNodeSourceType["NULL"] = "null";
        OpNodeSourceType["BOOLEAN"] = "boolean";
        OpNodeSourceType["OBJECT"] = "object";
        OpNodeSourceType["ARRAY"] = "array";
        OpNodeSourceType["NUMBER"] = "number";
        OpNodeSourceType["INTEGER"] = "integer";
        OpNodeSourceType["STRING"] = "string";
        OpNodeSourceType["MAP"] = "map";
        OpNodeSourceType["ENUM"] = "enum";
    })(OpNodeSourceType || (OpNodeSourceType = {}));
    function _isDataOfType(data, type) {
        switch (type) {
          case OpNodeSourceType.NULL:
            return data === undefined;

          case OpNodeSourceType.BOOLEAN:
            return typeof data === "boolean";

          case OpNodeSourceType.ARRAY:
            return Array.isArray(data);

          case OpNodeSourceType.NUMBER:
            return typeof data === "number";

          case OpNodeSourceType.INTEGER:
            return Number.isInteger(data);

          case OpNodeSourceType.STRING:
            return typeof data === "string";

          case OpNodeSourceType.MAP:
          case OpNodeSourceType.OBJECT:
            return typeof data === "object";

          case OpNodeSourceType.ENUM:
            return typeof data === "string";

          default:
            return false;
        }
    }
    var OpNodeEditorUIControlType;
    (function(OpNodeEditorUIControlType) {
        OpNodeEditorUIControlType["FLOAT"] = "float";
        OpNodeEditorUIControlType["TEXT"] = "text";
        OpNodeEditorUIControlType["SLIDER"] = "slider";
        OpNodeEditorUIControlType["CHECKBOX"] = "checkbox";
        OpNodeEditorUIControlType["COLOR"] = "color";
        OpNodeEditorUIControlType["VECTOR3"] = "vector3";
        OpNodeEditorUIControlType["DROPDOWN"] = "dropdown";
        OpNodeEditorUIControlType["COLOR_TIMELINE"] = "color_timeline";
        OpNodeEditorUIControlType["NUMBER_TIMELINE"] = "number_timeline";
        OpNodeEditorUIControlType["UNKNOWN"] = "unknown";
    })(OpNodeEditorUIControlType || (OpNodeEditorUIControlType = {}));
    class OpPropertyPattern {
        constructor(pattern) {
            this._pattern = pattern;
        }
        get pattern() {
            return this._pattern;
        }
        clone() {
            return new OpPropertyPattern(this._pattern);
        }
        toString() {
            return `Pattern(${this._pattern})`;
        }
        validate(_key, _data, _log) {
            if (typeof _data !== "string") {
                _log?.error(`Key(${_key}): Data(${JSON.stringify(_data)}) is not a string`);
                return false;
            }
            const regex = new RegExp(this._pattern);
            const isMatch = regex.test(_data);
            if (!isMatch) {
                _log?.error(`Key(${_key}): Data(${String(_data)}) does not match pattern(${this._pattern})`);
            }
            return isMatch;
        }
    }
    class OpPropertyEditorTag {
        constructor(editorTag) {
            this._editorTag = editorTag;
        }
        get editorTag() {
            return this._editorTag;
        }
        clone() {
            return new OpPropertyEditorTag(this._editorTag);
        }
        toString() {
            return `Editor tag (${this._editorTag})`;
        }
        validate(_key, _data, _log) {
            return true;
        }
    }
    class OpPropertyValueRange {
        constructor(minimum, maximum) {
            this._minimum = minimum;
            this._maximum = maximum;
        }
        get min() {
            return this._minimum;
        }
        get max() {
            return this._maximum;
        }
        clone() {
            return new OpPropertyValueRange(this._minimum, this._maximum);
        }
        toString() {
            return `ValueRange(${this._minimum}, ${this._maximum})`;
        }
        validate(_key, data, _log) {
            if (typeof data !== "number") {
                _log?.error(`Key(${_key}): Data(${JSON.stringify(data)}) is not a number`);
                return false;
            }
            const isInRange = (isNear(data, this._minimum) || data > this._minimum) && (isNear(data, this._maximum) || data < this._maximum);
            if (!isInRange) {
                _log?.error(`Key(${_key}): Data(${Number(data)}) is not in range(${this._minimum}, ${this._maximum})`);
            }
            return isInRange;
        }
    }
    class OpPropertyArrayBounds {
        constructor(minItems, maxItems) {
            this._minItems = minItems;
            this._maxItems = maxItems;
        }
        get minItems() {
            return this._minItems;
        }
        get maxItems() {
            return this._maxItems;
        }
        clone() {
            return new OpPropertyArrayBounds(this._minItems, this._maxItems);
        }
        toString() {
            return `ArrayBounds(${String(this._minItems)}, ${String(this._maxItems)})`;
        }
        validate(_key, _data, _log) {
            if (!Array.isArray(_data)) {
                return false;
            }
            if (this._minItems !== undefined && _data.length < this._minItems) {
                _log?.error(`Key(${_key}): Data(${JSON.stringify(_data)}) has less than min items(${this._minItems})`);
                return false;
            }
            if (this._maxItems !== undefined && _data.length > this._maxItems) {
                _log?.error(`Key(${_key}): Data(${JSON.stringify(_data)}) has more than max items(${this._maxItems})`);
                return false;
            }
            return true;
        }
    }
    class OpPropertyMapBounds {
        constructor(minProperties, maxProperties) {
            this._minProperties = minProperties;
            this._maxProperties = maxProperties;
        }
        get minProperties() {
            return this._minProperties;
        }
        get maxProperties() {
            return this._maxProperties;
        }
        clone() {
            return new OpPropertyMapBounds(this._minProperties, this._maxProperties);
        }
        toString() {
            return `MapBounds(${String(this._minProperties)}, ${String(this._maxProperties)})`;
        }
        validate(_key, _data, _log) {
            if (typeof _data !== "object") {
                return false;
            }
            const keys = Object.keys(_data);
            if (this._minProperties !== undefined && keys.length < this._minProperties) {
                _log?.error(`Key(${_key}): Data(${JSON.stringify(_data)}) has less than min properties(${this._minProperties})`);
                return false;
            }
            if (this._maxProperties !== undefined && keys.length > this._maxProperties) {
                _log?.error(`Key(${_key}): Data(${JSON.stringify(_data)}) has more than max properties(${this._maxProperties})`);
                return false;
            }
            return true;
        }
    }
    class OpPropertyStringLiteral {
        constructor(literal) {
            this._literal = literal;
        }
        get literal() {
            return this._literal;
        }
        clone() {
            return new OpPropertyStringLiteral(this._literal);
        }
        toString() {
            return `Literal(${this._literal})`;
        }
        validate(_key, _data, _log) {
            const isMatch = _key.localeCompare(this._literal) === 0;
            return isMatch;
        }
    }
    class OpPropertyEnum {
        constructor(enums) {
            this._enums = [];
            this._prettyEnums = [];
            this._enums = enums;
            this._prettyEnums = enums.map((e => e));
        }
        get enums() {
            return this._enums;
        }
        get prettyEnums() {
            return this._prettyEnums;
        }
        prettifyEnums(prettyFunction) {
            this._prettyEnums = this._enums.map((e => prettyFunction(e)));
        }
        getIndexOf(data) {
            let index = this._enums.indexOf(data);
            if (index < 0) {
                index = this._prettyEnums.indexOf(data);
            }
            return index;
        }
        clone() {
            return new OpPropertyEnum(this._enums);
        }
        toString() {
            return `Enum(${this._prettyEnums.join(", ")})`;
        }
        validate(_key, _data, _log) {
            if (typeof _data !== "string") {
                return false;
            }
            const isMatch = this._enums.includes(_data) || this._prettyEnums.includes(_data);
            if (!isMatch) {
                _log?.error(`Key(${_key}): Data(${_data}) is not in enum[${this._enums.join(", ")}]`);
            }
            return isMatch;
        }
    }
    class OpPropertyReadOnly {
        clone() {
            return new OpPropertyReadOnly;
        }
        toString() {
            return `ReadOnly(true)`;
        }
        validate(_key, _data, _log) {
            return true;
        }
    }
    class OpPropertyPrettifier {
        clone() {
            return new OpPropertyPrettifier;
        }
        toString() {
            return `Prettify(true)`;
        }
        validate(_key, _data, _log) {
            return true;
        }
        prettify(_input) {
            if (_input.startsWith("minecraft:")) {
                _input = _input.substring(10);
            }
            _input = _input.replace(/_/g, " ");
            _input = _input.replace(/([a-z])([A-Z])/g, "$1 $2");
            _input = _input.split(" ").map((word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())).join(" ");
            return _input;
        }
    }
    class OpPropertyLabelAliases {
        constructor(labelRemaps) {
            this._labelRemaps = labelRemaps;
        }
        get aliases() {
            return this._labelRemaps;
        }
        addAlias(_original, _new) {
            this._labelRemaps[_original] = _new;
        }
        clone() {
            return new OpPropertyLabelAliases(this._labelRemaps);
        }
        toString() {
            return `Labels(${Object.entries(this._labelRemaps).map((([key, value]) => `${key}:${value}`)).join(", ")})`;
        }
        validate(_key, _data, _log) {
            if (typeof this._labelRemaps !== "object" && !Array.isArray(this._labelRemaps)) {
                _log?.error(`format for alias ${JSON.stringify(this._labelRemaps)} is invalid`);
                return false;
            }
            const isMatch = Object.keys(this._labelRemaps).every((key => typeof key === "string" && typeof this._labelRemaps[key] === "string"));
            return isMatch;
        }
        getLabelAlias(_label) {
            return this._labelRemaps[_label] ?? _label;
        }
    }
    class OpPropertyTags {
        constructor(_tags) {
            this._tags = [];
            this._tags = _tags;
        }
        get tags() {
            return this._tags;
        }
        addTag(_new) {
            this.tags.push(_new);
        }
        clone() {
            return new OpPropertyTags(this._tags);
        }
        toString() {
            return `Tags(${this._tags.join(", ")})`;
        }
        validate(_tag, _log) {
            if (typeof this._tags !== "object" && !Array.isArray(this._tags)) {
                _log?.error(`format for tags ${JSON.stringify(this._tags)} is invalid`);
                return false;
            }
            const isMatch = this._tags.some((tag => tag === _tag));
            return isMatch;
        }
    }
    class OpPropertyHelp {
        constructor(_help) {
            this._help = _help;
        }
        get help() {
            return this._help;
        }
        clone() {
            return new OpPropertyHelp(this._help);
        }
        toString() {
            return `Help(${this._help})`;
        }
        validate(_help, _log) {
            return true;
        }
    }
    class OpPropertyType {
        constructor(type) {
            this._type = OpNodeSourceType.NULL;
            this._type = type;
        }
        get type() {
            return this._type;
        }
        clone() {
            return new OpPropertyType(this._type);
        }
        toString() {
            return `Type(${this._type})`;
        }
        validate(_key, _data, _log) {
            return _isDataOfType(_data, this._type);
        }
    }
    class OpPropertyEditorUIControl {
        constructor(controlType) {
            this._controlType = OpNodeEditorUIControlType.UNKNOWN;
            this._controlType = controlType;
        }
        get controlType() {
            return this._controlType;
        }
        clone() {
            return new OpPropertyEditorUIControl(this._controlType);
        }
        toString() {
            return `EditorControl(${this._controlType})`;
        }
        validate(_key, _data, _log) {
            return true;
        }
    }
    class OpPropertyStack {
        constructor() {
            this._properties = [];
        }
        addOrReplaceProperty(property) {
            for (let i = 0; i < this._properties.length; i++) {
                if (this._properties[i].constructor.name === property.constructor.name) {
                    this._properties[i] = property;
                    return;
                }
            }
            this._properties.push(property);
        }
        removeProperty(propType) {
            for (let i = 0; i < this._properties.length; i++) {
                if (this._properties[i].constructor.name === propType) {
                    this._properties.splice(i, 1);
                    return;
                }
            }
        }
        hasProperty(propType) {
            for (let i = 0; i < this._properties.length; i++) {
                if (this._properties[i].constructor.name === propType) {
                    return true;
                }
            }
            return false;
        }
        getProperty(propType) {
            for (let i = 0; i < this._properties.length; i++) {
                if (this._properties[i].constructor.name === propType) {
                    return this._properties[i];
                }
            }
            return undefined;
        }
        _extractEditorProperties(_node, _schemaTagString) {
            if (!_schemaTagString || _schemaTagString.length === 0) {
                return;
            }
            const splitKeyValuePairs = data => {
                const pairs = [];
                let inBraces = false;
                let key = "";
                let current = "";
                let expectValue = false;
                for (const char of data) {
                    if (char === "{") {
                        inBraces = true;
                        current += char;
                    } else if (char === "}") {
                        inBraces = false;
                        current += char;
                    } else if (char === ":" && !inBraces) {
                        key = current.trim();
                        current = "";
                        expectValue = true;
                    } else if (char === "," && !inBraces) {
                        const keyValue = current.trim();
                        pairs.push({
                            key,
                            keyValue
                        });
                        current = "";
                        expectValue = false;
                    } else {
                        current += char;
                    }
                }
                if (expectValue) {
                    const keyValue = current.trim();
                    pairs.push({
                        key,
                        keyValue
                    });
                }
                return pairs;
            };
            const isValidTagOrLabel = name => {
                const identifierRegex = /^[A-Za-z_][A-Za-z0-9_]*$/;
                return identifierRegex.test(name);
            };
            const keyValuePairs = splitKeyValuePairs(_schemaTagString);
            const aliasRemaps = new OpPropertyLabelAliases({});
            const tags = new OpPropertyTags([]);
            let help;
            for (const {key, keyValue} of keyValuePairs) {
                if (key === "alias" && keyValue.startsWith("{") && keyValue.endsWith("}")) {
                    const aliasKeyValue = keyValue.slice(1, -1);
                    const aliasKeyValuePairs = splitKeyValuePairs(aliasKeyValue);
                    Object.entries(aliasKeyValuePairs).forEach((([_, value]) => {
                        const aliasKey = value.key.trim();
                        const aliasValue = value.keyValue.trim();
                        if (aliasKey && aliasValue) {
                            aliasRemaps.addAlias(aliasKey, aliasValue);
                        } else {
                            throw new Error(`Invalid alias key-value pair: ${JSON.stringify(keyValuePairs)}`);
                        }
                    }));
                } else if (key === "tag" && keyValue.startsWith("{") && keyValue.endsWith("}")) {
                    const tagKeyValue = keyValue.slice(1, -1);
                    const tagKeyValuePairs = tagKeyValue.split(",");
                    tagKeyValuePairs.forEach((tag => {
                        const t = tag.trim();
                        if (!isValidTagOrLabel(t)) {
                            throw new Error(`Invalid tag: ${t}`);
                        }
                        tags.addTag(t);
                    }));
                } else if (key === "help" && keyValue.startsWith("{") && keyValue.endsWith("}")) {
                    const tagKeyValue = keyValue.slice(1, -1);
                    help = new OpPropertyHelp(tagKeyValue.trim());
                } else {
                    if (!(key && keyValue)) {
                        throw new Error(`Invalid (key:value,...) key-value pair: ${JSON.stringify(keyValuePairs)}`);
                    }
                    const prettifyOrReadonlyModifier = keyValue === "true" || keyValue === "1" || keyValue === "yes" || keyValue === "on";
                    if (key === "prettify") {
                        if (prettifyOrReadonlyModifier) {
                            this.addOrReplaceProperty(new OpPropertyPrettifier);
                        }
                    } else if (key === "readonly") {
                        if (prettifyOrReadonlyModifier) {
                            this.addOrReplaceProperty(new OpPropertyReadOnly);
                        }
                    } else if (key === "type") {
                        let controlType = OpNodeEditorUIControlType.FLOAT;
                        switch (keyValue) {
                          case "float":
                          case "number":
                            controlType = OpNodeEditorUIControlType.FLOAT;
                            break;

                          case "text":
                          case "string":
                            controlType = _node.enum !== undefined ? OpNodeEditorUIControlType.DROPDOWN : OpNodeEditorUIControlType.TEXT;
                            break;

                          case "enum":
                          case "dropdown":
                            controlType = OpNodeEditorUIControlType.DROPDOWN;
                            break;

                          case "slider":
                            controlType = OpNodeEditorUIControlType.SLIDER;
                            break;

                          case "checkbox":
                          case "boolean":
                          case "bool":
                            controlType = OpNodeEditorUIControlType.CHECKBOX;
                            break;

                          case "color":
                            controlType = OpNodeEditorUIControlType.COLOR;
                            break;

                          case "vector3":
                          case "vec3":
                            controlType = OpNodeEditorUIControlType.VECTOR3;
                            break;

                          case "colorTimeline":
                            controlType = OpNodeEditorUIControlType.COLOR_TIMELINE;
                            break;

                          case "numberTimeline":
                            controlType = OpNodeEditorUIControlType.NUMBER_TIMELINE;
                            break;

                          default:
                            controlType = OpNodeEditorUIControlType.UNKNOWN;
                            throw new Error(`Unknown editor control type: ${keyValue}`);
                        }
                        this.addOrReplaceProperty(new OpPropertyEditorUIControl(controlType));
                    }
                }
            }
            if (Object.keys(aliasRemaps.aliases).length > 0) {
                this.addOrReplaceProperty(aliasRemaps);
            }
            if (Object.keys(tags.tags).length > 0) {
                this.addOrReplaceProperty(tags);
            }
            if (help !== undefined) {
                this.addOrReplaceProperty(help);
            }
        }
        extractProperties(node) {
            if (node === undefined) {
                return;
            }
            if (node.type !== undefined) {
                let nodeType = OpNodeSourceType.NULL;
                switch (node.type) {
                  case "null":
                    nodeType = OpNodeSourceType.NULL;
                    break;

                  case "boolean":
                    nodeType = OpNodeSourceType.BOOLEAN;
                    break;

                  case "object":
                    nodeType = node.additionalProperties !== undefined ? OpNodeSourceType.MAP : OpNodeSourceType.OBJECT;
                    break;

                  case "array":
                    nodeType = OpNodeSourceType.ARRAY;
                    break;

                  case "number":
                    nodeType = OpNodeSourceType.NUMBER;
                    break;

                  case "integer":
                    nodeType = OpNodeSourceType.INTEGER;
                    break;

                  case "string":
                    nodeType = node.enum !== undefined ? OpNodeSourceType.ENUM : OpNodeSourceType.STRING;
                    break;

                  default:
                    throw new Error(`Unknown type: ${JSON.stringify(node.type)}`);
                }
                this.addOrReplaceProperty(new OpPropertyType(nodeType));
            }
            if (node.enum !== undefined) {
                const enumArray = [ ...node.enum ];
                this.addOrReplaceProperty(new OpPropertyEnum(enumArray));
            }
            if (node.$metaProperties !== undefined && node.$metaProperties.CEREAL_EDITOR_SCHEMA_TAG !== undefined) {
                this.addOrReplaceProperty(new OpPropertyEditorTag(node.$metaProperties.CEREAL_EDITOR_SCHEMA_TAG));
                const description = String(node.$metaProperties.CEREAL_EDITOR_SCHEMA_TAG).trim();
                this._extractEditorProperties(node, description);
            }
            if (node.minimum !== undefined && node.maximum !== undefined && !this.hasProperty(OpPropertyValueRange.name)) {
                this.addOrReplaceProperty(new OpPropertyValueRange(node.minimum, node.maximum));
            }
            if (node.pattern !== undefined) {
                this.addOrReplaceProperty(new OpPropertyPattern(node.pattern));
            }
            if (node.minProperties !== undefined || node.maxProperties !== undefined || node.additionalProperties !== undefined) {
                this.addOrReplaceProperty(new OpPropertyMapBounds(node.minProperties, node.maxProperties));
            } else if (node.minItems !== undefined || node.maxItems !== undefined || node.items !== undefined) {
                this.addOrReplaceProperty(new OpPropertyArrayBounds(node.minItems, node.maxItems));
            }
        }
        clone() {
            const stack = new OpPropertyStack;
            for (const property of this._properties) {
                stack.addOrReplaceProperty(property.clone());
            }
            return stack;
        }
        toString() {
            let str = "";
            for (let i = this._properties.length - 1; i >= 0; i--) {
                str += this._properties[i].toString() + " ";
            }
            return str;
        }
        validateAll(_key, _data, _log) {
            for (let i = this._properties.length - 1; i >= 0; i--) {
                if (!this._properties[i].validate(_key, _data, _log)) {
                    return false;
                }
            }
            return true;
        }
        validate(_type, _key, data, _log) {
            const property = this.getProperty(_type);
            if (property === undefined) {
                return true;
            }
            return property.validate(_key, data, _log);
        }
    }
    class OpBaseNode {
        constructor(_tabDepth, _schemaObject, _refMap, _propertyStack, _logger) {
            this._type = OpNodeSourceType.NULL;
            this._children = [];
            this._propertyStack = new OpPropertyStack;
            this._logger = _logger;
            _tabDepth = _tabDepth + "    ";
            if (_schemaObject === undefined) {
                throw new Error("SchemaObject is undefined");
            }
            _propertyStack.extractProperties(_schemaObject);
            _schemaObject = _refMap.resolve(_schemaObject);
            _propertyStack.extractProperties(_schemaObject);
            this._propertyStack = _propertyStack.clone();
            this._title = _schemaObject?.title ?? "";
            this._editorMetaProperties = _schemaObject?.$metaProperties?.CEREAL_EDITOR_SCHEMA_TAG ?? "";
            this._type = _schemaObject?.type ?? OpNodeSourceType.OBJECT;
            this._isArray = _schemaObject?.items !== undefined || this._title === "sequence container";
            this._isMap = _schemaObject?.additionalProperties !== undefined || this._title === "associative container";
            this._id = _schemaObject?.$id ?? "no-id";
            this._oneOf = _schemaObject?.oneOf !== undefined;
            if (this._type === "object" && this._isMap) {
                this._type = OpNodeSourceType.MAP;
            } else if (this._type === "object" && this._isArray) {
                this._type = OpNodeSourceType.ARRAY;
            }
            this._logger?.debug(`${_tabDepth}Title: ${this._title}, Id: ${this._id}, Type: ${this._type}, OneOf: ${this._oneOf}, Array: ${this._isArray}, Map: ${this._isMap}`);
            this._logger?.debug(`  ${_tabDepth}props[ ${this._propertyStack.toString()} ]`);
            if (typeof _schemaObject === "object") {
                if (_schemaObject.oneOf !== undefined) {
                    for (const oneOfObject of _schemaObject.oneOf) {
                        const oneOfPropertyStack = _propertyStack.clone();
                        oneOfPropertyStack.extractProperties(oneOfObject);
                        oneOfPropertyStack.removeProperty("OpPropertyStringLiteral");
                        const node = new OpBaseNode(_tabDepth, oneOfObject, _refMap, oneOfPropertyStack, this._logger);
                        this._children.push(node);
                    }
                } else if (_schemaObject.properties !== undefined) {
                    for (const key in _schemaObject.properties) {
                        const propertyPropertyStack = _propertyStack.clone();
                        let property = _schemaObject.properties[key];
                        propertyPropertyStack.extractProperties(property);
                        property = _refMap.resolve(property);
                        propertyPropertyStack.extractProperties(property);
                        propertyPropertyStack.addOrReplaceProperty(new OpPropertyStringLiteral(key));
                        const node = new OpBaseNode(_tabDepth, property, _refMap, propertyPropertyStack, this._logger);
                        this._children.push(node);
                    }
                } else {
                    if (this._type === OpNodeSourceType.ARRAY) {
                        if (_schemaObject.items !== undefined) {
                            const itemPropertyStack = _propertyStack.clone();
                            itemPropertyStack.extractProperties(_schemaObject.items);
                            itemPropertyStack.removeProperty("OpPropertyArrayBounds");
                            itemPropertyStack.removeProperty("OpPropertyStringLiteral");
                            const node = new OpBaseNode(_tabDepth, _schemaObject.items, _refMap, itemPropertyStack, this._logger);
                            this._children.push(node);
                        }
                    } else if (this._type === OpNodeSourceType.MAP) {
                        const additionalPropertyStack = _propertyStack.clone();
                        additionalPropertyStack.extractProperties(_schemaObject.additionalProperties);
                        additionalPropertyStack.removeProperty("OpPropertyMapBounds");
                        additionalPropertyStack.removeProperty("OpPropertyStringLiteral");
                        const uiControl = additionalPropertyStack.getProperty("OpPropertyEditorUIControl");
                        if (uiControl !== undefined) {
                            if (uiControl.controlType === OpNodeEditorUIControlType.COLOR_TIMELINE || uiControl.controlType === OpNodeEditorUIControlType.NUMBER_TIMELINE) {
                                additionalPropertyStack.removeProperty("OpPropertyEditorUIControl");
                            }
                            if (uiControl.controlType === OpNodeEditorUIControlType.NUMBER_TIMELINE && _schemaObject.minimum !== undefined && _schemaObject.maximum !== undefined) {
                                additionalPropertyStack.addOrReplaceProperty(new OpPropertyValueRange(_schemaObject.minimum, _schemaObject.maximum));
                            }
                        }
                        const node = new OpBaseNode(_tabDepth, _schemaObject.additionalProperties, _refMap, additionalPropertyStack, this._logger);
                        this._children.push(node);
                    } else {
                        this._logger?.debug(`  ${_tabDepth}No properties or oneOf`);
                    }
                }
            } else {
                this._logger?.debug(`  ${_tabDepth} current schema object is ${typeof _schemaObject} should be type object`);
            }
        }
        hasMatchingKey(_key) {
            const literalProperty = this._propertyStack.getProperty("OpPropertyStringLiteral");
            if (literalProperty !== undefined) {
                const literal = literalProperty;
                if (literal.literal === _key) {
                    return true;
                }
            }
            return true;
        }
        validate(_key, _data, _tabDepth, _path) {
            _tabDepth = _tabDepth + "    ";
            if (!this._oneOf && _key !== "") {
                _path += "/" + _key;
            }
            this._logger?.debug(`${_tabDepth}Node: ${this._title}, Type: ${this._type}, Id: ${this._id}, OneOf: ${this._oneOf}, Props: ${this._propertyStack.toString()}, Children: ${this._children.length}`);
            this._logger?.debug(`${_tabDepth}incoming Key: ${_key}, Type: ${typeof _data}, Data: ${JSON.stringify(_data)}, `);
            const isArray = Array.isArray(_data);
            if (!this._oneOf) {
                if (!this._propertyStack.validate("OpPropertyStringLiteral", _key, _data, this._logger)) {
                    return false;
                }
                if (!_isDataOfType(_data, this._type)) {
                    this._logger?.debug(`${_tabDepth}  Type mismatch: ${typeof _data} != ${this._type} (Array: ${isArray})`);
                    return false;
                }
                if (!this._propertyStack.validate("OpPropertyType", _key, _data, this._logger)) {
                    this._logger?.debug(`${_tabDepth}  Type mismatch: ${typeof _data} != ${this._type} (Array: ${isArray})`);
                    return false;
                }
                if (this._type === OpNodeSourceType.ARRAY) {
                    if (!this._propertyStack.validate("OpPropertyArrayBounds", _key, _data, this._logger)) {
                        return false;
                    }
                }
                if (this._type === OpNodeSourceType.MAP) {
                    if (!this._propertyStack.validate("OpPropertyMapBounds", _key, _data, this._logger)) {
                        return false;
                    }
                }
                if (this.type === OpNodeSourceType.STRING) {
                    if (!this._propertyStack.validate("OpPropertyPattern", _key, _data, this._logger)) {
                        return false;
                    }
                }
                if (this.type === OpNodeSourceType.NUMBER || this.type === OpNodeSourceType.INTEGER) {
                    if (!this._propertyStack.validate("OpPropertyValueRange", _key, _data, this._logger)) {
                        return false;
                    }
                }
            }
            if (!this._propertyStack.validate("OpPropertyStringLiteral", _key, _data, this._logger)) {
                return false;
            }
            if (!this._propertyStack.validate("OpPropertyEditorTag", _key, _data, this._logger)) {
                return false;
            }
            if (!this._propertyStack.validate("OpPropertyLabelAliases", _key, _data, this._logger)) {
                return false;
            }
            if (!this._oneOf) {
                if (_path !== "" && _key !== "") {
                    this._logger?.onStep(_path, _key, this._type, _data, this._propertyStack);
                }
            }
            if (this._type === OpNodeSourceType.OBJECT || this._type === OpNodeSourceType.MAP || this._oneOf) {
                if (this._oneOf) {
                    for (const child of this._children) {
                        if (child.validate(_key, _data, _tabDepth, _path)) {
                            return true;
                        }
                    }
                    this._logger?.debug(`${_tabDepth}  Object bounds validation failed (Key: ${_key}, Data: ${JSON.stringify(_data)})`);
                    return false;
                }
                for (const objectKey in _data) {
                    let found = false;
                    for (const child of this._children) {
                        if (child.hasMatchingKey(objectKey)) {
                            if (child.validate(objectKey, _data[objectKey], _tabDepth, _path)) {
                                found = true;
                                break;
                            }
                        }
                    }
                    if (!found) {
                        return false;
                    }
                }
                this._logger?.debug(`${_tabDepth}  All object properties validated successfully`);
                return true;
            } else if (isArray) {
                for (let index = 0; index < _data.length; index++) {
                    const element = _data[index];
                    for (const child of this._children) {
                        if (!child.validate(String(index), element, _tabDepth, _path)) {
                            this._logger?.debug(`${_tabDepth}  Array validation failed`);
                            return false;
                        }
                    }
                }
                this._logger?.debug(`${_tabDepth}  Array validation PASSED`);
                return true;
            } else if (this._type === OpNodeSourceType.STRING) {
                const propertyType = this._propertyStack.getProperty("OpPropertyType");
                if (propertyType !== undefined) {
                    if (propertyType.type === OpNodeSourceType.ENUM) {
                        const enumProperty = this._propertyStack.getProperty("OpPropertyEnum");
                        if (enumProperty !== undefined) {
                            if (!enumProperty.validate(_key, _data, this._logger)) {
                                return false;
                            }
                            this._logger?.debug(`${_tabDepth}  Enum validation PASSED`);
                            return true;
                        } else {
                            this._logger?.debug(`${_tabDepth}  Enum property not found`);
                            return false;
                        }
                    }
                }
            }
            this._logger?.debug(`${_tabDepth}  Data: "${_key} : ${JSON.stringify(_data)}" - appears valid`);
            return true;
        }
        get title() {
            return this._title;
        }
        get editorProperties() {
            return this._editorMetaProperties;
        }
        get type() {
            return this._type;
        }
        get id() {
            return this._id;
        }
    }
    class SchemaRefMap {
        constructor(_definitions) {
            this._map = new Map;
            if (_definitions !== undefined) {
                for (const key in _definitions) {
                    this._map.set(key, _definitions[key]);
                }
            }
        }
        resolve(_schema) {
            if (_schema === undefined) {
                throw new Error("Schema is undefined");
            }
            const refPrologue = "#/definitions/";
            if (_schema.$ref === undefined) {
                return _schema;
            }
            let ref = _schema.$ref;
            if (ref.startsWith(refPrologue)) {
                ref = ref.substring(refPrologue.length);
            } else {
                throw new Error(`Failed to resolve ref: ${String(_schema.$ref)}`);
            }
            const result = this._map.get(ref);
            if (result === undefined) {
                throw new Error(`Failed to resolve ref: ${String(_schema.$ref)}`);
            }
            return this.resolve(result);
        }
    }
    class SchemaValidatorBuilder {
        constructor(_logger) {
            this._schemaObject = {};
            this._root = undefined;
            this._refMap = new SchemaRefMap(undefined);
            this._logger = _logger;
        }
        build(_schemaObject) {
            this._schemaObject = _schemaObject;
            if (_schemaObject.definitions !== undefined) {
                this._refMap = new SchemaRefMap(_schemaObject.definitions);
            }
            try {
                const root = new OpBaseNode("", _schemaObject, this._refMap, new OpPropertyStack, this._logger);
                this._root = root;
            } catch {
                this._logger?.error(`Failed to build schema`);
                return false;
            }
            return true;
        }
        validate(_data) {
            if (_data === undefined) {
                throw new Error("Data is undefined");
            }
            if (this._root === undefined) {
                throw new Error("No Schema Map built yet");
            }
            return this._root.validate("", _data, "", "");
        }
    }
    async function deleteOperation(uiSession) {
        if (uiSession.extensionContext.selectionManager.volume.isEmpty) {
            uiSession.log.warning("resourcePack.editor.selectionTool.toast.delete.noSelection", {
                channelMask: server_editor_namespaceObject.LogChannel.All
            });
            return;
        }
        const selectionVolume = uiSession.extensionContext.selectionManager.volume.get();
        const onError = e => {
            uiSession.log.error(e.message);
        };
        await executeFunctionWithTransactionAndTicking(uiSession.extensionContext, uiSession.log, selectionVolume, "Delete", (() => {
            uiSession.extensionContext.blockUtilities.fillVolume(selectionVolume, lib_vanilla_MinecraftBlockTypes.Air);
        })).catch(onError);
    }
    class DeleteBehavior {
        constructor(uiSession, coreMenuItems) {
            const deleteAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    deleteOperation(uiSession).catch((e => uiSession.log.error(e.message, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    })));
                }
            });
            coreMenuItems.edit.addItem({
                label: "resourcePack.editor.menuBar.edit.delete",
                tooltip: "resourcePack.editor.menuBar.edit.delete.tooltip"
            }, deleteAction);
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalEditor, deleteAction, {
                key: server_editor_namespaceObject.KeyboardKey.DELETE
            }, {
                uniqueId: "editor:toolModeKeyBinding:delete",
                label: "resourcePack.editor.delete.keyBinding.title",
                tooltip: "resourcePack.editor.delete.keyBinding.tooltip"
            });
        }
        teardown() {}
    }
    class PreviewVolume {
        constructor(uiSession) {
            this._session = uiSession;
            this._outlineColor = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeFill);
            this._hullColor = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeBorder);
            this._highlightOutlineColor = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeOutlineBorder);
            this._highlightHullColor = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeOutlineFill);
            const dimensionBounds = this.session.extensionContext.blockUtilities.getDimensionLocationBoundingBox();
            const center = server_namespaceObject.BlockBoundingBoxUtils.getCenter(dimensionBounds);
            this._volume = new server_editor_namespaceObject.RelativeVolumeListBlockVolume;
            this._widgetGroup = this.session.extensionContext.widgetManager.createGroup({
                visible: true
            });
            this._widget = this._widgetGroup.createWidget(center, {
                visible: false,
                selectable: false
            });
            this._widgetVolumeComponent = this._widget.addVolumeOutline("outline", this._volume, {
                outlineColor: this._outlineColor,
                hullColor: this._hullColor,
                highlightOutlineColor: this._highlightOutlineColor,
                highlightHullColor: this._highlightHullColor,
                showOutline: false,
                showHighlightOutline: true,
                visible: true
            });
        }
        get session() {
            return this._session;
        }
        get locationIterator() {
            return this._volume.getBlockLocationIterator();
        }
        get isEmpty() {
            return this._volume.isEmpty;
        }
        get bounds() {
            return this._volume.getBoundingBox();
        }
        get volume() {
            return this._volume;
        }
        get visible() {
            return this._widget.visible;
        }
        set visible(value) {
            if (this._widget !== undefined && this._widget.visible !== value) {
                this._widget.visible = value;
            }
        }
        get location() {
            return this._widget.location;
        }
        set location(position) {
            this._widget.location = position;
        }
        set outlineColor(value) {
            this._outlineColor = value;
            this._widgetVolumeComponent.outlineColor = value;
        }
        set hullColor(value) {
            this._hullColor = value;
            this._widgetVolumeComponent.hullColor = value;
        }
        set highlightOutlineColor(value) {
            this._highlightOutlineColor = value;
            this._widgetVolumeComponent.highlightOutlineColor = value;
        }
        set highlightHullColor(value) {
            this._highlightHullColor = value;
            this._widgetVolumeComponent.highlightHullColor = value;
        }
        addVolume(volume) {
            this._volume.add(volume);
            if (this._volume.isEmpty) {
                return;
            }
            const bounds = this._volume.getBoundingBox();
            this._widget.location = bounds.min;
        }
        removeVolume(volume) {
            this._volume.remove(volume);
            if (this._volume.isEmpty) {
                return;
            }
            const bounds = this._volume.getBoundingBox();
            this._widget.location = bounds.min;
        }
        clearVolume() {
            this._volume.clear();
        }
        teardown() {
            this._widgetVolumeComponent.delete();
            this._widget.delete();
            this._widgetGroup.delete();
        }
    }
    var LineTelemetry;
    (function(LineTelemetry) {
        LineTelemetry["QuickAction"] = "QuickAction";
        LineTelemetry["LeftClick"] = "LeftClick";
        LineTelemetry["ToggleSelectPoint"] = "ToggleSelectPoint";
        LineTelemetry["ClearAllPoints"] = "ClearAllPoints";
        LineTelemetry["ClearSelectedPoints"] = "ClearSelectedPoints";
        LineTelemetry["FillLine"] = "FillLine";
        LineTelemetry["DeleteBlocks"] = "DeleteBlocks";
        LineTelemetry["ToggleSelectAll"] = "ToggleSelectAll";
        LineTelemetry["AddToSelection"] = "AddToSelection";
        LineTelemetry["WeightChanged"] = "WeightChanged";
        LineTelemetry["SelectionModeChanged"] = "SelectionModeChanged";
        LineTelemetry["AlgorithmChanged"] = "AlgorithmChanged";
        LineTelemetry["Nudge"] = "Nudge";
        LineTelemetry["Move"] = "Move";
    })(LineTelemetry || (LineTelemetry = {}));
    var CurveType;
    (function(CurveType) {
        CurveType[CurveType["None"] = 0] = "None";
        CurveType[CurveType["Hermite"] = 1] = "Hermite";
    })(CurveType || (CurveType = {}));
    var EaseType;
    (function(EaseType) {
        EaseType[EaseType["Linear"] = 0] = "Linear";
    })(EaseType || (EaseType = {}));
    class LinePreviewMap {
        constructor(uiSession) {
            this._uiSession = uiSession;
            this._previewVolume = new PreviewVolume(this._uiSession);
            this._locationMapping = new Map;
            const yellow = {
                red: .84,
                green: .7,
                blue: .09,
                alpha: .35
            };
            this.previewVolume.highlightHullColor = yellow;
        }
        get previewVolume() {
            return this._previewVolume;
        }
        addPoints(points) {
            for (let i = 0; i < points.length; i++) {
                const key = this.vector3ToString(points[i]);
                const value = this._locationMapping.get(key);
                this._locationMapping.set(key, value !== undefined ? value + 1 : 1);
            }
            this._previewVolume.addVolume(points);
            if (!this._previewVolume.visible && this._locationMapping.size > 0) {
                this._previewVolume.visible = true;
            }
        }
        removePoints(points) {
            const removedPts = [];
            for (let i = 0; i < points.length; i++) {
                const key = this.vector3ToString(points[i]);
                const value = this._locationMapping.get(key);
                if (value !== undefined) {
                    if (value === 1) {
                        this._locationMapping.delete(key);
                        removedPts.push(points[i]);
                    } else {
                        this._locationMapping.set(key, value - 1);
                    }
                }
            }
            this._previewVolume.removeVolume(removedPts);
        }
        hasPoint(point) {
            return this._locationMapping.has(this.vector3ToString(point));
        }
        clear() {
            this._previewVolume.visible = false;
            this._previewVolume.clearVolume();
            this._locationMapping.clear();
            this._previewVolume.visible = true;
        }
        teardown() {
            this.clear();
            this._previewVolume.visible = false;
            this._previewVolume.teardown();
        }
        vector3ToString(point) {
            return `${point.x},${point.y},${point.z}`;
        }
        stringToVector3(pointString) {
            let index = 0;
            const x = parseInt(pointString.slice(index, index = pointString.indexOf(",")), 10);
            const y = parseInt(pointString.slice(index + 1, index = pointString.indexOf(",", index + 1)), 10);
            const z = parseInt(pointString.slice(index + 1), 10);
            return {
                x,
                y,
                z
            };
        }
    }
    class ControlPoint extends BlockPoint {
        constructor(location, isSeparate, weightsOverridden, usingUniformValues, horizontalWeight, verticalWeight, blockLineTypeAlgorithm, linePreviewMap, widgetGroup, requestCursorTargetMode, requestGroundLevelAtLocation, gizmoMovedEvent, gizmoGrabbedEvent, gizmoReleasedEvent) {
            const blockPointType = blockLineTypeAlgorithm === BlockLineType.Direct || blockLineTypeAlgorithm === BlockLineType.Staggered ? BlockPointType.Normal : BlockPointType.Contour;
            super(location, requestCursorTargetMode, requestGroundLevelAtLocation, {
                horizontalWeight,
                verticalWeight,
                blockPointType
            });
            this._isSeparate = isSeparate;
            this._weightsOverridden = weightsOverridden;
            this._usingUniformValues = usingUniformValues;
            this._linePreviewMap = linePreviewMap;
            this._visible = false;
            this._widget = widgetGroup.createWidget(location, {
                selectable: true,
                snapToBlockLocation: true,
                visible: true,
                collisionOffset: {
                    x: .5,
                    y: .5,
                    z: .5
                },
                collisionRadius: 0,
                widgetName: "Line Tool - Control Point",
                stateChangeEvent: data => {
                    if (data.location !== undefined && !lib.Vector3Utils.equals(data.location, this.location)) {
                        const textComponent = data.widget.getComponent("position_text");
                        if (textComponent) {
                            textComponent.label = lib.Vector3Utils.toString(data.location, {
                                decimals: 1
                            });
                        }
                    }
                }
            });
            this._widget.addTextComponent("position_text", lib.Vector3Utils.toString(location, {
                decimals: 1
            }), {
                offset: {
                    x: .5,
                    y: 1,
                    z: .5
                },
                visible: true
            });
            this._movementGizmo = this._widget.addGizmoComponent("position_gizmo", {
                offset: {
                    x: .5,
                    y: .5,
                    z: .5
                },
                visible: true,
                stateChangeEvent: data => {
                    if (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerMoved || data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginMoved) {
                        if (!lib.Vector3Utils.equals(this.location, data.widget.location)) {
                            gizmoMovedEvent(this.location, data.widget.location, data.widget);
                        }
                    } else if (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginGrabbed || data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerGrabbed) {
                        gizmoGrabbedEvent(data.widget.location);
                    } else if (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginReleased || data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerReleased) {
                        gizmoReleasedEvent(data.widget.location);
                    }
                }
            });
            this._widget.addGuideComponent("position_guide");
        }
        get widget() {
            return this._widget;
        }
        get isSeparate() {
            return this._isSeparate;
        }
        get isSelected() {
            return this._widget.selected;
        }
        get isWeightsOverridden() {
            return this._weightsOverridden;
        }
        get usingUniformValues() {
            return this._usingUniformValues;
        }
        set isSelected(isSelected) {
            this._widget.selected = isSelected;
            this.setGizmoActivated(isSelected);
        }
        setWeightsOverridden(weightsOverridden) {
            this._weightsOverridden = weightsOverridden;
        }
        setUsingUniformValues(usingUniformValues) {
            this._usingUniformValues = usingUniformValues;
        }
        get visible() {
            return this._visible;
        }
        set visible(newIsVisible) {
            if (this._visible !== newIsVisible) {
                if (newIsVisible) {
                    this._linePreviewMap.addPoints([ ...this.lineDataIterator ]);
                } else {
                    this._linePreviewMap.removePoints([ ...this.lineDataIterator ]);
                }
                this._visible = newIsVisible;
            }
        }
        setGizmoActivated(isActivated) {
            this._movementGizmo.activated = isActivated;
        }
        move(targetLocation, moveGizmo = false) {
            const results = this.movePoint(targetLocation);
            if (moveGizmo) {
                this._widget.location = targetLocation;
            }
            return results;
        }
        teardown() {
            this.removeSplineComponent();
            this._widget?.delete();
        }
        getSplineComponentInterpPoints() {
            if (this._splineComponent) {
                let interpPoints = this._splineComponent.getInterpolatedPoints();
                for (const pts of interpPoints) {
                    pts.x = Math.floor(pts.x);
                    pts.y = Math.floor(pts.y);
                    pts.z = Math.floor(pts.z);
                }
                interpPoints = interpPoints.filter(((obj1, i, arr) => arr.findIndex((obj2 => lib.Vector3Utils.equals(obj2, obj1))) === i));
                interpPoints.shift();
                return interpPoints;
            }
            return [];
        }
        addSplineComponent(widgets) {
            if (this._splineComponent) {
                this.removeSplineComponent();
            }
            this._splineComponent = this._widget.addSplineComponent("spline", {
                splineType: server_editor_namespaceObject.SplineType.Hermite,
                controlPoints: widgets,
                offset: {
                    x: .5,
                    y: .5,
                    z: .5
                },
                visible: false
            });
        }
        addControlPointsToSplineComponent(widgets) {
            if (this._splineComponent) {
                let prevWidgets = this._splineComponent.getControlPoints();
                prevWidgets = prevWidgets.concat(widgets);
                this._splineComponent.setControlPoints(prevWidgets);
            }
        }
        removeControlPointsFromSplineComponent(widgets) {
            if (this._splineComponent) {
                const prevWidgets = this._splineComponent.getControlPoints();
                const newWidgets = prevWidgets.filter((value => !widgets.includes(value)));
                this._splineComponent.setControlPoints(newWidgets);
            }
        }
        removeAllControlPointsFromSplineComponent() {
            if (this._splineComponent) {
                this._splineComponent.setControlPoints([]);
            }
        }
        removeSplineComponent() {
            if (this._splineComponent) {
                this._widget.deleteComponent(this._splineComponent);
                this._splineComponent = undefined;
            }
        }
    }
    ControlPoint.MAP_MARKER_ENTITY_NAME = "editor:ruler_idle";
    class SegmentSelector {
        constructor(location, visible, curveType, easeType, widgetGroup, gizmoMovedEvent, gizmoGrabbedEvent, gizmoReleasedEvent) {
            this._location = location;
            this._visible = visible;
            this._curveType = curveType;
            this._easeType = easeType;
            this._curveWithPrevSegment = false;
            this._widget = widgetGroup.createWidget(location, {
                selectable: visible,
                snapToBlockLocation: true,
                visible,
                collisionOffset: {
                    x: .5,
                    y: .5,
                    z: .5
                },
                collisionRadius: 0,
                widgetName: "Line Tool - Segment Selector",
                stateChangeEvent: data => {
                    if (data.location !== undefined && !lib.Vector3Utils.equals(data.location, this._location)) {
                        const textComponent = data.widget.getComponent("position_text");
                        if (textComponent) {
                            textComponent.label = lib.Vector3Utils.toString(data.location, {
                                decimals: 1
                            });
                        }
                    }
                }
            });
            this._widget.addEntityComponent("marker", SegmentSelector.MAP_MARKER_ENTITY_NAME, {
                isClickable: false,
                visible: this._visible,
                offset: {
                    x: .5,
                    y: .25,
                    z: .5
                }
            });
            this._widget.addTextComponent("position_text", lib.Vector3Utils.toString(location, {
                decimals: 1
            }), {
                offset: {
                    x: .5,
                    y: 1,
                    z: .5
                },
                visible: this._visible
            });
            this._movementGizmo = this._widget.addGizmoComponent("position_gizmo", {
                offset: {
                    x: .5,
                    y: .5,
                    z: .5
                },
                visible,
                enablePlanes: true,
                stateChangeEvent: data => {
                    if (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerMoved || data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginMoved) {
                        if (!lib.Vector3Utils.equals(this._location, data.widget.location)) {
                            gizmoMovedEvent(this._location, data.widget.location, data.widget, this);
                        }
                    } else if (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginGrabbed || data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerGrabbed) {
                        gizmoGrabbedEvent(data.widget.location);
                    } else if (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginReleased || data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerReleased) {
                        gizmoReleasedEvent(data.widget.location);
                    }
                }
            });
            this._widget.addGuideComponent("position_guide");
        }
        get visible() {
            return this._widget.visible;
        }
        set visible(value) {
            this._widget.visible = value;
        }
        get isSelected() {
            return this._widget.selected;
        }
        set isSelected(value) {
            this._widget.selected = value;
            this._movementGizmo.activated = value;
        }
        get curveType() {
            return this._curveType;
        }
        get widget() {
            return this._widget;
        }
        set curveType(curveType) {
            this._curveType = curveType;
        }
        get easeType() {
            return this._easeType;
        }
        set easeType(easeType) {
            this._easeType = easeType;
        }
        get curveWithPrevSegment() {
            return this._curveWithPrevSegment;
        }
        set curveWithPrevSegment(curvesWithPrev) {
            this._curveWithPrevSegment = curvesWithPrev;
        }
        getSplineControlPoint() {
            return this._splineComponentControlPoint;
        }
        setSplineControlPoint(controlPoint) {
            this._splineComponentControlPoint = controlPoint;
        }
        getBaseSplineSegment() {
            return this._baseSplineSegment;
        }
        setBaseSplineSegment(segment) {
            this._baseSplineSegment = segment;
        }
        getLocation() {
            return this._location;
        }
        moveSelector(location, start, end, moveWidget = false) {
            if (moveWidget) {
                this._widget.location = location;
            }
            this._location = location;
            if (start) {
                if (lib.Vector3Utils.equals(this._location, start)) {
                    this._visible = false;
                    this._widget.visible = false;
                    return;
                }
            }
            if (end) {
                if (lib.Vector3Utils.equals(this._location, end)) {
                    this._visible = false;
                    this._widget.visible = false;
                    return;
                }
            }
            this._widget.visible = true;
        }
        teardown() {
            this._widget?.delete();
        }
    }
    SegmentSelector.MAP_MARKER_ENTITY_NAME = "editor:ruler_idle";
    class CurveSegment extends BlockCurve {
        constructor(uiSession, horizontalWeight, verticalWeight, linePreviewMap, requestCursorTargetMode, requestGroundLevelAtLocation, start, end, startData, endData) {
            super(start.location, end.location, requestCursorTargetMode, requestGroundLevelAtLocation, {
                horizontalWeight,
                verticalWeight,
                startData,
                endData,
                contour: false
            });
            this._startControlPoint = start;
            this._endControlPoint = end;
            this._linePreviewMap = linePreviewMap;
            this._visible = true;
        }
        get visible() {
            return this._visible;
        }
        teardown() {
            super.teardown();
        }
        set visible(newIsVisible) {
            if (this._visible !== newIsVisible) {
                if (newIsVisible) {
                    this._linePreviewMap.addPoints([ ...this.curveDataIterator ]);
                } else {
                    this._linePreviewMap.removePoints([ ...this.curveDataIterator ]);
                }
                this._visible = newIsVisible;
            }
        }
        getStartControlPoint() {
            return this._startControlPoint;
        }
        getEndControlPoint() {
            return this._endControlPoint;
        }
    }
    class LineSegment extends BlockLine {
        constructor(uiSession, horizontalWeight, verticalWeight, blockLineTypeAlgorithm, linePreviewMap, requestCursorTargetMode, requestGroundLevelAtLocation, start, end, startData, endData) {
            const curveOptions = {
                horizontalWeight,
                verticalWeight,
                startData,
                endData
            };
            super(start.location, end.location, requestCursorTargetMode, requestGroundLevelAtLocation, {
                curveOptions,
                blockLineType: blockLineTypeAlgorithm
            });
            this._linePreviewMap = linePreviewMap;
            this._visible = false;
            this._startControlPoint = start;
            this._endControlPoint = end;
        }
        get visible() {
            return this._visible;
        }
        getStartControlPoint() {
            return this._startControlPoint;
        }
        getEndControlPoint() {
            return this._endControlPoint;
        }
        teardown() {
            super.teardown();
        }
        set visible(newIsVisible) {
            void this.generateCurve().then((() => {
                if (this._visible !== newIsVisible) {
                    if (newIsVisible) {
                        this._linePreviewMap.addPoints([ ...this.curveDataIterator ]);
                    } else {
                        this._linePreviewMap.removePoints([ ...this.curveDataIterator ]);
                    }
                    this._visible = newIsVisible;
                }
            }));
        }
    }
    class SegmentsManager {
        constructor(uiSession, blockLineTypeAlgorithm, horizontalWeight, verticalWeight, requestStartTransaction, requestCommitTransaction, requestCancelTransaction) {
            this.pointGizmoMovedEventHandler = (oldLocation, newLocation, widget) => {
                const delta = lib.Vector3Utils.subtract(newLocation, oldLocation);
                if (lib.Vector3Utils.magnitude(delta) !== 0) {
                    if (!this.moveSelectedPoints(delta)) {
                        widget.location = oldLocation;
                    }
                }
            };
            this.segmentSelectorMovedEventHandler = (oldLocation, newLocation, widget, segmentSelector) => {
                const delta = lib.Vector3Utils.subtract(newLocation, oldLocation);
                if (lib.Vector3Utils.magnitude(delta) !== 0) {
                    if (!this.handleMoveSelector(segmentSelector, delta)) {
                        widget.location = oldLocation;
                    }
                }
            };
            this.segmentSelectorGizmoGrabbedEventHandler = location => {
                this._segmentGizmoGrabbedStartLocation = location;
                this._requestStartTransaction("SegmentSelectorGizmoMove");
            };
            this.segmentSelectorGizmoReleasedEventHandler = location => {
                if (this._segmentGizmoGrabbedStartLocation !== undefined && !lib.Vector3Utils.equals(location, this._segmentGizmoGrabbedStartLocation)) {
                    this._requestCommitTransaction("SegmentSelectorGizmoMove");
                } else {
                    this._uiSession.log.debug("Canceling transaction - move gizmo was released but not moved.");
                    this._requestCancelTransaction();
                }
                this._segmentGizmoGrabbedStartLocation = undefined;
            };
            this.pointGizmoGrabbedEventHandler = location => {
                this._gizmoGrabbedStartLocation = location;
                this._requestStartTransaction("ControlPointGizmoMove");
            };
            this.pointGizmoReleasedEventHandler = location => {
                if (this._gizmoGrabbedStartLocation !== undefined && !lib.Vector3Utils.equals(location, this._gizmoGrabbedStartLocation)) {
                    this._requestCommitTransaction("ControlPointGizmoMove");
                } else {
                    this._uiSession.log.debug("Canceling transaction - move gizmo was released but not moved.");
                    this._requestCancelTransaction();
                }
                this._gizmoGrabbedStartLocation = undefined;
            };
            this.cursorTargetModeRequested = () => this._uiSession.extensionContext.cursor.getProperties().targetMode ?? server_editor_namespaceObject.CursorTargetMode.Block;
            this.groundLevelAtLocationRequested = location => {
                const blockHit = this._uiSession.extensionContext.player.dimension.getBlockFromRay(location, lib.VECTOR3_DOWN, {
                    includePassableBlocks: false,
                    includeLiquidBlocks: true
                });
                if (blockHit?.block) {
                    return blockHit.block.location.y;
                } else {
                    return Infinity;
                }
            };
            this._uiSession = uiSession;
            this._blockLineTypeAlgorithm = blockLineTypeAlgorithm;
            this._horizontalWeight = horizontalWeight;
            this._verticalWeight = verticalWeight;
            this._requestStartTransaction = requestStartTransaction;
            this._requestCommitTransaction = requestCommitTransaction;
            this._requestCancelTransaction = requestCancelTransaction;
            this._widgetGroup = this._uiSession.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.Multiple
            });
            this._linePreviewMap = new LinePreviewMap(this._uiSession);
            this._controlPoints = [];
            this._lineSegments = [];
            this._segmentSelectors = [];
            this._gizmoGrabbedStartLocation = undefined;
        }
        get controlPoints() {
            return this._controlPoints;
        }
        get segmentSelectors() {
            return this._segmentSelectors;
        }
        get selectedSegmentSelector() {
            const selectors = [];
            let index = 0;
            for (let i = 0; i < this._segmentSelectors.length; ++i) {
                if (this._segmentSelectors[i].isSelected) {
                    index = i;
                    selectors.push(this._segmentSelectors[i]);
                }
            }
            if (selectors.length > 1 || selectors.length === 0) {
                return undefined;
            } else {
                return this._segmentSelectors[index];
            }
        }
        selectedSegmentSelectorHasCurveInPreviousSegment() {
            const selector = this.selectedSegmentSelector;
            if (!selector) {
                return false;
            }
            if (this._segmentSelectors.length === 1) {
                return false;
            }
            let currIndex = 0;
            for (let i = 0; i < this._segmentSelectors.length; ++i) {
                if (this._segmentSelectors[i] === selector) {
                    currIndex = i;
                    break;
                }
            }
            if (currIndex === 0) {
                return false;
            }
            return this._segmentSelectors[currIndex - 1].curveType === CurveType.Hermite;
        }
        get selectedPoints() {
            const points = [];
            for (const controlPoint of this._controlPoints) {
                if (controlPoint.isSelected) {
                    points.push(controlPoint);
                }
            }
            return points;
        }
        get linePreviewMap() {
            return this._linePreviewMap;
        }
        set blockLineTypeAlgorithm(newAlgorithm) {
            if (newAlgorithm !== this._blockLineTypeAlgorithm) {
                this._blockLineTypeAlgorithm = newAlgorithm;
                const blockPointType = newAlgorithm === BlockLineType.Direct || newAlgorithm === BlockLineType.Staggered ? BlockPointType.Normal : BlockPointType.Contour;
                for (let i = 0; i < this._controlPoints.length; i++) {
                    this.applyPreviewChangeResults(this._controlPoints[i].setBlockPointType(blockPointType));
                }
                for (let i = 0; i < this._lineSegments.length; i++) {
                    this._lineSegments[i].setOptions({
                        blockLineType: newAlgorithm,
                        curveOptions: {
                            contour: newAlgorithm === BlockLineType.Staggered ? true : false
                        }
                    }).then((result => {
                        this.applyPreviewChangeResults(result);
                    })).catch((err => {
                        this._uiSession.log.error(err.message);
                    }));
                }
            }
        }
        setState(state, segmentSelectorStates) {
            this.clearAll();
            let segmentSelectorIndex = 0;
            for (let i = 0; i < state.length; i++) {
                const newPoint = new ControlPoint(state[i].location, state[i].separation, state[i].weightsOverridden, state[i].usingUniformValue, state[i].horizontalWeight, state[i].verticalWeight, this._blockLineTypeAlgorithm, this._linePreviewMap, this._widgetGroup, this.cursorTargetModeRequested, this.groundLevelAtLocationRequested, this.pointGizmoMovedEventHandler, this.pointGizmoGrabbedEventHandler, this.pointGizmoReleasedEventHandler);
                this._controlPoints.push(newPoint);
                newPoint.isSelected = state[i].selection;
                newPoint.visible = true;
                if (i > 0 && !state[i].separation) {
                    const startPoint = this._controlPoints[i - 1];
                    const oldSegmentSelector = segmentSelectorStates[segmentSelectorIndex];
                    segmentSelectorIndex++;
                    const newSegmentSelector = new SegmentSelector(oldSegmentSelector.location, !lib.Vector3Utils.equals(oldSegmentSelector.location, startPoint.location) || !lib.Vector3Utils.equals(oldSegmentSelector.location, newPoint.location), oldSegmentSelector.curveType, oldSegmentSelector.easeType, this._widgetGroup, this.segmentSelectorMovedEventHandler, this.segmentSelectorGizmoGrabbedEventHandler, this.segmentSelectorGizmoReleasedEventHandler);
                    newSegmentSelector.isSelected = oldSegmentSelector.isSelected;
                    newSegmentSelector.curveWithPrevSegment = oldSegmentSelector.mergeWithPreviousCurve;
                    this._segmentSelectors.push(newSegmentSelector);
                    if (newSegmentSelector.curveType === CurveType.None) {
                        const newLineSegment = new LineSegment(this._uiSession, this._horizontalWeight, this._verticalWeight, this._blockLineTypeAlgorithm, this._linePreviewMap, this.cursorTargetModeRequested, this.groundLevelAtLocationRequested, this._controlPoints[i - 1], this._controlPoints[i], startPoint.isWeightsOverridden ? {
                            horizontalWeight: startPoint.horizontalWeight,
                            verticalWeight: startPoint.verticalWeight
                        } : undefined, newPoint.isWeightsOverridden ? {
                            horizontalWeight: newPoint.horizontalWeight,
                            verticalWeight: newPoint.verticalWeight
                        } : undefined);
                        this._lineSegments.push(newLineSegment);
                        newLineSegment.visible = true;
                    } else {
                        const newCurveSegment = new CurveSegment(this._uiSession, this._horizontalWeight, this._verticalWeight, this._linePreviewMap, this.cursorTargetModeRequested, this.groundLevelAtLocationRequested, startPoint, newPoint, startPoint.isWeightsOverridden ? {
                            horizontalWeight: startPoint.horizontalWeight,
                            verticalWeight: startPoint.verticalWeight
                        } : undefined, newPoint.isWeightsOverridden ? {
                            horizontalWeight: newPoint.horizontalWeight,
                            verticalWeight: newPoint.verticalWeight
                        } : undefined);
                        this._lineSegments.push(newCurveSegment);
                        const widgets = [ newSegmentSelector.widget, newPoint.widget ];
                        startPoint.addSplineComponent(widgets);
                        const index = this._lineSegments.length - 1;
                        let findIndex = index - 1;
                        while (findIndex >= 0 && this._segmentSelectors[findIndex].curveType !== CurveType.None && this._segmentSelectors[findIndex].curveWithPrevSegment) {
                            findIndex--;
                        }
                        if (newSegmentSelector.curveWithPrevSegment) {
                            const startPoint = this._lineSegments[findIndex].getStartControlPoint();
                            const startSegment = this._lineSegments[findIndex];
                            startSegment.visible = false;
                            let addedWidgets = [ this._segmentSelectors[findIndex].widget, startSegment.getEndControlPoint().widget ];
                            for (let i = findIndex + 1; i <= index; i++) {
                                addedWidgets = addedWidgets.concat([ this._segmentSelectors[i].widget, this._lineSegments[i].getEndControlPoint().widget ]);
                                this._lineSegments[i].visible = false;
                                void this._lineSegments[i].updateCurvePlot([]);
                                this._segmentSelectors[i].setSplineControlPoint(startPoint);
                                this._segmentSelectors[i].setBaseSplineSegment(startSegment);
                            }
                            startPoint.removeAllControlPointsFromSplineComponent();
                            startPoint.addControlPointsToSplineComponent(addedWidgets);
                            const interpPoints = startPoint.getSplineComponentInterpPoints();
                            startSegment.updateCurvePlot(interpPoints).then((() => {
                                startSegment.visible = true;
                            })).catch((err => {
                                this._uiSession.log.error(err.message);
                            }));
                        } else {
                            newCurveSegment.visible = false;
                            const interpPoints = startPoint.getSplineComponentInterpPoints();
                            newCurveSegment.updateCurvePlot(interpPoints).then((() => {
                                newCurveSegment.visible = true;
                            })).catch((err => {
                                this._uiSession.log.error(err.message);
                            }));
                        }
                    }
                }
            }
        }
        addNewPoint(targetLocation, isSeparate = false) {
            if (this._controlPoints.some((controlPoint => lib.Vector3Utils.equals(controlPoint.location, targetLocation)))) {
                return;
            }
            const newPoint = new ControlPoint(targetLocation, isSeparate, false, false, this._horizontalWeight, this._verticalWeight, this._blockLineTypeAlgorithm, this._linePreviewMap, this._widgetGroup, this.cursorTargetModeRequested, this.groundLevelAtLocationRequested, this.pointGizmoMovedEventHandler, this.pointGizmoGrabbedEventHandler, this.pointGizmoReleasedEventHandler);
            this._controlPoints.push(newPoint);
            newPoint.isSelected = true;
            newPoint.visible = true;
            if (this._controlPoints.length > 1 && !isSeparate) {
                const previousControlPoint = this._controlPoints[this._controlPoints.length - 2];
                const newLineSegment = new LineSegment(this._uiSession, this._horizontalWeight, this._verticalWeight, this._blockLineTypeAlgorithm, this._linePreviewMap, this.cursorTargetModeRequested, this.groundLevelAtLocationRequested, previousControlPoint, newPoint, previousControlPoint.isWeightsOverridden ? {
                    horizontalWeight: previousControlPoint.horizontalWeight,
                    verticalWeight: previousControlPoint.verticalWeight
                } : undefined, newPoint.isWeightsOverridden ? {
                    horizontalWeight: newPoint.horizontalWeight,
                    verticalWeight: newPoint.verticalWeight
                } : undefined);
                this._lineSegments.push(newLineSegment);
                const midPointRes = newLineSegment.getMidPoint();
                const midPoint = {
                    ...previousControlPoint.location
                };
                if (midPointRes) {
                    midPoint.x = Math.round(midPointRes.x);
                    midPoint.y = Math.round(midPointRes.y);
                    midPoint.z = Math.round(midPointRes.z);
                }
                const newSegmentSelector = new SegmentSelector(midPoint, !lib.Vector3Utils.equals(midPoint, previousControlPoint.location) || !lib.Vector3Utils.equals(midPoint, newPoint.location), CurveType.None, EaseType.Linear, this._widgetGroup, this.segmentSelectorMovedEventHandler, this.segmentSelectorGizmoGrabbedEventHandler, this.segmentSelectorGizmoReleasedEventHandler);
                if (!this._segmentSelectors.length) {
                    newLineSegment.visible = true;
                    this._segmentSelectors.push(newSegmentSelector);
                    return;
                }
                const prevSegSelector = this._segmentSelectors[this._segmentSelectors.length - 1];
                newSegmentSelector.curveType = prevSegSelector.curveType;
                newSegmentSelector.easeType = prevSegSelector.easeType;
                newSegmentSelector.curveWithPrevSegment = prevSegSelector.curveWithPrevSegment;
                this._segmentSelectors.push(newSegmentSelector);
                if (newSegmentSelector.curveType === CurveType.Hermite) {
                    this._lineSegments[this._lineSegments.length - 1] = new CurveSegment(this._uiSession, this._horizontalWeight, this._verticalWeight, this._linePreviewMap, this.cursorTargetModeRequested, this.groundLevelAtLocationRequested, previousControlPoint, newPoint, previousControlPoint.isWeightsOverridden ? {
                        horizontalWeight: previousControlPoint.horizontalWeight,
                        verticalWeight: previousControlPoint.verticalWeight
                    } : undefined, newPoint.isWeightsOverridden ? {
                        horizontalWeight: newPoint.horizontalWeight,
                        verticalWeight: newPoint.verticalWeight
                    } : undefined);
                    const widgets = [ newSegmentSelector.widget, newPoint.widget ];
                    previousControlPoint.addSplineComponent(widgets);
                    if (newSegmentSelector.curveWithPrevSegment) {
                        let findIndex = this._segmentSelectors.length - 1;
                        while (findIndex >= 0 && this._segmentSelectors[findIndex].curveType !== CurveType.None && this._segmentSelectors[findIndex].curveWithPrevSegment) {
                            findIndex--;
                        }
                        const baseSplineSegment = this._lineSegments[findIndex];
                        const baseSplineControlPoint = this._lineSegments[findIndex].getStartControlPoint();
                        newSegmentSelector.setBaseSplineSegment(baseSplineSegment);
                        newSegmentSelector.setSplineControlPoint(baseSplineControlPoint);
                        baseSplineControlPoint.addControlPointsToSplineComponent([ newSegmentSelector.widget, newPoint.widget ]);
                        const interpPoints = baseSplineControlPoint.getSplineComponentInterpPoints();
                        baseSplineSegment.updateCurvePlot(interpPoints).then((res => {
                            this.applyPreviewChangeResults(res);
                        })).catch((err => {
                            this._uiSession.log.error(err.message);
                        }));
                    } else {
                        const interpPoints = previousControlPoint.getSplineComponentInterpPoints();
                        this._lineSegments[this._lineSegments.length - 1].updateCurvePlot(interpPoints).then((res => {
                            this.applyPreviewChangeResults(res);
                        })).catch((err => {
                            this._uiSession.log.error(err.message);
                        }));
                    }
                } else {
                    newLineSegment.visible = true;
                }
            }
        }
        handleMoveSelector(segmentSelector, delta) {
            const index = this._segmentSelectors.findIndex((value => value === segmentSelector));
            const selector = this._segmentSelectors[index];
            if (selector.curveType === CurveType.None) {
                this.updateSegmentSelectorValues({
                    curveType: CurveType.Hermite
                });
            }
            const segment = this._lineSegments[index];
            this.moveSelector(selector, lib.Vector3Utils.add(selector.getLocation(), delta), segment.start, segment.end);
            return true;
        }
        clearAll() {
            for (let i = 0; i < this._controlPoints.length; i++) {
                this._controlPoints[i].teardown();
            }
            for (let i = 0; i < this._segmentSelectors.length; i++) {
                this._segmentSelectors[i].teardown();
            }
            this._controlPoints.length = 0;
            this._lineSegments.length = 0;
            this._segmentSelectors.length = 0;
            this._linePreviewMap.clear();
        }
        clearSelectedPoints() {
            if (this._controlPoints.length <= 0) {
                return;
            }
            const pointsToRemove = this._controlPoints.filter((controlPoint => controlPoint.isSelected));
            if (pointsToRemove.length === this._controlPoints.length) {
                this.clearAll();
            } else {
                for (let i = 0; i < pointsToRemove.length; i++) {
                    const prevSegIdx = this._lineSegments.findIndex((segment => lib.Vector3Utils.equals(segment.end, pointsToRemove[i].location)));
                    if (prevSegIdx !== -1) {
                        this._lineSegments[prevSegIdx].visible = false;
                        this._lineSegments.splice(prevSegIdx, 1);
                        this._segmentSelectors[prevSegIdx].teardown();
                        this._segmentSelectors.splice(prevSegIdx, 1);
                    }
                    const nextSegIdx = this._lineSegments.findIndex((segment => lib.Vector3Utils.equals(segment.start, pointsToRemove[i].location)));
                    if (nextSegIdx !== -1) {
                        this._lineSegments[nextSegIdx].visible = false;
                        this._lineSegments.splice(nextSegIdx, 1);
                        this._segmentSelectors[nextSegIdx].teardown();
                        this._segmentSelectors.splice(nextSegIdx, 1);
                    }
                    const pointIdx = this._controlPoints.findIndex((point => lib.Vector3Utils.equals(point.location, pointsToRemove[i].location)));
                    if (pointIdx !== -1) {
                        this._controlPoints[pointIdx].visible = false;
                        this._controlPoints[pointIdx].teardown();
                        this._controlPoints.splice(pointIdx, 1);
                    }
                }
                for (let i = 1; i < this._controlPoints.length; i++) {
                    const start = this._controlPoints[i - 1];
                    const end = this._controlPoints[i];
                    if (!end.isSeparate) {
                        const segIdx = this._lineSegments.findIndex((segment => lib.Vector3Utils.equals(segment.start, start.location) && lib.Vector3Utils.equals(segment.end, end.location)));
                        if (segIdx === -1) {
                            const newLineSegment = new LineSegment(this._uiSession, this._horizontalWeight, this._verticalWeight, this._blockLineTypeAlgorithm, this._linePreviewMap, this.cursorTargetModeRequested, this.groundLevelAtLocationRequested, start, end, start.isWeightsOverridden ? {
                                horizontalWeight: start.horizontalWeight,
                                verticalWeight: start.verticalWeight
                            } : undefined, end.isWeightsOverridden ? {
                                horizontalWeight: end.horizontalWeight,
                                verticalWeight: end.verticalWeight
                            } : undefined);
                            this._lineSegments.push(newLineSegment);
                            newLineSegment.visible = true;
                            const midPointRes = newLineSegment.getMidPoint();
                            const midPoint = {
                                ...start.location
                            };
                            if (midPointRes) {
                                midPoint.x = Math.round(midPointRes.x);
                                midPoint.y = Math.round(midPointRes.y);
                                midPoint.z = Math.round(midPointRes.z);
                            }
                            const newSegmentSelector = new SegmentSelector(midPoint, !lib.Vector3Utils.equals(midPoint, start.location) || !lib.Vector3Utils.equals(midPoint, end.location), CurveType.None, EaseType.Linear, this._widgetGroup, this.segmentSelectorMovedEventHandler, this.segmentSelectorGizmoGrabbedEventHandler, this.segmentSelectorGizmoReleasedEventHandler);
                            this._segmentSelectors.push(newSegmentSelector);
                        }
                    }
                }
            }
        }
        nudgeSelectedPoints(direction) {
            if (this._controlPoints.length <= 0) {
                return;
            }
            const rotationY = this._uiSession.extensionContext.player.getRotation().y;
            const rotationCorrectedVector = getRotationCorrectedDirectionVector(rotationY, direction);
            if (!this.moveSelectedPoints(rotationCorrectedVector, true)) {
                this._uiSession.log.warning(`Could not nudge control point(s) (points cannot overlap or be more than ${LineBehavior.MAX_CONTROL_POINTS_DISTANCE} blocks from the next/previous point).`);
            }
            if (this._controlPoints.length === this.selectedPoints.length) {
                for (let i = 0; i < this._segmentSelectors.length; ++i) {
                    const selector = this._segmentSelectors[i];
                    const segment = this._lineSegments[i];
                    this.moveSelector(selector, lib.Vector3Utils.add(selector.getLocation(), rotationCorrectedVector), segment.start, segment.end, true);
                }
                return;
            }
            const selectedSelector = this.selectedSegmentSelector;
            if (selectedSelector) {
                const index = this._segmentSelectors.findIndex((entry => entry === selectedSelector));
                const segment = this._lineSegments[index];
                this.moveSelector(selectedSelector, lib.Vector3Utils.add(selectedSelector.getLocation(), rotationCorrectedVector), segment.start, segment.end, true);
            }
        }
        moveSelectedPoints(translationVector, moveGizmo = false) {
            const selectedPoints = this.selectedPoints;
            const restrictedLocations = new Set;
            for (let i = 0; i < this._controlPoints.length; i++) {
                restrictedLocations.add(`${this._controlPoints[i].location.x},${this._controlPoints[i].location.y},${this._controlPoints[i].location.z}`);
            }
            if (selectedPoints.length === this._controlPoints.length) {
                for (let i = 0; i < this._controlPoints.length; i++) {
                    this.applyPreviewChangeResults(this._controlPoints[i].move(lib.Vector3Utils.add(this._controlPoints[i].location, translationVector), moveGizmo));
                }
                const alreadyMoved = new Map;
                for (let i = 0; i < this._lineSegments.length; i++) {
                    if (this._segmentSelectors[i].curveType === CurveType.None) {
                        this._lineSegments[i].translatePoints(translationVector).then((result => {
                            this.applyPreviewChangeResults(result);
                            this.moveSelector(this._segmentSelectors[i], this._lineSegments[i].getMidPoint() ?? lib.Vector3Utils.add(this._segmentSelectors[i].getLocation(), translationVector), this._lineSegments[i].start, this._lineSegments[i].end, true);
                        })).catch((err => {
                            this._uiSession.log.error(err.message);
                        }));
                    } else {
                        const startPoint = this._segmentSelectors[i].getSplineControlPoint() ?? this._lineSegments[i].getStartControlPoint();
                        const segment = this._segmentSelectors[i].getBaseSplineSegment() ?? this._lineSegments[i];
                        void this._lineSegments[i].translatePoints(translationVector);
                        if (alreadyMoved.get(segment)) {
                            continue;
                        }
                        alreadyMoved.set(segment, true);
                        const interpPoints = startPoint.getSplineComponentInterpPoints();
                        segment.updateCurvePlot(interpPoints).then((res => {
                            this.applyPreviewChangeResults(res);
                        })).catch((err => {
                            this._uiSession.log.error(err.message);
                        }));
                    }
                }
            } else {
                for (let i = 0; i < selectedPoints.length; i++) {
                    const newLocation = lib.Vector3Utils.add(selectedPoints[i].location, translationVector);
                    if (!lib.Vector3Utils.equals(lib.VECTOR3_ZERO, translationVector) && restrictedLocations.has(`${newLocation.x},${newLocation.y},${newLocation.z}`)) {
                        this._uiSession.log.warning(`Cannot overlap control points!`);
                        return false;
                    }
                }
                for (let i = 0; i < this._controlPoints.length; i++) {
                    if (!this._controlPoints[i].isSelected) {
                        continue;
                    }
                    if (i - 1 > 0 && !this._controlPoints[i - 1].isSelected) {
                        const newLocation = lib.Vector3Utils.add(this._controlPoints[i].location, translationVector);
                        if (Math.abs(lib.Vector3Utils.magnitude(lib.Vector3Utils.subtract(newLocation, this._controlPoints[i - 1].location))) > LineBehavior.MAX_CONTROL_POINTS_DISTANCE) {
                            this._uiSession.log.warning(`Could not move control point(s) (points cannot be more than ${LineBehavior.MAX_CONTROL_POINTS_DISTANCE} blocks from the next/previous point).`);
                            return false;
                        }
                    }
                    if (i + 1 < this._controlPoints.length && !this._controlPoints[i + 1].isSelected) {
                        const newLocation = lib.Vector3Utils.add(this._controlPoints[i].location, translationVector);
                        if (Math.abs(lib.Vector3Utils.magnitude(lib.Vector3Utils.subtract(newLocation, this._controlPoints[i + 1].location))) > LineBehavior.MAX_CONTROL_POINTS_DISTANCE) {
                            this._uiSession.log.warning(`Could not nudge control point(s) (points cannot be more than ${LineBehavior.MAX_CONTROL_POINTS_DISTANCE} blocks from the next/previous point).`);
                            return false;
                        }
                    }
                }
                for (let i = 0; i < selectedPoints.length; i++) {
                    const prevSegIdx = this._lineSegments.findIndex((segment => lib.Vector3Utils.equals(segment.end, selectedPoints[i].location)));
                    if (prevSegIdx !== -1) {
                        this._lineSegments[prevSegIdx].setEnd(lib.Vector3Utils.add(this._lineSegments[prevSegIdx].end, translationVector), selectedPoints[i].isWeightsOverridden ? {
                            horizontalWeight: selectedPoints[i].horizontalWeight,
                            verticalWeight: selectedPoints[i].verticalWeight
                        } : undefined).then((result => {
                            this.applyPreviewChangeResults(result);
                            if (this._segmentSelectors[prevSegIdx].curveType === CurveType.None) {
                                this.moveSelector(this._segmentSelectors[prevSegIdx], this._lineSegments[prevSegIdx].getMidPoint() ?? lib.Vector3Utils.add(this._segmentSelectors[prevSegIdx].getLocation(), translationVector), this._lineSegments[prevSegIdx].start, this._lineSegments[prevSegIdx].end, true);
                            } else {
                                const startPoint = this._segmentSelectors[prevSegIdx].getSplineControlPoint() ?? this._lineSegments[prevSegIdx].getStartControlPoint();
                                const segment = this._segmentSelectors[prevSegIdx].getBaseSplineSegment() ?? this._lineSegments[prevSegIdx];
                                const interpPoints = startPoint.getSplineComponentInterpPoints();
                                segment.updateCurvePlot(interpPoints).then((res => {
                                    this.applyPreviewChangeResults(res);
                                })).catch((err => {
                                    this._uiSession.log.error(err.message);
                                }));
                            }
                        })).catch((err => {
                            this._uiSession.log.error(err.message);
                        }));
                    }
                    const nextSegIdx = this._lineSegments.findIndex((segment => lib.Vector3Utils.equals(segment.start, selectedPoints[i].location)));
                    if (nextSegIdx !== -1) {
                        this._lineSegments[nextSegIdx].setStart(lib.Vector3Utils.add(this._lineSegments[nextSegIdx].start, translationVector), selectedPoints[i].isWeightsOverridden ? {
                            horizontalWeight: selectedPoints[i].horizontalWeight,
                            verticalWeight: selectedPoints[i].verticalWeight
                        } : undefined).then((results => {
                            this.applyPreviewChangeResults(results);
                            if (this._segmentSelectors[nextSegIdx].curveType === CurveType.None) {
                                this.moveSelector(this._segmentSelectors[nextSegIdx], this._lineSegments[nextSegIdx].getMidPoint() ?? lib.Vector3Utils.add(this._segmentSelectors[nextSegIdx].getLocation(), translationVector), this._lineSegments[nextSegIdx].start, this._lineSegments[nextSegIdx].end, true);
                            } else {
                                const startPoint = this._segmentSelectors[nextSegIdx].getSplineControlPoint() ?? this._lineSegments[nextSegIdx].getStartControlPoint();
                                const segment = this._segmentSelectors[nextSegIdx].getBaseSplineSegment() ?? this._lineSegments[nextSegIdx];
                                const interpPoints = startPoint.getSplineComponentInterpPoints();
                                segment.updateCurvePlot(interpPoints).then((res => {
                                    this.applyPreviewChangeResults(res);
                                })).catch((err => {
                                    this._uiSession.log.error(err.message);
                                }));
                            }
                        })).catch((err => {
                            this._uiSession.log.error(err.message);
                        }));
                    }
                    this.applyPreviewChangeResults(selectedPoints[i].move(lib.Vector3Utils.add(selectedPoints[i].location, translationVector), moveGizmo));
                }
            }
            return true;
        }
        async fillLine(fillWithAir = false) {
            if (this._linePreviewMap.previewVolume.isEmpty) {
                return;
            }
            const onError = e => {
                this._uiSession.log.error(`Fill operation failed with error: ${e.message}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            };
            await executeFunctionWithTransactionAndTicking(this._uiSession.extensionContext, this._uiSession.log, this._linePreviewMap.previewVolume.volume, "FillLine", (() => {
                if (fillWithAir) {
                    this._uiSession.extensionContext.blockUtilities.fillVolume(this._linePreviewMap.previewVolume.volume, lib_vanilla_MinecraftBlockTypes.Air);
                } else {
                    this._uiSession.extensionContext.blockUtilities.fillVolume(this._linePreviewMap.previewVolume.volume);
                }
            })).catch(onError);
        }
        updateSelectedControlPointData(isWeightOverridden, usingUniformValues, pointPosition, horizontalWeight, verticalWeight) {
            let updated = false;
            const selectedPoints = this.selectedPoints;
            if (selectedPoints.length !== 1) {
                return;
            }
            const selectedPoint = selectedPoints[0];
            const delta = lib.Vector3Utils.subtract(pointPosition, selectedPoint.location);
            if (selectedPoint.horizontalWeight !== horizontalWeight || selectedPoint.verticalWeight !== verticalWeight || !lib.Vector3Utils.equals(selectedPoint.location, pointPosition) || selectedPoint.isWeightsOverridden !== isWeightOverridden || selectedPoint.usingUniformValues !== usingUniformValues || lib.Vector3Utils.magnitude(delta) !== 0) {
                updated = true;
            }
            if (updated) {
                selectedPoint.setWeightsOverridden(isWeightOverridden);
                selectedPoint.setUsingUniformValues(usingUniformValues);
                this.applyPreviewChangeResults(selectedPoint.setWeights(horizontalWeight, verticalWeight));
                if (this.moveSelectedPoints(delta)) {
                    selectedPoint.move(pointPosition, true);
                }
            }
        }
        updateSegmentSelectorValues(options) {
            let updated = false;
            const segmentSelector = this.selectedSegmentSelector;
            if (!segmentSelector) {
                this._uiSession.log.error(`Changing a segment selector when one isn't selected`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const delta = lib.Vector3Utils.subtract(segmentSelector.getLocation(), options.knotPosition ?? segmentSelector.getLocation());
            const curveTypeChanged = segmentSelector.curveType !== (options.curveType ?? segmentSelector.curveType);
            const curveWithPrevChanged = segmentSelector.curveWithPrevSegment !== (options.curveWithPrevSegment ?? segmentSelector.curveWithPrevSegment);
            if (!lib.Vector3Utils.equals(segmentSelector.getLocation(), options.knotPosition ?? segmentSelector.getLocation()) || curveTypeChanged || curveWithPrevChanged || segmentSelector.easeType !== options.easeType || lib.Vector3Utils.magnitude(delta) !== 0) {
                updated = true;
            }
            if (updated) {
                const index = this._segmentSelectors.findIndex((value => value === segmentSelector));
                if (index === -1) {
                    this._uiSession.log.error(`Associated segment selector has no associated line segment`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    return;
                }
                const segment = this._lineSegments[index];
                segmentSelector.curveType = options.curveType ?? segmentSelector.curveType;
                segmentSelector.easeType = options.easeType ?? segmentSelector.easeType;
                segmentSelector.curveWithPrevSegment = options.curveWithPrevSegment ?? segmentSelector.curveWithPrevSegment;
                let findIndex = index - 1;
                while (findIndex >= 0 && this._segmentSelectors[findIndex].curveType !== CurveType.None && this._segmentSelectors[findIndex].curveWithPrevSegment) {
                    findIndex--;
                }
                let maxIndex = index + 1;
                while (maxIndex < this._segmentSelectors.length && this._segmentSelectors[maxIndex].curveType !== CurveType.None && this._segmentSelectors[maxIndex].curveWithPrevSegment) {
                    maxIndex++;
                }
                if (curveWithPrevChanged && index !== 0) {
                    const baseSegment = segmentSelector.getBaseSplineSegment();
                    if (baseSegment) {
                        baseSegment.visible = false;
                    }
                    segment.visible = false;
                    if (segmentSelector.curveWithPrevSegment) {
                        void segment.updateCurvePlot([]);
                        const startPoint = this._lineSegments[findIndex].getStartControlPoint();
                        const startSegment = this._lineSegments[findIndex];
                        startSegment.visible = false;
                        let addedWidgets = [ this._segmentSelectors[findIndex].widget, startSegment.getEndControlPoint().widget ];
                        for (let i = findIndex + 1; i < maxIndex; i++) {
                            addedWidgets = addedWidgets.concat([ this._segmentSelectors[i].widget, this._lineSegments[i].getEndControlPoint().widget ]);
                            this._lineSegments[i].visible = false;
                            void this._lineSegments[i].updateCurvePlot([]);
                            this._segmentSelectors[i].setSplineControlPoint(startPoint);
                            this._segmentSelectors[i].setBaseSplineSegment(startSegment);
                        }
                        startPoint.removeAllControlPointsFromSplineComponent();
                        startPoint.addControlPointsToSplineComponent(addedWidgets);
                        const interpPoints = startPoint.getSplineComponentInterpPoints();
                        startSegment.updateCurvePlot(interpPoints).then((() => {
                            startSegment.visible = true;
                        })).catch((err => {
                            this._uiSession.log.error(err.message);
                        }));
                    } else {
                        const baseSplineSegment = segmentSelector.getBaseSplineSegment();
                        const baseSplineControlPoint = segmentSelector.getSplineControlPoint();
                        if (!baseSplineSegment || !baseSplineControlPoint) {
                            this._uiSession.log.error(`Expected switching from merged curve to non-merged to have an original base spline segment`);
                        } else {
                            baseSplineSegment.visible = false;
                            let addedWidgets = [ this._segmentSelectors[findIndex].widget, baseSplineSegment.getEndControlPoint().widget ];
                            for (let i = findIndex + 1; i < index; i++) {
                                addedWidgets = addedWidgets.concat([ this._segmentSelectors[i].widget, this._lineSegments[i].getEndControlPoint().widget ]);
                            }
                            baseSplineControlPoint.removeAllControlPointsFromSplineComponent();
                            baseSplineControlPoint.addControlPointsToSplineComponent(addedWidgets);
                            baseSplineSegment.updateCurvePlot(baseSplineControlPoint.getSplineComponentInterpPoints()).then((() => {
                                baseSplineSegment.visible = true;
                            })).catch((err => {
                                this._uiSession.log.error(err.message);
                            }));
                            const startPoint = segment.getStartControlPoint();
                            addedWidgets = [ segmentSelector.widget, segment.getEndControlPoint().widget ];
                            for (let i = index + 1; i < maxIndex; i++) {
                                addedWidgets = addedWidgets.concat([ this._segmentSelectors[i].widget, this._lineSegments[i].getEndControlPoint().widget ]);
                                this._lineSegments[i].visible = false;
                                void this._lineSegments[i].updateCurvePlot([]);
                                this._segmentSelectors[i].setSplineControlPoint(startPoint);
                                this._segmentSelectors[i].setBaseSplineSegment(segment);
                            }
                            startPoint.removeAllControlPointsFromSplineComponent();
                            startPoint.addControlPointsToSplineComponent(addedWidgets);
                            segmentSelector.setBaseSplineSegment(undefined);
                            segmentSelector.setSplineControlPoint(undefined);
                            segment.updateCurvePlot(startPoint.getSplineComponentInterpPoints()).then((() => {
                                segment.visible = true;
                            })).catch((err => {
                                this._uiSession.log.error(err.message);
                            }));
                        }
                    }
                }
                if (curveTypeChanged) {
                    const startPoint = segment.getStartControlPoint();
                    const endPoint = segment.getEndControlPoint();
                    this._lineSegments[index].visible = false;
                    switch (segmentSelector.curveType) {
                      case CurveType.Hermite:
                        {
                            this._lineSegments[index] = new CurveSegment(this._uiSession, this._horizontalWeight, this._verticalWeight, this._linePreviewMap, this.cursorTargetModeRequested, this.groundLevelAtLocationRequested, startPoint, endPoint, startPoint.isWeightsOverridden ? {
                                horizontalWeight: startPoint.horizontalWeight,
                                verticalWeight: startPoint.verticalWeight
                            } : undefined, endPoint.isWeightsOverridden ? {
                                horizontalWeight: endPoint.horizontalWeight,
                                verticalWeight: endPoint.verticalWeight
                            } : undefined);
                            const widgets = [ segmentSelector.widget, endPoint.widget ];
                            startPoint.addSplineComponent(widgets);
                            const interpPoints = startPoint.getSplineComponentInterpPoints();
                            this._lineSegments[index].updateCurvePlot(interpPoints).then((res => {
                                this.applyPreviewChangeResults(res);
                            })).catch((err => {
                                this._uiSession.log.error(err.message);
                            }));
                            break;
                        }

                      case CurveType.None:
                        {
                            startPoint.removeSplineComponent();
                            segmentSelector.curveWithPrevSegment = false;
                            const baseSplineSegment = segmentSelector.getBaseSplineSegment();
                            const baseSplineControlPoint = segmentSelector.getSplineControlPoint();
                            if (baseSplineSegment && baseSplineControlPoint) {
                                segment.visible = false;
                                baseSplineSegment.visible = false;
                                let addedWidgets = [ this._segmentSelectors[findIndex].widget, baseSplineSegment.getEndControlPoint().widget ];
                                for (let i = findIndex + 1; i < index; i++) {
                                    addedWidgets = addedWidgets.concat([ this._segmentSelectors[i].widget, this._lineSegments[i].getEndControlPoint().widget ]);
                                }
                                baseSplineControlPoint.removeAllControlPointsFromSplineComponent();
                                baseSplineControlPoint.addControlPointsToSplineComponent(addedWidgets);
                                baseSplineSegment.updateCurvePlot(baseSplineControlPoint.getSplineComponentInterpPoints()).then((() => {
                                    baseSplineSegment.visible = true;
                                })).catch((err => {
                                    this._uiSession.log.error(err.message);
                                }));
                                const newStartSegment = this._lineSegments.at(index + 1) ?? this._lineSegments[index];
                                const newHeadSegmentSelector = this._segmentSelectors.at(index + 1) ?? this._segmentSelectors[index];
                                newHeadSegmentSelector.curveWithPrevSegment = false;
                                newHeadSegmentSelector.setBaseSplineSegment(undefined);
                                newHeadSegmentSelector.setSplineControlPoint(undefined);
                                newStartSegment.visible = false;
                                const newStartPoint = newStartSegment.getStartControlPoint();
                                if (index + 1 < maxIndex - 1) {
                                    addedWidgets = [ newHeadSegmentSelector.widget, newStartSegment.getEndControlPoint().widget ];
                                    for (let i = index + 2; i < maxIndex; i++) {
                                        addedWidgets = addedWidgets.concat([ this._segmentSelectors[i].widget, this._lineSegments[i].getEndControlPoint().widget ]);
                                        this._lineSegments[i].visible = false;
                                        void this._lineSegments[i].updateCurvePlot([]);
                                        this._segmentSelectors[i].setSplineControlPoint(newStartPoint);
                                        this._segmentSelectors[i].setBaseSplineSegment(newStartSegment);
                                    }
                                    newStartPoint.removeAllControlPointsFromSplineComponent();
                                    newStartPoint.addControlPointsToSplineComponent(addedWidgets);
                                }
                                segmentSelector.setBaseSplineSegment(undefined);
                                segmentSelector.setSplineControlPoint(undefined);
                                newStartSegment.updateCurvePlot(newStartPoint.getSplineComponentInterpPoints()).then((() => {
                                    newStartSegment.visible = true;
                                })).catch((err => {
                                    this._uiSession.log.error(err.message);
                                }));
                            }
                            this._lineSegments[index] = new LineSegment(this._uiSession, this._horizontalWeight, this._verticalWeight, this._blockLineTypeAlgorithm, this._linePreviewMap, this.cursorTargetModeRequested, this.groundLevelAtLocationRequested, startPoint, endPoint, startPoint.isWeightsOverridden ? {
                                horizontalWeight: startPoint.horizontalWeight,
                                verticalWeight: startPoint.verticalWeight
                            } : undefined, endPoint.isWeightsOverridden ? {
                                horizontalWeight: endPoint.horizontalWeight,
                                verticalWeight: endPoint.verticalWeight
                            } : undefined);
                            this._lineSegments[index].visible = true;
                            const midPointRes = this._lineSegments[index].getMidPoint();
                            const midPoint = {
                                ...startPoint.location
                            };
                            if (midPointRes) {
                                midPoint.x = Math.round(midPointRes.x);
                                midPoint.y = Math.round(midPointRes.y);
                                midPoint.z = Math.round(midPointRes.z);
                            }
                            this.moveSelector(this._segmentSelectors[index], midPoint, startPoint.location, endPoint.location, true);
                            break;
                        }
                    }
                }
                if (lib.Vector3Utils.magnitude(delta) !== 0) {
                    this.moveSelector(segmentSelector, options.knotPosition ?? segmentSelector.getLocation(), segment.start, segment.end, true);
                }
            }
        }
        moveSelector(segmentSelector, knotPosition, start, end, moveWidget = false) {
            segmentSelector.moveSelector(knotPosition, start, end, moveWidget);
            const index = this._segmentSelectors.findIndex((value => value === segmentSelector));
            if (index === -1) {
                this._uiSession.log.error(`Associated segment selector has no associated line segment`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            if (segmentSelector.curveType === CurveType.Hermite) {
                const startPoint = segmentSelector.getSplineControlPoint() ?? this._lineSegments[index].getStartControlPoint();
                const segment = segmentSelector.getBaseSplineSegment() ?? this._lineSegments[index];
                const interpPoints = startPoint.getSplineComponentInterpPoints();
                segment.updateCurvePlot(interpPoints).then((res => {
                    this.applyPreviewChangeResults(res);
                })).catch((err => {
                    this._uiSession.log.error(err.message);
                }));
            }
        }
        updateLineWeights(horizontalWeight, verticalWeight) {
            let updated = false;
            if (this._horizontalWeight !== horizontalWeight) {
                this._horizontalWeight = horizontalWeight;
                updated = true;
            }
            if (this._verticalWeight !== verticalWeight) {
                this._verticalWeight = verticalWeight;
                updated = true;
            }
            if (updated) {
                for (let i = 0; i < this._lineSegments.length; i++) {
                    this._lineSegments[i].setWeights(horizontalWeight, verticalWeight).then((results => this.applyPreviewChangeResults(results))).catch((err => {
                        this._uiSession.log.error(err.message);
                    }));
                }
            }
        }
        toggleSelectAllPoints() {
            if (this._controlPoints.length <= 0) {
                return;
            }
            if (this._controlPoints.some((controlPoint => !controlPoint.isSelected))) {
                this._widgetGroup.selectAllWidgets();
                this._controlPoints[this._controlPoints.length - 1].setGizmoActivated(true);
            } else {
                this._widgetGroup.deselectAllWidgets();
            }
        }
        toggleSelectPoint(controlPoint) {
            controlPoint.isSelected = !controlPoint.isSelected;
        }
        toggleVisibility(isVisible) {
            this._widgetGroup.visible = isVisible;
            this._linePreviewMap.previewVolume.visible = isVisible;
        }
        teardown() {
            this.clearAll();
            this._linePreviewMap.teardown();
        }
        applyPreviewChangeResults(results) {
            if (results.pointsRemoved.length > 0) {
                this._linePreviewMap.removePoints(results.pointsRemoved);
            }
            if (results.pointsAdded.length > 0) {
                this._linePreviewMap.addPoints(results.pointsAdded);
            }
        }
    }
    var QuickActionMode;
    (function(QuickActionMode) {
        QuickActionMode[QuickActionMode["Invalid"] = -1] = "Invalid";
        QuickActionMode[QuickActionMode["FillLine"] = 1] = "FillLine";
        QuickActionMode[QuickActionMode["DeleteBlocks"] = 2] = "DeleteBlocks";
        QuickActionMode[QuickActionMode["AddToSelection"] = 3] = "AddToSelection";
        QuickActionMode[QuickActionMode["ClearSelectedPoints"] = 4] = "ClearSelectedPoints";
        QuickActionMode[QuickActionMode["ClearAllPoints"] = 5] = "ClearAllPoints";
    })(QuickActionMode || (QuickActionMode = {}));
    const curveTypeValues = [ {
        label: "None",
        value: CurveType.None
    }, {
        label: "Hermite",
        value: CurveType.Hermite
    } ];
    const easeTypeValues = [ {
        label: "Linear",
        value: EaseType.Linear
    } ];
    const Line_PERSISTENCE_GROUP_NAME = "editor:line";
    const Line_PERSISTENCE_GROUPITEM_NAME = "line_settings";
    class InputModifierWatcher {
        constructor(_session, tool, _modifier) {
            this._isDown = false;
            const action = _session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.StatefulAction,
                onExecute: state => {
                    this._isDown = state;
                }
            });
            tool.registerKeyBinding(action, {
                key: _modifier,
                modifier: server_editor_namespaceObject.InputModifier.Any
            });
        }
        get isDown() {
            return this._isDown;
        }
    }
    class LineBehavior {
        constructor(uiSession) {
            this.startTransactionRequestedEventHandler = name => {
                this.startTransaction(name);
            };
            this.commitTransactionRequestedEventHandler = name => {
                this.commitTransaction(name);
            };
            this.cancelTransactionRequestedEventHandler = () => {
                this.cancelTransaction();
            };
            this._uiSession = uiSession;
            this._uiSession.log.debug(`Initializing ${LineBehavior.BEHAVIOR_NAME}`);
            this._persistenceManager = getPersistenceManager(uiSession.extensionContext.player);
            this._updatePointAndLineValsOperationTickHandle = undefined;
            this._pointLinePropsDirty = false;
            this._segmentSelectorPropsDirty = false;
            this._toolCursorProperties = {
                outlineColor: LineBehavior.SELECTION_COLOR_LIGHT_BLUE,
                controlMode: server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse,
                targetMode: server_editor_namespaceObject.CursorTargetMode.Block,
                visible: true
            };
            this._paneProperties = {
                quickActionMode: (0, server_editor_namespaceObject.makeObservable)(QuickActionMode.Invalid),
                blockLineTypeAlgorithm: (0, server_editor_namespaceObject.makeObservable)(BlockLineType.Direct),
                isUniformWeight: (0, server_editor_namespaceObject.makeObservable)(false),
                uniformWeight: (0, server_editor_namespaceObject.makeObservable)(1),
                horizontalWeight: (0, server_editor_namespaceObject.makeObservable)(1),
                verticalWeight: (0, server_editor_namespaceObject.makeObservable)(1),
                uniformWeightPropertyItem: {},
                horizontalWeightPropertyItem: {},
                verticalWeightPropertyItem: {},
                fillButtonPropertyItem: {}
            };
            this._controlPointProperties = {
                pointPosition: (0, server_editor_namespaceObject.makeObservable)({
                    x: 0,
                    y: 0,
                    z: 0
                }),
                useGlobalLineWeight: (0, server_editor_namespaceObject.makeObservable)(true),
                isUniformWeight: (0, server_editor_namespaceObject.makeObservable)(false),
                uniformWeight: (0, server_editor_namespaceObject.makeObservable)(1),
                horizontalWeight: (0, server_editor_namespaceObject.makeObservable)(1),
                verticalWeight: (0, server_editor_namespaceObject.makeObservable)(1),
                isUniformWeightPropertyItem: undefined,
                uniformWeightPropertyItem: undefined,
                horizontalWeightPropertyItem: undefined,
                verticalWeightPropertyItem: undefined
            };
            this._segmentOptionProperties = {
                segmentKnotPosition: (0, server_editor_namespaceObject.makeObservable)({
                    x: 0,
                    y: 0,
                    z: 0
                }),
                curveType: (0, server_editor_namespaceObject.makeObservable)(CurveType.None),
                mergeWithPreviousCurve: (0, server_editor_namespaceObject.makeObservable)(false),
                easeType: (0, server_editor_namespaceObject.makeObservable)(EaseType.Linear),
                knotPositionPropertyItem: undefined
            };
            this._telemetryManager = new TelemetryManager(this._uiSession.extensionContext.player, TelemetrySource.Line);
            this._lineSegmentsManager = new SegmentsManager(this._uiSession, this._paneProperties.blockLineTypeAlgorithm.value, this._paneProperties.horizontalWeight.value, this._paneProperties.verticalWeight.value, this.startTransactionRequestedEventHandler, this.commitTransactionRequestedEventHandler, this.cancelTransactionRequestedEventHandler);
            this._transactionHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(this._uiSession.extensionContext.transactionManager, (payload => {
                const oldState = payload.oldState;
                this.updateState(oldState);
            }), (payload => {
                const newState = payload.newState;
                this.updateState(newState);
            }));
            this._loadSettings();
            this._tool = this.createTool();
            this._pane = this.createPane();
            this._ctrlWatcher = new InputModifierWatcher(this._uiSession, this._tool, server_editor_namespaceObject.KeyboardKey.CTRL);
            this._cursorControlHolderPane = this._pane.createSubPane({
                title: "Hidden Cursor Control Holder Pane",
                hasExpander: false
            });
            this._cursorModeControl = new CursorModeControl(this._uiSession, this._tool, this._cursorControlHolderPane, true, this._toolCursorProperties, {
                hasPaneMargins: false
            });
            this._cursorModeControl.initialize();
            this._controlPointWeightPane = this.createLineAndPointWeightsPanes(this._pane);
            this._segmentOptionsPane = this.createSegmentOptionsPane(this._pane);
            this._pane.endConstruct();
            this._tool.bindPropertyPane(this._pane);
            this.registerMouseButtonInputs();
            this.registerKeyboardInputs();
        }
        teardown() {
            this._cursorModeControl.shutdown();
            this._lineSegmentsManager.teardown();
        }
        createTool() {
            const toolToggleAction = this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._uiSession.toolRail.setSelectedToolId(tool.id);
                }
            });
            this._uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, toolToggleAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_L,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:toolModeKeyBinding:toggleLine",
                label: "resourcePack.editor.toolRail.line.keyBinding.toggleTool.title",
                tooltip: "resourcePack.editor.toolRail.line.keyBinding.toggleTool.tooltip"
            });
            const tool = this._uiSession.toolRail.addTool("editor:modalTool:line", {
                title: "resourcePack.editor.toolRail.line.title",
                icon: "pack://textures/editor/Line.png?filtering=point",
                tooltip: {
                    description: "resourcePack.editor.toolRail.line.tooltip",
                    image: "pack://textures/editor/LineTool.gif"
                },
                action: toolToggleAction
            });
            tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    this._cursorModeControl.activateControl();
                    this._updatePointAndLineValsOperationTickHandle = server_namespaceObject.system.runInterval((() => {
                        this.runUpdatePointAndLineValsOperation();
                        this.runUpdateSegmentSelectorValsOperation();
                        this.toggleSelectedControlPointOp();
                        this.toggleSelectedSegmentOptionsOp();
                    }), server_namespaceObject.TicksPerSecond);
                    this._lineSegmentsManager.toggleVisibility(true);
                    for (const selector of this._lineSegmentsManager.segmentSelectors) {
                        selector.isSelected = false;
                    }
                    for (const point of this._lineSegmentsManager.controlPoints) {
                        point.isSelected = false;
                    }
                } else {
                    if (this._updatePointAndLineValsOperationTickHandle !== undefined) {
                        server_namespaceObject.system.clearRun(this._updatePointAndLineValsOperationTickHandle);
                        this._updatePointAndLineValsOperationTickHandle = undefined;
                    }
                    this._cursorModeControl.deactivateControl();
                    this._lineSegmentsManager.toggleVisibility(false);
                }
            }));
            return tool;
        }
        createPane() {
            const pane = this._uiSession.createPropertyPane({
                title: "resourcePack.editor.toolRail.line.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.toolRail.line.tooltip", {
                        link: "https://aka.ms/BedrockEditorLineTool",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            pane.beginConstruct();
            pane.addDropdown(this._paneProperties.blockLineTypeAlgorithm, {
                title: "resourcePack.editor.toolRail.line.pane.algorithm.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.algorithm.tooltip",
                entries: [ {
                    label: "resourcePack.editor.toolRail.line.pane.algorithm.Direct",
                    value: BlockLineType.Direct
                }, {
                    label: "resourcePack.editor.toolRail.line.pane.algorithm.StaggeredContour",
                    value: BlockLineType.Staggered
                } ],
                onChange: () => {
                    this.updateLineAlgorithm();
                    this._saveSettings();
                }
            });
            pane.addDivider();
            pane.addToggleGroup(this._paneProperties.quickActionMode, {
                title: "resourcePack.editor.toolRail.line.quickAction.title",
                tooltip: "resourcePack.editor.toolRail.line.quickAction.tooltip",
                hiddenLabel: false,
                entries: [ {
                    value: QuickActionMode.FillLine,
                    icon: "fillIcon",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.toolRail.line.quickAction.fillLines",
                            props: [ getInputMarkup("editor:lineToolKeyBinding:fill") ]
                        },
                        description: "resourcePack.editor.toolRail.line.quickAction.fillLines.tooltip"
                    }
                }, {
                    value: QuickActionMode.DeleteBlocks,
                    icon: "trashCanIcon",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.toolRail.line.quickAction.deleteBlocks",
                            props: [ getInputMarkup("editor:lineToolKeyBinding:delete") ]
                        },
                        description: "resourcePack.editor.toolRail.line.quickAction.deleteBlocks.tooltip"
                    }
                }, {
                    value: QuickActionMode.AddToSelection,
                    icon: "marqueeAddIcon",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.toolRail.line.quickAction.addToSelection",
                            props: [ getInputMarkup("editor:lineToolKeyBinding:addToSelection") ]
                        },
                        description: "resourcePack.editor.toolRail.line.quickAction.addToSelection.tooltip"
                    }
                }, {
                    value: QuickActionMode.ClearSelectedPoints,
                    icon: "pack://textures/editor/Point-Subtract.png",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.toolRail.line.quickAction.clearSelectedPoints",
                            props: [ getInputMarkup("editor:lineToolKeyBinding:clearSelected") ]
                        },
                        description: "resourcePack.editor.toolRail.line.quickAction.clearSelectedPoints.tooltip"
                    }
                }, {
                    value: QuickActionMode.ClearAllPoints,
                    icon: "clearIcon",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.toolRail.line.quickAction.clearAllPoints",
                            props: [ getInputMarkup("editor:lineToolKeyBinding:clearAll") ]
                        },
                        description: "resourcePack.editor.toolRail.line.quickAction.clearAllPoints.tooltip"
                    }
                } ],
                onChange: newVal => {
                    this._paneProperties.quickActionMode.set(QuickActionMode.Invalid);
                    switch (newVal) {
                      case QuickActionMode.FillLine:
                        {
                            this._telemetryManager.fireTelemetryEvent(LineTelemetry.QuickAction, {
                                action: LineTelemetry.FillLine
                            });
                            this.fillLine();
                            break;
                        }

                      case QuickActionMode.DeleteBlocks:
                        {
                            this._telemetryManager.fireTelemetryEvent(LineTelemetry.QuickAction, {
                                action: LineTelemetry.DeleteBlocks
                            });
                            this.deleteBlocks();
                            break;
                        }

                      case QuickActionMode.AddToSelection:
                        {
                            this._telemetryManager.fireTelemetryEvent(LineTelemetry.QuickAction, {
                                action: LineTelemetry.AddToSelection
                            });
                            this.addToSelection();
                            break;
                        }

                      case QuickActionMode.ClearSelectedPoints:
                        {
                            this._telemetryManager.fireTelemetryEvent(LineTelemetry.QuickAction, {
                                action: LineTelemetry.ClearSelectedPoints
                            });
                            this.clearSelectedPoints();
                            break;
                        }

                      case QuickActionMode.ClearAllPoints:
                        {
                            this._telemetryManager.fireTelemetryEvent(LineTelemetry.QuickAction, {
                                action: LineTelemetry.ClearAllPoints
                            });
                            this.clearAllPoints();
                            break;
                        }
                    }
                }
            });
            pane.addDivider();
            pane.hide();
            return pane;
        }
        disableControlPointWeightSliders(usingGlobalWeights) {
            if (!this._controlPointProperties.isUniformWeightPropertyItem || !this._controlPointProperties.uniformWeightPropertyItem || !this._controlPointProperties.horizontalWeightPropertyItem || !this._controlPointProperties.verticalWeightPropertyItem) {
                return;
            }
            this._controlPointProperties.isUniformWeightPropertyItem.enable = !usingGlobalWeights;
            this._controlPointProperties.uniformWeightPropertyItem.enable = !usingGlobalWeights;
            this._controlPointProperties.horizontalWeightPropertyItem.enable = !usingGlobalWeights;
            this._controlPointProperties.verticalWeightPropertyItem.enable = !usingGlobalWeights;
            this._controlPointProperties.isUniformWeightPropertyItem.visible = !usingGlobalWeights;
            if (this._controlPointProperties.isUniformWeightPropertyItem.value) {
                this._controlPointProperties.uniformWeightPropertyItem.visible = !usingGlobalWeights;
            }
            if (!this._controlPointProperties.isUniformWeightPropertyItem.value) {
                this._controlPointProperties.horizontalWeightPropertyItem.visible = !usingGlobalWeights;
                this._controlPointProperties.verticalWeightPropertyItem.visible = !usingGlobalWeights;
            }
        }
        toggleUniformControlPointWeights(usingUniformValues) {
            if (!this._controlPointProperties.isUniformWeightPropertyItem || !this._controlPointProperties.uniformWeightPropertyItem || !this._controlPointProperties.horizontalWeightPropertyItem || !this._controlPointProperties.verticalWeightPropertyItem) {
                return;
            }
            this._controlPointProperties.uniformWeightPropertyItem.visible = usingUniformValues;
            this._controlPointProperties.uniformWeightPropertyItem.enable = usingUniformValues;
            this._controlPointProperties.horizontalWeightPropertyItem.visible = !usingUniformValues;
            this._controlPointProperties.horizontalWeightPropertyItem.enable = !usingUniformValues;
            this._controlPointProperties.verticalWeightPropertyItem.visible = !usingUniformValues;
            this._controlPointProperties.verticalWeightPropertyItem.enable = !usingUniformValues;
        }
        createLineAndPointWeightsPanes(pane) {
            const globalWeightPane = pane.createSubPane({
                title: "resourcePack.editor.toolRail.line.pane.globallineweight.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.line.pane.globallineweight.title",
                    description: [ "resourcePack.editor.toolRail.line.pane.thicknessWeight.tooltip" ]
                },
                hasExpander: true
            });
            globalWeightPane.beginConstruct();
            globalWeightPane.addBool(this._paneProperties.isUniformWeight, {
                title: "resourcePack.editor.toolRail.line.pane.uniformWeight.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.uniformWeight.tooltip",
                onChange: newVal => {
                    this._paneProperties.uniformWeightPropertyItem.visible = newVal;
                    this._paneProperties.uniformWeightPropertyItem.enable = newVal;
                    this._paneProperties.horizontalWeightPropertyItem.visible = !newVal;
                    this._paneProperties.horizontalWeightPropertyItem.enable = !newVal;
                    this._paneProperties.verticalWeightPropertyItem.visible = !newVal;
                    this._paneProperties.verticalWeightPropertyItem.enable = !newVal;
                    this._pointLinePropsDirty = true;
                    this._saveSettings();
                }
            });
            this._paneProperties.uniformWeightPropertyItem = globalWeightPane.addNumber(this._paneProperties.uniformWeight, {
                title: "resourcePack.editor.toolRail.line.pane.thicknessWeight.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.thicknessWeight.tooltip",
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                min: LineBehavior.LINE_MIN_WEIGHT,
                max: LineBehavior.LINE_MAX_WEIGHT,
                enable: this._paneProperties.isUniformWeight.value,
                visible: this._paneProperties.isUniformWeight.value,
                onChange: () => {
                    this._pointLinePropsDirty = true;
                    this._saveSettings();
                }
            });
            this._paneProperties.horizontalWeightPropertyItem = globalWeightPane.addNumber(this._paneProperties.horizontalWeight, {
                title: "resourcePack.editor.toolRail.line.pane.thicknessHorizontalWeight.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.thicknessHorizontalWeight.tooltip",
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                min: LineBehavior.LINE_MIN_WEIGHT,
                max: LineBehavior.LINE_MAX_WEIGHT,
                enable: !this._paneProperties.isUniformWeight.value,
                visible: !this._paneProperties.isUniformWeight.value,
                onChange: () => {
                    this._pointLinePropsDirty = true;
                    this._saveSettings();
                }
            });
            this._paneProperties.verticalWeightPropertyItem = globalWeightPane.addNumber(this._paneProperties.verticalWeight, {
                title: "resourcePack.editor.toolRail.line.pane.thicknessVerticalWeight.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.thicknessVerticalWeight.tooltip",
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                min: LineBehavior.LINE_MIN_WEIGHT,
                max: LineBehavior.LINE_MAX_WEIGHT,
                enable: !this._paneProperties.isUniformWeight.value,
                visible: !this._paneProperties.isUniformWeight.value,
                onChange: () => {
                    this._pointLinePropsDirty = true;
                    this._saveSettings();
                }
            });
            globalWeightPane.endConstruct();
            const controlPointPane = pane.createSubPane({
                title: "Point Pane",
                hasExpander: false
            });
            controlPointPane.beginConstruct();
            const pointPropertiesPane = controlPointPane.createSubPane({
                title: "resourcePack.editor.toolRail.line.point.properties.pane.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.line.point.properties.pane.title",
                    description: [ "resourcePack.editor.toolRail.line.point.properties.pane.tooltip" ]
                },
                hasExpander: true,
                hasMargins: false
            });
            pointPropertiesPane.beginConstruct();
            pointPropertiesPane.addVector3(this._controlPointProperties.pointPosition, {
                title: "resourcePack.editor.toolRail.line.point.properties.position.pane.title",
                tooltip: "resourcePack.editor.toolRail.line.point.properties.position.pane.tooltip",
                onChange: () => {
                    this._pointLinePropsDirty = true;
                }
            });
            pointPropertiesPane.endConstruct();
            const pointWeightPane = controlPointPane.createSubPane({
                title: "resourcePack.editor.toolRail.line.point.weight.pane.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.line.point.weight.pane.title",
                    description: [ "resourcePack.editor.toolRail.line.point.weight.pane.tooltip" ]
                },
                hasExpander: true,
                hasMargins: false
            });
            pointWeightPane.beginConstruct();
            pointWeightPane.addBool(this._controlPointProperties.useGlobalLineWeight, {
                title: "resourcePack.editor.toolRail.line.point.globalweight.title",
                tooltip: "resourcePack.editor.toolRail.line.point.globalweight.tooltip",
                onChange: newVal => {
                    this.disableControlPointWeightSliders(newVal);
                    this._pointLinePropsDirty = true;
                }
            });
            this._controlPointProperties.isUniformWeightPropertyItem = pointWeightPane.addBool(this._controlPointProperties.isUniformWeight, {
                title: "resourcePack.editor.toolRail.line.pane.uniformWeight.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.point.uniformWeight.tooltip",
                onChange: newVal => {
                    this.toggleUniformControlPointWeights(newVal);
                    this._pointLinePropsDirty = true;
                },
                enable: !this._controlPointProperties.useGlobalLineWeight.value,
                visible: false
            });
            this._controlPointProperties.uniformWeightPropertyItem = pointWeightPane.addNumber(this._controlPointProperties.uniformWeight, {
                title: "resourcePack.editor.toolRail.line.pane.thicknessWeight.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.point.thicknessWeight.tooltip",
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                min: LineBehavior.LINE_MIN_WEIGHT,
                max: LineBehavior.LINE_MAX_WEIGHT,
                enable: !this._controlPointProperties.useGlobalLineWeight.value,
                visible: false,
                onChange: () => {
                    this._pointLinePropsDirty = true;
                }
            });
            this._controlPointProperties.horizontalWeightPropertyItem = pointWeightPane.addNumber(this._controlPointProperties.horizontalWeight, {
                title: "resourcePack.editor.toolRail.line.pane.thicknessHorizontalWeight.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.point.thicknessHorizontalWeight.tooltip",
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                min: LineBehavior.LINE_MIN_WEIGHT,
                max: LineBehavior.LINE_MAX_WEIGHT,
                enable: !this._controlPointProperties.useGlobalLineWeight.value,
                onChange: () => {
                    this._pointLinePropsDirty = true;
                },
                visible: false
            });
            this._controlPointProperties.verticalWeightPropertyItem = pointWeightPane.addNumber(this._controlPointProperties.verticalWeight, {
                title: "resourcePack.editor.toolRail.line.pane.thicknessVerticalWeight.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.point.thicknessVerticalWeight.tooltip",
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                min: LineBehavior.LINE_MIN_WEIGHT,
                max: LineBehavior.LINE_MAX_WEIGHT,
                enable: !this._controlPointProperties.useGlobalLineWeight.value,
                onChange: () => {
                    this._pointLinePropsDirty = true;
                },
                visible: false
            });
            pointWeightPane.endConstruct();
            controlPointPane.hide();
            controlPointPane.endConstruct();
            return controlPointPane;
        }
        createSegmentOptionsPane(pane) {
            const segmentOptionsPanes = pane.createSubPane({
                title: "Segment Options",
                hasExpander: false
            });
            segmentOptionsPanes.beginConstruct();
            const segmentPointProperties = segmentOptionsPanes.createSubPane({
                title: "resourcePack.editor.toolRail.line.pane.segment.properties.pane.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.line.pane.segment.properties.pane.title",
                    description: [ "resourcePack.editor.toolRail.line.pane.segment.properties.pane.tooltip" ]
                },
                hasExpander: true,
                hasMargins: false
            });
            segmentPointProperties.beginConstruct();
            this._segmentOptionProperties.knotPositionPropertyItem = segmentPointProperties.addVector3(this._segmentOptionProperties.segmentKnotPosition, {
                title: "resourcePack.editor.toolRail.line.pane.segment.properties.knot.position.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.segment.properties.knot.position.tooltip",
                onChange: () => {
                    this._segmentSelectorPropsDirty = true;
                }
            });
            segmentPointProperties.endConstruct();
            const segmentCurveOptions = segmentOptionsPanes.createSubPane({
                title: "resourcePack.editor.toolRail.line.pane.segment.curve.properties.pane.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.line.pane.segment.curve.properties.pane.title",
                    description: [ "resourcePack.editor.toolRail.line.pane.segment.curve.properties.pane.tooltip" ]
                },
                hasExpander: true,
                hasMargins: false
            });
            segmentCurveOptions.beginConstruct();
            this._segmentOptionProperties.mergeWithPrevPropertyItem = segmentCurveOptions.addBool(this._segmentOptionProperties.mergeWithPreviousCurve, {
                title: "resourcePack.editor.toolRail.line.pane.segment.curve.properties.merge.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.segment.curve.properties.merge.tooltip",
                enable: false,
                onChange: () => {
                    this._segmentSelectorPropsDirty = true;
                }
            });
            segmentCurveOptions.addDropdown(this._segmentOptionProperties.curveType, {
                title: "resourcePack.editor.toolRail.line.pane.segment.curve.properties.type.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.segment.curve.properties.type.tooltip",
                entries: curveTypeValues,
                onChange: () => {
                    this._segmentSelectorPropsDirty = true;
                }
            });
            segmentCurveOptions.endConstruct();
            const segmentEaseOptions = segmentOptionsPanes.createSubPane({
                title: "resourcePack.editor.toolRail.line.pane.segment.ease.properties.pane.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.line.pane.segment.ease.properties.pane.title",
                    description: [ "resourcePack.editor.toolRail.line.pane.segment.ease.properties.pane.tooltip" ]
                },
                hasExpander: true,
                hasMargins: false
            });
            segmentEaseOptions.beginConstruct();
            segmentEaseOptions.addDropdown(this._segmentOptionProperties.easeType, {
                title: "resourcePack.editor.toolRail.line.pane.segment.ease.properties.type.title",
                tooltip: "resourcePack.editor.toolRail.line.pane.segment.ease.properties.type.tooltip",
                entries: easeTypeValues,
                onChange: () => {
                    this._segmentSelectorPropsDirty = true;
                }
            });
            segmentEaseOptions.endConstruct();
            segmentOptionsPanes.endConstruct();
            return segmentOptionsPanes;
        }
        registerMouseButtonInputs() {
            const executeAction = this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton && mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonUp && this._tool.isActive) {
                        if (mouseProps.modifiers.ctrl) {
                            this.ctrlClick(mouseRay);
                        } else {
                            this.click(mouseRay);
                        }
                    }
                }
            });
            this._tool.registerMouseButtonBinding(executeAction);
        }
        registerKeyboardInputs() {
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.clearAllPoints();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.BACKSPACE,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: `editor:lineToolKeyBinding:clearAll`,
                label: `resourcePack.editor.toolRail.line.keyBinding.clearAll.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.clearAll.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.clearSelectedPoints();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.BACKSPACE,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:clearSelected`,
                label: `resourcePack.editor.toolRail.line.keyBinding.clearSelected.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.clearSelected.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.fillLine();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_F,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: `editor:lineToolKeyBinding:fill`,
                label: `resourcePack.editor.toolRail.line.keyBinding.fill.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.fill.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.toggleAllPoints();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_A,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: `editor:lineToolKeyBinding:toggleAll`,
                label: `resourcePack.editor.toolRail.line.keyBinding.toggleAll.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.toggleAll.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.deleteBlocks();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.DELETE
            }, {
                uniqueId: `editor:lineToolKeyBinding:delete`,
                label: `resourcePack.editor.toolRail.line.keyBinding.delete.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.delete.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.addToSelection();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_S,
                modifier: server_editor_namespaceObject.InputModifier.Alt
            }, {
                uniqueId: `editor:lineToolKeyBinding:addToSelection`,
                label: `resourcePack.editor.toolRail.line.keyBinding.addToSelection.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.addToSelection.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.clampWeights(1, true);
                    this._pointLinePropsDirty = true;
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.RIGHT,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:increaseHorizontalWeight`,
                label: `resourcePack.editor.toolRail.line.keyBinding.increaseHorizontalWeight.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.increaseHorizontalWeight.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.clampWeights(-1, true);
                    this._pointLinePropsDirty = true;
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.LEFT,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:decreaseHorizontalWeight`,
                label: `resourcePack.editor.toolRail.line.keyBinding.decreaseHorizontalWeight.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.decreaseHorizontalWeight.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.clampWeights(1, false);
                    this._pointLinePropsDirty = true;
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.UP,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:increaseVerticalWeight`,
                label: `resourcePack.editor.toolRail.line.keyBinding.increaseVerticalWeight.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.increaseVerticalWeight.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.clampWeights(-1, false);
                    this._pointLinePropsDirty = true;
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.DOWN,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:decreaseVerticalWeight`,
                label: `resourcePack.editor.toolRail.line.keyBinding.decreaseVerticalWeight.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.decreaseVerticalWeight.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.nudgeSelected(direction_Direction.Up, "up");
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_UP,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:moveUp`,
                label: `resourcePack.editor.toolRail.line.keyBinding.moveUp.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.moveUp.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.nudgeSelected(direction_Direction.Down, "down");
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_DOWN,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:moveDown`,
                label: `resourcePack.editor.toolRail.line.keyBinding.moveDown.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.moveDown.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.nudgeSelected(direction_Direction.Left, "left");
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.LEFT,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:moveLeft`,
                label: `resourcePack.editor.toolRail.line.keyBinding.moveLeft.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.moveLeft.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.nudgeSelected(direction_Direction.Right, "right");
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.RIGHT,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:moveRight`,
                label: `resourcePack.editor.toolRail.line.keyBinding.moveRight.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.moveRight.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.nudgeSelected(direction_Direction.Forward, "forward");
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.UP,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:moveForward`,
                label: `resourcePack.editor.toolRail.line.keyBinding.moveForward.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.moveForward.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.nudgeSelected(direction_Direction.Back, "back");
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.DOWN,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:lineToolKeyBinding:moveBack`,
                label: `resourcePack.editor.toolRail.line.keyBinding.moveBack.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.moveBack.tooltip`
            });
            this._tool.registerKeyBinding(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._tool.isActive) {
                        const cursorRay = this._uiSession.extensionContext.cursor.getRay();
                        const location = this._uiSession.extensionContext.cursor.getPosition();
                        const ray = {
                            location,
                            direction: cursorRay.start,
                            cursorBlockLocation: location,
                            rayHit: cursorRay.hit
                        };
                        this._ctrlWatcher.isDown ? this.ctrlClick(ray) : this.click(ray);
                    }
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.ENTER
            }, {
                uniqueId: `editor:lineToolKeyBinding:select`,
                label: `resourcePack.editor.toolRail.line.keyBinding.select.title`,
                tooltip: `resourcePack.editor.toolRail.line.keyBinding.select.tooltip`
            });
        }
        clampWeights(value, isHorizontal) {
            let weight = this._paneProperties.isUniformWeight.value ? this._paneProperties.uniformWeight.value : isHorizontal ? this._paneProperties.horizontalWeight.value : this._paneProperties.verticalWeight.value;
            weight += value;
            const clamped = Math.min(Math.max(weight, LineBehavior.LINE_MIN_WEIGHT), LineBehavior.LINE_MAX_WEIGHT);
            if (this._paneProperties.isUniformWeight.value) {
                this._paneProperties.uniformWeight.set(clamped);
            } else if (isHorizontal) {
                this._paneProperties.horizontalWeight.set(clamped);
            } else {
                this._paneProperties.verticalWeight.set(clamped);
            }
        }
        updateState(stateInfo) {
            this._lineSegmentsManager.setState(stateInfo.segmentStates, stateInfo.segmentSelectorStates);
            try {
                this._uiSession.extensionContext.selectionManager.volume.set(stateInfo.selectionVolume);
            } catch (e) {
                this._uiSession.log.error(`Something went wrong while restoring the selection volume during an undo/redo: '${stringFromException(e)}'`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
        }
        startTransaction(name) {
            if (this._tempTransactionData !== undefined) {
                throw new Error("Cannot perform a transactionable operation while another transaction is active");
            }
            const lineToolName = `LineTool:${name}`;
            const segmentStates = [];
            for (let i = 0; i < this._lineSegmentsManager.controlPoints.length; i++) {
                const segmentState = {
                    location: this._lineSegmentsManager.controlPoints[i].location,
                    separation: this._lineSegmentsManager.controlPoints[i].isSeparate,
                    selection: this._lineSegmentsManager.controlPoints[i].isSelected,
                    weightsOverridden: this._lineSegmentsManager.controlPoints[i].isWeightsOverridden,
                    usingUniformValue: this._lineSegmentsManager.controlPoints[i].usingUniformValues,
                    horizontalWeight: this._lineSegmentsManager.controlPoints[i].horizontalWeight,
                    verticalWeight: this._lineSegmentsManager.controlPoints[i].verticalWeight
                };
                segmentStates.push(segmentState);
            }
            const segmentSelectorStates = [];
            for (let i = 0; i < this._lineSegmentsManager.segmentSelectors.length; i++) {
                const selectorState = {
                    location: this._lineSegmentsManager.segmentSelectors[i].getLocation(),
                    curveType: this._lineSegmentsManager.segmentSelectors[i].curveType,
                    easeType: this._lineSegmentsManager.segmentSelectors[i].easeType,
                    isSelected: this._lineSegmentsManager.segmentSelectors[i].isSelected,
                    mergeWithPreviousCurve: this._lineSegmentsManager.segmentSelectors[i].curveWithPrevSegment
                };
                segmentSelectorStates.push(selectorState);
            }
            const oldState = {
                segmentStates,
                segmentSelectorStates,
                selectionVolume: this._uiSession.extensionContext.selectionManager.volume.get()
            };
            const newState = {
                segmentStates: [],
                segmentSelectorStates: [],
                selectionVolume: oldState.selectionVolume
            };
            this._tempTransactionData = {
                oldState,
                newState,
                operationName: lineToolName
            };
            this._uiSession.extensionContext.transactionManager.openTransaction(lineToolName);
        }
        commitTransaction(name) {
            if (this._tempTransactionData) {
                const lineToolName = `LineTool:${name}`;
                const newPointStates = [];
                for (let i = 0; i < this._lineSegmentsManager.controlPoints.length; i++) {
                    const segmentState = {
                        location: this._lineSegmentsManager.controlPoints[i].location,
                        separation: this._lineSegmentsManager.controlPoints[i].isSeparate,
                        selection: this._lineSegmentsManager.controlPoints[i].isSelected,
                        weightsOverridden: this._lineSegmentsManager.controlPoints[i].isWeightsOverridden,
                        usingUniformValue: this._lineSegmentsManager.controlPoints[i].usingUniformValues,
                        horizontalWeight: this._lineSegmentsManager.controlPoints[i].horizontalWeight,
                        verticalWeight: this._lineSegmentsManager.controlPoints[i].verticalWeight
                    };
                    newPointStates.push(segmentState);
                }
                const newSegmentSelectorStates = [];
                for (let i = 0; i < this._lineSegmentsManager.segmentSelectors.length; i++) {
                    const selectorState = {
                        location: this._lineSegmentsManager.segmentSelectors[i].getLocation(),
                        curveType: this._lineSegmentsManager.segmentSelectors[i].curveType,
                        easeType: this._lineSegmentsManager.segmentSelectors[i].easeType,
                        isSelected: this._lineSegmentsManager.segmentSelectors[i].isSelected,
                        mergeWithPreviousCurve: this._lineSegmentsManager.segmentSelectors[i].curveWithPrevSegment
                    };
                    newSegmentSelectorStates.push(selectorState);
                }
                this._tempTransactionData.newState = {
                    segmentStates: newPointStates,
                    segmentSelectorStates: newSegmentSelectorStates,
                    selectionVolume: this._uiSession.extensionContext.selectionManager.volume.get()
                };
                this._transactionHandler.addUserDefinedOperation(this._tempTransactionData, lineToolName);
                this._uiSession.extensionContext.transactionManager.commitOpenTransaction();
                this._tempTransactionData = undefined;
            } else {
                this._uiSession.log.warning("There was no transaction data available to commit");
            }
        }
        cancelTransaction() {
            this._uiSession.extensionContext.transactionManager.discardOpenTransaction();
            this._tempTransactionData = undefined;
        }
        performSingleTransactionableOperation(operation, name) {
            this.startTransaction(name);
            try {
                const operationCompleted = operation();
                if (!operationCompleted) {
                    throw new Error(`Operation 'LineTool:${name}' failed`);
                }
                this.commitTransaction(name);
            } catch (e) {
                this.cancelTransaction();
                this._uiSession.log.error(`Something went wrong! 'LineTool:${name}' failed: ${stringFromException(e)}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
        }
        clearAllPoints() {
            if (this._lineSegmentsManager.controlPoints.length === 0) {
                this._uiSession.log.warning(`No control points to clear.`);
                return;
            }
            this.performSingleTransactionableOperation((() => {
                this._telemetryManager.fireTelemetryEvent(LineTelemetry.ClearAllPoints);
                this._lineSegmentsManager.clearAll();
                this.toggleSelectedControlPointOp();
                return true;
            }), "ClearAllPoints");
        }
        fillLine() {
            if (this._lineSegmentsManager.controlPoints.length === 0) {
                this._uiSession.log.warning(`No lines or points available to fill`);
                return;
            }
            this._telemetryManager.fireTelemetryEvent(LineTelemetry.FillLine);
            this._lineSegmentsManager.fillLine().then((() => {})).catch((() => {}));
        }
        deleteBlocks() {
            if (this._lineSegmentsManager.controlPoints.length === 0) {
                this._uiSession.log.warning(`No blocks highlighted to delete.`);
                return;
            }
            this._telemetryManager.fireTelemetryEvent(LineTelemetry.DeleteBlocks);
            this._lineSegmentsManager.fillLine(true).then((() => {})).catch((() => {}));
        }
        updateLineAlgorithm() {
            this._telemetryManager.fireTelemetryEvent(LineTelemetry.AlgorithmChanged, {
                mode: this._paneProperties.blockLineTypeAlgorithm.value
            });
            this._lineSegmentsManager.blockLineTypeAlgorithm = this._paneProperties.blockLineTypeAlgorithm.value;
        }
        updatePointAndLineVals() {
            this._telemetryManager.fireTelemetryEvent(LineTelemetry.WeightChanged);
            this._lineSegmentsManager.updateSelectedControlPointData(!this._controlPointProperties.useGlobalLineWeight.value, this._controlPointProperties.isUniformWeight.value, this._controlPointProperties.pointPosition.value, this._controlPointProperties.isUniformWeight.value ? this._controlPointProperties.uniformWeight.value : this._controlPointProperties.horizontalWeight.value, this._controlPointProperties.isUniformWeight.value ? this._controlPointProperties.uniformWeight.value : this._controlPointProperties.verticalWeight.value);
            this._lineSegmentsManager.updateLineWeights(this._paneProperties.isUniformWeight.value ? this._paneProperties.uniformWeight.value : this._paneProperties.horizontalWeight.value, this._paneProperties.isUniformWeight.value ? this._paneProperties.uniformWeight.value : this._paneProperties.verticalWeight.value);
        }
        clearSelectedPoints() {
            if (!this._lineSegmentsManager.controlPoints.some((point => point.isSelected))) {
                this._uiSession.log.warning(`No selected control points to clear.`);
                return;
            }
            this.performSingleTransactionableOperation((() => {
                this._telemetryManager.fireTelemetryEvent(LineTelemetry.ClearSelectedPoints);
                this._lineSegmentsManager.clearSelectedPoints();
                this.toggleSelectedControlPointOp();
                return true;
            }), "ClearSelectedPoints");
        }
        toggleAllPoints() {
            if (this._lineSegmentsManager.controlPoints.length === 0) {
                this._uiSession.log.warning(`No control points to toggle.`);
                return;
            }
            this.performSingleTransactionableOperation((() => {
                this._telemetryManager.fireTelemetryEvent(LineTelemetry.ToggleSelectAll);
                this._lineSegmentsManager.toggleSelectAllPoints();
                return true;
            }), "ToggleSelectAllLinePoints");
        }
        addToSelection() {
            if (this._lineSegmentsManager.linePreviewMap.previewVolume.isEmpty) {
                this._uiSession.log.warning(`No lines exist to add to selection.`);
                return;
            }
            this.performSingleTransactionableOperation((() => {
                this._telemetryManager.fireTelemetryEvent(LineTelemetry.AddToSelection);
                this._uiSession.extensionContext.selectionManager.volume.add(this._lineSegmentsManager.linePreviewMap.previewVolume.volume);
                this._lineSegmentsManager.clearAll();
                return true;
            }), `AddToSelection`);
        }
        nudgeSelected(direction, directionStr) {
            if (this._lineSegmentsManager.controlPoints.length === 0) {
                this._uiSession.log.warning(`No control points to nudge.`);
                return;
            }
            this.performSingleTransactionableOperation((() => {
                this._telemetryManager.fireTelemetryEvent(LineTelemetry.Nudge, {
                    direction: directionStr
                });
                this._lineSegmentsManager.nudgeSelectedPoints(direction);
                return true;
            }), `Nudge${directionStr}`);
        }
        ctrlClick(mouseRay) {
            const found = this.getClosestControlPointClicked(mouseRay.location, mouseRay.direction);
            if (found !== undefined) {
                this.performSingleTransactionableOperation((() => {
                    this._telemetryManager.fireTelemetryEvent(LineTelemetry.LeftClick, {
                        mode: "noModifiers"
                    });
                    this._lineSegmentsManager.toggleSelectPoint(found);
                    this.updateControlPointProps(found);
                    return true;
                }), "ToggleSelectPoint");
            } else if (mouseRay?.cursorBlockLocation) {
                const targetLocation = mouseRay.cursorBlockLocation;
                if (this._lineSegmentsManager.controlPoints.length >= LineBehavior.MAX_CONTROL_POINTS) {
                    this._uiSession.log.warning(`Cannot place more than ${LineBehavior.MAX_CONTROL_POINTS} points.`);
                    return;
                }
                if (!this.isLocationValidForNewPoint(targetLocation)) {
                    this._uiSession.log.warning(`Cannot place point here (new control points must be within view distance, and no two points can exist in the same location).`);
                    return;
                }
                this.performSingleTransactionableOperation((() => {
                    this._telemetryManager.fireTelemetryEvent(LineTelemetry.LeftClick, {
                        mode: "ctrl"
                    });
                    this._lineSegmentsManager.addNewPoint(targetLocation, true);
                    this.toggleSelectedControlPointOp();
                    return true;
                }), "AddSeparatedPoint");
            }
        }
        click(mouseRay) {
            const found = this.getClosestControlPointClicked(mouseRay.location, mouseRay.direction);
            if (found !== undefined) {
                this.performSingleTransactionableOperation((() => {
                    this._telemetryManager.fireTelemetryEvent(LineTelemetry.LeftClick, {
                        mode: "noModifiers"
                    });
                    this._lineSegmentsManager.toggleSelectPoint(found);
                    this.updateControlPointProps(found);
                    return true;
                }), "ToggleSelectPoint");
            } else if (mouseRay?.cursorBlockLocation) {
                const targetLocation = mouseRay.cursorBlockLocation;
                if (this._lineSegmentsManager.controlPoints.length >= LineBehavior.MAX_CONTROL_POINTS) {
                    this._uiSession.log.warning(`Cannot place more than ${LineBehavior.MAX_CONTROL_POINTS} points.`);
                    return;
                }
                if (!this.isLocationValidForNewPoint(targetLocation)) {
                    this._uiSession.log.warning(`Cannot place point here (new control points must be within view distance of the player, and no two points can exist in the same location).`);
                    return;
                }
                this.performSingleTransactionableOperation((() => {
                    this._telemetryManager.fireTelemetryEvent(LineTelemetry.LeftClick, {
                        mode: "noModifiers"
                    });
                    this._lineSegmentsManager.addNewPoint(targetLocation);
                    this.toggleSelectedControlPointOp();
                    return true;
                }), "AddPoint");
            }
        }
        getClosestControlPointClicked(startPos, direction) {
            let minDistance = Infinity;
            let result = undefined;
            const start = [ startPos.x, startPos.y, startPos.z ];
            const dir = [ direction.x, direction.y, direction.z ];
            for (let i = 0; i < this._lineSegmentsManager.controlPoints.length; i++) {
                let tMin = 0;
                let tMax = Infinity;
                const blockMin = {
                    x: this._lineSegmentsManager.controlPoints[i].location.x,
                    y: this._lineSegmentsManager.controlPoints[i].location.y,
                    z: this._lineSegmentsManager.controlPoints[i].location.z
                };
                const blockMax = {
                    x: this._lineSegmentsManager.controlPoints[i].location.x + 1,
                    y: this._lineSegmentsManager.controlPoints[i].location.y + 1,
                    z: this._lineSegmentsManager.controlPoints[i].location.z + 1
                };
                for (let i = 0; i < 3; i++) {
                    const min = [ blockMin.x, blockMin.y, blockMin.z ][i];
                    const max = [ blockMax.x, blockMax.y, blockMax.z ][i];
                    if (Math.abs(dir[i]) < 1e-6) {
                        if (start[i] < min || start[i] > max) {
                            continue;
                        }
                    } else {
                        const t1 = (min - start[i]) / dir[i];
                        const t2 = (max - start[i]) / dir[i];
                        tMin = Math.max(tMin, Math.min(t1, t2));
                        tMax = Math.min(tMax, Math.max(t1, t2));
                    }
                }
                if (tMax >= Math.max(0, tMin)) {
                    const ptDistance = Math.abs(lib.Vector3Utils.magnitude(lib.Vector3Utils.subtract(this._lineSegmentsManager.controlPoints[i].location, startPos)));
                    if (ptDistance < minDistance) {
                        result = this._lineSegmentsManager.controlPoints[i];
                        minDistance = ptDistance;
                    }
                }
            }
            return result;
        }
        runUpdatePointAndLineValsOperation() {
            if (this._pointLinePropsDirty) {
                this.updatePointAndLineVals();
                this._pointLinePropsDirty = false;
            }
        }
        runUpdateSegmentSelectorValsOperation() {
            if (this._segmentSelectorPropsDirty) {
                this.updateSegmentSelectorValues();
                this._segmentSelectorPropsDirty = false;
            }
        }
        updateSegmentSelectorValues() {
            const options = {
                knotPosition: this._segmentOptionProperties.segmentKnotPosition.value,
                curveType: this._segmentOptionProperties.curveType.value,
                curveWithPrevSegment: this._segmentOptionProperties.mergeWithPreviousCurve.value,
                easeType: this._segmentOptionProperties.easeType.value
            };
            void this._lineSegmentsManager.updateSegmentSelectorValues(options);
        }
        toggleSelectedControlPointOp() {
            const selectedPoints = this._lineSegmentsManager.selectedPoints;
            if (selectedPoints.length !== 1) {
                this._controlPointWeightPane.hide();
                return;
            }
            this.updateControlPointProps(selectedPoints[0]);
            this._controlPointWeightPane.show();
        }
        updateControlPointProps(selectedPoint) {
            this._controlPointProperties.pointPosition.set(selectedPoint.location);
            this._controlPointProperties.horizontalWeight.set(selectedPoint.horizontalWeight);
            this._controlPointProperties.verticalWeight.set(selectedPoint.verticalWeight);
            if (this._controlPointProperties.isUniformWeight.value !== selectedPoint.usingUniformValues) {
                this._controlPointProperties.isUniformWeight.set(selectedPoint.usingUniformValues);
                this.toggleUniformControlPointWeights(selectedPoint.usingUniformValues);
            }
            if (this._controlPointProperties.useGlobalLineWeight.value !== !selectedPoint.isWeightsOverridden) {
                this._controlPointProperties.useGlobalLineWeight.set(!selectedPoint.isWeightsOverridden);
                this.disableControlPointWeightSliders(!selectedPoint.isWeightsOverridden);
            }
        }
        toggleSelectedSegmentOptionsOp() {
            const selectedSelector = this._lineSegmentsManager.selectedSegmentSelector;
            if (selectedSelector === undefined) {
                this._segmentOptionsPane.hide();
                return;
            }
            this.updateSelectedSelectorProps(selectedSelector);
            this._segmentOptionsPane.show();
        }
        updateSelectedSelectorProps(segmentSelector) {
            this._segmentOptionProperties.curveType.set(segmentSelector.curveType);
            this._segmentOptionProperties.easeType.set(segmentSelector.easeType);
            this._segmentOptionProperties.mergeWithPreviousCurve.set(segmentSelector.curveWithPrevSegment);
            if (this._segmentOptionProperties.mergeWithPrevPropertyItem) {
                this._segmentOptionProperties.mergeWithPrevPropertyItem.enable = this._lineSegmentsManager.selectedSegmentSelectorHasCurveInPreviousSegment() && segmentSelector.curveType === CurveType.Hermite;
            }
            this._segmentOptionProperties.segmentKnotPosition.set(segmentSelector.getLocation());
            if (this._segmentOptionProperties.knotPositionPropertyItem) {
                if (segmentSelector.curveType === CurveType.None) {
                    this._segmentOptionProperties.knotPositionPropertyItem.enable = false;
                } else {
                    this._segmentOptionProperties.knotPositionPropertyItem.enable = true;
                }
            }
        }
        isLocationValidForNewPoint(location) {
            if (this._lineSegmentsManager.controlPoints.length === 0) {
                return true;
            }
            const locationUnoccupied = !this._lineSegmentsManager.controlPoints.some((pt => lib.Vector3Utils.equals(pt.location, location)));
            const viewDistance = this._uiSession.extensionContext.cursor.maxViewBlockDistance;
            const playerLocation = this._uiSession.extensionContext.player.location;
            const playerXZLocation = {
                x: playerLocation.x,
                y: 0,
                z: playerLocation.z
            };
            const XZLocation = {
                x: location.x,
                y: 0,
                z: location.z
            };
            const locationWithinMaxDistance = Math.abs(lib.Vector3Utils.magnitude(lib.Vector3Utils.subtract(playerXZLocation, XZLocation))) <= viewDistance;
            return locationUnoccupied && locationWithinMaxDistance;
        }
        _loadSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(Line_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const storeItem = group.fetchItem(Line_PERSISTENCE_GROUPITEM_NAME);
                if (storeItem && storeItem.value) {
                    try {
                        const storedSettings = storeItem.value;
                        this._paneProperties.blockLineTypeAlgorithm.set(storedSettings.algorithm);
                        this._paneProperties.horizontalWeight.set(storedSettings.horizontalWeight);
                        this._paneProperties.verticalWeight.set(storedSettings.verticalWeight);
                        this._paneProperties.isUniformWeight.set(storedSettings.isUniformWeight);
                        this._paneProperties.uniformWeight.set(storedSettings.uniformWeight);
                    } catch (error) {
                        this._uiSession.log.error("Fail to load the settings, error: " + stringFromException(error));
                    }
                }
                group.dispose();
            }
        }
        _saveSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(Line_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const settings = {
                    algorithm: this._paneProperties.blockLineTypeAlgorithm.value,
                    horizontalWeight: this._paneProperties.horizontalWeight.value,
                    verticalWeight: this._paneProperties.verticalWeight.value,
                    isUniformWeight: this._paneProperties.isUniformWeight.value,
                    uniformWeight: this._paneProperties.uniformWeight.value
                };
                const storeItem = group.getOrCreateItem(Line_PERSISTENCE_GROUPITEM_NAME, settings);
                if (storeItem) {
                    storeItem.commit();
                }
                group.dispose();
                return;
            }
            this._uiSession.log.error("Fail to save settings for Line");
        }
    }
    LineBehavior.BEHAVIOR_NAME = "Line";
    LineBehavior.LINE_MIN_WEIGHT = 1;
    LineBehavior.LINE_MAX_WEIGHT = 5;
    LineBehavior.MAX_CONTROL_POINTS = 80;
    LineBehavior.MAX_CONTROL_POINTS_DISTANCE = 100;
    LineBehavior.MAX_PTS_PLAYER_DISTANCE = 100;
    LineBehavior.SELECTION_COLOR_LIGHT_BLUE = {
        red: 0,
        green: .85,
        blue: .95,
        alpha: 1
    };
    class Stack {
        constructor(maxStackSize) {
            this.maxStackSize = maxStackSize;
            this.internalStack = [];
            this.stackHead = -1;
        }
        isEmpty() {
            return this.internalStack.length === 0;
        }
        push(element) {
            if (this.stackHead < this.internalStack.length - 1) {
                this.internalStack.length = this.stackHead + 1;
            }
            const elementsToTrim = this.maxStackSize && this.internalStack.length >= this.maxStackSize ? this.maxStackSize - this.internalStack.length + 1 : 0;
            this.internalStack = [ ...this.internalStack.slice(elementsToTrim), element ];
            this.stackHead = this.internalStack.length - 1;
        }
        moveHeadDown() {
            if (this.isEmpty()) {
                return;
            }
            this.stackHead = (0, lib.clampNumber)(--this.stackHead, 0, this.internalStack.length - 1);
        }
        moveHeadUp() {
            if (this.isEmpty()) {
                return;
            }
            this.stackHead = (0, lib.clampNumber)(++this.stackHead, 0, this.internalStack.length - 1);
        }
        head() {
            if (this.isEmpty()) {
                return undefined;
            }
            return this.internalStack[this.stackHead];
        }
        length() {
            return this.internalStack.length;
        }
        clear() {
            this.internalStack = [];
            this.stackHead = -1;
        }
        forEach(callbackfn) {
            this.internalStack.forEach(callbackfn);
        }
    }
    const logNavigationInfoDynamicPropertyName = "navigationstack:lognavigationinfo";
    class NavigationStackBehavior {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this.stack = new Stack(NavigationStackBehavior.MAX_STACK_SIZE);
            this.logNavigationInfo = false;
            this.navigationLoggingMenuItem = undefined;
            this.updateInternalHandle = undefined;
            uiSession.log.debug(`Initializing ${NavigationStackBehavior.BEHAVIOR_NAME}`);
            this.loadDynamicProperties(uiSession);
            if (this.shouldAddAutomatedRecord(uiSession.extensionContext.player)) {
                this.addRecordToStack(uiSession);
            }
            if (!this.updateInternalHandle) {
                this.queueInitialDelayAddRecordCheck(uiSession);
            }
        }
        teardown() {
            this.uiSession.log.debug(`Shutting down ${NavigationStackBehavior.BEHAVIOR_NAME}`);
            if (this.updateInternalHandle) {
                server_namespaceObject.system.clearRun(this.updateInternalHandle);
            }
        }
        shouldAddAutomatedRecord(player) {
            const headRecord = this.stack.head();
            if (headRecord) {
                if (player.dimension !== headRecord.dimension) {
                    return true;
                }
                const playerVelocity = player.getVelocity();
                const playerLocation = player.location;
                const headRecordLocation = headRecord.pos;
                const distanceFromHeadRecord = lib.Vector3Utils.magnitude(lib.Vector3Utils.subtract(headRecordLocation, playerLocation));
                const shouldAddAutomatedRecord = Math.abs(playerVelocity.x) === 0 && Math.abs(playerVelocity.y) === 0 && Math.abs(playerVelocity.z) === 0 && distanceFromHeadRecord >= NavigationStackBehavior.AUTO_ADD_MIN_DISTANCE_IN_BLOCKS;
                return shouldAddAutomatedRecord;
            } else {
                return true;
            }
        }
        addRecordToStack(uiSession) {
            const player = uiSession.extensionContext.player;
            this.stack.push({
                pos: player.location,
                rot: player.getRotation(),
                dimension: player.dimension
            });
            this.logStack();
        }
        queueInitialDelayAddRecordCheck(uiSession) {
            this.updateInternalHandle = server_namespaceObject.system.runTimeout((() => {
                if (this.shouldAddAutomatedRecord(uiSession.extensionContext.player)) {
                    this.addRecordToStack(uiSession);
                    this.queueInitialDelayAddRecordCheck(uiSession);
                } else {
                    this.doRepeatedAutomatedRecordCheck(uiSession);
                }
            }), NavigationStackBehavior.AUTO_ADD_INTERVAL_IN_SECONDS * server_namespaceObject.TicksPerSecond);
        }
        doRepeatedAutomatedRecordCheck(uiSession) {
            this.updateInternalHandle = server_namespaceObject.system.runInterval((() => {
                if (this.shouldAddAutomatedRecord(uiSession.extensionContext.player)) {
                    if (this.updateInternalHandle) {
                        server_namespaceObject.system.clearRun(this.updateInternalHandle);
                        this.updateInternalHandle = undefined;
                    }
                    this.addRecordToStack(uiSession);
                    this.queueInitialDelayAddRecordCheck(uiSession);
                }
            }), NavigationStackBehavior.POLL_INTERVAL_IN_SECONDS * server_namespaceObject.TicksPerSecond);
        }
        loadDynamicProperties(uiSession) {
            const player = uiSession.extensionContext.player;
            const logNavigationInfo = player.getDynamicProperty(logNavigationInfoDynamicPropertyName);
            if (logNavigationInfo) {
                if (typeof logNavigationInfo === "boolean") {
                    this.logNavigationInfo = logNavigationInfo;
                } else {
                    server_editor_namespaceObject.editor.log.warning(`LogNavigationInfo dynamic property type expected to be 'boolean' for NavigationStack extension, instead found '${typeof logNavigationInfo}'`);
                }
            }
        }
        logStack() {
            if (!this.logNavigationInfo) {
                return;
            }
            const logProperties = {
                tags: [ "Editor", "Navigation" ]
            };
            const headRecord = this.stack.head();
            if (headRecord) {
                this.stack.forEach(((record, index) => {
                    const pos = record.pos;
                    const rot = record.rot;
                    const dimensionID = record.dimension.id;
                    const headIndicator = record === headRecord ? "*" : "";
                    server_editor_namespaceObject.editor.log.info(`${index}: pos [${lib.Vector3Utils.toString(pos)}], rot [${lib.Vector2Utils.toString(rot)}], dim [${dimensionID}] ${headIndicator}`, logProperties);
                }));
            } else {
                server_editor_namespaceObject.editor.log.info("Navigation: stack is empty", logProperties);
            }
        }
    }
    NavigationStackBehavior.BEHAVIOR_NAME = "Navigation Stack";
    NavigationStackBehavior.MAX_STACK_SIZE = 50;
    NavigationStackBehavior.POLL_INTERVAL_IN_SECONDS = .5;
    NavigationStackBehavior.AUTO_ADD_INTERVAL_IN_SECONDS = 5;
    NavigationStackBehavior.AUTO_ADD_MIN_DISTANCE_IN_BLOCKS = 5;
    class PauseBehavior {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this.pauseMobsMenuItem = undefined;
            this.simulationStateChangeHandle = server_editor_namespaceObject.editor.afterEvents.simulationStateChange.subscribe((evt => {
                if (this.pauseMobsMenuItem) {
                    this.pauseMobsMenuItem.checked = evt.paused;
                }
            }));
        }
        createPauseMenu(parentMenu) {
            const alternatePauseMobsAction = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this.pauseMobsMenuItem) {
                        if (server_editor_namespaceObject.editor.simulation.isPaused()) {
                            this.pauseMobsMenuItem.checked = false;
                            server_editor_namespaceObject.editor.simulation.setPaused(false);
                        } else {
                            this.pauseMobsMenuItem.checked = true;
                            server_editor_namespaceObject.editor.simulation.setPaused(true);
                        }
                    }
                }
            });
            this.pauseMobsMenuItem = parentMenu.addItem({
                label: "resourcePack.editor.menuBar.worldOptions.pause",
                checked: server_editor_namespaceObject.editor.simulation.isPaused(),
                tooltip: "resourcePack.editor.menuBar.worldOptions.pause.tooltip"
            }, alternatePauseMobsAction);
        }
        teardown() {
            if (this.simulationStateChangeHandle) {
                server_editor_namespaceObject.editor.afterEvents.simulationStateChange.unsubscribe(this.simulationStateChangeHandle);
            }
        }
    }
    class PlayerCountBehavior {
        constructor(uiSession) {
            const statusBarItem = uiSession.statusBar.createItem({
                alignment: server_editor_namespaceObject.StatusBarAlignment.Right,
                icon: "playersIcon"
            });
            uiSession.eventSubscriptionCache.subscribeToBedrockEvent("playerJoin", (() => this.updateStatusBarText(statusBarItem, server_namespaceObject.world.getAllPlayers().length + 1)));
            uiSession.eventSubscriptionCache.subscribeToBedrockEvent("playerLeave", (() => this.updateStatusBarText(statusBarItem, server_namespaceObject.world.getAllPlayers().length)));
            this.updateStatusBarText(statusBarItem, server_namespaceObject.world.getAllPlayers().length);
        }
        updateStatusBarText(statusBarItem, playerCount) {
            statusBarItem.setText({
                id: "resourcePack.editor.statusBar.connectedPlayers",
                props: [ `${playerCount}` ]
            });
        }
        teardown() {}
    }
    function formatAsTimeString(hours, minutes) {
        return hours.toString().padStart(2, "0") + ":" + minutes.toString().padStart(2, "0");
    }
    const Playtest_mcHoursPerTick = 1e3;
    const Playtest_mcMinsPerTick = 16.6667;
    const CUSTOM_TOD = -2;
    const Playtest_validGameModes = [ {
        val: server_namespaceObject.GameMode.Survival,
        label: "resourcePack.editor.exportProject.gameMode.survival"
    }, {
        val: server_namespaceObject.GameMode.Creative,
        label: "resourcePack.editor.exportProject.gameMode.creative"
    }, {
        val: server_namespaceObject.GameMode.Adventure,
        label: "resourcePack.editor.exportProject.gameMode.adventure"
    } ];
    const validDifficulties = [ {
        val: server_namespaceObject.Difficulty.Peaceful,
        label: "resourcePack.editor.exportProject.difficulty.peaceful"
    }, {
        val: server_namespaceObject.Difficulty.Easy,
        label: "resourcePack.editor.exportProject.difficulty.easy"
    }, {
        val: server_namespaceObject.Difficulty.Normal,
        label: "resourcePack.editor.exportProject.difficulty.normal"
    }, {
        val: server_namespaceObject.Difficulty.Hard,
        label: "resourcePack.editor.exportProject.difficulty.hard"
    } ];
    const Playtest_validDaylightCycle = [ {
        val: server_editor_namespaceObject.DaylightCycle.Normal,
        label: "resourcePack.editor.exportProject.cheatsSettings.daylightCycle.normal"
    }, {
        val: server_editor_namespaceObject.DaylightCycle.AlwaysDay,
        label: "resourcePack.editor.exportProject.cheatsSettings.daylightCycle.alwaysDay"
    }, {
        val: server_editor_namespaceObject.DaylightCycle.LockTime,
        label: "resourcePack.editor.exportProject.cheatsSettings.daylightCycle.lockTime"
    } ];
    const validWeather = [ {
        val: server_namespaceObject.WeatherType.Clear,
        label: "resourcePack.editor.exportProject.weather.clear"
    }, {
        val: server_namespaceObject.WeatherType.Rain,
        label: "resourcePack.editor.exportProject.weather.rain"
    }, {
        val: server_namespaceObject.WeatherType.Thunder,
        label: "resourcePack.editor.exportProject.weather.thunder"
    } ];
    const validTimes = [ {
        label: "resourcePack.editor.timeOfDay.currentTime",
        time: -1
    }, {
        label: "resourcePack.editor.timeOfDay.dropDown.day",
        time: server_namespaceObject.TimeOfDay.Day
    }, {
        label: "resourcePack.editor.timeOfDay.dropDown.noon",
        time: server_namespaceObject.TimeOfDay.Noon
    }, {
        label: "resourcePack.editor.timeOfDay.dropDown.sunset",
        time: server_namespaceObject.TimeOfDay.Sunset
    }, {
        label: "resourcePack.editor.timeOfDay.dropDown.night",
        time: server_namespaceObject.TimeOfDay.Night
    }, {
        label: "resourcePack.editor.timeOfDay.dropDown.midnight",
        time: server_namespaceObject.TimeOfDay.Midnight
    }, {
        label: "resourcePack.editor.timeOfDay.dropDown.sunrise",
        time: server_namespaceObject.TimeOfDay.Sunrise
    }, {
        label: "resourcePack.editor.timeOfDay.dropDown.custom",
        time: CUSTOM_TOD
    } ];
    const PLAY_TEST_GROUP = "editor:playtest";
    const PANE_SETTINGS_NAME = "pane_settings";
    class PlaytestBehavior {
        constructor(uiSession) {
            this._lastPlayTestAvailability = false;
            this._persistenceManager = getPersistenceManager(uiSession.extensionContext.player);
            this._playTestData = this.loadPlayTestSettings();
            this._extensionMenuItem = this.addMenuItem(uiSession);
            this._propertyPane = this.buildPropertyPane(uiSession);
            this.registerActionBarItem(uiSession);
            this._tickRunId = server_namespaceObject.system.runInterval((() => {
                const readyCondition = uiSession.extensionContext.playtest.getPlaytestSessionAvailability();
                const isReady = readyCondition === server_editor_namespaceObject.PlaytestSessionResult.OK;
                if (this._lastPlayTestAvailability !== isReady) {
                    if (this._testButton) {
                        this._testButton.enable = isReady;
                    }
                    this._lastPlayTestAvailability = isReady;
                }
            }), server_namespaceObject.TicksPerSecond / 4);
        }
        addMenuItem(uiSession) {
            const coreMenuItems = uiSession.scratchStorage?.coreMenuItems;
            const playtestMenuItem = coreMenuItems?.file.addItem({
                label: "resourcePack.editor.playtest.Menu.Title",
                tooltip: "resourcePack.editor.playtest.Dialog.tooltip"
            }, uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._propertyPane?.show();
                }
            }));
            return playtestMenuItem;
        }
        registerActionBarItem(uiSession) {
            const showPlaytestAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._propertyPane?.show();
                }
            });
            uiSession.actionBar.registerItem(server_editor_namespaceObject.CoreActionBarItemType.Playtest, showPlaytestAction, {
                label: "resourcePack.editor.playtest.Menu.Title",
                icon: "pack://textures/editor/Play.png",
                tooltipTitle: "resourcePack.editor.playtest.Menu.Title",
                tooltipDescription: "resourcePack.editor.playtest.Dialog.tooltip",
                enabled: true,
                executeOnAdd: true
            });
        }
        buildPropertyPane(uiSession) {
            const propertyPane = uiSession.createPropertyPane({
                title: "resourcePack.editor.playtest.Dialog.Title",
                uniqueId: "editor:pane:playtest",
                infoTooltip: {
                    description: [ "resourcePack.editor.playtest.Dialog.tooltip", {
                        link: "https://aka.ms/BedrockEditorTestSettings",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            const player = uiSession.extensionContext.player;
            const gameTypeItems = Playtest_validGameModes.map(((v, i) => {
                const item = {
                    label: v.label,
                    value: i
                };
                return item;
            }));
            propertyPane.addDropdown(this._playTestData.gameMode, {
                title: "resourcePack.editor.playtest.Dialog.GameMode",
                tooltip: "resourcePack.editor.playtest.Dialog.GameMode.tooltip",
                entries: gameTypeItems,
                onChange: () => {
                    this.savePlayTestSettings(player);
                }
            });
            const difficultyItems = validDifficulties.map(((v, i) => {
                const item = {
                    label: v.label,
                    value: i
                };
                return item;
            }));
            propertyPane.addDropdown(this._playTestData.difficulty, {
                title: "resourcePack.editor.playtest.Dialog.Difficulty",
                tooltip: "resourcePack.editor.playtest.Dialog.Difficulty.tooltip",
                entries: difficultyItems,
                onChange: () => {
                    this.savePlayTestSettings(player);
                }
            });
            propertyPane.addBool(this._playTestData.overrideSpawn, {
                title: "resourcePack.editor.playtest.Dialog.OverrideSpawn",
                tooltip: "resourcePack.editor.playtest.Dialog.OverrideSpawn.tooltip",
                onChange: () => {
                    this.savePlayTestSettings(player);
                }
            });
            const advancedPane = propertyPane.createSubPane({
                title: "resourcePack.editor.playtest.AdvancedSettings.title",
                infoTooltip: {
                    title: "resourcePack.editor.playtest.AdvancedSettings.title",
                    description: [ "resourcePack.editor.playtest.AdvancedSettings.tooltip" ]
                }
            });
            advancedPane.collapse();
            const daylightCycleItems = Playtest_validDaylightCycle.map(((v, i) => {
                const item = {
                    label: v.label,
                    value: i
                };
                return item;
            }));
            advancedPane.addDropdown(this._playTestData.daylightCycle, {
                title: "resourcePack.editor.playtest.Dialog.DaylightCycle",
                tooltip: "resourcePack.editor.playtest.Dialog.DaylightCycle.tooltip",
                entries: daylightCycleItems,
                onChange: () => {
                    this.savePlayTestSettings(player);
                }
            });
            const customTime = advancedPane.addString(this._playTestData.time, {
                title: "resourcePack.editor.timeOfDay.customTime",
                tooltip: "resourcePack.editor.timeOfDay.customTime.tooltip",
                enable: this._playTestData.timeOfDay.value === 7,
                onChange: (newValue, oldValue) => {
                    this.savePlayTestSettings(player);
                    if (!this._playTestData) {
                        return;
                    }
                    if (oldValue === newValue) {
                        return;
                    }
                    this._playTestData.time.set(this.parseTimeValue(newValue.toString()));
                }
            });
            const timeItems = validTimes.map(((v, i) => {
                const item = {
                    label: v.label,
                    value: i
                };
                return item;
            }));
            advancedPane.addDropdown(this._playTestData.timeOfDay, {
                title: "resourcePack.editor.playtest.Dialog.TimeOfDay",
                tooltip: "resourcePack.editor.playtest.Dialog.TimeOfDay.tooltip",
                entries: timeItems,
                onChange: newValue => {
                    if (Number.isSafeInteger(newValue)) {
                        const num = validTimes[newValue].time;
                        if (num === CUSTOM_TOD) {
                            customTime.enable = true;
                        } else if (num >= 0) {
                            this._playTestData.time.set(this.getTimeStringFromTime(num));
                            customTime.enable = false;
                        }
                    }
                    this.savePlayTestSettings(player);
                }
            });
            advancedPane.addBool(this._playTestData.weatherCycle, {
                title: "resourcePack.editor.playtest.Dialog.WeatherCycle",
                tooltip: "resourcePack.editor.playtest.Dialog.WeatherCycle.tooltip",
                onChange: () => {
                    this.savePlayTestSettings(player);
                }
            });
            const weatherItems = validWeather.map(((v, i) => {
                const item = {
                    label: v.label,
                    value: i
                };
                return item;
            }));
            advancedPane.addDropdown(this._playTestData.weather, {
                title: "resourcePack.editor.playtest.Dialog.weather",
                tooltip: "resourcePack.editor.playtest.Dialog.weather.tooltip",
                entries: weatherItems,
                onChange: () => {
                    this.savePlayTestSettings(player);
                }
            });
            advancedPane.addBool(this._playTestData.showCoordinates, {
                title: "resourcePack.editor.playtest.Dialog.ShowCoordinates",
                tooltip: "resourcePack.editor.playtest.Dialog.ShowCoordinates.tooltip",
                onChange: () => {
                    this.savePlayTestSettings(player);
                }
            });
            const oneSleepingPlayerMessage = {
                id: "resourcePack.editor.exportProject.advancedSettings.requiredSleepingPlayers.onePlayerMessage"
            };
            const initialTitlePercentMessage = this._playTestData.sleepSkipPercent.value <= 0 ? oneSleepingPlayerMessage.id : this._playTestData.sleepSkipPercent.value >= 101 ? `${100}` + `%%` : `${this._playTestData.sleepSkipPercent.value}` + `%%`;
            const localizedPercentTitle = {
                id: "resourcePack.editor.exportProject.advancedSettings.requiredSleepingPlayers",
                props: [ `${initialTitlePercentMessage}` ]
            };
            advancedPane.addBool(this._playTestData.bedsWork, {
                title: "resourcePack.editor.exportProject.advancedSettings.bedsWork",
                tooltip: "resourcePack.editor.exportProject.advancedSettings.bedsWork.tooltip",
                variant: server_editor_namespaceObject.BoolPropertyItemVariant.Checkbox,
                onChange: newValue => {
                    sleepSkipPercentPropItem.enable = newValue;
                    if (newValue) {
                        this._playTestData.sleepSkipPercent.set(100);
                    } else {
                        const sleepDisabledValue = 101;
                        this._playTestData.sleepSkipPercent.set(sleepDisabledValue);
                        if (localizedPercentTitle.props) {
                            localizedPercentTitle.props = [ `${this._playTestData.sleepSkipPercent.value}%%` ];
                        }
                        sleepSkipPercentPropItem.setTitle(localizedPercentTitle);
                    }
                    this.savePlayTestSettings(player);
                }
            });
            const sleepSkipPercentProps = {
                title: localizedPercentTitle,
                tooltip: "resourcePack.editor.exportProject.advancedSettings.requiredSleepingPlayers.tooltip",
                min: 0,
                max: 100,
                isInteger: true,
                enable: this._playTestData.bedsWork.value,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    if (localizedPercentTitle.props && newValue > 0) {
                        localizedPercentTitle.props = [ `${newValue}%%` ];
                    } else {
                        localizedPercentTitle.props = [ oneSleepingPlayerMessage.id ];
                    }
                    sleepSkipPercentPropItem.setTitle(localizedPercentTitle);
                    this.savePlayTestSettings(player);
                }
            };
            const sleepSkipPercentPropItem = advancedPane.addNumber(this._playTestData.sleepSkipPercent, sleepSkipPercentProps);
            const informationSubPane = propertyPane.createSubPane({
                title: "resourcePack.editor.playtest.Dialog.Information",
                infoTooltip: {
                    title: "resourcePack.editor.playtest.Dialog.Information",
                    description: [ "resourcePack.editor.playtest.Dialog.Information.tooltip" ]
                }
            });
            informationSubPane.addText("resourcePack.editor.playtest.Dialog.Information.text");
            this._lastPlayTestAvailability = uiSession.extensionContext.playtest.getPlaytestSessionAvailability() === server_editor_namespaceObject.PlaytestSessionResult.OK;
            this._testButton = propertyPane.addButton(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: async () => {
                    if (!this._playTestData) {
                        return;
                    }
                    const options = this.getGameOptionsFromPlayTestData(this._playTestData, uiSession);
                    const readyCondition = uiSession.extensionContext.playtest.getPlaytestSessionAvailability();
                    const isReady = readyCondition === server_editor_namespaceObject.PlaytestSessionResult.OK;
                    uiSession.log.debug(`Session status result: ${getEnumKeyByEnumValue(server_editor_namespaceObject.PlaytestSessionResult, readyCondition)}`);
                    if (!isReady) {
                        if (this._testButton) {
                            this._testButton.enable = false;
                        }
                        return;
                    }
                    fireTelemetryEvent(player, TelemetrySource.TestWorld, "TestWorldButton", {
                        settings: options
                    });
                    const result = await uiSession.extensionContext.playtest.beginPlaytest(options);
                    uiSession.log.debug(`Ending Playtest Session with result: ${getEnumKeyByEnumValue(server_editor_namespaceObject.PlaytestSessionResult, result)}`);
                }
            }), {
                title: "resourcePack.editor.playtest.Dialog.TestButton",
                visible: true,
                enable: this._lastPlayTestAvailability
            });
            return propertyPane;
        }
        loadPlayTestSettings() {
            let loadedData;
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(PLAY_TEST_GROUP, option);
            if (group) {
                const paneSettings = group.fetchItem(PANE_SETTINGS_NAME);
                if (paneSettings) {
                    loadedData = paneSettings.value;
                }
                group.dispose();
            }
            const defaultPaneData = {
                gameMode: (0, server_editor_namespaceObject.makeObservable)(loadedData?.gameMode ?? 0),
                difficulty: (0, server_editor_namespaceObject.makeObservable)(loadedData?.difficulty ?? 2),
                daylightCycle: (0, server_editor_namespaceObject.makeObservable)(loadedData?.daylightCycle ?? server_editor_namespaceObject.DaylightCycle.Normal),
                respawnRadius: (0, server_editor_namespaceObject.makeObservable)(loadedData?.respawnRadius ?? 10),
                weatherCycle: (0, server_editor_namespaceObject.makeObservable)(loadedData?.weatherCycle ?? true),
                weather: (0, server_editor_namespaceObject.makeObservable)(loadedData?.weather ?? 0),
                showCoordinates: (0, server_editor_namespaceObject.makeObservable)(loadedData?.showCoordinates ?? true),
                timeOfDay: (0, server_editor_namespaceObject.makeObservable)(loadedData?.timeOfDay ?? 0),
                time: (0, server_editor_namespaceObject.makeObservable)(loadedData?.time ?? ""),
                overrideSpawn: (0, server_editor_namespaceObject.makeObservable)(loadedData?.overrideSpawn ?? true),
                bedsWork: (0, server_editor_namespaceObject.makeObservable)(loadedData?.bedsWork ?? true),
                sleepSkipPercent: (0, server_editor_namespaceObject.makeObservable)(loadedData?.sleepSkipPercent ?? 100)
            };
            return defaultPaneData;
        }
        savePlayTestSettings(player) {
            if (player) {
                const paneData = Object.entries(this._playTestData).reduce(((data, [key, observable]) => {
                    data[key] = observable.value;
                    return data;
                }), {});
                const option = {
                    scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                    version: 0
                };
                const group = this._persistenceManager.getOrCreateGroup(PLAY_TEST_GROUP, option);
                if (group) {
                    const paneSettings = group.getOrCreateItem(PANE_SETTINGS_NAME, paneData);
                    paneSettings.commit();
                    group.dispose();
                }
            }
        }
        parseTimeValue(timeString) {
            let returnStr = "";
            let time = Number(timeString);
            if (isNaN(time)) {
                if (timeString.indexOf(":") >= 0) {
                    const timeArray = timeString.split(":");
                    if (timeArray.length === 2) {
                        let hours = Number(timeArray[0]);
                        let minutes = Number(timeArray[1]);
                        if (!isNaN(hours) && !isNaN(minutes)) {
                            if (minutes > 59) {
                                minutes = 0;
                                hours += 1;
                            } else {
                                minutes = (0, lib.clampNumber)(minutes, 0, 59);
                            }
                            if (hours > 23) {
                                hours = 23;
                                minutes = 59;
                            } else {
                                hours = (0, lib.clampNumber)(hours, 0, 23);
                            }
                            returnStr = formatAsTimeString(hours.toString(), minutes.toString());
                        }
                    }
                }
            } else {
                time = (0, lib.clampNumber)(time, 0, 23999);
                returnStr = this.getTimeStringFromTime(time);
            }
            return returnStr;
        }
        getTimeFromTimeString(timeOfDay) {
            if (Number.isSafeInteger(timeOfDay)) {
                return Number(timeOfDay);
            } else {
                if (timeOfDay.indexOf(":")) {
                    const timeArray = timeOfDay.split(":");
                    if (timeArray.length === 2) {
                        let hours = Number(timeArray[0]) - 6;
                        if (hours < 0) {
                            hours = 24 - (6 + hours);
                        }
                        let minutes = Number(timeArray[1]);
                        hours = (0, lib.clampNumber)(hours, 0, 23);
                        minutes = (0, lib.clampNumber)(minutes, 0, 59);
                        return hours * Playtest_mcHoursPerTick + minutes * Playtest_mcMinsPerTick;
                    }
                }
            }
            return 0;
        }
        getTimeStringFromTime(timeOfDay) {
            const mcHours = Math.trunc(timeOfDay / Playtest_mcHoursPerTick);
            const mcMinutes = timeOfDay % Playtest_mcHoursPerTick;
            const hours = (mcHours + 6) % 24;
            let minutes = Math.round(mcMinutes / Playtest_mcMinsPerTick);
            minutes = (0, lib.clampNumber)(minutes, 0, 59);
            return formatAsTimeString(hours.toString(), minutes.toString());
        }
        getGameOptionsFromPlayTestData(data, uiSession) {
            const gameMode = Playtest_validGameModes[data.gameMode.value].val;
            const difficulty = validDifficulties[data.difficulty.value].val;
            const timeOfDay = validTimes[data.timeOfDay.value].time;
            const daylightCycle = Playtest_validDaylightCycle[data.daylightCycle.value].val;
            const options = {
                daylightCycle,
                difficulty,
                respawnRadius: data.respawnRadius.value,
                gameMode,
                disableWeather: !data.weatherCycle.value,
                weather: data.weather.value,
                showCoordinates: data.showCoordinates.value,
                bedsWork: data.bedsWork.value,
                sleepSkipPercent: data.sleepSkipPercent.value
            };
            if (timeOfDay === CUSTOM_TOD) {
                options.timeOfDay = this.getTimeFromTimeString(data.time.value);
            } else if (timeOfDay >= 0) {
                options.timeOfDay = timeOfDay;
            } else {
                options.timeOfDay = 0;
            }
            if (data.overrideSpawn) {
                options.spawnPosition = uiSession.extensionContext.player.location;
                options.dimensionId = uiSession.extensionContext.player.dimension.id.replace("minecraft:", "").replace("_", " ");
            }
            return options;
        }
        teardown() {
            if (this._tickRunId) {
                server_namespaceObject.system.clearRun(this._tickRunId);
            }
        }
    }
    const Controls = {
        Up: server_editor_namespaceObject.KeyboardKey.PAGE_UP,
        Down: server_editor_namespaceObject.KeyboardKey.PAGE_DOWN,
        Forward: server_editor_namespaceObject.KeyboardKey.UP,
        Back: server_editor_namespaceObject.KeyboardKey.DOWN,
        Left: server_editor_namespaceObject.KeyboardKey.LEFT,
        Right: server_editor_namespaceObject.KeyboardKey.RIGHT,
        Select: server_editor_namespaceObject.KeyboardKey.ENTER,
        Clear: server_editor_namespaceObject.KeyboardKey.KEY_D
    };
    const SelectionCommonTypes_KEY_REPEAT_DELAY = 5;
    const SelectionCommonTypes_KEY_REPEAT_INTERVAL = 1;
    var SelectionToolMode;
    (function(SelectionToolMode) {
        SelectionToolMode[SelectionToolMode["Marquee"] = 1] = "Marquee";
        SelectionToolMode[SelectionToolMode["Freehand"] = 2] = "Freehand";
        SelectionToolMode[SelectionToolMode["MagicSelect"] = 3] = "MagicSelect";
        SelectionToolMode[SelectionToolMode["Nudge"] = 4] = "Nudge";
        SelectionToolMode[SelectionToolMode["Default"] = 1] = "Default";
    })(SelectionToolMode || (SelectionToolMode = {}));
    var SelectionCommonTypes_QuickActionMode;
    (function(QuickActionMode) {
        QuickActionMode[QuickActionMode["Invalid"] = -1] = "Invalid";
        QuickActionMode[QuickActionMode["DeselectSelection"] = 1] = "DeselectSelection";
        QuickActionMode[QuickActionMode["FillSelection"] = 2] = "FillSelection";
        QuickActionMode[QuickActionMode["DeleteSelection"] = 3] = "DeleteSelection";
    })(SelectionCommonTypes_QuickActionMode || (SelectionCommonTypes_QuickActionMode = {}));
    var TrimActionMode;
    (function(TrimActionMode) {
        TrimActionMode[TrimActionMode["Invalid"] = -1] = "Invalid";
        TrimActionMode[TrimActionMode["TrimVolume"] = 1] = "TrimVolume";
        TrimActionMode[TrimActionMode["RemoveAir"] = 2] = "RemoveAir";
        TrimActionMode[TrimActionMode["ShrinkWrap"] = 3] = "ShrinkWrap";
        TrimActionMode[TrimActionMode["Hollow"] = 4] = "Hollow";
    })(TrimActionMode || (TrimActionMode = {}));
    var SelectionTelemetry;
    (function(SelectionTelemetry) {
        SelectionTelemetry["QuickAction"] = "QuickAction";
        SelectionTelemetry["FillSelection"] = "FillSelection";
        SelectionTelemetry["DeleteSelection"] = "DeleteSelection";
        SelectionTelemetry["FreehandSelectionBegin"] = "FreehandSelectionBegin";
        SelectionTelemetry["FreehandSelectionComplete"] = "FreehandSelectionComplete";
        SelectionTelemetry["SelectionCreated"] = "SelectionCreated";
        SelectionTelemetry["SelectionExpanded"] = "SelectionExpanded";
        SelectionTelemetry["SelectionMoveTop"] = "SelectionMoveTop";
        SelectionTelemetry["SelectionShrink"] = "SelectionShrink";
        SelectionTelemetry["SelectionGrow"] = "SelectionGrow";
        SelectionTelemetry["ModeChanged"] = "ModeChanged";
        SelectionTelemetry["Deselect"] = "Deselect";
        SelectionTelemetry["TrimVolume"] = "TrimVolume";
        SelectionTelemetry["RemoveAir"] = "RemoveAir";
        SelectionTelemetry["MagicSelect"] = "MagicSelect";
        SelectionTelemetry["HollowVolume"] = "HollowVolume";
        SelectionTelemetry["ManifestGeneration"] = "ManifestGeneration";
    })(SelectionTelemetry || (SelectionTelemetry = {}));
    function deepCopy(obj) {
        const serializedObject = (0, server_editor_namespaceObject.serialize)(obj);
        const objectCopy = (0, server_editor_namespaceObject.deserialize)(serializedObject);
        return objectCopy;
    }
    function createRGBAColorFromInts(r, g, b, a) {
        const red = Math.min(255, Math.max(0, r)) / 255;
        const green = Math.min(255, Math.max(0, g)) / 255;
        const blue = Math.min(255, Math.max(0, b)) / 255;
        const alpha = Math.min(255, Math.max(0, a)) / 255;
        return {
            blue,
            green,
            red,
            alpha
        };
    }
    function limitVolumeSize(volume, prospectiveTo, maxVolumeSize) {
        const newVolume = new BlockVolume(volume.from, prospectiveTo);
        const newSpan = newVolume.getSpan();
        const deltaSizeX = newSpan.x - maxVolumeSize.x;
        const deltaSizeY = newSpan.y - maxVolumeSize.y;
        const deltaSizeZ = newSpan.z - maxVolumeSize.z;
        const oldSpan = volume.getSpan();
        const dirX = newSpan.x > oldSpan.x ? 1 : -1;
        const dirY = newSpan.y > oldSpan.y ? 1 : -1;
        const dirZ = newSpan.z > oldSpan.z ? 1 : -1;
        let newX = newVolume.to.x;
        let newY = newVolume.to.y;
        let newZ = newVolume.to.z;
        if (deltaSizeX > 0) {
            newX -= dirX * deltaSizeX;
        }
        if (deltaSizeY > 0) {
            newY -= dirY * deltaSizeY;
        }
        if (deltaSizeZ > 0) {
            newZ -= dirZ * deltaSizeZ;
        }
        return new BlockVolume(volume.from, {
            x: newX,
            y: newY,
            z: newZ
        });
    }
    var NudgeOperation;
    (function(NudgeOperation) {
        NudgeOperation[NudgeOperation["None"] = 0] = "None";
        NudgeOperation[NudgeOperation["Move"] = 1] = "Move";
        NudgeOperation[NudgeOperation["Copy"] = 2] = "Copy";
    })(NudgeOperation || (NudgeOperation = {}));
    var NudgeUpdateOptions;
    (function(NudgeUpdateOptions) {
        NudgeUpdateOptions[NudgeUpdateOptions["None"] = 0] = "None";
        NudgeUpdateOptions[NudgeUpdateOptions["UpdateWidgetPosition"] = 1] = "UpdateWidgetPosition";
        NudgeUpdateOptions[NudgeUpdateOptions["ForceUpdateSelectionVisuals"] = 2] = "ForceUpdateSelectionVisuals";
        NudgeUpdateOptions[NudgeUpdateOptions["All"] = 3] = "All";
    })(NudgeUpdateOptions || (NudgeUpdateOptions = {}));
    class SelectionCreationModeBase {
        isSelectionCreationMode() {
            return true;
        }
    }
    class NudgeControlsHelper {
        constructor(session, tool, bindingIdRoot, bindingNameRoot, modifiers, callback) {
            this._numKeysDown = 0;
            this._callback = callback;
            const nudgeBindings = [ {
                key: server_editor_namespaceObject.KeyboardKey.LEFT,
                dir: direction_Direction.Left,
                tag: "left"
            }, {
                key: server_editor_namespaceObject.KeyboardKey.RIGHT,
                dir: direction_Direction.Right,
                tag: "right"
            }, {
                key: server_editor_namespaceObject.KeyboardKey.UP,
                dir: direction_Direction.Forward,
                tag: "forward"
            }, {
                key: server_editor_namespaceObject.KeyboardKey.DOWN,
                dir: direction_Direction.Back,
                tag: "backward"
            }, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_UP,
                dir: direction_Direction.Up,
                tag: "up"
            }, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_DOWN,
                dir: direction_Direction.Down,
                tag: "down"
            } ];
            nudgeBindings.forEach((val => {
                const bindingIdBase = bindingIdRoot + ":" + val.tag;
                const bindingNameBase = bindingNameRoot + "." + val.tag;
                this.buildBinding(session, tool, {
                    key: val.key,
                    modifier: modifiers
                }, bindingIdBase, bindingNameBase, val.dir);
            }));
        }
        buildBinding(session, tool, keys, bindingId, bindingNameRoot, dir) {
            const action = session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                onExecute: _state => {
                    const metaNudgeState = this.processAndCalculateNudgeState(_state);
                    const rotationY = session.extensionContext.player.getRotation().y;
                    const nudgeDelta = getRotationCorrectedDirectionVector(rotationY, dir);
                    this._callback(metaNudgeState, nudgeDelta);
                }
            });
            tool.registerKeyBinding(action, keys, {
                uniqueId: bindingId,
                label: bindingNameRoot + ".title",
                tooltip: bindingNameRoot + ".tooltip"
            });
        }
        processAndCalculateNudgeState(keyState) {
            if (keyState === server_editor_namespaceObject.ContinuousActionState.Begin) {
                ++this._numKeysDown;
            } else if (keyState === server_editor_namespaceObject.ContinuousActionState.End) {
                --this._numKeysDown;
            }
            if (keyState === server_editor_namespaceObject.ContinuousActionState.Begin && this._numKeysDown === 1) {
                return server_editor_namespaceObject.ContinuousActionState.Begin;
            } else if (keyState === server_editor_namespaceObject.ContinuousActionState.End && this._numKeysDown === 0) {
                return server_editor_namespaceObject.ContinuousActionState.End;
            } else {
                return server_editor_namespaceObject.ContinuousActionState.Repeat;
            }
        }
    }
    var server_editor_bindings_x = y => {
        var x = {};
        __webpack_require__.d(x, y);
        return x;
    };
    var server_editor_bindings_y = x => () => x;
    const server_editor_bindings_namespaceObject = server_editor_bindings_x({
        ["Axis"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_bindings_e2bf1028__.Axis,
        ["InputModifier"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_bindings_e2bf1028__.InputModifier,
        ["PaintCompletionState"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_bindings_e2bf1028__.PaintCompletionState,
        ["WidgetGizmoEventType"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_bindings_e2bf1028__.WidgetGizmoEventType,
        ["WidgetGroupSelectionMode"]: () => __WEBPACK_EXTERNAL_MODULE__minecraft_server_editor_bindings_e2bf1028__.WidgetGroupSelectionMode
    });
    var MarqueeSelectionVolumeState;
    (function(MarqueeSelectionVolumeState) {
        MarqueeSelectionVolumeState[MarqueeSelectionVolumeState["Idle"] = 0] = "Idle";
        MarqueeSelectionVolumeState[MarqueeSelectionVolumeState["Dragging"] = 1] = "Dragging";
        MarqueeSelectionVolumeState[MarqueeSelectionVolumeState["Done"] = 2] = "Done";
    })(MarqueeSelectionVolumeState || (MarqueeSelectionVolumeState = {}));
    var ThreePointSelectionState;
    (function(ThreePointSelectionState) {
        ThreePointSelectionState[ThreePointSelectionState["NoPoints"] = 0] = "NoPoints";
        ThreePointSelectionState[ThreePointSelectionState["FirstCorner"] = 1] = "FirstCorner";
        ThreePointSelectionState[ThreePointSelectionState["BottomFace"] = 2] = "BottomFace";
        ThreePointSelectionState[ThreePointSelectionState["Finished"] = 3] = "Finished";
    })(ThreePointSelectionState || (ThreePointSelectionState = {}));
    class MarqueeSelectionVolume {
        get parent() {
            return this._modeImpl.parent;
        }
        constructor(_modeImpl, _worldVolume, onChanged) {
            this._state = MarqueeSelectionVolumeState.Idle;
            this._threePointSelectionState = ThreePointSelectionState.NoPoints;
            this._firstCorner = undefined;
            this._secondCorner = undefined;
            this._isNudgeActionActive = false;
            this._onChanged = () => {};
            this._modeImpl = _modeImpl;
            this._worldVolume = _worldVolume;
            this._onChanged = onChanged || this._onChanged;
            this._widget = this._modeImpl.parent.widgetGroup.createWidget(_worldVolume.from, {
                snapToBlockLocation: true,
                visible: true,
                selectable: false
            });
            this._widget.addGizmoComponent("originHandle", {
                axes: server_editor_namespaceObject.Axis.X | server_editor_namespaceObject.Axis.Y | server_editor_namespaceObject.Axis.Z,
                visible: true,
                normalizedAutoOffset: {
                    x: 0,
                    y: 0,
                    z: 0
                },
                stateChangeEvent: evt => this.onOriginEvent(evt)
            });
            const volumeSize = _worldVolume.getSpan();
            const boundsColors = _modeImpl.parent.boundingBoxColor;
            this._widgetBoxComponent = this._widget.addBoundingBox("bbox", volumeSize, {
                visible: true,
                boundsOffset: lib.VECTOR3_ZERO,
                showWorldIntersections: true,
                enableResizeHandles: server_editor_namespaceObject.Axis.X | server_editor_namespaceObject.Axis.Y | server_editor_namespaceObject.Axis.Z,
                hullColor: boundsColors.hull,
                outlineColor: boundsColors.outline,
                limit: {
                    min: lib.VECTOR3_ONE,
                    max: server_editor_namespaceObject.editor.constants.maxDynamicSelectionSize,
                    maxBlockVolume: server_editor_namespaceObject.editor.constants.maxBlockVolume
                },
                stateChangeEvent: evt => this.onMarqueCornerEvent(evt)
            });
        }
        teardown() {
            this._widgetBoxComponent.delete();
            this._widget.delete();
        }
        get visible() {
            return this._widget.visible;
        }
        set visible(value) {
            this._widget.visible = value;
        }
        get blockVolume() {
            return this._worldVolume;
        }
        get from() {
            return this._worldVolume.from;
        }
        set from(value) {
            this._worldVolume.from = value;
            this._widget.location = value;
            this._widgetBoxComponent.boundsOffset = lib.VECTOR3_ZERO;
            this._widgetBoxComponent.offset = lib.VECTOR3_ZERO;
            this._modeImpl.volumeOrigin = value;
        }
        get to() {
            return this._worldVolume.to;
        }
        set to(value) {
            if (!this.parent.session.extensionContext.blockUtilities.isLocationInsideCurrentDimensionBounds(value)) {
                this.parent.debugLog(`Invalid 'to' location for widget ${lib.Vector3Utils.toString(value)}`);
                return;
            }
            this._worldVolume.to = value;
            let bounds;
            try {
                bounds = this._worldVolume.getBoundingBox();
            } catch (_e) {
                this.parent.debugLog("Failed to get bounding box from volume");
                return;
            }
            this._widget.location = bounds.min;
            this._widgetBoxComponent.size = server_namespaceObject.BlockBoundingBoxUtils.getSpan(bounds);
            this._widgetBoxComponent.boundsOffset = lib.VECTOR3_ZERO;
            this._modeImpl.volumeOrigin = bounds.min;
            this._modeImpl.volumeSize = this._widgetBoxComponent.size;
        }
        set at(value) {
            if (!this.parent.session.extensionContext.blockUtilities.isLocationInsideCurrentDimensionBounds(value)) {
                this.parent.debugLog(`Invalid 'at' location for widget ${lib.Vector3Utils.toString(value)}`);
                return;
            }
            const diff = lib.Vector3Utils.subtract(value, this.from);
            this.from = value;
            this.to = lib.Vector3Utils.add(this.to, diff);
        }
        set span(value) {
            const span = {
                x: Math.max(1, value.x),
                y: Math.max(1, value.y),
                z: Math.max(1, value.z)
            };
            const size = {
                x: span.x - 1,
                y: span.y - 1,
                z: span.z - 1
            };
            const newTo = {
                x: this.from.x + size.x,
                y: this.from.y + size.y,
                z: this.from.z + size.z
            };
            this.to = newTo;
        }
        setFromBounds(value) {
            if (!server_namespaceObject.BlockBoundingBoxUtils.isValid(value)) {
                throw new Error(`Invalid bounds: ${JSON.stringify(value)}`);
            }
            const min = {
                x: value.min.x < value.max.x ? value.min.x : value.max.x,
                y: value.min.y < value.max.y ? value.min.y : value.max.y,
                z: value.min.z < value.max.z ? value.min.z : value.max.z
            };
            const max = {
                x: value.min.x > value.max.x ? value.min.x : value.max.x,
                y: value.min.y > value.max.y ? value.min.y : value.max.y,
                z: value.min.z > value.max.z ? value.min.z : value.max.z
            };
            this.from = min;
            this.to = max;
        }
        deactivateHandles() {
            this._widgetBoxComponent.deactivateHandles();
        }
        get state() {
            return this._state;
        }
        get threePointSelectionState() {
            return this._threePointSelectionState;
        }
        get firstCorner() {
            return this._firstCorner;
        }
        get secondCorner() {
            return this._secondCorner;
        }
        set state(value) {
            this._state = value;
        }
        set threePointSelectionState(value) {
            this._threePointSelectionState = value;
        }
        set firstCorner(value) {
            this._firstCorner = value;
        }
        set secondCorner(value) {
            this._secondCorner = value;
        }
        get isDragging() {
            return this._state === MarqueeSelectionVolumeState.Dragging;
        }
        get isIdle() {
            return this._state === MarqueeSelectionVolumeState.Idle;
        }
        get isDone() {
            return this._state === MarqueeSelectionVolumeState.Done;
        }
        get isShiftDown() {
            return this._modeImpl?.parent?.isModifierDown(server_editor_bindings_namespaceObject.InputModifier.Shift) ?? false;
        }
        onColorChangeEvent(_outline, _hull) {
            this._widgetBoxComponent.hullColor = _hull;
            this._widgetBoxComponent.outlineColor = _outline;
        }
        toggleCornerGizmos(showCorners) {
            if (showCorners) {
                this._widgetBoxComponent.enableResizeHandles = server_editor_namespaceObject.Axis.X | server_editor_namespaceObject.Axis.Y | server_editor_namespaceObject.Axis.Z;
            } else {
                this._widgetBoxComponent.enableResizeHandles = server_editor_namespaceObject.Axis.None;
            }
        }
        onOriginEvent(evt) {
            if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginGrabbed && this._modeImpl.parent.isModifierDown(server_editor_bindings_namespaceObject.InputModifier.Alt) && this._modeImpl.parent.isModifierDown(server_editor_bindings_namespaceObject.InputModifier.Shift)) {
                this.parent.startExternalNudge(NudgeOperation.Move);
                this._isNudgeActionActive = true;
            } else if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginGrabbed && this._modeImpl.parent.isModifierDown(server_editor_bindings_namespaceObject.InputModifier.Alt) && this._modeImpl.parent.isModifierDown(server_editor_bindings_namespaceObject.InputModifier.Control)) {
                this.parent.startExternalNudge(NudgeOperation.Copy);
                this._isNudgeActionActive = true;
            } else if (this._isNudgeActionActive) {
                if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginReleased) {
                    this.parent.commitExternalNudge();
                    this._isNudgeActionActive = false;
                } else if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginMoved) {
                    this.parent.updateExternalNudge(evt.widget.location);
                }
            } else {
                this.onMarqueOriginEvent(evt);
            }
        }
        onMarqueCornerEvent(evt) {
            if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerGrabbed) {
                if (!this.parent.isTransactionOperationActive()) {
                    this.parent.beginTransactionableOperation("Marquee Volume Resize");
                }
                return;
            }
            try {
                const prevBounds = this._worldVolume.getBoundingBox();
                const newTransformedVolume = evt.component.transformedWorldVolume;
                const newBounds = newTransformedVolume.getBoundingBox();
                if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerMoved) {
                    if (!server_namespaceObject.BlockBoundingBoxUtils.equals(prevBounds, newBounds)) {
                        const maxSelectionSize = server_editor_namespaceObject.editor.constants.maxDynamicSelectionSize;
                        const span = lib.Vector3Utils.clamp(newTransformedVolume.getSpan(), {
                            min: {
                                x: 1,
                                y: 1,
                                z: 1
                            },
                            max: maxSelectionSize
                        });
                        this._modeImpl.volumeOrigin = newTransformedVolume.from;
                        this._modeImpl.volumeSize = span;
                    }
                }
                if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerReleased) {
                    if (!server_namespaceObject.BlockBoundingBoxUtils.equals(prevBounds, newBounds)) {
                        const maxSelectionSize = server_editor_namespaceObject.editor.constants.maxDynamicSelectionSize;
                        const span = lib.Vector3Utils.clamp(newTransformedVolume.getSpan(), {
                            min: {
                                x: 1,
                                y: 1,
                                z: 1
                            },
                            max: maxSelectionSize
                        });
                        this._worldVolume.from = newTransformedVolume.from;
                        this._worldVolume.to = lib.Vector3Utils.add(newTransformedVolume.from, lib.Vector3Utils.subtract(span, lib.VECTOR3_ONE));
                        this.parent.endTransactionableOperation();
                        this._onChanged(this);
                    } else {
                        this.parent.debugLog(`Corner gizmo release with no changes - just ignoring: ${evt.eventType}`);
                        this.parent.cancelTransactionableOperation();
                    }
                } else {
                    this._modeImpl.debugLog(`Unhandled gizmo event: ${evt.eventType ?? "undefined"}`);
                }
            } catch {}
        }
        onMarqueOriginEvent(evt) {
            if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginActivated || evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginDeactivated) {
                this.parent.debugLog(`Origin gizmo ${evt.eventType}`);
                return;
            }
            if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginGrabbed) {
                this.parent.debugLog(`Origin gizmo grabbed - opening transaction`);
                this.parent.beginTransactionableOperation("Marquee Volume Move");
                return;
            }
            try {
                const prevBounds = this._worldVolume.getBoundingBox();
                const newTransformedVolume = this._widgetBoxComponent.transformedWorldVolume;
                const newBounds = newTransformedVolume.getBoundingBox();
                this.parent.debugLog(`Transformed Volume: ${lib.Vector3Utils.toString(newBounds.min)} -> ${lib.Vector3Utils.toString(newBounds.max)}`);
                if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginMoved) {
                    if (!server_namespaceObject.BlockBoundingBoxUtils.equals(prevBounds, newBounds)) {
                        const maxSelectionSize = server_editor_namespaceObject.editor.constants.maxDynamicSelectionSize;
                        const span = lib.Vector3Utils.clamp(newTransformedVolume.getSpan(), {
                            min: {
                                x: 1,
                                y: 1,
                                z: 1
                            },
                            max: maxSelectionSize
                        });
                        this._modeImpl.volumeOrigin = newTransformedVolume.from;
                        this._modeImpl.volumeSize = span;
                    }
                }
                if (evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginReleased) {
                    if (!server_namespaceObject.BlockBoundingBoxUtils.equals(prevBounds, newBounds)) {
                        const maxSelectionSize = server_editor_namespaceObject.editor.constants.maxDynamicSelectionSize;
                        const span = lib.Vector3Utils.clamp(newTransformedVolume.getSpan(), {
                            min: {
                                x: 1,
                                y: 1,
                                z: 1
                            },
                            max: maxSelectionSize
                        });
                        this._worldVolume.from = newTransformedVolume.from;
                        this._worldVolume.to = lib.Vector3Utils.add(newTransformedVolume.from, lib.Vector3Utils.subtract(span, lib.VECTOR3_ONE));
                        this.parent.endTransactionableOperation();
                        this._onChanged(this);
                    } else {
                        this.parent.debugLog(`Origin gizmo release with no changes - just ignoring: ${evt.eventType}`);
                        this.parent.cancelTransactionableOperation();
                    }
                } else {
                    this.parent.debugLog(`Unhandled gizmo event: ${evt.eventType ?? "undefined"}`);
                }
            } catch {}
        }
    }
    class SelectionModeMarquee extends SelectionCreationModeBase {
        constructor(_parentPane, _parent) {
            super();
            this._volumeStack = [];
            this._translationKeyRepeatRefCount = 0;
            this._resizeKeyRepeatRefCount = 0;
            this._resizeShrink = false;
            this._tickHandle = undefined;
            this._shiftTickHandle = undefined;
            this._parentPane = _parentPane;
            this._parent = _parent;
            this._modePane = this._parentPane.createSubPane({
                title: "resourcePack.editor.selectionTool.marquee.title",
                infoTooltip: {
                    title: "resourcePack.editor.selectionTool.marquee.title",
                    description: [ "resourcePack.editor.selectionTool.marqueePane.tooltip" ]
                },
                hasMargins: false
            });
            this._origin = (0, server_editor_namespaceObject.makeObservable)({
                x: 0,
                y: 0,
                z: 0
            });
            this._size = (0, server_editor_namespaceObject.makeObservable)({
                x: 1,
                y: 1,
                z: 1
            });
            const subPaneTransform = this._modePane.createSubPane({
                title: "resourcePack.editor.selectionTool.transformPane.title",
                infoTooltip: {
                    title: "resourcePack.editor.selectionTool.transformPane.title",
                    description: [ "resourcePack.editor.selectionTool.transformPane.tooltip" ]
                }
            });
            this._transformVec3UIComponent = subPaneTransform.addVector3(this._origin, {
                title: "resourcePack.editor.selectionTool.transformPane.origin",
                tooltip: "resourcePack.editor.selectionTool.transformPane.origin.tooltip",
                min: {
                    x: -3e5,
                    y: this.parent.session.extensionContext.player.dimension.heightRange.min,
                    z: -3e5
                },
                max: {
                    x: 3e5,
                    y: this.parent.session.extensionContext.player.dimension.heightRange.max,
                    z: 3e5
                },
                onChange: (newValue, oldValue) => {
                    this.parent.performSingleTransactionableOperation((() => {
                        const volume = this._currentVolume();
                        if (volume) {
                            volume.at = this._origin.value;
                        }
                        this.applyVolumeStackToSelectionManager();
                        const direction = lib.Vector3Utils.subtract(newValue, oldValue);
                        this.parent.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionMoveTop, {
                            direction
                        });
                        return true;
                    }), "Marquee Manual Origin change");
                }
            });
            this._sizeVec3UIComponent = subPaneTransform.addVector3(this._size, {
                title: "resourcePack.editor.selectionTool.transformPane.size",
                tooltip: "resourcePack.editor.selectionTool.transformPane.size.tooltip",
                min: {
                    x: 1,
                    y: 1,
                    z: 1
                },
                max: server_editor_namespaceObject.editor.constants.maxDynamicSelectionSize,
                onChange: (newValue, oldValue) => {
                    this.parent.performSingleTransactionableOperation((() => {
                        const volume = this._currentVolume();
                        if (volume) {
                            volume.span = clampVolumeAlongAxis(oldValue, this._size.value, server_editor_namespaceObject.editor.constants.maxBlockVolume);
                        }
                        this.applyVolumeStackToSelectionManager();
                        return true;
                    }), "Marquee Manual Size change");
                    const direction = lib.Vector3Utils.subtract(newValue, oldValue);
                    const grow = direction.x > 0 || direction.y > 0 || direction.z > 0;
                    this.parent.telemetryManager.fireTelemetryEvent(grow ? SelectionTelemetry.SelectionGrow : SelectionTelemetry.SelectionShrink, {
                        direction
                    });
                }
            });
        }
        get parentPane() {
            return this._parentPane;
        }
        get modePane() {
            return this._modePane;
        }
        get parent() {
            return this._parent;
        }
        get session() {
            return this._parent.session;
        }
        set volumeOrigin(value) {
            this._origin.set(value);
        }
        set volumeSize(value) {
            this._size.set(value);
        }
        get modeType() {
            return SelectionToolMode.Marquee;
        }
        debugLog(message) {
            this.parent.debugLog(message);
        }
        teardown() {
            this._volumeStack.forEach((volume => {
                volume.teardown();
            }));
        }
        activate(_toolActive) {
            if (_toolActive) {
                this._modePane.show();
            }
            this._tickHandle = server_namespaceObject.system.runInterval((() => {
                this._onTick();
            }), server_namespaceObject.TicksPerSecond / 3);
            this._showVolumes();
        }
        deactivate(_toolActive, _switchingModes) {
            if (_toolActive) {
                this._modePane.hide();
            }
            if (this._tickHandle) {
                server_namespaceObject.system.clearRun(this._tickHandle);
                this._tickHandle = undefined;
            }
            if (this._shiftTickHandle) {
                server_namespaceObject.system.clearRun(this._shiftTickHandle);
                this._shiftTickHandle = undefined;
            }
            this._volumeStack.forEach((volume => {
                volume.deactivateHandles();
            }));
            if (_switchingModes) {
                this.parent.performSingleTransactionableOperation((() => {
                    this._clearVolumeStack();
                    return true;
                }), "Deactivate Marquee");
            }
        }
        clearSelection() {
            this.parent.performSingleTransactionableOperation((() => {
                this.session.extensionContext.selectionManager.volume.clear();
                this._clearVolumeStack();
                return true;
            }), "Clear Selection");
            this.volumeOrigin = lib.VECTOR3_ZERO;
            this.volumeSize = {
                x: 1,
                y: 1,
                z: 1
            };
        }
        applyImmediateSelection() {}
        onMouseClickAndDrag(_mouseRay, _mouseProps, _oneShot = false) {
            if (_mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton) {
                switch (_mouseProps.inputType) {
                  case server_editor_namespaceObject.MouseInputType.ButtonDown:
                    {
                        if (_mouseRay.rayHit) {
                            this._onLeftMousePressed(_mouseProps.modifiers.ctrl, _mouseProps.modifiers.shift, _mouseRay);
                        }
                        break;
                    }

                  case server_editor_namespaceObject.MouseInputType.Drag:
                    {
                        if (_mouseRay.rayHit) {
                            this._onLeftMouseDrag(_mouseProps.modifiers.ctrl, _mouseProps.modifiers.shift, _mouseRay);
                        }
                        break;
                    }

                  case server_editor_namespaceObject.MouseInputType.ButtonUp:
                    {
                        if (_mouseRay.rayHit) {
                            this._onLeftMouseReleased(_mouseProps.modifiers.shift, _mouseRay);
                        }
                        break;
                    }

                  case server_editor_namespaceObject.MouseInputType.DragStart:
                  case server_editor_namespaceObject.MouseInputType.DragEnd:
                  default:
                    {
                        break;
                    }
                }
            }
        }
        _onTick() {
            if (this._parent.isSimpleSelectEnabled()) {
                return;
            }
            const volume = this._currentVolume();
            if (!volume) {
                return;
            }
            if (volume.isShiftDown) {
                if (!this._shiftTickHandle) {
                    this._shiftTickHandle = server_namespaceObject.system.runInterval((() => {
                        this._onShiftTick();
                    }), 1);
                }
            } else if (this._shiftTickHandle) {
                server_namespaceObject.system.clearRun(this._shiftTickHandle);
                this._shiftTickHandle = undefined;
            }
        }
        _onShiftTick() {
            if (this._parent.isSimpleSelectEnabled()) {
                if (this._shiftTickHandle) {
                    server_namespaceObject.system.clearRun(this._shiftTickHandle);
                    this._shiftTickHandle = undefined;
                }
                return;
            }
            const volume = this._currentVolume();
            if (!volume) {
                return;
            }
            const mouseHit = this.session.extensionContext.cursor.getRay();
            if (!mouseHit.hit) {
                return;
            }
            volume.toggleCornerGizmos(!volume.isShiftDown || volume.threePointSelectionState === ThreePointSelectionState.Finished || volume.threePointSelectionState === ThreePointSelectionState.NoPoints);
            if (!volume.isShiftDown) {
                if (this._shiftTickHandle) {
                    server_namespaceObject.system.clearRun(this._shiftTickHandle);
                    this._shiftTickHandle = undefined;
                }
                return;
            }
            const mouseRay = lib.Vector3Utils.normalize(lib.Vector3Utils.subtract(mouseHit.end, mouseHit.start));
            if (volume.threePointSelectionState === ThreePointSelectionState.FirstCorner) {
                const secondPointCandidate = calculateYPlaneIntersection(volume.firstCorner ?? volume.from, mouseHit.start, mouseRay);
                if (secondPointCandidate) {
                    if (!lib.Vector3Utils.equals(secondPointCandidate, volume.to) && this._isValidCornerPoint(secondPointCandidate, volume.from)) {
                        this._tryAssignVolumeTo(volume, secondPointCandidate);
                    }
                }
            } else if (volume.threePointSelectionState === ThreePointSelectionState.BottomFace) {
                const thirdPointCandidate = calculateClosestPointOnSecondLine(mouseHit.start, mouseRay, volume.secondCorner ?? volume.to, lib.VECTOR3_UP);
                if (thirdPointCandidate) {
                    if (!lib.Vector3Utils.equals(thirdPointCandidate, volume.to) && this._isValidCornerPoint(thirdPointCandidate, volume.from)) {
                        this._tryAssignVolumeTo(volume, thirdPointCandidate);
                    }
                }
            }
        }
        _onLeftMousePressed(isCtrlDown, isShiftDown, mouseRay) {
            if (!this.parent.isTransactionOperationActive()) {
                this.parent.beginTransactionableOperation("Marquee Selection Operation");
            }
            let currVolume = this._currentVolume();
            if (!currVolume) {
                currVolume = this._createVolume(new server_namespaceObject.BlockVolume(mouseRay.cursorBlockLocation, mouseRay.cursorBlockLocation), true);
                currVolume.firstCorner = mouseRay.cursorBlockLocation;
                currVolume.secondCorner = undefined;
                currVolume.threePointSelectionState = ThreePointSelectionState.NoPoints;
            }
            currVolume.state = MarqueeSelectionVolumeState.Idle;
            const threePointSelectionEnabled = !this._parent.isSimpleSelectEnabled();
            if (threePointSelectionEnabled && isShiftDown) {
                switch (currVolume.threePointSelectionState) {
                  case ThreePointSelectionState.FirstCorner:
                    {
                        const newSecondCorner = calculateYPlaneIntersection(currVolume.from, mouseRay.location, mouseRay.direction);
                        if (newSecondCorner) {
                            if (this._isValidCornerPoint(newSecondCorner, currVolume.from)) {
                                this._tryAssignVolumeTo(currVolume, newSecondCorner);
                                currVolume.secondCorner = currVolume.to;
                                currVolume.threePointSelectionState = ThreePointSelectionState.BottomFace;
                            }
                        }
                        break;
                    }

                  case ThreePointSelectionState.BottomFace:
                    {
                        const topOrBottomCorner = calculateClosestPointOnSecondLine(mouseRay.location, mouseRay.direction, currVolume.secondCorner ?? currVolume.to, lib.VECTOR3_UP);
                        if (topOrBottomCorner) {
                            const newSecondCorner = {
                                x: currVolume?.secondCorner?.x ?? currVolume.to.x,
                                y: topOrBottomCorner.y,
                                z: currVolume?.secondCorner?.z ?? currVolume.to.z
                            };
                            if (this._isValidCornerPoint(newSecondCorner, currVolume.from)) {
                                this._tryAssignVolumeTo(currVolume, newSecondCorner);
                                currVolume.secondCorner = currVolume.to;
                                currVolume.threePointSelectionState = ThreePointSelectionState.Finished;
                            }
                        }
                        break;
                    }

                  case ThreePointSelectionState.NoPoints:
                  case ThreePointSelectionState.Finished:
                    {
                        if (this._tryAssignVolumeFrom(currVolume, mouseRay.cursorBlockLocation) && this._tryAssignVolumeTo(currVolume, mouseRay.cursorBlockLocation)) {
                            currVolume.firstCorner = mouseRay.cursorBlockLocation;
                            currVolume.secondCorner = undefined;
                            currVolume.threePointSelectionState = ThreePointSelectionState.FirstCorner;
                        }
                        break;
                    }

                  default:
                    {
                        break;
                    }
                }
            } else {
                if (isShiftDown) {
                    const targetLocation = mouseRay.cursorBlockLocation;
                    if (!lib.Vector3Utils.equals(targetLocation, currVolume.to) && this._isValidCornerPoint(targetLocation, currVolume.from)) {
                        this._tryAssignVolumeTo(currVolume, targetLocation);
                    }
                } else {
                    if (!isCtrlDown) {
                        this._clearVolumeStack();
                    }
                    const newVolume = this._createVolume(new server_namespaceObject.BlockVolume(mouseRay.cursorBlockLocation, mouseRay.cursorBlockLocation), true);
                    newVolume.firstCorner = mouseRay.cursorBlockLocation;
                    newVolume.secondCorner = undefined;
                    newVolume.state = MarqueeSelectionVolumeState.Idle;
                    newVolume.threePointSelectionState = ThreePointSelectionState.FirstCorner;
                }
            }
            this.applyVolumeStackToSelectionManager();
        }
        _onLeftMouseDrag(isCtrlDown, isShiftDown, mouseRay) {
            if (!this.parent.isTransactionOperationActive()) {
                return;
            }
            const currVolume = this._currentVolume();
            if (!currVolume) {
                return;
            }
            currVolume.state = MarqueeSelectionVolumeState.Dragging;
            const threePointSelectionEnabled = !this._parent.isSimpleSelectEnabled();
            if (threePointSelectionEnabled && isShiftDown) {
                switch (currVolume.threePointSelectionState) {
                  case ThreePointSelectionState.FirstCorner:
                    {
                        const newSecondCorner = calculateYPlaneIntersection(currVolume.firstCorner ?? currVolume.from, mouseRay.location, mouseRay.direction);
                        if (newSecondCorner) {
                            if (!lib.Vector3Utils.equals(newSecondCorner, currVolume.to) && this._isValidCornerPoint(currVolume.from, newSecondCorner)) {
                                this._tryAssignVolumeTo(currVolume, newSecondCorner);
                                currVolume.secondCorner = currVolume.to;
                            }
                        }
                        break;
                    }

                  case ThreePointSelectionState.NoPoints:
                  case ThreePointSelectionState.BottomFace:
                  case ThreePointSelectionState.Finished:
                  default:
                    {
                        break;
                    }
                }
            } else {
                const targetLocation = mouseRay.cursorBlockLocation;
                if (!lib.Vector3Utils.equals(targetLocation, currVolume.to) && this._isValidCornerPoint(currVolume.from, targetLocation)) {
                    this._tryAssignVolumeTo(currVolume, targetLocation);
                }
            }
        }
        _onLeftMouseReleased(isShiftDown, mouseRay) {
            if (!this.parent.isTransactionOperationActive()) {
                return;
            }
            const currVolume = this._currentVolume();
            if (!currVolume) {
                return;
            }
            if (currVolume.state === MarqueeSelectionVolumeState.Dragging) {
                const threePointSelectionEnabled = !this._parent.isSimpleSelectEnabled();
                if (threePointSelectionEnabled && isShiftDown) {
                    if (currVolume.threePointSelectionState === ThreePointSelectionState.FirstCorner) {
                        const newSecondCorner = calculateYPlaneIntersection(currVolume.firstCorner ?? currVolume.from, mouseRay.location, mouseRay.direction);
                        if (newSecondCorner) {
                            if (!lib.Vector3Utils.equals(newSecondCorner, currVolume.to) && this._isValidCornerPoint(newSecondCorner, currVolume.from)) {
                                this._tryAssignVolumeTo(currVolume, newSecondCorner);
                                currVolume.secondCorner = currVolume.to;
                                currVolume.threePointSelectionState = ThreePointSelectionState.BottomFace;
                            }
                        }
                    }
                } else {
                    const targetLocation = mouseRay.cursorBlockLocation;
                    if (!lib.Vector3Utils.equals(targetLocation, currVolume.to) && this._isValidCornerPoint(targetLocation, currVolume.from)) {
                        this._tryAssignVolumeTo(currVolume, targetLocation);
                    }
                }
            }
            currVolume.state = MarqueeSelectionVolumeState.Done;
            this.applyVolumeStackToSelectionManager();
            if (this.parent.isTransactionOperationActive()) {
                this.parent.endTransactionableOperation();
            }
        }
        _isValidCornerPoint(firstCorner, secondCornerCandidate) {
            const difference = lib.Vector3Utils.subtract(secondCornerCandidate, firstCorner);
            const size = {
                x: Math.abs(difference.x),
                y: Math.abs(difference.y),
                z: Math.abs(difference.z)
            };
            if (size.x < 1 || size.y < 1 || size.z < 1) {
                return size.x <= server_editor_namespaceObject.editor.constants.maxDynamicSelectionSize.x && size.y <= server_editor_namespaceObject.editor.constants.maxDynamicSelectionSize.y && size.z <= server_editor_namespaceObject.editor.constants.maxDynamicSelectionSize.z;
            }
            return isWithinLimits(size, server_editor_namespaceObject.editor.constants.maxBlockVolume);
        }
        _tryAssignVolumeFrom(volume, fromLocation) {
            try {
                volume.from = fromLocation;
                return true;
            } catch (_e) {
                if (_e instanceof Error) {
                    this.session.log.error(`${_e.message}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
                this.parent.cancelTransactionableOperation();
                return false;
            }
        }
        _tryAssignVolumeTo(volume, toLocation) {
            try {
                volume.to = toLocation;
                return true;
            } catch (_e) {
                if (_e instanceof Error) {
                    this.session.log.error(`${_e.message}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
                this.parent.cancelTransactionableOperation();
                return false;
            }
        }
        _showVolumes() {
            this._volumeStack.forEach((volume => {
                volume.visible = true;
            }));
        }
        _hideVolumes() {
            this._volumeStack.forEach((volume => {
                volume.visible = false;
            }));
        }
        applyVolumeStackToSelectionManager() {
            const newVolume = new server_editor_namespaceObject.RelativeVolumeListBlockVolume;
            this._volumeStack.forEach((volume => {
                newVolume.add(volume.blockVolume);
            }));
            this.session.extensionContext.selectionManager.volume.set(newVolume);
        }
        _clearSelectionManager() {
            this.session.extensionContext.selectionManager.volume.clear();
        }
        _clearVolumeStack() {
            this._volumeStack.forEach((volume => {
                volume.teardown();
            }));
            this._volumeStack = [];
            this._clearSelectionManager();
            this.volumeOrigin = lib.VECTOR3_ZERO;
            this.volumeSize = {
                x: 1,
                y: 1,
                z: 1
            };
        }
        _createVolume(_volume, _applyToSelection) {
            this._volumeStack.forEach((volume => {
                volume.deactivateHandles();
            }));
            const volume = new MarqueeSelectionVolume(this, _volume, (marqueeVolume => {
                this.debugLog(`Marquee bounds changed to ${lib.Vector3Utils.toString(marqueeVolume.from)} -> ${lib.Vector3Utils.toString(marqueeVolume.to)}`);
                this.volumeOrigin = _volume.from;
                this.volumeSize = _volume.getSpan();
                this.applyVolumeStackToSelectionManager();
            }));
            this._volumeStack.push(volume);
            if (_applyToSelection) {
                this.applyVolumeStackToSelectionManager();
            }
            return volume;
        }
        _currentVolume() {
            if (this._volumeStack.length === 0) {
                return undefined;
            }
            return this._volumeStack[this._volumeStack.length - 1];
        }
        _popVolume() {
            const volume = this._volumeStack.pop();
            if (volume) {
                volume.teardown();
            }
        }
        fillTransactionPayload(_payload) {
            _payload.mode = this.modeType;
            _payload.volumes = [];
            this._volumeStack.forEach((volume => {
                const relativeVolume = new server_editor_namespaceObject.RelativeVolumeListBlockVolume;
                relativeVolume.add(volume.blockVolume);
                _payload.volumes.push(relativeVolume);
            }));
        }
        applyUndo(_payload) {
            if (_payload.mode !== this.modeType) {
                throw new Error("Undo payload mode does not match current mode");
            }
            this.volumeOrigin = lib.VECTOR3_ZERO;
            this.volumeSize = {
                x: 1,
                y: 1,
                z: 1
            };
            this._clearVolumeStack();
            _payload.volumes.forEach((volume => {
                const volumeList = volume.getVolumeList();
                volumeList.forEach((volume => {
                    this._createVolume(volume, true);
                }));
            }));
            const latestVolume = this._currentVolume();
            if (latestVolume) {
                this.volumeOrigin = latestVolume.blockVolume.getMin();
                this.volumeSize = latestVolume.blockVolume.getSpan();
            }
        }
        applyRedo(_payload) {
            if (_payload.mode !== this.modeType) {
                throw new Error("Undo payload mode does not match current mode");
            }
            this.volumeOrigin = lib.VECTOR3_ZERO;
            this.volumeSize = {
                x: 1,
                y: 1,
                z: 1
            };
            this._clearVolumeStack();
            _payload.volumes.forEach((volume => {
                const volumeList = volume.getVolumeList();
                volumeList.forEach((volume => {
                    this._createVolume(volume, true);
                }));
            }));
            const latestVolume = this._currentVolume();
            if (latestVolume) {
                this.volumeOrigin = latestVolume.blockVolume.getMin();
                this.volumeSize = latestVolume.blockVolume.getSpan();
            }
        }
        onExternalSelectionChanged(_evt) {
            this.volumeOrigin = lib.VECTOR3_ZERO;
            this.volumeSize = {
                x: 1,
                y: 1,
                z: 1
            };
            if (!this.session.extensionContext.selectionManager.volume.isEmpty) {
                if (this.session.extensionContext.selectionManager.volume.volumeCount === 1) {
                    const volume = this._currentVolume();
                    if (volume) {
                        volume.deactivateHandles();
                        let externalVolumeBounds;
                        try {
                            externalVolumeBounds = this.session.extensionContext.selectionManager.volume.getBoundingBox();
                            volume.setFromBounds(externalVolumeBounds);
                        } catch {
                            this._popVolume();
                        }
                    } else {
                        let externalVolumeBounds;
                        try {
                            externalVolumeBounds = this.session.extensionContext.selectionManager.volume.getBoundingBox();
                            const newVolume = new server_namespaceObject.BlockVolume(externalVolumeBounds.min, externalVolumeBounds.max);
                            const applyToSelection = false;
                            this._createVolume(newVolume, applyToSelection);
                        } catch {
                            this._popVolume();
                        }
                    }
                } else {
                    while (this._volumeStack.length > 0) {
                        this._popVolume();
                    }
                }
            } else {
                while (this._volumeStack.length > 0) {
                    this._popVolume();
                }
            }
        }
        onDimensionChange() {
            this.debugLog("Dimension change - clearing volume stack");
            this._clearVolumeStack();
            this._transformVec3UIComponent.updateAxisLimits({
                min: {
                    y: this.parent.session.extensionContext.player.dimension.heightRange.min
                },
                max: {
                    y: this.parent.session.extensionContext.player.dimension.heightRange.max
                }
            });
        }
        beginManualInputTranslateVolume() {
            const first = this._translationKeyRepeatRefCount === 0;
            if (this._translationKeyRepeatRefCount === 0) {
                this.parent.beginTransactionableOperation("Marquee Volume Manual Translate");
            }
            ++this._translationKeyRepeatRefCount;
            return first;
        }
        manualInputTranslateVolume(_directionVector) {
            const volume = this._currentVolume();
            if (volume) {
                try {
                    const bounds = volume.blockVolume.getBoundingBox();
                    const newBounds = server_namespaceObject.BlockBoundingBoxUtils.translate(bounds, _directionVector);
                    if (!this.session.extensionContext.blockUtilities.isLocationInsideCurrentDimensionBounds(newBounds)) {
                        return;
                    }
                    volume.from = newBounds.min;
                    volume.to = newBounds.max;
                } catch {
                    this._popVolume();
                }
            }
        }
        endManualInputTranslateVolume() {
            --this._translationKeyRepeatRefCount;
            if (this._translationKeyRepeatRefCount === 0) {
                this.parent.endTransactionableOperation();
                this.applyVolumeStackToSelectionManager();
            } else if (this._translationKeyRepeatRefCount < 0) {
                throw new Error("Translation key repeat count is less than zero - mismatch of press/releases");
            }
        }
        beginManualInputResizeVolume(_shrink) {
            const first = this._resizeKeyRepeatRefCount === 0;
            if (this._resizeKeyRepeatRefCount === 0) {
                this._resizeShrink = _shrink;
                this.parent.beginTransactionableOperation("Marquee Volume Manual Resize");
            }
            ++this._resizeKeyRepeatRefCount;
            return first;
        }
        shrinkVolumeAlongViewAxis(_viewRotation, _direction) {
            if (this._resizeKeyRepeatRefCount > 0) {
                if (!this._resizeShrink) {
                    return;
                }
            }
            const volume = this._currentVolume();
            if (volume) {
                const actualVolume = volume.blockVolume;
                const worldBounds = this.session.extensionContext.blockUtilities.getDimensionLocationBoundingBox();
                const newVolume = shrinkVolumeAlongViewAxis(actualVolume, _viewRotation, _direction, 1, worldBounds);
                try {
                    const newBounds = newVolume.getBoundingBox();
                    volume.from = newBounds.min;
                    volume.to = newBounds.max;
                } catch {
                    this._popVolume();
                }
            }
        }
        growVolumeAlongViewAxis(_viewRotation, _direction) {
            if (this._resizeKeyRepeatRefCount > 0) {
                if (this._resizeShrink) {
                    return;
                }
            }
            const volume = this._currentVolume();
            if (volume) {
                const actualVolume = volume.blockVolume;
                const worldBounds = this.session.extensionContext.blockUtilities.getDimensionLocationBoundingBox();
                const newVolume = growVolumeAlongViewAxis(actualVolume, _viewRotation, _direction, 1, worldBounds);
                try {
                    const newBounds = newVolume.getBoundingBox();
                    volume.from = newBounds.min;
                    volume.to = newBounds.max;
                } catch {
                    this._popVolume();
                }
            }
        }
        endManualInputResizeVolume() {
            --this._resizeKeyRepeatRefCount;
            if (this._resizeKeyRepeatRefCount === 0) {
                this.parent.endTransactionableOperation();
                this.applyVolumeStackToSelectionManager();
            } else if (this._resizeKeyRepeatRefCount < 0) {
                throw new Error("Resize key repeat count is less than zero - mismatch of press/releases");
            }
        }
        onColorChangeEvent() {
            const boundsColors = this.parent.boundingBoxColor;
            this._volumeStack.forEach((volume => {
                volume.onColorChangeEvent(boundsColors.outline, boundsColors.hull);
            }));
        }
    }
    class FreehandSelectionVolume {
        constructor(_modeImpl, _onChanged) {
            this._onChanged = () => {};
            this._modeImpl = _modeImpl;
            this._onChanged = _onChanged || this._onChanged;
            let min = lib.VECTOR3_ZERO;
            let visible = true;
            try {
                const selectionBounds = this._modeImpl.session.extensionContext.selectionManager.volume.getBoundingBox();
                min = selectionBounds.min;
            } catch {
                visible = false;
            }
            this._widget = this._modeImpl.parent.widgetGroup.createWidget(min, {
                snapToBlockLocation: true,
                visible,
                selectable: false
            });
            this._widget.addGizmoComponent("freehandToolGizmo", {
                axes: server_editor_namespaceObject.Axis.X | server_editor_namespaceObject.Axis.Y | server_editor_namespaceObject.Axis.Z,
                visible: true,
                normalizedAutoOffset: {
                    x: 0,
                    y: 0,
                    z: 0
                },
                stateChangeEvent: evt => {
                    if (evt.eventType !== undefined && evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginMoved) {
                        this.applyVolumeLocationToSelectionManager();
                        return;
                    }
                }
            });
            const boundsColors = _modeImpl.parent.boundingBoxColor;
            const outlineColors = _modeImpl.parent.outlineBoxColor;
            this._widgetVolumeComponent = this._widget.addVolumeOutline("freehand_outline", undefined, {
                normalizedOrigin: {
                    x: -1,
                    y: -1,
                    z: -1
                },
                showHighlightOutline: true,
                showOutline: true,
                visible: true,
                hullColor: boundsColors.hull,
                outlineColor: boundsColors.outline,
                highlightOutlineColor: outlineColors.outline,
                highlightHullColor: outlineColors.hull
            });
        }
        teardown() {
            this._widget.visible = false;
            this._widgetVolumeComponent.delete();
            this._widget.delete();
        }
        get visible() {
            return this._widget.visible;
        }
        set visible(value) {
            this._widget.visible = value;
        }
        get actualSelectionBoundingBox() {
            let ret = {
                min: lib.VECTOR3_ZERO,
                max: lib.VECTOR3_ZERO
            };
            try {
                ret = this._modeImpl.session.extensionContext.selectionManager.volume.getBoundingBox();
            } catch {}
            return ret;
        }
        get blockVolume() {
            return this._modeImpl.session.extensionContext.selectionManager.volume.get();
        }
        refreshFromSelection() {
            try {
                const selectionBounds = this._modeImpl.session.extensionContext.selectionManager.volume.getBoundingBox();
                this._widget.location = selectionBounds.min;
                this.visible = true;
            } catch {
                this.visible = false;
            }
        }
        translate(_direction) {
            const selectionBounds = this._modeImpl.session.extensionContext.selectionManager.volume.getBoundingBox();
            const newBounds = server_namespaceObject.BlockBoundingBoxUtils.translate(selectionBounds, _direction);
            if (!this._modeImpl.session.extensionContext.blockUtilities.isLocationInsideCurrentDimensionBounds(newBounds)) {
                return;
            }
            let location = this._widget.location;
            location = lib.Vector3Utils.add(location, _direction);
            this._widget.location = location;
        }
        applyVolumeLocationToSelectionManager() {
            const location = this._widget.location;
            const oldBounds = this.actualSelectionBoundingBox;
            this._modeImpl.session.extensionContext.selectionManager.volume.moveTo(location);
            const newBounds = this.actualSelectionBoundingBox;
            this._modeImpl.debugLog(`Moved selection from ${lib.Vector3Utils.toString(oldBounds.min)} to ${lib.Vector3Utils.toString(newBounds.min)}`);
        }
        onColorChangeEvent(_boundsOutline, _boundsHull, _volumeOutline, _volumeHull) {
            this._widgetVolumeComponent.hullColor = _boundsHull;
            this._widgetVolumeComponent.outlineColor = _boundsOutline;
            this._widgetVolumeComponent.highlightHullColor = _volumeHull;
            this._widgetVolumeComponent.highlightOutlineColor = _volumeOutline;
        }
    }
    class SelectionModeFreehand extends SelectionCreationModeBase {
        constructor(_parentPane, _parent) {
            super();
            this._freehandSelectionActive = false;
            this._volumeStack = [];
            this._translationKeyRepeatRefCount = 0;
            this._parent = _parent;
            this._parentPane = _parentPane;
            this._modePane = this._parentPane.createSubPane({
                title: "NO_ID",
                hasMargins: false,
                hasExpander: false
            });
            this._brushSharedControl = new BrushPaintSharedControl(this._parent.session, this._parent.tool, this._modePane, {
                paintMode: server_editor_namespaceObject.PaintMode.FreehandSelect
            }, (0, server_editor_namespaceObject.getDefaultBrushShapes)(), {
                hasPaneMargins: false
            });
            this._brushSharedControl.initialize();
        }
        get parentPane() {
            return this._parentPane;
        }
        get modePane() {
            return this._modePane;
        }
        get parent() {
            return this._parent;
        }
        get session() {
            return this._parent.session;
        }
        get modeType() {
            return SelectionToolMode.Freehand;
        }
        debugLog(message) {
            this.parent.debugLog(message);
        }
        teardown() {
            for (const volume of this._volumeStack) {
                volume.teardown();
            }
        }
        activate(_toolActive) {
            if (_toolActive) {
                this._brushSharedControl?.activateControl();
                this._brushSharedControl?.activateVisualization();
            }
            this._freehandSelectionActive = false;
            this._showVolumes();
        }
        deactivate(_toolActive, _switchingModes) {
            if (_toolActive) {
                this._brushSharedControl?.deactivateControl();
            }
            this._freehandSelectionActive = false;
            if (_switchingModes) {
                this.parent.performSingleTransactionableOperation((() => {
                    this._clearVolumeStack();
                    return true;
                }), "Deactivate Freehand");
            }
        }
        clearSelection() {
            this.parent.performSingleTransactionableOperation((() => {
                this.session.extensionContext.selectionManager.volume.clear();
                this._clearVolumeStack();
                return true;
            }), "Clear Selection");
            this._popVolume();
            this._clearSelectionManager();
        }
        applyImmediateSelection() {
            if (this.parent.isTransactionOperationActive()) {
                this.session.log.warning(`Freehand selection already active`);
                return;
            }
            this.parent.beginTransactionableOperation("Freehand Volume Creation");
            this._beginFreehandSelection(true);
        }
        onMouseClickAndDrag(_mouseRay, _mouseProps, _oneShot = false) {
            if (_mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton) {
                if (_mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown) {
                    if (this.parent.isTransactionOperationActive()) {
                        this.session.log.warning(`Freehand selection already active`);
                        return;
                    }
                    this.parent.beginTransactionableOperation("Freehand Volume Creation");
                    if (!(_mouseProps.modifiers.shift || _mouseProps.modifiers.ctrl)) {
                        this.debugLog(`Clearing Freehand Stack - no SHIFT or CTRL pressed`);
                        this._clearSelectionManager();
                    } else {
                        this.debugLog(`SHIFT or CTRL pressed - leaving selection contents intact`);
                    }
                    this._beginFreehandSelection(_oneShot);
                } else if (_mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonUp) {
                    this._endFreehandSelection();
                }
            }
        }
        _beginFreehandSelection(_oneShot = false) {
            if (this._freehandSelectionActive) {
                this.session.log.warning(`Freehand selection already active`);
                return;
            }
            this.parent.telemetryManager.fireTelemetryEvent(SelectionTelemetry.FreehandSelectionBegin, {
                oneShot: _oneShot
            });
            this._freehandSelectionActive = true;
            this._popVolume();
            if (_oneShot) {
                this.session.extensionContext.brushShapeManager.singlePaint((_state => {
                    if (_state === server_editor_namespaceObject.PaintCompletionState.Success) {
                        this._freehandSelectionActive = false;
                        this._createVolume();
                        this.parent.endTransactionableOperation();
                    } else {
                        this._popVolume();
                        this.parent.cancelTransactionableOperation();
                    }
                }));
            } else {
                this.session.extensionContext.brushShapeManager.beginPainting((_state => {
                    if (_state === server_editor_namespaceObject.PaintCompletionState.Success) {
                        this._freehandSelectionActive = false;
                        this._createVolume();
                        this.parent.endTransactionableOperation();
                    } else {
                        this._popVolume();
                        this.parent.cancelTransactionableOperation();
                    }
                }));
            }
        }
        _endFreehandSelection() {
            if (!this._freehandSelectionActive) {
                this.session.log.warning(`Freehand selection not active`);
                return;
            }
            this.parent.telemetryManager.fireTelemetryEvent(SelectionTelemetry.FreehandSelectionComplete);
            this.session.extensionContext.brushShapeManager.endPainting(false);
        }
        _showVolumes() {
            this._volumeStack.forEach((volume => {
                volume.visible = true;
            }));
        }
        _hideVolumes() {
            this._volumeStack.forEach((volume => {
                volume.visible = false;
            }));
        }
        applyVolumeStackToSelectionManager() {
            const newVolume = new server_editor_namespaceObject.RelativeVolumeListBlockVolume;
            this._volumeStack.forEach((volume => {
                newVolume.add(volume.blockVolume);
            }));
            this.session.extensionContext.selectionManager.volume.set(newVolume);
        }
        _clearSelectionManager() {
            this.session.extensionContext.selectionManager.volume.clear();
        }
        _clearVolumeStack() {
            this._volumeStack.forEach((volume => {
                volume.teardown();
            }));
            this._volumeStack = [];
            this._clearSelectionManager();
        }
        _createVolume() {
            const volume = new FreehandSelectionVolume(this);
            this._volumeStack.push(volume);
            return volume;
        }
        _currentVolume() {
            if (this._volumeStack.length === 0) {
                return undefined;
            }
            return this._volumeStack[this._volumeStack.length - 1];
        }
        _popVolume() {
            const volume = this._volumeStack.pop();
            if (volume) {
                volume.teardown();
            }
        }
        fillTransactionPayload(_payload) {
            _payload.mode = this.modeType;
            _payload.volumes = this._volumeStack.map((volume => deepCopy(volume.blockVolume)));
        }
        applyUndo(_payload) {
            if (_payload.mode !== this.modeType) {
                throw new Error("Undo payload mode does not match current mode");
            }
            this._clearVolumeStack();
            _payload.volumes.forEach((_volume => {
                this.session.extensionContext.selectionManager.volume.add(_volume);
            }));
            this._createVolume();
        }
        applyRedo(_payload) {
            if (_payload.mode !== this.modeType) {
                throw new Error("Undo payload mode does not match current mode");
            }
            this._clearVolumeStack();
            _payload.volumes.forEach((_volume => {
                this.session.extensionContext.selectionManager.volume.add(_volume);
            }));
            this._createVolume();
        }
        onExternalSelectionChanged(_evt) {
            while (this._volumeStack.length > 0) {
                this._popVolume();
            }
            if (!this.session.extensionContext.selectionManager.volume.isEmpty) {
                if (this.session.extensionContext.selectionManager.volume.volumeCount !== 1) {
                    this._createVolume();
                }
            }
        }
        onDimensionChange() {
            this.debugLog("Dimension change - clearing volume stack");
            this._clearVolumeStack();
        }
        beginManualInputTranslateVolume() {
            const first = this._translationKeyRepeatRefCount === 0;
            if (this._translationKeyRepeatRefCount === 0) {
                this.parent.beginTransactionableOperation("Freehand Volume Manual Translate");
            }
            ++this._translationKeyRepeatRefCount;
            return first;
        }
        manualInputTranslateVolume(_directionVector) {
            const volume = this._currentVolume();
            if (volume) {
                volume.translate(_directionVector);
            }
        }
        endManualInputTranslateVolume() {
            --this._translationKeyRepeatRefCount;
            if (this._translationKeyRepeatRefCount === 0) {
                const volume = this._currentVolume();
                if (volume) {
                    volume.applyVolumeLocationToSelectionManager();
                }
                this.parent.endTransactionableOperation();
            } else if (this._translationKeyRepeatRefCount < 0) {
                throw new Error("Translation key repeat count is less than zero - mismatch of press/releases");
            }
        }
        beginManualInputResizeVolume(_shrink) {
            return false;
        }
        shrinkVolumeAlongViewAxis(_viewRotation, _direction) {}
        growVolumeAlongViewAxis(_viewRotation, _direction) {}
        endManualInputResizeVolume() {}
        onColorChangeEvent() {
            const boundsColors = this.parent.boundingBoxColor;
            const outlineColors = this.parent.outlineBoxColor;
            this._volumeStack.forEach((volume => {
                volume.onColorChangeEvent(boundsColors.outline, boundsColors.hull, outlineColors.outline, outlineColors.hull);
            }));
        }
    }
    const BlockMaskSharedControl_PERSISTENCE_GROUP_NAME = "editor:brushpaint";
    const PROPERTY_NAME = "BlockMaskControl";
    const PROPERTY_LOCALIZATION_PREFIX = `resourcePack.editor.${PROPERTY_NAME}`;
    var BlockMaskControlMaskMode;
    (function(BlockMaskControlMaskMode) {
        BlockMaskControlMaskMode[BlockMaskControlMaskMode["Disabled"] = 0] = "Disabled";
        BlockMaskControlMaskMode[BlockMaskControlMaskMode["Mask"] = 1] = "Mask";
        BlockMaskControlMaskMode[BlockMaskControlMaskMode["Replace"] = 2] = "Replace";
    })(BlockMaskControlMaskMode || (BlockMaskControlMaskMode = {}));
    class BlockMaskSharedControl extends SharedControlImpl {
        constructor(session, parentTool, parentPropertyPane, controlGroupName, onBlockMaskModeChanged) {
            super(session, parentTool, parentPropertyPane, PROPERTY_NAME, PROPERTY_LOCALIZATION_PREFIX + "." + controlGroupName);
            this._maskMode = (0, server_editor_namespaceObject.makeObservable)(BlockMaskControlMaskMode.Disabled);
            this._blockListReplaceIds = (0, server_editor_namespaceObject.makeObservable)([]);
            this._blockListReplace = [];
            this._blockListMaskIds = (0, server_editor_namespaceObject.makeObservable)([]);
            this._blockListMask = [];
            this._onBlockMaskModeChanged = onBlockMaskModeChanged;
            this._blockMaskKey = `${this.tool.id}_BlockMask_Mask`;
            this._blockReplaceKey = `${this.tool.id}_BlockMask_Replace`;
            this._persistenceManager = getPersistenceManager(this.session.extensionContext.player);
        }
        debugLog(_msg) {
            this.session.log.debug(`${PROPERTY_NAME}::${_msg}`);
        }
        info(_msg) {
            this.session.log.info(`${PROPERTY_NAME}::${_msg}`);
        }
        initialize() {
            super.initialize();
            this._blockListMask = this._loadBlockMask(this._blockMaskKey, convertBlockStringsToBlockType([ "air" ]));
            this._blockListReplace = this._loadBlockMask(this._blockReplaceKey, convertBlockStringsToBlockType([ "air" ]));
        }
        shutdown() {
            super.shutdown();
        }
        activateControl() {
            this.debugLog(`activateControl`);
            if (this.isActive) {
                this.debugLog(`activateControl - exiting early - already active`);
                return;
            }
            super.activateControl();
            this._constructUI();
        }
        deactivateControl() {
            this.debugLog("deactivateControl");
            if (!this.isActive) {
                this.debugLog("deactivateControl - exiting early - already deactivated");
                return;
            }
            super.deactivateControl();
            this._destroyUI();
        }
        _constructUI() {
            this.debugLog("constructUI");
            if (this._controlPane) {
                this.propertyPane.removeSubPane(this._controlPane);
                this._controlPane = undefined;
            }
            this._controlPane = this.propertyPane.createSubPane({
                title: this.localize("rootPane.title"),
                hasExpander: false
            });
            this._controlPane.addToggleGroup(this._maskMode, {
                title: this.localize("toggleGroup.title"),
                tooltip: this.localize("toggleGroup.tooltip"),
                entries: [ {
                    label: this.localize("toggleGroup.item.disabled.label"),
                    value: BlockMaskControlMaskMode.Disabled,
                    icon: "squareIcon",
                    tooltip: this.localize("toggleGroup.item.disabled.tooltip")
                }, {
                    label: this.localize("toggleGroup.item.mask.label"),
                    value: BlockMaskControlMaskMode.Mask,
                    icon: "pack://textures/editor/mask.png",
                    tooltip: this.localize("toggleGroup.item.mask.tooltip")
                }, {
                    label: this.localize("toggleGroup.item.replace.label"),
                    value: BlockMaskControlMaskMode.Replace,
                    icon: "pack://textures/editor/replace.png",
                    tooltip: this.localize("toggleGroup.item.replace.tooltip")
                } ],
                onChange: _newMode => {
                    switch (_newMode) {
                      case BlockMaskControlMaskMode.Disabled:
                        maskControl.visible = false;
                        replaceControl.visible = false;
                        break;

                      case BlockMaskControlMaskMode.Mask:
                        maskControl.visible = true;
                        replaceControl.visible = false;
                        break;

                      case BlockMaskControlMaskMode.Replace:
                        maskControl.visible = false;
                        replaceControl.visible = true;
                        break;
                    }
                    this._onBlockMaskModeChanged(_newMode);
                }
            });
            this._blockListMaskIds.set(convertBlockTypesToBlockStrings(this._blockListMask));
            const maskControl = this._controlPane.addBlockList(this._blockListMaskIds, {
                visible: false,
                onChange: newVal => {
                    this._blockListMask = convertBlockStringsToBlockType(newVal);
                    this._saveBlockMasks();
                }
            });
            this._blockListReplaceIds.set(convertBlockTypesToBlockStrings(this._blockListReplace));
            const replaceControl = this._controlPane.addBlockList(this._blockListReplaceIds, {
                visible: false,
                onChange: newVal => {
                    this._blockListReplace = convertBlockStringsToBlockType(newVal);
                    this._saveBlockMasks();
                }
            });
        }
        _destroyUI() {}
        _getBlockMaskListTypeFromInternalMaskType(internalMaskType) {
            switch (internalMaskType) {
              case BlockMaskControlMaskMode.Mask:
                return server_editor_namespaceObject.BlockMaskListType.Mask;

              case BlockMaskControlMaskMode.Replace:
                return server_editor_namespaceObject.BlockMaskListType.Replace;

              case BlockMaskControlMaskMode.Disabled:
                return server_editor_namespaceObject.BlockMaskListType.Disabled;

              default:
                throw new Error("Invalid internal mask type");
            }
            return server_editor_namespaceObject.BlockMaskListType.Disabled;
        }
        getBlockMask() {
            const maskType = this._getBlockMaskListTypeFromInternalMaskType(this._maskMode.value);
            const blockList = this._maskMode.value === BlockMaskControlMaskMode.Mask ? this._blockListMask : this._blockListReplace;
            return {
                maskType,
                blockList
            };
        }
        _saveBlockMasks() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(BlockMaskSharedControl_PERSISTENCE_GROUP_NAME, option);
            const errorMsg = "Fail to store block mask";
            if (!group) {
                this.session.log.error(errorMsg);
                return;
            } else {
                const maskList = convertBlockTypesToBlockStrings(this._blockListMask);
                const maskListItem = group.getOrCreateItem(this._blockMaskKey, maskList);
                if (maskListItem && maskListItem.value) {
                    maskListItem.commit();
                }
                const replaceList = convertBlockTypesToBlockStrings(this._blockListReplace);
                const replaceListItem = group.getOrCreateItem(this._blockReplaceKey, replaceList);
                if (replaceListItem && replaceListItem.value) {
                    replaceListItem.commit();
                }
                group.dispose();
            }
        }
        _loadBlockMask(key, defaultList) {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(BlockMaskSharedControl_PERSISTENCE_GROUP_NAME, option);
            const errorMsg = "No stored block mask found";
            if (!group) {
                this.session.log.info(errorMsg);
            } else {
                const storeItem = group.fetchItem(key);
                if (storeItem && storeItem.value) {
                    const blockList = convertBlockStringsToBlockType(storeItem.value);
                    if (blockList.length > 0) {
                        return blockList;
                    }
                }
                group.dispose();
            }
            return defaultList;
        }
    }
    class MagicSelectionVolume {
        constructor(_modeImpl, _onChanged) {
            this._onChanged = () => {};
            this._modeImpl = _modeImpl;
            this._onChanged = _onChanged || this._onChanged;
            let min = lib.VECTOR3_ZERO;
            let visible = true;
            try {
                const selectionBounds = this._modeImpl.session.extensionContext.selectionManager.volume.getBoundingBox();
                min = selectionBounds.min;
            } catch {
                visible = false;
            }
            this._widget = this._modeImpl.parent.widgetGroup.createWidget(min, {
                snapToBlockLocation: true,
                visible,
                selectable: false
            });
            const boundsColors = _modeImpl.parent.boundingBoxColor;
            const outlineColors = _modeImpl.parent.outlineBoxColor;
            this._widgetVolumeComponent = this._widget.addVolumeOutline("magic_outline", undefined, {
                normalizedOrigin: {
                    x: -1,
                    y: -1,
                    z: -1
                },
                showHighlightOutline: true,
                showOutline: true,
                visible: true,
                hullColor: boundsColors.hull,
                outlineColor: boundsColors.outline,
                highlightOutlineColor: outlineColors.outline,
                highlightHullColor: outlineColors.hull
            });
            this._widget.addGizmoComponent("smartToolGizmo", {
                axes: server_editor_namespaceObject.Axis.X | server_editor_namespaceObject.Axis.Y | server_editor_namespaceObject.Axis.Z,
                visible: true,
                normalizedAutoOffset: {
                    x: 0,
                    y: 0,
                    z: 0
                },
                stateChangeEvent: evt => {
                    if (evt.eventType !== undefined && evt.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginMoved) {
                        this.applyVolumeLocationToSelectionManager();
                        return;
                    }
                }
            });
        }
        teardown() {
            this._widget.visible = false;
            this._widgetVolumeComponent.delete();
            this._widget.delete();
        }
        get visible() {
            return this._widget.visible;
        }
        set visible(value) {
            this._widget.visible = value;
        }
        get actualSelectionBoundingBox() {
            let ret = {
                min: lib.VECTOR3_ZERO,
                max: lib.VECTOR3_ZERO
            };
            try {
                ret = this._modeImpl.session.extensionContext.selectionManager.volume.getBoundingBox();
            } catch {}
            return ret;
        }
        get blockVolume() {
            return this._modeImpl.session.extensionContext.selectionManager.volume.get();
        }
        refreshFromSelection() {
            try {
                const selectionBounds = this._modeImpl.session.extensionContext.selectionManager.volume.getBoundingBox();
                this._widget.location = selectionBounds.min;
                this.visible = true;
            } catch {
                this.visible = false;
            }
        }
        translate(_direction) {
            const selectionBounds = this._modeImpl.session.extensionContext.selectionManager.volume.getBoundingBox();
            const newBounds = server_namespaceObject.BlockBoundingBoxUtils.translate(selectionBounds, _direction);
            if (!this._modeImpl.session.extensionContext.blockUtilities.isLocationInsideCurrentDimensionBounds(newBounds)) {
                return;
            }
            let location = this._widget.location;
            location = lib.Vector3Utils.add(location, _direction);
            this._widget.location = location;
        }
        applyVolumeLocationToSelectionManager() {
            const location = this._widget.location;
            const oldBounds = this.actualSelectionBoundingBox;
            this._modeImpl.session.extensionContext.selectionManager.volume.moveTo(location);
            const newBounds = this.actualSelectionBoundingBox;
            this._modeImpl.debugLog(`Moved selection from ${lib.Vector3Utils.toString(oldBounds.min)} to ${lib.Vector3Utils.toString(newBounds.min)}`);
        }
        onColorChangeEvent(_boundsOutline, _boundsHull, _volumeOutline, _volumeHull) {
            this._widgetVolumeComponent.hullColor = _boundsHull;
            this._widgetVolumeComponent.outlineColor = _boundsOutline;
            this._widgetVolumeComponent.highlightHullColor = _volumeHull;
            this._widgetVolumeComponent.highlightOutlineColor = _volumeOutline;
        }
    }
    class SelectionModeMagic extends SelectionCreationModeBase {
        constructor(_parentPane, _parent) {
            super();
            this._volumeStack = [];
            this._translationKeyRepeatRefCount = 0;
            this._parent = _parent;
            this._parentPane = _parentPane;
            this._modePane = this._parentPane.createSubPane({
                title: "NO_ID",
                hasMargins: false,
                hasExpander: false
            });
        }
        get parentPane() {
            return this._parentPane;
        }
        get modePane() {
            return this._modePane;
        }
        get parent() {
            return this._parent;
        }
        get session() {
            return this._parent.session;
        }
        get modeType() {
            return SelectionToolMode.MagicSelect;
        }
        debugLog(message) {
            this.parent.debugLog(message);
        }
        teardown() {
            for (const volume of this._volumeStack) {
                volume.teardown();
            }
        }
        activate(_toolActive) {
            this._showVolumes();
        }
        deactivate(_toolActive, _switchingModes) {
            if (_switchingModes) {
                this.parent.performSingleTransactionableOperation((() => {
                    this._clearVolumeStack();
                    return true;
                }), "Deactivate Magic Select");
            }
        }
        clearSelection() {
            this.parent.performSingleTransactionableOperation((() => {
                this.session.extensionContext.selectionManager.volume.clear();
                this._clearVolumeStack();
                return true;
            }), "Clear Selection");
            this._popVolume();
            this._clearSelectionManager();
        }
        applyImmediateSelection() {}
        onMouseClickAndDrag(_mouseRay, _mouseProps, _oneShot = false) {
            if (_mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton) {
                if (_mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown) {
                    this.parent.beginTransactionableOperation("Magic Select Volume Creation");
                    if (!_mouseProps.modifiers.shift) {
                        this.debugLog(`Clearing Magic Select Stack - no SHIFT`);
                        this._clearSelectionManager();
                    } else {
                        this.debugLog(`SHIFT pressed - leaving selection contents intact`);
                    }
                    this.parent.telemetryManager.fireTelemetryEvent(SelectionTelemetry.MagicSelect);
                    this._popVolume();
                    const block = this.session.extensionContext.player.dimension.getBlock(_mouseRay.cursorBlockLocation);
                    if (block) {
                        const newSelection = this._selectObjectFromBase(block);
                        this.session.extensionContext.selectionManager.volume.add(newSelection);
                        this._createVolume();
                    }
                    this.parent.endTransactionableOperation();
                }
            }
        }
        _showVolumes() {
            this._volumeStack.forEach((volume => {
                volume.visible = true;
            }));
        }
        _hideVolumes() {
            this._volumeStack.forEach((volume => {
                volume.visible = false;
            }));
        }
        applyVolumeStackToSelectionManager() {
            const newVolume = new server_editor_namespaceObject.RelativeVolumeListBlockVolume;
            this._volumeStack.forEach((volume => {
                newVolume.add(volume.blockVolume);
            }));
            this.session.extensionContext.selectionManager.volume.set(newVolume);
        }
        _clearSelectionManager() {
            this.session.extensionContext.selectionManager.volume.clear();
        }
        _clearVolumeStack() {
            this._volumeStack.forEach((volume => {
                volume.teardown();
            }));
            this._volumeStack = [];
            this._clearSelectionManager();
        }
        _createVolume() {
            const volume = new MagicSelectionVolume(this);
            this._volumeStack.push(volume);
            return volume;
        }
        _currentVolume() {
            if (this._volumeStack.length === 0) {
                return undefined;
            }
            return this._volumeStack[this._volumeStack.length - 1];
        }
        _popVolume() {
            const volume = this._volumeStack.pop();
            if (volume) {
                volume.teardown();
            }
        }
        fillTransactionPayload(_payload) {
            _payload.mode = this.modeType;
            _payload.volumes = this._volumeStack.map((volume => deepCopy(volume.blockVolume)));
        }
        applyUndo(_payload) {
            if (_payload.mode !== this.modeType) {
                throw new Error("Undo payload mode does not match current mode");
            }
            this._clearVolumeStack();
            _payload.volumes.forEach((_volume => {
                this.session.extensionContext.selectionManager.volume.add(_volume);
            }));
            this._createVolume();
        }
        applyRedo(_payload) {
            if (_payload.mode !== this.modeType) {
                throw new Error("Undo payload mode does not match current mode");
            }
            this._clearVolumeStack();
            _payload.volumes.forEach((_volume => {
                this.session.extensionContext.selectionManager.volume.add(_volume);
            }));
            this._createVolume();
        }
        onExternalSelectionChanged(_evt) {
            while (this._volumeStack.length > 0) {
                this._popVolume();
            }
        }
        onDimensionChange() {
            this.debugLog("Dimension change - clearing volume stack");
            this._clearVolumeStack();
        }
        beginManualInputTranslateVolume() {
            const first = this._translationKeyRepeatRefCount === 0;
            if (this._translationKeyRepeatRefCount === 0) {
                this.parent.beginTransactionableOperation("MagicSelect Volume Manual Translate");
            }
            ++this._translationKeyRepeatRefCount;
            return first;
        }
        manualInputTranslateVolume(_directionVector) {
            const volume = this._currentVolume();
            if (volume) {
                volume.translate(_directionVector);
            }
        }
        endManualInputTranslateVolume() {
            --this._translationKeyRepeatRefCount;
            if (this._translationKeyRepeatRefCount === 0) {
                const volume = this._currentVolume();
                if (volume) {
                    volume.applyVolumeLocationToSelectionManager();
                }
                this.parent.endTransactionableOperation();
            } else if (this._translationKeyRepeatRefCount < 0) {
                throw new Error("Translation key repeat count is less than zero - mismatch of press/releases");
            }
        }
        beginManualInputResizeVolume(_shrink) {
            return false;
        }
        shrinkVolumeAlongViewAxis(_viewRotation, _direction) {}
        growVolumeAlongViewAxis(_viewRotation, _direction) {}
        endManualInputResizeVolume() {}
        onColorChangeEvent() {
            const boundsColors = this.parent.boundingBoxColor;
            const outlineColors = this.parent.outlineBoxColor;
            this._volumeStack.forEach((volume => {
                volume.onColorChangeEvent(boundsColors.outline, boundsColors.hull, outlineColors.outline, outlineColors.hull);
            }));
        }
        _selectObjectFromBase(startBlock) {
            const searchOffsets = [ {
                x: 1,
                y: 0,
                z: 0
            }, {
                x: -1,
                y: 0,
                z: 0
            }, {
                x: 0,
                y: 1,
                z: 0
            }, {
                x: 0,
                y: -1,
                z: 0
            }, {
                x: 0,
                y: 0,
                z: 1
            }, {
                x: 0,
                y: 0,
                z: -1
            } ];
            const newVolume = new server_editor_namespaceObject.RelativeVolumeListBlockVolume;
            if (startBlock) {
                const radius = 16;
                const from = {
                    x: startBlock.location.x - radius,
                    y: startBlock.location.y,
                    z: startBlock.location.z - radius
                };
                const to = {
                    x: startBlock.location.x + radius,
                    y: startBlock.location.y + radius * 2,
                    z: startBlock.location.z + radius
                };
                const bounds = new server_namespaceObject.BlockVolume(from, to);
                const dimension = startBlock.dimension;
                const fillStack = [];
                const selectStack = [];
                const visitedBlocks = new Vector3Set;
                fillStack.push(startBlock.location);
                visitedBlocks.add(startBlock.location);
                while (fillStack.length > 0) {
                    const loc = fillStack.pop();
                    if (loc === undefined || !bounds.isInside(loc)) continue;
                    const blockAtLoc = dimension.getBlock(loc);
                    if (!blockAtLoc || blockAtLoc.type === server_namespaceObject.BlockTypes.get(lib_vanilla_MinecraftBlockTypes.Air)) {
                        continue;
                    }
                    selectStack.push(loc);
                    for (const offset of searchOffsets) {
                        const offsetLoc = {
                            x: loc.x + offset.x,
                            y: loc.y + offset.y,
                            z: loc.z + offset.z
                        };
                        if (!bounds.isInside(offsetLoc)) continue;
                        if (visitedBlocks.contains(offsetLoc)) {
                            continue;
                        }
                        fillStack.push(offsetLoc);
                        visitedBlocks.add(offsetLoc);
                    }
                }
                for (const selectLoc of selectStack) {
                    newVolume.add(selectLoc);
                }
            }
            return newVolume;
        }
    }
    var NudgeWidgetMode;
    (function(NudgeWidgetMode) {
        NudgeWidgetMode[NudgeWidgetMode["NudgeMode"] = 0] = "NudgeMode";
        NudgeWidgetMode[NudgeWidgetMode["ExternalMode"] = 1] = "ExternalMode";
    })(NudgeWidgetMode || (NudgeWidgetMode = {}));
    class WorldBoundsCache {
        constructor() {
            this._boundingBoxes = new Map;
        }
        getBounds(dim) {
            if (!this._boundingBoxes.has(dim.id)) {
                this._boundingBoxes.set(dim.id, this.buildWorldBoundingBox(dim.heightRange));
            }
            return this._boundingBoxes.get(dim.id);
        }
        buildWorldBoundingBox(heights) {
            const xzExtents = 3e7;
            const min = {
                x: -xzExtents,
                y: heights.min,
                z: -xzExtents
            };
            const max = {
                x: xzExtents,
                y: heights.max,
                z: xzExtents
            };
            return server_namespaceObject.BlockBoundingBoxUtils.createValid(min, max);
        }
    }
    var NudgeUIMode;
    (function(NudgeUIMode) {
        NudgeUIMode[NudgeUIMode["Enabled"] = 0] = "Enabled";
        NudgeUIMode[NudgeUIMode["NoSelectionMessage"] = 1] = "NoSelectionMessage";
        NudgeUIMode[NudgeUIMode["Disabled"] = 2] = "Disabled";
    })(NudgeUIMode || (NudgeUIMode = {}));
    class NudgeUI {
        constructor(nudgeCallback, gotoCallback) {
            this._uiActionItems = [];
            this._uiPanes = [];
            this._goToPositionValue = (0, server_editor_namespaceObject.makeObservable)({
                x: 0,
                y: 0,
                z: 0
            });
            this._nudgeCallback = nudgeCallback;
            this._gotoCallback = gotoCallback;
        }
        addUIToPanel(_parentPane, session) {
            const noSelectionText = (0, server_editor_namespaceObject.makeObservable)({
                id: "resourcePack.editor.selectionTool.quickMove.noselection"
            });
            this._needsSelectionText = _parentPane.addText(noSelectionText, {
                visible: false
            });
            const buttonPane = this.createNudgeButtons(session, _parentPane);
            const positionEntry = _parentPane.addVector3(this._goToPositionValue, {
                title: "resourcePack.editor.selectionTool.quickMove.directions.setposition.title",
                tooltip: "resourcePack.editor.selectionTool.quickMove.directions.setposition.tooltip",
                visible: false
            });
            const gotoAction = session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => this._gotoCallback(this._goToPositionValue.value)
            });
            const goToPositionButton = _parentPane.addButton(gotoAction, {
                title: "resourcePack.editor.selectionTool.quickMove.directions.setposition.commit.title",
                tooltip: "resourcePack.editor.selectionTool.quickMove.directions.setposition.commit.tooltip",
                visible: false
            });
            this._uiActionItems = [ positionEntry, goToPositionButton ];
            this._uiPanes = [ buttonPane ];
        }
        createNudgeButtons(session, pane) {
            const directionsPane = pane.createSubPane({
                title: "",
                hasExpander: false,
                hasMargins: false,
                collapsed: true
            });
            directionsPane.hide();
            directionsPane.addDivider();
            directionsPane.addText("", {
                title: "resourcePack.editor.selectionTool.quickMove.directions.title",
                tooltip: "resourcePack.editor.selectionTool.quickMove.directions.tooltip",
                border: false
            });
            const directionButtonsPane = directionsPane.createSubPane({
                title: "",
                hasExpander: false,
                layout: server_editor_namespaceObject.PaneLayoutType.Wrapping,
                alignment: server_editor_namespaceObject.LayoutAlignment.Start
            });
            const directions = [ {
                dir: direction_Direction.Left,
                icon: "Left",
                tag: "left"
            }, {
                dir: direction_Direction.Right,
                icon: "Right",
                tag: "right"
            }, {
                dir: direction_Direction.Forward,
                icon: "Up-Left",
                tag: "forward"
            }, {
                dir: direction_Direction.Back,
                icon: "Down-Right",
                tag: "backward"
            }, {
                dir: direction_Direction.Up,
                icon: "Up",
                tag: "up"
            }, {
                dir: direction_Direction.Down,
                icon: "Down",
                tag: "down"
            } ];
            directions.forEach((info => {
                this.addNudgeDirectionButton(session, directionButtonsPane, info);
            }));
            return directionsPane;
        }
        addNudgeDirectionButton(session, buttonPane, info) {
            const action = session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => this.onDirectionPressed(session, info.dir)
            });
            const locKeyBase = "resourcePack.editor.selectionTool.quickMove.directions." + info.tag;
            buttonPane.addButton(action, {
                shrinkToIcon: true,
                tooltip: {
                    title: {
                        id: locKeyBase + ".title",
                        props: [ getInputMarkup("editor:selectionTool:quickMove:nudge:" + info.tag) ]
                    },
                    description: locKeyBase + ".tooltip"
                },
                icon: `pack://textures/editor/Arrow-${info.icon}.png?filtering=point`
            });
        }
        onDirectionPressed(session, direction) {
            const rotationY = session.extensionContext.player.getRotation().y;
            const nudgeDelta = getRotationCorrectedDirectionVector(rotationY, direction);
            this._nudgeCallback(nudgeDelta);
        }
        setMode(_mode) {
            const actionsVisible = _mode === NudgeUIMode.Enabled;
            const noSelectionMessageVisible = _mode === NudgeUIMode.NoSelectionMessage;
            this._uiActionItems.forEach((value => value.visible = actionsVisible));
            this._uiPanes.forEach((value => {
                if (actionsVisible) {
                    value.show();
                } else {
                    value.hide();
                }
            }));
            this._needsSelectionText.visible = noSelectionMessageVisible;
        }
        updatePosition(pos) {
            this._goToPositionValue.set(pos);
        }
    }
    function calculatePlacementOffset(box) {
        const span = lib.Vector3Utils.subtract(box.max, box.min);
        const adjustedSpan = lib.Vector3Utils.add(span, {
            x: 1,
            y: 1,
            z: 1
        });
        return lib.Vector3Utils.scale(adjustedSpan, .5);
    }
    class NudgeWidget {
        constructor(clipboard, session, callback, startLocation) {
            this._widgetGroup = session.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_bindings_namespaceObject.WidgetGroupSelectionMode.None,
                visible: true
            });
            this._widget = this._widgetGroup.createWidget(startLocation, {
                selectable: false,
                visible: false
            });
            this._widgetGizmoComponent = this._widget.addGizmoComponent("gizmo", {
                stateChangeEvent: evt => callback(evt),
                visible: true,
                axes: server_editor_bindings_namespaceObject.Axis.X | server_editor_bindings_namespaceObject.Axis.Y | server_editor_bindings_namespaceObject.Axis.Z
            });
            this._session = session;
            this._clipboardItem = clipboard;
        }
        show(location, selectionBox, mode) {
            const widgetOffset = calculatePlacementOffset(selectionBox);
            this._widget.visible = true;
            this._widget.location = location;
            this._widgetGizmoComponent.offset = widgetOffset;
            this._widgetGizmoComponent.visible = mode === NudgeWidgetMode.NudgeMode;
            this.createPreview(widgetOffset, mode === NudgeWidgetMode.NudgeMode);
        }
        hide() {
            this._widget.visible = false;
            this.deletePreview();
        }
        teardown() {
            this.deletePreview();
            this._widgetGizmoComponent.delete();
            this._widget.delete();
            this._widgetGroup.delete();
        }
        getPosition() {
            return this._widget.location;
        }
        updatePosition(loc) {
            this._widget.location = loc;
        }
        createPreview(offset, showOutline) {
            this._widgetClipboardComponent = this._widget.addClipboardComponent("nudge viz", this._clipboardItem, {
                showOutline,
                offset,
                hullColor: {
                    red: 0,
                    green: 1,
                    blue: 0,
                    alpha: .1
                },
                highlightHullColor: {
                    red: 0,
                    green: 1,
                    blue: 0,
                    alpha: .2
                },
                highlightOutlineColor: {
                    red: 1,
                    green: 1,
                    blue: 1,
                    alpha: 0
                }
            });
        }
        deletePreview() {
            this._widgetClipboardComponent?.delete();
            this._widgetClipboardComponent = undefined;
        }
    }
    class NudgeSelectionToolMode {
        constructor(_session, parent) {
            this._originalLocation = {
                x: 0,
                y: 0,
                z: 0
            };
            this._currentLocation = {
                x: 0,
                y: 0,
                z: 0
            };
            this._activeOperation = NudgeOperation.None;
            this._activeOperationIsExternallyDriven = false;
            this._isActive = false;
            this._session = _session;
            this._parent = parent;
            this._clipboardItem = _session.extensionContext.clipboardManager.create();
            this._vizUndoHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(this._session.extensionContext.transactionManager, (payload => this.applyPayload(payload.old)), (payload => this.applyPayload(payload.new)));
            this._nudgeWidget = new NudgeWidget(this._clipboardItem, _session, (evt => this.onGizmoEvent(evt)), this._originalLocation);
            const singleAtomicMove = newPosition => {
                this.startNudge(NudgeOperation.Move);
                if (this.updateNudge(newPosition, NudgeUpdateOptions.UpdateWidgetPosition)) {
                    this.commitNudge();
                } else {
                    this.cancelNudge();
                }
            };
            this._nudgeUI = new NudgeUI((dir => {
                singleAtomicMove(lib.Vector3Utils.add(this._currentLocation, dir));
            }), (position => {
                singleAtomicMove(position);
            }));
            this._selectionAfterEventHandle = this._session.extensionContext.afterEvents.SelectionChange.subscribe((_ => this.updateNudgeEnabled()));
            this._worldBounds = new WorldBoundsCache;
        }
        buildNudgeHandler(op, modifiers) {
            const opString = op === NudgeOperation.Move ? "nudge" : "copy";
            const bindingIdBase = "editor:selectionTool:quickMove:" + opString;
            const bindingNameBase = "resourcePack.editor.selectionTool.keyBinding.quickMoveMode." + opString;
            return new NudgeControlsHelper(this._session, this._parent.tool, bindingIdBase, bindingNameBase, modifiers, ((state, dir) => {
                this.onKeyEvent(state, dir, op);
            }));
        }
        teardown() {
            this.shutdownNudge();
            this._nudgeWidget.teardown();
            this._session.extensionContext.afterEvents.SelectionChange.unsubscribe(this._selectionAfterEventHandle);
        }
        get modeType() {
            return SelectionToolMode.Nudge;
        }
        isActive() {
            return this._isActive;
        }
        activate(_toolActive) {
            const selectionIsEmpty = this._session.extensionContext.selectionManager.volume.isEmpty;
            if (selectionIsEmpty) {
                this._session.log.warning("Cannot perform nudge without a selection.");
                this.setNudgeUIMode(NudgeUIMode.NoSelectionMessage);
                return;
            } else {
                this.setNudgeUIMode(NudgeUIMode.Enabled);
            }
            this.initializeNudge(NudgeWidgetMode.NudgeMode);
            this._nudgeUI.updatePosition(this._originalLocation);
            this._isActive = true;
        }
        deactivate(_toolActive, _clearVolumeStack) {
            this._isActive = false;
            if (this._activeOperation !== NudgeOperation.None) {
                this.cancelNudge();
            }
            this.setNudgeUIMode(NudgeUIMode.Disabled);
            this.shutdownNudge();
        }
        addNudgeUI(parentPane) {
            this._nudgeUI.addUIToPanel(parentPane, this._session);
        }
        isSelectionCreationMode() {
            return false;
        }
        shouldBeEnabled() {
            return !this._session.extensionContext.selectionManager.volume.isEmpty;
        }
        startNudgeFromExternalMode(operation) {
            this._activeOperationIsExternallyDriven = true;
            this.initializeNudge(NudgeWidgetMode.ExternalMode);
            this.startNudge(operation);
        }
        startNudge(operation) {
            const selectionVolume = this._session.extensionContext.selectionManager.volume.get();
            const selectionBox = this._session.extensionContext.selectionManager.volume.getBoundingBox();
            const transactions = this._session.extensionContext.transactionManager;
            this._session.extensionContext.transactionManager.openTransaction("Nudge");
            if (operation === NudgeOperation.Move) {
                transactions.trackBlockChangeArea(selectionBox.min, selectionBox.max);
                this._session.extensionContext.blockUtilities.fillVolume(selectionVolume, lib_vanilla_MinecraftBlockTypes.Air);
                transactions.commitTrackedChanges();
            }
            this._originalLocation = selectionBox.min;
            this._currentLocation = this._originalLocation;
            this._activeOperation = operation;
        }
        updateNudge(pos, updateOptions = NudgeUpdateOptions.None) {
            if (!this.willNewLocationBeValid(pos)) {
                if (updateOptions & NudgeUpdateOptions.UpdateWidgetPosition) {
                    this._session.log.warning("Cannot place blocks outside of world bounds.");
                }
                return false;
            }
            this._currentLocation = pos;
            if (updateOptions & NudgeUpdateOptions.UpdateWidgetPosition) {
                this._nudgeWidget.updatePosition(pos);
            }
            this._session.extensionContext.selectionManager.volume.moveTo(pos);
            if (updateOptions & NudgeUpdateOptions.ForceUpdateSelectionVisuals) {
                this._parent.forceSelectionChangeUpdate();
            }
            this._nudgeUI.updatePosition(pos);
            return true;
        }
        commitNudge() {
            if (this._activeOperation === NudgeOperation.None) {
                return;
            }
            this._clipboardItem.writeToWorld(this._currentLocation);
            const payload = {
                old: {
                    visPosition: new lib.Vector3Builder(this._originalLocation)
                },
                new: {
                    visPosition: new lib.Vector3Builder(this._currentLocation)
                }
            };
            this._vizUndoHandler.addUserDefinedOperation(payload, "Nudge Selection");
            this._parent.forceSelectionChangeUpdate();
            this._session.extensionContext.transactionManager.commitOpenTransaction();
            this._originalLocation = new lib.Vector3Builder(this._currentLocation);
            this._activeOperation = NudgeOperation.None;
            if (this._activeOperationIsExternallyDriven) {
                this.shutdownNudge();
            }
        }
        cancelNudge() {
            if (this._activeOperation === NudgeOperation.Move) {
                this._clipboardItem.writeToWorld(this._originalLocation);
            }
            if (!lib.Vector3Utils.equals(this._nudgeWidget.getPosition(), this._originalLocation)) {
                this._nudgeWidget.updatePosition(this._originalLocation);
            }
            if (!lib.Vector3Utils.equals(this._originalLocation, this._currentLocation)) {
                this._session.extensionContext.selectionManager.volume.moveTo(this._originalLocation);
                this._parent.forceSelectionChangeUpdate();
            }
            this._session.extensionContext.transactionManager.discardOpenTransaction();
            this._activeOperation = NudgeOperation.None;
            if (this._activeOperationIsExternallyDriven) {
                this.shutdownNudge();
            }
            this._currentLocation = this._originalLocation;
        }
        onGizmoEvent(evt) {
            if (evt.eventType === server_editor_bindings_namespaceObject.WidgetGizmoEventType.OriginGrabbed) {
                const operation = this._parent.isModifierDown(server_editor_namespaceObject.InputModifier.Control) ? NudgeOperation.Copy : NudgeOperation.Move;
                this.startNudge(operation);
            }
            if (evt.eventType === server_editor_bindings_namespaceObject.WidgetGizmoEventType.OriginMoved) {
                this.updateNudge(evt.widget.location);
            }
            if (evt.eventType === server_editor_bindings_namespaceObject.WidgetGizmoEventType.OriginReleased) {
                const widgetMoved = !lib.Vector3Utils.equals(this._originalLocation, evt.widget.location);
                const validDestination = this.willNewLocationBeValid(evt.widget.location);
                if (widgetMoved && validDestination) {
                    this.commitNudge();
                } else {
                    this.cancelNudge();
                }
                if (!validDestination) {
                    this._session.log.warning("Cannot place blocks outside of world bounds.");
                }
            }
        }
        onKeyEvent(state, dir, _operation) {
            const isExternal = !this.isActive();
            if (state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                if (isExternal) {
                    this.startNudgeFromExternalMode(_operation);
                } else {
                    this.startNudge(_operation);
                }
            }
            if (state === server_editor_namespaceObject.ContinuousActionState.Begin || state === server_editor_namespaceObject.ContinuousActionState.Repeat) {
                const newPos = lib.Vector3Utils.add(dir, this._currentLocation);
                this.updateNudge(newPos, NudgeUpdateOptions.UpdateWidgetPosition);
            }
            if (state === server_editor_namespaceObject.ContinuousActionState.End) {
                if (!lib.Vector3Utils.equals(this._currentLocation, this._originalLocation)) {
                    this.commitNudge();
                } else {
                    this.cancelNudge();
                }
            }
        }
        applyPayload(payload) {
            this.updateNudge(payload.visPosition, NudgeUpdateOptions.All);
        }
        setNudgeUIMode(uiMode) {
            const nonNudgeVisibility = uiMode === NudgeUIMode.Disabled;
            this._parent.widgetGroup.visible = nonNudgeVisibility;
            this._parent.setQuickActionsVisibility(nonNudgeVisibility);
            this._parent.setTrimActionsVisibility(nonNudgeVisibility);
            this._nudgeUI.setMode(uiMode);
        }
        initializeNudge(_mode) {
            const selectionVolumeContainer = this._session.extensionContext.selectionManager.volume;
            const selectionBox = selectionVolumeContainer.getBoundingBox();
            const selectionVolume = selectionVolumeContainer.get();
            this._clipboardItem.readFromWorld(selectionVolume);
            this._originalLocation = selectionBox.min;
            this._currentLocation = new lib.Vector3Builder(this._originalLocation);
            this._nudgeWidget.show(this._currentLocation, selectionBox, _mode);
        }
        shutdownNudge() {
            this._clipboardItem.clear();
            this._nudgeWidget.hide();
            this._activeOperationIsExternallyDriven = false;
        }
        updateNudgeEnabled() {
            const newValue = this.shouldBeEnabled();
            const currentValue = this._parent.isNudgeEnabled();
            if (currentValue !== newValue) {
                this._parent.setNudgeEnabled(newValue);
            }
        }
        willNewLocationBeValid(newPosition) {
            const currentBounds = this._worldBounds.getBounds(this._session.extensionContext.player.dimension);
            const newMax = lib.Vector3Utils.add(newPosition, this._clipboardItem.size);
            return server_namespaceObject.BlockBoundingBoxUtils.isInside(currentBounds, newPosition) && server_namespaceObject.BlockBoundingBoxUtils.isInside(currentBounds, newMax);
        }
    }
    class SelectionBehavior_InputModifierWatcher {
        constructor(_session, tool, _modifier) {
            this._isDown = false;
            const action = _session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.StatefulAction,
                onExecute: state => {
                    this._isDown = state;
                }
            });
            tool.registerKeyBinding(action, {
                key: _modifier,
                modifier: server_editor_namespaceObject.InputModifier.Any
            });
        }
        get isDown() {
            return this._isDown;
        }
    }
    const SelectionBehavior_PERSISTENCE_GROUP_NAME = "editor:selection";
    const SelectionBehavior_PERSISTENCE_GROUPITEM_NAME = "trim_settings";
    class SelectionBehavior {
        get toolId() {
            return this._tool.id;
        }
        get session() {
            return this.uiSession;
        }
        get tool() {
            return this._tool;
        }
        get telemetryManager() {
            return this._telemetryManager;
        }
        get widgetGroup() {
            return this._widgetGroup;
        }
        get transactionHandler() {
            return this._transactionHandler;
        }
        get boundingBoxColor() {
            return {
                outline: this._colorBoundingBoxOutline,
                hull: this._colorBoundingBoxHull
            };
        }
        get outlineBoxColor() {
            return {
                outline: this._colorOutlineBoxOutline,
                hull: this._colorOutlineBoxHull
            };
        }
        get isActiveTool() {
            return this.tool.isActive;
        }
        constructor(uiSession) {
            this.uiSession = uiSession;
            this._useSimpleSelectionMode = (0, server_editor_namespaceObject.makeObservable)(true);
            this._quickActionMode = (0, server_editor_namespaceObject.makeObservable)(SelectionCommonTypes_QuickActionMode.Invalid);
            this._volumeTrimActionMode = (0, server_editor_namespaceObject.makeObservable)(TrimActionMode.Invalid);
            this._volumeTrimIgnoreLiquid = (0, server_editor_namespaceObject.makeObservable)(true);
            this._volumeTrimOnlyCollision = (0, server_editor_namespaceObject.makeObservable)(true);
            this._lastSelectionCreationModeBeforeNonCreationMode = SelectionToolMode.Default;
            this._cleanupHandles = [];
            this._colorBoundingBoxOutline = createRGBAColorFromInts(239, 201, 24, 255);
            this._colorBoundingBoxHull = createRGBAColorFromInts(116, 243, 239, 33);
            this._colorOutlineBoxOutline = createRGBAColorFromInts(0, 255, 0, 255);
            this._colorOutlineBoxHull = createRGBAColorFromInts(116, 243, 239, 114);
            this._manifestCurrentKeys = new Set;
            this.shrinkVolume = (uiSession, direction) => {
                if (uiSession.extensionContext.selectionManager.volume.isEmpty) {
                    return;
                }
                const rotationY = uiSession.extensionContext.player.getRotation().y;
                this.selectionCreationMode?.shrinkVolumeAlongViewAxis(rotationY, direction);
            };
            this.growVolume = (uiSession, direction) => {
                if (uiSession.extensionContext.selectionManager.volume.isEmpty) {
                    return;
                }
                const rotationY = uiSession.extensionContext.player.getRotation().y;
                this.selectionCreationMode?.growVolumeAlongViewAxis(rotationY, direction);
            };
            this.bindToolInput = uiSession => {
                const singleClickAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                    onExecute: (mouseRay, mouseProps) => {
                        this.selectionCreationMode?.onMouseClickAndDrag(mouseRay, mouseProps, false);
                    }
                });
                this._tool.registerMouseButtonBinding(singleClickAction);
                const dragClickAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                    onExecute: (mouseRay, mouseProps) => {
                        this.selectionCreationMode?.onMouseClickAndDrag(mouseRay, mouseProps, false);
                    }
                });
                this._tool.registerMouseDragBinding(dragClickAction);
                const moveSelectionUpAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionMoveTop, {
                                direction: direction_Direction.Up
                            });
                            this.selectionCreationMode?.beginManualInputTranslateVolume();
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputTranslateVolume();
                            return;
                        }
                        const rotationY = uiSession.extensionContext.player.getRotation().y;
                        const correctedVector = getRotationCorrectedDirectionVector(rotationY, direction_Direction.Up);
                        this.selectionCreationMode?.manualInputTranslateVolume(correctedVector);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                const moveSelectionDownAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionMoveTop, {
                                direction: direction_Direction.Down
                            });
                            this.selectionCreationMode?.beginManualInputTranslateVolume();
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputTranslateVolume();
                            return;
                        }
                        const rotationY = uiSession.extensionContext.player.getRotation().y;
                        const correctedVector = getRotationCorrectedDirectionVector(rotationY, direction_Direction.Down);
                        this.selectionCreationMode?.manualInputTranslateVolume(correctedVector);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                const moveSelectionLeftAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionMoveTop, {
                                direction: direction_Direction.Left
                            });
                            this.selectionCreationMode?.beginManualInputTranslateVolume();
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputTranslateVolume();
                            return;
                        }
                        const rotationY = uiSession.extensionContext.player.getRotation().y;
                        const correctedVector = getRotationCorrectedDirectionVector(rotationY, direction_Direction.Left);
                        this.selectionCreationMode?.manualInputTranslateVolume(correctedVector);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                const moveSelectionRightAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionMoveTop, {
                                direction: direction_Direction.Right
                            });
                            this.selectionCreationMode?.beginManualInputTranslateVolume();
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputTranslateVolume();
                            return;
                        }
                        const rotationY = uiSession.extensionContext.player.getRotation().y;
                        const correctedVector = getRotationCorrectedDirectionVector(rotationY, direction_Direction.Right);
                        this.selectionCreationMode?.manualInputTranslateVolume(correctedVector);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                const moveSelectionForwardAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionMoveTop, {
                                direction: direction_Direction.Forward
                            });
                            this.selectionCreationMode?.beginManualInputTranslateVolume();
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputTranslateVolume();
                            return;
                        }
                        const rotationY = uiSession.extensionContext.player.getRotation().y;
                        const correctedVector = getRotationCorrectedDirectionVector(rotationY, direction_Direction.Forward);
                        this.selectionCreationMode?.manualInputTranslateVolume(correctedVector);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                const moveSelectionBackAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionMoveTop, {
                                direction: direction_Direction.Back
                            });
                            this.selectionCreationMode?.beginManualInputTranslateVolume();
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputTranslateVolume();
                            return;
                        }
                        const rotationY = uiSession.extensionContext.player.getRotation().y;
                        const correctedVector = getRotationCorrectedDirectionVector(rotationY, direction_Direction.Back);
                        this.selectionCreationMode?.manualInputTranslateVolume(correctedVector);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(moveSelectionForwardAction, {
                    key: Controls.Forward,
                    modifier: server_editor_namespaceObject.InputModifier.Alt
                }, "moveSelectionForward");
                this._registerToolKeyBinding(moveSelectionBackAction, {
                    key: Controls.Back,
                    modifier: server_editor_namespaceObject.InputModifier.Alt
                }, "moveSelectionBack");
                this._registerToolKeyBinding(moveSelectionLeftAction, {
                    key: Controls.Left,
                    modifier: server_editor_namespaceObject.InputModifier.Alt
                }, "moveSelectionLeft");
                this._registerToolKeyBinding(moveSelectionRightAction, {
                    key: Controls.Right,
                    modifier: server_editor_namespaceObject.InputModifier.Alt
                }, "moveSelectionRight");
                this._registerToolKeyBinding(moveSelectionUpAction, {
                    key: Controls.Up,
                    modifier: server_editor_namespaceObject.InputModifier.Alt
                }, "moveSelectionUp");
                this._registerToolKeyBinding(moveSelectionDownAction, {
                    key: Controls.Down,
                    modifier: server_editor_namespaceObject.InputModifier.Alt
                }, "moveSelectionDown");
                this._nudgeMoveControls = this._nudgeMode.buildNudgeHandler(NudgeOperation.Move, server_editor_namespaceObject.InputModifier.Alt | server_editor_namespaceObject.InputModifier.Shift);
                this._nudgeCopyControls = this._nudgeMode.buildNudgeHandler(NudgeOperation.Copy, server_editor_namespaceObject.InputModifier.Alt | server_editor_namespaceObject.InputModifier.Control);
                const keySelectAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        const selectionCreationMode = this.selectionCreationMode;
                        if (selectionCreationMode !== undefined) {
                            this.uiSession.extensionContext.selectionManager.volume.clear();
                            selectionCreationMode.applyImmediateSelection();
                        }
                    }
                });
                this._registerToolKeyBinding(keySelectAction, {
                    key: Controls.Select
                }, "select");
                const keySelectMultipleAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        this.selectionCreationMode?.applyImmediateSelection();
                    }
                });
                this._registerToolKeyBinding(keySelectMultipleAction, {
                    key: Controls.Select,
                    modifier: server_editor_namespaceObject.InputModifier.Shift
                }, "selectMultiple");
                const keyGrowUpAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(false);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionGrow, {
                                    direction: direction_Direction.Up
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.growVolume(uiSession, direction_Direction.Up);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyGrowUpAction, {
                    key: Controls.Up,
                    modifier: server_editor_namespaceObject.InputModifier.Shift
                }, "growUp");
                const keyGrowDownAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(false);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionGrow, {
                                    direction: direction_Direction.Down
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.growVolume(uiSession, direction_Direction.Down);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyGrowDownAction, {
                    key: Controls.Down,
                    modifier: server_editor_namespaceObject.InputModifier.Shift
                }, "growDown");
                const keyGrowForwardAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(false);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionGrow, {
                                    direction: direction_Direction.Forward
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.growVolume(uiSession, direction_Direction.Forward);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyGrowForwardAction, {
                    key: Controls.Forward,
                    modifier: server_editor_namespaceObject.InputModifier.Shift
                }, "growForward");
                const keyGrowBackAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(false);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionGrow, {
                                    direction: direction_Direction.Back
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.growVolume(uiSession, direction_Direction.Back);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyGrowBackAction, {
                    key: Controls.Back,
                    modifier: server_editor_namespaceObject.InputModifier.Shift
                }, "growBack");
                const keyGrowLeftAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(false);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionGrow, {
                                    direction: direction_Direction.Left
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.growVolume(uiSession, direction_Direction.Left);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyGrowLeftAction, {
                    key: Controls.Left,
                    modifier: server_editor_namespaceObject.InputModifier.Shift
                }, "growLeft");
                const keyGrowRightAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(false);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionGrow, {
                                    direction: direction_Direction.Right
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.growVolume(uiSession, direction_Direction.Right);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyGrowRightAction, {
                    key: Controls.Right,
                    modifier: server_editor_namespaceObject.InputModifier.Shift
                }, "growRight");
                const keyShrinkUpAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(true);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionShrink, {
                                    direction: direction_Direction.Up
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.shrinkVolume(uiSession, direction_Direction.Up);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyShrinkUpAction, {
                    key: Controls.Up,
                    modifier: server_editor_namespaceObject.InputModifier.Control
                }, "shrinkUp");
                const keyShrinkDownAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(true);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionShrink, {
                                    direction: direction_Direction.Down
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.shrinkVolume(uiSession, direction_Direction.Down);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyShrinkDownAction, {
                    key: Controls.Down,
                    modifier: server_editor_namespaceObject.InputModifier.Control
                }, "shrinkDown");
                const keyShrinkForwardAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(true);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionShrink, {
                                    direction: direction_Direction.Forward
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.shrinkVolume(uiSession, direction_Direction.Forward);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyShrinkForwardAction, {
                    key: Controls.Forward,
                    modifier: server_editor_namespaceObject.InputModifier.Control
                }, "shrinkForward");
                const keyShrinkBackAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(true);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionShrink, {
                                    direction: direction_Direction.Back
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.shrinkVolume(uiSession, direction_Direction.Back);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyShrinkBackAction, {
                    key: Controls.Back,
                    modifier: server_editor_namespaceObject.InputModifier.Control
                }, "shrinkBack");
                const keyShrinkLeftAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(true);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionShrink, {
                                    direction: direction_Direction.Left
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.shrinkVolume(uiSession, direction_Direction.Left);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyShrinkLeftAction, {
                    key: Controls.Left,
                    modifier: server_editor_namespaceObject.InputModifier.Control
                }, "shrinkLeft");
                const keyShrinkRightAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                    onExecute: _state => {
                        if (_state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                            const first = this.selectionCreationMode?.beginManualInputResizeVolume(true);
                            if (first) {
                                this.telemetryManager.fireTelemetryEvent(SelectionTelemetry.SelectionShrink, {
                                    direction: direction_Direction.Right
                                });
                            }
                        }
                        if (_state === server_editor_namespaceObject.ContinuousActionState.End) {
                            this.selectionCreationMode?.endManualInputResizeVolume();
                            return;
                        }
                        this.shrinkVolume(uiSession, direction_Direction.Right);
                    },
                    repeatInterval: SelectionCommonTypes_KEY_REPEAT_INTERVAL,
                    repeatDelay: SelectionCommonTypes_KEY_REPEAT_DELAY
                });
                this._registerToolKeyBinding(keyShrinkRightAction, {
                    key: Controls.Right,
                    modifier: server_editor_namespaceObject.InputModifier.Control
                }, "shrinkRight");
            };
            this.addDeselectAndFillMenuItems = uiSession => {
                uiSession.scratchStorage?.coreMenuItems?.edit.addItem({
                    label: "resourcePack.editor.menuBar.edit.deselect",
                    tooltip: "resourcePack.editor.menuBar.edit.deselect.tooltip"
                }, this._deselectAction);
                uiSession.scratchStorage?.coreMenuItems?.edit.addItem({
                    label: "resourcePack.editor.menuBar.edit.quickFill",
                    tooltip: "resourcePack.editor.menuBar.edit.quickFill.tooltip"
                }, this._executeFillAction);
            };
            this._addModeSelectionControls = (_uiSession, _parentPane) => {
                this._modeToggleGroup = _parentPane.addToggleGroup(this._selectionMode, {
                    title: "resourcePack.editor.selectionTool.modeSelection.title",
                    tooltip: "resourcePack.editor.selectionTool.modeSelection.tooltip",
                    hiddenLabel: false,
                    entries: this.buildToggleGroupEntries(this._nudgeMode.shouldBeEnabled()),
                    onChange: (_newValue, _oldValue) => {
                        const clearSelection = SelectionBehavior.isSelectionCreationMode(_newValue);
                        this._switchSelectionMode(_newValue, true, clearSelection);
                    }
                });
                this._nudgeMode.addNudgeUI(_parentPane);
                this._nudgeMode.updateNudgeEnabled();
                this._quickActionsDivider = _parentPane.addDivider();
                this._simpleSelectionCheckBox = _parentPane.addBool(this._useSimpleSelectionMode, {
                    visible: false,
                    title: "resourcePack.editor.selectionTool.modeSelection.useSimpleSelection.title",
                    tooltip: "resourcePack.editor.selectionTool.modeSelection.useSimpleSelection.tooltip",
                    onChange: () => {
                        this._saveTrimSettings();
                    }
                });
                this._quickActionsUI = _parentPane.addToggleGroup(this._quickActionMode, {
                    title: "resourcePack.editor.selectionTool.quickAction.title",
                    tooltip: "resourcePack.editor.selectionTool.quickAction.tooltip",
                    hiddenLabel: false,
                    entries: [ {
                        value: SelectionCommonTypes_QuickActionMode.DeselectSelection,
                        label: {
                            id: "resourcePack.editor.selectionTool.quickAction.clearSelection",
                            props: [ getInputMarkup("editor:toolModeKeyBinding:deselectSelection") ]
                        },
                        icon: "marqueeRemoveIcon",
                        tooltip: "resourcePack.editor.selectionTool.quickAction.clearSelection.tooltip"
                    }, {
                        value: SelectionCommonTypes_QuickActionMode.FillSelection,
                        label: {
                            id: "resourcePack.editor.selectionTool.quickAction.fillSelection",
                            props: [ getInputMarkup("editor:toolModeKeyBinding:fillSelection") ]
                        },
                        icon: "fillIcon",
                        tooltip: "resourcePack.editor.selectionTool.quickAction.fillSelection.tooltip"
                    }, {
                        value: SelectionCommonTypes_QuickActionMode.DeleteSelection,
                        label: {
                            id: "resourcePack.editor.selectionTool.quickAction.deleteSelection",
                            props: [ getInputMarkup("editor:toolModeKeyBinding:delete") ]
                        },
                        icon: "trashCanIcon",
                        tooltip: "resourcePack.editor.selectionTool.quickAction.deleteSelection.tooltip"
                    } ],
                    onChange: _newValue => {
                        this._quickActionMode.set(SelectionCommonTypes_QuickActionMode.Invalid);
                        switch (_newValue) {
                          case SelectionCommonTypes_QuickActionMode.DeselectSelection:
                            this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.QuickAction, {
                                action: SelectionTelemetry.Deselect
                            });
                            this.clearSelection();
                            break;

                          case SelectionCommonTypes_QuickActionMode.FillSelection:
                            {
                                this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.QuickAction, {
                                    action: SelectionTelemetry.FillSelection
                                });
                                this._executeFillAction.onExecute();
                            }
                            break;

                          case SelectionCommonTypes_QuickActionMode.DeleteSelection:
                            {
                                const blockType = server_namespaceObject.BlockTypes.get(lib_vanilla_MinecraftBlockTypes.Air);
                                if (!blockType) {
                                    return;
                                }
                                this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.QuickAction, {
                                    action: SelectionTelemetry.DeleteSelection
                                });
                                this.performDeleteOperation(this.uiSession).catch((e => this.uiSession.log.error(e.message, {
                                    channelMask: server_editor_namespaceObject.LogChannel.All
                                })));
                            }
                            break;
                        }
                    }
                });
            };
            this._addVolumeTrimActionControls = (_uiSession, _parentPane) => {
                this._volumeTrimActionsPane = _parentPane.createSubPane({
                    title: "Hidden Volume Trim Action Pane",
                    hasExpander: false
                });
                const trimVolumeAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        if (this.session.extensionContext.selectionManager.volume.isEmpty) {
                            this.session.log.warning("resourcePack.editor.selectionTool.toast.trimSelection.noSelection", {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                            return;
                        }
                        this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.QuickAction, {
                            action: SelectionTelemetry.TrimVolume
                        });
                        this._performTrimOperation(this.uiSession, this.uiSession.extensionContext).catch((e => this.uiSession.log.error(e.message, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        })));
                    }
                });
                const trimAirAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        if (this.session.extensionContext.selectionManager.volume.isEmpty) {
                            this.session.log.warning("resourcePack.editor.selectionTool.toast.removeAir.noSelection", {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                            return;
                        }
                        this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.QuickAction, {
                            action: SelectionTelemetry.RemoveAir
                        });
                        this._performRemoveAirOperation(this.uiSession, this.uiSession.extensionContext).catch((e => this.uiSession.log.error(e.message, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        })));
                    }
                });
                const trimHollowAction = this.session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        if (this.session.extensionContext.selectionManager.volume.isEmpty) {
                            this.session.log.warning("resourcePack.editor.selectionTool.toast.hollow.noSelection", {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                            return;
                        }
                        this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.QuickAction, {
                            action: SelectionTelemetry.HollowVolume
                        });
                        this._performHollowOperation(this.uiSession, this.uiSession.extensionContext).catch((e => this.uiSession.log.error(e.message, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        })));
                    }
                });
                this._volumeTrimActionsPane.addToggleGroup(this._volumeTrimActionMode, {
                    title: "resourcePack.editor.selectionTool.trimAction.title",
                    tooltip: "resourcePack.editor.selectionTool.trimAction.tooltip",
                    hiddenLabel: false,
                    entries: [ {
                        value: TrimActionMode.TrimVolume,
                        label: "resourcePack.editor.selectionTool.trimAction.trimVolume",
                        icon: "objectIcon",
                        tooltip: "resourcePack.editor.selectionTool.trimAction.trimVolume.tooltip"
                    }, {
                        value: TrimActionMode.RemoveAir,
                        label: "resourcePack.editor.selectionTool.trimAction.removeAir",
                        icon: "scaleIcon",
                        tooltip: "resourcePack.editor.selectionTool.trimAction.removeAir.tooltip"
                    }, {
                        value: TrimActionMode.Hollow,
                        label: "resourcePack.editor.selectionTool.trimAction.trimHollow",
                        icon: "enderEyeIcon",
                        tooltip: "resourcePack.editor.selectionTool.trimAction.trimHollow.tooltip"
                    } ],
                    onChange: (_newValue, _oldValue) => {
                        this._volumeTrimActionMode.set(TrimActionMode.Invalid);
                        switch (_newValue) {
                          case TrimActionMode.TrimVolume:
                            trimVolumeAction.onExecute();
                            break;

                          case TrimActionMode.RemoveAir:
                            trimAirAction.onExecute();
                            break;

                          case TrimActionMode.Hollow:
                            trimHollowAction.onExecute();
                            break;
                        }
                    }
                });
                this._registerToolKeyBinding(trimVolumeAction, {
                    key: server_editor_namespaceObject.KeyboardKey.UNDEFINED
                }, "trimVolume");
                this._registerToolKeyBinding(trimAirAction, {
                    key: server_editor_namespaceObject.KeyboardKey.UNDEFINED
                }, "trimRemoveAir");
                this._registerToolKeyBinding(trimHollowAction, {
                    key: server_editor_namespaceObject.KeyboardKey.UNDEFINED
                }, "trimHollow");
                this._volumeTrimActionsSettingsPane = this._volumeTrimActionsPane.createSubPane({
                    title: "resourcePack.editor.selectionTool.trimAction.trimVolume.SettingsPane.title",
                    infoTooltip: {
                        title: "resourcePack.editor.selectionTool.trimAction.trimVolume.SettingsPane.title",
                        description: [ "resourcePack.editor.selectionTool.trimAction.trimVolume.SettingsPane.tooltip" ]
                    },
                    hasExpander: true,
                    collapsed: true,
                    hasMargins: false
                });
                const ignoreLiquidUIElement = this._volumeTrimActionsSettingsPane.addBool(this._volumeTrimIgnoreLiquid, {
                    title: "resourcePack.editor.selectionTool.trimAction.trimVolume.SettingsPane.ignoreLiquid",
                    tooltip: "resourcePack.editor.selectionTool.trimAction.trimVolume.SettingsPane.ignoreLiquid.tooltip",
                    variant: server_editor_namespaceObject.BoolPropertyItemVariant.ToggleSwitch,
                    onChange: () => {
                        this._saveTrimSettings();
                    }
                });
                const collisionOnlyUIElement = this._volumeTrimActionsSettingsPane.addBool(this._volumeTrimOnlyCollision, {
                    title: "resourcePack.editor.selectionTool.trimAction.trimVolume.SettingsPane.onlyCollidable",
                    tooltip: "resourcePack.editor.selectionTool.trimAction.trimVolume.SettingsPane.onlyCollidable.tooltip",
                    variant: server_editor_namespaceObject.BoolPropertyItemVariant.ToggleSwitch,
                    onChange: () => {
                        this._saveTrimSettings();
                    }
                });
                this._blockMaskSharedControl = new BlockMaskSharedControl(this.session, this.tool, this._volumeTrimActionsSettingsPane, "trim", (_mode => {
                    if (_mode === BlockMaskControlMaskMode.Disabled) {
                        ignoreLiquidUIElement.enable = true;
                        collisionOnlyUIElement.enable = true;
                    } else {
                        ignoreLiquidUIElement.enable = false;
                        collisionOnlyUIElement.enable = false;
                    }
                }));
                this._blockMaskSharedControl.initialize();
                this._blockMaskSharedControl.activateControl();
            };
            this._addManifestGenerationControls = (_uiSession, _parentPane) => {
                this._manifestPane = _parentPane.createSubPane({
                    title: "resourcePack.editor.selectionTool.blockManifest.title",
                    infoTooltip: {
                        title: "resourcePack.editor.selectionTool.blockManifest.title",
                        description: [ "resourcePack.editor.selectionTool.blockManifest.tooltip" ]
                    },
                    hasExpander: true,
                    collapsed: false,
                    hasMargins: true
                });
                const generateManifestAction = () => {
                    if (this.session.extensionContext.selectionManager.volume.isEmpty) {
                        this.session.log.warning("resourcePack.editor.selectionTool.toast.noSelection.title", {
                            channelMask: server_editor_namespaceObject.LogChannel.Toast,
                            subMessage: "resourcePack.editor.selectionTool.toast.noSelection.description"
                        });
                        return;
                    }
                    void this._startManifestGeneration();
                };
                this._manifestPane.addButton(generateManifestAction, {
                    title: "resourcePack.editor.selectionTool.blockManifest.button.generateManifest.title",
                    tooltip: "resourcePack.editor.selectionTool.blockManifest.button.generateManifest.tooltip"
                });
                this._manifestProgressIndicator = this._manifestPane.addProgressIndicator({
                    title: "resourcePack.editor.selectionTool.blockManifest.progressIndicator.generatingManifest"
                });
                this._manifestProgressIndicator.visible = false;
                this._manifestBlockTable = this._manifestPane.addBlockTable({
                    entries: new Map,
                    title: "resourcePack.editor.selectionTool.blockManifest.blockTable.title",
                    tooltip: "resourcePack.editor.selectionTool.blockManifest.blockTable.tooltip",
                    enable: false,
                    visible: false,
                    onOperationClick: (block, operation) => {
                        this.session.log.debug(`Block operation: ${operation} on ${block}`);
                        if (operation === "deselect") {
                            void this._handleDeselectBlock(block);
                        } else if (operation === "replace") {
                            void this._handleReplaceBlock(block);
                        }
                    }
                });
            };
            this._addTool = (uiSession, action) => {
                const tool = uiSession.toolRail.addTool(SelectionBehavior.MODAL_TOOL_ID, {
                    title: "resourcePack.editor.selectionTool.toolRail.title",
                    icon: "pack://textures/editor/marquee.png?filtering=point",
                    tooltip: {
                        description: "resourcePack.editor.selectionTool.toolRail.description",
                        image: "pack://textures/editor/Selection.gif"
                    },
                    action
                });
                return tool;
            };
            this._bindGlobalActivationShortcut = uiSession => {
                uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, this._toggleAction, {
                    key: server_editor_namespaceObject.KeyboardKey.KEY_S,
                    modifier: server_editor_namespaceObject.InputModifier.Control
                }, {
                    uniqueId: "editor:toolModeKeyBinding:toggleSelection",
                    label: "resourcePack.editor.selectionTool.keyBinding.toggleTool.title",
                    tooltip: "resourcePack.editor.selectionTool.keyBinding.toggleTool.tooltip"
                });
                this._fillActionBarItem = uiSession.actionBar.registerItem(server_editor_namespaceObject.CoreActionBarItemType.Fill, this._executeFillAction, {
                    label: "resourcePack.editor.actionBar.fill",
                    icon: "pack://textures/editor/Fill.png",
                    tooltipTitle: "resourcePack.editor.actionBar.fill.tooltipTitle",
                    tooltipDescription: "resourcePack.editor.actionBar.fill.tooltipDescription",
                    enabled: !uiSession.extensionContext.selectionManager.volume.isEmpty
                });
                uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, this._executeFillAction, {
                    key: server_editor_namespaceObject.KeyboardKey.KEY_F,
                    modifier: server_editor_namespaceObject.InputModifier.Control
                }, {
                    uniqueId: "editor:toolModeKeyBinding:fillSelection",
                    label: "resourcePack.editor.selectionTool.keyBinding.fill.title",
                    tooltip: "resourcePack.editor.selectionTool.keyBinding.fill.tooltip"
                });
                uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, this._deselectAction, {
                    key: server_editor_namespaceObject.KeyboardKey.KEY_D,
                    modifier: server_editor_namespaceObject.InputModifier.Control
                }, {
                    uniqueId: "editor:toolModeKeyBinding:deselectSelection",
                    label: "resourcePack.editor.selectionTool.keyBinding.deselect.title",
                    tooltip: "resourcePack.editor.selectionTool.keyBinding.deselect.tooltip"
                });
                const switchToNudge = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        if (this._nudgeMode.shouldBeEnabled()) {
                            this._switchSelectionMode(SelectionToolMode.Nudge, true, false);
                        }
                    }
                });
                this._tool.registerKeyBinding(switchToNudge, {
                    key: server_editor_namespaceObject.KeyboardKey.KEY_N
                }, {
                    uniqueId: "editor:toolModeKeyBinding:quickMoveMode",
                    label: "resourcePack.editor.selectionTool.keyBinding.quickMoveMode.title",
                    tooltip: "resourcePack.editor.selectionTool.keyBinding.quickMoveMode.tooltip"
                });
            };
            this._performFillOperation = async (session, context) => {
                if (context.selectionManager.volume.isEmpty) {
                    session.log.warning("resourcePack.editor.selectionTool.toast.fill.noSelection", {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    return;
                }
                const onError = e => {
                    session.log.error(`Fill operation failed with error: ${e.message}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                };
                const volume = context.selectionManager.volume.get();
                await executeFunctionWithTransactionAndTicking(session.extensionContext, session.log, volume, "Select-Fill", (() => {
                    session.extensionContext.blockUtilities.fillVolume(volume);
                })).catch(onError);
            };
            this._internalChangeVolumeContentsNotification = () => {
                this._marqueeModeImplementation?.onExternalSelectionChanged({});
                this._freehandModeImplementation?.onExternalSelectionChanged({});
                this._magicModeImplementation?.onExternalSelectionChanged({});
                if (!SelectionBehavior.isSelectionCreationMode(this._selectionMode.value)) {
                    return;
                }
                if (this.session.extensionContext.selectionManager.volume.volumeCount <= 1) {
                    if (this._selectionMode.value !== SelectionToolMode.Marquee) {
                        this._switchSelectionMode(SelectionToolMode.Marquee, true, false);
                    }
                } else if (this.session.extensionContext.selectionManager.volume.volumeCount > 1) {
                    if (this._selectionMode.value !== SelectionToolMode.Freehand) {
                        this._switchSelectionMode(SelectionToolMode.Freehand, true, false);
                    }
                }
            };
            this.performDeleteOperation = async session => {
                await deleteOperation(session);
            };
            this._startManifestGeneration = async () => {
                this._clearBlockTable();
                if (this._manifestProgressIndicator) {
                    this._manifestProgressIndicator.visible = true;
                }
                try {
                    const manifest = await this.session.extensionContext.selectionManager.generateManifest();
                    if (this._manifestProgressIndicator) {
                        this._manifestProgressIndicator.visible = false;
                    }
                    if (this._manifestBlockTable) {
                        this._manifestBlockTable.visible = true;
                        this._manifestBlockTable.enable = true;
                    }
                    this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.ManifestGeneration, {
                        totalBlocks: manifest.totalBlocks,
                        uniqueBlockTypes: manifest.entries?.length || 0,
                        success: true
                    });
                    if (manifest.entries && manifest.entries.length > 0) {
                        this._renderBlockTable(manifest.entries);
                    }
                } catch (err) {
                    this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.ManifestGeneration, {
                        totalBlocks: 0,
                        uniqueBlockTypes: 0,
                        success: false
                    });
                    this.session.log.error(`Manifest generation failed: ${err.message}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    if (this._manifestProgressIndicator) {
                        this._manifestProgressIndicator.visible = false;
                    }
                }
            };
            this._renderBlockTable = entries => {
                if (!this._manifestBlockTable) {
                    return;
                }
                if (this._manifestCurrentKeys.size > 0) {
                    for (const key of this._manifestCurrentKeys) {
                        try {
                            this._manifestBlockTable.deleteEntry(key);
                        } catch (_err) {}
                    }
                    this._manifestCurrentKeys.clear();
                }
                for (const {blockIdentifier, count} of entries) {
                    try {
                        const displayId = blockIdentifier.startsWith("minecraft:") ? blockIdentifier.substring(10) : blockIdentifier;
                        this._manifestBlockTable.addOrUpdateEntry(displayId, {
                            count
                        });
                        this._manifestCurrentKeys.add(displayId);
                    } catch (_e) {
                        const displayId = blockIdentifier.startsWith("minecraft:") ? blockIdentifier.substring(10) : blockIdentifier;
                        this._manifestBlockTable.addOrUpdateEntry(displayId, {
                            count
                        });
                        this._manifestCurrentKeys.add(displayId);
                    }
                }
            };
            this._clearBlockTable = () => {
                if (!this._manifestBlockTable) return;
                this._manifestBlockTable.visible = false;
                this._manifestBlockTable.enable = false;
                if (this._manifestCurrentKeys.size > 0) {
                    for (const key of this._manifestCurrentKeys) {
                        try {
                            this._manifestBlockTable.deleteEntry(key);
                        } catch (_err) {}
                    }
                    this._manifestCurrentKeys.clear();
                }
            };
            this._handleDeselectBlock = async blockId => {
                if (!blockId) {
                    this.session.log.warning("No block ID provided for deselect operation");
                    return;
                }
                if (this._manifestProgressIndicator) {
                    this._manifestProgressIndicator.visible = true;
                }
                try {
                    const fullBlockId = blockId.includes(":") ? blockId : `minecraft:${blockId}`;
                    this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.QuickAction, {
                        action: "DeselectBlocks"
                    });
                    const blocksRemoved = await this.session.extensionContext.selectionManager.deselectBlocks(fullBlockId);
                    this.session.log.info(`Removed ${blocksRemoved} block${blocksRemoved !== 1 ? "s" : ""} of type ${blockId}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.Toast
                    });
                    await this._startManifestGeneration();
                } catch (err) {
                    this.session.log.error(`Deselect operation failed: ${err.message}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                } finally {
                    if (this._manifestProgressIndicator) {
                        this._manifestProgressIndicator.visible = false;
                    }
                }
            };
            this._handleReplaceBlock = async blockId => {
                if (!blockId) {
                    this.session.log.warning("No block ID provided for replace operation");
                    return;
                }
                const newBlockId = await this._showBlockPickerForReplace();
                if (!newBlockId) {
                    return;
                }
                if (this._manifestProgressIndicator) {
                    this._manifestProgressIndicator.visible = true;
                }
                try {
                    const fullBlockId = blockId.includes(":") ? blockId : `minecraft:${blockId}`;
                    const fullNewBlockId = newBlockId.includes(":") ? newBlockId : `minecraft:${newBlockId}`;
                    this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.QuickAction, {
                        action: "ReplaceBlocks"
                    });
                    const blocksReplaced = await this.session.extensionContext.selectionManager.replaceBlocks(fullBlockId, fullNewBlockId);
                    this.session.log.info(`Replaced ${blocksReplaced} block${blocksReplaced !== 1 ? "s" : ""} from ${blockId} to ${newBlockId}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.Toast
                    });
                    await this._startManifestGeneration();
                } catch (err) {
                    this.session.log.error(`Replace operation failed: ${err.message}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                } finally {
                    if (this._manifestProgressIndicator) {
                        this._manifestProgressIndicator.visible = false;
                    }
                }
            };
            this._showBlockPickerForReplace = () => new Promise((resolve => {
                this.session.dialogManager.activateDialog({
                    dialogId: server_editor_namespaceObject.CoreModalDialogType.DataPicker,
                    data: {
                        default: "stone",
                        variant: server_editor_namespaceObject.DataPickerModalDialogVariant.Block
                    },
                    onResponse: resp => {
                        if (resp.type === server_editor_namespaceObject.ModalDialogResponseType.Confirm) {
                            resolve(resp.selected);
                        } else {
                            resolve(undefined);
                        }
                    }
                });
            }));
            const storage = uiSession.scratchStorage;
            if (!storage) {
                throw new Error("Can not instantiate Selection functionality without valid CoreEditor storage.");
            }
            this._persistenceManager = getPersistenceManager(this.session.extensionContext.player);
            this._loadTrimSettings();
            this._telemetryManager = new TelemetryManager(uiSession.extensionContext.player, TelemetrySource.Selection);
            this._selectionMode = (0, server_editor_namespaceObject.makeObservable)(SelectionToolMode.Marquee);
            this._widgetGroup = this.session.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.None,
                visible: true
            });
            this._toolCursorProperties = {
                outlineColor: {
                    red: 1,
                    green: 1,
                    blue: 0,
                    alpha: 1
                },
                controlMode: server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse,
                targetMode: server_editor_namespaceObject.CursorTargetMode.Block,
                visible: true
            };
            this._colorBoundingBoxHull = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeFill);
            this._colorBoundingBoxOutline = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeBorder);
            this._colorOutlineBoxHull = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeOutlineFill);
            this._colorOutlineBoxOutline = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeOutlineBorder);
            this.debugLog(`Selection Tool initialized with colors:`);
            this.debugLog(`  BoundingBox Hull:${JSON.stringify(this._colorBoundingBoxHull)}, Outline:${JSON.stringify(this._colorBoundingBoxOutline)}`);
            this.debugLog(`  OutlineBox Hull:${JSON.stringify(this._colorOutlineBoxHull)}, Outline:${JSON.stringify(this._colorOutlineBoxOutline)}`);
            const themeChangeEventHandle = uiSession.extensionContext.afterEvents.currentThemeColorChange.subscribe((_event => {
                switch (_event.colorKey) {
                  case server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeFill:
                    this._colorBoundingBoxHull = _event.color;
                    this.selectionCreationMode?.onColorChangeEvent();
                    break;

                  case server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeBorder:
                    this._colorBoundingBoxOutline = _event.color;
                    this.selectionCreationMode?.onColorChangeEvent();
                    break;

                  case server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeOutlineFill:
                    this._colorOutlineBoxHull = _event.color;
                    this.selectionCreationMode?.onColorChangeEvent();
                    break;

                  case server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeOutlineBorder:
                    this._colorOutlineBoxOutline = _event.color;
                    this.selectionCreationMode?.onColorChangeEvent();
                    break;
                }
            }));
            this._cleanupHandles.push((() => uiSession.extensionContext.afterEvents.currentThemeColorChange.unsubscribe(themeChangeEventHandle)));
            this._transactionHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(this.session.extensionContext.transactionManager, (_payload => {
                const oldStack = _payload.oldVolumeStack;
                this._switchSelectionMode(oldStack.mode, true, true);
                this.selectionCreationMode?.applyUndo(oldStack);
            }), (_payload => {
                const newStack = _payload.newVolumeStack;
                this._switchSelectionMode(newStack.mode, true, true);
                this.selectionCreationMode?.applyRedo(newStack);
            }));
            this._toggleAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._tool.isActive) {
                        this.cycleSelectionMode();
                    } else {
                        uiSession.toolRail.setSelectedToolId(this._tool.id);
                    }
                }
            });
            this._executeFillAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.FillSelection);
                    this._performFillOperation(uiSession, uiSession.extensionContext).catch((e => uiSession.log.error(e.message, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    })));
                }
            });
            this._deselectAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.Deselect);
                    this.clearSelection();
                }
            });
            this._tool = this._addTool(uiSession, this._toggleAction);
            this._rootPane = uiSession.createPropertyPane({
                title: "resourcePack.editor.selectionTool.settingsPane.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.selectionTool.toolRail.description", {
                        link: "https://aka.ms/BedrockEditorSelection",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this._tool.bindPropertyPane(this._rootPane);
            this._nudgeMode = new NudgeSelectionToolMode(this.session, this);
            this._addModeSelectionControls(uiSession, this._rootPane);
            this._trimActionsDivider = this._rootPane.addDivider();
            this._addVolumeTrimActionControls(uiSession, this._rootPane);
            this._rootPane.addDivider();
            this._addCursorControls(uiSession, this._rootPane);
            this._rootPane.addDivider();
            this._addManifestGenerationControls(uiSession, this._rootPane);
            this._rootPane.addDivider();
            this._modeHolderPane = this._rootPane.createSubPane({
                title: "Hidden Mode Holder Pane",
                hasExpander: false
            });
            this._marqueeModeImplementation = new SelectionModeMarquee(this._modeHolderPane, this);
            this._freehandModeImplementation = new SelectionModeFreehand(this._modeHolderPane, this);
            this._magicModeImplementation = new SelectionModeMagic(this._modeHolderPane, this);
            this._activeModeImplementation = this._marqueeModeImplementation;
            this._activeModeImplementation.activate(true);
            this._selectionMode.set(SelectionToolMode.Marquee);
            this._tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    if (this.session.extensionContext.selectionManager.volume.volumeCount <= 1) {
                        if (this._selectionMode.value !== SelectionToolMode.Marquee) {
                            this._switchSelectionMode(SelectionToolMode.Marquee, false, false);
                        } else {
                            this._activeModeImplementation?.activate(true);
                        }
                    } else if (this.session.extensionContext.selectionManager.volume.volumeCount > 1) {
                        if (this._selectionMode.value === SelectionToolMode.Marquee) {
                            this._switchSelectionMode(SelectionToolMode.Freehand, false, false);
                        } else {
                            this._activeModeImplementation?.activate(true);
                        }
                    } else {
                        this._activeModeImplementation?.activate(true);
                    }
                    this._cursorModeSharedControl?.activateControl();
                } else {
                    this._activeModeImplementation?.deactivate(true, false);
                    this._cursorModeSharedControl?.deactivateControl();
                }
            }));
            this.bindToolInput(uiSession);
            this._bindGlobalActivationShortcut(uiSession);
            server_namespaceObject.system.runTimeout((() => uiSession.toolRail.setSelectedToolId(this._tool.id)));
            const selectionChangeEventHandle = uiSession.extensionContext.afterEvents.SelectionChange.subscribe((event => {
                if (!this._tool.isActive) {
                    if (event.volumeEventData) {
                        let type = "";
                        switch (event.volumeEventData.type) {
                          case server_editor_namespaceObject.SelectionVolumeEventType.Add:
                            type = "Add";
                            break;

                          case server_editor_namespaceObject.SelectionVolumeEventType.Remove:
                            type = "Remove";
                            break;

                          case server_editor_namespaceObject.SelectionVolumeEventType.Set:
                            type = "Set";
                            break;

                          case server_editor_namespaceObject.SelectionVolumeEventType.Clear:
                            type = "Clear";
                            break;

                          case server_editor_namespaceObject.SelectionVolumeEventType.Translate:
                            type = "Translate";
                            break;

                          case server_editor_namespaceObject.SelectionVolumeEventType.Move:
                            type = "Move";
                            break;
                        }
                        this.debugLog(`Selection was changed!! (${type})`);
                        this._internalChangeVolumeContentsNotification();
                    }
                }
                this._clearBlockTable();
                const enableFill = !uiSession.extensionContext.selectionManager.volume.isEmpty;
                if (this._fillActionBarItem && enableFill !== this._fillActionBarItem.getEnabled()) {
                    this._fillActionBarItem.setEnabled(enableFill);
                }
            }));
            this._cleanupHandles.push((() => uiSession.extensionContext.afterEvents.SelectionChange.unsubscribe(selectionChangeEventHandle)));
            this.uiSession.eventSubscriptionCache.subscribeToBedrockEvent("playerDimensionChange", (event => {
                if (event.player.id === uiSession.extensionContext.player.id) {
                    uiSession.extensionContext.selectionManager.volume.clear();
                    this._marqueeModeImplementation.onDimensionChange();
                    this._freehandModeImplementation.onDimensionChange();
                    this._magicModeImplementation.onDimensionChange();
                }
            }));
            this._altWatcher = new SelectionBehavior_InputModifierWatcher(this.session, this.tool, server_editor_namespaceObject.KeyboardKey.ALT);
            this._shiftWatcher = new SelectionBehavior_InputModifierWatcher(this.session, this.tool, server_editor_namespaceObject.KeyboardKey.SHIFT);
            this._ctrlWatcher = new SelectionBehavior_InputModifierWatcher(this.session, this.tool, server_editor_namespaceObject.KeyboardKey.CTRL);
        }
        get selectionCreationMode() {
            return this._activeModeImplementation?.isSelectionCreationMode() ? this._activeModeImplementation : undefined;
        }
        performSingleTransactionableOperation(_operation, _name) {
            if (this._temporaryTransactionData !== undefined) {
                throw new Error("Cannot perform a transactionable operation while a transaction is active");
            }
            if (this.selectionCreationMode === undefined) {
                throw new Error("Cannot perform a transactionable operation while no mode is active");
            }
            this._temporaryTransactionData = {
                oldVolumeStack: {
                    mode: SelectionToolMode.Marquee,
                    volumes: []
                },
                newVolumeStack: {
                    mode: SelectionToolMode.Marquee,
                    volumes: []
                },
                name: _name
            };
            this.selectionCreationMode?.fillTransactionPayload(this._temporaryTransactionData.oldVolumeStack);
            try {
                const completedOK = _operation();
                if (!completedOK) {
                    throw new Error("Operation failed");
                }
                this.selectionCreationMode?.fillTransactionPayload(this._temporaryTransactionData.newVolumeStack);
                this.createTransaction(this._temporaryTransactionData, _name);
                this._temporaryTransactionData = undefined;
            } catch (_e) {
                this._temporaryTransactionData = undefined;
            }
        }
        beginTransactionableOperation(_name) {
            if (this._temporaryTransactionData !== undefined) {
                throw new Error("Cannot begin a transactionable operation while a transaction is active");
            }
            if (this.selectionCreationMode === undefined) {
                throw new Error("Cannot begin a transactionable operation while no mode is active");
            }
            this._temporaryTransactionData = {
                oldVolumeStack: {
                    mode: SelectionToolMode.Marquee,
                    volumes: []
                },
                newVolumeStack: {
                    mode: SelectionToolMode.Marquee,
                    volumes: []
                },
                name: _name
            };
            this.selectionCreationMode?.fillTransactionPayload(this._temporaryTransactionData.oldVolumeStack);
        }
        endTransactionableOperation() {
            if (this._temporaryTransactionData === undefined) {
                throw new Error("Cannot end a transactionable operation without a begin");
            }
            if (this.selectionCreationMode === undefined) {
                throw new Error("Cannot end a transactionable operation while no mode is active");
            }
            this.selectionCreationMode?.fillTransactionPayload(this._temporaryTransactionData.newVolumeStack);
            this.createTransaction(this._temporaryTransactionData, this._temporaryTransactionData.name ?? "Selection (unnamed)");
            this._temporaryTransactionData = undefined;
        }
        cancelTransactionableOperation() {
            this._temporaryTransactionData = undefined;
        }
        createTransaction(_payload, _name) {
            this.session.extensionContext.transactionManager.openTransaction("Selection");
            this.transactionHandler.addUserDefinedOperation(_payload, _name);
            this.session.extensionContext.transactionManager.commitOpenTransaction();
        }
        isTransactionOperationActive() {
            return this._temporaryTransactionData !== undefined;
        }
        _addCursorControls(_uiSession, _rootPane) {
            this._cursorControlHolderPane = _rootPane.createSubPane({
                title: "Hidden Cursor Control Holder Pane",
                hasExpander: false
            });
            const bindManualControls = true;
            this._cursorModeSharedControl = new CursorModeControl(_uiSession, this._tool, this._cursorControlHolderPane, bindManualControls, this._toolCursorProperties, {
                hasPaneMargins: false
            });
            this._cursorModeSharedControl.initialize();
        }
        teardown() {
            if (this._activeModeImplementation) {
                this._activeModeImplementation.deactivate(this.tool.isActive, false);
                this._activeModeImplementation = undefined;
            }
            this._marqueeModeImplementation.teardown();
            this._freehandModeImplementation.teardown();
            this._magicModeImplementation.teardown();
            this._nudgeMode.teardown();
            if (this._cursorModeSharedControl && this._cursorModeSharedControl.isActive) {
                this._cursorModeSharedControl.deactivateControl();
            }
            this.uiSession.extensionContext.selectionManager.volume.clear();
            this._widgetGroup.delete();
            this._cleanupHandles.forEach((handle => handle()));
        }
        cycleSelectionMode() {
            switch (this._selectionMode.value) {
              case SelectionToolMode.Marquee:
                this._switchSelectionMode(SelectionToolMode.Freehand, true);
                break;

              case SelectionToolMode.Freehand:
                this._switchSelectionMode(SelectionToolMode.MagicSelect, true);
                break;

              case SelectionToolMode.MagicSelect:
                this._switchSelectionMode(SelectionToolMode.Marquee, true);
                break;

              default:
                this._switchSelectionMode(this._lastSelectionCreationModeBeforeNonCreationMode, true);
                break;
            }
        }
        startExternalNudge(op) {
            this._nudgeMode.startNudgeFromExternalMode(op);
        }
        updateExternalNudge(_pos) {
            this._nudgeMode.updateNudge(_pos, NudgeUpdateOptions.UpdateWidgetPosition);
        }
        commitExternalNudge() {
            this._nudgeMode.commitNudge();
        }
        cancelExternalNudge() {
            this._nudgeMode.cancelNudge();
        }
        isModifierDown(_modifier) {
            if (_modifier === server_editor_namespaceObject.InputModifier.Alt) {
                return this._altWatcher.isDown;
            } else if (_modifier === server_editor_namespaceObject.InputModifier.Control) {
                return this._ctrlWatcher.isDown;
            } else if (_modifier === server_editor_namespaceObject.InputModifier.Shift) {
                return this._shiftWatcher.isDown;
            } else {
                return false;
            }
        }
        isSimpleSelectEnabled() {
            return this._useSimpleSelectionMode?.value ?? false;
        }
        isNudgeEnabled() {
            const nudgeEntry = this._modeToggleGroup?.getEntryByValue(SelectionToolMode.Nudge);
            return nudgeEntry?.enabled ?? false;
        }
        setNudgeEnabled(enabled) {
            this._modeToggleGroup.updateEntries(this.buildToggleGroupEntries(enabled));
        }
        static isSelectionCreationMode(mode) {
            return mode === SelectionToolMode.Freehand || mode === SelectionToolMode.MagicSelect || mode === SelectionToolMode.Marquee;
        }
        getSelectionCreationMode(mode) {
            switch (mode) {
              case SelectionToolMode.Freehand:
                return this._freehandModeImplementation;

              case SelectionToolMode.MagicSelect:
                return this._magicModeImplementation;

              case SelectionToolMode.Marquee:
                return this._marqueeModeImplementation;

              default:
                return undefined;
            }
        }
        _switchSelectionMode(_newMode, userInitiated = false, _clearActiveVolumeStack = true) {
            const lastMode = this._activeModeImplementation?.modeType ?? SelectionToolMode.Default;
            if (_newMode === undefined || this._activeModeImplementation?.modeType !== _newMode) {
                if (userInitiated) {
                    this._activeModeImplementation?.deactivate(this.isActiveTool, _clearActiveVolumeStack);
                }
                if (this._activeModeImplementation !== undefined && !this._activeModeImplementation.isSelectionCreationMode() && _newMode !== undefined && SelectionBehavior.isSelectionCreationMode(_newMode) && _newMode !== this._lastSelectionCreationModeBeforeNonCreationMode) {
                    this._activeModeImplementation = this.getSelectionCreationMode(this._lastSelectionCreationModeBeforeNonCreationMode);
                    this.selectionCreationMode?.clearSelection();
                }
                this._activeModeImplementation = undefined;
            }
            if (_newMode === undefined || _newMode === this._activeModeImplementation?.modeType) {
                return;
            }
            switch (_newMode) {
              case SelectionToolMode.Marquee:
                this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.ModeChanged, {
                    mode: "Marquee"
                }, userInitiated);
                this._activeModeImplementation = this._marqueeModeImplementation;
                this._activeModeImplementation.activate(this.isActiveTool);
                break;

              case SelectionToolMode.Freehand:
                this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.ModeChanged, {
                    mode: "Paint"
                }, userInitiated);
                this._activeModeImplementation = this._freehandModeImplementation;
                this._activeModeImplementation.activate(this.isActiveTool);
                break;

              case SelectionToolMode.MagicSelect:
                this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.ModeChanged, {
                    mode: "Magic"
                }, userInitiated);
                this._activeModeImplementation = this._magicModeImplementation;
                this._activeModeImplementation.activate(this.isActiveTool);
                break;

              case SelectionToolMode.Nudge:
                this._telemetryManager.fireTelemetryEvent(SelectionTelemetry.ModeChanged, {
                    mode: "Nudge"
                }, userInitiated);
                this._lastSelectionCreationModeBeforeNonCreationMode = lastMode;
                this._activeModeImplementation = this._nudgeMode;
                this._activeModeImplementation.activate(this.isActiveTool);
                break;

              default:
                throw new Error("Unknown selection mode requested");
            }
            this._simpleSelectionCheckBox.visible = false;
            this._selectionMode.set(this._activeModeImplementation?.modeType);
        }
        _registerToolKeyBinding(action, binding, tag) {
            this._tool.registerKeyBinding(action, binding, {
                uniqueId: `editor:selectionToolKeyBinding:${tag}`,
                label: `resourcePack.editor.selectionTool.keyBinding.${tag}.title`,
                tooltip: `resourcePack.editor.selectionTool.keyBinding.${tag}.tooltip`
            });
        }
        forceSelectionChangeUpdate() {
            this._internalChangeVolumeContentsNotification();
        }
        setQuickActionsVisibility(visible) {
            if (this._quickActionsUI) {
                this._quickActionsUI.visible = visible;
            }
            if (this._quickActionsDivider) {
                this._quickActionsDivider.visible = visible;
            }
        }
        setTrimActionsVisibility(visible) {
            if (this._volumeTrimActionsPane) {
                if (visible) {
                    this._volumeTrimActionsPane.show();
                } else {
                    this._volumeTrimActionsPane.hide();
                }
            }
            if (this._trimActionsDivider) {
                this._trimActionsDivider.visible = visible;
            }
        }
        async _performTrimOperation(session, context) {
            if (context.selectionManager.volume.isEmpty) {
                session.log.warning("resourcePack.editor.selectionTool.toast.trimSelection.noSelection", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const onError = e => {
                session.log.error(`Trim operation failed with error: ${e.message}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            };
            const volume = context.selectionManager.volume.get();
            let bounds;
            try {
                bounds = volume.getBoundingBox();
            } catch (_e) {
                this.debugLog("Failed to get bounding box for volume to trim");
                return;
            }
            const boundsCopy = server_namespaceObject.BlockBoundingBoxUtils.createValid(bounds.min, bounds.max);
            await executeTickSafeOperation(session.extensionContext, session.log, boundsCopy, (() => {
                this.performSingleTransactionableOperation((() => {
                    const retainMarqueeAfterTrimming = true;
                    const ignoreLiquid = this._volumeTrimIgnoreLiquid.value;
                    const ignoreNoCollision = this._volumeTrimOnlyCollision.value;
                    const blockMask = this._blockMaskSharedControl?.getBlockMask();
                    const newVolume = this.session.extensionContext.blockUtilities.trimVolumeToFitContents(volume, retainMarqueeAfterTrimming, ignoreLiquid, ignoreNoCollision, blockMask);
                    if (newVolume.isEmpty) {
                        session.log.warning("resourcePack.editor.selectionTool.toast.trimSelection.noBlocksRemaining", {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        context.selectionManager.volume.clear();
                    } else {
                        const originalCapacity = volume.getCapacity();
                        const newCapacity = newVolume.getCapacity();
                        if (originalCapacity === newCapacity) {
                            session.log.warning("resourcePack.editor.selectionTool.toast.trimSelection.noChanges", {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                        } else {
                            context.selectionManager.volume.set(newVolume);
                        }
                    }
                    return true;
                }), "Trim Volume");
                this._internalChangeVolumeContentsNotification();
            })).catch(onError);
        }
        async _performRemoveAirOperation(session, context) {
            if (context.selectionManager.volume.isEmpty) {
                session.log.warning("resourcePack.editor.selectionTool.toast.removeAir.noSelection", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const onError = e => {
                session.log.error(`Remove air operation failed with error: ${e.message}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            };
            const volume = context.selectionManager.volume.get();
            let bounds;
            try {
                bounds = volume.getBoundingBox();
            } catch (_e) {
                this.debugLog("Failed to get bounding box for volume to remove air");
                return;
            }
            const boundsCopy = server_namespaceObject.BlockBoundingBoxUtils.createValid(bounds.min, bounds.max);
            await executeTickSafeOperation(session.extensionContext, session.log, boundsCopy, (() => {
                this.performSingleTransactionableOperation((() => {
                    const retainMarqueeAfterTrimming = false;
                    const ignoreLiquid = this._volumeTrimIgnoreLiquid.value;
                    const ignoreNoCollision = this._volumeTrimOnlyCollision.value;
                    const blockMask = this._blockMaskSharedControl?.getBlockMask();
                    const newVolume = this.session.extensionContext.blockUtilities.trimVolumeToFitContents(volume, retainMarqueeAfterTrimming, ignoreLiquid, ignoreNoCollision, blockMask);
                    if (newVolume.isEmpty) {
                        session.log.warning("resourcePack.editor.selectionTool.toast.removeAir.noBlocksRemaining", {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        context.selectionManager.volume.clear();
                    } else {
                        const originalCapacity = volume.getCapacity();
                        const newCapacity = newVolume.getCapacity();
                        if (originalCapacity === newCapacity) {
                            session.log.warning("resourcePack.editor.selectionTool.toast.removeAir.noChanges", {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                        } else {
                            context.selectionManager.volume.set(newVolume);
                        }
                    }
                    return true;
                }), "Remove Air");
                this._internalChangeVolumeContentsNotification();
            })).catch(onError);
        }
        async _performHollowOperation(session, context) {
            if (context.selectionManager.volume.isEmpty) {
                session.log.warning("resourcePack.editor.selectionTool.toast.hollow.noSelection", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const onError = e => {
                session.log.error(`Hollow operation failed with error: ${e.message}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            };
            const volume = context.selectionManager.volume.get();
            let bounds;
            try {
                bounds = volume.getBoundingBox();
            } catch (_e) {
                this.debugLog("Failed to get bounding box for volume to hollow");
                return;
            }
            const boundsCopy = server_namespaceObject.BlockBoundingBoxUtils.createValid(bounds.min, bounds.max);
            await executeTickSafeOperation(session.extensionContext, session.log, boundsCopy, (() => {
                this.performSingleTransactionableOperation((() => {
                    const newVolume = this.session.extensionContext.blockUtilities.findObscuredBlocksWithinVolume(volume);
                    if (newVolume.isEmpty) {
                        session.log.warning("resourcePack.editor.selectionTool.toast.hollow.noChanges", {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                    } else {
                        context.selectionManager.volume.set(newVolume);
                    }
                    return true;
                }), "Hollow Volume");
                this._internalChangeVolumeContentsNotification();
            })).catch(onError);
        }
        debugLog(_message) {}
        clearSelection() {
            this.selectionCreationMode?.clearSelection();
            this._freehandModeImplementation._clearVolumeStack();
            this._marqueeModeImplementation._clearVolumeStack();
        }
        buildToggleGroupEntries(nudgeEnabled) {
            return [ {
                value: SelectionToolMode.Marquee,
                icon: "marqueeIcon",
                tooltip: {
                    title: {
                        id: "resourcePack.editor.selectionTool.modeSelection.marquee.title",
                        props: [ getInputMarkup("editor:toolModeKeyBinding:toggleSelection") ]
                    },
                    description: {
                        id: "resourcePack.editor.selectionTool.modeSelection.marquee.tooltip",
                        props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:toolModeKeyBinding:toggleSelection") ]
                    }
                }
            }, {
                value: SelectionToolMode.Freehand,
                icon: "brushIcon",
                tooltip: {
                    title: {
                        id: "resourcePack.editor.selectionTool.modeSelection.freehand.title",
                        props: [ getInputMarkup("editor:toolModeKeyBinding:toggleSelection") ]
                    },
                    description: {
                        id: "resourcePack.editor.selectionTool.modeSelection.freehand.tooltip",
                        props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:toolModeKeyBinding:toggleSelection") ]
                    }
                }
            }, {
                value: SelectionToolMode.MagicSelect,
                icon: "eyeDropperIcon",
                tooltip: {
                    title: {
                        id: "resourcePack.editor.selectionTool.modeSelection.magic.title",
                        props: [ getInputMarkup("editor:toolModeKeyBinding:toggleSelection") ]
                    },
                    description: {
                        id: "resourcePack.editor.selectionTool.modeSelection.magic.tooltip",
                        props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:toolModeKeyBinding:toggleSelection") ]
                    }
                }
            }, {
                value: SelectionToolMode.Nudge,
                icon: "dragIcon",
                tooltip: {
                    title: {
                        id: "resourcePack.editor.selectionTool.modeSelection.quickMove.title",
                        props: [ getInputMarkup("editor:toolModeKeyBinding:quickMoveMode") ]
                    },
                    description: {
                        id: "resourcePack.editor.selectionTool.modeSelection.quickMove.tooltip",
                        props: [ newLineMarkup + newLineMarkup ]
                    }
                },
                enabled: nudgeEnabled
            } ];
        }
        _loadTrimSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 1
            };
            const group = this._persistenceManager.getGroup(SelectionBehavior_PERSISTENCE_GROUP_NAME, option);
            const errorMsg = "No stored trim settings found";
            if (!group) {
                this.session.log.info(errorMsg);
            } else {
                const storeItem = group.fetchItem(SelectionBehavior_PERSISTENCE_GROUPITEM_NAME);
                if (storeItem && storeItem.value) {
                    this._volumeTrimIgnoreLiquid.set(storeItem.value.volumeTrimIgnoreLiquid);
                    this._volumeTrimOnlyCollision.set(storeItem.value.volumeTrimOnlyCollision);
                    this._useSimpleSelectionMode.set(storeItem.value.simpleSelectionEnabled);
                }
                group.dispose();
            }
        }
        _saveTrimSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 1
            };
            const group = this._persistenceManager.getOrCreateGroup(SelectionBehavior_PERSISTENCE_GROUP_NAME, option);
            const errorMsg = "No stored trim settings found";
            if (group) {
                const data = {
                    volumeTrimIgnoreLiquid: this._volumeTrimIgnoreLiquid.value,
                    volumeTrimOnlyCollision: this._volumeTrimOnlyCollision.value,
                    simpleSelectionEnabled: this._useSimpleSelectionMode.value
                };
                const storeItem = group.getOrCreateItem(SelectionBehavior_PERSISTENCE_GROUPITEM_NAME, data);
                if (storeItem) {
                    storeItem.commit();
                }
                group.dispose();
                return;
            }
            this.session.log.error(errorMsg);
        }
    }
    SelectionBehavior.MODAL_TOOL_ID = "editor:modalTool:selection";
    class UndoRedoBehavior {
        constructor(uiSession, coreMenuItems) {
            this._canUndo = false;
            this._canRedo = false;
            this._transactionManager = uiSession.extensionContext.transactionManager;
            this._canUndo = this._transactionManager.undoSize() > 0;
            this._canRedo = this._transactionManager.redoSize() > 0;
            const undoAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._transactionManager.undo();
                }
            });
            const redoAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._transactionManager.redo();
                }
            });
            this._undoMenuItem = coreMenuItems.edit.addItem({
                label: "resourcePack.editor.menuBar.edit.undo",
                enabled: this._canUndo,
                tooltip: "resourcePack.editor.menuBar.edit.undo.tooltip"
            }, undoAction);
            this._redoMenuItem = coreMenuItems.edit.addItem({
                label: "resourcePack.editor.menuBar.edit.redo",
                enabled: this._canRedo,
                tooltip: "resourcePack.editor.menuBar.edit.redo.tooltip"
            }, redoAction);
            this._undoActionBarItem = uiSession.actionBar.registerItem(server_editor_namespaceObject.CoreActionBarItemType.Undo, undoAction, {
                label: "resourcePack.editor.actionBar.undo",
                icon: "undoIcon",
                tooltipTitle: "resourcePack.editor.actionBar.undo.tooltipTitle",
                tooltipDescription: "resourcePack.editor.actionBar.undo.tooltipDescription",
                enabled: this._canUndo
            });
            this._redoActionBarItem = uiSession.actionBar.registerItem(server_editor_namespaceObject.CoreActionBarItemType.Redo, redoAction, {
                label: "resourcePack.editor.actionBar.redo",
                icon: "redoIcon",
                tooltipTitle: "resourcePack.editor.actionBar.redo.tooltipTitle",
                tooltipDescription: "resourcePack.editor.actionBar.redo.tooltipDescription",
                enabled: this._canRedo
            });
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalEditor, undoAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_Z,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:globalKeyBinding:undo",
                label: "resourcePack.editor.transaction.keyBinding.undo.title",
                tooltip: "resourcePack.editor.transaction.keyBinding.undo.tooltip"
            });
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalEditor, redoAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_Y,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:globalKeyBinding:redo",
                label: "resourcePack.editor.transaction.keyBinding.redo.title",
                tooltip: "resourcePack.editor.transaction.keyBinding.redo.tooltip"
            });
            this.updateHandle = server_namespaceObject.system.runInterval((() => {
                this._checkUndoRedoState();
            }), server_namespaceObject.TicksPerSecond / 2);
        }
        _checkUndoRedoState() {
            const canUndo = this._transactionManager.undoSize() > 0;
            const canRedo = this._transactionManager.redoSize() > 0;
            if (canUndo !== this._canUndo) {
                if (this._undoActionBarItem) {
                    this._undoActionBarItem.setEnabled(canUndo);
                }
                if (this._undoMenuItem) {
                    this._undoMenuItem.enabled = canUndo;
                }
                this._canUndo = canUndo;
            }
            if (canRedo !== this._canRedo) {
                if (this._redoActionBarItem) {
                    this._redoActionBarItem.setEnabled(canRedo);
                }
                if (this._redoMenuItem) {
                    this._redoMenuItem.enabled = canRedo;
                }
                this._canRedo = canRedo;
            }
        }
        teardown() {
            if (this.updateHandle) {
                server_namespaceObject.system.clearRun(this.updateHandle);
            }
        }
    }
    var SummonTelemetry;
    (function(SummonTelemetry) {
        SummonTelemetry["Create"] = "Create";
        SummonTelemetry["Delete"] = "Delete";
        SummonTelemetry["Clear"] = "Clear";
        SummonTelemetry["Nudge"] = "Nudge";
        SummonTelemetry["Undo"] = "Undo";
        SummonTelemetry["Redo"] = "Redo";
        SummonTelemetry["PickerUpdated"] = "PickerUpdated";
        SummonTelemetry["Select"] = "Select";
        SummonTelemetry["SelectMove"] = "SelectMove";
        SummonTelemetry["MoveCompleted"] = "MoveCompleted";
    })(SummonTelemetry || (SummonTelemetry = {}));
    const ROTATION_SCROLL_STEP_DEGREES = 10;
    const SummonTool_PERSISTENCE_GROUP_NAME = "editor:summon";
    const SummonTool_PERSISTENCE_GROUPITEM_NAME = "summon_settings";
    class SummonTool {
        constructor(session) {
            this.NUDGE_REPEAT_INTERVAL = 5;
            this._nudgeActions = [];
            this._activeNudgeActions = new Set([]);
            this._isWidgetMoving = false;
            this._entityOffset = (0, server_editor_namespaceObject.makeObservable)({
                x: 0,
                y: 0,
                z: 0
            });
            this._entityGridAlignment = (0, server_editor_namespaceObject.makeObservable)({
                x: 1,
                y: 1,
                z: 1
            });
            this._session = session;
            this._cursorProperties = {
                outlineColor: {
                    red: 1,
                    green: 1,
                    blue: 0,
                    alpha: 1
                },
                controlMode: server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse,
                targetMode: server_editor_namespaceObject.CursorTargetMode.Face,
                visible: true,
                fixedModeDistance: 5
            };
            this._persistenceManager = getPersistenceManager(session.extensionContext.player);
            this.telemetryManager = new TelemetryManager(session.extensionContext.player, TelemetrySource.Summon);
            const dimensionBounds = this._session.extensionContext.blockUtilities.getDimensionLocationBoundingBox();
            const center = server_namespaceObject.BlockBoundingBoxUtils.getCenter(dimensionBounds);
            this._widgetGroup = this._session.extensionContext.widgetManager.createGroup({
                visible: true
            });
            this._widget = this._widgetGroup.createWidget(center, {
                visible: false,
                selectable: true,
                snapToBlockLocation: false,
                widgetName: "summonToolWidget"
            });
            this._widget.addGizmoComponent("entity_gizmo", {
                offset: {
                    x: 0,
                    y: .5,
                    z: 0
                },
                visible: true,
                stateChangeEvent: data => {
                    if (!this._selectedEntity || !data.widget.location) {
                        return;
                    }
                    const widgetLocation = lib.Vector3Utils.subtract(data.widget.location, {
                        x: 0,
                        y: .5,
                        z: 0
                    });
                    const entityLocation = {
                        ...widgetLocation
                    };
                    const offset = this._entityOffset.value;
                    const gridAlignment = this._entityGridAlignment.value;
                    entityLocation.x = Math.round(entityLocation.x / gridAlignment.x) * gridAlignment.x;
                    entityLocation.y = Math.round(entityLocation.y / gridAlignment.y) * gridAlignment.y;
                    entityLocation.z = Math.round(entityLocation.z / gridAlignment.z) * gridAlignment.z;
                    entityLocation.x += offset.x;
                    entityLocation.y += offset.y;
                    entityLocation.z += offset.z;
                    if ((data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerMoved || data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginMoved) && !this._isWidgetMoving) {
                        this._isWidgetMoving = true;
                        this._widgetMoveStartLocation = entityLocation;
                    }
                    if (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerMoved || data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginMoved) {
                        this._selectedEntity.teleport(entityLocation);
                    }
                    if (this._isWidgetMoving && (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginReleased || data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerReleased)) {
                        const manager = this._session.extensionContext.transactionManager;
                        manager.openTransaction("Summon Tool - Move Entity");
                        this.telemetryManager.fireTelemetryEvent(SummonTelemetry.MoveCompleted, {
                            mode: "Begin"
                        });
                        try {
                            const oldLocation = this._widgetMoveStartLocation ?? this._selectedEntity.location;
                            const newLocation = entityLocation;
                            const transactionPayload = {
                                entityID: this._selectedEntity.id,
                                oldLocation,
                                newLocation
                            };
                            this.telemetryManager.fireTelemetryEvent(SummonTelemetry.MoveCompleted, {
                                mode: "End"
                            });
                            this._moveTransactionHandler.addUserDefinedOperation(transactionPayload, "Entity Move");
                        } catch (e) {
                            this._session.log.error(`Unable to commit move entity transaction. ${stringFromException(e)}`, {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                            manager.discardOpenTransaction();
                            this._isWidgetMoving = false;
                            this._widgetMoveStartLocation = undefined;
                            return;
                        }
                        manager.commitOpenTransaction();
                        this._isWidgetMoving = false;
                        this._widgetMoveStartLocation = undefined;
                    }
                }
            });
            const activationAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._session.toolRail.setSelectedToolId(this._tool.id);
                }
            });
            this._tool = this._session.toolRail.addTool(SummonTool.MODAL_TOOL_ID, {
                title: "resourcePack.editor.toolRail.summonTool.tool.title",
                icon: "pack://textures/editor/Entity.png?filtering=point",
                tooltip: {
                    description: "resourcePack.editor.toolRail.summonTool.tool.tip",
                    image: "pack://textures/editor/Summon.gif"
                },
                action: activationAction
            });
            this._tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    this._session.extensionContext.cursor.pushPropertiesById(this._cursorProperties, SummonTool.MODAL_TOOL_ID);
                } else {
                    if (this._isWidgetMoving) {
                        const manager = this._session.extensionContext.transactionManager;
                        manager.discardOpenTransaction();
                        this._isWidgetMoving = false;
                        this._widgetMoveStartLocation = undefined;
                    }
                    this.shutdownMouseWatcher();
                    this.clearSelection();
                    this._session.extensionContext.cursor.popPropertiesById(SummonTool.MODAL_TOOL_ID);
                }
            }));
            this._createTransactionHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(this._session.extensionContext.transactionManager, (() => {
                this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Undo, {
                    mode: "Clear"
                });
                this.clearSelection();
            }), (payload => {
                this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Redo, {
                    mode: "Create"
                });
                const entity = server_namespaceObject.world.getEntity(payload.entityID);
                if (entity) {
                    this.selectEntity(entity);
                }
            }));
            this._deleteTransactionHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(this._session.extensionContext.transactionManager, (payload => {
                this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Undo, {
                    mode: "Create"
                });
                const entity = server_namespaceObject.world.getEntity(payload.entityID);
                if (entity) {
                    this.selectEntity(entity);
                }
            }), (() => {
                this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Redo, {
                    mode: "Clear"
                });
                this.clearSelection();
            }));
            this._moveTransactionHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(this._session.extensionContext.transactionManager, (payload => {
                const entity = server_namespaceObject.world.getEntity(payload.entityID);
                if (entity) {
                    entity.teleport(payload.oldLocation);
                    this.selectEntity(entity);
                }
            }), (payload => {
                const entity = server_namespaceObject.world.getEntity(payload.entityID);
                if (entity) {
                    entity.teleport(payload.newLocation);
                    this.selectEntity(entity);
                }
            }));
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, activationAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_S,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editor:toolModeKeyBinding:toggleSummonTool",
                label: "resourcePack.editor.toolRail.summonTool.keyBinding.toggle.title",
                tooltip: "resourcePack.editor.toolRail.summonTool.keyBinding.toggle.tooltip"
            });
            this._registerToolKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._selectedEntity) {
                        this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Delete);
                        const manager = this._session.extensionContext.transactionManager;
                        manager.openTransaction("Summon Tool - Delete Entity");
                        try {
                            if (this._selectedEntity) {
                                const transactionPayload = {
                                    entityID: this._selectedEntity.id
                                };
                                this._deleteTransactionHandler.addUserDefinedOperation(transactionPayload, "Entity Delete");
                                manager.addEntityOperation(this._selectedEntity, server_editor_namespaceObject.EntityOperationType.Delete);
                            }
                        } catch (e) {
                            this._session.log.warning(`Unable to commit delete entity transaction. ${stringFromException(e)}`);
                            manager.discardOpenTransaction();
                            return;
                        }
                        manager.commitOpenTransaction();
                        try {
                            this._selectedEntity.remove();
                        } catch (e) {
                            this._session.log.error(`${stringFromException(e)}`, {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                        } finally {
                            this.clearSelection();
                        }
                    }
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.DELETE
            }, "delete");
            this._registerToolKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Clear);
                    this.clearSelection();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_D,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, "clear");
            const keyUpAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                onExecute: state => {
                    if (state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                        this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Nudge, {
                            direction: "up"
                        });
                        this.nudgeSelected(lib.VECTOR3_UP);
                    } else if (state === server_editor_namespaceObject.ContinuousActionState.Repeat) {
                        this.nudgeSelected(lib.VECTOR3_UP);
                    }
                    this.handleNudgeState(state, keyUpAction.id);
                },
                repeatInterval: this.NUDGE_REPEAT_INTERVAL
            });
            const keyDownAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                onExecute: state => {
                    if (state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                        this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Nudge, {
                            direction: "down"
                        });
                        this.nudgeSelected(lib.VECTOR3_DOWN);
                    } else if (state === server_editor_namespaceObject.ContinuousActionState.Repeat) {
                        this.nudgeSelected(lib.VECTOR3_DOWN);
                    }
                    this.handleNudgeState(state, keyDownAction.id);
                },
                repeatInterval: this.NUDGE_REPEAT_INTERVAL
            });
            const keyLeftAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                onExecute: state => {
                    const nudgeVector = this.getRelativeNudgeDirection(direction_Direction.Left);
                    if (state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                        this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Nudge, {
                            direction: "left"
                        });
                        this.nudgeSelected(nudgeVector);
                    } else if (state === server_editor_namespaceObject.ContinuousActionState.Repeat) {
                        this.nudgeSelected(nudgeVector);
                    }
                    this.handleNudgeState(state, keyDownAction.id);
                },
                repeatInterval: this.NUDGE_REPEAT_INTERVAL
            });
            const keyRightAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                onExecute: state => {
                    const nudgeVector = this.getRelativeNudgeDirection(direction_Direction.Right);
                    if (state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                        this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Nudge, {
                            direction: "right"
                        });
                        this.nudgeSelected(nudgeVector);
                    } else if (state === server_editor_namespaceObject.ContinuousActionState.Repeat) {
                        this.nudgeSelected(nudgeVector);
                    }
                    this.handleNudgeState(state, keyDownAction.id);
                },
                repeatInterval: this.NUDGE_REPEAT_INTERVAL
            });
            const keyForwardAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                onExecute: state => {
                    const nudgeVector = this.getRelativeNudgeDirection(direction_Direction.Forward);
                    if (state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                        this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Nudge, {
                            direction: "forward"
                        });
                        this.nudgeSelected(nudgeVector);
                    } else if (state === server_editor_namespaceObject.ContinuousActionState.Repeat) {
                        this.nudgeSelected(nudgeVector);
                    }
                    this.handleNudgeState(state, keyDownAction.id);
                },
                repeatInterval: this.NUDGE_REPEAT_INTERVAL
            });
            const keyBackAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.ContinuousAction,
                onExecute: state => {
                    const nudgeVector = this.getRelativeNudgeDirection(direction_Direction.Back);
                    if (state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                        this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Nudge, {
                            direction: "back"
                        });
                        this.nudgeSelected(nudgeVector);
                    } else if (state === server_editor_namespaceObject.ContinuousActionState.Repeat) {
                        this.nudgeSelected(nudgeVector);
                    }
                    this.handleNudgeState(state, keyDownAction.id);
                },
                repeatInterval: this.NUDGE_REPEAT_INTERVAL
            });
            this._nudgeActions = [ keyUpAction, keyDownAction, keyLeftAction, keyRightAction, keyBackAction, keyForwardAction ];
            this._registerToolKeyBinding(keyForwardAction, {
                key: server_editor_namespaceObject.KeyboardKey.UP
            }, "moveForward");
            this._registerToolKeyBinding(keyBackAction, {
                key: server_editor_namespaceObject.KeyboardKey.DOWN
            }, "moveBack");
            this._registerToolKeyBinding(keyLeftAction, {
                key: server_editor_namespaceObject.KeyboardKey.LEFT
            }, "moveLeft");
            this._registerToolKeyBinding(keyRightAction, {
                key: server_editor_namespaceObject.KeyboardKey.RIGHT
            }, "moveRight");
            this._registerToolKeyBinding(keyUpAction, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_UP
            }, "moveUp");
            this._registerToolKeyBinding(keyDownAction, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_DOWN
            }, "moveDown");
            this._rotation = (0, server_editor_namespaceObject.makeObservable)(0);
            this._mouseMoveWatcherId = -1;
            this._loadSettings();
            {
                this._pane = this._session.createPropertyPane({
                    title: "resourcePack.editor.toolRail.summonTool.pane.title",
                    infoTooltip: {
                        description: [ "resourcePack.editor.toolRail.summonTool.tool.tip", {
                            link: "https://aka.ms/BedrockEditorSummonTool",
                            text: "resourcePack.editor.help.learnMore"
                        } ]
                    }
                });
                this._entityType = (0, server_editor_namespaceObject.makeObservable)(MinecraftEntityTypes.Pig);
                this._pane.addVector3(this._entityOffset, {
                    title: "resourcePack.editor.toolRail.summonTool.tool.Offset",
                    tooltip: "resourcePack.editor.toolRail.summonTool.tool.Offset.tooltip",
                    isInteger: false,
                    min: {
                        x: 0,
                        y: 0,
                        z: 0
                    },
                    max: {
                        x: 8,
                        y: 8,
                        z: 8
                    },
                    onChange: () => {
                        this._saveSettings();
                    }
                });
                this._pane.addVector3(this._entityGridAlignment, {
                    title: "resourcePack.editor.toolRail.summonTool.tool.GridSize",
                    tooltip: "resourcePack.editor.toolRail.summonTool.tool.GridSize.tooltip",
                    isInteger: true,
                    min: {
                        x: 1,
                        y: 1,
                        z: 1
                    },
                    max: {
                        x: 8,
                        y: 8,
                        z: 8
                    },
                    onChange: () => {
                        this._saveSettings();
                    }
                });
                this._pane.addDivider();
                this._pane.addNumber(this._rotation, {
                    title: "resourcePack.editor.toolRail.summonTool.tool.selectSubPane.rotation",
                    tooltip: "resourcePack.editor.toolRail.summonTool.tool.selectSubPane.rotation.tooltip",
                    min: -360,
                    max: 360,
                    isInteger: true,
                    variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                    onChange: () => {
                        this.updateRotation();
                        this._saveSettings();
                    }
                });
                this._pane.addText("resourcePack.editor.toolRail.summonTool.tool.infoText");
                this._pane.addComboBox(this._entityType, {
                    title: "resourcePack.editor.summonTool.summonSubPane.EntityPickerTitle",
                    tooltip: "resourcePack.editor.toolRail.summonTool.pane.type.tooltip",
                    dataType: server_editor_namespaceObject.ComboBoxPropertyItemDataType.Entity,
                    onChange: newValue => {
                        this.telemetryManager.fireTelemetryEvent(SummonTelemetry.PickerUpdated, {
                            entity: newValue
                        });
                    }
                });
                this._tool.bindPropertyPane(this._pane);
            }
            const executeMouseButtonAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction !== server_editor_namespaceObject.MouseActionType.LeftButton) {
                        return;
                    }
                    const buttonDown = mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown;
                    if (buttonDown) {
                        const player = this._session.extensionContext.player;
                        const dimension = player.dimension;
                        const entityHitList = dimension.getEntitiesFromRay(mouseRay.location, mouseRay.direction);
                        let hitEntity = undefined;
                        if (entityHitList.length > 1) {
                            hitEntity = entityHitList[1];
                            if (hitEntity.entity === this._selectedEntity) {
                                this.telemetryManager.fireTelemetryEvent(SummonTelemetry.SelectMove, {
                                    state: "Begin"
                                });
                                this.handleBeginSelectMove(mouseRay);
                            } else if (hitEntity.entity !== this._selectedEntity) {
                                this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Select);
                                this.selectEntity(hitEntity.entity);
                            }
                        } else {
                            this.telemetryManager.fireTelemetryEvent(SummonTelemetry.Create);
                            this.handleBeginSummonMode(mouseRay);
                        }
                    } else {
                        if (this._mouseMoveWatcherId >= 0) {
                            this.telemetryManager.fireTelemetryEvent(SummonTelemetry.SelectMove, {
                                state: "End"
                            });
                            this.handleEndSelectMove(mouseRay);
                        }
                    }
                }
            });
            this._tool.registerMouseButtonBinding(executeMouseButtonAction);
            const rotateEntityAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    if (!this._selectedEntity) {
                        return;
                    }
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.Wheel && mouseProps.modifiers.shift) {
                        if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.WheelOut) {
                            const newRot = this._rotation.value + ROTATION_SCROLL_STEP_DEGREES;
                            this._rotation.set(newRot > 360 ? newRot - 720 : newRot);
                            this.updateRotation();
                        } else if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.WheelIn) {
                            const newRot = this._rotation.value - ROTATION_SCROLL_STEP_DEGREES;
                            this._rotation.set(newRot < -360 ? 720 + newRot : newRot);
                            this.updateRotation();
                        }
                    }
                }
            });
            this._tool.registerMouseWheelBinding(rotateEntityAction);
        }
        nudgeSelected(nudgeVector) {
            if (this._selectedEntity && this._mouseMoveWatcherId < 0) {
                try {
                    const currentLocation = this._selectedEntity.location;
                    const newLocation = lib.Vector3Utils.add(currentLocation, nudgeVector);
                    this._selectedEntity.teleport(newLocation);
                    this.updateSelectionPreview();
                } catch (e) {
                    this._session.log.error(`Nudge failed: ${stringFromException(e)}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
            }
        }
        handleNudgeState(state, actionId) {
            if (state === server_editor_namespaceObject.ContinuousActionState.Begin) {
                this._activeNudgeActions.add(actionId);
            }
            if (state === server_editor_namespaceObject.ContinuousActionState.Repeat) {
                if (this._activeNudgeActions.size > 0) {
                    this._nudgeActions.forEach((action => action.repeatDelay = 0));
                }
            } else if (state === server_editor_namespaceObject.ContinuousActionState.End) {
                this._activeNudgeActions.delete(actionId);
                if (this._activeNudgeActions.size === 0) {
                    this._nudgeActions.forEach((action => action.repeatDelay = undefined));
                }
            }
        }
        selectEntity(entity) {
            this._selectedEntity = entity;
            this._rotation.set(entity.getRotation().y);
            this._widget.location = entity.location;
            this._widget.visible = true;
            this.updateSelectionPreview();
        }
        getRelativeNudgeDirection(direction) {
            const rotationY = this._session.extensionContext.player.getRotation().y;
            const rotationCorrectedVector = getRotationCorrectedDirectionVector(rotationY, direction);
            return rotationCorrectedVector;
        }
        updateRotation() {
            if (!this._selectedEntity) {
                return;
            }
            let rotation = this._rotation.value;
            if (rotation < -360) {
                rotation += 360;
            } else if (rotation > 360) {
                rotation -= 360;
            }
            const location = this._selectedEntity.location;
            this._selectedEntity.setRotation({
                x: 0,
                y: rotation
            });
            this._selectedEntity.teleport(location);
            this._rotation.set(rotation);
        }
        shutdownMouseWatcher() {
            if (this._mouseMoveWatcherId >= 0) {
                server_namespaceObject.system.clearRun(this._mouseMoveWatcherId);
                this._mouseMoveWatcherId = -1;
            }
        }
        handleEndSelectMove(mouseRay) {
            this.shutdownMouseWatcher();
            if (this._selectedEntity) {
                const targetLoc = {
                    x: mouseRay.cursorBlockLocation.x + .5,
                    y: mouseRay.cursorBlockLocation.y,
                    z: mouseRay.cursorBlockLocation.z + .5
                };
                this._selectedEntity.teleport(targetLoc);
            }
            this.updateSelectionPreview();
        }
        handleBeginSelectMove(_) {
            if (!this._selectedEntity) {
                return;
            }
            let currentCursorLocation = this._session.extensionContext.cursor.getPosition();
            const mouseWatcherTick = () => {
                if (this._mouseMoveWatcherId >= 0 && this._selectedEntity) {
                    const cursorLoc = lib.Vector3Utils.floor(this._session.extensionContext.cursor.getPosition());
                    if (!lib.Vector3Utils.equals(cursorLoc, currentCursorLocation)) {
                        currentCursorLocation = cursorLoc;
                        const entityNewPos = lib.Vector3Utils.add(currentCursorLocation, {
                            x: .5,
                            y: 0,
                            z: .5
                        });
                        this._selectedEntity.teleport(entityNewPos);
                        this.updateSelectionPreview();
                    }
                    this._mouseMoveWatcherId = server_namespaceObject.system.run(mouseWatcherTick);
                }
            };
            this._mouseMoveWatcherId = server_namespaceObject.system.run(mouseWatcherTick);
            this.updateSelectionPreview();
        }
        handleBeginSummonMode(mouseRay) {
            const spawnLoc = {
                ...mouseRay.cursorBlockLocation
            };
            const offset = this._entityOffset.value;
            const gridAlignment = this._entityGridAlignment.value;
            spawnLoc.x = Math.round(spawnLoc.x / gridAlignment.x) * gridAlignment.x;
            spawnLoc.y = Math.round(spawnLoc.y / gridAlignment.y) * gridAlignment.y;
            spawnLoc.z = Math.round(spawnLoc.z / gridAlignment.z) * gridAlignment.z;
            spawnLoc.x += offset.x;
            spawnLoc.y += offset.y;
            spawnLoc.z += offset.z;
            const player = this._session.extensionContext.player;
            const dimension = player.dimension;
            try {
                this._selectedEntity = dimension.spawnEntity(this._entityType.value, spawnLoc, {
                    initialPersistence: true
                });
            } catch (e) {
                this._session.log.error(`${stringFromException(e)}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                this.clearSelection();
            }
            if (this._selectedEntity) {
                this.selectEntity(this._selectedEntity);
            }
            this.updateRotation();
            const manager = this._session.extensionContext.transactionManager;
            manager.openTransaction("Summon Tool - Create Entity");
            try {
                if (this._selectedEntity) {
                    manager.addEntityOperation(this._selectedEntity, server_editor_namespaceObject.EntityOperationType.Create);
                    const transactionPayload = {
                        entityID: this._selectedEntity.id
                    };
                    this._createTransactionHandler.addUserDefinedOperation(transactionPayload, "Entity Create");
                }
            } catch (e) {
                this._session.log.warning(`Unable to commit create entity transaction. ${stringFromException(e)}`);
                manager.discardOpenTransaction();
                return;
            }
            manager.commitOpenTransaction();
        }
        teardown() {
            this.shutdownMouseWatcher();
        }
        clearSelection() {
            this._widget.visible = false;
            this._selectedEntity = undefined;
        }
        updateSelectionPreview() {
            if (this._selectedEntity) {
                this._widget.visible = true;
                this._widget.location = this._selectedEntity.location;
            } else {
                this._widget.visible = false;
            }
        }
        _registerToolKeyBinding(action, binding, tag) {
            this._tool.registerKeyBinding(action, binding, {
                uniqueId: `editor:summonToolKeyBinding:${tag}`,
                label: `resourcePack.editor.toolRail.summonTool.keyBinding.${tag}.title`,
                tooltip: `resourcePack.editor.toolRail.summonTool.keyBinding.${tag}.tooltip`
            });
        }
        _loadSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(SummonTool_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const storeItem = group.fetchItem(SummonTool_PERSISTENCE_GROUPITEM_NAME);
                if (storeItem && storeItem.value) {
                    try {
                        const storedSettings = storeItem.value;
                        this._entityOffset.set(storedSettings.entityOffset);
                        this._entityGridAlignment.set(storedSettings.entityGridAlignment);
                        this._rotation.set(storedSettings.rotation);
                    } catch (error) {
                        this._session.log.error("Fail to load the settings, error: " + stringFromException(error));
                    }
                }
                group.dispose();
            }
        }
        _saveSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(SummonTool_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const settings = {
                    entityOffset: this._entityOffset.value,
                    entityGridAlignment: this._entityGridAlignment.value,
                    rotation: this._rotation.value
                };
                const storeItem = group.getOrCreateItem(SummonTool_PERSISTENCE_GROUPITEM_NAME, settings);
                if (storeItem) {
                    storeItem.commit();
                }
                group.dispose();
                return;
            }
            this._session.log.error("Fail to save settings for Summon");
        }
    }
    SummonTool.MODAL_TOOL_ID = "editor:modalTool:summon";
    const TimeOfDay_validDaylightCycle = [ {
        val: server_editor_namespaceObject.DaylightCycle.Normal,
        label: "resourcePack.editor.exportProject.cheatsSettings.daylightCycle.normal"
    }, {
        val: server_editor_namespaceObject.DaylightCycle.AlwaysDay,
        label: "resourcePack.editor.exportProject.cheatsSettings.daylightCycle.alwaysDay"
    }, {
        val: server_editor_namespaceObject.DaylightCycle.LockTime,
        label: "resourcePack.editor.exportProject.cheatsSettings.daylightCycle.lockTime"
    } ];
    var TimeOfDayTelemetry;
    (function(TimeOfDayTelemetry) {
        TimeOfDayTelemetry["SettingsChanged"] = "SettingsChanged";
    })(TimeOfDayTelemetry || (TimeOfDayTelemetry = {}));
    const TimeOfDay_PERSISTENCE_GROUP_NAME = "editor:time_of_day";
    const TimeOfDay_PERSISTENCE_GROUPITEM_NAME = "time_of_day_settings";
    class TimeOfDayBehavior {
        constructor(_uiSession, _parentMenu) {
            this._uiSession = _uiSession;
            this._timeOfDayValue = (0, server_editor_namespaceObject.makeObservable)(server_namespaceObject.world.getTimeOfDay());
            this._timeOfDayTimeString = (0, server_editor_namespaceObject.makeObservable)(convertTODToTime(server_namespaceObject.world.getTimeOfDay(), false));
            this._clockType = (0, server_editor_namespaceObject.makeObservable)(ClockType.CLOCK_24HR);
            this._customTime = (0, server_editor_namespaceObject.makeObservable)(0);
            this._daylightCycle = (0, server_editor_namespaceObject.makeObservable)(server_editor_namespaceObject.DaylightCycle.LockTime);
            this._currentPreset = (0, server_editor_namespaceObject.makeObservable)(TODDropDown.None);
            this._storedSettings = new Map;
            this._messageSubscriptionHandle = undefined;
            this.openMenuAction = this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._timeOfDayValue.set(server_namespaceObject.world.getTimeOfDay());
                    this._pane?.show();
                }
            });
            this._persistenceManager = getPersistenceManager(_uiSession.extensionContext.player);
            this.createMenuItem(_parentMenu);
            this.telemetryManager = new TelemetryManager(_uiSession.extensionContext.player, TelemetrySource.TimeOfDay);
            this._pane = _uiSession.createPropertyPane({
                title: "resourcePack.editor.timeOfDay.title",
                uniqueId: "editor:pane:timeOfDay",
                infoTooltip: {
                    description: [ "resourcePack.editor.timeOfDay.tooltip", {
                        link: "https://aka.ms/BedrockEditorTimeOfDaySettings",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            const clockItems = clockValues.map((v => {
                const item = {
                    label: v.stringId,
                    value: v.index
                };
                return item;
            }));
            this._pane.addDropdown(this._clockType, {
                title: "resourcePack.editor.timeOfDay.clockType",
                tooltip: "resourcePack.editor.timeOfDay.clockType.tooltip",
                enable: true,
                entries: clockItems,
                onChange: newValue => {
                    this.telemetryManager.fireTelemetryEvent(TimeOfDayTelemetry.SettingsChanged, {
                        settingName: "clockType",
                        newSetting: newValue
                    });
                    this.saveSettings();
                }
            });
            this._pane.addString(this._timeOfDayTimeString, {
                title: "resourcePack.editor.timeOfDay.currentTime",
                tooltip: "resourcePack.editor.timeOfDay.currentTime.tooltip",
                enable: false
            });
            const daylightCycleItems = TimeOfDay_validDaylightCycle.map(((v, i) => {
                const item = {
                    label: v.label,
                    value: i
                };
                return item;
            }));
            this._pane.addDropdown(this._daylightCycle, {
                title: "resourcePack.editor.timeOfDay.daylightCycle",
                tooltip: "resourcePack.editor.timeOfDay.daylightCycle.tooltip",
                entries: daylightCycleItems,
                onChange: newValue => {
                    const currentTime = server_namespaceObject.world.getTimeOfDay();
                    this.setDaylightCycle(newValue, currentTime, _uiSession);
                    this._currentPreset.set(TODDropDown.None);
                    this.telemetryManager.fireTelemetryEvent(TimeOfDayTelemetry.SettingsChanged, {
                        settingName: "daylightCycle",
                        newSetting: newValue
                    });
                    this.saveSettings();
                }
            });
            this._pane.addDivider();
            const timeItems = validPresets.map((v => {
                const item = {
                    label: v.stringId,
                    value: v.time
                };
                return item;
            }));
            this._pane.addDropdown(this._currentPreset, {
                title: "resourcePack.editor.timeOfDay.dropDown.title",
                tooltip: "resourcePack.editor.timeOfDay.dropDown.tooltip",
                entries: timeItems,
                onChange: newValue => {
                    if (newValue === TODDropDown.None) {
                        this._customTimeHandle.enable = true;
                        this._customTimeHandle.visible = true;
                    } else {
                        this.setDaylightCycle(server_editor_namespaceObject.DaylightCycle.LockTime, newValue, _uiSession);
                        this._timeOfDayValue.set(newValue);
                        server_namespaceObject.world.setTimeOfDay(newValue);
                        this._customTimeHandle.enable = false;
                        this._customTimeHandle.visible = false;
                    }
                    this.telemetryManager.fireTelemetryEvent(TimeOfDayTelemetry.SettingsChanged, {
                        settingName: "currentPreset",
                        newSetting: newValue
                    });
                    this.saveSettings();
                }
            });
            this._customTimeHandle = this._pane.addNumber(this._customTime, {
                title: "resourcePack.editor.timeOfDay.customTime",
                tooltip: "resourcePack.editor.timeOfDay.customTime.tooltip",
                min: 0,
                max: 24 * mcHoursPerTick - 1,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                onChange: newValue => {
                    this._timeOfDayValue.set(newValue);
                    this.setDaylightCycle(server_editor_namespaceObject.DaylightCycle.LockTime, newValue, _uiSession);
                    this._daylightCycle.set(server_editor_namespaceObject.DaylightCycle.LockTime);
                }
            });
            this._updateHandle = server_namespaceObject.system.runInterval((() => {
                const currentTime = server_namespaceObject.world.getTimeOfDay();
                if (this._pane.visible) {
                    if (this._clockType.value !== ClockType.MINECRAFT_CLOCK) {
                        const is24HrClock = this._clockType.value === ClockType.CLOCK_24HR ? true : false;
                        this._timeOfDayTimeString.set(convertTODToTime(server_namespaceObject.world.getTimeOfDay(), is24HrClock));
                    } else {
                        this._timeOfDayTimeString.set(currentTime.toString());
                    }
                }
            }), 3);
            this._messageSubscriptionHandle = subscribeTimeOfDayChangeMessages(((_id, _timeOfDayChange) => {
                this._uiSession.log.info(`Time of day change requested by ${_id} to ${_timeOfDayChange}`);
                this._storedSettings.set(_id, {
                    currentPreset: this._currentPreset.value,
                    currentTime: this._timeOfDayValue.value,
                    daylightCycle: this._daylightCycle.value,
                    customTime: this._customTime.value,
                    controlEnabled: this._customTimeHandle.enable,
                    controlVisible: this._customTimeHandle.visible
                });
                if (typeof _timeOfDayChange === "number") {
                    this._customTimeHandle.enable = true;
                    this._customTimeHandle.visible = true;
                    this._currentPreset.set(TODDropDown.None);
                    this._timeOfDayValue.set(_timeOfDayChange);
                    this.setDaylightCycle(server_editor_namespaceObject.DaylightCycle.LockTime, _timeOfDayChange, _uiSession);
                    this._daylightCycle.set(server_editor_namespaceObject.DaylightCycle.LockTime);
                    this._customTime.set(_timeOfDayChange);
                } else if (_timeOfDayChange === TODDropDown.None) {
                    this._customTimeHandle.enable = false;
                    this._customTimeHandle.visible = false;
                    this._currentPreset.set(_timeOfDayChange);
                    this._timeOfDayValue.set(0);
                    this.setDaylightCycle(server_editor_namespaceObject.DaylightCycle.Normal, 0, _uiSession);
                    this._daylightCycle.set(server_editor_namespaceObject.DaylightCycle.Normal);
                    this._customTime.set(0);
                } else {
                    throw new Error(`Invalid time of day change value: ${typeof _timeOfDayChange}`);
                }
                this.saveSettings();
            }), (_id => {
                const stored = this._storedSettings.get(_id);
                if (stored) {
                    this._customTimeHandle.enable = stored.controlEnabled;
                    this._customTimeHandle.visible = stored.controlVisible;
                    this._currentPreset.set(stored.currentPreset);
                    this._timeOfDayValue.set(stored.currentTime);
                    this.setDaylightCycle(stored.daylightCycle, stored.currentTime, _uiSession);
                    this._daylightCycle.set(stored.daylightCycle);
                    this._customTime.set(stored.customTime);
                }
            }));
            this.loadSettings();
        }
        createMenuItem(menu) {
            menu.addItem({
                label: "resourcePack.editor.timeOfDay.menu.title",
                tooltip: "resourcePack.editor.timeOfDay.menu.tooltip"
            }, this.openMenuAction);
        }
        setDaylightCycle(daylightCycle, currentTime, uiSession) {
            this._daylightCycle.set(daylightCycle);
            try {
                server_namespaceObject.world.getDimension("overworld").runCommand(`alwaysday ${(daylightCycle === server_editor_namespaceObject.DaylightCycle.AlwaysDay || daylightCycle === server_editor_namespaceObject.DaylightCycle.LockTime).toString()}`);
                const timeStr = daylightCycle === server_editor_namespaceObject.DaylightCycle.Normal ? "started" : "stopped";
                uiSession.log.info(`Time ${timeStr}`);
                if (daylightCycle === server_editor_namespaceObject.DaylightCycle.AlwaysDay) {
                    server_namespaceObject.world.setTimeOfDay(TODDropDown.Noon);
                } else {
                    server_namespaceObject.world.setTimeOfDay(currentTime);
                }
            } catch (_err) {
                uiSession.log.error("Unable to adjust daylight cycle due to unknown error.", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
        }
        loadSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(TimeOfDay_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const storeItem = group.fetchItem(TimeOfDay_PERSISTENCE_GROUPITEM_NAME);
                if (storeItem && storeItem.value) {
                    try {
                        const storedSettings = storeItem.value;
                        this._clockType.set(storedSettings.clockType);
                        this._customTime.set(storedSettings.customTime);
                        this._daylightCycle.set(storedSettings.daylightCycle);
                        this._currentPreset.set(storedSettings.currentPreset);
                        if (this._currentPreset.value === TODDropDown.None) {
                            this._customTimeHandle.enable = true;
                            this._customTimeHandle.visible = true;
                        } else {
                            this._customTimeHandle.enable = false;
                            this._customTimeHandle.visible = false;
                        }
                    } catch (error) {
                        this._uiSession.log.error("Fail to load the settings, error: " + stringFromException(error));
                    }
                }
                group.dispose();
            }
        }
        saveSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(TimeOfDay_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const settings = {
                    clockType: this._clockType.value,
                    currentPreset: this._currentPreset.value,
                    customTime: this._customTime.value,
                    daylightCycle: this._daylightCycle.value
                };
                const storeItem = group.getOrCreateItem(TimeOfDay_PERSISTENCE_GROUPITEM_NAME, settings);
                if (storeItem) {
                    storeItem.commit();
                }
                group.dispose();
                return;
            }
            this._uiSession.log.error("Fail to save settings for Time Of Day");
        }
        teardown() {
            if (this._updateHandle) {
                server_namespaceObject.system.clearRun(this._updateHandle);
            }
            if (this._messageSubscriptionHandle) {
                unsubscribeTimeOfDayChangeMessages(this._messageSubscriptionHandle);
            }
        }
    }
    TimeOfDayBehavior.BEHAVIOR_NAME = "Time of Day";
    const STORED_LOCATION_GROUP_SETTINGS = "editor:navigation";
    const STORED_LOCATION_GROUP_ITEM_SETTINGS = "settings";
    const STORED_LOCATION_WORLD_PROPERTY_NAME = "goto-mark:storedLocations";
    const STORED_LOCATION_NAME_MAX_LENGTH = 16;
    const WHITE_RGBA = {
        red: 1,
        green: 1,
        blue: 1,
        alpha: 1
    };
    const BLACK_RGBA = {
        red: 0,
        green: 0,
        blue: 0,
        alpha: 1
    };
    const MAX_LOADED_CHUNK_SIZE = 78;
    const CACHE_LENGTH = 4 * MAX_LOADED_CHUNK_SIZE;
    const CACHE_UPDATE_DISTANCE = 16;
    const CACHE_MAX_SIZE = (CACHE_LENGTH + 1) * (CACHE_LENGTH + 1);
    const MAP_IMAGE_SIZE = 35;
    var MapSize;
    (function(MapSize) {
        MapSize[MapSize["Small"] = 0] = "Small";
        MapSize[MapSize["Middle"] = 1] = "Middle";
        MapSize[MapSize["Large"] = 2] = "Large";
    })(MapSize || (MapSize = {}));
    var Navigation_Direction;
    (function(Direction) {
        Direction[Direction["North"] = 0] = "North";
        Direction[Direction["East"] = 1] = "East";
        Direction[Direction["South"] = 2] = "South";
        Direction[Direction["West"] = 3] = "West";
        Direction[Direction["Northeast"] = 4] = "Northeast";
        Direction[Direction["Southwest"] = 5] = "Southwest";
        Direction[Direction["Southeast"] = 6] = "Southeast";
        Direction[Direction["Northwest"] = 7] = "Northwest";
    })(Navigation_Direction || (Navigation_Direction = {}));
    const mapSizeInPixels = {
        [MapSize.Small]: 64,
        [MapSize.Middle]: 128,
        [MapSize.Large]: 256
    };
    const pixelFactors = {
        [MapSize.Small]: 4,
        [MapSize.Middle]: 2,
        [MapSize.Large]: 1
    };
    const DimensionIds = {
        "minecraft:overworld": 0,
        "minecraft:nether": 1,
        "minecraft:the_end": 2
    };
    var NavigationTelemetry;
    (function(NavigationTelemetry) {
        NavigationTelemetry["ShowMapToggle"] = "ShowMapToggle";
        NavigationTelemetry["TeleportToLocation"] = "TeleportToLocation";
        NavigationTelemetry["StoredLocationsChanged"] = "StoredLocationsChanged";
        NavigationTelemetry["TeleportToStoredLocation"] = "TeleportToStoredLocation";
        NavigationTelemetry["DeleteStoredLocation"] = "DeleteStoredLocation";
        NavigationTelemetry["SaveLocation"] = "SaveLocation";
        NavigationTelemetry["TeleportViaMap"] = "TeleportViaMap";
        NavigationTelemetry["TeleportToPlayer"] = "TeleportToPlayer";
        NavigationTelemetry["ToggleSelectAll"] = "ToggleSelectAll";
        NavigationTelemetry["BulkDeleteInitiated"] = "BulkDeleteInitiated";
        NavigationTelemetry["CreateNewLocation"] = "CreateNewLocation";
    })(NavigationTelemetry || (NavigationTelemetry = {}));
    class NavigationBehavior {
        constructor(uiSession, parentMenu) {
            this.uiSession = uiSession;
            this.mapPayload = (0, server_editor_namespaceObject.makeObservable)("");
            this.previousDirectionPlayerIsFacing = Navigation_Direction.North;
            this.mapSizeSelection = (0, server_editor_namespaceObject.makeObservable)(MapSize.Small);
            this.selectedLocationIndex = 0;
            this.quickActionMode = (0, server_editor_namespaceObject.makeObservable)(0);
            this.lastUpdateTimestamp = 0;
            this.previousPlayerIds = new Set;
            this.initializedMinimapCache = false;
            this.openMenuAction = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.parentPane?.show();
                }
            });
            this.isWithinPlayerIconArea = (x, z) => z >= -15 && z <= 12 && x >= -9 && x <= 10 && !((x >= -9 && x <= -6 || x >= 7 && x <= 10) && (z >= -15 && z <= -8 || z >= 9 && z <= 12) || (x >= -5 && x <= -2 || x >= 3 && x <= 6) && z >= -15 && z <= -12);
            this.isWhiteBlockInPlayerIcon = (x, z) => x >= -1 && x <= 2 && z >= -11 && z <= 8 || (x >= -5 && x <= -2 || x >= 3 && x <= 6) && z >= -7 && z <= 8;
            this.playerIconMap = new Map([ [ Navigation_Direction.North, [ (z, x) => this.isWithinPlayerIconArea(x, z), (z, x) => this.isWhiteBlockInPlayerIcon(x, z) ] ], [ Navigation_Direction.East, [ (z, x) => this.isWithinPlayerIconArea(z, -x), (z, x) => this.isWhiteBlockInPlayerIcon(z, -x) ] ], [ Navigation_Direction.South, [ (z, x) => this.isWithinPlayerIconArea(x, -z), (z, x) => this.isWhiteBlockInPlayerIcon(x, -z) ] ], [ Navigation_Direction.West, [ (z, x) => this.isWithinPlayerIconArea(z, x), (z, x) => this.isWhiteBlockInPlayerIcon(z, x) ] ], [ Navigation_Direction.Northwest, [ (z, x) => z >= -12 && z <= 12 && x >= -12 && x <= 12 && !(this.playerIconAreaIndexArrays[x + 12].includes(z) || this.playerIconAreaIndexArrays[z + 12].includes(x)), (z, x) => this.playerIconWhiteBlockIndexArrays[x + 12].includes(z) || this.playerIconWhiteBlockIndexArrays[z + 12].includes(x) ] ], [ Navigation_Direction.Northeast, [ (z, x) => z >= -12 && z <= 12 && x >= -12 && x <= 12 && !(this.playerIconAreaIndexArrays[-x + 12].includes(z) || this.playerIconAreaIndexArrays[z + 12].includes(-x)), (z, x) => this.playerIconWhiteBlockIndexArrays[-x + 12].includes(z) || this.playerIconWhiteBlockIndexArrays[z + 12].includes(-x) ] ], [ Navigation_Direction.Southeast, [ (z, x) => z >= -12 && z <= 12 && x >= -12 && x <= 12 && !(this.playerIconAreaIndexArrays[-x + 12].includes(-z) || this.playerIconAreaIndexArrays[-z + 12].includes(-x)), (z, x) => this.playerIconWhiteBlockIndexArrays[-x + 12].includes(-z) || this.playerIconWhiteBlockIndexArrays[-z + 12].includes(-x) ] ], [ Navigation_Direction.Southwest, [ (z, x) => z >= -12 && z <= 12 && x >= -12 && x <= 12 && !(this.playerIconAreaIndexArrays[x + 12].includes(-z) || this.playerIconAreaIndexArrays[-z + 12].includes(x)), (z, x) => this.playerIconWhiteBlockIndexArrays[x + 12].includes(-z) || this.playerIconWhiteBlockIndexArrays[-z + 12].includes(x) ] ] ]);
            this.playerIconAreaIndexArrays = [ [ -12, -11, -8, -7, -6, -5, -2, -1, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ], [ -7, -6, -1, 4, 5, 6, 7, 8, 9, 10, 11, 12 ], [ 5, 6, 7, 8, 9, 10, 11, 12 ], [ 6, 7, 8, 9, 10, 11, 12 ], [ 7, 8, 9, 10, 11, 12 ], [ 8, 9, 10, 11, 12 ], [ 9, 10, 11, 12 ], [ 10, 11, 12 ], [ 11, 12 ], [ 12 ], [], [], [ 12 ], [ 12 ], [ 11, 12 ], [ 12 ], [], [], [ 12 ], [ 11, 12 ], [ 10, 11, 12 ], [ 9, 10, 11, 12 ], [ 10, 11, 12 ], [ 11, 12 ], [ 12 ] ];
            this.playerIconWhiteBlockIndexArrays = [ [], [], [], [], [ -7, -6, -1, 0 ], [ -7, -6, -5 - 2, -1, 0, 1 ], [ -6, -5, -4, -3, -2, -1, 0, 1, 2 ], [ -5, -4, -3, -2, -1, 0, 1, 2, 3 ], [ -4, -3, -2, -1, 0, 1, 2, 3, 4 ], [ -3, -2, -1, 0, 1, 2, 3, 4, 5 ], [ -2, -1, 0, 1, 2, 3, 4, 5, 6 ], [ -1, 0, 1, 2, 3, 4, 5, 6, 7 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ], [ 1, 2, 3, 4, 5, 6, 7, 8 ], [ 2, 3, 4, 5, 6, 7, 8, 9 ], [ 3, 4, 5, 6, 7, 8 ], [ 4, 5, 6, 7 ], [ 5, 6 ], [], [], [], [], [], [], [] ];
            uiSession.log.debug(`Initializing extension [${uiSession.extensionContext.extensionInfo.name}] for player [${uiSession.extensionContext.player.name}]`);
            this.createMenuItem(parentMenu);
            this.persistenceManager = getPersistenceManager(uiSession.extensionContext.player);
            this.telemetryManager = new TelemetryManager(uiSession.extensionContext.player, TelemetrySource.Navigation);
            this.previousLocation = uiSession.extensionContext.player.location;
            this.storedLocations = [];
            this.transactionHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(uiSession.extensionContext.transactionManager, (payload => {
                uiSession.log.info(`Teleporting to location ${lib.Vector3Utils.toString(payload.current)}`);
                try {
                    uiSession.extensionContext.player.teleport(payload.current);
                } catch (e) {
                    uiSession.log.error(`Teleport failed: ${(0, server_editor_namespaceObject.stringFromException)(e)}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
            }), (payload => {
                uiSession.log.info(`Teleporting to location ${lib.Vector3Utils.toString(payload.destination)}`);
                try {
                    uiSession.extensionContext.player.teleport(payload.destination);
                } catch (e) {
                    uiSession.log.error(`Teleport failed: ${(0, server_editor_namespaceObject.stringFromException)(e)}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
            }));
            this.surfaceBlockColorCache = {
                center: uiSession.extensionContext.player.location,
                blocks: {},
                isUpdating: false
            };
            this.locationMarkRenderingStorage = {};
            this.loadLocationsFromWorld();
            this.startStoredLocationsSynchronization();
            this.loadSettings();
            this._buildParentPane();
            uiSession.actionBar.registerItem("editor:actionBarItem:goToMark", this.openMenuAction, {
                label: "resourcePack.editor.goToMark.title",
                icon: "pack://textures/editor/goto-mark.png",
                tooltipTitle: "resourcePack.editor.goToMark.actionBar.tooltip.title",
                tooltipDescription: "resourcePack.editor.goToMark.actionBar.tooltip.description",
                executeOnAdd: true
            });
        }
        teardown() {
            this.uiSession.log.debug(`Shutting down extension [${this.uiSession.extensionContext.extensionInfo.name}] for player [${this.uiSession.extensionContext.player.name}]`);
            if (this.updateHandle) {
                server_namespaceObject.system.clearRun(this.updateHandle);
            }
            if (this.cacheClearHandle) {
                server_namespaceObject.system.clearRun(this.cacheClearHandle);
            }
            if (this.cacheUpdateHandle) {
                server_namespaceObject.system.clearRun(this.cacheUpdateHandle);
            }
            if (this.storedLocationsSyncHandle) {
                server_namespaceObject.system.clearRun(this.storedLocationsSyncHandle);
            }
            if (this.playerListSyncHandle) {
                server_namespaceObject.system.clearRun(this.playerListSyncHandle);
            }
        }
        createMenuItem(menu) {
            menu.addItem({
                label: "resourcePack.editor.goToMark.title",
                tooltip: "resourcePack.editor.goToMark.menuTooltip"
            }, this.openMenuAction);
        }
        _buildParentPane() {
            this.parentPane = this.uiSession.createPropertyPane({
                title: "resourcePack.editor.goToMark.title",
                uniqueId: "editor:pane:goToMark",
                infoTooltip: {
                    description: [ "resourcePack.editor.goToMark.tooltip", {
                        link: "https://aka.ms/BedrockEditorNavigationPanel",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this.parentPane.onPropertyPaneVisibilityUpdated.subscribe((data => {
                if (!this.initializedMinimapCache && data.isVisible) {
                    this.initializedMinimapCache = true;
                    this.updateLocationMarkRenderingStorage();
                    this.updateSurfaceBlockColorCache().then((() => {
                        this.mapPayload.set(this._createMiniMap());
                    })).catch((e => {
                        this.uiSession.log.error(`${e.message}`, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                    })).finally((() => {
                        this.surfaceBlockColorCache.isUpdating = false;
                    }));
                }
            }));
            this.buildMinimapPane();
            this.buildUsersPane();
            this.buildLocationPane();
            return this.parentPane;
        }
        buildMinimapPane() {
            if (!this.parentPane) {
                this.uiSession.log.error("An error occurred: No UI pane could be found", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const minimapPane = this.parentPane.createSubPane({
                title: "resourcePack.editor.goToMark.pane.mapPane.heading",
                collapsed: false
            });
            const currentLocation = lib.Vector3Utils.floor(this.uiSession.extensionContext.player.location);
            const playerLocation = (0, server_editor_namespaceObject.makeObservable)(currentLocation);
            this.previousLocation = {
                ...currentLocation
            };
            this.mapSizeDropDown = minimapPane.addDropdown(this.mapSizeSelection, {
                visible: true,
                enable: true,
                title: "resourcePack.editor.goToMark.pane.mapSize",
                entries: [ {
                    label: "64 x 64 blocks",
                    value: MapSize.Small
                }, {
                    label: "128 x 128 blocks",
                    value: MapSize.Middle
                }, {
                    label: "256 x 256 blocks",
                    value: MapSize.Large
                } ],
                onChange: () => {
                    this.updateSurfaceBlockColorCache().then((() => {
                        this.mapPayload.set(this._createMiniMap());
                    })).catch((e => {
                        this.uiSession.log.error(`${e.message}`, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                    })).finally((() => {
                        this.surfaceBlockColorCache.isUpdating = false;
                    }));
                    this.saveSettings();
                }
            });
            this.refreshMapButton = minimapPane.addButton(this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.updateSurfaceBlockColorCache().then((() => {
                        this.mapPayload.set(this._createMiniMap());
                    })).catch((e => {
                        this.uiSession.log.error(e.message, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                    })).finally((() => {
                        this.surfaceBlockColorCache.isUpdating = false;
                    }));
                }
            }), {
                title: "resourcePack.editor.goToMark.pane.refreshMap",
                visible: true,
                enable: true
            });
            this.mapImage = minimapPane.addImage(this.mapPayload, {
                visible: true,
                imageSize: MAP_IMAGE_SIZE,
                alignment: server_editor_namespaceObject.LayoutAlignment.Center,
                onClick: (x, y) => {
                    const mapSize = mapSizeInPixels[this.mapSizeSelection.value];
                    const me = this.uiSession.extensionContext.player;
                    const currentLocation = lib.Vector3Utils.floor(me.location);
                    const clickedXZLocation = {
                        x: currentLocation.x + Math.floor(x * mapSize) - mapSize / 2,
                        y: 0,
                        z: currentLocation.z + Math.floor(y * mapSize) - mapSize / 2
                    };
                    const cacheKey = this.createCacheKey(clickedXZLocation.x, clickedXZLocation.z, DimensionIds[me.dimension.id]);
                    const blockBelowPlayerCacheKey = this.createCacheKey(currentLocation.x, currentLocation.z, DimensionIds[me.dimension.id]);
                    const cache = this.surfaceBlockColorCache;
                    if (cache.blocks[cacheKey] && cache.blocks[blockBelowPlayerCacheKey]) {
                        const blockBelowPlayerLocation = cache.blocks[blockBelowPlayerCacheKey].location;
                        const blockLocation = cache.blocks[cacheKey].location;
                        const teleportLocation = {
                            x: blockLocation.x,
                            y: blockLocation.y + currentLocation.y - blockBelowPlayerLocation.y,
                            z: blockLocation.z
                        };
                        this.teleportTo(teleportLocation);
                        this.telemetryManager.fireTelemetryEvent(NavigationTelemetry.TeleportViaMap);
                    } else {
                        this.uiSession.log.error(`Please wait for the blocks to be loaded`, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                    }
                }
            });
            const teleportLimit = 3e7;
            const teleportSubPane = minimapPane.createSubPane({
                layout: server_editor_namespaceObject.PaneLayoutType.Horizontal,
                hasExpander: false,
                hasMargins: false
            });
            teleportSubPane.addVector3(playerLocation, {
                tooltip: "resourcePack.editor.goToMark.pane.location.tooltip",
                min: {
                    x: -teleportLimit,
                    y: -teleportLimit,
                    z: -teleportLimit
                },
                max: {
                    x: teleportLimit,
                    y: teleportLimit,
                    z: teleportLimit
                },
                style: {
                    width: server_editor_namespaceObject.LayoutFlex.Grow,
                    minWidth: 10
                },
                hasClearButton: false
            });
            teleportSubPane.addButton(this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const panelLocation = playerLocation.value;
                    this.teleportTo(panelLocation);
                    this.telemetryManager.fireTelemetryEvent(NavigationTelemetry.TeleportToLocation);
                }
            }), {
                icon: "pack://textures/editor/Teleport.png",
                hiddenLabel: true,
                shrinkToIcon: true,
                title: "resourcePack.editor.goToMark.pane.teleport",
                visible: true,
                style: {
                    verticalAlignment: server_editor_namespaceObject.LayoutAlignment.Center
                }
            });
            this.updateHandle = server_namespaceObject.system.runInterval((() => {
                if (!this.parentPane?.visible) {
                    return;
                }
                const player = this.uiSession.extensionContext.player;
                const currentLocation = lib.Vector3Utils.floor(player.location);
                const previousLocation = lib.Vector3Utils.floor(this.previousLocation);
                const directionPlayerIsFacing = this.getCurrentDirectionPlayerIsFacing();
                if (lib.Vector3Utils.equals(currentLocation, previousLocation) && directionPlayerIsFacing === this.previousDirectionPlayerIsFacing) {
                    return;
                }
                this.previousLocation = currentLocation;
                playerLocation.set({
                    ...currentLocation
                });
                this.previousDirectionPlayerIsFacing = directionPlayerIsFacing;
            }), 1);
            this.cacheUpdateHandle = server_namespaceObject.system.runInterval((() => {
                if (!this.parentPane?.visible) {
                    return;
                }
                const cache = this.surfaceBlockColorCache;
                const playerLocation = lib.Vector3Utils.floor(this.uiSession.extensionContext.player.location);
                if (!this.isPlayerFarFromCenter(cache.center, playerLocation)) {
                    return;
                }
                this.updateSurfaceBlockColorCache().then((() => {
                    this.mapPayload.set(this._createMiniMap());
                })).catch((e => {
                    this.uiSession.log.error(e.message, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                })).finally((() => {
                    cache.isUpdating = false;
                }));
            }), 10);
            this.cacheClearHandle = server_namespaceObject.system.runInterval((() => {
                if (!this.parentPane?.visible) {
                    return;
                }
                const cache = this.surfaceBlockColorCache;
                if (Object.keys(cache.blocks).length > CACHE_MAX_SIZE) {
                    this.uiSession.log.debug(`Cache Clean starts: cache size ${Object.keys(cache.blocks).length} at ${Date.now().toString()}`);
                    const latestPlayerLocation = lib.Vector3Utils.floor(this.uiSession.extensionContext.player.location);
                    for (const key in cache.blocks) {
                        if (Object.prototype.hasOwnProperty.call(cache.blocks, key)) {
                            if (this.shouldDeleteItemFromCache(latestPlayerLocation, cache.blocks[key].location)) {
                                delete cache.blocks[key];
                            }
                        }
                    }
                    this.uiSession.log.debug(`Cache Clean finished!: cache size ${Object.keys(cache.blocks).length} at ${Date.now().toString()}`);
                }
            }), 20);
            minimapPane.addDivider();
        }
        buildUsersPane() {
            if (!this.parentPane) {
                this.uiSession.log.error("An error occurred: No UI pane could be found", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const usersPane = this.parentPane.createSubPane({
                title: "resourcePack.editor.goToMark.pane.usersPane.heading",
                collapsed: true
            });
            const players = server_namespaceObject.world.getAllPlayers();
            if (!this.playerColors) {
                this.playerColors = new Map;
            }
            players.forEach((player => {
                if (!this.playerColors?.has(player.id)) {
                    const color = this.generatePlayerColor(player.id);
                    this.playerColors?.set(player.id, color);
                }
                this.previousPlayerIds.add(player.id);
            }));
            this.usersListPane = usersPane.addListPane({
                height: 20,
                defaultSlots: this.createUserSlots(players),
                slotConfig: {
                    height: 4,
                    clickable: false,
                    outline: true,
                    variant: server_editor_namespaceObject.ListPaneSlotVariant.Muted,
                    entryLayout: {
                        mainSection: [ {
                            type: server_editor_namespaceObject.ListPaneEntryType.Image,
                            size: 3.2
                        }, {
                            type: server_editor_namespaceObject.ListPaneEntryType.Text,
                            size: server_editor_namespaceObject.LayoutFlex.Grow,
                            alignment: server_editor_namespaceObject.LayoutAlignment.Start
                        } ],
                        outerSection: [ {
                            type: server_editor_namespaceObject.ListPaneEntryType.Image,
                            size: 3.6,
                            alignment: server_editor_namespaceObject.LayoutAlignment.Center
                        }, {
                            type: server_editor_namespaceObject.ListPaneEntryType.Button,
                            size: 4
                        } ]
                    }
                }
            });
            this.startPlayerListSynchronization();
        }
        startPlayerListSynchronization() {
            this.playerListSyncHandle = server_namespaceObject.system.runInterval((() => {
                if (!this.parentPane?.visible || !this.usersListPane) {
                    return;
                }
                try {
                    const currentPlayers = server_namespaceObject.world.getAllPlayers();
                    const currentPlayerIds = new Set;
                    const validPlayers = currentPlayers.filter((player => {
                        try {
                            if (player && player.id && player.name) {
                                currentPlayerIds.add(player.id);
                                return true;
                            }
                            return false;
                        } catch {
                            return false;
                        }
                    }));
                    let hasChanges = false;
                    validPlayers.forEach((player => {
                        if (!this.previousPlayerIds.has(player.id)) {
                            if (!this.playerColors?.has(player.id)) {
                                const color = this.generatePlayerColor(player.id);
                                this.playerColors?.set(player.id, color);
                            }
                            hasChanges = true;
                            this.uiSession.log.info(`Player ${player.name} joined`);
                        }
                    }));
                    this.previousPlayerIds.forEach((playerId => {
                        if (!currentPlayerIds.has(playerId)) {
                            this.playerColors?.delete(playerId);
                            hasChanges = true;
                            this.uiSession.log.info(`Player with id ${playerId} left`);
                        }
                    }));
                    if (hasChanges || this.previousPlayerIds.size !== currentPlayerIds.size) {
                        this.previousPlayerIds = currentPlayerIds;
                        this.usersListPane.updateSlots(this.createUserSlots(validPlayers));
                    }
                } catch (error) {
                    this.uiSession.log.error(`Error syncing player list: ${(0, server_editor_namespaceObject.stringFromException)(error)}`);
                }
            }), 20);
        }
        createUserSlots(players) {
            return players.map((player => {
                const playerColor = this.playerColors?.get(player.id) || WHITE_RGBA;
                const isCurrentPlayer = player.id === this.uiSession.extensionContext.player.id;
                return {
                    entries: [ {
                        type: server_editor_namespaceObject.ListPaneEntryType.Image,
                        value: {
                            path: "pack://textures/editor/Player.png",
                            type: server_editor_namespaceObject.ImageResourceType.Icon
                        }
                    }, {
                        type: server_editor_namespaceObject.ListPaneEntryType.Text,
                        value: player.name
                    }, {
                        type: server_editor_namespaceObject.ListPaneEntryType.Image,
                        value: {
                            path: this.createColorSquareImage(playerColor),
                            type: server_editor_namespaceObject.ImageResourceType.Default
                        }
                    }, {
                        type: server_editor_namespaceObject.ListPaneEntryType.Button,
                        icon: "pack://textures/editor/Teleport.png",
                        tooltip: `resourcePack.editor.goToMark.pane.teleport`,
                        enabled: !isCurrentPlayer,
                        onClick: () => {
                            if (!isCurrentPlayer) {
                                this.teleportToPlayer(player);
                            }
                        }
                    } ]
                };
            }));
        }
        generatePlayerColor(playerId) {
            const colors = [ {
                red: 1,
                green: 0,
                blue: 0,
                alpha: 1
            }, {
                red: 0,
                green: 1,
                blue: 0,
                alpha: 1
            }, {
                red: 0,
                green: 0,
                blue: 1,
                alpha: 1
            }, {
                red: 1,
                green: 1,
                blue: 0,
                alpha: 1
            }, {
                red: 1,
                green: 0,
                blue: 1,
                alpha: 1
            }, {
                red: 0,
                green: 1,
                blue: 1,
                alpha: 1
            }, {
                red: 1,
                green: .5,
                blue: 0,
                alpha: 1
            }, {
                red: .5,
                green: 0,
                blue: 1,
                alpha: 1
            }, {
                red: .5,
                green: .5,
                blue: .5,
                alpha: 1
            }, {
                red: 0,
                green: 0,
                blue: 0,
                alpha: 1
            }, {
                red: 1,
                green: .75,
                blue: .8,
                alpha: 1
            }, {
                red: .6,
                green: .4,
                blue: .2,
                alpha: 1
            }, {
                red: 1,
                green: .5,
                blue: .31,
                alpha: 1
            }, {
                red: .75,
                green: 1,
                blue: 0,
                alpha: 1
            } ];
            let hash = 0;
            for (let i = 0; i < playerId.length; i++) {
                const char = playerId.charCodeAt(i);
                hash = (hash << 5) - hash + char;
                hash = hash & hash;
            }
            const colorIndex = Math.abs(hash) % colors.length;
            return colors[colorIndex];
        }
        createColorSquareImage(color) {
            const size = 16;
            const rgbValues = [];
            for (let i = 0; i < size * size; i++) {
                rgbValues.push({
                    r: Math.round(color.red * 255),
                    g: Math.round(color.green * 255),
                    b: Math.round(color.blue * 255)
                });
            }
            return CreateBase64ImageFromRGB(rgbValues, size, size);
        }
        teleportToPlayer(targetPlayer) {
            try {
                const targetLocation = targetPlayer.location;
                this.teleportTo(targetLocation);
                this.uiSession.log.info(`Teleporting to player ${targetPlayer.name}`);
                this.telemetryManager.fireTelemetryEvent(NavigationTelemetry.TeleportToPlayer);
            } catch (e) {
                this.uiSession.log.error(`Failed to teleport to player: ${(0, server_editor_namespaceObject.stringFromException)(e)}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
        }
        mapDropdownItems() {
            return this.storedLocations.map(((v, index) => {
                const item = {
                    label: `${index + 1}: ${v.name} (${lib.Vector3Utils.toString(v.location)})`,
                    value: index
                };
                return item;
            }));
        }
        createTransaction(current, destination) {
            const transactionPayload = {
                current,
                destination
            };
            if (!this.uiSession.scratchStorage) {
                return;
            }
            this.uiSession.extensionContext.transactionManager.openTransaction("goto position");
            this.transactionHandler.addUserDefinedOperation(transactionPayload, "Goto(Teleport)");
            this.uiSession.extensionContext.transactionManager.commitOpenTransaction();
        }
        teleportTo(destination) {
            this.createTransaction(this.uiSession.extensionContext.player.location, destination);
            this.uiSession.log.info(`Teleporting to location ${lib.Vector3Utils.toString(destination)}`);
            try {
                this.uiSession.extensionContext.player.teleport(destination);
            } catch (e) {
                this.uiSession.log.error(`Teleport failed: ${(0, server_editor_namespaceObject.stringFromException)(e)}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
        }
        buildLocationPane() {
            if (!this.parentPane) {
                this.uiSession.log.error("An error occurred: No UI pane could be found", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const locationPane = this.parentPane.createSubPane({
                title: "resourcePack.editor.goToMark.pane.locationPane.title",
                collapsed: false
            });
            this.deleteConfirmDialog = this.uiSession.dialogManager.registerDialog({
                uniqueId: "navigation:deleteConfirm",
                width: 80
            });
            this.deleteConfirmDialog.contentPane.addText("editor.sharedUtils.modaldialogconfirmation.title", {
                border: false
            });
            this.deleteConfirmDialog.controlPane.addButton((() => {
                this.performBulkDelete();
                this.deleteConfirmDialog?.sendDismiss();
            }), {
                title: "editor.sharedUtils.modaldialogconfirmation.yes",
                variant: server_editor_namespaceObject.ButtonVariant.Primary
            });
            this.deleteConfirmDialog.controlPane.addButton((() => {
                this.deleteConfirmDialog?.sendDismiss();
            }), {
                title: "editor.sharedUtils.modaldialogconfirmation.cancel",
                variant: server_editor_namespaceObject.ButtonVariant.Secondary
            });
            this.singleDeleteConfirmDialog = this.uiSession.dialogManager.registerDialog({
                uniqueId: "navigation:singleDeleteConfirm",
                width: 80,
                height: 30
            });
            this.singleDeleteConfirmDialog.contentPane.addText("editor.sharedUtils.modaldialogconfirmation.title");
            this.singleDeleteConfirmDialog.controlPane.addButton((() => {
                this.deleteCurrentLocation();
                this.singleDeleteConfirmDialog?.sendDismiss();
            }), {
                title: "editor.sharedUtils.modaldialogconfirmation.yes",
                variant: server_editor_namespaceObject.ButtonVariant.Primary
            });
            this.singleDeleteConfirmDialog.controlPane.addButton((() => this.singleDeleteConfirmDialog?.sendDismiss()), {
                title: "editor.sharedUtils.modaldialogconfirmation.cancel",
                variant: server_editor_namespaceObject.ButtonVariant.Secondary
            });
            locationPane.addToggleGroup(this.quickActionMode, {
                entries: [ {
                    icon: "pack://textures/editor/Point-Subtract.png",
                    value: 1
                }, {
                    icon: "trashCanIcon",
                    tooltip: "resourcePack.editor.goToMark.pane.locationPane.delete",
                    value: 2
                } ],
                onChange: newValue => {
                    switch (newValue) {
                      case 1:
                        this.toggleSelectAll();
                        break;

                      case 2:
                        this.deleteSelectedLocations();
                        break;
                    }
                    this.quickActionMode.set(0);
                }
            });
            const locationListHeaderPane = locationPane.createSubPane({
                hasExpander: false,
                hasMargins: false,
                layout: server_editor_namespaceObject.PaneLayoutType.Horizontal
            });
            locationListHeaderPane.addText("", {
                style: {
                    width: server_editor_namespaceObject.LayoutFlex.Grow,
                    minWidth: 0,
                    verticalAlignment: server_editor_namespaceObject.LayoutAlignment.End
                },
                title: "resourcePack.editor.goToMark.pane.locationPane.listHeader",
                border: false
            });
            locationListHeaderPane.addButton((() => {
                this.createNewLocation();
            }), {
                tooltip: "resourcePack.editor.goToMark.pane.locationPane.store",
                hiddenLabel: true,
                shrinkToIcon: true,
                icon: "pack://textures/editor/plus.png"
            });
            locationPane.addDivider();
            this.storedLocationsList = locationPane.addListPane({
                height: 20,
                onSlotClicked: slot => {
                    const userData = slot.getUserData();
                    this.selectedLocationIndex = userData;
                    this.updateLocationDetails();
                    if (!slot.selected) {
                        this.storedLocationsList?.selectSlot(slot.id, true);
                        this.locationDetailsPane?.show();
                    } else {
                        slot.setSelected(false);
                        this.locationDetailsPane?.hide();
                    }
                },
                defaultSlots: this.createLocationSlots(),
                slotConfig: {
                    height: 4.4,
                    clickable: true,
                    variant: server_editor_namespaceObject.ListPaneSlotVariant.Secondary,
                    entryLayout: {
                        mainSection: [ {
                            type: server_editor_namespaceObject.ListPaneEntryType.Bool,
                            size: 3.6
                        }, {
                            type: server_editor_namespaceObject.ListPaneEntryType.Image,
                            size: 3.2
                        }, {
                            type: server_editor_namespaceObject.ListPaneEntryType.Text,
                            size: server_editor_namespaceObject.LayoutFlex.Grow,
                            alignment: server_editor_namespaceObject.LayoutAlignment.Start
                        } ],
                        outerSection: [ {
                            type: server_editor_namespaceObject.ListPaneEntryType.Button,
                            size: 4
                        } ]
                    }
                }
            });
            this.locationDetailsPane = this.parentPane.drawerPane;
            this.locationDetailsPane.onPropertyPaneVisibilityUpdated.subscribe((data => {
                if (!data.isVisible) {
                    this.storedLocationsList?.selectSlot("", true);
                }
            }));
            this.updateLocationDetails();
        }
        loadLocationsFromWorld() {
            try {
                const fetchedLocationsString = server_namespaceObject.world.getDynamicProperty(STORED_LOCATION_WORLD_PROPERTY_NAME);
                if (!fetchedLocationsString) {
                    this.uiSession.log.info("No stored locations found in world storage");
                    this.storedLocations = [];
                    this.lastUpdateTimestamp = 0;
                } else {
                    const data = JSON.parse(fetchedLocationsString);
                    if (!data) {
                        this.storedLocations = [];
                        this.lastUpdateTimestamp = 0;
                        return;
                    }
                    this.storedLocations = data.locations || [];
                    this.lastUpdateTimestamp = data.lastUpdate;
                }
            } catch (e) {
                this.uiSession.log.info(`Exception ${(0, server_editor_namespaceObject.stringFromException)(e)} occurred during world storage load`);
                this.storedLocations = [];
                this.lastUpdateTimestamp = 0;
            }
        }
        startStoredLocationsSynchronization() {
            this.storedLocationsSyncHandle = server_namespaceObject.system.runInterval((() => {
                if (!this.parentPane?.visible) {
                    return;
                }
                try {
                    const worldDataString = server_namespaceObject.world.getDynamicProperty(STORED_LOCATION_WORLD_PROPERTY_NAME);
                    if (!worldDataString) return;
                    const data = JSON.parse(worldDataString);
                    if (data.lastUpdate > this.lastUpdateTimestamp && data.lastUpdatedBy !== this.uiSession.extensionContext.player.id) {
                        const oldLocations = [ ...this.storedLocations ];
                        this.storedLocations = data.locations || [];
                        this.lastUpdateTimestamp = data.lastUpdate || Date.now();
                        this.refreshLocationsList();
                        this.updateLocationDetails();
                        const deletedLocations = oldLocations.filter((oldLoc => !this.storedLocations.some((newLoc => newLoc.name === oldLoc.name && lib.Vector3Utils.equals(newLoc.location, oldLoc.location)))));
                        if (deletedLocations.length > 0) {
                            deletedLocations.forEach((deletedLoc => {
                                this.updateLocationMarkRenderingStorage(deletedLoc);
                            }));
                        }
                        this.updateLocationMarkRenderingStorage();
                        this.mapPayload?.set(this._createMiniMap());
                        this.uiSession.log.info("Received location update from another player");
                    }
                } catch (error) {
                    this.uiSession.log.error("Error occurred while checking for location updates: " + (0, 
                    server_editor_namespaceObject.stringFromException)(error));
                }
            }), 20);
        }
        createLocationSlots() {
            return this.storedLocations.map(((location, index) => ({
                entries: [ {
                    type: server_editor_namespaceObject.ListPaneEntryType.Bool,
                    value: false
                }, {
                    type: server_editor_namespaceObject.ListPaneEntryType.Image,
                    value: {
                        path: "pack://textures/editor/Pin_24.png",
                        type: server_editor_namespaceObject.ImageResourceType.Icon
                    }
                }, {
                    type: server_editor_namespaceObject.ListPaneEntryType.Text,
                    value: location.name
                }, {
                    type: server_editor_namespaceObject.ListPaneEntryType.Button,
                    icon: "pack://textures/editor/Teleport.png",
                    tooltip: "resourcePack.editor.goToMark.pane.teleport",
                    variant: server_editor_namespaceObject.ButtonVariant.Secondary,
                    onClick: () => {
                        this.teleportTo(location.location);
                        this.telemetryManager.fireTelemetryEvent(NavigationTelemetry.TeleportToLocation);
                    }
                } ],
                options: {
                    userData: index
                }
            })));
        }
        updateLocationDetails() {
            if (!this.locationDetailsPane) {
                return;
            }
            const oldNameInput = this.locationNameInput;
            const oldColorPicker = this.locationMarkColorPicker;
            const oldPositionInput = this.locationPositionInput;
            const oldTeleportButton = this.teleportButton;
            const oldDeleteButton = this.deleteButton;
            if (this.storedLocations.length === 0 || this.selectedLocationIndex < 0) {
                if (oldNameInput) oldNameInput.visible = false;
                if (oldColorPicker) oldColorPicker.visible = false;
                if (oldPositionInput) oldPositionInput.visible = false;
                if (oldTeleportButton) oldTeleportButton.visible = false;
                if (oldDeleteButton) oldDeleteButton.visible = false;
                this.locationDetailsPane.hide();
                return;
            }
            if (this.selectedLocationIndex >= this.storedLocations.length) {
                this.selectedLocationIndex = this.storedLocations.length - 1;
            }
            const currentLocation = this.storedLocations[this.selectedLocationIndex];
            if (!currentLocation) {
                this.locationDetailsPane.hide();
                return;
            }
            const nameObservable = (0, server_editor_namespaceObject.makeObservable)(currentLocation.name);
            const colorObservable = (0, server_editor_namespaceObject.makeObservable)(currentLocation.color);
            const positionObservable = (0, server_editor_namespaceObject.makeObservable)(currentLocation.location);
            if (oldNameInput) oldNameInput.visible = false;
            if (oldColorPicker) oldColorPicker.visible = false;
            if (oldPositionInput) oldPositionInput.visible = false;
            if (oldTeleportButton) oldTeleportButton.visible = false;
            if (oldDeleteButton) oldDeleteButton.visible = false;
            this.locationNameInput = this.locationDetailsPane.addString(nameObservable, {
                title: "resourcePack.editor.goToMark.pane.locationPane.inputName",
                onChange: newName => {
                    const trimmedName = newName.trim();
                    if (trimmedName.length > 0 && trimmedName.length <= STORED_LOCATION_NAME_MAX_LENGTH) {
                        const existingNames = this.storedLocations.filter(((_, index) => index !== this.selectedLocationIndex)).map((loc => loc.name.toLowerCase()));
                        let finalName = trimmedName;
                        if (existingNames.includes(finalName.toLowerCase())) {
                            finalName = this.getUniqueLocationName(finalName);
                            nameObservable.set(finalName);
                        }
                        this.storedLocations[this.selectedLocationIndex].name = finalName;
                        this.storeLocationsToPlayer();
                        this.refreshLocationsList();
                    } else if (trimmedName.length === 0) {
                        const defaultName = this.getUniqueLocationName("Location");
                        this.storedLocations[this.selectedLocationIndex].name = defaultName;
                        nameObservable.set(defaultName);
                        this.storeLocationsToPlayer();
                        this.refreshLocationsList();
                    } else if (trimmedName.length > STORED_LOCATION_NAME_MAX_LENGTH) {
                        const truncatedName = trimmedName.substring(0, STORED_LOCATION_NAME_MAX_LENGTH);
                        this.storedLocations[this.selectedLocationIndex].name = truncatedName;
                        nameObservable.set(truncatedName);
                        this.storeLocationsToPlayer();
                        this.refreshLocationsList();
                    }
                }
            });
            this.locationMarkColorPicker = this.locationDetailsPane.addColorPicker(colorObservable, {
                visible: true,
                enable: true,
                variant: server_editor_namespaceObject.ColorPickerPropertyItemVariant.Inline,
                title: "resourcePack.editor.goToMark.pane.locationPane.markColor",
                hiddenAlpha: true,
                onChange: color => {
                    this.storedLocations[this.selectedLocationIndex].color = {
                        ...color
                    };
                    this.storeLocationsToPlayer();
                    this.updateLocationMarkRenderingStorage();
                    this.mapPayload?.set(this._createMiniMap());
                }
            });
            const teleportLimit = 3e7;
            this.locationPositionInput = this.locationDetailsPane.addVector3(positionObservable, {
                title: "resourcePack.editor.goToMark.pane.location",
                min: {
                    x: -teleportLimit,
                    y: -teleportLimit,
                    z: -teleportLimit
                },
                max: {
                    x: teleportLimit,
                    y: teleportLimit,
                    z: teleportLimit
                },
                onChange: newPosition => {
                    this.storedLocations[this.selectedLocationIndex].location = {
                        ...newPosition
                    };
                    this.storeLocationsToPlayer();
                }
            });
            this.teleportButton = this.locationDetailsPane.addButton(this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const destination = this.storedLocations[this.selectedLocationIndex].location;
                    this.teleportTo(destination);
                    this.telemetryManager.fireTelemetryEvent(NavigationTelemetry.TeleportToStoredLocation);
                }
            }), {
                title: "resourcePack.editor.goToMark.pane.teleport",
                visible: true
            });
            this.deleteButton = this.locationDetailsPane.addButton(this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this.selectedLocationIndex < 0 || this.selectedLocationIndex >= this.storedLocations.length) {
                        this.uiSession.log.info("No selected location to delete");
                        return;
                    }
                    this.uiSession.dialogManager.activateDialog({
                        dialogId: "navigation:singleDeleteConfirm"
                    });
                }
            }), {
                title: "resourcePack.editor.goToMark.pane.locationPane.delete",
                visible: true
            });
        }
        deleteCurrentLocation() {
            if (this.selectedLocationIndex < 0 || this.selectedLocationIndex >= this.storedLocations.length) {
                this.uiSession.log.info("No selected location to delete");
                return;
            }
            const deleted = this.storedLocations.splice(this.selectedLocationIndex, 1)[0];
            this.updateLocationMarkRenderingStorage(deleted);
            this.storeLocationsToPlayer();
            if (this.storedLocations.length === 0) {
                this.selectedLocationIndex = -1;
            } else if (this.selectedLocationIndex >= this.storedLocations.length) {
                this.selectedLocationIndex = this.storedLocations.length - 1;
            }
            this.refreshLocationsList();
            this.updateLocationDetails();
            this.mapPayload?.set(this._createMiniMap());
            this.uiSession.log.info(`Deleted location "${deleted.name}"`);
            this.telemetryManager.fireTelemetryEvent(NavigationTelemetry.DeleteStoredLocation);
        }
        createNewLocation() {
            const currentLocation = lib.Vector3Utils.floor(this.uiSession.extensionContext.player.location);
            let counter = 1;
            let newName = `Location ${counter}`;
            const existingNames = this.storedLocations.map((loc => loc.name.toLowerCase()));
            while (existingNames.includes(newName.toLowerCase())) {
                counter++;
                newName = `Location ${counter}`;
            }
            this.uiSession.log.info(`Adding Location ${lib.Vector3Utils.toString(currentLocation)} as "${newName}"`);
            this.storedLocations.push({
                name: newName,
                location: currentLocation,
                color: {
                    ...WHITE_RGBA
                }
            });
            this.storeLocationsToPlayer();
            this.selectedLocationIndex = this.storedLocations.length - 1;
            this.refreshLocationsList();
            this.updateLocationDetails();
            this.updateLocationMarkRenderingStorage();
            this.mapPayload?.set(this._createMiniMap());
            this.telemetryManager.fireTelemetryEvent(NavigationTelemetry.CreateNewLocation);
        }
        getUniqueLocationName(baseName) {
            if (!baseName || baseName.trim() === "") {
                let counter = 1;
                let defaultName = `Location ${counter}`;
                const existingNames = this.storedLocations.map((loc => loc.name.toLowerCase()));
                while (existingNames.includes(defaultName.toLowerCase())) {
                    counter++;
                    defaultName = `Location ${counter}`;
                }
                return defaultName;
            }
            baseName = baseName.trim();
            const existingNames = this.storedLocations.map((loc => loc.name.toLowerCase()));
            if (!existingNames.includes(baseName.toLowerCase())) {
                return baseName;
            }
            let counter = 1;
            let uniqueName = "";
            const match = baseName.match(/^(.+?)\s*\{(\d+)\}$/);
            if (match) {
                baseName = match[1].trim();
                counter = parseInt(match[2], 10) + 1;
            }
            do {
                uniqueName = `${baseName} {${counter}}`;
                counter++;
            } while (existingNames.includes(uniqueName.toLowerCase()));
            return uniqueName;
        }
        toggleSelectAll() {
            if (!this.storedLocationsList) {
                return;
            }
            let hasUnchecked = false;
            for (let i = 0; i < this.storedLocations.length; i++) {
                const slot = this.storedLocationsList.getSlotByIndex(i);
                if (slot) {
                    const checkbox = slot.getEntry(0);
                    if (checkbox && !checkbox.value) {
                        hasUnchecked = true;
                        break;
                    }
                }
            }
            for (let i = 0; i < this.storedLocations.length; i++) {
                const slot = this.storedLocationsList.getSlotByIndex(i);
                if (slot) {
                    const checkbox = slot.getEntry(0);
                    if (checkbox) {
                        checkbox.setValue(hasUnchecked);
                    }
                }
            }
            this.telemetryManager.fireTelemetryEvent(NavigationTelemetry.ToggleSelectAll, {
                selectAll: hasUnchecked,
                locationCount: this.storedLocations.length
            });
        }
        deleteSelectedLocations() {
            const selectedIndices = this.getSelectedLocationIndices();
            if (selectedIndices.length === 0) {
                this.uiSession.log.info("No locations selected for deletion");
                return;
            }
            this.uiSession.dialogManager.activateDialog({
                dialogId: "navigation:deleteConfirm"
            });
        }
        performBulkDelete() {
            const selectedIndices = this.getSelectedLocationIndices();
            if (selectedIndices.length === 0) {
                return;
            }
            for (let i = selectedIndices.length - 1; i >= 0; i--) {
                const index = selectedIndices[i];
                const locationData = this.storedLocations[index];
                this.storedLocations.splice(index, 1);
                this.updateLocationMarkRenderingStorage(locationData);
            }
            this.storeLocationsToPlayer();
            this.selectedLocationIndex = this.storedLocations.length > 0 ? 0 : -1;
            this.refreshLocationsList();
            this.updateLocationDetails();
            this.mapPayload?.set(this._createMiniMap());
            this.uiSession.log.info(`Deleted ${selectedIndices.length} locations`);
            this.telemetryManager.fireTelemetryEvent(NavigationTelemetry.BulkDeleteInitiated);
        }
        getSelectedLocationIndices() {
            const selectedIndices = [];
            if (!this.storedLocationsList) {
                return selectedIndices;
            }
            for (let i = 0; i < this.storedLocations.length; i++) {
                const slot = this.storedLocationsList.getSlotByIndex(i);
                if (slot) {
                    const checkbox = slot.getEntry(0);
                    if (checkbox?.value) {
                        selectedIndices.push(i);
                    }
                }
            }
            return selectedIndices;
        }
        refreshLocationsList() {
            if (!this.storedLocationsList) {
                return;
            }
            this.storedLocationsList.updateSlots(this.createLocationSlots());
            const slot = this.storedLocationsList.getSlotByIndex(this.selectedLocationIndex);
            if (slot) {
                this.storedLocationsList.selectSlot(slot.id, true);
                this.locationDetailsPane?.show();
            }
        }
        storeLocationsToPlayer() {
            const data = {
                locations: this.storedLocations,
                lastUpdate: Date.now(),
                lastUpdatedBy: this.uiSession.extensionContext.player.id
            };
            server_namespaceObject.world.setDynamicProperty(STORED_LOCATION_WORLD_PROPERTY_NAME, JSON.stringify(data));
            this.lastUpdateTimestamp = data.lastUpdate;
            this.uiSession.log.debug(`Stored ${this.storedLocations.length} locations to world storage`);
        }
        _createMiniMap() {
            const mapSize = mapSizeInPixels[this.mapSizeSelection.value];
            const pixelFactor = pixelFactors[this.mapSizeSelection.value];
            const me = this.uiSession.extensionContext.player;
            const currentPlayerLocation = lib.Vector3Utils.floor(me.location);
            const currentDirectionPlayerIsFacing = this.getCurrentDirectionPlayerIsFacing();
            const maxHeight = me.dimension.heightRange.max;
            const dimensionID = DimensionIds[me.dimension.id];
            const rgbValues = [];
            const cache = this.surfaceBlockColorCache;
            for (let zOffset = -mapSize / 2 * pixelFactor; zOffset < mapSize / 2 * pixelFactor; zOffset++) {
                for (let xOffset = -mapSize / 2 * pixelFactor; xOffset < mapSize / 2 * pixelFactor; xOffset++) {
                    let color = WHITE_RGBA;
                    const blockXOffset = Math.floor(xOffset / pixelFactor);
                    const blockZOffset = Math.floor(zOffset / pixelFactor);
                    const isWithinPlayerArea = this.playerIconMap.get(currentDirectionPlayerIsFacing)?.[0];
                    const isWhiteBlock = this.playerIconMap.get(currentDirectionPlayerIsFacing)?.[1];
                    const highestLocation = {
                        x: currentPlayerLocation.x + blockXOffset,
                        y: maxHeight,
                        z: currentPlayerLocation.z + blockZOffset
                    };
                    const currentXZString = this.createCacheKey(highestLocation.x, highestLocation.z, this.mapSizeSelection.value);
                    const cacheKey = this.createCacheKey(highestLocation.x, highestLocation.z, dimensionID);
                    if (cache.blocks[cacheKey]) {
                        color = cache.blocks[cacheKey].color;
                    }
                    if (isWithinPlayerArea?.(zOffset, xOffset)) {
                        color = isWhiteBlock?.(zOffset, xOffset) ? {
                            ...WHITE_RGBA
                        } : {
                            ...BLACK_RGBA
                        };
                    } else if (currentXZString in this.locationMarkRenderingStorage) {
                        color = this.locationMarkRenderingStorage[currentXZString].color;
                    }
                    const rgbObject = {
                        r: Math.round(color.red * 255),
                        g: Math.round(color.green * 255),
                        b: Math.round(color.blue * 255)
                    };
                    rgbValues.push(rgbObject);
                }
            }
            const base64Payload = CreateBase64ImageFromRGB(rgbValues, mapSize * pixelFactor, mapSize * pixelFactor);
            return base64Payload;
        }
        async updateSurfaceBlockColorCache() {
            const me = this.uiSession.extensionContext.player;
            const currentPlayerLocation = lib.Vector3Utils.floor(me.location);
            const maxHeight = me.dimension.heightRange.max;
            const dimensionID = DimensionIds[me.dimension.id];
            const cache = this.surfaceBlockColorCache;
            if (cache.isUpdating) {
                return;
            }
            cache.center = currentPlayerLocation;
            cache.isUpdating = true;
            this.uiSession.log.debug(`Cache Update starts with cache size ${Object.keys(cache.blocks).length} at ${Date.now()}. Please wait for a while...`);
            const mapSize = mapSizeInPixels[this.mapSizeSelection.value];
            const region = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(me).regionManager.leaseRegion({
                extentX: {
                    min: currentPlayerLocation.x - mapSize / 2,
                    max: currentPlayerLocation.x + mapSize / 2
                },
                extentZ: {
                    min: currentPlayerLocation.z - mapSize / 2,
                    max: currentPlayerLocation.z + mapSize / 2
                }
            });
            await region.waitUntilAvailable();
            const maxHeightDistance = maxHeight - me.dimension.heightRange.min;
            for (let zOffset = -mapSize / 2; zOffset < mapSize / 2; zOffset++) {
                for (let xOffset = -mapSize / 2; xOffset < mapSize / 2; xOffset++) {
                    const highestLocation = {
                        x: currentPlayerLocation.x + xOffset,
                        y: maxHeight,
                        z: currentPlayerLocation.z + zOffset
                    };
                    const cacheKey = this.createCacheKey(highestLocation.x, highestLocation.z, dimensionID);
                    try {
                        const topLocation = region.getAvailableLocationFromRay({
                            x: highestLocation.x + .5,
                            y: highestLocation.y,
                            z: highestLocation.z + .5
                        }, lib.VECTOR3_DOWN, {
                            includeLiquidBlocks: true,
                            maxDistance: maxHeightDistance
                        });
                        if (topLocation) {
                            const color = region.getBlockMapColor(topLocation);
                            cache.blocks[cacheKey] = {
                                color: {
                                    ...color
                                },
                                location: lib.Vector3Utils.floor(topLocation)
                            };
                        }
                    } catch {}
                }
            }
            region.dispose();
            this.uiSession.log.debug(`Cache Update finished with cache size ${Object.keys(cache.blocks).length} at ${Date.now().toString()}`);
        }
        createCacheKey(x, z, extraItem) {
            return `${x},${z},${extraItem}`;
        }
        updateLocationMarkRenderingStorage(deletedLocation) {
            if (deletedLocation) {
                for (const locationString in this.locationMarkRenderingStorage) {
                    if (Object.prototype.hasOwnProperty.call(this.locationMarkRenderingStorage, locationString)) {
                        if (this.locationMarkRenderingStorage[locationString].relatedStoredLocation === deletedLocation) {
                            delete this.locationMarkRenderingStorage[locationString];
                        }
                    }
                }
            }
            this.processLocationMarkOnDifferentMapSize(-8, 0, -3, 3, ((z, x) => z === 0 && x === 0 || z === -1 && x >= -1 && x <= 1 || z === -2 && x >= -1 && x <= 1 || z === -3 && x >= -2 && x <= 2 || z >= -6 && z <= -4 && x >= -3 && x <= 3 || z === -7 && x >= -2 && x <= 2 || z === -8 && x >= -1 && x <= 1), ((z, x) => z === 0 && x === 0 || z === -1 && (x === -1 || x === 1) || z === -2 && (x === -1 || x === 1) || z === -3 && (x === -2 || x === 2) || z >= -6 && z <= -4 && (x === -3 || x === 3) || z === -7 && (x === -2 || x === 2) || z === -8 && x >= -1 && x <= 1), ((z, x) => z === -4 && x === 0 || z === -5 && x >= -1 && x <= 1 || z === -6 && x === 0), MapSize.Small);
            this.processLocationMarkOnDifferentMapSize(-8, 0, -3, 3, ((z, x) => z === 0 && x === 0 || z === -1 && x >= -1 && x <= 1 || z === -2 && x >= -1 && x <= 1 || z === -3 && x >= -2 && x <= 2 || z >= -6 && z <= -4 && x >= -3 && x <= 3 || z === -7 && x >= -2 && x <= 2 || z === -8 && x >= -1 && x <= 1), ((z, x) => z === 0 && x === 0 || z === -1 && (x === -1 || x === 1) || z === -2 && (x === -1 || x === 1) || z === -3 && (x === -2 || x === 2) || z >= -6 && z <= -4 && (x === -3 || x === 3) || z === -7 && (x === -2 || x === 2) || z === -8 && x >= -1 && x <= 1), ((z, x) => z === -4 && x === 0 || z === -5 && x >= -1 && x <= 1 || z === -6 && x === 0), MapSize.Middle);
            this.processLocationMarkOnDifferentMapSize(-18, 0, -7, 7, ((z, x) => z >= -2 && z <= 0 && x >= -1 && x <= 1 || z >= -6 && z <= -3 && x >= -3 && x <= 3 || z >= -8 && z <= -7 && x >= -5 && x <= 5 || z >= -14 && z <= -9 && x >= -7 && x <= 7 || z >= -16 && z <= -15 && x >= -5 && x <= 5 || z >= -18 && z <= -17 && x >= -3 && x <= 3), ((z, x) => z >= -2 && z <= 0 && (x === -1 || x === 0 || x === 1) || z >= -6 && z <= -3 && (x === -3 || x === -2 || x === 2 || x === 3) || z >= -8 && z <= -7 && (x === -4 || x === -5 || x === 4 || x === 5) || z >= -14 && z <= -9 && (x === -7 || x === -6 || x === 6 || x === 7) || z >= -16 && z <= -15 && (x === -4 || x === -5 || x === 4 || x === 5) || z >= -18 && z <= -17 && x >= -3 && x <= 3), ((z, x) => z === -7 && x === 0 || z === -8 && x === 0 || z === -9 && x >= 0 && x <= 1 || z === -10 && x >= -1 && x <= 1 || z === -11 && x >= -4 && x <= 2 || z === -12 && x >= -2 && x <= 2 || z === -13 && x >= 0 && x <= 3 || z === -14 && x === 3), MapSize.Large);
        }
        processLocationMarkOnDifferentMapSize(zLowerBound, zUpperBound, xLowerBound, xUpperBound, isWithinRange, isWithinOuterBorderRange, isWithinInnerBorderRange, mapSize) {
            for (const locationData of this.storedLocations) {
                for (let zOffset = zUpperBound; zOffset >= zLowerBound; zOffset--) {
                    for (let xOffset = xLowerBound; xOffset <= xUpperBound; xOffset++) {
                        const currentLocation = {
                            x: locationData.location.x + xOffset,
                            y: locationData.location.y,
                            z: locationData.location.z + zOffset
                        };
                        if (isWithinRange(zOffset, xOffset)) {
                            const locationString = this.createCacheKey(currentLocation.x, currentLocation.z, mapSize);
                            let color;
                            if (isWithinOuterBorderRange(zOffset, xOffset)) {
                                color = {
                                    ...BLACK_RGBA
                                };
                            } else if (isWithinInnerBorderRange(zOffset, xOffset)) {
                                color = this.isLocationMarkNearWhite(locationData.color) ? {
                                    ...BLACK_RGBA
                                } : {
                                    ...WHITE_RGBA
                                };
                            } else {
                                color = {
                                    ...locationData.color
                                };
                            }
                            if (!(locationString in this.locationMarkRenderingStorage)) {
                                this.locationMarkRenderingStorage[locationString] = {
                                    color,
                                    relatedStoredLocation: locationData
                                };
                            } else if (locationData.location.z >= this.locationMarkRenderingStorage[locationString].relatedStoredLocation.location.z) {
                                this.locationMarkRenderingStorage[locationString].relatedStoredLocation = locationData;
                                this.locationMarkRenderingStorage[locationString].color = color;
                            }
                        }
                    }
                }
            }
        }
        getCurrentDirectionPlayerIsFacing() {
            const player = this.uiSession.extensionContext.player;
            let directionPlayerIsFacing;
            const viewDirection = player.getViewDirection();
            let angle = Math.atan2(viewDirection.z, viewDirection.x);
            if (angle < 0) {
                angle += 2 * Math.PI;
            }
            if (angle >= 15 * Math.PI / 8 || angle < Math.PI / 8) {
                directionPlayerIsFacing = Navigation_Direction.East;
            } else if (angle >= Math.PI / 8 && angle < 3 * Math.PI / 8) {
                directionPlayerIsFacing = Navigation_Direction.Southeast;
            } else if (angle >= 3 * Math.PI / 8 && angle < 5 * Math.PI / 8) {
                directionPlayerIsFacing = Navigation_Direction.South;
            } else if (angle >= 5 * Math.PI / 8 && angle < 7 * Math.PI / 8) {
                directionPlayerIsFacing = Navigation_Direction.Southwest;
            } else if (angle >= 7 * Math.PI / 8 && angle < 9 * Math.PI / 8) {
                directionPlayerIsFacing = Navigation_Direction.West;
            } else if (angle >= 9 * Math.PI / 8 && angle < 11 * Math.PI / 8) {
                directionPlayerIsFacing = Navigation_Direction.Northwest;
            } else if (angle >= 11 * Math.PI / 8 && angle < 13 * Math.PI / 8) {
                directionPlayerIsFacing = Navigation_Direction.North;
            } else {
                directionPlayerIsFacing = Navigation_Direction.Northeast;
            }
            return directionPlayerIsFacing;
        }
        isPlayerFarFromCenter(center, currentLocation) {
            return Math.abs(center.x - currentLocation.x) > CACHE_UPDATE_DISTANCE || Math.abs(center.z - currentLocation.z) > CACHE_UPDATE_DISTANCE;
        }
        shouldDeleteItemFromCache(latestPlayerLocation, itemLocation) {
            return Math.abs(latestPlayerLocation.x - itemLocation.x) > CACHE_LENGTH / 2 || Math.abs(latestPlayerLocation.z - itemLocation.z) > CACHE_LENGTH / 2;
        }
        isLocationMarkNearWhite(color) {
            return color.red >= .9 && color.blue >= .9 && color.green >= .9;
        }
        loadSettings() {
            try {
                const option = {
                    scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                    version: 0
                };
                const settingsGroup = this.persistenceManager.getGroup(STORED_LOCATION_GROUP_SETTINGS, option);
                if (settingsGroup) {
                    const storeItem = settingsGroup.fetchItem(STORED_LOCATION_GROUP_ITEM_SETTINGS);
                    if (storeItem && storeItem.value) {
                        this.mapSizeSelection.set(storeItem.value.mapSize);
                        this.uiSession.log.info(`Found ${this.storedLocations.length} stored locations during initialization`);
                    }
                    settingsGroup.dispose();
                }
            } catch (e) {
                this.uiSession.log.info(`Exception ${(0, server_editor_namespaceObject.stringFromException)(e)} occurred during initialization`);
            }
        }
        saveSettings() {
            try {
                const option = {
                    scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                    version: 0
                };
                const settingsGroup = this.persistenceManager.getOrCreateGroup(STORED_LOCATION_GROUP_SETTINGS, option);
                if (settingsGroup) {
                    const settings = {
                        mapSize: this.mapSizeSelection.value
                    };
                    const storeItem = settingsGroup.getOrCreateItem(STORED_LOCATION_GROUP_ITEM_SETTINGS, settings);
                    storeItem.commit();
                    settingsGroup.dispose();
                }
            } catch (e) {
                this.uiSession.log.info(`Exception ${(0, server_editor_namespaceObject.stringFromException)(e)} occurred during save`);
            }
        }
    }
    class WeatherBehavior {
        auxLog(logString, currentPlayer) {
            const currentTags = [ "Editor", "Weather" ];
            const currentLogProperties = {
                player: currentPlayer,
                tags: currentTags
            };
            server_editor_namespaceObject.editor.log.info(logString, currentLogProperties);
        }
        setWeatherAndLog(newWeatherType) {
            const dimension = server_namespaceObject.world.getDimension("overworld");
            dimension.setWeather(newWeatherType, this.weatherDuration);
            this.auxLog(`Setting weather to ${newWeatherType} in the Overworld dimension`);
        }
        getWeather() {
            const dimension = server_namespaceObject.world.getDimension("overworld");
            return dimension.getWeather();
        }
        resetMenuStates() {
            if (this.clearWeatherMenuItem) {
                this.clearWeatherMenuItem.checked = false;
            }
            if (this.rainWeatherMenuItem) {
                this.rainWeatherMenuItem.checked = false;
            }
            if (this.thunderWeatherMenuItem) {
                this.thunderWeatherMenuItem.checked = false;
            }
        }
        updateMenuStates(newWeatherType) {
            this.resetMenuStates();
            switch (newWeatherType) {
              case server_namespaceObject.WeatherType.Clear:
                if (this.clearWeatherMenuItem) {
                    this.clearWeatherMenuItem.checked = true;
                }
                break;

              case server_namespaceObject.WeatherType.Rain:
                if (this.rainWeatherMenuItem) {
                    this.rainWeatherMenuItem.checked = true;
                }
                break;

              case server_namespaceObject.WeatherType.Thunder:
                if (this.thunderWeatherMenuItem) {
                    this.thunderWeatherMenuItem.checked = true;
                }
                break;
            }
        }
        setSubscriptionToWeatherChangeEvent(uiSession) {
            uiSession.eventSubscriptionCache.subscribeToBedrockEvent("weatherChange", (evt => {
                this.auxLog(`Weather is now ${evt.newWeather} in the Overworld dimension`, uiSession.extensionContext.player);
                this.updateMenuStates(evt.newWeather);
            }));
        }
        constructor(uiSession, parentMenu) {
            this.uiSession = uiSession;
            this.weatherMenu = undefined;
            this.clearWeatherMenuItem = undefined;
            this.rainWeatherMenuItem = undefined;
            this.thunderWeatherMenuItem = undefined;
            this.weatherDuration = 1e6;
            this._weatherChangeSubscriptionHandle = undefined;
            this._weatherChangeMap = new Map;
            this.createWeatherMenu(parentMenu);
            this.setSubscriptionToWeatherChangeEvent(this.uiSession);
            this.updateMenuStates(this.getWeather());
            this._weatherChangeSubscriptionHandle = subscribeWeatherChangeMessages(((id, weatherChange) => {
                this.uiSession.log.info(`Weather change requested by ${id} to ${weatherChange}`);
                this._weatherChangeMap.set(id, this.getWeather());
                this.setWeatherAndLog(weatherChange);
            }), (id => {
                this.uiSession.log.info(`Weather restore requested by ${id}`);
                const previousWeather = this._weatherChangeMap.get(id);
                if (previousWeather !== undefined) {
                    this.setWeatherAndLog(previousWeather);
                }
            }));
        }
        createWeatherMenu(parentMenu) {
            const weatherClearAction = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.setWeatherAndLog(server_namespaceObject.WeatherType.Clear);
                }
            });
            const weatherRainAction = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.setWeatherAndLog(server_namespaceObject.WeatherType.Rain);
                }
            });
            const weatherThunderAction = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.setWeatherAndLog(server_namespaceObject.WeatherType.Thunder);
                }
            });
            if (this.uiSession.scratchStorage) {
                this.weatherMenu = parentMenu.addItem({
                    label: "resourcePack.editor.menuBar.parentMenu.weather",
                    tooltip: "resourcePack.editor.menuBar.parentMenu.weather.tooltip"
                });
                this.clearWeatherMenuItem = this.weatherMenu.addItem({
                    label: "resourcePack.editor.menuBar.parentMenu.weather.clear"
                }, weatherClearAction);
                this.rainWeatherMenuItem = this.weatherMenu.addItem({
                    label: "resourcePack.editor.menuBar.parentMenu.weather.rain"
                }, weatherRainAction);
                this.thunderWeatherMenuItem = this.weatherMenu.addItem({
                    label: "resourcePack.editor.menuBar.parentMenu.weather.thunder"
                }, weatherThunderAction);
            }
        }
        teardown() {
            this.resetMenuStates();
        }
    }
    const mapMarkerEntityName = "editor:ruler_idle";
    const POSITION_TEXT_COMPONENT_NAME = "position_text";
    const EMPTY_INFO = "---";
    var MeasuringMarkSelectionState;
    (function(MeasuringMarkSelectionState) {
        MeasuringMarkSelectionState[MeasuringMarkSelectionState["NotSelected"] = 0] = "NotSelected";
        MeasuringMarkSelectionState[MeasuringMarkSelectionState["StartPositionSelected"] = 1] = "StartPositionSelected";
        MeasuringMarkSelectionState[MeasuringMarkSelectionState["EndPositionSelected"] = 2] = "EndPositionSelected";
    })(MeasuringMarkSelectionState || (MeasuringMarkSelectionState = {}));
    var RulerTelemetry;
    (function(RulerTelemetry) {
        RulerTelemetry["StartPointSelected"] = "StartPointSelected";
        RulerTelemetry["EndPointSelected"] = "EndPointSelected";
        RulerTelemetry["Reset"] = "Reset";
        RulerTelemetry["DragStart"] = "DragStart";
        RulerTelemetry["DragEnd"] = "DragEnd";
        RulerTelemetry["SelectAllWidgets"] = "SelectAllWidgets";
        RulerTelemetry["DeselectAllWidgets"] = "DeselectAllWidgets";
    })(RulerTelemetry || (RulerTelemetry = {}));
    var AxisLockState;
    (function(AxisLockState) {
        AxisLockState["None"] = "none";
        AxisLockState["X"] = "x";
        AxisLockState["Y"] = "y";
        AxisLockState["Z"] = "z";
    })(AxisLockState || (AxisLockState = {}));
    var RulerOperation;
    (function(RulerOperation) {
        RulerOperation["CreateRuler"] = "createRuler";
        RulerOperation["CompleteRuler"] = "completeRuler";
        RulerOperation["ClearAll"] = "clearAll";
        RulerOperation["PositionChange"] = "positionChange";
    })(RulerOperation || (RulerOperation = {}));
    const TRANSACTION_NAMES = {
        [RulerOperation.CreateRuler]: "RulerTool:PlaceStartPoint",
        [RulerOperation.CompleteRuler]: "RulerTool:PlaceEndPoint",
        [RulerOperation.ClearAll]: "RulerTool:ClearRuler",
        [RulerOperation.PositionChange]: "RulerTool:PositionChange"
    };
    var RulerMode;
    (function(RulerMode) {
        RulerMode["Idle"] = "idle";
        RulerMode["WaitingForStartPosition"] = "waitingForStartPosition";
        RulerMode["WaitingForEndPosition"] = "waitingForEndPosition";
    })(RulerMode || (RulerMode = {}));
    class Midpoint {
        constructor(start, end, group, uiSession) {
            this._start = start;
            this._end = end;
            this._uiSession = uiSession;
            this.calculateDeltaAndLength();
            const startCenter = lib.Vector3Utils.add(this._start.location, {
                x: .5,
                y: .5,
                z: .5
            });
            const endCenter = lib.Vector3Utils.add(this._end.location, {
                x: .5,
                y: .5,
                z: .5
            });
            this._location = lib.Vector3Utils.add(lib.Vector3Utils.scale(lib.Vector3Utils.subtract(endCenter, startCenter), .5), startCenter);
            this._widget = group.createWidget(this._location, {
                selectable: true,
                snapToBlockLocation: false,
                visible: true,
                collisionRadius: 0,
                widgetName: "Ruler Tool - Midpoint"
            });
        }
        calculateDeltaAndLength() {
            this._delta = lib.Vector3Utils.subtract(this._end.location, this._start.location);
            const blockCountX = Math.abs(this._delta.x);
            const blockCountY = Math.abs(this._delta.y);
            const blockCountZ = Math.abs(this._delta.z);
            this._length = Math.max(blockCountX, blockCountY, blockCountZ);
        }
        update() {
            this.calculateDeltaAndLength();
            const startCenter = lib.Vector3Utils.add(this._start.location, {
                x: .5,
                y: .5,
                z: .5
            });
            const endCenter = lib.Vector3Utils.add(this._end.location, {
                x: .5,
                y: .5,
                z: .5
            });
            this._location = lib.Vector3Utils.add(lib.Vector3Utils.scale(lib.Vector3Utils.subtract(endCenter, startCenter), .5), startCenter);
            this._widget.location = this._location;
        }
        destroy() {
            this._widget.delete();
        }
    }
    class MeasuringMark {
        constructor(other, position, widgetGroup, updater, uiSession, rulerToolId, onSelectionChanged, axisConstraintFn) {
            this._location = position;
            this._lastKnownPosition = position;
            this._other = other;
            this._onSelectionChanged = onSelectionChanged;
            this._uiSession = uiSession;
            this._axisConstraintFn = axisConstraintFn;
            this._widget = widgetGroup.createWidget(position, {
                selectable: true,
                snapToBlockLocation: true,
                visible: true,
                collisionOffset: {
                    x: .5,
                    y: .5,
                    z: .5
                },
                collisionRadius: .5,
                widgetName: "Ruler Tool - Measuring Mark",
                stateChangeEvent: data => {
                    if (data.mouseEvent !== undefined) {
                        const isMousePress = data.mouseEvent.action === server_editor_namespaceObject.WidgetMouseButtonActionType.Pressed;
                        const isLeftClick = !data.mouseEvent.shiftPressed && !data.mouseEvent.controlPressed && !data.mouseEvent.altPressed;
                        if (isMousePress && isLeftClick) {
                            const currentToolId = uiSession.toolRail.getSelectedToolId();
                            if (currentToolId !== rulerToolId) {
                                uiSession.toolRail.setSelectedToolId(rulerToolId);
                                return;
                            }
                        }
                    }
                    if (data.location !== undefined) {
                        let constrainedLocation = data.location;
                        if (this._axisConstraintFn && this._other) {
                            const basePos = this._location;
                            const targetPos = data.location;
                            if (!this._lastConstraintCache || !lib.Vector3Utils.equals(this._lastConstraintCache.basePos, basePos) || !lib.Vector3Utils.equals(this._lastConstraintCache.targetPos, targetPos)) {
                                constrainedLocation = this._axisConstraintFn(basePos, targetPos);
                                this._lastConstraintCache = {
                                    basePos,
                                    targetPos,
                                    result: constrainedLocation
                                };
                            } else {
                                constrainedLocation = this._lastConstraintCache.result;
                            }
                        }
                        this._location = constrainedLocation;
                        const textComponent = data.widget.getComponent(POSITION_TEXT_COMPONENT_NAME);
                        if (textComponent) {
                            textComponent.label = lib.Vector3Utils.toString(constrainedLocation, {
                                decimals: 1
                            });
                        }
                        if (this._selectionIndicator) {
                            this._selectionIndicator.location = constrainedLocation;
                        }
                        if (!lib.Vector3Utils.equals(constrainedLocation, data.location)) {
                            this._widget.location = constrainedLocation;
                        }
                        updater();
                    }
                    if (data.selected !== undefined) {
                        if (data.selected === this._widget.selected) {
                            return;
                        }
                        uiSession.log.debug(`[RulerTool] Widget selection changed to: ${data.selected}`);
                        if (data.selected && !this._selectionIndicator) {
                            this._selectionIndicator = widgetGroup.createWidget(this._location, {
                                selectable: false,
                                snapToBlockLocation: false,
                                visible: true,
                                collisionRadius: 0,
                                widgetName: `Ruler Tool - Selection Indicator - ${Date.now()}`
                            });
                            this._selectionIndicator.addGizmoComponent("selection_gizmo", {
                                offset: {
                                    x: .5,
                                    y: .1,
                                    z: .5
                                },
                                visible: true
                            });
                        } else if (!data.selected && this._selectionIndicator) {
                            this._selectionIndicator.delete();
                            this._selectionIndicator = undefined;
                        }
                        if (this._onSelectionChanged) {
                            this._onSelectionChanged(data.selected);
                        }
                    }
                }
            });
            this._widget.addEntityComponent("marker", mapMarkerEntityName, {
                isClickable: true,
                visible: true,
                offset: {
                    x: .5,
                    y: 0,
                    z: .5
                }
            });
            this._widget.addTextComponent(POSITION_TEXT_COMPONENT_NAME, lib.Vector3Utils.toString(position, {
                decimals: 1
            }), {
                offset: {
                    x: 0,
                    y: 1,
                    z: 0
                },
                visible: true
            });
            this._gizmoComponent = this._widget.addGizmoComponent("position_gizmo", {
                offset: {
                    x: .5,
                    y: 0,
                    z: .5
                },
                visible: true
            });
            this._widget.addGuideComponent("position_guide");
            if (this._other) {
                const spline = this._widget.addSplineComponent("spline", {
                    splineType: server_editor_namespaceObject.SplineType.Line,
                    controlPoints: [],
                    offset: {
                        x: .5,
                        y: 0,
                        z: .5
                    }
                });
                const widgetList = [ this._other.widget ];
                spline.setControlPoints(widgetList);
            }
        }
        destroy() {
            if (this._selectionIndicator) {
                this._selectionIndicator.delete();
                this._selectionIndicator = undefined;
            }
            this._widget.delete();
        }
        isLocation(location) {
            return lib.Vector3Utils.equals(this._location, location);
        }
        get widget() {
            return this._widget;
        }
        get location() {
            return this._location;
        }
        setSelected(selected, widgetGroup) {
            if (this._widget.selected === selected) {
                return;
            }
            this._widget.selected = selected;
            if (selected && !this._selectionIndicator) {
                this._selectionIndicator = widgetGroup.createWidget(this._location, {
                    selectable: false,
                    snapToBlockLocation: false,
                    visible: true,
                    collisionRadius: 0,
                    widgetName: `Ruler Tool - Selection Indicator - ${Date.now()}`
                });
                this._selectionIndicator.addGizmoComponent("selection_gizmo", {
                    offset: {
                        x: .5,
                        y: .1,
                        z: .5
                    },
                    visible: true
                });
            } else if (!selected && this._selectionIndicator) {
                this._selectionIndicator.delete();
                this._selectionIndicator = undefined;
            }
            if (this._selectionIndicator) {
                this._selectionIndicator.location = this._location;
            }
            if (this._onSelectionChanged) {
                this._onSelectionChanged(selected);
            }
        }
        updateLocation(newLocation) {
            this._location = newLocation;
            this._widget.location = newLocation;
            const textComponent = this._widget.getComponent(POSITION_TEXT_COMPONENT_NAME);
            if (textComponent) {
                textComponent.label = lib.Vector3Utils.toString(newLocation, {
                    decimals: 1
                });
            }
            if (this._selectionIndicator) {
                this._selectionIndicator.location = newLocation;
            }
            this._lastKnownPosition = newLocation;
        }
    }
    class RulerToolBehavior {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this._endPointSelectionState = MeasuringMarkSelectionState.NotSelected;
            this._selectionState = new SimpleStateSelector(MeasuringMarkSelectionState.NotSelected);
            this._rulers = [];
            this._activeRulerIndex = -1;
            this._startPointSelected = false;
            this._endPointSelected = false;
            this._isDragging = false;
            this._axisLocks = new Set;
            this._lockXAxis = (0, server_editor_namespaceObject.makeObservable)(false);
            this._lockYAxis = (0, server_editor_namespaceObject.makeObservable)(false);
            this._lockZAxis = (0, server_editor_namespaceObject.makeObservable)(false);
            this._startPointVector = (0, server_editor_namespaceObject.makeObservable)({
                x: 0,
                y: 0,
                z: 0
            });
            this._endPointVector = (0, server_editor_namespaceObject.makeObservable)({
                x: 0,
                y: 0,
                z: 0
            });
            this._infoText = (0, server_editor_namespaceObject.makeObservable)(EMPTY_INFO);
            this._distanceText = (0, server_editor_namespaceObject.makeObservable)("0.0 blocks");
            this._isManualInput = false;
            this._isRestoringFromTransaction = false;
            this._lastCapturedPositions = [];
            this._isCreatingRuler = false;
            this.telemetryManager = new TelemetryManager(uiSession.extensionContext.player, TelemetrySource.Ruler);
            this._widgetGroup = uiSession.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.Multiple,
                visible: true
            });
            this._cursorProperties = uiSession.extensionContext.cursor.getDefaultProperties();
            if (this._cursorProperties.fillColor) {
                delete this._cursorProperties.fillColor;
            }
            this._cursorProperties.outlineColor = {
                red: 0,
                green: 1,
                blue: 0,
                alpha: 1
            };
            this._cursorProperties.controlMode = server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse;
            this._cursorProperties.targetMode = server_editor_namespaceObject.CursorTargetMode.Face;
            this._cursorProperties.visible = true;
            this._tool = this.addTool(uiSession);
            this._tool.registerKeyBinding(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => this.toggleSelectAllWidgets()
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_A,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:rulerTool:toggleSelectAll",
                label: "resourcePack.editor.toolRail.rulerTool.keyBinding.selectAll.label",
                tooltip: "resourcePack.editor.toolRail.rulerTool.keyBinding.selectAll.tooltip"
            });
            this._tool.registerKeyBinding(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.deleteSelectedRulerLine();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.DELETE
            }, {
                uniqueId: "editor:rulerTool:deleteRulerLine",
                label: "resourcePack.editor.toolRail.rulerTool.keyBinding.deleteRulerLine.label",
                tooltip: "resourcePack.editor.toolRail.rulerTool.keyBinding.deleteRulerLine.tooltip"
            });
            this._tool.registerKeyBinding(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.uiSession.log.info(`[RulerTool] X-axis lock key pressed`);
                    this.toggleAxisLock(AxisLockState.X);
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_X
            }, {
                uniqueId: "editor:rulerTool:toggleXAxis",
                label: "resourcePack.editor.toolRail.rulerTool.keyBinding.toggleXAxisLock.label",
                tooltip: "resourcePack.editor.toolRail.rulerTool.keyBinding.toggleXAxisLock.tooltip"
            });
            this._tool.registerKeyBinding(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.uiSession.log.info(`[RulerTool] Y-axis lock key pressed`);
                    this.toggleAxisLock(AxisLockState.Y);
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_Y
            }, {
                uniqueId: "editor:rulerTool:toggleYAxis",
                label: "resourcePack.editor.toolRail.rulerTool.keyBinding.toggleYAxisLock.label",
                tooltip: "resourcePack.editor.toolRail.rulerTool.keyBinding.toggleYAxisLock.tooltip"
            });
            this._tool.registerKeyBinding(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.uiSession.log.info(`[RulerTool] Z-axis lock key pressed`);
                    this.toggleAxisLock(AxisLockState.Z);
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_Z
            }, {
                uniqueId: "editor:rulerTool:toggleZAxis",
                label: "resourcePack.editor.toolRail.rulerTool.keyBinding.toggleZAxisLock.label",
                tooltip: "resourcePack.editor.toolRail.rulerTool.keyBinding.toggleZAxisLock.tooltip"
            });
            this._tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    uiSession.extensionContext.cursor.pushPropertiesById(this._cursorProperties, RulerToolBehavior.MODAL_TOOL_ID);
                } else {
                    if (this._tempTransactionData) {
                        this.cancelTransaction();
                    }
                    this._axisLocks.clear();
                    this._axisLockStartPosition = undefined;
                    this.updateAxisLockUI();
                    uiSession.extensionContext.cursor.popPropertiesById(RulerToolBehavior.MODAL_TOOL_ID);
                }
            }));
            const pane = this.uiSession.createPropertyPane({
                title: "resourcePack.editor.toolRail.rulerTool.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.toolRail.rulerTool.description", {
                        link: "https://aka.ms/BedrockEditorRulerTool",
                        text: "resourcePack.editor.toolRail.rulerTool.learnMore"
                    } ]
                }
            });
            pane.addText(this._infoText, {
                title: "resourcePack.editor.toolRail.rulerTool.measurement.title"
            });
            pane.addText(this._distanceText, {
                title: "resourcePack.editor.toolRail.rulerTool.distance.title"
            });
            pane.addVector3(this._startPointVector, {
                title: "resourcePack.editor.toolRail.rulerTool.startPoint.title",
                onChange: (newValue, _oldValue) => {
                    this.onStartPointChanged(newValue);
                }
            });
            pane.addVector3(this._endPointVector, {
                title: "resourcePack.editor.toolRail.rulerTool.endPoint.title",
                onChange: (newValue, _oldValue) => {
                    this.onEndPointChanged(newValue);
                }
            });
            pane.addDivider();
            pane.addBool(this._lockXAxis, {
                title: "resourcePack.editor.toolRail.rulerTool.lockXAxis.title",
                onChange: newValue => {
                    this.onAxisLockCheckboxChanged(AxisLockState.X, newValue);
                }
            });
            pane.addBool(this._lockYAxis, {
                title: "resourcePack.editor.toolRail.rulerTool.lockYAxis.title",
                onChange: newValue => {
                    this.onAxisLockCheckboxChanged(AxisLockState.Y, newValue);
                }
            });
            pane.addBool(this._lockZAxis, {
                title: "resourcePack.editor.toolRail.rulerTool.lockZAxis.title",
                onChange: newValue => {
                    this.onAxisLockCheckboxChanged(AxisLockState.Z, newValue);
                }
            });
            pane.addDivider();
            pane.addButton(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.clearRuler();
                }
            }), {
                title: "resourcePack.editor.toolRail.rulerTool.clearRuler.title"
            });
            this._tool.bindPropertyPane(pane);
            this._transactionHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(this.uiSession.extensionContext.transactionManager, (payload => {
                this.restoreFromTransaction(payload, false);
            }), (payload => {
                this.restoreFromTransaction(payload, true);
            }));
            this.updateAxisLockUI();
        }
        toggleAxisLock(axis) {
            if (!this._tool.isActive) {
                return;
            }
            if (this._axisLocks.has(axis)) {
                this._axisLocks.delete(axis);
            } else {
                this._axisLocks.add(axis);
                this.captureAxisLockBasePosition();
            }
            this.updateAxisLockUI();
            this.updateGizmoAxisVisibility();
        }
        onAxisLockCheckboxChanged(axis, enabled) {
            if (enabled) {
                this._axisLocks.add(axis);
                this.captureAxisLockBasePosition();
            } else {
                this._axisLocks.delete(axis);
            }
            this.updateGizmoAxisVisibility();
        }
        captureAxisLockBasePosition() {
            if (this._endPoint && this._endPoint.widget) {
                this._axisLockStartPosition = {
                    ...this._endPoint.widget.location
                };
            } else if (this._startPoint && this._startPoint.widget) {
                this._axisLockStartPosition = {
                    ...this._startPoint.widget.location
                };
            }
        }
        updateAxisLockUI() {
            this._lockXAxis.set(this._axisLocks.has(AxisLockState.X));
            this._lockYAxis.set(this._axisLocks.has(AxisLockState.Y));
            this._lockZAxis.set(this._axisLocks.has(AxisLockState.Z));
        }
        hasActiveAxisLocks() {
            return this._axisLocks.size > 0;
        }
        getAxisConstrainedPosition(basePosition, targetPosition) {
            if (!this.hasActiveAxisLocks()) {
                return targetPosition;
            }
            const constrainedPosition = {
                ...basePosition
            };
            if (this._axisLocks.has(AxisLockState.X)) {
                constrainedPosition.x = targetPosition.x;
            }
            if (this._axisLocks.has(AxisLockState.Y)) {
                constrainedPosition.y = targetPosition.y;
            }
            if (this._axisLocks.has(AxisLockState.Z)) {
                constrainedPosition.z = targetPosition.z;
            }
            return constrainedPosition;
        }
        getOneBlockOffsetForAxis(startPosition) {
            if (!this.hasActiveAxisLocks()) {
                return startPosition;
            }
            const offsetPosition = {
                ...startPosition
            };
            if (this._axisLocks.has(AxisLockState.X)) {
                offsetPosition.x += 1;
            } else if (this._axisLocks.has(AxisLockState.Y)) {
                offsetPosition.y += 1;
            } else if (this._axisLocks.has(AxisLockState.Z)) {
                offsetPosition.z += 1;
            }
            return offsetPosition;
        }
        updateGizmoAxisVisibility() {
            const updateGizmo = gizmoComponent => {
                if (!gizmoComponent) return;
                if (this._axisLocks.size === 0) {
                    gizmoComponent.enabledAxes = server_editor_namespaceObject.Axis.X | server_editor_namespaceObject.Axis.Y | server_editor_namespaceObject.Axis.Z;
                } else {
                    let enabledAxes = 0;
                    if (this._axisLocks.has(AxisLockState.X)) {
                        enabledAxes |= server_editor_namespaceObject.Axis.X;
                    }
                    if (this._axisLocks.has(AxisLockState.Y)) {
                        enabledAxes |= server_editor_namespaceObject.Axis.Y;
                    }
                    if (this._axisLocks.has(AxisLockState.Z)) {
                        enabledAxes |= server_editor_namespaceObject.Axis.Z;
                    }
                    gizmoComponent.enabledAxes = enabledAxes;
                }
            };
            if (this._startPoint?.widget) {
                try {
                    const gizmoComponent = this._startPoint.widget.getComponent("position_gizmo");
                    updateGizmo(gizmoComponent);
                } catch (_error) {}
            }
            if (this._endPoint?.widget) {
                try {
                    const gizmoComponent = this._endPoint.widget.getComponent("position_gizmo");
                    updateGizmo(gizmoComponent);
                } catch (_error) {}
            }
            for (const ruler of this._rulers) {
                if (ruler.startPoint?.widget) {
                    try {
                        const gizmoComponent = ruler.startPoint.widget.getComponent("position_gizmo");
                        updateGizmo(gizmoComponent);
                    } catch (_error) {}
                }
                if (ruler.endPoint?.widget) {
                    try {
                        const gizmoComponent = ruler.endPoint.widget.getComponent("position_gizmo");
                        updateGizmo(gizmoComponent);
                    } catch (_error) {}
                }
            }
        }
        formatErrorMessage(error) {
            return String(error);
        }
        handleError(operation, error) {
            const errorMessage = `Failed to ${operation}: ${this.formatErrorMessage(error)}`;
            this.uiSession.log.warning(errorMessage);
        }
        startTransaction(operation) {
            if (this._transactionHandler && !this._tempTransactionData) {
                const oldState = {
                    rulers: this.captureCurrentPositions(),
                    currentStartMark: this._startPoint?.location,
                    currentEndMark: this._endPoint?.location,
                    mode: this.getCurrentMode()
                };
                const newState = {
                    rulers: [],
                    currentStartMark: undefined,
                    currentEndMark: undefined,
                    mode: RulerMode.Idle
                };
                this._tempTransactionData = {
                    operationType: operation,
                    oldState,
                    newState,
                    operationName: TRANSACTION_NAMES[operation]
                };
                this.uiSession.extensionContext.transactionManager.openTransaction(TRANSACTION_NAMES[operation]);
            }
        }
        commitTransaction(operation) {
            if (this._transactionHandler && this._tempTransactionData) {
                try {
                    const transactionName = TRANSACTION_NAMES[operation];
                    this._tempTransactionData.newState = {
                        rulers: this.captureCurrentPositions(),
                        currentStartMark: this._startPoint?.location,
                        currentEndMark: this._endPoint?.location,
                        mode: this.getCurrentMode()
                    };
                    this._transactionHandler.addUserDefinedOperation(this._tempTransactionData, transactionName);
                    this.uiSession.extensionContext.transactionManager.commitOpenTransaction();
                    this._tempTransactionData = undefined;
                    this.updateCapturedPositions();
                } catch (error) {
                    this.handleError("commit transaction", error);
                    if (this._tempTransactionData) {
                        this.cancelTransaction();
                    }
                }
            } else {
                this.uiSession.log.warning("There was no transaction data available to commit");
            }
        }
        cancelTransaction() {
            if (this._tempTransactionData) {
                try {
                    this.uiSession.extensionContext.transactionManager.discardOpenTransaction();
                } catch (error) {
                    this.handleError("cancel transaction", error);
                } finally {
                    this._tempTransactionData = undefined;
                }
            }
        }
        restoreFromTransaction(payload, isRedo = false) {
            this._isRestoringFromTransaction = true;
            try {
                if (payload.operationType === RulerOperation.ClearAll) {
                    this.clearRulerSilently();
                    this.restoreRulersFromPayload(isRedo ? payload.newState : payload.oldState);
                } else if (payload.operationType === RulerOperation.CreateRuler || payload.operationType === RulerOperation.CompleteRuler) {
                    if (isRedo) {
                        this.clearRulerSilently();
                        this.restoreRulersFromPayload(payload.newState);
                    } else {
                        this.undoRulerOperation(payload);
                    }
                } else if (payload.operationType === RulerOperation.PositionChange) {
                    this.clearRulerSilently();
                    this.restoreRulersFromPayload(isRedo ? payload.newState : payload.oldState);
                }
            } finally {
                this._isRestoringFromTransaction = false;
            }
        }
        destroyRulerWidgets(ruler) {
            this.safeDestroy(ruler.startPoint);
            this.safeDestroy(ruler.endPoint);
            this.safeDestroy(ruler.midPoint);
        }
        undoRulerOperation(payload) {
            const oldRulers = payload.oldState.rulers;
            const newRulers = payload.newState.rulers;
            const addedRulers = newRulers.filter((newRuler => !oldRulers.some((oldRuler => this.areRulersEqual(oldRuler, newRuler)))));
            for (const addedRuler of addedRulers) {
                const indexToRemove = this._rulers.findIndex((ruler => ruler.startPoint?.location && addedRuler.startPoint && ruler.endPoint?.location && addedRuler.endPoint && this.areVector3Equal(ruler.startPoint.location, addedRuler.startPoint) && this.areVector3Equal(ruler.endPoint.location, addedRuler.endPoint)));
                if (indexToRemove >= 0) {
                    const ruler = this._rulers[indexToRemove];
                    this.destroyRulerWidgets(ruler);
                    this._rulers.splice(indexToRemove, 1);
                    if (this._activeRulerIndex === indexToRemove) {
                        this._activeRulerIndex = -1;
                    } else if (this._activeRulerIndex > indexToRemove) {
                        this._activeRulerIndex--;
                    }
                }
            }
            this.clearCurrentRulerSilently();
            this.restoreCurrentRulerState(payload.oldState);
            this.updateInputFieldsFromRuler();
            this.updateInfoText();
        }
        areRulersEqual(ruler1, ruler2) {
            return this.areVector3Equal(ruler1.startPoint, ruler2.startPoint) && this.areVector3Equal(ruler1.endPoint, ruler2.endPoint);
        }
        areVector3Equal(v1, v2) {
            if (!v1 && !v2) return true;
            if (!v1 || !v2) return false;
            return lib.Vector3Utils.equals(v1, v2);
        }
        clearCurrentRulerSilently() {
            this.destroyCurrentRulerWidgets();
            this._startPoint = undefined;
            this._endPoint = undefined;
            this._midPoint = undefined;
            this._startPointSelected = false;
            this._endPointSelected = false;
            this._activeRulerIndex = -1;
            this._selectionState.resetState(MeasuringMarkSelectionState.NotSelected);
        }
        safeDestroy(widget) {
            if (widget) {
                try {
                    widget.destroy();
                } catch {}
            }
        }
        destroyCurrentRulerWidgets() {
            this.safeDestroy(this._startPoint);
            this.safeDestroy(this._endPoint);
            this.safeDestroy(this._midPoint);
        }
        restoreCurrentRulerState(state) {
            if (state.currentStartMark && state.mode === RulerMode.WaitingForEndPosition) {
                try {
                    this._startPoint = this.createMeasuringMark(undefined, state.currentStartMark, (() => {
                        this.updateInputFieldsFromRuler();
                        this._midPoint?.update();
                    }), (selected => {
                        this._startPointSelected = selected;
                    }));
                    this._selectionState.resetState(MeasuringMarkSelectionState.StartPositionSelected);
                } catch (_e) {
                    this.handleError("restore ruler start point from transaction", _e);
                }
            }
            if (state.currentEndMark && state.currentStartMark && this._startPoint) {
                try {
                    this._endPoint = this.createMeasuringMark(this._startPoint, state.currentEndMark, (() => {
                        this.updateInputFieldsFromRuler();
                        this._midPoint?.update();
                    }), (selected => {
                        this._endPointSelected = selected;
                    }));
                    this._midPoint = new Midpoint(this._startPoint, this._endPoint, this._widgetGroup, this.uiSession);
                    this._selectionState.resetState(MeasuringMarkSelectionState.EndPositionSelected);
                } catch (_e) {
                    this._endPoint = undefined;
                    this._midPoint = undefined;
                }
            }
            this.updateInputFieldsFromRuler();
            this.updateInfoText();
        }
        createMeasuringMarkUpdateCallback() {
            return () => {
                if (!this._isRestoringFromTransaction) {
                    this.updateInputFieldsFromRuler();
                    this._midPoint?.update();
                }
            };
        }
        restoreRulersFromPayload(state) {
            this._isRestoringFromTransaction = true;
            const updateCallback = this.createMeasuringMarkUpdateCallback();
            for (const rulerData of state.rulers) {
                const startPos = rulerData.startPoint;
                const endPos = rulerData.endPoint;
                if (startPos && endPos) {
                    try {
                        const startMark = this.createMeasuringMark(undefined, startPos, updateCallback);
                        const endMark = this.createMeasuringMark(startMark, endPos, updateCallback);
                        const midPoint = new Midpoint(startMark, endMark, this._widgetGroup, this.uiSession);
                        this._rulers.push({
                            startPoint: startMark,
                            endPoint: endMark,
                            midPoint,
                            startPointSelected: false,
                            endPointSelected: false
                        });
                    } catch (_e) {
                        this.handleError("restore ruler from transaction", _e);
                        continue;
                    }
                }
            }
            if (state.currentStartMark && state.mode === RulerMode.WaitingForEndPosition) {
                try {
                    this._startPoint = this.createMeasuringMark(undefined, state.currentStartMark, updateCallback, (selected => {
                        this._startPointSelected = selected;
                    }));
                    this._selectionState.resetState(MeasuringMarkSelectionState.StartPositionSelected);
                } catch {}
            }
            if (state.currentEndMark && state.currentStartMark && this._startPoint) {
                try {
                    this._endPoint = this.createMeasuringMark(this._startPoint, state.currentEndMark, updateCallback, (selected => {
                        this._endPointSelected = selected;
                    }));
                    this._midPoint = new Midpoint(this._startPoint, this._endPoint, this._widgetGroup, this.uiSession);
                    this._selectionState.resetState(MeasuringMarkSelectionState.EndPositionSelected);
                } catch (_e) {
                    this._endPoint = undefined;
                    this._midPoint = undefined;
                }
            }
            this._activeRulerIndex = this._rulers.length > 0 ? this._rulers.length - 1 : -1;
            this._isRestoringFromTransaction = false;
            this.updateInputFieldsFromRuler();
            this.updateInfoText();
            this.updateCapturedPositions();
        }
        captureCurrentPositions() {
            return this._rulers.map((ruler => ({
                startPoint: ruler.startPoint?.location,
                endPoint: ruler.endPoint?.location
            })));
        }
        hasPositionsChanged() {
            const currentPositions = this.captureCurrentPositions();
            if (currentPositions.length !== this._lastCapturedPositions.length) {
                return true;
            }
            return currentPositions.some(((current, index) => {
                const last = this._lastCapturedPositions[index];
                if (!last) return true;
                return !this.areVector3Equal(current.startPoint, last.startPoint) || !this.areVector3Equal(current.endPoint, last.endPoint);
            }));
        }
        updateCapturedPositions() {
            this._lastCapturedPositions = this.captureCurrentPositions();
        }
        createPositionChangeTransaction() {
            if (!this._transactionHandler) {
                return;
            }
            try {
                const oldPositions = this._lastCapturedPositions;
                const newPositions = this.captureCurrentPositions();
                const payload = {
                    operationType: RulerOperation.PositionChange,
                    oldState: {
                        rulers: oldPositions,
                        currentStartMark: this._startPoint?.location,
                        currentEndMark: this._endPoint?.location,
                        mode: this.getCurrentMode()
                    },
                    newState: {
                        rulers: newPositions,
                        currentStartMark: this._startPoint?.location,
                        currentEndMark: this._endPoint?.location,
                        mode: this.getCurrentMode()
                    },
                    operationName: "RulerTool:PositionChange"
                };
                this.uiSession.extensionContext.transactionManager.openTransaction("RulerTool:PositionChange");
                this._transactionHandler.addUserDefinedOperation(payload, "RulerTool:PositionChange");
                this.uiSession.extensionContext.transactionManager.commitOpenTransaction();
                this.updateCapturedPositions();
            } catch (error) {
                this.handleError("create position change transaction", error);
            }
        }
        clearRulerSilently() {
            this.destroyAllRulerWidgets();
            this._rulers = [];
            this._activeRulerIndex = -1;
            this._startPoint = undefined;
            this._endPoint = undefined;
            this._midPoint = undefined;
            this._startPointSelected = false;
            this._endPointSelected = false;
            this._endPointSelectionState = MeasuringMarkSelectionState.NotSelected;
            this._selectionState.resetState(this._endPointSelectionState);
            this._startPointVector.set({
                x: 0,
                y: 0,
                z: 0
            });
            this._endPointVector.set({
                x: 0,
                y: 0,
                z: 0
            });
            this._isManualInput = false;
        }
        onStartPointChanged(value) {
            const flooredVector = {
                x: Math.floor(value.x),
                y: Math.floor(value.y),
                z: Math.floor(value.z)
            };
            const isClearOperation = flooredVector.x === 0 && flooredVector.y === 0 && flooredVector.z === 0;
            if (this.hasActiveAxisLocks() && this._startPoint && !isClearOperation) {
                const currentLocation = this._startPoint.location;
                const constrainedVector = {
                    x: this._lockXAxis.value ? currentLocation.x : flooredVector.x,
                    y: this._lockYAxis.value ? currentLocation.y : flooredVector.y,
                    z: this._lockZAxis.value ? currentLocation.z : flooredVector.z
                };
                this._startPointVector.set(constrainedVector);
                return;
            }
            this._isManualInput = true;
            this._startPointVector.set(flooredVector);
            this.updateRulerFromInputs();
        }
        onEndPointChanged(value) {
            const flooredVector = {
                x: Math.floor(value.x),
                y: Math.floor(value.y),
                z: Math.floor(value.z)
            };
            const isClearOperation = flooredVector.x === 0 && flooredVector.y === 0 && flooredVector.z === 0;
            if (this.hasActiveAxisLocks() && this._endPoint && !isClearOperation) {
                const currentLocation = this._endPoint.location;
                const constrainedVector = {
                    x: this._lockXAxis.value ? currentLocation.x : flooredVector.x,
                    y: this._lockYAxis.value ? currentLocation.y : flooredVector.y,
                    z: this._lockZAxis.value ? currentLocation.z : flooredVector.z
                };
                this._endPointVector.set(constrainedVector);
                return;
            }
            this._isManualInput = true;
            this._endPointVector.set(flooredVector);
            this.updateRulerFromInputs();
        }
        updateRulerFromInputs() {
            if (!this._isManualInput) return;
            const startLocation = this._startPointVector.value;
            const endLocation = this._endPointVector.value;
            const isStartAtOrigin = startLocation.x === 0 && startLocation.y === 0 && startLocation.z === 0;
            const isEndAtOrigin = endLocation.x === 0 && endLocation.y === 0 && endLocation.z === 0;
            if (isStartAtOrigin && isEndAtOrigin) {
                if (this._startPoint) {
                    this._startPoint.destroy();
                    this._startPoint = undefined;
                }
                if (this._endPoint) {
                    this._endPoint.destroy();
                    this._endPoint = undefined;
                }
                if (this._midPoint) {
                    this._midPoint.destroy();
                    this._midPoint = undefined;
                }
                this._startPointSelected = false;
                this._endPointSelected = false;
                this._infoText.set("");
                this._distanceText.set("0");
                this._axisLocks.clear();
                this._axisLockStartPosition = undefined;
                this.updateAxisLockUI();
                this._isManualInput = false;
                return;
            }
            if (isStartAtOrigin && this._startPoint) {
                this._startPoint.destroy();
                this._startPoint = undefined;
                this._startPointSelected = false;
                if (this._midPoint) {
                    this._midPoint.destroy();
                    this._midPoint = undefined;
                }
                this.updateInfoText();
                this._isManualInput = false;
                return;
            }
            if (isEndAtOrigin && this._endPoint) {
                this._endPoint.destroy();
                this._endPoint = undefined;
                this._endPointSelected = false;
                if (this._midPoint) {
                    this._midPoint.destroy();
                    this._midPoint = undefined;
                }
                this.updateInfoText();
                this._isManualInput = false;
                return;
            }
            if (this._startPoint) {
                this._startPoint.updateLocation(startLocation);
            } else {
                this._startPoint = this.createMeasuringMark(undefined, startLocation, (() => {
                    this.updateInputFieldsFromRuler();
                    this.updateInfoText();
                    this._midPoint?.update();
                }), (selected => {
                    this._startPointSelected = selected;
                }));
            }
            if (this._endPoint) {
                this._endPoint.updateLocation(endLocation);
            } else {
                this._endPoint = this.createMeasuringMark(this._startPoint, endLocation, (() => {
                    this.updateInputFieldsFromRuler();
                    this.updateInfoText();
                    this._midPoint?.update();
                }), (selected => {
                    this._endPointSelected = selected;
                }));
            }
            if (this._midPoint) {
                this._midPoint.update();
            } else if (this._startPoint && this._endPoint) {
                this._midPoint = new Midpoint(this._startPoint, this._endPoint, this._widgetGroup, this.uiSession);
            }
            this.updateInputFieldsFromRuler();
            this._selectionState.resetState(MeasuringMarkSelectionState.EndPositionSelected);
            this.updateInfoText();
            this._isManualInput = false;
        }
        clearRuler() {
            this.startTransaction(RulerOperation.ClearAll);
            this.telemetryManager.fireTelemetryEvent(RulerTelemetry.Reset);
            this._rulers.forEach((ruler => {
                try {
                    ruler.startPoint?.destroy();
                } catch (_error) {}
                try {
                    ruler.endPoint?.destroy();
                } catch (_error) {}
                try {
                    ruler.midPoint?.destroy();
                } catch (_error) {}
            }));
            this._rulers = [];
            this._activeRulerIndex = -1;
            if (this._startPoint) {
                try {
                    this._startPoint.destroy();
                } catch (_error) {}
                this._startPoint = undefined;
            }
            if (this._endPoint) {
                try {
                    this._endPoint.destroy();
                } catch (_error) {}
                this._endPoint = undefined;
            }
            if (this._midPoint) {
                try {
                    this._midPoint.destroy();
                } catch (_error) {}
                this._midPoint = undefined;
            }
            this._startPointSelected = false;
            this._endPointSelected = false;
            this._endPointSelectionState = MeasuringMarkSelectionState.NotSelected;
            this._selectionState.resetState(this._endPointSelectionState);
            this._startPointVector.set({
                x: 0,
                y: 0,
                z: 0
            });
            this._endPointVector.set({
                x: 0,
                y: 0,
                z: 0
            });
            this._axisLocks.clear();
            this._axisLockStartPosition = undefined;
            this.updateAxisLockUI();
            this._isManualInput = false;
            this._infoText.set("");
            this._distanceText.set("0");
            this.commitTransaction(RulerOperation.ClearAll);
        }
        formatRulerInfo(startPoint, endPoint) {
            let text = `S(${lib.Vector3Utils.toString(startPoint, {
                decimals: 1
            })})`;
            let distance = 0;
            if (endPoint) {
                text += ` -> E(${lib.Vector3Utils.toString(endPoint, {
                    decimals: 1
                })})`;
                const delta = lib.Vector3Utils.subtract(endPoint, startPoint);
                text += ` D(${lib.Vector3Utils.toString(delta, {
                    decimals: 1
                })})`;
                const distanceX = Math.abs(delta.x);
                const distanceY = Math.abs(delta.y);
                const distanceZ = Math.abs(delta.z);
                distance = Math.max(distanceX, distanceY, distanceZ);
                this.uiSession.log.debug(`[RulerTool] Start: ${lib.Vector3Utils.toString(startPoint)}, End: ${lib.Vector3Utils.toString(endPoint)}`);
                this.uiSession.log.debug(`[RulerTool] Delta: ${lib.Vector3Utils.toString(delta)}, Distance: ${distance}`);
                text += ` L:${distance.toFixed(1)}`;
            }
            return {
                text,
                distance
            };
        }
        updateInfoText() {
            let text = "";
            let distance = 0;
            if (this._startPoint && (!this._rulers.length || this._activeRulerIndex === -1)) {
                const result = this.formatRulerInfo(this._startPoint.location, this._endPoint?.location);
                text = result.text;
                distance = result.distance;
            } else if (this._activeRulerIndex >= 0 && this._activeRulerIndex < this._rulers.length) {
                const activeRuler = this._rulers[this._activeRulerIndex];
                if (activeRuler.startPoint) {
                    const result = this.formatRulerInfo(activeRuler.startPoint.location, activeRuler.endPoint?.location);
                    text = result.text;
                    distance = result.distance;
                }
            } else if (this._startPoint) {
                const result = this.formatRulerInfo(this._startPoint.location, this._endPoint?.location);
                text = result.text;
                distance = result.distance;
            }
            if (this._rulers.length > 1 && this._activeRulerIndex >= 0 && this._activeRulerIndex < this._rulers.length) {
                text += ` [${this._activeRulerIndex + 1}/${this._rulers.length}]`;
            }
            this._infoText.set(text ? text : EMPTY_INFO);
            this._distanceText.set(distance > 0 ? `${distance.toFixed(2)} blocks` : "0.0 blocks");
        }
        updateRulerUI() {
            this.updateInputFieldsFromRuler();
            this.updateInfoText();
            this._midPoint?.update();
        }
        createNewRuler() {
            const rulerData = {
                endPoint: undefined,
                midPoint: undefined,
                startPointSelected: false,
                endPointSelected: false
            };
            return rulerData;
        }
        setActiveRuler(index) {
            if (index >= 0 && index < this._rulers.length) {
                this._activeRulerIndex = index;
                const ruler = this._rulers[index];
                this._startPoint = ruler.startPoint;
                this._endPoint = ruler.endPoint;
                this._midPoint = ruler.midPoint;
                this._startPointSelected = ruler.startPointSelected;
                this._endPointSelected = ruler.endPointSelected;
                this.updateInputFieldsFromRuler();
                this.updateInfoText();
            }
        }
        updateActiveRulerFromLegacyProperties() {
            if (this._activeRulerIndex >= 0 && this._activeRulerIndex < this._rulers.length) {
                const ruler = this._rulers[this._activeRulerIndex];
                ruler.startPoint = this._startPoint;
                ruler.endPoint = this._endPoint;
                ruler.midPoint = this._midPoint;
                ruler.startPointSelected = this._startPointSelected;
                ruler.endPointSelected = this._endPointSelected;
            }
        }
        createMeasuringMark(other, position, updater, onSelectionChanged) {
            const mark = new MeasuringMark(other, position, this._widgetGroup, (() => {
                if (!this._isRestoringFromTransaction && !this._isManualInput && this.hasPositionsChanged()) {
                    this.createPositionChangeTransaction();
                }
                updater();
            }), this.uiSession, this._tool.id, onSelectionChanged, ((basePos, targetPos) => {
                const effectiveBase = this.hasActiveAxisLocks() && this._axisLockStartPosition ? this._axisLockStartPosition : basePos;
                return this.getAxisConstrainedPosition(effectiveBase, targetPos);
            }));
            return mark;
        }
        getCurrentMode() {
            if (this._startPoint && !this._endPoint) {
                return RulerMode.WaitingForEndPosition;
            } else if (this._startPoint && this._endPoint) {
                return RulerMode.Idle;
            } else {
                return RulerMode.Idle;
            }
        }
        updateInputFieldsFromRuler() {
            if (this._isManualInput) {
                return;
            }
            if (this._startPoint) {
                this._startPointVector.set(this._startPoint.location);
            } else {
                this._startPointVector.set({
                    x: 0,
                    y: 0,
                    z: 0
                });
            }
            if (this._endPoint) {
                this._endPointVector.set(this._endPoint.location);
            } else {
                this._endPointVector.set({
                    x: 0,
                    y: 0,
                    z: 0
                });
            }
        }
        destroyAllRulerWidgets() {
            this._rulers.forEach((ruler => {
                this.destroyRulerWidgets(ruler);
            }));
            this.destroyCurrentRulerWidgets();
        }
        teardown() {
            if (this._tempTransactionData) {
                this.cancelTransaction();
            }
            this.destroyAllRulerWidgets();
            try {
                this.uiSession.extensionContext.widgetManager.deleteGroup(this._widgetGroup);
            } catch {}
            if (this._transactionHandler) {
                this._transactionHandler = undefined;
            }
        }
        addTool(uiSession) {
            const toolToggleAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    uiSession.toolRail.setSelectedToolId(tool.id);
                }
            });
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, toolToggleAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_R,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editorCore:ruler:toggleTool",
                label: "resourcePack.editor.toolRail.rulerTool.keyBinding.toggleTool.label",
                tooltip: "resourcePack.editor.toolRail.rulerTool.keyBinding.toggleTool.tooltip"
            });
            const tool = uiSession.toolRail.addTool(RulerToolBehavior.MODAL_TOOL_ID, {
                title: "resourcePack.editor.toolRail.rulerTool.title",
                icon: "pack://textures/editor/Ruler.png?filtering=point",
                tooltip: {
                    description: "resourcePack.editor.toolRail.rulerTool.tooltip.description",
                    image: "pack://textures/editor/Ruler.gif"
                },
                action: toolToggleAction
            });
            const executeAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    if (!this._tool.isActive || !mouseRay?.cursorBlockLocation) {
                        return;
                    }
                    const targetLocation = mouseRay.cursorBlockLocation;
                    const roundedLocation = {
                        x: Math.floor(targetLocation.x),
                        y: Math.floor(targetLocation.y),
                        z: Math.floor(targetLocation.z)
                    };
                    const constrainedLocation = this.hasActiveAxisLocks() && this._startPoint && this._startPoint.widget ? this.getAxisConstrainedPosition(this._startPoint.widget.location, roundedLocation) : roundedLocation;
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton) {
                        this._isManualInput = false;
                        const isCtrlPressed = mouseProps.modifiers?.ctrl || false;
                        if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown) {
                            if (!this._startPoint || this._endPoint && isCtrlPressed) {
                                this.startTransaction(RulerOperation.CreateRuler);
                                if (this._endPoint && isCtrlPressed) {
                                    if (this._activeRulerIndex === -1 && this._startPoint && this._endPoint) {
                                        const newRulerData = {
                                            startPoint: this._startPoint,
                                            endPoint: this._endPoint,
                                            midPoint: this._midPoint,
                                            startPointSelected: this._startPointSelected,
                                            endPointSelected: this._endPointSelected
                                        };
                                        this._rulers.push(newRulerData);
                                        this._activeRulerIndex = this._rulers.length - 1;
                                    }
                                    const newRulerPartial = this.createNewRuler();
                                    const newRulerIndex = this._rulers.length;
                                    this._rulers.push({
                                        ...newRulerPartial,
                                        startPoint: this.createMeasuringMark(undefined, constrainedLocation, (() => {
                                            this.updateRulerUI();
                                        }), (selected => {
                                            if (newRulerIndex < this._rulers.length) {
                                                this._rulers[newRulerIndex].startPointSelected = selected;
                                            }
                                            if (this._activeRulerIndex === newRulerIndex) {
                                                this._startPointSelected = selected;
                                            }
                                        }))
                                    });
                                    this.setActiveRuler(this._rulers.length - 1);
                                } else {
                                    if (this._endPoint) {
                                        this.telemetryManager.fireTelemetryEvent(RulerTelemetry.Reset);
                                        this._startPoint?.destroy();
                                        this._endPoint?.destroy();
                                        this._midPoint?.destroy();
                                        if (this._activeRulerIndex >= 0) {
                                            this._rulers.splice(this._activeRulerIndex, 1);
                                            this._activeRulerIndex = -1;
                                        }
                                        this._startPoint = undefined;
                                        this._endPoint = undefined;
                                        this._midPoint = undefined;
                                        this._selectionState.resetState(MeasuringMarkSelectionState.NotSelected);
                                    }
                                    this._startPoint = this.createMeasuringMark(undefined, constrainedLocation, (() => {
                                        this.updateRulerUI();
                                    }), (selected => {
                                        this._startPointSelected = selected;
                                    }));
                                    if (this.hasActiveAxisLocks()) {
                                        this._axisLockStartPosition = constrainedLocation;
                                    }
                                }
                                this._selectionState.resetState(MeasuringMarkSelectionState.StartPositionSelected);
                                this.telemetryManager.fireTelemetryEvent(RulerTelemetry.StartPointSelected);
                                this.commitTransaction(RulerOperation.CreateRuler);
                                this._dragStartLocation = constrainedLocation;
                                this.updateInputFieldsFromRuler();
                                this.updateGizmoAxisVisibility();
                            }
                        } else if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.Drag && this._dragStartLocation && this._startPoint) {
                            if (!this._isDragging) {
                                this._isDragging = true;
                                this.telemetryManager.fireTelemetryEvent(RulerTelemetry.DragStart);
                            }
                            const endpointLocation = constrainedLocation;
                            if (!this._endPoint) {
                                this.startTransaction(RulerOperation.CompleteRuler);
                                this._endPoint = this.createMeasuringMark(this._startPoint, endpointLocation, (() => {
                                    this.updateRulerUI();
                                }), (selected => {
                                    this._endPointSelected = selected;
                                }));
                                this._midPoint = new Midpoint(this._startPoint, this._endPoint, this._widgetGroup, uiSession);
                                this._selectionState.resetState(MeasuringMarkSelectionState.EndPositionSelected);
                                this.commitTransaction(RulerOperation.CompleteRuler);
                            } else {
                                this._endPoint.updateLocation(endpointLocation);
                            }
                            this.updateInputFieldsFromRuler();
                            this.updateInfoText();
                            this._midPoint?.update();
                            this.updateGizmoAxisVisibility();
                        } else if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonUp) {
                            if (this._isDragging) {
                                this._isDragging = false;
                                this._dragStartLocation = undefined;
                                this.telemetryManager.fireTelemetryEvent(RulerTelemetry.DragEnd);
                                if (this._endPoint) {
                                    this._endPoint.updateLocation(constrainedLocation);
                                    this.telemetryManager.fireTelemetryEvent(RulerTelemetry.EndPointSelected);
                                    if (this._activeRulerIndex === -1 && this._startPoint && this._endPoint) {
                                        const completedRuler = {
                                            startPoint: this._startPoint,
                                            endPoint: this._endPoint,
                                            midPoint: this._midPoint,
                                            startPointSelected: this._startPointSelected,
                                            endPointSelected: this._endPointSelected
                                        };
                                        this._rulers.push(completedRuler);
                                        this._activeRulerIndex = this._rulers.length - 1;
                                    } else {
                                        this.updateActiveRulerFromLegacyProperties();
                                    }
                                    this._midPoint?.update();
                                    this.updateInputFieldsFromRuler();
                                    this.updateInfoText();
                                }
                            } else {
                                if (this._startPoint && !this._endPoint) {
                                    if (this._dragStartLocation && lib.Vector3Utils.equals(this._dragStartLocation, constrainedLocation)) {
                                        this._dragStartLocation = undefined;
                                        return;
                                    }
                                    this.startTransaction(RulerOperation.CompleteRuler);
                                    const endpointLocation = constrainedLocation;
                                    this._endPoint = this.createMeasuringMark(this._startPoint, endpointLocation, (() => {
                                        this.updateRulerUI();
                                    }), (selected => {
                                        this._endPointSelected = selected;
                                    }));
                                    this._midPoint = new Midpoint(this._startPoint, this._endPoint, this._widgetGroup, uiSession);
                                    this._selectionState.resetState(MeasuringMarkSelectionState.EndPositionSelected);
                                    this.telemetryManager.fireTelemetryEvent(RulerTelemetry.EndPointSelected);
                                    if (this._activeRulerIndex === -1 && this._startPoint && this._endPoint) {
                                        const completedRuler = {
                                            startPoint: this._startPoint,
                                            endPoint: this._endPoint,
                                            midPoint: this._midPoint,
                                            startPointSelected: this._startPointSelected,
                                            endPointSelected: this._endPointSelected
                                        };
                                        this._rulers.push(completedRuler);
                                        this._activeRulerIndex = this._rulers.length - 1;
                                    } else {
                                        this.updateActiveRulerFromLegacyProperties();
                                    }
                                    this._dragStartLocation = undefined;
                                    this.updateInputFieldsFromRuler();
                                    this.updateInfoText();
                                    this.updateGizmoAxisVisibility();
                                    this.commitTransaction(RulerOperation.CompleteRuler);
                                } else {
                                    this._dragStartLocation = undefined;
                                }
                            }
                        }
                    }
                }
            });
            tool.registerMouseButtonBinding(executeAction);
            return tool;
        }
        toggleSelectAllWidgets() {
            let allSelected = true;
            let hasAnyWidgets = false;
            for (let i = 0; i < this._rulers.length; i++) {
                const ruler = this._rulers[i];
                if (ruler.startPoint) {
                    hasAnyWidgets = true;
                    if (!ruler.startPointSelected) {
                        allSelected = false;
                    }
                }
                if (ruler.endPoint) {
                    hasAnyWidgets = true;
                    if (!ruler.endPointSelected) {
                        allSelected = false;
                    }
                }
            }
            if (this._startPoint && this._activeRulerIndex === -1) {
                hasAnyWidgets = true;
                if (!this._startPointSelected) {
                    allSelected = false;
                }
            }
            if (this._endPoint && this._activeRulerIndex === -1) {
                hasAnyWidgets = true;
                if (!this._endPointSelected) {
                    allSelected = false;
                }
            }
            if (hasAnyWidgets && allSelected) {
                this.telemetryManager.fireTelemetryEvent(RulerTelemetry.DeselectAllWidgets);
                this.deselectAllWidgets();
            } else {
                this.telemetryManager.fireTelemetryEvent(RulerTelemetry.SelectAllWidgets);
                for (let i = 0; i < this._rulers.length; i++) {
                    const ruler = this._rulers[i];
                    if (ruler.startPoint) {
                        ruler.startPoint.setSelected(true, this._widgetGroup);
                        ruler.startPointSelected = true;
                    }
                    if (ruler.endPoint) {
                        ruler.endPoint.setSelected(true, this._widgetGroup);
                        ruler.endPointSelected = true;
                    }
                }
                if (this._startPoint && this._activeRulerIndex === -1) {
                    this._startPoint.setSelected(true, this._widgetGroup);
                    this._startPointSelected = true;
                }
                if (this._endPoint && this._activeRulerIndex === -1) {
                    this._endPoint.setSelected(true, this._widgetGroup);
                    this._endPointSelected = true;
                }
            }
        }
        syncWidgetSelectionToRulerState(widget, currentRulerState) {
            if (widget?.selected) {
                return true;
            }
            return currentRulerState;
        }
        syncSelectionStates() {
            for (let i = 0; i < this._rulers.length; i++) {
                const ruler = this._rulers[i];
                ruler.startPointSelected = this.syncWidgetSelectionToRulerState(ruler.startPoint?.widget, ruler.startPointSelected);
                ruler.endPointSelected = this.syncWidgetSelectionToRulerState(ruler.endPoint?.widget, ruler.endPointSelected);
            }
            if (this._activeRulerIndex >= 0 && this._activeRulerIndex < this._rulers.length) {
                const activeRuler = this._rulers[this._activeRulerIndex];
                this._startPointSelected = activeRuler.startPointSelected;
                this._endPointSelected = activeRuler.endPointSelected;
            } else if (this._activeRulerIndex === -1) {
                this._startPointSelected = this.syncWidgetSelectionToRulerState(this._startPoint?.widget, this._startPointSelected);
                this._endPointSelected = this.syncWidgetSelectionToRulerState(this._endPoint?.widget, this._endPointSelected);
            }
        }
        deleteSelectedRulerLine() {
            if (!this._tool.isActive) {
                this.uiSession.log.debug("[RulerTool] Delete attempted but ruler tool not active");
                return;
            }
            this.syncSelectionStates();
            let totalRulers = this._rulers.length;
            let selectedRulers = 0;
            let hasActiveRulerSelected = false;
            for (let i = 0; i < this._rulers.length; i++) {
                const ruler = this._rulers[i];
                const hasSelection = ruler.startPointSelected || ruler.endPointSelected;
                if (hasSelection) {
                    selectedRulers++;
                }
            }
            if (this._activeRulerIndex === -1 && (this._startPoint || this._endPoint)) {
                totalRulers++;
                if (this._startPointSelected || this._endPointSelected) {
                    selectedRulers++;
                    hasActiveRulerSelected = true;
                }
            }
            this.uiSession.log.debug(`[RulerTool] Delete status: totalRulers=${totalRulers}, selectedRulers=${selectedRulers}, hasActiveRulerSelected=${hasActiveRulerSelected}`);
            this.uiSession.log.debug(`[RulerTool] Active ruler index: ${this._activeRulerIndex}, start point exists: ${!!this._startPoint}, end point exists: ${!!this._endPoint}`);
            this.uiSession.log.debug(`[RulerTool] Start selected: ${this._startPointSelected}, end selected: ${this._endPointSelected}`);
            if (totalRulers > 0 && selectedRulers === totalRulers) {
                this.uiSession.log.debug("[RulerTool] All rulers selected - clearing everything");
                this.clearRuler();
                return;
            }
            if (selectedRulers === 0) {
                this.uiSession.log.debug("[RulerTool] No rulers selected - nothing to delete");
                return;
            }
            const rulersToDelete = [];
            for (let i = 0; i < this._rulers.length; i++) {
                const ruler = this._rulers[i];
                if (ruler.startPointSelected || ruler.endPointSelected) {
                    rulersToDelete.push(i);
                }
            }
            for (let i = rulersToDelete.length - 1; i >= 0; i--) {
                const rulerIndex = rulersToDelete[i];
                const ruler = this._rulers[rulerIndex];
                ruler.startPoint?.destroy();
                ruler.endPoint?.destroy();
                ruler.midPoint?.destroy();
                this._rulers.splice(rulerIndex, 1);
                if (this._activeRulerIndex > rulerIndex) {
                    this._activeRulerIndex--;
                } else if (this._activeRulerIndex === rulerIndex) {
                    this._activeRulerIndex = -1;
                }
            }
            if (hasActiveRulerSelected) {
                this._startPoint?.destroy();
                this._endPoint?.destroy();
                this._midPoint?.destroy();
                this._startPoint = undefined;
                this._endPoint = undefined;
                this._midPoint = undefined;
                this._startPointSelected = false;
                this._endPointSelected = false;
                this._activeRulerIndex = -1;
            }
            if (this._activeRulerIndex === -1) {
                if (this._rulers.length > 0) {
                    this.setActiveRuler(0);
                } else {
                    this._startPoint = undefined;
                    this._endPoint = undefined;
                    this._midPoint = undefined;
                    this._startPointSelected = false;
                    this._endPointSelected = false;
                    this._startPointVector.set({
                        x: 0,
                        y: 0,
                        z: 0
                    });
                    this._endPointVector.set({
                        x: 0,
                        y: 0,
                        z: 0
                    });
                    this.updateInfoText();
                }
            }
        }
        deselectAllWidgets() {
            for (const ruler of this._rulers) {
                if (ruler.startPoint) {
                    ruler.startPoint.setSelected(false, this._widgetGroup);
                    ruler.startPointSelected = false;
                }
                if (ruler.endPoint) {
                    ruler.endPoint.setSelected(false, this._widgetGroup);
                    ruler.endPointSelected = false;
                }
            }
            if (this._startPoint && this._activeRulerIndex === -1) {
                this._startPoint.setSelected(false, this._widgetGroup);
                this._startPointSelected = false;
            }
            if (this._endPoint && this._activeRulerIndex === -1) {
                this._endPoint.setSelected(false, this._widgetGroup);
                this._endPointSelected = false;
            }
        }
    }
    RulerToolBehavior.BEHAVIOR_NAME = "Ruler Tool";
    RulerToolBehavior.MODAL_TOOL_ID = "editor:modalTool:ruler";
    class ExportBehavior {
        constructor(_uiSession, parentMenu) {
            this._uiSession = _uiSession;
            this._exportStatusMessage = (0, server_editor_namespaceObject.makeObservable)("");
            this._exportPane = this.buildPropertyPane(this._uiSession);
            this.createMenuItem(parentMenu);
            this.addActionBarItem();
        }
        createMenuItem(menu) {
            menu.addItem({
                label: "resourcePack.editor.menuBar.file.export",
                tooltip: "resourcePack.editor.menuBar.file.export.tooltip"
            }, this._uiSession?.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._exportPane) {
                        this._exportPane?.show();
                    }
                }
            }));
        }
        addActionBarItem() {
            const showExportPaneAction = this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._exportPane) {
                        this._exportPane?.show();
                    }
                }
            });
            this._uiSession.actionBar.registerItem(server_editor_namespaceObject.CoreActionBarItemType.Export, showExportPaneAction, {
                label: "resourcePack.editor.menuBar.file.export",
                icon: "pack://textures/editor/Export.png",
                tooltipTitle: "resourcePack.editor.menuBar.file.export",
                tooltipDescription: "resourcePack.editor.menuBar.file.export.actionBar.tooltip",
                enabled: true,
                executeOnAdd: true
            });
        }
        buildPropertyPane(uiSession) {
            const exportPane = uiSession.createPropertyPane({
                title: `resourcePack.editor.menuBar.file.export`,
                infoTooltip: {
                    description: [ "resourcePack.editor.exportProject.pane.tooltip" ]
                },
                uniqueId: "editor:pane:exportProject"
            });
            const playerUISession = uiSession;
            if (playerUISession) {
                this._worldSettings = new WorldSettingsPane(playerUISession, exportPane, true);
            }
            const exportType = this._worldSettings?.getObservablePaneElements().exportType;
            exportPane.beginConstruct();
            if (exportType) {
                exportPane.addDropdown(exportType, {
                    title: `resourcePack.editor.exportProject.exportType`,
                    tooltip: `resourcePack.editor.exportProject.exportType.tooltip`,
                    entries: [ {
                        label: "resourcePack.editor.exportProject.exportType.playableWorld",
                        value: 0
                    } ]
                });
            }
            const versionNumber = this._uiSession.extensionContext.exportManager.getGameVersion();
            if (versionNumber) {
                const warningPane = exportPane.createSubPane({
                    title: `resourcePack.editor.exportProject.exportNotes`,
                    infoTooltip: {
                        title: `resourcePack.editor.exportProject.exportNotes`,
                        description: [ `resourcePack.editor.exportProject.exportNotes.tooltip` ]
                    }
                });
                warningPane.addText({
                    id: "resourcePack.editor.exportProject.exportNotes.warning",
                    props: [ `${versionNumber}` ]
                });
            }
            exportPane.addDivider();
            this._worldSettings?.BuildPropertyPane();
            exportPane.addDivider();
            const buttonPane = exportPane.addButtonPane({
                itemMinWidth: 16
            });
            buttonPane.addButton(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._worldSettings) {
                        const options = this._worldSettings.getGameOptions();
                        this.tryExport(options);
                        fireTelemetryEvent(uiSession.extensionContext.player, TelemetrySource.Export, "ExportButton", {
                            settings: options
                        });
                    }
                }
            }), {
                title: `resourcePack.editor.exportProject.export`
            });
            buttonPane.addButton(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._worldSettings) {
                        this._worldSettings.setToDefaultGameOptions();
                        fireTelemetryEvent(uiSession.extensionContext.player, TelemetrySource.Export, "ResetButton");
                    }
                }
            }), {
                title: `resourcePack.editor.exportProject.resetToDefault`
            });
            this._exportStatusMessagePane = exportPane.addText(this._exportStatusMessage, {
                visible: false
            });
            this._progressModalScreen = exportPane.createModalOverlayPane({
                title: "resourcePack.editor.exportProject.exportNotes.export"
            });
            this._progressModalScreen.contentPane.addProgressIndicator({
                title: "resourcePack.editor.exportProject.exportNotes.progress"
            });
            exportPane.endConstruct();
            return exportPane;
        }
        tryExport(options) {
            if (!this._uiSession?.extensionContext.exportManager.canExportProject() || this._exportTimeoutHandle !== undefined) {
                this._exportStatusMessage.set("resourcePack.editor.exportProject.exportNotes.busy");
                return;
            }
            if (this._exportStatusMessagePane) {
                this._exportStatusMessagePane.visible = false;
            }
            this._progressModalScreen?.show();
            this._exportTimeoutHandle = server_namespaceObject.system.runTimeout((() => {
                this._uiSession.extensionContext.exportManager.beginExportProject(options).then((exportResult => {
                    this._uiSession?.log.info(`Project Export ending with result: ${capitalizeAndSpaceEnumName(getEnumKeyByEnumValue(server_editor_namespaceObject.ExportResult, exportResult))}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    switch (exportResult) {
                      case server_editor_namespaceObject.ExportResult.ValidWorldExport:
                        this._exportStatusMessage.set("resourcePack.editor.exportProject.exportNotes.exportSuccess");
                        break;

                      case server_editor_namespaceObject.ExportResult.WorldExportBusy:
                        this._exportStatusMessage.set("resourcePack.editor.exportProject.exportNotes.busy");
                        break;

                      default:
                        this._exportStatusMessage.set("resourcePack.editor.exportProject.exportNotes.exportFailed");
                    }
                })).catch((error => {
                    this._uiSession.log.error(`Export error : ${error}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    this._exportStatusMessage.set("resourcePack.editor.exportProject.exportNotes.exportFailed");
                })).finally((() => {
                    if (this._exportStatusMessagePane) {
                        this._exportStatusMessagePane.visible = true;
                    }
                    this._progressModalScreen?.hide();
                    this._exportTimeoutHandle = undefined;
                }));
            }), server_namespaceObject.TicksPerSecond);
        }
        teardown() {
            if (this._exportTimeoutHandle !== undefined) {
                server_namespaceObject.system.clearRun(this._exportTimeoutHandle);
            }
        }
    }
    var BrushTelemetry;
    (function(BrushTelemetry) {
        BrushTelemetry["StartPaining"] = "StartPaining";
        BrushTelemetry["EndPainting"] = "EndPainting";
    })(BrushTelemetry || (BrushTelemetry = {}));
    class BrushPainterBehavior {
        get session() {
            return this._session;
        }
        get tool() {
            return this._tool;
        }
        get rootPane() {
            return this._rootPane;
        }
        constructor(_session) {
            this._session = _session;
            this.telemetryManager = new TelemetryManager(_session.extensionContext.player, TelemetrySource.Brush);
            this._cursorProperties = {
                outlineColor: {
                    red: 0,
                    green: .5,
                    blue: .5,
                    alpha: .2
                },
                controlMode: server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse,
                targetMode: server_editor_namespaceObject.CursorTargetMode.Block,
                visible: true
            };
            const activationAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.session.toolRail.setSelectedToolId(this.tool.id);
                }
            });
            this._tool = this.session.toolRail.addTool("editor:modalTool:brushPainter", {
                title: "resourcePack.editor.brushPaint.title",
                icon: "pack://textures/editor/Brush.png?filtering=point",
                tooltip: {
                    description: {
                        id: "resourcePack.editor.brushPaint.tool.tooltip",
                        props: [ getInputMarkup("editor:toolModeKeyBinding:togglePencilBrushMode") ]
                    },
                    image: "pack://textures/editor/Brush.gif"
                },
                action: activationAction
            });
            this.session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, activationAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_B,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:toolModeKeyBinding:toggleBrushMode",
                label: "resourcePack.editor.brushPaint.inputContext.activateBrushPaint.title",
                tooltip: "resourcePack.editor.brushPaint.inputContext.activateBrushPaint.tooltip"
            });
            this._rootPane = this.session.createPropertyPane({
                title: "resourcePack.editor.brushPaint.title",
                infoTooltip: {
                    description: [ {
                        id: "resourcePack.editor.brushPaint.tool.tooltip",
                        props: [ getInputMarkup("editor:toolModeKeyBinding:togglePencilBrushMode") ]
                    }, {
                        link: "https://aka.ms/BedrockEditorBrush",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this.tool.bindPropertyPane(this.rootPane);
            const bindManualControls = true;
            this._cursorModeControl = new CursorModeControl(this.session, this.tool, this.rootPane, bindManualControls, this._cursorProperties);
            this._cursorModeControl.initialize();
            this._brushControl = new BrushPaintSharedControl(this.session, this.tool, this.rootPane, {
                paintMode: server_editor_namespaceObject.PaintMode.BlockPaint
            }, (0, server_editor_namespaceObject.getDefaultBrushShapes)([ server_editor_namespaceObject.CoreBrushShapeType.SingleBlock ]));
            this._brushControl.initialize();
            this.tool.onModalToolActivation.subscribe((data => {
                if (data.isActiveTool) {
                    this._cursorModeControl.activateControl();
                    this._brushControl.activateControl();
                } else {
                    this._onLeave();
                }
            }));
            this._paintingActive = false;
            this._registerMouseUpDownAction();
            this._registerKeyboardInputActions();
        }
        _registerMouseUpDownAction() {
            const action = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (_mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton) {
                        if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown) {
                            this.telemetryManager.fireTelemetryEvent(BrushTelemetry.StartPaining);
                            this._beginPainting();
                        } else if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonUp && this._paintingActive) {
                            this.telemetryManager.fireTelemetryEvent(BrushTelemetry.EndPainting, {
                                offset: this._session.extensionContext.brushShapeManager.getBrushShapeOffset()
                            });
                            this._endPainting();
                        }
                    }
                }
            });
            this._tool.registerMouseButtonBinding(action);
        }
        _registerKeyboardInputActions() {
            const singlePressPaintAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._paintingActive) {
                        return;
                    }
                    this.session.extensionContext.transactionManager.openTransaction("Brush Paint");
                    this.session.extensionContext.brushShapeManager.singlePaint((state => {
                        if (state === server_editor_bindings_namespaceObject.PaintCompletionState.Success) {
                            this.session.extensionContext.transactionManager.commitOpenTransaction();
                        } else {
                            this.session.extensionContext.transactionManager.discardOpenTransaction();
                            this.session.log.error(`Error during painting`, {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                        }
                        this._paintingActive = false;
                    }));
                }
            });
            this.tool.registerKeyBinding(singlePressPaintAction, {
                key: server_editor_namespaceObject.KeyboardKey.ENTER
            }, {
                uniqueId: "editor:brushPainter:paintAtCursor",
                label: "resourcePack.editor.brushPaint.inputContext.oneshot.title",
                tooltip: "resourcePack.editor.brushPaint.inputContext.oneshot.tooltip"
            });
        }
        _beginPainting() {
            if (this.session.extensionContext.brushShapeManager.isBrushPaintBusy() || this.session.extensionContext.transactionManager.isBusy()) {
                this.session.log.warning(`Brush already active`);
                return;
            }
            this._paintingActive = true;
            this.session.extensionContext.transactionManager.openTransaction("Brush Paint");
            this.session.extensionContext.brushShapeManager.beginPainting((state => {
                if (state === server_editor_bindings_namespaceObject.PaintCompletionState.Success) {
                    this.session.extensionContext.transactionManager.commitOpenTransaction();
                } else {
                    this.session.extensionContext.transactionManager.discardOpenTransaction();
                    this.session.log.error(`Error during painting`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
                this._paintingActive = false;
            }));
        }
        _endPainting() {
            this._paintingActive = false;
            this.session.extensionContext.brushShapeManager.endPainting(false);
        }
        _onLeave() {
            if (this._paintingActive) {
                this._endPainting();
            }
            if (this._cursorModeControl.isActive) {
                this._cursorModeControl.deactivateControl();
            }
            if (this._brushControl.isActive) {
                this._brushControl.deactivateControl();
            }
        }
        teardown() {
            this._onLeave();
            this._cursorModeControl.shutdown();
            this._brushControl.shutdown();
        }
    }
    BrushPainterBehavior.BEHAVIOR_NAME = "Brush Paint";
    var LocateMode;
    (function(LocateMode) {
        LocateMode[LocateMode["Biome"] = 0] = "Biome";
    })(LocateMode || (LocateMode = {}));
    var LocateTelemetry;
    (function(LocateTelemetry) {
        LocateTelemetry["SelectionBiome"] = "SelectionBiome";
        LocateTelemetry["FindBiome"] = "FindBiome";
        LocateTelemetry["GoToResults"] = "GoToResults";
    })(LocateTelemetry || (LocateTelemetry = {}));
    class LocateTool {
        constructor(_session, parentMenu) {
            this._session = _session;
            this.PANE_ID = "editor:pane:locate";
            this._locatorType = (0, server_editor_namespaceObject.makeObservable)(LocateMode.Biome);
            this._results = {
                foundMessage: (0, server_editor_namespaceObject.makeObservable)(""),
                foundPos: (0, server_editor_namespaceObject.makeObservable)(lib.VECTOR3_ZERO)
            };
            this.blockedBiomes = new Set([ "hell" ]);
            this.telemetryManager = new TelemetryManager(this._session.extensionContext.player, TelemetrySource.Locate);
            this._rootPane = this._session.createPropertyPane({
                title: "resourcePack.editor.locate.title",
                uniqueId: this.PANE_ID,
                infoTooltip: {
                    description: [ "resourcePack.editor.locate.tooltip", {
                        link: "https://aka.ms/BedrockEditorLocate",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this._createLocatorPane();
            this._createResultsPane();
            this._activationAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._rootPane.show();
                }
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, this._activationAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_L,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editor:toolModeKeyBinding:toggleLocateTool",
                label: "resourcePack.editor.locate.keyBinding.toggleTool.title",
                tooltip: "resourcePack.editor.locate.keyBinding.toggleTool.tooltip"
            });
            this._session.actionBar.registerItem(server_editor_namespaceObject.CoreActionBarItemType.Locate, this._activationAction, {
                label: "resourcePack.editor.locate.title",
                icon: "pack://textures/editor/Pin.png",
                tooltipTitle: "resourcePack.editor.locate.title",
                tooltipDescription: "resourcePack.editor.locate.actionBar.tooltip",
                enabled: true,
                executeOnAdd: true
            });
            this.createMenuItem(parentMenu);
        }
        teardown() {}
        createMenuItem(menu) {
            menu.addItem({
                label: "resourcePack.editor.locate.title",
                tooltip: "resourcePack.editor.locate.tooltip"
            }, this._activationAction);
        }
        _createLocatorPane() {
            this._locatorPane = this._rootPane.createSubPane({
                title: "resourcePack.editor.locate.locatetype.title"
            });
            this._locatorPane.addDropdown(this._locatorType, {
                title: "resourcePack.editor.locate.locatetype.title",
                tooltip: "resourcePack.editor.locate.locatetype.tooltip",
                entries: [ {
                    label: "resourcePack.editor.locate.locatetype.biome",
                    value: LocateMode.Biome
                } ],
                onChange: newValue => {
                    if (newValue === LocateMode.Biome) {
                        this._locatorPane.toggleSubPaneVisibility(this._biomePane.id);
                    }
                    this._resultOutputPane?.hide();
                }
            });
            this._biomePane = this._locatorPane.createSubPane({
                title: "resourcePack.editor.locate.biome.title"
            });
            const listOfBiomes = server_namespaceObject.BiomeTypes.getAll().map((v => {
                const id = v.id.replace("minecraft:", "");
                const item = {
                    label: id.split("_").map((word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())).join(" "),
                    value: id
                };
                return item;
            }));
            const defaultBiome = listOfBiomes[0].value;
            const biomeType = {
                biomeId: (0, server_editor_namespaceObject.makeObservable)(defaultBiome),
                biomePos: (0, server_editor_namespaceObject.makeObservable)(lib.VECTOR3_ZERO)
            };
            this._biomePane.addComboBox(biomeType.biomeId, {
                title: "resourcePack.editor.locate.biome.title",
                entries: listOfBiomes,
                defaultValue: defaultBiome,
                onChange: () => {
                    this._resultOutputPane?.hide();
                    this.telemetryManager.fireTelemetryEvent(LocateTelemetry.FindBiome, {
                        biomeId: biomeType.biomeId.value
                    });
                }
            });
            this._biomePane.addButton((() => {
                const player = this._session.extensionContext.player;
                const biomePos = player.dimension.findClosestBiome(player.location, biomeType.biomeId.value);
                this._resultOutputPane?.show();
                if (biomePos) {
                    this._session.log.info(`Found ${biomeType.biomeId.value} at ${lib.Vector3Utils.toString(biomePos)}`);
                    this._results.foundMessage.set({
                        id: "resourcePack.editor.locate.results.found.result",
                        props: [ biomeType.biomeId.value ]
                    });
                    this._results.foundPos.set(biomePos);
                    this._resultOutputPane.toggleSubPaneVisibility(this._resultSuccessPane.id);
                } else {
                    this._resultOutputPane.toggleSubPaneVisibility(this._resultErrorPane.id);
                }
                this.telemetryManager.fireTelemetryEvent(LocateTelemetry.FindBiome, {
                    biomeId: biomeType.biomeId.value
                });
            }), {
                title: "resourcePack.editor.locate.biome.find",
                visible: true,
                icon: "pinIcon"
            });
        }
        _createResultsPane() {
            this._resultOutputPane = this._rootPane.createSubPane({
                title: "resourcePack.editor.locate.results.title"
            });
            this._resultSuccessPane = this._resultOutputPane.createSubPane({
                title: "resourcePack.editor.locate.results.foundat.title"
            });
            this._resultSuccessPane.addText(this._results.foundMessage);
            this._resultSuccessPane.addVector3(this._results.foundPos, {
                title: "resourcePack.editor.locate.results.foundat",
                enable: false,
                visible: true
            });
            this._resultSuccessPane.addButton((() => {
                const pos = this._results.foundPos;
                this._session.extensionContext.player.teleport(pos.value);
                this.telemetryManager.fireTelemetryEvent(LocateTelemetry.GoToResults);
            }), {
                title: "resourcePack.editor.locate.results.goto"
            });
            this._resultErrorPane = this._resultOutputPane.createSubPane({
                title: "resourcePack.editor.locate.results.notfound.title"
            });
            this._resultErrorPane.addText("resourcePack.editor.locate.results.notfound", {
                border: true
            });
            this._resultOutputPane.hide();
        }
    }
    const PROPERTY_CLIPBOARDPREVIEWCONTROL_NAME = "ClipboardPreviewControl";
    const PROPERTY_CLIPBOARDPREVIEWCONTROL_LOCALIZATION_PREFIX = `resourcePack.editor.${PROPERTY_CLIPBOARDPREVIEWCONTROL_NAME}`;
    class ClipboardPreviewControl extends SharedControlImpl {
        constructor(session, parentTool, parentPropertyPane, clipboardItem, options) {
            super(session, parentTool, parentPropertyPane, PROPERTY_CLIPBOARDPREVIEWCONTROL_NAME, PROPERTY_CLIPBOARDPREVIEWCONTROL_LOCALIZATION_PREFIX);
            this._structureSize = (0, server_editor_namespaceObject.makeObservable)(new lib.Vector3Builder(0, 0, 0));
            this._structureHumanReadableOrigin = (0, server_editor_namespaceObject.makeObservable)(new lib.Vector3Builder(0, 0, 0));
            this._structureOffset = (0, server_editor_namespaceObject.makeObservable)(new lib.Vector3Builder(0, 0, 0));
            this._structureRotationIndex = (0, server_editor_namespaceObject.makeObservable)(0);
            this._structureMirrorX = (0, server_editor_namespaceObject.makeObservable)(false);
            this._structureMirrorZ = (0, server_editor_namespaceObject.makeObservable)(false);
            this._editorMode = server_editor_namespaceObject.EditorMode.Tool;
            this._fillVolume = async (dimension, volume, fillBlockType) => {
                const operation = blockLocation => {
                    const block = dimension.getBlock(blockLocation);
                    if (block) {
                        block.setType(fillBlockType);
                    }
                };
                await executeLargeOperationFromIteratorWithTransactionAndTicking(this.session.extensionContext, this.session.log, volume.getBoundingBox(), volume.getBlockLocationIterator(), "Inverse Paste", operation);
            };
            this._clipboardItem = clipboardItem;
            this._setupParametersFromClipboardItem();
            this._structureRotationIndex.set(this._getRotationOrderIndex(options?.rotation ?? server_namespaceObject.StructureRotation.None));
            const {mirrorX, mirrorZ} = this._getBooleansFromMirrorAxis(options?.mirrorAxis ?? server_namespaceObject.StructureMirrorAxis.None);
            this._structureMirrorX.set(mirrorX);
            this._structureMirrorZ.set(mirrorZ);
            this._structureOffset.set(lib.VECTOR3_ZERO);
            const defaultOrigin = calculateClipboardAbsoluteAnchorValue(this._clipboardItem);
            this._structureHumanReadableOrigin.set(defaultOrigin);
            this._bindToCursor = options?.bindToCursor ?? true;
            this._widgetGroup = this._createWidgetGroup();
            this._transferParametersToClipboardComponent();
            this.session.extensionContext.afterEvents.clipboardChange.subscribe((_event => {
                if (_event.itemId === this._clipboardItem.id) {
                    this._setupParametersFromClipboardItem();
                    this._transferParametersToClipboardComponent();
                }
            }));
        }
        initialize() {
            this.session.log.debug("ClipboardPreviewControl::initialize");
            super.initialize();
            if (!this.tool) {
                throw new Error("Tool is not initialized");
            }
            const offsetNudgeUpAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._nudgeOffset(lib.VECTOR3_UP);
                }
            });
            const offsetNudgeDownAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._nudgeOffset(lib.VECTOR3_DOWN);
                }
            });
            const offsetNudgeForwardAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Forward);
                    this._nudgeOffset(nudgeVector);
                }
            });
            const offsetNudgeBackAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Back);
                    this._nudgeOffset(nudgeVector);
                }
            });
            const offsetNudgeLeftAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Left);
                    this._nudgeOffset(nudgeVector);
                }
            });
            const offsetNudgeRightAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Right);
                    this._nudgeOffset(nudgeVector);
                }
            });
            this.registerToolKeyBinding(offsetNudgeUpAction, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_UP,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetUp");
            this.registerToolKeyBinding(offsetNudgeDownAction, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_DOWN,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetDown");
            this.registerToolKeyBinding(offsetNudgeForwardAction, {
                key: server_editor_namespaceObject.KeyboardKey.UP,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetForward");
            this.registerToolKeyBinding(offsetNudgeBackAction, {
                key: server_editor_namespaceObject.KeyboardKey.DOWN,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetBack");
            this.registerToolKeyBinding(offsetNudgeLeftAction, {
                key: server_editor_namespaceObject.KeyboardKey.LEFT,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetLeft");
            this.registerToolKeyBinding(offsetNudgeRightAction, {
                key: server_editor_namespaceObject.KeyboardKey.RIGHT,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, "nudgeOffsetRight");
            const keyOriginUpAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._nudgeOrigin(lib.VECTOR3_UP);
                }
            });
            const keyOriginDownAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._nudgeOrigin(lib.VECTOR3_DOWN);
                }
            });
            const keyOriginLeftAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Left);
                    this._nudgeOrigin(nudgeVector);
                }
            });
            const keyOriginRightAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Right);
                    this._nudgeOrigin(nudgeVector);
                }
            });
            const keyOriginForwardAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Forward);
                    this._nudgeOrigin(nudgeVector);
                }
            });
            const keyOriginBackAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Back);
                    this._nudgeOrigin(nudgeVector);
                }
            });
            this.registerToolKeyBinding(keyOriginForwardAction, {
                key: server_editor_namespaceObject.KeyboardKey.UP,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, "moveOriginForward");
            this.registerToolKeyBinding(keyOriginBackAction, {
                key: server_editor_namespaceObject.KeyboardKey.DOWN,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, "moveOriginBack");
            this.registerToolKeyBinding(keyOriginLeftAction, {
                key: server_editor_namespaceObject.KeyboardKey.LEFT,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, "moveOriginLeft");
            this.registerToolKeyBinding(keyOriginRightAction, {
                key: server_editor_namespaceObject.KeyboardKey.RIGHT,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, "moveOriginRight");
            this.registerToolKeyBinding(keyOriginUpAction, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_UP,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, "moveOriginUp");
            this.registerToolKeyBinding(keyOriginDownAction, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_DOWN,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, "moveOriginDown");
            const rotateClockwiseAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const index = (this._structureRotationIndex.value + 1) % ClipboardPreviewControl._rotationOrder.length;
                    this._structureRotationIndex.set(index);
                    if (this._widgetComponent) {
                        this._widgetComponent.rotation = this._getRotationFromOrderedIndex(index);
                    }
                }
            });
            this.registerToolKeyBinding(rotateClockwiseAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_R
            }, "rotateClockWise");
            const rotateAntiClockwiseAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const index = ((this._structureRotationIndex.value - 1) % ClipboardPreviewControl._rotationOrder.length + ClipboardPreviewControl._rotationOrder.length) % ClipboardPreviewControl._rotationOrder.length;
                    this._structureRotationIndex.set(index);
                    if (this._widgetComponent) {
                        this._widgetComponent.rotation = this._getRotationFromOrderedIndex(index);
                    }
                }
            });
            this.registerToolKeyBinding(rotateAntiClockwiseAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_R,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, "rotateCounterClockWise");
            const mirrorXAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._structureMirrorX.set(!this._structureMirrorX.value);
                    if (this._widgetComponent) {
                        const mirrorAxis = this._getMirrorAxisFromBooleans(this._structureMirrorX.value, this._structureMirrorZ.value);
                        this._widgetComponent.mirror = mirrorAxis;
                    }
                }
            });
            this.registerToolKeyBinding(mirrorXAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_X
            }, "toggleMirrorX");
            const mirrorZAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._structureMirrorZ.set(!this._structureMirrorZ.value);
                    if (this._widgetComponent) {
                        const mirrorAxis = this._getMirrorAxisFromBooleans(this._structureMirrorX.value, this._structureMirrorZ.value);
                        this._widgetComponent.mirror = mirrorAxis;
                    }
                }
            });
            this.registerToolKeyBinding(mirrorZAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_Z
            }, "toggleMirrorZ");
        }
        shutdown() {
            this.session.log.debug("ClipboardPreviewControl::shutdown");
            super.shutdown();
        }
        activateControl() {
            this.session.log.debug("ClipboardPreviewControl::activateControl");
            if (this.isActive) {
                this.session.log.debug("ClipboardPreviewControl::activateControl - exiting early - already active");
                return;
            }
            super.activateControl();
            this._setupParametersFromClipboardItem();
            this._transferParametersToClipboardComponent();
            this._constructControlUI();
        }
        deactivateControl() {
            this.session.log.debug("ClipboardPreviewControl::deactivateControl");
            if (!this.isActive) {
                this.session.log.debug("ClipboardPreviewControl::deactivateControl - exiting early - already deactivated");
                return;
            }
            super.deactivateControl();
            this._destroyControlUI();
        }
        activateVisualization() {
            this.session.log.debug("ClipboardPreviewControl::activateVisualization");
            this._widgetGroup.visible = true;
            this._createClipboardWidget();
        }
        deactivateVisualization() {
            this.session.log.debug("ClipboardPreviewControl::deactivateVisualization");
            this._widgetGroup.visible = false;
            this._destroyClipboardWidget();
        }
        _constructControlUI() {
            this.session.log.debug("ClipboardPreviewControl::constructControlUI");
            if (this._controlPane) {
                this._structureOriginUIComponent = undefined;
                this.propertyPane.removeSubPane(this._controlPane);
                this._controlPane = undefined;
            }
            this._controlPane = this.propertyPane.createSubPane({
                title: this.localize("rootPane.title"),
                infoTooltip: {
                    title: this.localize("rootPane.title"),
                    description: [ this.localize("rootPane.tooltip") ]
                },
                hasExpander: true
            });
            this._controlPane.beginConstruct();
            this._controlPane.addVector3(this._structureSize, {
                title: this.localize("structureSize.title"),
                tooltip: this.localize("structureSize.tooltip"),
                enable: false,
                isInteger: true
            });
            const placementPane = this._controlPane.createSubPane({
                title: this.localize("placement.title"),
                infoTooltip: {
                    title: this.localize("placement.title"),
                    description: [ this.localize("placement.tooltip") ]
                },
                hasExpander: true,
                hasMargins: false
            });
            this._structureOriginUIComponent = placementPane.addVector3(this._structureHumanReadableOrigin, {
                title: this.localize("origin.title"),
                tooltip: this.localize("origin.tooltip"),
                enable: true,
                isInteger: false,
                min: ClipboardPreviewControl.MIN_ORIGIN,
                max: this._calculateStructureOriginMax(this._structureSize.value),
                onChange: _newValue => {
                    if (this._widgetComponent) {
                        this._widgetComponent.normalizedOrigin = calculateClipboardNormalizedAnchorValue(this._clipboardItem, _newValue);
                    }
                }
            });
            placementPane.addVector3(this._structureOffset, {
                title: this.localize("offset.title"),
                tooltip: this.localize("offset.tooltip"),
                enable: true,
                isInteger: true,
                min: ClipboardPreviewControl.MIN_OFFSET,
                max: ClipboardPreviewControl.MAX_OFFSET,
                onChange: _newValue => {
                    if (this._widgetComponent) {
                        this._widgetComponent.clipboardOffset = _newValue;
                    }
                }
            });
            placementPane.addDropdown(this._structureRotationIndex, {
                title: this.localize("rotation.title"),
                tooltip: {
                    title: {
                        id: this.localize("rotation.tooltip.title"),
                        props: [ getInputMarkup("editor:ClipboardPreviewControl:rotateClockWise") ]
                    },
                    description: {
                        id: this.localize("rotation.tooltip"),
                        props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:ClipboardPreviewControl:rotateClockWise"), newLineMarkup, getInputMarkup("editor:ClipboardPreviewControl:rotateCounterClockWise") ]
                    }
                },
                entries: [ {
                    value: 0,
                    label: this.localize("rotation.none")
                }, {
                    value: 1,
                    label: this.localize("rotation.90")
                }, {
                    value: 2,
                    label: this.localize("rotation.180")
                }, {
                    value: 3,
                    label: this.localize("rotation.270")
                } ],
                onChange: _newValue => {
                    if (this._widgetComponent) {
                        this._widgetComponent.rotation = this._getRotationFromOrderedIndex(_newValue);
                    }
                }
            });
            placementPane.addBool(this._structureMirrorX, {
                enable: true,
                title: this.localize("mirror.axis.x"),
                tooltip: {
                    title: {
                        id: this.localize("mirror.axis.x.tooltip.title"),
                        props: [ getInputMarkup("editor:ClipboardPreviewControl:toggleMirrorX") ]
                    },
                    description: this.localize("mirror.axis.x.tooltip")
                },
                onChange: _newValue => {
                    const mirrorAxis = this._getMirrorAxisFromBooleans(_newValue, this._structureMirrorZ.value);
                    if (this._widgetComponent) {
                        this._widgetComponent.mirror = mirrorAxis;
                    }
                }
            });
            placementPane.addBool(this._structureMirrorZ, {
                enable: true,
                title: this.localize("mirror.axis.z"),
                tooltip: {
                    title: {
                        id: this.localize("mirror.axis.z.tooltip.title"),
                        props: [ getInputMarkup("editor:ClipboardPreviewControl:toggleMirrorZ") ]
                    },
                    description: this.localize("mirror.axis.z.tooltip")
                },
                onChange: _newValue => {
                    if (this._widgetComponent) {
                        const mirrorAxis = this._getMirrorAxisFromBooleans(this._structureMirrorX.value, _newValue);
                        this._widgetComponent.mirror = mirrorAxis;
                    }
                }
            });
            this._controlPane.endConstruct();
        }
        _destroyControlUI() {
            this.session.log.debug("ClipboardPreviewControl::destroyControlUI");
            this._structureOriginUIComponent = undefined;
            if (this._controlPane) {
                this.propertyPane.removeSubPane(this._controlPane);
                this._controlPane = undefined;
            }
        }
        _setupParametersFromClipboardItem() {
            const clipboardSize = this._clipboardItem.size;
            this._structureSize.set(clipboardSize);
            const humanReadableOrigin = calculateClipboardAbsoluteAnchorValue(this._clipboardItem);
            this._structureHumanReadableOrigin.set(humanReadableOrigin);
            if (this._structureOriginUIComponent) {
                const maxHumanReadableOrigin = this._calculateStructureOriginMax(clipboardSize);
                this._structureOriginUIComponent.updateAxisLimits({
                    max: maxHumanReadableOrigin
                });
            }
        }
        _calculateStructureOriginMax(itemSize) {
            const result = lib.Vector3Utils.clamp(lib.Vector3Utils.subtract(itemSize, lib.VECTOR3_ONE), {
                min: lib.VECTOR3_ZERO,
                max: itemSize
            });
            return result;
        }
        _transferParametersToClipboardComponent() {
            if (this._widgetComponent) {
                this._widgetComponent.clipboardOffset = this._structureOffset.value;
                this._widgetComponent.rotation = this._getRotationFromOrderedIndex(this._structureRotationIndex.value);
                this._widgetComponent.mirror = this._getMirrorAxisFromBooleans(this._structureMirrorX.value, this._structureMirrorZ.value);
                this._widgetComponent.normalizedOrigin = calculateClipboardNormalizedAnchorValue(this._clipboardItem, this._structureHumanReadableOrigin.value);
            }
        }
        _getRotationOrderIndex(rotation) {
            const index = ClipboardPreviewControl._rotationOrder.indexOf(rotation);
            return index;
        }
        _getRotationFromOrderedIndex(index) {
            return ClipboardPreviewControl._rotationOrder[index];
        }
        _getMirrorAxisFromBooleans(mirrorX, mirrorZ) {
            if (mirrorX && mirrorZ) {
                return server_namespaceObject.StructureMirrorAxis.XZ;
            } else if (mirrorX) {
                return server_namespaceObject.StructureMirrorAxis.X;
            } else if (mirrorZ) {
                return server_namespaceObject.StructureMirrorAxis.Z;
            }
            return server_namespaceObject.StructureMirrorAxis.None;
        }
        _getBooleansFromMirrorAxis(mirrorAxis) {
            switch (mirrorAxis) {
              case server_namespaceObject.StructureMirrorAxis.XZ:
                return {
                    mirrorX: true,
                    mirrorZ: true
                };

              case server_namespaceObject.StructureMirrorAxis.X:
                return {
                    mirrorX: true,
                    mirrorZ: false
                };

              case server_namespaceObject.StructureMirrorAxis.Z:
                return {
                    mirrorX: false,
                    mirrorZ: true
                };

              default:
                return {
                    mirrorX: false,
                    mirrorZ: false
                };
            }
        }
        _getRelativeNudgeDirection(direction) {
            const rotationY = this.session.extensionContext.player.getRotation().y;
            const rotationCorrectedVector = getRotationCorrectedDirectionVector(rotationY, direction);
            return rotationCorrectedVector;
        }
        _nudgeOffset(nudgeVector) {
            let update = lib.Vector3Utils.add(this._structureOffset.value, nudgeVector);
            update = lib.Vector3Utils.clamp(update, {
                min: ClipboardPreviewControl.MIN_OFFSET,
                max: ClipboardPreviewControl.MAX_OFFSET
            });
            this._structureOffset.set(update);
            if (this._widgetComponent) {
                this._widgetComponent.clipboardOffset = update;
            }
        }
        _nudgeOrigin(nudgeVector) {
            if (this._widgetComponent) {
                const clipboardRotation = this._widgetComponent.rotation;
                let rotatedVector = nudgeVector;
                switch (clipboardRotation) {
                  case server_namespaceObject.StructureRotation.Rotate90:
                    rotatedVector = {
                        x: nudgeVector.z,
                        y: nudgeVector.y,
                        z: -nudgeVector.x
                    };
                    break;

                  case server_namespaceObject.StructureRotation.Rotate180:
                    rotatedVector = {
                        x: -nudgeVector.x,
                        y: nudgeVector.y,
                        z: -nudgeVector.z
                    };
                    break;

                  case server_namespaceObject.StructureRotation.Rotate270:
                    rotatedVector = {
                        x: -nudgeVector.z,
                        y: nudgeVector.y,
                        z: nudgeVector.x
                    };
                }
                let update = lib.Vector3Utils.add(this._structureHumanReadableOrigin.value, rotatedVector);
                const maxSize = this._calculateStructureOriginMax(this._structureSize.value);
                update = lib.Vector3Utils.clamp(update, {
                    min: lib.VECTOR3_ZERO,
                    max: maxSize
                });
                this._structureHumanReadableOrigin.set(update);
                this._widgetComponent.normalizedOrigin = calculateClipboardNormalizedAnchorValue(this._clipboardItem, update);
            }
        }
        pastePreviewIntoWorld(location) {
            if (!this.isActive) {
                throw new Error("Control must be active");
            }
            if (this._clipboardItem.isEmpty) {
                this.session.log.info("Clipboard is empty");
                return;
            }
            const vector3_half = new lib.Vector3Builder(0, 0, 0);
            const clipboardTarget = lib.Vector3Utils.add(location ?? this.session.extensionContext.cursor.getPosition(), vector3_half);
            const transactionManager = this.session.extensionContext.transactionManager;
            transactionManager.openTransaction("Paste Preview");
            const writeOptions = {
                normalizedOrigin: calculateClipboardNormalizedAnchorValue(this._clipboardItem, this._structureHumanReadableOrigin.value),
                offset: this._structureOffset.value,
                mirror: this._getMirrorAxisFromBooleans(this._structureMirrorX.value, this._structureMirrorZ.value),
                rotation: this._getRotationFromOrderedIndex(this._structureRotationIndex.value)
            };
            try {
                const wroteOK = this._clipboardItem.writeToWorld(clipboardTarget, writeOptions);
                if (!wroteOK) {
                    throw new Error("unknown error");
                }
                transactionManager.commitOpenTransaction();
            } catch (e) {
                transactionManager.discardOpenTransaction();
                this.session.log.error(`Failed to write clipboard to world (${(0, server_editor_namespaceObject.stringFromException)(e)})`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
        }
        pasteClipboardSilhouette(location) {
            if (!this.isActive) {
                throw new Error("Control must be active");
            }
            if (this._clipboardItem.isEmpty) {
                this.session.log.info("Clipboard is empty");
                return;
            }
            const vector3_half = new lib.Vector3Builder(.5, .5, .5);
            const cursorTarget = lib.Vector3Utils.add(location ?? this.session.extensionContext.cursor.getPosition(), vector3_half);
            const writeOptions = {
                normalizedOrigin: calculateClipboardNormalizedAnchorValue(this._clipboardItem, this._structureHumanReadableOrigin.value),
                offset: this._structureOffset.value,
                mirror: this._getMirrorAxisFromBooleans(this._structureMirrorX.value, this._structureMirrorZ.value),
                rotation: this._getRotationFromOrderedIndex(this._structureRotationIndex.value)
            };
            const writeVolume = this._clipboardItem.getPredictedWriteVolume(cursorTarget, writeOptions);
            const fillBlockType = server_namespaceObject.BlockTypes.get(lib_vanilla_MinecraftBlockTypes.Air);
            this._fillVolume(this.session.extensionContext.player.dimension, writeVolume, fillBlockType).catch((e => this.session.log.error(e.message, {
                channelMask: server_editor_namespaceObject.LogChannel.All
            })));
        }
        _createWidgetGroup() {
            const widgetGroup = this.session.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.None,
                visible: false
            });
            return widgetGroup;
        }
        _createClipboardWidget() {
            this._destroyClipboardWidget();
            const options = {
                bindPositionToBlockCursor: this._bindToCursor,
                collisionOffset: new lib.Vector3Builder(0, 0, 0),
                collisionRadius: 0,
                selectable: false,
                visible: true,
                widgetName: "Clipboard Preview Control"
            };
            this._widget = this._widgetGroup.createWidget(new lib.Vector3Builder(0, 0, 0), options);
            const clipboardOptions = {
                mirror: this._getMirrorAxisFromBooleans(this._structureMirrorX.value, this._structureMirrorZ.value),
                rotation: this._getRotationFromOrderedIndex(this._structureRotationIndex.value),
                clipboardOffset: this._structureOffset.value,
                normalizedOrigin: calculateClipboardNormalizedAnchorValue(this._clipboardItem, this._structureHumanReadableOrigin.value),
                showOutline: true,
                visible: true
            };
            const clipboardItem = this.session.extensionContext.clipboardManager.clipboard;
            this._widgetComponent = this._widget.addClipboardComponent("clipboard-preview-shared-control", clipboardItem, clipboardOptions);
        }
        _destroyClipboardWidget() {
            this._widgetComponent?.delete();
            this._widget?.delete();
            this._widget = undefined;
            this._widgetComponent = undefined;
        }
    }
    ClipboardPreviewControl._rotationOrder = [ server_namespaceObject.StructureRotation.None, server_namespaceObject.StructureRotation.Rotate90, server_namespaceObject.StructureRotation.Rotate180, server_namespaceObject.StructureRotation.Rotate270 ];
    ClipboardPreviewControl.MIN_ORIGIN = {
        x: 0,
        y: 0,
        z: 0
    };
    ClipboardPreviewControl.MIN_OFFSET = {
        x: -100,
        y: -100,
        z: -100
    };
    ClipboardPreviewControl.MAX_OFFSET = {
        x: 100,
        y: 100,
        z: 100
    };
    var PastePreviewTelemetry;
    (function(PastePreviewTelemetry) {
        PastePreviewTelemetry["PastePreviewActivated"] = "PastePreviewActivated";
        PastePreviewTelemetry["PastePreviewIntoWorld"] = "PastePreviewIntoWorld";
        PastePreviewTelemetry["ClearPastePreview"] = "ClearPastePreview";
    })(PastePreviewTelemetry || (PastePreviewTelemetry = {}));
    class PastePreviewBehavior {
        get session() {
            return this._session;
        }
        get tool() {
            return this._tool;
        }
        get rootPane() {
            return this._rootPane;
        }
        constructor(_session, _fallbackToolId) {
            this._session = _session;
            this._fallbackToolId = _fallbackToolId;
            this._isActive = false;
            this.telemetryManager = new TelemetryManager(this._session.extensionContext.player, TelemetrySource.PastePreview);
            this._cursorProperties = {
                outlineColor: {
                    red: 0,
                    green: .5,
                    blue: .5,
                    alpha: .2
                },
                controlMode: server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse,
                targetMode: server_editor_namespaceObject.CursorTargetMode.Face,
                visible: true
            };
            this._activationAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (!this._clipboardPreviewControl.isActive) {
                        this.telemetryManager.fireTelemetryEvent(PastePreviewTelemetry.PastePreviewActivated);
                        this._session.toolRail.setSelectedToolId(this._tool.id);
                        this._clipboardPreviewControl.activateControl();
                        this._clipboardPreviewControl.activateVisualization();
                    }
                }
            });
            this._tool = this._session.toolRail.addTool("editor:modalTool:pastePreview", {
                title: "resourcePack.editor.pastepreview.tool.title",
                icon: "pack://textures/editor/Paste.png?filtering=point",
                tooltip: {
                    description: "resourcePack.editor.pastepreview.tool.tip",
                    image: "pack://textures/editor/PastePreview.gif"
                },
                action: this._activationAction
            });
            this._rootPane = this.session.createPropertyPane({
                title: "resourcePack.editor.pastePreview.tool.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.pastepreview.tool.tip", {
                        link: "https://aka.ms/BedrockEditorPastePreview",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this.tool.bindPropertyPane(this.rootPane);
            const bindManualControls = true;
            this._cursorModeControl = new CursorModeControl(this.session, this.tool, this.rootPane, bindManualControls, this._cursorProperties);
            this._cursorModeControl.initialize();
            this._clipboardPreviewControl = new ClipboardPreviewControl(this.session, this.tool, this.rootPane, this.session.extensionContext.clipboardManager.clipboard);
            this._clipboardPreviewControl.initialize();
            this.tool.onModalToolActivation.subscribe((data => {
                this._isActive = data.isActiveTool;
                if (data.isActiveTool) {
                    this.session.log.debug("NewPastePreview::onModalToolActivation");
                    this._cursorModeControl.activateControl();
                    this._clipboardPreviewControl.activateControl();
                    this._clipboardPreviewControl.activateVisualization();
                } else {
                    this.session.log.debug("NewPastePreview::onModalToolDeactivation");
                    this._onLeave();
                }
            }));
            this._registerMouseUpDownAction();
            this._registerKeyboardInputActions();
        }
        _registerKeyboardInputActions() {
            const pasteClipboardIntoWorldAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._clipboardPreviewControl.isActive) {
                        this._clipboardPreviewControl.pastePreviewIntoWorld();
                    }
                }
            });
            this._tool.registerKeyBinding(pasteClipboardIntoWorldAction, {
                key: server_editor_namespaceObject.KeyboardKey.ENTER
            }, {
                uniqueId: `editor:pastePreviewToolKeyBinding:pasteAtCursor.Enter`,
                label: `resourcePack.editor.pastepreview.keyBinding.pasteAtCursor.title`,
                tooltip: `resourcePack.editor.pastepreview.keyBinding.pasteAtCursor.tooltip`
            });
            this._tool.registerKeyBinding(pasteClipboardIntoWorldAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_V,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:pastePreviewToolKeyBinding:pasteAtCursor.Ctrl.V",
                label: `resourcePack.editor.pastepreview.keyBinding.pasteAtCursor.title`,
                tooltip: `resourcePack.editor.pastepreview.keyBinding.pasteAtCursor.tooltip`
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, this._activationAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_V,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:toolModeKeyBinding:pastepreview",
                label: "resourcePack.editor.pastepreview.keyBinding.pastepreview.title",
                tooltip: "resourcePack.editor.pastepreview.keyBinding.pastepreview.tooltip"
            });
            const deactivatePreviewAndFallbackAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.telemetryManager.fireTelemetryEvent(PastePreviewTelemetry.ClearPastePreview);
                    this._clipboardPreviewControl.deactivateVisualization();
                    this._clipboardPreviewControl.deactivateControl();
                    this._activateFallbackTool();
                }
            });
            this._tool.registerKeyBinding(deactivatePreviewAndFallbackAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_D,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: `editor:pastePreviewToolKeyBinding:clearPreview`,
                label: `resourcePack.editor.pastepreview.keyBinding.clearPreview.title`,
                tooltip: `resourcePack.editor.pastepreview.keyBinding.clearPreview.tooltip`
            });
            this._tool.registerKeyBinding(deactivatePreviewAndFallbackAction, {
                key: server_editor_namespaceObject.KeyboardKey.ESCAPE
            });
        }
        _registerMouseUpDownAction() {
            const mouseClickAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (_, mouseProps) => {
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton) {
                        if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown) {
                            if (this._clipboardPreviewControl.isActive) {
                                if (mouseProps.modifiers.ctrl) {
                                    this.telemetryManager.fireTelemetryEvent(PastePreviewTelemetry.PastePreviewIntoWorld, {
                                        mode: "silhouette"
                                    });
                                    this._clipboardPreviewControl.pasteClipboardSilhouette();
                                } else {
                                    this.telemetryManager.fireTelemetryEvent(PastePreviewTelemetry.PastePreviewIntoWorld, {
                                        mode: "quick"
                                    });
                                    this._clipboardPreviewControl.pastePreviewIntoWorld();
                                }
                            }
                        }
                    }
                }
            });
            this._tool.registerMouseButtonBinding(mouseClickAction);
        }
        _activateFallbackTool() {
            this._session.toolRail.setSelectedToolId(this._fallbackToolId);
        }
        _onLeave() {
            if (this._cursorModeControl.isActive) {
                this._cursorModeControl.deactivateControl();
            }
            if (this._clipboardPreviewControl.isActive) {
                this._clipboardPreviewControl.deactivateVisualization();
                this._clipboardPreviewControl.deactivateControl();
            }
        }
        teardown() {
            this._onLeave();
            this._cursorModeControl.shutdown();
            this._clipboardPreviewControl.shutdown();
        }
    }
    PastePreviewBehavior.BEHAVIOR_NAME = "New Paste Preview";
    class CopyPasteBehavior {
        constructor(uiSession, parentMenu) {
            this._session = uiSession;
            const simpleCopyAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: async () => {
                    await this._copySelectionToClipboard();
                }
            });
            const simpleCutAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: async () => {
                    await this._copySelectionToClipboard();
                    await deleteOperation(this._session);
                }
            });
            const simplePasteAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._pasteFromClipboard();
                }
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, simpleCopyAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_C,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:toolModeKeyBinding:copySelection",
                label: "resourcePack.editor.copypaste.keyBinding.copy.title",
                tooltip: "resourcePack.editor.copypaste.keyBinding.copy.tooltip"
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, simpleCutAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_X,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:toolModeKeyBinding:cutSelection",
                label: "resourcePack.editor.copypaste.keyBinding.cut.title",
                tooltip: "resourcePack.editor.copypaste.keyBinding.cut.tooltip"
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, simplePasteAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_V,
                modifier: server_editor_namespaceObject.InputModifier.Shift | server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:toolModeKeyBinding:paste",
                label: "resourcePack.editor.copypaste.keyBinding.paste.title",
                tooltip: "resourcePack.editor.copypaste.keyBinding.paste.tooltip"
            });
            this._copyActionBar = uiSession.actionBar.registerItem("editor:copypaste:copy", simpleCopyAction, {
                label: "resourcePack.editor.copypaste.actionbar.copy.title",
                icon: "copyIcon",
                tooltipTitle: "resourcePack.editor.copypaste.actionbar.copy.tooltip",
                tooltipDescription: "resourcePack.editor.copypaste.actionbar.copy.tooltipDescription",
                enabled: true
            });
            this._cutActionBar = uiSession.actionBar.registerItem("editor:copypaste:cut", simpleCutAction, {
                label: "resourcePack.editor.copypaste.actionbar.cut.title",
                icon: "cutIcon",
                tooltipTitle: "resourcePack.editor.copypaste.actionbar.cut.tooltip",
                tooltipDescription: "resourcePack.editor.copypaste.actionbar.cut.tooltipDescription",
                enabled: true
            });
            parentMenu.addItem({
                label: "resourcePack.editor.copypaste.menu.cut.title",
                uniqueId: "editor:copypaste:menu:cut",
                tooltip: "resourcePack.editor.copypaste.menu.cut.tooltip"
            }, simpleCutAction);
            parentMenu.addItem({
                label: "resourcePack.editor.copypaste.menu.copy.title",
                uniqueId: "editor:copypaste:menu:copy",
                tooltip: "resourcePack.editor.copypaste.menu.copy.tooltip"
            }, simpleCopyAction);
        }
        get session() {
            return this._session;
        }
        async _copySelectionToClipboard() {
            if (!this.session.extensionContext.selectionManager.volume.isEmpty) {
                this.session.extensionContext.clipboardManager.clipboard.clear();
                const selectionVolume = this.session.extensionContext.selectionManager.volume.get();
                await executeTickSafeOperation(this._session.extensionContext, this._session.log, selectionVolume.getBoundingBox(), (() => {
                    this.session.extensionContext.clipboardManager.clipboard.readFromWorld(selectionVolume);
                }));
            } else {
                this.session.log.info("Unable to copy to clipboard: selection is empty");
            }
        }
        _pasteFromClipboard() {
            const clipboardItem = this._session.extensionContext.clipboardManager.clipboard;
            if (clipboardItem.isEmpty) {
                this.session.log.info("Unable to paste to world: clipboard is empty");
                return;
            }
            const vector3_half = new lib.Vector3Builder(.5, .5, .5);
            const clipboardTarget = lib.Vector3Utils.add(this._session.extensionContext.cursor.getPosition(), vector3_half);
            const transactionManager = this._session.extensionContext.transactionManager;
            transactionManager.openTransaction("Simple Paste");
            const writeOptions = {
                normalizedOrigin: new lib.Vector3Builder(0, 0, 0),
                offset: new lib.Vector3Builder(0, 0, 0),
                mirror: server_namespaceObject.StructureMirrorAxis.None,
                rotation: server_namespaceObject.StructureRotation.None
            };
            try {
                const wroteOK = clipboardItem.writeToWorld(clipboardTarget, writeOptions);
                if (!wroteOK) {
                    throw new Error("unknown error");
                }
                transactionManager.commitOpenTransaction();
            } catch (e) {
                transactionManager.discardOpenTransaction();
                this.session.log.error(`Failed to write clipboard to world (${(0, server_editor_namespaceObject.stringFromException)(e)})`);
            }
        }
        teardown() {}
    }
    const SmartFill_PERSISTENCE_GROUP_NAME = "editor:smartfill";
    const SmartFill_PERSISTENCE_GROUPITEM_NAME = "smartfill_settings";
    const ALL_DIRECTIONS = [ direction_Direction.Up, direction_Direction.Down, direction_Direction.Left, direction_Direction.Right, direction_Direction.Forward, direction_Direction.Back ];
    var SmartFillTelemetry;
    (function(SmartFillTelemetry) {
        SmartFillTelemetry["Fill"] = "Fill";
    })(SmartFillTelemetry || (SmartFillTelemetry = {}));
    class SmartFill_PreviewVolume {
        constructor(_session) {
            this._session = _session;
            this._outlineColor = this._session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeFill);
            this._hullColor = this._session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeBorder);
            this._highlightOutlineColor = this._session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeOutlineBorder);
            this._highlightHullColor = this._session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeOutlineFill);
            this._persistenceManager = getPersistenceManager(this._session.extensionContext.player);
            const dimensionBounds = this._session.extensionContext.blockUtilities.getDimensionLocationBoundingBox();
            const center = server_namespaceObject.BlockBoundingBoxUtils.getCenter(dimensionBounds);
            this._widgetGroup = this._session.extensionContext.widgetManager.createGroup({
                visible: true
            });
            this._widget = this._widgetGroup.createWidget(center, {
                visible: false,
                selectable: false
            });
            this._widgetVolumeComponent = this._widget.addVolumeOutline("outline", new server_editor_namespaceObject.RelativeVolumeListBlockVolume, {
                outlineColor: this._outlineColor,
                hullColor: this._hullColor,
                highlightOutlineColor: this._highlightOutlineColor,
                highlightHullColor: this._highlightHullColor,
                showOutline: false,
                showHighlightOutline: true,
                visible: true
            });
        }
        teardown() {
            this._widgetVolumeComponent.delete();
            this._widget.delete();
            this._widgetGroup.delete();
        }
        get lastVolume() {
            return this._lastVolume;
        }
        get visible() {
            return this._widget.visible;
        }
        set visible(value) {
            this._widget.visible = value;
        }
        get location() {
            return this._widget.location;
        }
        set location(position) {
            this._widget.location = position;
        }
        set outlineColor(value) {
            this._outlineColor = value;
            this._widgetVolumeComponent.outlineColor = value;
        }
        set hullColor(value) {
            this._hullColor = value;
            this._widgetVolumeComponent.hullColor = value;
        }
        set highlightOutlineColor(value) {
            this._highlightOutlineColor = value;
            this._widgetVolumeComponent.highlightOutlineColor = value;
        }
        set highlightHullColor(value) {
            this._highlightHullColor = value;
            this._widgetVolumeComponent.highlightHullColor = value;
        }
        addVolume(volume) {
            if (!volume.isEmpty) {
                const bounds = volume.getBoundingBox();
                this._widget.location = bounds.min;
            }
            this._lastVolume = volume;
            this._widgetVolumeComponent.setVolume(volume);
        }
        clearVolume() {
            this._widgetVolumeComponent.setVolume(undefined);
            this._lastVolume = undefined;
        }
    }
    class SmartFillToolBehavior {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this.SELECTION_COLOR = {
                red: 0,
                green: .85,
                blue: .95,
                alpha: 1
            };
            this.visualizationPosition = lib.VECTOR3_ZERO;
            this.visualizationInProgress = false;
            this.initSelectionInProcessing = false;
            this.selectionMin = lib.VECTOR3_ZERO;
            this.selectionMax = lib.VECTOR3_ZERO;
            this.REGION_HALF_EXTENT = 128;
            uiSession.log.debug(`Initializing ${SmartFillToolBehavior.BEHAVIOR_NAME}`);
            this._persistenceManager = getPersistenceManager(uiSession.extensionContext.player);
            this.telemetryManager = new TelemetryManager(uiSession.extensionContext.player, TelemetrySource.SmartFill);
            this.cursorProperties = uiSession.extensionContext.cursor.getProperties();
            if (this.cursorProperties.fillColor) {
                delete this.cursorProperties.fillColor;
            }
            this.cursorProperties.outlineColor = this.SELECTION_COLOR;
            this.cursorProperties.controlMode = server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse;
            this.cursorProperties.targetMode = server_editor_namespaceObject.CursorTargetMode.Block;
            this.cursorProperties.visible = true;
            this.currentAreaLimit = (0, server_editor_namespaceObject.makeObservable)(SmartFillToolBehavior.AREA_LIMIT);
            this.limitFillToSelection = (0, server_editor_namespaceObject.makeObservable)(false);
            this.globalSelectionSet = new Vector3Pool;
            this._loadSettings();
            this.tool = this.addTool(uiSession);
            this.pane = this.buildPane(uiSession, this.tool);
            this.tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    uiSession.extensionContext.cursor.pushPropertiesById(this.cursorProperties, SmartFillToolBehavior.MODAL_TOOL_ID);
                    if (this.limitFillToSelection.value) {
                        this._initSelectionSet();
                    }
                    this._setupVisualization();
                } else {
                    uiSession.extensionContext.cursor.popPropertiesById(SmartFillToolBehavior.MODAL_TOOL_ID);
                    this._destroyVisualization();
                    this._clearSelectionSet();
                }
            }));
            this.selectionChangeEventSubscriptionHandle = uiSession.extensionContext.afterEvents.SelectionChange.subscribe((() => {
                this.visualization?.clearVolume();
                if (this.limitFillToSelection.value) {
                    this._clearSelectionSet();
                    this._initSelectionSet();
                }
            }));
        }
        _removeVisualizationTick() {
            if (this.visualizationTickHandle) {
                server_namespaceObject.system.clearRun(this.visualizationTickHandle);
            }
            if (this._fillRegion) {
                this._fillRegion.dispose();
                this._fillRegion = undefined;
            }
            this.visualizationTickHandle = undefined;
            this.visualizationInProgress = false;
        }
        _setupVisualizationTick() {
            const onTick = () => {
                if (this.visualizationInProgress) {
                    return;
                }
                const cursor = this.uiSession.extensionContext.cursor;
                const position = cursor.getPosition();
                if (!lib.Vector3Utils.equals(position, this.visualizationPosition)) {
                    this.visualizationPosition = position;
                    if (this.visualization) {
                        if (!this._fillRegion) {
                            this._fillRegion = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(this.uiSession.extensionContext.player).regionManager.leaseRegion({
                                extentX: {
                                    min: position.x - this.REGION_HALF_EXTENT,
                                    max: position.x + this.REGION_HALF_EXTENT
                                },
                                extentZ: {
                                    min: position.z - this.REGION_HALF_EXTENT,
                                    max: position.z + this.REGION_HALF_EXTENT
                                }
                            });
                        } else {
                            this._fillRegion.requestMove(position).catch((error => {
                                this.uiSession.log.warning(`${stringFromException(error)}`);
                            }));
                        }
                        this.visualizationInProgress = true;
                        this._fillRegion.waitUntilAvailable().then((() => {
                            if (!this._fillRegion?.isAirBlock(position)) {
                                this.generateFillVolumeSelection(this.uiSession, position).then((volume => {
                                    if (this.visualization && !(this.visualization.lastVolume && this.visualization.lastVolume.isInside(position))) {
                                        this.visualization.clearVolume();
                                        if (volume) {
                                            this.visualization.addVolume(volume);
                                        }
                                    }
                                })).catch((e => {
                                    this.uiSession.log.error(stringFromException(e));
                                })).finally((() => {
                                    this.visualizationInProgress = false;
                                }));
                            } else {
                                this.visualizationInProgress = false;
                            }
                        })).catch((() => {
                            this.visualizationInProgress = false;
                        }));
                    }
                }
            };
            this.visualizationTickHandle = server_namespaceObject.system.runInterval(onTick, 5);
        }
        _destroyVisualization() {
            if (this.visualization) {
                this.visualization.clearVolume();
                this.visualization.teardown();
                this.visualization = undefined;
            }
            this._removeVisualizationTick();
            if (this.visualizationJobHandle !== undefined) {
                server_namespaceObject.system.clearJob(this.visualizationJobHandle);
                this.visualizationJobHandle = undefined;
            }
        }
        _setupVisualization() {
            this.visualizationPosition = lib.VECTOR3_ZERO;
            this.visualization = new SmartFill_PreviewVolume(this.uiSession);
            this.visualization.visible = true;
            this._setupVisualizationTick();
        }
        teardown() {
            this.uiSession.log.debug(`Shutting down ${SmartFillToolBehavior.BEHAVIOR_NAME}`);
            this._destroyVisualization();
            if (this.selectionChangeEventSubscriptionHandle) {
                this.uiSession.extensionContext.afterEvents.SelectionChange.unsubscribe(this.selectionChangeEventSubscriptionHandle);
                this.selectionChangeEventSubscriptionHandle = undefined;
            }
            this._clearSelectionSet();
        }
        addTool(uiSession) {
            const toolToggleAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    uiSession.toolRail.setSelectedToolId(tool.id);
                }
            });
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, toolToggleAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_M,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editorCore:smartFill:toggleTool",
                label: "resourcePack.editor.toolRail.smartFillTool.keyBinding.toggleTool.title",
                tooltip: "resourcePack.editor.toolRail.smartFillTool.keyBinding.toggleTool.tooltip"
            });
            const tool = uiSession.toolRail.addTool(SmartFillToolBehavior.MODAL_TOOL_ID, {
                title: "resourcePack.editor.toolRail.smartFillTool.title",
                icon: "pack://textures/editor/Fill.png?filtering=point",
                tooltip: "resourcePack.editor.toolRail.smartFillTool.tooltip",
                action: toolToggleAction
            });
            const executeAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: async (mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton && mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonUp && this.tool.isActive) {
                        const fillVolume = this.visualization?.lastVolume;
                        if (fillVolume === undefined) {
                            return;
                        }
                        this._destroyVisualization();
                        await this.applyFillToSelection(uiSession, fillVolume, SmartFillToolBehavior.WRITE_OPERATION_NAME, SmartFillToolBehavior.BEHAVIOR_NAME);
                        this._setupVisualization();
                    }
                }
            });
            tool.registerMouseButtonBinding(executeAction);
            return tool;
        }
        async generateFillVolumeSelection(uiSession, targetLocation) {
            const selection = await this.buildFloodSelectionFromLocation(uiSession, targetLocation, ALL_DIRECTIONS, this.currentAreaLimit.value);
            return selection;
        }
        _clearSelectionSet() {
            if (this.initialSelectionJobHandle !== undefined) {
                server_namespaceObject.system.clearJob(this.initialSelectionJobHandle);
                this.initialSelectionJobHandle = undefined;
            }
            this.initSelectionInProcessing = false;
            this.globalSelectionSet.reset();
        }
        _initSelectionSet() {
            const onSelectionInitial = () => {
                if (!this.uiSession.extensionContext.selectionManager.volume.isEmpty) {
                    this.initSelectionInProcessing = true;
                    const selectionBounds = this.uiSession.extensionContext.selectionManager.volume.getBoundingBox();
                    this.selectionMin = selectionBounds.min;
                    this.selectionMax = selectionBounds.max;
                    this.globalSelectionSet.init(selectionBounds.min, selectionBounds.max);
                    const selectionVolume = new server_namespaceObject.BlockVolume(selectionBounds.min, selectionBounds.max);
                    const iterator = selectionVolume.getBlockLocationIterator();
                    for (const position of iterator) {
                        this.globalSelectionSet.add(position);
                    }
                    this.initSelectionInProcessing = false;
                }
            };
            if (!this.initialSelectionJobHandle && !this.initSelectionInProcessing) {
                this.initialSelectionJobHandle = server_namespaceObject.system.runTimeout(onSelectionInitial, 2);
            }
        }
        async buildFloodSelectionFromLocation(uiSession, targetLocation, allowedDirections, areaLimit) {
            const consideredLocations = new Vector3Set;
            const addedLocations = new Vector3Set;
            const stack = [ targetLocation ];
            const outputVolume = new server_editor_namespaceObject.RelativeVolumeListBlockVolume;
            const BOX_SIZE = areaLimit;
            const min = lib.Vector3Utils.subtract(targetLocation, {
                x: BOX_SIZE,
                y: BOX_SIZE,
                z: BOX_SIZE
            });
            const max = lib.Vector3Utils.add(targetLocation, {
                x: BOX_SIZE,
                y: BOX_SIZE,
                z: BOX_SIZE
            });
            const bounds = server_namespaceObject.BlockBoundingBoxUtils.createValid(min, max);
            let targetBlock = undefined;
            try {
                targetBlock = this._fillRegion?.getBlockTypeId(targetLocation);
            } catch {}
            if (targetBlock === undefined) {
                uiSession.log.warning("Starting block was undefined, this likely means the block was too far away");
                return outputVolume;
            }
            const operation = currentLocation => {
                if (this.limitFillToSelection.value && !this.uiSession.extensionContext.selectionManager.volume.isEmpty) {
                    if (this.initSelectionInProcessing) {
                        return;
                    }
                    const selectionBounds = this.uiSession.extensionContext.selectionManager.volume.getBoundingBox();
                    if (!lib.Vector3Utils.equals(this.selectionMin, selectionBounds.min) || !lib.Vector3Utils.equals(this.selectionMax, selectionBounds.max)) {
                        this._clearSelectionSet();
                        this._initSelectionSet();
                    }
                }
                if (!server_namespaceObject.BlockBoundingBoxUtils.isInside(bounds, currentLocation) || this._fillRegion?.getBlockTypeId(currentLocation) !== targetBlock || this.limitFillToSelection.value && !this.globalSelectionSet.contains(currentLocation)) {
                    return;
                }
                outputVolume.add(currentLocation);
                addedLocations.add(currentLocation);
                for (const direction of ALL_DIRECTIONS) {
                    if (allowedDirections.length > 0 && !allowedDirections.includes(direction)) {
                        continue;
                    }
                    const directionVector = getDirectionVector(direction);
                    const newLocation = lib.Vector3Utils.add(currentLocation, directionVector);
                    if (!consideredLocations.contains(newLocation)) {
                        stack.push(newLocation);
                        consideredLocations.add(newLocation);
                    }
                }
            };
            await new Promise(((resolve, reject) => {
                if (this.visualizationJobHandle !== undefined) {
                    server_namespaceObject.system.clearJob(this.visualizationJobHandle);
                }
                this.visualizationJobHandle = server_namespaceObject.system.runJob(workerGenerator(resolve, reject, stack, operation));
            }));
            return outputVolume;
        }
        async applyFillToSelection(uiSession, selection, operationName, toolName) {
            const onError = e => {
                uiSession.log.error(`${toolName} operation failed with error: ${e.message}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            };
            if (selection.isEmpty) {
                return;
            }
            const bounds = selection.getBoundingBox();
            this.telemetryManager.fireTelemetryEvent(SmartFillTelemetry.Fill, {
                selectionSize: lib.Vector3Utils.subtract(bounds.max, bounds.min)
            });
            await executeFunctionWithTransactionAndTicking(uiSession.extensionContext, uiSession.log, selection, operationName, (() => {
                uiSession.extensionContext.blockUtilities.fillVolume(selection);
            })).catch(onError);
        }
        buildPane(uiSession, tool) {
            const pane = uiSession.createPropertyPane({
                title: "resourcePack.editor.toolRail.smartFillTool.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.toolRail.smartFillTool.tooltip", {
                        link: "https://aka.ms/BedrockEditorSmartFill",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            pane.addNumber(this.currentAreaLimit, {
                isInteger: true,
                max: SmartFillToolBehavior.AREA_LIMIT,
                min: 1,
                title: "resourcePack.editor.toolRail.smartFillTool.areaLimit.title",
                tooltip: "resourcePack.editor.toolRail.smartFillTool.areaLimit.tooltip",
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: () => {
                    this._saveSettings();
                }
            });
            pane.addBool(this.limitFillToSelection, {
                title: "resourcePack.editor.toolRail.smartFillTool.limitFillToSelection",
                tooltip: "resourcePack.editor.toolRail.smartFillTool.limitFillToSelectionTooltip",
                onChange: () => {
                    if (this.limitFillToSelection.value) {
                        this._initSelectionSet();
                    } else {
                        this._clearSelectionSet();
                    }
                    this._saveSettings();
                }
            });
            tool.bindPropertyPane(pane);
            return pane;
        }
        _loadSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(SmartFill_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const storeItem = group.fetchItem(SmartFill_PERSISTENCE_GROUPITEM_NAME);
                if (storeItem && storeItem.value) {
                    try {
                        const storedSettings = storeItem.value;
                        this.currentAreaLimit.set(storedSettings.currentAreaLimit);
                        this.limitFillToSelection.set(storedSettings.limitFillToSelection);
                    } catch (error) {
                        this.uiSession.log.error("Fail to load the settings, error: " + stringFromException(error));
                    }
                }
                group.dispose();
            }
        }
        _saveSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(SmartFill_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const settings = {
                    currentAreaLimit: this.currentAreaLimit.value,
                    limitFillToSelection: this.limitFillToSelection.value
                };
                const storeItem = group.getOrCreateItem(SmartFill_PERSISTENCE_GROUPITEM_NAME, settings);
                if (storeItem) {
                    storeItem.commit();
                }
                group.dispose();
                return;
            }
            this.uiSession.log.error("Fail to save settings for SmartFill");
        }
    }
    SmartFillToolBehavior.BEHAVIOR_NAME = "Smart Fill Tool";
    SmartFillToolBehavior.MODAL_TOOL_ID = "editor:modalTool:smartFill";
    SmartFillToolBehavior.READ_OPERATION_NAME = "Smart-Fill-Read";
    SmartFillToolBehavior.WRITE_OPERATION_NAME = "Smart-Fill-Write";
    SmartFillToolBehavior.AREA_LIMIT = 16;
    SmartFillToolBehavior.DEFAULT_FILL_PERCENTAGE = 100;
    const SmartFill_MAX_WORKER_OPERATIONS = 500;
    function* workerGenerator(jobCompleted, jobFailed, stack, operation) {
        try {
            let opCount = 0;
            while (stack.length > 0) {
                const pos = stack.pop();
                if (!pos) {
                    break;
                }
                operation(pos);
                ++opCount;
                if (opCount > SmartFill_MAX_WORKER_OPERATIONS) {
                    opCount = 0;
                    yield;
                }
            }
        } catch (e) {
            jobFailed(e);
        }
        jobCompleted();
    }
    var TerrainMode;
    (function(TerrainMode) {
        TerrainMode[TerrainMode["FlattenMode"] = 1] = "FlattenMode";
        TerrainMode[TerrainMode["SmoothMode"] = 2] = "SmoothMode";
        TerrainMode[TerrainMode["RoughenMode"] = 3] = "RoughenMode";
        TerrainMode[TerrainMode["ElevationMode"] = 4] = "ElevationMode";
    })(TerrainMode || (TerrainMode = {}));
    var TerrainTelemetry;
    (function(TerrainTelemetry) {
        TerrainTelemetry["StartPaining"] = "StartPaining";
        TerrainTelemetry["EndPainting"] = "EndPainting";
    })(TerrainTelemetry || (TerrainTelemetry = {}));
    const Terrain_PERSISTENCE_GROUP_NAME = "editor:terrain";
    const Terrain_PERSISTENCE_GROUPITEM_NAME = "terrain_settings";
    class TerrainBehavior {
        constructor(session) {
            this.BEHAVIOR_NAME = "Terrain";
            this._flattenDefaults = {
                INTENSITY_MIN: 1,
                INTENSITY_MAX: 100,
                SMOOTHING_MIN: 0,
                SMOOTHING_MAX: 100,
                DEFAULT_MODE: server_editor_namespaceObject.FlattenMode.Both,
                DEFAULT_INTENSITY: 100,
                DEFAULT_SMOOTHING: 0,
                DEFAULT_FLOOR_OVERRIDE: false,
                BRUSH_SHAPES: [ new server_editor_namespaceObject.CylinderBrushShape({
                    uniform: true,
                    height: 12,
                    radius: 10,
                    hideRotation: true
                }) ],
                SETTINGS_MAP: {
                    [server_editor_namespaceObject.FlattenMode.Both]: {
                        flattenMode: server_editor_namespaceObject.FlattenMode.Both,
                        brushOffset: {
                            x: 0,
                            y: -12 / 2,
                            z: 0
                        },
                        targetMode: server_editor_namespaceObject.CursorTargetMode.Block
                    },
                    [server_editor_namespaceObject.FlattenMode.Down]: {
                        flattenMode: server_editor_namespaceObject.FlattenMode.Down,
                        brushOffset: {
                            x: 0,
                            y: 1,
                            z: 0
                        },
                        targetMode: server_editor_namespaceObject.CursorTargetMode.Block
                    },
                    [server_editor_namespaceObject.FlattenMode.Up]: {
                        flattenMode: server_editor_namespaceObject.FlattenMode.Up,
                        brushOffset: {
                            x: 0,
                            y: -12,
                            z: 0
                        },
                        targetMode: server_editor_namespaceObject.CursorTargetMode.Block
                    }
                }
            };
            this._smoothRoughDefaults = {
                INTENSITY_MIN: 0,
                INTENSITY_MAX: 9,
                DEFAULT_INTENSITY: 9,
                BRUSH_SHAPES: [ new server_editor_namespaceObject.EllipsoidBrushShape({
                    uniform: true,
                    radius: 8
                }), new server_editor_namespaceObject.CuboidBrushShape, new server_editor_namespaceObject.CylinderBrushShape ]
            };
            this._elevationDefaults = {
                INTENSITY_MIN: 1,
                INTENSITY_MAX: 100,
                FALLOFF_MIN: 1,
                FALLOFF_MAX: 20,
                SAMPLE_LAYERS_MIN: 1,
                SAMPLE_LAYERS_MAX: 16,
                BRUSH_RADIUS_MIN: 1,
                BRUSH_RADIUS_MAX: 20,
                DEFAULT_MODE: server_editor_namespaceObject.BrushElevationMode.Raise,
                DEFAULT_INTENSITY: 25,
                DEFAULT_FALLOFF: 1,
                DEFAULT_SAMPLE_LAYERS: 2,
                DEFAULT_BRUSH_RADIUS: 12,
                BRUSH_SHAPES: [ new server_editor_namespaceObject.CylinderBrushShape({
                    uniform: true,
                    height: 1,
                    radius: 12,
                    hideRotation: true
                }) ],
                VISUALIZER_INSTANCE_RADIUS_INCREMENT: .001,
                BASE_RADIUS_ADJUSTMENT: .5,
                NUM_VISUALIZER_INSTANCES: 20,
                DISC_COLOR: {
                    red: 1,
                    green: 0,
                    blue: 0,
                    alpha: .3
                },
                FALLOFF_DISC_COLOR: {
                    red: 1,
                    green: .65,
                    blue: 0,
                    alpha: .3
                },
                VISUALIZER_INSTANCE_BASE_NAME: "elevation-render-visualizer-",
                SETTINGS_MAP: {
                    [server_editor_namespaceObject.BrushElevationMode.Raise]: {
                        elevationMode: server_editor_namespaceObject.BrushElevationMode.Raise,
                        targetMode: server_editor_namespaceObject.CursorTargetMode.Block
                    },
                    [server_editor_namespaceObject.BrushElevationMode.Lower]: {
                        elevationMode: server_editor_namespaceObject.BrushElevationMode.Lower,
                        targetMode: server_editor_namespaceObject.CursorTargetMode.Block
                    }
                }
            };
            this._terrainDefaults = {
                DEFAULT_MODE: TerrainMode.FlattenMode,
                DEFAULT_CURSOR_PROPERTIES: {
                    outlineColor: {
                        red: 0,
                        green: .5,
                        blue: .5,
                        alpha: .2
                    },
                    controlMode: server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse,
                    targetMode: server_editor_namespaceObject.CursorTargetMode.Block,
                    visible: true
                },
                DEFAULT_BRUSH_OFFSET: {
                    x: 0,
                    y: 0,
                    z: 0
                },
                MODE_ROTATION_MAP: {
                    [TerrainMode.FlattenMode]: TerrainMode.ElevationMode,
                    [TerrainMode.ElevationMode]: TerrainMode.SmoothMode,
                    [TerrainMode.SmoothMode]: TerrainMode.RoughenMode,
                    [TerrainMode.RoughenMode]: TerrainMode.FlattenMode
                }
            };
            this.TERRAIN_SETTINGS_MAP = {
                [TerrainMode.FlattenMode]: {
                    terrainMode: TerrainMode.FlattenMode,
                    cursorProperties: this._terrainDefaults.DEFAULT_CURSOR_PROPERTIES,
                    brushOffset: this._terrainDefaults.DEFAULT_BRUSH_OFFSET,
                    brushShapes: this._flattenDefaults.BRUSH_SHAPES,
                    paintMode: server_editor_namespaceObject.PaintMode.Flatten
                },
                [TerrainMode.SmoothMode]: {
                    terrainMode: TerrainMode.SmoothMode,
                    cursorProperties: this._terrainDefaults.DEFAULT_CURSOR_PROPERTIES,
                    brushOffset: this._terrainDefaults.DEFAULT_BRUSH_OFFSET,
                    brushShapes: this._smoothRoughDefaults.BRUSH_SHAPES,
                    paintMode: server_editor_namespaceObject.PaintMode.Smooth
                },
                [TerrainMode.RoughenMode]: {
                    terrainMode: TerrainMode.RoughenMode,
                    cursorProperties: this._terrainDefaults.DEFAULT_CURSOR_PROPERTIES,
                    brushOffset: this._terrainDefaults.DEFAULT_BRUSH_OFFSET,
                    brushShapes: this._smoothRoughDefaults.BRUSH_SHAPES,
                    paintMode: server_editor_namespaceObject.PaintMode.Roughen
                },
                [TerrainMode.ElevationMode]: {
                    terrainMode: TerrainMode.ElevationMode,
                    cursorProperties: this._terrainDefaults.DEFAULT_CURSOR_PROPERTIES,
                    brushOffset: this._terrainDefaults.DEFAULT_BRUSH_OFFSET,
                    brushShapes: this._elevationDefaults.BRUSH_SHAPES,
                    paintMode: server_editor_namespaceObject.PaintMode.Elevation
                }
            };
            this._terrainMode = (0, server_editor_namespaceObject.makeObservable)(this._terrainDefaults.DEFAULT_MODE);
            this._flattenMode = (0, server_editor_namespaceObject.makeObservable)(this._flattenDefaults.DEFAULT_MODE);
            this._flattenIntensity = (0, server_editor_namespaceObject.makeObservable)(this._flattenDefaults.DEFAULT_INTENSITY);
            this._flattenSmoothing = (0, server_editor_namespaceObject.makeObservable)(this._flattenDefaults.DEFAULT_SMOOTHING);
            this._floorBlockOverride = (0, server_editor_namespaceObject.makeObservable)(this._flattenDefaults.DEFAULT_FLOOR_OVERRIDE);
            this._smoothRoughIntensity = (0, server_editor_namespaceObject.makeObservable)(this._smoothRoughDefaults.DEFAULT_INTENSITY);
            this._elevationMode = (0, server_editor_namespaceObject.makeObservable)(this._elevationDefaults.DEFAULT_MODE);
            this._elevationIntensity = (0, server_editor_namespaceObject.makeObservable)(this._elevationDefaults.DEFAULT_INTENSITY);
            this._elevationFalloff = (0, server_editor_namespaceObject.makeObservable)(this._elevationDefaults.DEFAULT_FALLOFF);
            this._elevationSampleLayers = (0, server_editor_namespaceObject.makeObservable)(this._elevationDefaults.DEFAULT_SAMPLE_LAYERS);
            this._elevationBrushRadius = (0, server_editor_namespaceObject.makeObservable)(this._elevationDefaults.DEFAULT_BRUSH_RADIUS);
            this._flattenProperties = [];
            this._smoothenProperties = [];
            this._roughenProperties = [];
            this._elevationProperties = [];
            this._isPainting = false;
            this._isActive = false;
            this._visualizerInstances = [];
            this._falloffVisualizerInstances = [];
            this._session = session;
            this._telemetryManager = new TelemetryManager(this._session.extensionContext.player, TelemetrySource.Terrain);
            this._persistenceManager = getPersistenceManager(this._session.extensionContext.player);
            this._tool = this._initTool();
            this._toolPane = this._initPane();
            this._loadSettings();
            this._cursorControl = this._initCursorControl(this.TERRAIN_SETTINGS_MAP[this._terrainDefaults.DEFAULT_MODE].cursorProperties);
            this._brushControl = this._initBrushControl(this.TERRAIN_SETTINGS_MAP[this._terrainDefaults.DEFAULT_MODE].paintMode, this.TERRAIN_SETTINGS_MAP[this._terrainDefaults.DEFAULT_MODE].brushShapes);
            this._widgetGroup = this._initVisualizer();
            this._initFalloffVisualizer();
            this._tool.bindPropertyPane(this._toolPane);
            this._registerMousePaintInputs();
            this._brushOffsetBackup = this._session.extensionContext.brushShapeManager.getBrushShapeOffset();
            this._tool.onModalToolActivation.subscribe((data => {
                this._isActive = data.isActiveTool;
                if (this._isActive) {
                    this._backupBrushAndCursor();
                    this._activateControls();
                    this._onTerrainModeChanged();
                } else {
                    this._deactivateControls();
                    this._restoreBrushAndCursor();
                }
            }));
        }
        _initTool() {
            const activationAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._session.toolRail.setSelectedToolId(this._tool.id);
                }
            });
            const tool = this._session.toolRail.addTool("editor:Terrain", {
                title: "resourcePack.editor.toolRail.Terrain.title",
                icon: "pack://textures/editor/Terrain.png?filtering=point",
                tooltip: {
                    description: {
                        id: "resourcePack.editor.toolRail.Terrain.description",
                        props: [ getInputMarkup("editor:terrainToolKeybinding:switch") ]
                    },
                    image: "pack://textures/editor/Terrain.gif"
                },
                action: activationAction
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, activationAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_T,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:toolModeKeyBinding:toggleTerrain",
                label: "resourcePack.editor.toolRail.Terrain.keybinding.toggleTool.title",
                tooltip: "resourcePack.editor.toolRail.Terrain.keybinding.toggleTool.tooltip"
            });
            tool.registerKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const newMode = this._terrainDefaults.MODE_ROTATION_MAP[this._terrainMode.value];
                    if (this._terrainMode.value !== newMode) {
                        this._terrainMode.set(newMode);
                        this._onTerrainModeChanged();
                    }
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_T,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: `editor:terrainToolKeybinding:switch`,
                label: `resourcePack.editor.toolRail.Terrain.keyBinding.switch.title`,
                tooltip: `resourcePack.editor.toolRail.Terrain.keyBinding.switch.tooltip`
            });
            tool.registerKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._switchToFlattenMode(server_editor_namespaceObject.FlattenMode.Both);
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_F,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:terrainToolKeybinding:switchToFlattenBoth`,
                label: `resourcePack.editor.toolRail.Terrain.keybinding.FlattenBoth.switch.title`,
                tooltip: `resourcePack.editor.toolRail.Terrain.keybinding.FlattenBoth.switch.title.tooltip`
            });
            tool.registerKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._switchToFlattenMode(server_editor_namespaceObject.FlattenMode.Down);
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_D,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:terrainToolKeybinding:switchToFlattenDown`,
                label: `resourcePack.editor.toolRail.Terrain.keybinding.FlattenDown.switch.title`,
                tooltip: `resourcePack.editor.toolRail.Terrain.keybinding.FlattenDown.switch.title.tooltip`
            });
            tool.registerKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._switchToFlattenMode(server_editor_namespaceObject.FlattenMode.Up);
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_U,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:terrainToolKeybinding:switchToFlattenUp`,
                label: `resourcePack.editor.toolRail.Terrain.keybinding.FlattenUp.switch.title`,
                tooltip: `resourcePack.editor.toolRail.Terrain.keybinding.FlattenUp.switch.title.tooltip`
            });
            tool.registerKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._switchToElevationMode(server_editor_namespaceObject.BrushElevationMode.Raise);
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_R,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:terrainToolKeybinding:switchToRaise`,
                label: `resourcePack.editor.toolRail.Terrain.keybinding.Raise.switch.title`,
                tooltip: `resourcePack.editor.toolRail.Terrain.keybinding.Raise.switch.title.tooltip`
            });
            tool.registerKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._switchToElevationMode(server_editor_namespaceObject.BrushElevationMode.Lower);
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_L,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: `editor:terrainToolKeybinding:switchToLower`,
                label: `resourcePack.editor.toolRail.Terrain.keybinding.Lower.switch.title`,
                tooltip: `resourcePack.editor.toolRail.Terrain.keybinding.Lower.switch.title.tooltip`
            });
            return tool;
        }
        _initPane() {
            const toolPane = this._session.createPropertyPane({
                title: "resourcePack.editor.toolRail.Terrain.title",
                infoTooltip: {
                    description: [ {
                        id: "resourcePack.editor.toolRail.Terrain.description",
                        props: [ getInputMarkup("editor:terrainToolKeybinding:switch") ]
                    }, {
                        link: "https://aka.ms/BedrockEditorSmoothRoughen",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            toolPane.beginConstruct();
            toolPane.addToggleGroup(this._terrainMode, {
                title: "resourcePack.editor.toolRail.Terrain.Mode.title",
                tooltip: "resourcePack.editor.toolRail.Terrain.Mode.tooltip",
                hiddenLabel: false,
                entries: [ {
                    value: TerrainMode.FlattenMode,
                    icon: "pack://textures/editor/Terrain-Flatten.png?filtering=point",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.toolRail.Terrain.Flatten.mode.title",
                            props: [ getInputMarkup("editor:terrainToolKeybinding:switch") ]
                        },
                        description: {
                            id: "resourcePack.editor.toolRail.Terrain.Flatten.tooltip",
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:terrainToolKeybinding:switch") ]
                        }
                    }
                }, {
                    value: TerrainMode.ElevationMode,
                    icon: "pack://textures/editor/Terrain-Elevation.png?filtering=point",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.toolRail.Terrain.Elevation.mode.title",
                            props: [ getInputMarkup("editor:terrainToolKeybinding:switch") ]
                        },
                        description: {
                            id: "resourcePack.editor.toolRail.Terrain.Elevation.tooltip",
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:terrainToolKeybinding:switch") ]
                        }
                    }
                }, {
                    value: TerrainMode.SmoothMode,
                    icon: "pack://textures/editor/Terrain-Smooth.png?filtering=point",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.toolRail.Terrain.Smooth.mode.title",
                            props: [ getInputMarkup("editor:terrainToolKeybinding:switch") ]
                        },
                        description: {
                            id: "resourcePack.editor.toolRail.Terrain.Smooth.tooltip",
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:terrainToolKeybinding:switch") ]
                        }
                    }
                }, {
                    value: TerrainMode.RoughenMode,
                    icon: "pack://textures/editor/Terrain-Roughen.png?filtering=point",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.toolRail.Terrain.Roughen.mode.title",
                            props: [ getInputMarkup("editor:terrainToolKeybinding:switch") ]
                        },
                        description: {
                            id: "resourcePack.editor.toolRail.Terrain.Roughen.tooltip",
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:terrainToolKeybinding:switch") ]
                        }
                    }
                } ],
                onChange: () => {
                    this._onTerrainModeChanged();
                }
            });
            this._flattenProperties.push(toolPane.addToggleGroup(this._flattenMode, {
                title: "resourcePack.editor.toolRail.Terrain.Mode.SubMode.Flatten.title",
                tooltip: "resourcePack.editor.toolRail.Terrain.Mode.SubMode.Flatten.tooltip",
                hiddenLabel: false,
                entries: [ {
                    value: server_editor_namespaceObject.FlattenMode.Both,
                    label: {
                        id: "resourcePack.editor.toolRail.Terrain.FlattenBoth.mode.title",
                        props: [ getInputMarkup("editor:terrainToolKeybinding:switchToFlattenBoth") ]
                    },
                    icon: "pack://textures/editor/Terrain-Flatten-Both.png?filtering=point",
                    tooltip: {
                        id: "resourcePack.editor.toolRail.Terrain.FlattenBoth.tooltip",
                        props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:terrainToolKeybinding:switchToFlattenBoth") ]
                    }
                }, {
                    value: server_editor_namespaceObject.FlattenMode.Down,
                    label: {
                        id: "resourcePack.editor.toolRail.Terrain.FlattenDown.mode.title",
                        props: [ getInputMarkup("editor:terrainToolKeybinding:switchToFlattenDown") ]
                    },
                    icon: "pack://textures/editor/Terrain-Flatten-Down.png?filtering=point",
                    tooltip: {
                        id: "resourcePack.editor.toolRail.Terrain.FlattenDown.tooltip",
                        props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:terrainToolKeybinding:switchToFlattenDown") ]
                    }
                }, {
                    value: server_editor_namespaceObject.FlattenMode.Up,
                    label: {
                        id: "resourcePack.editor.toolRail.Terrain.FlattenUp.mode.title",
                        props: [ getInputMarkup("editor:terrainToolKeybinding:switchToFlattenUp") ]
                    },
                    icon: "pack://textures/editor/Terrain-Flatten-Up.png?filtering=point",
                    tooltip: {
                        id: "resourcePack.editor.toolRail.Terrain.FlattenUp.tooltip",
                        props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:terrainToolKeybinding:switchToFlattenUp") ]
                    }
                } ],
                onChange: () => {
                    this._onFlattenModeChanged();
                }
            }));
            this._flattenProperties.push(toolPane.addNumber(this._flattenIntensity, {
                isInteger: true,
                title: "resourcePack.editor.toolRail.Terrain.FlattenIntensity",
                tooltip: "resourcePack.editor.toolRail.Terrain.FlattenIntensity.tooltip",
                min: this._flattenDefaults.INTENSITY_MIN,
                max: this._flattenDefaults.INTENSITY_MAX,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    this._flattenIntensity.set(newValue);
                    this._session.extensionContext.brushShapeManager.setTerrainStrength(newValue);
                    this._saveSettings();
                }
            }));
            this._flattenProperties.push(toolPane.addNumber(this._flattenSmoothing, {
                isInteger: true,
                title: "resourcePack.editor.toolRail.Terrain.FlattenSmoothing",
                tooltip: "resourcePack.editor.toolRail.Terrain.FlattenSmoothing.tooltip",
                min: this._flattenDefaults.SMOOTHING_MIN,
                max: this._flattenDefaults.SMOOTHING_MAX,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    this._flattenSmoothing.set(newValue);
                    this._session.extensionContext.brushShapeManager.setFlattenSmoothing(newValue);
                    this._saveSettings();
                }
            }));
            this._flattenProperties.push(toolPane.addBool(this._floorBlockOverride, {
                title: "resourcePack.editor.toolRail.Terrain.FloorBlockOverride",
                tooltip: "resourcePack.editor.toolRail.Terrain.FloorBlockOverride.tooltip",
                variant: server_editor_namespaceObject.BoolPropertyItemVariant.Checkbox,
                onChange: newValue => {
                    this._floorBlockOverride.set(newValue);
                    this._session.extensionContext.brushShapeManager.setFloorBlockOverride(newValue);
                    this._saveSettings();
                }
            }));
            this._smoothenProperties.push(toolPane.addNumber(this._smoothRoughIntensity, {
                isInteger: true,
                title: "resourcePack.editor.toolRail.Terrain.SmoothStrength",
                tooltip: "resourcePack.editor.toolRail.Terrain.SmoothStrength.tooltip",
                min: this._smoothRoughDefaults.INTENSITY_MIN,
                max: this._smoothRoughDefaults.INTENSITY_MAX,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    this._smoothRoughIntensity.set(newValue);
                    this._session.extensionContext.brushShapeManager.setTerrainStrength(newValue);
                    this._saveSettings();
                }
            }));
            this._roughenProperties.push(toolPane.addNumber(this._smoothRoughIntensity, {
                isInteger: true,
                title: "resourcePack.editor.toolRail.Terrain.RoughenStrength",
                tooltip: "resourcePack.editor.toolRail.Terrain.RoughenStrength.tooltip",
                min: this._smoothRoughDefaults.INTENSITY_MIN,
                max: this._smoothRoughDefaults.INTENSITY_MAX,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    this._smoothRoughIntensity.set(newValue);
                    this._session.extensionContext.brushShapeManager.setTerrainStrength(newValue);
                }
            }));
            this._elevationProperties.push(toolPane.addToggleGroup(this._elevationMode, {
                title: "resourcePack.editor.toolRail.Terrain.Mode.SubMode.Elevation.title",
                tooltip: "resourcePack.editor.toolRail.Terrain.Mode.SubMode.Elevation.tooltip",
                hiddenLabel: false,
                entries: [ {
                    value: server_editor_namespaceObject.BrushElevationMode.Raise,
                    label: {
                        id: "resourcePack.editor.toolRail.Terrain.Raise.mode.title",
                        props: [ getInputMarkup("editor:terrainToolKeybinding:switchToRaise") ]
                    },
                    icon: "pack://textures/editor/Terrain-Elevation-Raise.png?filtering=point",
                    tooltip: {
                        id: "resourcePack.editor.toolRail.Terrain.Raise.tooltip",
                        props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:terrainToolKeybinding:switchToRaise") ]
                    }
                }, {
                    value: server_editor_namespaceObject.BrushElevationMode.Lower,
                    label: {
                        id: "resourcePack.editor.toolRail.Terrain.Lower.mode.title",
                        props: [ getInputMarkup("editor:terrainToolKeybinding:switchToLower") ]
                    },
                    icon: "pack://textures/editor/Terrain-Elevation-Lower.png?filtering=point",
                    tooltip: {
                        id: "resourcePack.editor.toolRail.Terrain.Lower.tooltip",
                        props: [ newLineMarkup + newLineMarkup, getInputMarkup("editor:terrainToolKeybinding:switchToLower") ]
                    }
                } ],
                onChange: () => {
                    this._onElevationModeChanged();
                }
            }));
            this._elevationProperties.push(toolPane.addNumber(this._elevationIntensity, {
                isInteger: true,
                title: "resourcePack.editor.toolRail.Terrain.ElevationIntensity",
                tooltip: "resourcePack.editor.toolRail.Terrain.ElevationIntensity.tooltip",
                min: this._elevationDefaults.INTENSITY_MIN,
                max: this._elevationDefaults.INTENSITY_MAX,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    this._elevationIntensity.set(newValue);
                    this._session.extensionContext.brushShapeManager.setTerrainStrength(newValue);
                    this._saveSettings();
                }
            }));
            this._elevationProperties.push(toolPane.addNumber(this._elevationFalloff, {
                isInteger: true,
                title: "resourcePack.editor.toolRail.Terrain.ElevationFalloff",
                tooltip: "resourcePack.editor.toolRail.Terrain.ElevationFalloff.tooltip",
                min: this._elevationDefaults.FALLOFF_MIN,
                max: this._elevationDefaults.FALLOFF_MAX,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    let finalValue = newValue;
                    if (newValue > this._elevationBrushRadius.value) {
                        this._elevationFalloff.set(this._elevationBrushRadius.value);
                        this._session.extensionContext.brushShapeManager.setElevationFalloff(this._elevationFalloff.value);
                        finalValue = this._elevationBrushRadius.value;
                        this._session.log.info(`Elevation falloff value cannot exceed the elevation brush radius`);
                    } else {
                        this._elevationFalloff.set(newValue);
                        this._session.extensionContext.brushShapeManager.setElevationFalloff(newValue);
                    }
                    this._falloffVisualizerInstances.forEach((instance => {
                        instance.disc.radius = finalValue + this._elevationDefaults.BASE_RADIUS_ADJUSTMENT + instance.radiusAdjustment;
                        instance.renderComp.setPrimitive(instance.disc);
                    }));
                }
            }));
            this._elevationProperties.push(toolPane.addNumber(this._elevationSampleLayers, {
                isInteger: true,
                title: "resourcePack.editor.toolRail.Terrain.ElevationSampleLayers",
                tooltip: "resourcePack.editor.toolRail.Terrain.ElevationSampleLayers.tooltip",
                min: this._elevationDefaults.SAMPLE_LAYERS_MIN,
                max: this._elevationDefaults.SAMPLE_LAYERS_MAX,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    this._elevationSampleLayers.set(newValue);
                    this._session.extensionContext.brushShapeManager.setElevationSampleLayers(newValue);
                }
            }));
            this._elevationProperties.push(toolPane.addNumber(this._elevationBrushRadius, {
                isInteger: true,
                title: "resourcePack.editor.toolRail.Terrain.ElevationBrushRadius",
                tooltip: "resourcePack.editor.toolRail.Terrain.ElevationBrushRadius.tooltip",
                min: this._elevationDefaults.BRUSH_RADIUS_MIN,
                max: this._elevationDefaults.BRUSH_RADIUS_MAX,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    this._elevationBrushRadius.set(newValue);
                    this._session.extensionContext.brushShapeManager.setElevationBrushRadius(newValue);
                    this._visualizerInstances.forEach((instance => {
                        instance.disc.radius = newValue + this._elevationDefaults.BASE_RADIUS_ADJUSTMENT + instance.radiusAdjustment;
                        instance.renderComp.setPrimitive(instance.disc);
                    }));
                    if (newValue < this._elevationFalloff.value) {
                        this._elevationFalloff.set(newValue);
                        this._session.extensionContext.brushShapeManager.setElevationFalloff(newValue);
                        this._session.log.info(`Reduced elevation falloff to match elevation brush radius.`);
                        this._falloffVisualizerInstances.forEach((instance => {
                            instance.disc.radius = newValue + this._elevationDefaults.BASE_RADIUS_ADJUSTMENT + instance.radiusAdjustment;
                            instance.renderComp.setPrimitive(instance.disc);
                        }));
                    }
                }
            }));
            toolPane.addDivider();
            toolPane.endConstruct();
            return toolPane;
        }
        _initCursorControl(cursorProperties) {
            const cursorControl = new CursorModeControl(this._session, this._tool, this._toolPane, true, cursorProperties);
            cursorControl.initialize();
            return cursorControl;
        }
        _initBrushControl(paintMode, brushShapes) {
            const brushControl = new BrushPaintSharedControl(this._session, this._tool, this._toolPane, {
                paintMode
            }, brushShapes);
            brushControl.initialize();
            return brushControl;
        }
        _initVisualizer() {
            const widgetGroup = this._session.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.None,
                visible: false
            });
            const options = {
                bindPositionToBlockCursor: true,
                collisionOffset: new lib.Vector3Builder(0, 0, 0),
                collisionRadius: 0,
                selectable: false,
                visible: true,
                widgetName: "Elevation Brush"
            };
            this._elevationVisualizerWidget = widgetGroup.createWidget(new lib.Vector3Builder(0, 0, 0), options);
            const renderOptions = {
                offset: new lib.Vector3Builder(.5, 1.1, .5),
                visible: true
            };
            for (let i = 0; i < this._elevationDefaults.NUM_VISUALIZER_INSTANCES; ++i) {
                const radAdjustment = this._elevationDefaults.VISUALIZER_INSTANCE_RADIUS_INCREMENT * i;
                const disc = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeDisc(new lib.Vector3Builder(0, 0, 0), this._elevationDefaults.DEFAULT_BRUSH_RADIUS + this._elevationDefaults.BASE_RADIUS_ADJUSTMENT + radAdjustment, this._elevationDefaults.DISC_COLOR);
                this._visualizerInstances[i] = {
                    radiusAdjustment: radAdjustment,
                    disc,
                    renderComp: this._elevationVisualizerWidget.addRenderPrimitiveComponent(this._elevationDefaults.VISUALIZER_INSTANCE_BASE_NAME + i.toString(), disc, renderOptions)
                };
            }
            return widgetGroup;
        }
        _initFalloffVisualizer() {
            const options = {
                bindPositionToBlockCursor: true,
                collisionOffset: new lib.Vector3Builder(0, 0, 0),
                collisionRadius: 0,
                selectable: false,
                visible: true,
                widgetName: "Elevation Falloff Visualizer"
            };
            this._elevationFalloffVisualizerWidget = this._widgetGroup.createWidget(new lib.Vector3Builder(0, 0, 0), options);
            const renderOptions = {
                offset: new lib.Vector3Builder(.5, 1.1, .5),
                visible: true
            };
            for (let i = 0; i < this._elevationDefaults.NUM_VISUALIZER_INSTANCES; ++i) {
                const radAdjustment = this._elevationDefaults.VISUALIZER_INSTANCE_RADIUS_INCREMENT * i;
                const disc = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeDisc(new lib.Vector3Builder(0, 0, 0), this._elevationDefaults.DEFAULT_FALLOFF + this._elevationDefaults.BASE_RADIUS_ADJUSTMENT + radAdjustment, this._elevationDefaults.FALLOFF_DISC_COLOR);
                this._falloffVisualizerInstances[i] = {
                    radiusAdjustment: radAdjustment,
                    disc,
                    renderComp: this._elevationFalloffVisualizerWidget.addRenderPrimitiveComponent(this._elevationDefaults.VISUALIZER_INSTANCE_BASE_NAME + i.toString(), disc, renderOptions)
                };
            }
        }
        _registerMousePaintInputs() {
            const action = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton) {
                        if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown) {
                            this._telemetryManager.fireTelemetryEvent(TerrainTelemetry.StartPaining);
                            this._beginPainting();
                        } else if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonUp && this._isPainting) {
                            switch (this._terrainMode.value) {
                              case TerrainMode.ElevationMode:
                                {
                                    this._telemetryManager.fireTelemetryEvent(TerrainTelemetry.EndPainting, {
                                        terrainMode: this._terrainMode.value,
                                        elevationMode: this._elevationMode.value,
                                        intensity: this._elevationIntensity.value,
                                        falloff: this._elevationFalloff.value,
                                        sampleLayers: this._elevationSampleLayers.value,
                                        brushRadius: this._elevationBrushRadius.value
                                    });
                                    break;
                                }

                              case TerrainMode.FlattenMode:
                                {
                                    this._telemetryManager.fireTelemetryEvent(TerrainTelemetry.EndPainting, {
                                        terrainMode: this._terrainMode.value,
                                        flattenMode: this._flattenMode.value,
                                        intensity: this._flattenIntensity.value,
                                        floorBlockOverride: this._floorBlockOverride.value,
                                        smoothing: this._flattenSmoothing.value,
                                        brushOffset: this._session.extensionContext.brushShapeManager.getBrushShapeOffset()
                                    });
                                    break;
                                }

                              case TerrainMode.RoughenMode:
                              case TerrainMode.SmoothMode:
                                {
                                    this._telemetryManager.fireTelemetryEvent(TerrainTelemetry.EndPainting, {
                                        terrainMode: this._terrainMode.value,
                                        intensity: this._smoothRoughIntensity.value,
                                        brushOffset: this._session.extensionContext.brushShapeManager.getBrushShapeOffset()
                                    });
                                    break;
                                }
                            }
                            this._endPainting();
                        }
                    }
                }
            });
            this._tool.registerMouseButtonBinding(action);
        }
        _switchToFlattenMode(newMode) {
            if (this._terrainMode.value !== TerrainMode.FlattenMode) {
                this._flattenMode.set(newMode);
                this._terrainMode.set(TerrainMode.FlattenMode);
                this._onTerrainModeChanged();
            } else if (this._flattenMode.value !== newMode) {
                this._flattenMode.set(newMode);
                this._onFlattenModeChanged();
            }
        }
        _switchToElevationMode(newMode) {
            if (this._terrainMode.value !== TerrainMode.ElevationMode) {
                this._elevationMode.set(newMode);
                this._terrainMode.set(TerrainMode.ElevationMode);
                this._onTerrainModeChanged();
            } else if (this._elevationMode.value !== newMode) {
                this._elevationMode.set(newMode);
                this._onElevationModeChanged();
            }
        }
        _onTerrainModeChanged() {
            if (this._toolPane.visible) {
                this._toolPane.hide();
            }
            this._session.extensionContext.brushShapeManager.setBrushShapeVisible(true);
            this._widgetGroup.visible = false;
            const terrainSettings = this.TERRAIN_SETTINGS_MAP[this._terrainMode.value];
            this._brushControl.switchBrushPaintMode(terrainSettings.paintMode);
            this._brushControl.updateBrushShapes(terrainSettings.brushShapes);
            this._brushControl.session.extensionContext.brushShapeManager.setBrushShapeOffset(terrainSettings.brushOffset);
            if (this._terrainMode.value === TerrainMode.FlattenMode) {
                this._onFlattenModeChanged();
            } else if (this._terrainMode.value === TerrainMode.ElevationMode) {
                this._onElevationModeChanged();
            }
            this._brushControl.session.extensionContext.brushShapeManager.setTerrainStrength(this._terrainMode.value === TerrainMode.FlattenMode ? this._flattenIntensity.value : this._terrainMode.value === TerrainMode.ElevationMode ? this._elevationIntensity.value : this._smoothRoughIntensity.value);
            this._updatePropertyVisibilities();
            this._toolPane.show();
            this._saveSettings();
        }
        _onFlattenModeChanged() {
            const flattenSettings = this._flattenDefaults.SETTINGS_MAP[this._flattenMode.value];
            this._brushControl.session.extensionContext.brushShapeManager.setBrushShapeOffset(flattenSettings.brushOffset);
            this._cursorControl.forceTargetMode(flattenSettings.targetMode);
            this._session.extensionContext.brushShapeManager.setFlattenSmoothing(this._flattenSmoothing.value);
            this._session.extensionContext.brushShapeManager.setFloorBlockOverride(this._floorBlockOverride.value);
            this._session.extensionContext.brushShapeManager.setFlattenMode(this._flattenMode.value);
            this._saveSettings();
        }
        _onElevationModeChanged() {
            const elevationSettings = this._elevationDefaults.SETTINGS_MAP[this._elevationMode.value];
            this._cursorControl.forceTargetMode(elevationSettings.targetMode);
            this._session.extensionContext.brushShapeManager.setElevationFalloff(this._elevationFalloff.value);
            this._session.extensionContext.brushShapeManager.setElevationSampleLayers(this._elevationSampleLayers.value);
            this._session.extensionContext.brushShapeManager.setElevationBrushRadius(this._elevationBrushRadius.value);
            this._session.extensionContext.brushShapeManager.setElevationMode(this._elevationMode.value);
            this._session.extensionContext.brushShapeManager.setBrushShapeVisible(false);
            this._widgetGroup.visible = true;
        }
        _updatePropertyVisibilities() {
            this._flattenProperties.forEach((item => {
                item.visible = this._terrainMode.value === TerrainMode.FlattenMode;
            }));
            this._smoothenProperties.forEach((item => {
                item.visible = this._terrainMode.value === TerrainMode.SmoothMode;
            }));
            this._roughenProperties.forEach((item => {
                item.visible = this._terrainMode.value === TerrainMode.RoughenMode;
            }));
            this._elevationProperties.forEach((item => {
                item.visible = this._terrainMode.value === TerrainMode.ElevationMode;
            }));
        }
        _backupBrushAndCursor() {
            this._brushOffsetBackup = this._session.extensionContext.brushShapeManager.getBrushShapeOffset();
        }
        _restoreBrushAndCursor() {
            this._session.extensionContext.brushShapeManager.setBrushShapeOffset(this._brushOffsetBackup);
        }
        _beginPainting() {
            if (this._isPainting || this._session.extensionContext.brushShapeManager.isBrushPaintBusy() || this._session.extensionContext.transactionManager.isBusy()) {
                this._session.log.warning(`Painting already active`);
                return;
            }
            this._isPainting = true;
            this._session.extensionContext.transactionManager.openTransaction(this.BEHAVIOR_NAME);
            this._session.extensionContext.brushShapeManager.beginPainting((state => {
                if (state === server_editor_namespaceObject.PaintCompletionState.Success) {
                    this._session.extensionContext.transactionManager.commitOpenTransaction();
                } else {
                    this._session.extensionContext.transactionManager.discardOpenTransaction();
                    this._session.log.error(`Error during terrain brushing`);
                }
                this._isPainting = false;
            }));
        }
        _endPainting() {
            this._isPainting = false;
            this._session.extensionContext.brushShapeManager.endPainting(false);
        }
        _activateControls() {
            if (!this._cursorControl.isActive) {
                this._cursorControl.activateControl();
            }
            if (!this._brushControl.isActive) {
                this._brushControl.activateControl();
                this._brushControl.activateVisualization();
            }
        }
        _deactivateControls() {
            if (this._isPainting) {
                this._endPainting();
            }
            if (this._cursorControl.isActive) {
                this._cursorControl.deactivateControl();
            }
            if (this._brushControl.isActive) {
                this._brushControl.deactivateControl();
            }
            this._widgetGroup.visible = false;
        }
        _loadSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(Terrain_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const storeItem = group.fetchItem(Terrain_PERSISTENCE_GROUPITEM_NAME);
                if (storeItem && storeItem.value) {
                    try {
                        const storedSettings = storeItem.value;
                        if (storedSettings.terrainMode !== undefined) {
                            this._terrainMode.set(storedSettings.terrainMode);
                        }
                        if (storedSettings.flattenMode !== undefined) {
                            this._flattenMode.set(storedSettings.flattenMode);
                        }
                        if (storedSettings.flattenSmoothing !== undefined) {
                            this._flattenSmoothing.set(storedSettings.flattenSmoothing);
                        }
                        if (storedSettings.flattenIntensity !== undefined) {
                            this._flattenIntensity.set(storedSettings.flattenIntensity);
                        }
                        if (storedSettings.floorBlockOverride !== undefined) {
                            this._floorBlockOverride.set(storedSettings.floorBlockOverride);
                        }
                    } catch (error) {
                        this._session.log.error("Fail to load the settings, error: " + stringFromException(error));
                    }
                }
                group.dispose();
            }
        }
        _saveSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(Terrain_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const settings = {
                    flattenIntensity: this._flattenIntensity.value,
                    flattenSmoothing: this._flattenSmoothing.value,
                    floorBlockOverride: this._floorBlockOverride.value,
                    terrainMode: this._terrainMode.value,
                    flattenMode: this._flattenMode.value
                };
                const storeItem = group.getOrCreateItem(Terrain_PERSISTENCE_GROUPITEM_NAME, settings);
                if (storeItem) {
                    storeItem.commit();
                }
                group.dispose();
                return;
            }
            this._session.log.error("Fail to save settings for Terrain");
        }
        teardown() {
            this._deactivateControls();
            this._cursorControl.shutdown();
            this._brushControl.shutdown();
            this._widgetGroup.deleteWidget(this._elevationVisualizerWidget);
            this._widgetGroup.deleteWidget(this._elevationFalloffVisualizerWidget);
            if (this._widgetGroup) {
                this._widgetGroup.delete();
            }
        }
    }
    const ExtrudeTool_PERSISTENCE_GROUP_NAME = "editor:extrude";
    const ExtrudeTool_PERSISTENCE_GROUPITEM_NAME = "extrude_settings";
    class ExtrudeTool_PreviewVolume {
        constructor(uiSession) {
            this._session = uiSession;
            this._outlineColor = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeFill);
            this._hullColor = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeBorder);
            this._highlightOutlineColor = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeOutlineBorder);
            this._highlightHullColor = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeOutlineFill);
            const dimensionBounds = this.session.extensionContext.blockUtilities.getDimensionLocationBoundingBox();
            const center = server_namespaceObject.BlockBoundingBoxUtils.getCenter(dimensionBounds);
            this._volume = new server_editor_namespaceObject.RelativeVolumeListBlockVolume;
            this._widgetGroup = this.session.extensionContext.widgetManager.createGroup({
                visible: true
            });
            this._widget = this._widgetGroup.createWidget(center, {
                visible: false,
                selectable: false
            });
            this._widgetVolumeComponent = this._widget.addVolumeOutline("outline", this._volume, {
                outlineColor: this._outlineColor,
                hullColor: this._hullColor,
                highlightOutlineColor: this._highlightOutlineColor,
                highlightHullColor: this._highlightHullColor,
                showOutline: false,
                showHighlightOutline: true,
                visible: true
            });
        }
        teardown() {
            this._widgetVolumeComponent.delete();
            this._widget.delete();
            this._widgetGroup.delete();
        }
        get session() {
            return this._session;
        }
        get visible() {
            return this._widget.visible;
        }
        set visible(value) {
            this._widget.visible = value;
        }
        get location() {
            return this._widget.location;
        }
        set location(position) {
            this._widget.location = position;
        }
        set outlineColor(value) {
            this._outlineColor = value;
            this._widgetVolumeComponent.outlineColor = value;
        }
        set hullColor(value) {
            this._hullColor = value;
            this._widgetVolumeComponent.hullColor = value;
        }
        set highlightOutlineColor(value) {
            this._highlightOutlineColor = value;
            this._widgetVolumeComponent.highlightOutlineColor = value;
        }
        set highlightHullColor(value) {
            this._highlightHullColor = value;
            this._widgetVolumeComponent.highlightHullColor = value;
        }
        addVolume(volume) {
            this._volume.add(volume);
            if (this._volume.isEmpty) {
                return;
            }
            const bounds = this._volume.getBoundingBox();
            this._widget.location = bounds.min;
        }
        clearVolume() {
            this._volume.clear();
        }
        get locationIterator() {
            return this._volume.getBlockLocationIterator();
        }
        get isEmpty() {
            return this._volume.isEmpty;
        }
    }
    var ExtrudeTool_ContiguousSelectionType;
    (function(ContiguousSelectionType) {
        ContiguousSelectionType[ContiguousSelectionType["SameBlock"] = 0] = "SameBlock";
        ContiguousSelectionType[ContiguousSelectionType["BlockStates"] = 1] = "BlockStates";
        ContiguousSelectionType[ContiguousSelectionType["SolidBlock"] = 2] = "SolidBlock";
        ContiguousSelectionType[ContiguousSelectionType["AllBlocks"] = 3] = "AllBlocks";
        ContiguousSelectionType[ContiguousSelectionType["Custom"] = 4] = "Custom";
    })(ExtrudeTool_ContiguousSelectionType || (ExtrudeTool_ContiguousSelectionType = {}));
    var QuickExtrudeMode;
    (function(QuickExtrudeMode) {
        QuickExtrudeMode[QuickExtrudeMode["Shrink"] = 0] = "Shrink";
        QuickExtrudeMode[QuickExtrudeMode["Grow"] = 1] = "Grow";
    })(QuickExtrudeMode || (QuickExtrudeMode = {}));
    var ExtrudeTelemetry;
    (function(ExtrudeTelemetry) {
        ExtrudeTelemetry["QuickExtrude"] = "QuickExtrude";
    })(ExtrudeTelemetry || (ExtrudeTelemetry = {}));
    class ExtrudeTool {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this.SELECTION_COLOR = {
                red: 1,
                green: 1,
                blue: 1,
                alpha: 0
            };
            this.SELECTION_OUTLINE_COLOR = {
                red: 1,
                green: 1,
                blue: 1,
                alpha: .1
            };
            this.SHRINK_SELECTION_COLOR = {
                red: 1,
                green: 0,
                blue: 0,
                alpha: 1
            };
            this.GROW_SELECTION_COLOR = {
                red: 0,
                green: 0,
                blue: 1,
                alpha: 1
            };
            this.extruderSettingsSubPane = undefined;
            this.quickExtrudeSettingsSubPane = undefined;
            this.contiguousSelectionBlockList = [];
            this.previousSelection = new Vector3Set;
            this.searchOffsets = [];
            this.selectStack = new Vector3Set;
            this.quickExtrudeFaceSelection = new Vector3Set;
            this.trackList = new Map;
            this._persistenceManager = getPersistenceManager(uiSession.extensionContext.player);
            this.faceSize = (0, server_editor_namespaceObject.makeObservable)(ExtrudeTool.MAX_FACE_SIZE);
            this.contiguousSelectionType = (0, server_editor_namespaceObject.makeObservable)(ExtrudeTool_ContiguousSelectionType.SameBlock);
            this.layerCount = (0, server_editor_namespaceObject.makeObservable)(ExtrudeTool.MIN_LAYERS);
            this.hasAdjacentBlocks = (0, server_editor_namespaceObject.makeObservable)(false);
            this.hasOpenedTransaction = false;
            this.hasTrailingBlocks = (0, server_editor_namespaceObject.makeObservable)(true);
            this.quickExtrudeFaceDirection = 0;
            this.quickExtrudePreviewActive = false;
            this.quickExtrudeMode = (0, server_editor_namespaceObject.makeObservable)(QuickExtrudeMode.Grow);
            this.sampleCount = (0, server_editor_namespaceObject.makeObservable)(ExtrudeTool.MIN_SAMPLES);
            this.searchRadius = (0, server_editor_namespaceObject.makeObservable)(ExtrudeTool.MIN_RADIUS);
            this.toleranceLevel = (0, server_editor_namespaceObject.makeObservable)(ExtrudeTool.MIN_TOLERANCE);
            this.telemetryManager = new TelemetryManager(uiSession.extensionContext.player, TelemetrySource.Extrude);
            this._loadSettings();
            this.tool = this._createTool(uiSession);
            this.pane = this._createToolPane(uiSession);
            this.cursorProperties = uiSession.extensionContext.cursor.getDefaultProperties();
            this.cursorProperties.outlineColor = {
                red: 2,
                green: 1,
                blue: 2,
                alpha: 1
            };
            this.cursorProperties.controlMode = server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse;
            this.cursorProperties.targetMode = server_editor_namespaceObject.CursorTargetMode.Block;
            this.cursorProperties.visible = true;
            this.searchOffsets.push({
                x: 0,
                y: 0,
                z: 0
            });
            for (let x = -1; x <= 1; x += 2) {
                this.searchOffsets.push({
                    x,
                    y: 0,
                    z: 0
                });
            }
            for (let y = -1; y <= 1; y += 2) {
                this.searchOffsets.push({
                    x: 0,
                    y,
                    z: 0
                });
            }
            for (let z = -1; z <= 1; z += 2) {
                this.searchOffsets.push({
                    x: 0,
                    y: 0,
                    z
                });
            }
            this.preview = new ExtrudeTool_PreviewVolume(uiSession);
            this.preview.outlineColor = this.SELECTION_OUTLINE_COLOR;
            this.preview.hullColor = this.SELECTION_COLOR;
            this.preview.visible = false;
            this.previousAnchorPosition = {
                x: 0,
                y: 0,
                z: 0
            };
            this.previousWidgetPosition = {
                x: 0,
                y: 0,
                z: 0
            };
            this.currentPreviewLocation = {
                x: 0,
                y: 0,
                z: 0
            };
            this.anchorPreviewLocation = {
                x: 0,
                y: 0,
                z: 0
            };
            this.quickExtrudePreviewPosition = {
                x: 0,
                y: 0,
                z: 0
            };
            this._registerMouseAction(uiSession);
            this.tool.bindPropertyPane(this.pane);
            this.newSelectionTransactionHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(this.uiSession.extensionContext.transactionManager, (payload => {
                const newSelectionArray = payload.differenceInNewSelection;
                if (newSelectionArray !== undefined) {
                    for (const selection of newSelectionArray) {
                        this.selectStack.delete(selection);
                    }
                }
            }), (payload => {
                const anchor = payload.newAnchorPosition;
                const newSelectionArray = payload.differenceInNewSelection;
                const position = payload.newWidgetPosition;
                if (this.widget !== undefined && anchor !== undefined && newSelectionArray !== undefined && position !== undefined) {
                    this.anchorPreviewLocation = anchor;
                    this.currentPreviewLocation = position;
                    this.widget.location = position;
                    for (const selection of newSelectionArray) {
                        this.selectStack.add(selection);
                    }
                    this.previousAnchorPosition = anchor;
                    this.previousWidgetPosition = position;
                    this._copySelectionMap(this.previousSelection, this.selectStack);
                }
            }));
            this.oldSelectionTransactionHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(this.uiSession.extensionContext.transactionManager, (payload => {
                const anchor = payload.oldAnchorPosition;
                const oldSelectionArray = payload.differenceInOldSelection;
                const position = payload.oldWidgetPosition;
                if (this.widget !== undefined && anchor !== undefined && oldSelectionArray !== undefined && position !== undefined) {
                    this.anchorPreviewLocation = anchor;
                    this.currentPreviewLocation = position;
                    this.widget.location = position;
                    for (const selection of oldSelectionArray) {
                        this.selectStack.add(selection);
                    }
                    this.previousAnchorPosition = anchor;
                    this.previousWidgetPosition = position;
                    this._copySelectionMap(this.previousSelection, this.selectStack);
                    this._drawPreviewFromSelectStack();
                }
            }), (payload => {
                const oldSelectionArray = payload.differenceInOldSelection;
                if (oldSelectionArray !== undefined) {
                    for (const selection of oldSelectionArray) {
                        this.selectStack.delete(selection);
                    }
                    this._drawPreviewFromSelectStack();
                }
            }));
            this.quickExtrudePreviewActive = false;
            if (ExtrudeTool.ENABLE_VISUALIZATION) {
                const onTick = () => {
                    const cursor = this.uiSession.extensionContext.cursor;
                    const position = cursor.getPosition();
                    const direction = cursor.faceDirection;
                    if (this.quickExtrudePreviewActive && (!lib.Vector3Utils.equals(position, this.quickExtrudePreviewPosition) || direction !== this.quickExtrudeFaceDirection)) {
                        this.quickExtrudePreviewPosition = position;
                        this.quickExtrudeFaceDirection = direction;
                        this._createFacePreview();
                    }
                };
                this.tickHandle = server_namespaceObject.system.runInterval(onTick, ExtrudeTool.TICK_REFRESH_RATE);
            }
        }
        _createTool(uiSession) {
            const toolToggleAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    uiSession.toolRail.setSelectedToolId(tool.id);
                }
            });
            const tool = uiSession.toolRail.addTool(ExtrudeTool.MODAL_TOOL_ID, {
                title: "resourcePack.editor.toolRail.ExtrudeTool.title",
                icon: "pack://textures/editor/Lift.png?filtering=point",
                tooltip: {
                    description: "resourcePack.editor.toolRail.ExtrudeTool.tooltip",
                    image: "pack://textures/editor/Extrude.gif"
                },
                action: toolToggleAction
            });
            tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    uiSession.extensionContext.cursor.pushPropertiesById(this.cursorProperties, ExtrudeTool.MODAL_TOOL_ID);
                    this.quickExtrudePreviewActive = true;
                } else {
                    uiSession.extensionContext.cursor.popPropertiesById(ExtrudeTool.MODAL_TOOL_ID);
                    this.quickExtrudePreviewActive = false;
                    this._destroyFacePreview();
                    this._clearState();
                }
            }));
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, toolToggleAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_E,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editorCore:ExtrudeTool:toggleTool",
                label: "resourcePack.editor.toolRail.ExtrudeTool.keyBinding.toggleTool.title",
                tooltip: "resourcePack.editor.toolRail.ExtrudeTool.keyBinding.toggleTool.tooltip"
            });
            return tool;
        }
        _createFacePreview() {
            if (!ExtrudeTool.ENABLE_VISUALIZATION) {
                return;
            }
            const cursor = this.uiSession.extensionContext.cursor;
            const cursorPosition = cursor.getPosition();
            const cursorDirection = cursor.faceDirection;
            let direction = server_namespaceObject.Direction.Down;
            const scale = {
                x: 1,
                y: 1,
                z: 1
            };
            const growthOffset = {
                x: 0,
                y: 0,
                z: 0
            };
            const shrinkDirection = {
                x: 0,
                y: 0,
                z: 0
            };
            switch (cursorDirection) {
              case 0:
                direction = server_namespaceObject.Direction.Down;
                if (this.quickExtrudeMode.value === QuickExtrudeMode.Grow) {
                    scale.y = 1;
                }
                growthOffset.y = -1;
                shrinkDirection.y = 1;
                break;

              case 1:
                direction = server_namespaceObject.Direction.Up;
                if (this.quickExtrudeMode.value === QuickExtrudeMode.Grow) {
                    scale.y = 1;
                }
                growthOffset.y = 1;
                shrinkDirection.y = -1;
                break;

              case 2:
                direction = server_namespaceObject.Direction.North;
                if (this.quickExtrudeMode.value === QuickExtrudeMode.Grow) {
                    scale.z = 1;
                }
                growthOffset.z = -1;
                shrinkDirection.z = 1;
                break;

              case 3:
                direction = server_namespaceObject.Direction.South;
                if (this.quickExtrudeMode.value === QuickExtrudeMode.Grow) {
                    scale.z = 1;
                }
                growthOffset.z = 1;
                shrinkDirection.z = -1;
                break;

              case 4:
                direction = server_namespaceObject.Direction.West;
                if (this.quickExtrudeMode.value === QuickExtrudeMode.Grow) {
                    scale.x = 1;
                }
                growthOffset.x = -1;
                shrinkDirection.x = 1;
                break;

              case 5:
                direction = server_namespaceObject.Direction.East;
                if (this.quickExtrudeMode.value === QuickExtrudeMode.Grow) {
                    scale.x = 1;
                }
                growthOffset.x = 1;
                shrinkDirection.x = -1;
                break;
            }
            const dimension = this.uiSession.extensionContext.player.dimension;
            const centerBlock = dimension.getBlock(cursorPosition);
            if (centerBlock === undefined) {
                return;
            }
            const selectionStack = this._selectContiguousFaceForQuickExtrude(this.uiSession, direction, centerBlock, true);
            if (selectionStack.size > 0) {
                this._destroyFacePreview();
                this._copySelectionMap(this.quickExtrudeFaceSelection, selectionStack);
                const color = this.quickExtrudeMode.value === QuickExtrudeMode.Shrink ? this.SHRINK_SELECTION_COLOR : this.GROW_SELECTION_COLOR;
                if (this.quickExtrudeMode.value === QuickExtrudeMode.Shrink) {
                    let currentLayer = new Vector3Set;
                    this._copySelectionMap(currentLayer, selectionStack);
                    for (let i = 2; i <= this.layerCount.value; i++) {
                        const layer = this._quickExtrudeGetSelectionAfterShrink(currentLayer, shrinkDirection);
                        currentLayer.clear();
                        currentLayer = layer;
                        this._appendSelectionMap(selectionStack, currentLayer);
                    }
                }
                this.preview.highlightOutlineColor = color;
                this.preview.clearVolume();
                selectionStack.forEach((selection => {
                    let loc = {
                        ...selection
                    };
                    if (this.quickExtrudeMode.value === QuickExtrudeMode.Grow) {
                        loc = lib.Vector3Utils.add(selection, growthOffset);
                    }
                    this.preview.addVolume(loc);
                }));
                this.preview.visible = true;
            }
        }
        _destroyFacePreview() {
            this.preview.clearVolume();
            this.preview.visible = false;
        }
        _createThisContiguousSelectionBlockList(parentPane) {
            this.contiguousSelectionBlockListTable = parentPane.addBlockList(convertBlockTypesToBlockStrings(this.contiguousSelectionBlockList), {
                onChange: newVal => {
                    this.contiguousSelectionBlockList = convertBlockStringsToBlockType(newVal);
                    this._saveSettings();
                }
            });
        }
        _createTrailingBlocksProperty(parentPane) {
            const trailingBlocksValue = parentPane.addNumber(this.sampleCount, {
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.SampleLayerCount.title",
                min: ExtrudeTool.MIN_SAMPLES,
                max: ExtrudeTool.MAX_SAMPLES,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                onChange: (_newVal, _oldVal) => {
                    this._saveSettings();
                }
            });
            return trailingBlocksValue;
        }
        _createContiguousSelectionPane(parentPane) {
            const contiguousSelectionSettingsSubPane = parentPane.createSubPane({
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.ContiguousSelectionSettings.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.ExtrudeTool.pane.ContiguousSelectionSettings.title",
                    description: [ "resourcePack.editor.toolRail.ExtrudeTool.pane.ContiguousSelectionSettings.tooltip" ]
                }
            });
            contiguousSelectionSettingsSubPane.addDropdown(this.contiguousSelectionType, {
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.ContiguousSelectionType.title",
                tooltip: "resourcePack.editor.toolRail.ExtrudeTool.pane.ContiguousSelectionType.tooltip",
                entries: [ {
                    label: "resourcePack.editor.toolRail.ExtrudeTool.pane.ContiguousSelectionType.SameBlocks",
                    value: 0
                }, {
                    label: "resourcePack.editor.toolRail.ExtrudeTool.pane.ContiguousSelectionType.SameBlocksAndStates",
                    value: 1
                }, {
                    label: "resourcePack.editor.toolRail.ExtrudeTool.pane.ContiguousSelectionType.SolidBlocks",
                    value: 2
                }, {
                    label: "resourcePack.editor.toolRail.ExtrudeTool.pane.ContiguousSelectionType.AllBlocks",
                    value: 3
                }, {
                    label: "resourcePack.editor.toolRail.ExtrudeTool.pane.ContiguousSelectionType.CustomBlockList",
                    value: 4
                } ],
                onChange: () => {
                    if (this.contiguousSelectionBlockListTable) {
                        if (this.contiguousSelectionType.value === ExtrudeTool_ContiguousSelectionType.Custom) {
                            this.contiguousSelectionBlockListTable.visible = true;
                        } else {
                            this.contiguousSelectionBlockListTable.visible = false;
                        }
                        this._saveSettings();
                    }
                }
            });
            this._createThisContiguousSelectionBlockList(contiguousSelectionSettingsSubPane);
            if (this.contiguousSelectionBlockListTable) {
                if (this.contiguousSelectionType.value === ExtrudeTool_ContiguousSelectionType.Custom) {
                    this.contiguousSelectionBlockListTable.visible = true;
                } else {
                    this.contiguousSelectionBlockListTable.visible = false;
                }
            }
            const toleranceItem = contiguousSelectionSettingsSubPane.addNumber(this.toleranceLevel, {
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.ToleranceLevel.title",
                min: ExtrudeTool.MIN_TOLERANCE,
                max: ExtrudeTool.MAX_TOLERANCE,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                onChange: () => {
                    this._saveSettings();
                }
            });
            const hasAdjacentBlocksItem = contiguousSelectionSettingsSubPane.addBool(this.hasAdjacentBlocks, {
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.HasAdjacentBlocks.title",
                onChange: () => {
                    this._saveSettings();
                }
            });
            toleranceItem.visible = false;
            hasAdjacentBlocksItem.visible = true;
            this.quickExtrudePreviewActive = true;
            return contiguousSelectionSettingsSubPane;
        }
        _destroyExtrusionPane(parentPane) {
            if (this.extruderSettingsSubPane) {
                parentPane.removeSubPane(this.extruderSettingsSubPane);
                this.extruderSettingsSubPane = undefined;
            }
        }
        _createExtrusionPane(parentPane) {
            this._destroyExtrusionPane(parentPane);
            this.extruderSettingsSubPane = parentPane.createSubPane({
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.ExtruderSettings.title"
            });
            this.extruderSettingsSubPane.hide();
            const contiguousPane = this._createContiguousSelectionPane(this.extruderSettingsSubPane);
            contiguousPane.addNumber(this.searchRadius, {
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.Radius.title",
                min: ExtrudeTool.MIN_RADIUS,
                max: ExtrudeTool.MAX_RADIUS,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true
            });
            contiguousPane.show();
            const trailingBlocksSettingsSubPane = this.extruderSettingsSubPane.createSubPane({
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.TrailingBlocks.title"
            });
            trailingBlocksSettingsSubPane.addBool(this.hasTrailingBlocks, {
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.TrailingBlocks.title",
                onChange: () => {
                    if (this.hasTrailingBlocks.value) {
                        TrailingBlocksProperties.visible = true;
                    } else {
                        TrailingBlocksProperties.visible = false;
                    }
                }
            });
            const TrailingBlocksProperties = this._createTrailingBlocksProperty(trailingBlocksSettingsSubPane);
            if (this.hasTrailingBlocks.value) {
                TrailingBlocksProperties.visible = true;
            } else {
                TrailingBlocksProperties.visible = false;
            }
            this.extruderSettingsSubPane.show();
        }
        _destroyQuickExtrudePane(parentPane) {
            if (this.quickExtrudeSettingsSubPane) {
                parentPane.removeSubPane(this.quickExtrudeSettingsSubPane);
                this.quickExtrudeSettingsSubPane = undefined;
            }
        }
        _createQuickExtrudePane(parentPane) {
            this._destroyQuickExtrudePane(parentPane);
            this.quickExtrudeSettingsSubPane = parentPane.createSubPane({
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.QuickExtrudeSettings.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.QuickExtrudeSettings.title",
                    description: [ "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.QuickExtrudeSettings.tooltip" ]
                }
            });
            this.quickExtrudeSettingsSubPane.hide();
            this.quickExtrudeSettingsSubPane.addToggleGroup(this.quickExtrudeMode, {
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.QuickExtrudeMode.title",
                hiddenLabel: true,
                entries: [ {
                    label: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.QuickExtrudeMode.expand.title",
                    value: QuickExtrudeMode.Grow,
                    icon: "pack://textures/editor/Marquee-Add.png?filtering=point",
                    tooltip: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.QuickExtrudeMode.expand.tooltip"
                }, {
                    label: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.QuickExtrudeMode.decrease.title",
                    value: QuickExtrudeMode.Shrink,
                    icon: "pack://textures/editor/Marquee-Subtract.png?filtering=point",
                    tooltip: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.QuickExtrudeMode.decrease.tooltip"
                } ],
                onChange: () => {
                    this._createFacePreview();
                    this._saveSettings();
                }
            });
            this.quickExtrudeSettingsSubPane.addNumber(this.faceSize, {
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.Settings.facesize.title",
                tooltip: "resourcePack.editor.toolRail.ExtrudeTool.pane.Settings.facesize.tooltip",
                min: ExtrudeTool.MIN_FACE_SIZE,
                max: ExtrudeTool.MAX_FACE_SIZE,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                onChange: () => {
                    this._saveSettings();
                }
            });
            this.quickExtrudeSettingsSubPane.addNumber(this.layerCount, {
                title: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.LayerCount.title",
                tooltip: "resourcePack.editor.toolRail.ExtrudeTool.pane.SelectionMode.LayerCount.tooltip",
                min: ExtrudeTool.MIN_LAYERS,
                max: ExtrudeTool.MAX_LAYERS,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                onChange: () => {
                    this._saveSettings();
                }
            });
            this._createContiguousSelectionPane(this.quickExtrudeSettingsSubPane);
            this.quickExtrudeSettingsSubPane.show();
        }
        _createToolPane(uiSession) {
            const pane = uiSession.createPropertyPane({
                title: "resourcePack.editor.toolRail.ExtrudeTool.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.toolRail.ExtrudeTool.tooltip", {
                        link: "https://aka.ms/BedrockEditorExtrude",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this._destroyExtrusionPane(pane);
            this._createQuickExtrudePane(pane);
            this.quickExtrudePreviewActive = true;
            return pane;
        }
        teardown() {
            this._clearState();
            if (this.tickHandle !== undefined) {
                server_namespaceObject.system.clearRun(this.tickHandle);
            }
        }
        _getQuickExtrudeVectorFromDirection(direction) {
            const quickExtrudeDirection = {
                x: 0,
                y: 0,
                z: 0
            };
            switch (direction) {
              case server_namespaceObject.Direction.Up:
                quickExtrudeDirection.y = 1;
                break;

              case server_namespaceObject.Direction.Down:
                quickExtrudeDirection.y = -1;
                break;

              case server_namespaceObject.Direction.North:
                quickExtrudeDirection.z = -1;
                break;

              case server_namespaceObject.Direction.South:
                quickExtrudeDirection.z = 1;
                break;

              case server_namespaceObject.Direction.East:
                quickExtrudeDirection.x = 1;
                break;

              case server_namespaceObject.Direction.West:
                quickExtrudeDirection.x = -1;
                break;
            }
            return quickExtrudeDirection;
        }
        _registerMouseAction(uiSession) {
            const executeAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton && mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown && this.tool.isActive && mouseRay?.cursorBlockLocation) {
                        try {
                            this._applyExtrude(mouseRay.location, mouseRay.direction, mouseRay.cursorBlockLocation);
                        } catch (e) {
                            this.uiSession.log.error(`Unable to apply extrude:  ${e.message}`, {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                            if (this.hasOpenedTransaction) {
                                this.uiSession.extensionContext.transactionManager.discardOpenTransaction();
                                this.hasOpenedTransaction = false;
                            }
                        }
                    }
                }
            });
            this.tool.registerMouseButtonBinding(executeAction);
        }
        _applyExtrude(rayLocation, rayDirection, targetLocation) {
            const dimension = this.uiSession.extensionContext.player.dimension;
            const raycastFace = dimension.getBlockFromRay(rayLocation, rayDirection)?.face;
            if (raycastFace === undefined) {
                return undefined;
            }
            const quickExtrudeDirection = this._getQuickExtrudeVectorFromDirection(raycastFace);
            let quickExtrudeShrinkSelection = new Vector3Set;
            const targetBlock = dimension.getBlock(targetLocation);
            if (targetBlock) {
                this.preview.visible = true;
                this.trackList.clear();
                this.uiSession.extensionContext.transactionManager.openTransaction("resourcePack.editor.toolRail.ExtrudeTool.title");
                this.hasOpenedTransaction = true;
                this.selectStack = this._selectContiguousFaceForQuickExtrude(this.uiSession, raycastFace, targetBlock, true);
                this.anchorPreviewLocation = targetLocation;
                this.currentPreviewLocation = targetLocation;
                switch (this.quickExtrudeMode.value) {
                  case QuickExtrudeMode.Grow:
                    this.telemetryManager.fireTelemetryEvent(ExtrudeTelemetry.QuickExtrude, {
                        mode: "grow",
                        faceSize: this.faceSize.value,
                        layerCount: this.layerCount.value,
                        contiguousSelection: this.contiguousSelectionType.value,
                        hasAdjacentBlocks: this.hasAdjacentBlocks.value
                    });
                    for (let i = 0; i < this.layerCount.value; i++) {
                        this._growSelection(lib.Vector3Utils.add(this.currentPreviewLocation, quickExtrudeDirection));
                        this.currentPreviewLocation = lib.Vector3Utils.add(this.currentPreviewLocation, quickExtrudeDirection);
                    }
                    break;

                  case QuickExtrudeMode.Shrink:
                    this.telemetryManager.fireTelemetryEvent(ExtrudeTelemetry.QuickExtrude, {
                        mode: "shrink",
                        faceSize: this.faceSize.value,
                        layerCount: this.layerCount.value,
                        contiguousSelection: this.contiguousSelectionType.value,
                        hasAdjacentBlocks: this.hasAdjacentBlocks.value
                    });
                    for (let i = 0; i < this.layerCount.value; i++) {
                        quickExtrudeShrinkSelection.clear();
                        quickExtrudeShrinkSelection = this._quickExtrudeGetSelectionAfterShrink(this.selectStack, lib.Vector3Utils.scale(quickExtrudeDirection, -1));
                        this._shrinkSelection(lib.Vector3Utils.subtract(this.currentPreviewLocation, quickExtrudeDirection));
                        this.currentPreviewLocation = lib.Vector3Utils.subtract(this.currentPreviewLocation, quickExtrudeDirection);
                        this._copySelectionMap(this.selectStack, quickExtrudeShrinkSelection);
                        if (this.selectStack.size <= 0) {
                            break;
                        }
                    }
                }
                this._clearState();
                if (this.hasOpenedTransaction) {
                    this.hasOpenedTransaction = false;
                    try {
                        this.uiSession.extensionContext.transactionManager.commitOpenTransaction();
                    } catch (e) {
                        this.uiSession.extensionContext.transactionManager.discardOpenTransaction();
                        this.uiSession.log.error(`Error committing transaction: ${e.message}`, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                    }
                }
            }
        }
        _getPositionKey(loc) {
            return [ loc.x, loc.y, loc.z ].join(",");
        }
        _drawPreviewFromSelectStack() {
            this.preview.clearVolume();
            this.selectStack.forEach((value => {
                let isEdge = false;
                for (let x = -1; x <= 1 && !isEdge; x += 2) {
                    const position = {
                        x: value.x + x,
                        y: value.y,
                        z: value.z
                    };
                    if (!this.selectStack.contains(position)) {
                        isEdge = true;
                    }
                }
                for (let y = -1; y <= 1 && !isEdge; y += 2) {
                    const position = {
                        x: value.x,
                        y: value.y + y,
                        z: value.z
                    };
                    if (!this.selectStack.contains(position)) {
                        isEdge = true;
                    }
                }
                for (let z = -1; z <= 1 && !isEdge; z += 2) {
                    const position = {
                        x: value.x,
                        y: value.y,
                        z: value.z + z
                    };
                    if (!this.selectStack.contains(position)) {
                        isEdge = true;
                    }
                }
                if (isEdge) {
                    this.preview.addVolume(value);
                }
            }));
        }
        _growSelection(moveLocation) {
            const offset = lib.Vector3Utils.subtract(moveLocation, this.currentPreviewLocation);
            const newSelection = new Vector3Set;
            const newBlockType = new CustomSet((block => vec3HashFunction(block.location)));
            const player = this.uiSession.extensionContext.player;
            const dimension = player.dimension;
            this.selectStack.forEach((loc => {
                const block = dimension.getBlock(loc);
                if (block === undefined) {
                    return;
                }
                const newLocation = lib.Vector3Utils.add(loc, offset);
                if (!newSelection.contains(newLocation)) {
                    newSelection.add(newLocation);
                    newBlockType.add(block);
                }
            }));
            newSelection.forEach((loc => {
                this.selectStack.add(loc);
                const targetBlock = dimension.getBlock(loc);
                if (targetBlock === undefined) {
                    return;
                }
                const oldLocation = lib.Vector3Utils.subtract(loc, offset);
                const oldBlock = newBlockType.value(vec3HashFunction(oldLocation));
                if (oldBlock === undefined) {
                    return;
                }
                this._addBlockLocationToTransaction(loc);
                targetBlock.setType(oldBlock.typeId);
                const selectionBlockStates = oldBlock.permutation.getAllStates();
                if (selectionBlockStates !== undefined) {
                    for (const key of Object.keys(selectionBlockStates)) {
                        const tag = key;
                        const newPermutation = targetBlock.permutation.withState(tag, selectionBlockStates[key]);
                        targetBlock.setPermutation(newPermutation);
                    }
                }
            }));
        }
        _shrinkSelection(moveLocation) {
            const offset = lib.Vector3Utils.subtract(moveLocation, this.currentPreviewLocation);
            const newSelection = new Vector3Set;
            const newBlockType = new CustomSet((block => vec3HashFunction(block.location)));
            const player = this.uiSession.extensionContext.player;
            const dimension = player.dimension;
            this.selectStack.forEach((loc => {
                const block = dimension.getBlock(loc);
                if (block === undefined) {
                    return;
                }
                const newLocation = lib.Vector3Utils.add(loc, offset);
                if (this.selectStack.contains(newLocation)) {
                    newSelection.add(newLocation);
                    newBlockType.add(block);
                }
            }));
            this.selectStack.forEach((loc => {
                const targetBlock = dimension.getBlock(loc);
                if (targetBlock === undefined) {
                    return;
                }
                this._addBlockLocationToTransaction(loc);
                if (!newSelection.contains(loc)) {
                    targetBlock.setType(lib_vanilla_MinecraftBlockTypes.Air);
                } else {
                    const newBlock = newBlockType.value(vec3HashFunction(loc));
                    if (newBlock !== undefined) {
                        targetBlock.setType(newBlock.typeId);
                    }
                }
            }));
        }
        _quickExtrudeGetSelectionAfterShrink(originalSelection, offset) {
            const newSelection = new Vector3Set;
            const player = this.uiSession.extensionContext.player;
            const dimension = player.dimension;
            originalSelection.forEach((value => {
                const sampleBlock = dimension.getBlock(value);
                if (sampleBlock === undefined) {
                    return;
                }
                const testPosition = lib.Vector3Utils.add(value, offset);
                const testBlock = dimension.getBlock(testPosition);
                if (testBlock === undefined) {
                    return;
                }
                if (this._areBlocksContiguous(sampleBlock, testBlock) === true) {
                    newSelection.add(testPosition);
                }
            }));
            return newSelection;
        }
        _isDraggingSelection(direction, isMovingUp, isMovingDown, isMovingNorth, isMovingSouth, isMovingWest, isMovingEast) {
            const size = lib.Vector3Utils.subtract(this.currentPreviewLocation, this.anchorPreviewLocation);
            switch (direction) {
              case server_namespaceObject.Direction.Up:
                if (size.y === 0 && isMovingDown) {
                    return true;
                }
                break;

              case server_namespaceObject.Direction.Down:
                if (size.y === 0 && isMovingUp) {
                    return true;
                }
                break;

              case server_namespaceObject.Direction.North:
                if (size.z === 0 && isMovingSouth) {
                    return true;
                }
                break;

              case server_namespaceObject.Direction.South:
                if (size.z === 0 && isMovingNorth) {
                    return true;
                }
                break;

              case server_namespaceObject.Direction.East:
                if (size.x === 0 && isMovingWest) {
                    return true;
                }
                break;

              case server_namespaceObject.Direction.West:
                if (size.x === 0 && isMovingEast) {
                    return true;
                }
                break;
            }
            return false;
        }
        _isBlockTypeInSelectionList(block) {
            if (this.contiguousSelectionBlockList === undefined || this.contiguousSelectionBlockList.length === 0) {
                return false;
            }
            const blockType = block.type;
            if (blockType === undefined) {
                return false;
            }
            for (let i = 0; i < this.contiguousSelectionBlockList.length; i++) {
                if (this.contiguousSelectionBlockList[i] === blockType) {
                    return true;
                }
            }
            return false;
        }
        _areBlocksContiguous(blockToFollow, blockToTest) {
            switch (this.contiguousSelectionType.value) {
              case ExtrudeTool_ContiguousSelectionType.SameBlock:
                return isSameBlockType(blockToFollow, blockToTest);

              case ExtrudeTool_ContiguousSelectionType.BlockStates:
                return isSameBlockAndProperties(blockToFollow, blockToTest);

              case ExtrudeTool_ContiguousSelectionType.SolidBlock:
                return isBlockSolid(blockToTest);

              case ExtrudeTool_ContiguousSelectionType.AllBlocks:
                return isBlockNotAir(blockToTest);

              case ExtrudeTool_ContiguousSelectionType.Custom:
                return this._isBlockTypeInSelectionList(blockToTest);
            }
            return false;
        }
        _isBlockExposedInDirection(targetLocation, direction) {
            const ExtrusionDirection = {
                x: 0,
                y: 0,
                z: 0
            };
            switch (direction) {
              case server_namespaceObject.Direction.Up:
                ExtrusionDirection.y = 1;
                break;

              case server_namespaceObject.Direction.Down:
                ExtrusionDirection.y = -1;
                break;

              case server_namespaceObject.Direction.North:
                ExtrusionDirection.z = -1;
                break;

              case server_namespaceObject.Direction.South:
                ExtrusionDirection.z = 1;
                break;

              case server_namespaceObject.Direction.East:
                ExtrusionDirection.x = 1;
                break;

              case server_namespaceObject.Direction.West:
                ExtrusionDirection.x = -1;
                break;
            }
            const dimension = this.uiSession.extensionContext.player.dimension;
            const blockToCheck = dimension.getBlock(lib.Vector3Utils.add(targetLocation, ExtrusionDirection));
            if (blockToCheck === undefined || blockToCheck.typeId !== lib_vanilla_MinecraftBlockTypes.Air) {
                return false;
            }
            return true;
        }
        _selectContiguousFaceForQuickExtrude(uiSession, selectionDirection, block, checkTolerance) {
            uiSession.extensionContext.selectionManager.volume.clear();
            const FaceSelection = new Vector3Set;
            if (block) {
                const faceSize = (this.faceSize.value - 1) / 2;
                const from = {
                    x: block.location.x - faceSize,
                    y: block.location.y - faceSize,
                    z: block.location.z - faceSize
                };
                const to = {
                    x: block.location.x + faceSize,
                    y: block.location.y + faceSize,
                    z: block.location.z + faceSize
                };
                switch (selectionDirection) {
                  case server_namespaceObject.Direction.Up:
                    from.y = block.location.y;
                    to.y = block.location.y;
                    break;

                  case server_namespaceObject.Direction.Down:
                    from.y = block.location.y;
                    to.y = block.location.y;
                    break;

                  case server_namespaceObject.Direction.North:
                    from.z = block.location.z;
                    to.z = block.location.z;
                    break;

                  case server_namespaceObject.Direction.South:
                    from.z = block.location.z;
                    to.z = block.location.z;
                    break;

                  case server_namespaceObject.Direction.East:
                    from.x = block.location.x;
                    to.x = block.location.x;
                    break;

                  case server_namespaceObject.Direction.West:
                    from.x = block.location.x;
                    to.x = block.location.x;
                    break;
                }
                let bounds = new server_namespaceObject.BlockVolume(from, to);
                const dimension = block.dimension;
                let furthestUp = block.location.y;
                let furthestDown = block.location.y;
                let furthestWest = block.location.x;
                let furthestEast = block.location.x;
                let furthestNorth = block.location.z;
                let furthestSouth = block.location.z;
                let fillStack = [];
                let hasAdjustedBounds = false;
                const outOfBoundsBlocks = [];
                const visitedBlocks = new Map;
                const initialTolerance = checkTolerance && this.hasAdjacentBlocks.value ? 1 : 0;
                fillStack.push({
                    Position: block.location,
                    Tolerance: initialTolerance
                });
                visitedBlocks.set(this._getPositionKey(block.location), {
                    Checked: true,
                    Tolerance: initialTolerance
                });
                while (fillStack.length > 0 || !hasAdjustedBounds) {
                    if (fillStack.length <= 0) {
                        if (furthestUp < Math.floor(to.y) && furthestDown === Math.floor(from.y)) {
                            from.y = furthestUp - (to.y - from.y);
                        } else if (furthestUp === Math.floor(to.y) && furthestDown > Math.floor(from.y)) {
                            to.y = furthestDown + (to.y - from.y);
                        }
                        if (furthestEast < Math.floor(to.x) && furthestWest === Math.floor(from.x)) {
                            from.x = furthestEast - (to.x - from.x);
                        } else if (furthestEast === Math.floor(to.x) && furthestWest > Math.floor(from.x)) {
                            to.x = furthestWest + (to.x - from.x);
                        }
                        if (furthestSouth === Math.floor(to.z) && furthestNorth > Math.floor(from.z)) {
                            to.z = furthestNorth + (to.z - from.z);
                        } else if (furthestSouth < Math.floor(to.z) && furthestNorth === Math.floor(from.z)) {
                            from.z = furthestSouth - (to.z - from.z);
                        }
                        fillStack = outOfBoundsBlocks;
                        bounds = new server_namespaceObject.BlockVolume(from, to);
                        hasAdjustedBounds = true;
                    }
                    const checkBlock = fillStack.pop();
                    if (checkBlock !== undefined) {
                        const loc = checkBlock.Position;
                        visitedBlocks.set(this._getPositionKey(loc), {
                            Checked: true,
                            Tolerance: checkBlock.Tolerance
                        });
                        if (loc === undefined || !bounds.isInside(loc)) continue;
                        let isContiguous = true;
                        try {
                            const blockAtLoc = dimension.getBlock(loc);
                            if (blockAtLoc !== undefined) {
                                switch (this.contiguousSelectionType.value) {
                                  case ExtrudeTool_ContiguousSelectionType.SameBlock:
                                    if (!isSameBlockType(block, blockAtLoc)) {
                                        isContiguous = false;
                                        if (checkBlock.Tolerance <= 0) {
                                            continue;
                                        }
                                    }
                                    break;

                                  case ExtrudeTool_ContiguousSelectionType.BlockStates:
                                    if (!isSameBlockAndProperties(block, blockAtLoc)) {
                                        isContiguous = false;
                                        if (checkBlock.Tolerance <= 0) {
                                            continue;
                                        }
                                    }
                                    break;

                                  case ExtrudeTool_ContiguousSelectionType.SolidBlock:
                                    if (!isBlockSolid(blockAtLoc)) {
                                        isContiguous = false;
                                        if (checkBlock.Tolerance <= 0) {
                                            continue;
                                        }
                                    }
                                    break;

                                  case ExtrudeTool_ContiguousSelectionType.AllBlocks:
                                    if (!isBlockNotAir(blockAtLoc)) {
                                        isContiguous = false;
                                        if (checkBlock.Tolerance <= 0) {
                                            continue;
                                        }
                                    }
                                    break;

                                  case ExtrudeTool_ContiguousSelectionType.Custom:
                                    if (!this._isBlockTypeInSelectionList(blockAtLoc)) {
                                        isContiguous = false;
                                        if (checkBlock.Tolerance <= 0) {
                                            continue;
                                        }
                                    }
                                    break;
                                }
                                if (!this._isBlockExposedInDirection(loc, selectionDirection)) {
                                    isContiguous = false;
                                    if (checkBlock.Tolerance <= 0) {
                                        continue;
                                    }
                                }
                            } else {
                                continue;
                            }
                        } catch {
                            continue;
                        }
                        let remainingTolerance = checkBlock.Tolerance - 1;
                        if (isContiguous) {
                            if (loc.x < furthestWest) {
                                furthestWest = loc.x;
                            }
                            if (loc.x > furthestEast) {
                                furthestEast = loc.x;
                            }
                            if (loc.z < furthestNorth) {
                                furthestNorth = loc.z;
                            }
                            if (loc.z > furthestSouth) {
                                furthestSouth = loc.z;
                            }
                            if (loc.y < furthestDown) {
                                furthestDown = loc.y;
                            }
                            if (loc.y > furthestUp) {
                                furthestUp = loc.y;
                            }
                            FaceSelection.add(loc);
                            remainingTolerance = initialTolerance;
                        }
                        for (const offset of this.searchOffsets) {
                            const offsetLoc = {
                                x: loc.x + offset.x,
                                y: loc.y + offset.y,
                                z: loc.z + offset.z
                            };
                            if (!bounds.isInside(offsetLoc)) {
                                outOfBoundsBlocks.push({
                                    Position: offsetLoc,
                                    Tolerance: remainingTolerance
                                });
                                continue;
                            }
                            const visitedBlock = visitedBlocks.get(this._getPositionKey(offsetLoc));
                            if (visitedBlock !== undefined) {
                                if (visitedBlock.Tolerance >= remainingTolerance && visitedBlock.Checked) {
                                    continue;
                                }
                            }
                            fillStack.push({
                                Position: offsetLoc,
                                Tolerance: remainingTolerance
                            });
                            visitedBlocks.set(this._getPositionKey(offsetLoc), {
                                Checked: false,
                                Tolerance: remainingTolerance
                            });
                        }
                    }
                }
            }
            return FaceSelection;
        }
        _registerToolKeyBinding(action, binding, tag) {
            this.tool.registerKeyBinding(action, binding, {
                uniqueId: `editor:ExtrudeToolKeyBinding:${tag}`,
                label: `resourcePack.editor.toolRail.ExtrudeTool.keyBinding.${tag}`
            });
        }
        _clearState() {
            this.widget?.delete();
            this.widget = undefined;
            this.preview.clearVolume();
            this.selectStack.clear();
        }
        _addBlockLocationToTransaction(blockLocation) {
            if (this.hasOpenedTransaction && !this.trackList.has(lib.Vector3Utils.toString(blockLocation))) {
                this.trackList.set(lib.Vector3Utils.toString(blockLocation), blockLocation);
                this.uiSession.extensionContext.transactionManager.trackBlockChangeList([ blockLocation ]);
            }
        }
        _getNewSelectionChanges(previousSelection, newSelection) {
            const selectionArray = [];
            newSelection.forEach((value => {
                if (!previousSelection.contains(value)) {
                    selectionArray.push(value);
                }
            }));
            return selectionArray;
        }
        _getOldSelectionChanges(previousSelection, newSelection) {
            const selectionArray = [];
            previousSelection.forEach((value => {
                if (!newSelection.contains(value)) {
                    selectionArray.push(value);
                }
            }));
            return selectionArray;
        }
        _copySelectionMap(destinationMap, sourceMap) {
            destinationMap.clear();
            sourceMap.forEach((value => {
                destinationMap.add(value);
            }));
        }
        _appendSelectionMap(destinationMap, sourceMap) {
            sourceMap.forEach((value => {
                destinationMap.add(value);
            }));
        }
        _SelectionMapToVolume(sourceMap) {
            const volume = new server_editor_namespaceObject.RelativeVolumeListBlockVolume;
            sourceMap.forEach((value => {
                volume.add(value);
            }));
            return volume;
        }
        _addSelectionChangesToTransaction() {
            if (this.widget !== undefined) {
                const differenceInNewSelection = this._getNewSelectionChanges(this.previousSelection, this.selectStack);
                const differenceInOldSelection = this._getOldSelectionChanges(this.previousSelection, this.selectStack);
                let selectionTransactionSuccessful = true;
                try {
                    const transactionPayload = {
                        differenceInOldSelection,
                        oldAnchorPosition: this.previousAnchorPosition,
                        oldWidgetPosition: this.previousWidgetPosition
                    };
                    this.oldSelectionTransactionHandler.addUserDefinedOperation(transactionPayload, "Extruder Previous Selection Data");
                } catch (e) {
                    selectionTransactionSuccessful = false;
                    this.uiSession.log.error(`Error adding selection to transaction: ${e.message}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
                try {
                    const transactionPayload = {
                        differenceInNewSelection,
                        newAnchorPosition: this.anchorPreviewLocation,
                        newWidgetPosition: this.widget.location
                    };
                    this.newSelectionTransactionHandler.addUserDefinedOperation(transactionPayload, "Extruder Current Selection Data");
                } catch (e) {
                    selectionTransactionSuccessful = false;
                    this.uiSession.log.error(`Error adding selection to transaction: ${e.message}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
                if (selectionTransactionSuccessful && this.widget !== undefined) {
                    this.previousAnchorPosition = this.anchorPreviewLocation;
                    this._copySelectionMap(this.previousSelection, this.selectStack);
                    this.previousWidgetPosition = this.widget.location;
                }
            }
        }
        _loadSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(ExtrudeTool_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const storeItem = group.fetchItem(ExtrudeTool_PERSISTENCE_GROUPITEM_NAME);
                if (storeItem && storeItem.value) {
                    try {
                        const storedSettings = storeItem.value;
                        this.faceSize.set(storedSettings.faceSize);
                        this.contiguousSelectionType.set(storedSettings.contiguousSelection);
                        this.layerCount.set(storedSettings.layerCount);
                        this.hasAdjacentBlocks.set(storedSettings.hasAdjacentBlocks);
                        this.quickExtrudeMode.set(storedSettings.mode);
                        if (storedSettings.contiguousSelectionBlockList) {
                            this.contiguousSelectionBlockList = storedSettings.contiguousSelectionBlockList;
                        }
                    } catch (error) {
                        this.uiSession.log.error("Fail to load the settings, error: " + stringFromException(error));
                    }
                }
                group.dispose();
            }
        }
        _saveSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(ExtrudeTool_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const settings = {
                    faceSize: this.faceSize.value,
                    contiguousSelection: this.contiguousSelectionType.value,
                    layerCount: this.layerCount.value,
                    hasAdjacentBlocks: this.hasAdjacentBlocks.value,
                    mode: this.quickExtrudeMode.value
                };
                if (this.contiguousSelectionBlockList.length > 0) {
                    settings.contiguousSelectionBlockList = this.contiguousSelectionBlockList;
                }
                const storeItem = group.getOrCreateItem(ExtrudeTool_PERSISTENCE_GROUPITEM_NAME, settings);
                if (storeItem) {
                    storeItem.commit();
                }
                group.dispose();
                return;
            }
            this.uiSession.log.error("Fail to save settings for Extrude");
        }
    }
    ExtrudeTool.BEHAVIOR_NAME = "Extrude Tool";
    ExtrudeTool.MODAL_TOOL_ID = "editor:modalTool:extrude";
    ExtrudeTool.ENABLE_VISUALIZATION = true;
    ExtrudeTool.MIN_FACE_SIZE = 1;
    ExtrudeTool.MAX_FACE_SIZE = 32;
    ExtrudeTool.MIN_LAYERS = 1;
    ExtrudeTool.MAX_LAYERS = 16;
    ExtrudeTool.MIN_RADIUS = 1;
    ExtrudeTool.MAX_RADIUS = 100;
    ExtrudeTool.MIN_SAMPLES = 1;
    ExtrudeTool.MAX_SAMPLES = 16;
    ExtrudeTool.MIN_TOLERANCE = 1;
    ExtrudeTool.MAX_TOLERANCE = 16;
    ExtrudeTool.TICK_REFRESH_RATE = 5;
    const RepeaterTool_PERSISTENCE_GROUP_NAME = "editor:repeater";
    const RepeaterTool_PERSISTENCE_GROUPITEM_NAME = "repeater_settings";
    var RepeaterTelemetry;
    (function(RepeaterTelemetry) {
        RepeaterTelemetry["Repeat"] = "Repeat";
        RepeaterTelemetry["Line"] = "Line";
        RepeaterTelemetry["Grid"] = "Grid";
        RepeaterTelemetry["Uniform"] = "Uniform";
        RepeaterTelemetry["Separate"] = "Separate";
    })(RepeaterTelemetry || (RepeaterTelemetry = {}));
    var ToolMode;
    (function(ToolMode) {
        ToolMode[ToolMode["Line"] = 0] = "Line";
        ToolMode[ToolMode["Grid"] = 1] = "Grid";
    })(ToolMode || (ToolMode = {}));
    var GridRepeatType;
    (function(GridRepeatType) {
        GridRepeatType[GridRepeatType["Uniform"] = 0] = "Uniform";
        GridRepeatType[GridRepeatType["Separate"] = 1] = "Separate";
    })(GridRepeatType || (GridRepeatType = {}));
    const toolModeValues = [ {
        label: "resourcePack.editor.toolRail.RepeaterTool.mode.Line",
        value: ToolMode.Line
    }, {
        label: "resourcePack.editor.toolRail.RepeaterTool.mode.Grid",
        value: ToolMode.Grid
    } ];
    const gridRepeatValues = [ {
        label: "resourcePack.editor.toolRail.RepeaterTool.repeat.Uniform",
        value: GridRepeatType.Uniform
    }, {
        label: "resourcePack.editor.toolRail.RepeaterTool.repeat.Separate",
        value: GridRepeatType.Separate
    } ];
    class RepeaterTool {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this.isActiveTool = false;
            this.spacing = (0, server_editor_namespaceObject.makeObservable)({
                x: 1,
                y: 1,
                z: 1
            });
            this.statusMessage = (0, server_editor_namespaceObject.makeObservable)("");
            this.toolMode = (0, server_editor_namespaceObject.makeObservable)(ToolMode.Line);
            this.lineRepetitions = (0, server_editor_namespaceObject.makeObservable)(RepeaterTool.DEFAULT_REPETITIONS);
            this.gridRepeatType = (0, server_editor_namespaceObject.makeObservable)(GridRepeatType.Uniform);
            this.gridUniformRepetitions = (0, server_editor_namespaceObject.makeObservable)(RepeaterTool.DEFAULT_REPETITIONS);
            this.gridUniformRepeatX = (0, server_editor_namespaceObject.makeObservable)(true);
            this.gridUniformRepeatY = (0, server_editor_namespaceObject.makeObservable)(true);
            this.gridUniformRepeatZ = (0, server_editor_namespaceObject.makeObservable)(true);
            this.gridSeparateRepetitionsX = (0, server_editor_namespaceObject.makeObservable)(RepeaterTool.DEFAULT_REPETITIONS);
            this.gridSeparateRepetitionsY = (0, server_editor_namespaceObject.makeObservable)(RepeaterTool.DEFAULT_REPETITIONS);
            this.gridSeparateRepetitionsZ = (0, server_editor_namespaceObject.makeObservable)(RepeaterTool.DEFAULT_REPETITIONS);
            this.session = uiSession;
            this._persistenceManager = getPersistenceManager(uiSession.extensionContext.player);
            uiSession.log.debug(`Initializing ${RepeaterTool.BEHAVIOR_NAME}`);
            this.telemetryManager = new TelemetryManager(uiSession.extensionContext.player, TelemetrySource.Repeater);
            this.visualizationWidgets = uiSession.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.Multiple,
                visible: true
            });
            this._loadSettings();
            this.tool = this.createTool(uiSession);
            this.rootToolPane = this._createRootToolPane(uiSession);
            this._showHidePanes();
            this._queueVisualizationRedraw(uiSession);
            this.tool.bindPropertyPane(this.rootToolPane);
        }
        createTool(uiSession) {
            const toolToggleAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    uiSession.toolRail.setSelectedToolId(tool.id);
                }
            });
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, toolToggleAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_R,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editorCore:repeater:toggleTool",
                label: "resourcePack.editor.toolRail.RepeaterTool.keyBinding.toggleTool.title",
                tooltip: "resourcePack.editor.toolRail.RepeaterTool.keyBinding.toggleTool.tooltip"
            });
            const tool = uiSession.toolRail.addTool("editor:modalTool:repeater", {
                title: "resourcePack.editor.toolRail.RepeaterTool.title",
                icon: "pack://textures/editor/Repeater.png?filtering=point",
                tooltip: {
                    description: "resourcePack.editor.toolRail.RepeaterTool.tooltip",
                    image: "pack://textures/editor/Repeater.gif"
                },
                action: toolToggleAction
            });
            tool.onModalToolActivation.subscribe((data => {
                this.isActiveTool = data.isActiveTool;
                if (data.isActiveTool) {
                    this._recalculateSpacing(uiSession);
                    this._queueVisualizationRedraw(uiSession);
                } else {
                    this._clearVisualization();
                }
            }));
            this.selectionChangeEventSubscriptionHandle = uiSession.extensionContext.afterEvents.SelectionChange.subscribe((() => this._redrawVisualization(this.session)));
            return tool;
        }
        _clearVisualization() {
            if (this.widget) {
                this.visualizationWidgets.deleteWidget(this.widget);
                this.widget = undefined;
            }
        }
        _recalculateSpacing(uiSession) {
            if (uiSession.extensionContext.selectionManager.volume.isEmpty) {
                this.spacing.set({
                    x: 1,
                    y: 1,
                    z: 1
                });
                return;
            }
            const selectionBounds = uiSession.extensionContext.selectionManager.volume.getBoundingBox();
            const startCoordinate = selectionBounds.min;
            const endCoordinate = selectionBounds.max;
            const boundingBoxDimensions = lib.Vector3Utils.subtract(endCoordinate, startCoordinate);
            this.spacing.set(lib.Vector3Utils.add(boundingBoxDimensions, {
                x: 1,
                y: 1,
                z: 1
            }));
        }
        _queueVisualizationRedraw(uiSession) {
            if (!this.queueVisualizationsRedrawHandle) {
                this.queueVisualizationsRedrawHandle = server_namespaceObject.system.runTimeout((() => {
                    this._redrawVisualization(uiSession);
                }), RepeaterTool.REDRAW_BATCH_DELAY);
            }
        }
        _redrawVisualization(uiSession) {
            if (this.queueVisualizationsRedrawHandle) {
                this.queueVisualizationsRedrawHandle = undefined;
            }
            if (uiSession.extensionContext.selectionManager.volume.isEmpty) {
                this._clearVisualization();
                if (this.statusMessagePane) {
                    this.statusMessage.set({
                        id: "resourcePack.editor.toolRail.RepeaterTool.statusMessage.noSelection"
                    });
                    this.statusMessagePane.visible = true;
                }
                return;
            }
            if (!this.isActiveTool) {
                return;
            }
            if (this.statusMessagePane) {
                this.statusMessagePane.visible = false;
            }
            this._clearVisualization();
            if (this.spacing.value.x === 0 && this.spacing.value.y === 0 && this.spacing.value.z === 0 || this.toolMode.value === ToolMode.Grid && (this.gridRepeatType.value === GridRepeatType.Separate && this.gridSeparateRepetitionsX.value === 0 && this.gridSeparateRepetitionsY.value === 0 && this.gridSeparateRepetitionsZ.value === 0 || this.gridRepeatType.value === GridRepeatType.Uniform && !this.gridUniformRepeatX.value && !this.gridUniformRepeatY.value && !this.gridUniformRepeatZ.value)) {
                return;
            }
            const startCoordinate = uiSession.extensionContext.selectionManager.volume.getBoundingBox().min;
            const shapeOffset = this._getSelectionOffset(uiSession);
            const visualizationStart = lib.Vector3Utils.add(startCoordinate, shapeOffset);
            const clipboardItem = this._getClipboardItemFromSelection(uiSession);
            const widget = this.visualizationWidgets.createWidget(visualizationStart, {});
            try {
                if (this.toolMode.value === ToolMode.Line) {
                    this._addLineVisualizationToWidget(uiSession, widget, clipboardItem);
                } else if (this.toolMode.value === ToolMode.Grid) {
                    this._addGridVisualizationToWidget(uiSession, widget, clipboardItem);
                }
            } catch (error) {
                this.uiSession.log.error(`Error while adding repetitions: ${error.message}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            } finally {
                this.widget = widget;
            }
        }
        _addLineVisualizationToWidget(uiSession, widget, clipboardItem) {
            let errorMessage;
            for (let i = 0; i < this.lineRepetitions.value; i++) {
                const offset = {
                    x: this.spacing.value.x * (i + 1),
                    y: this.spacing.value.y * (i + 1),
                    z: this.spacing.value.z * (i + 1)
                };
                try {
                    widget.addClipboardComponent(`Visualization-${i}`, clipboardItem, {
                        showOutline: true,
                        offset
                    });
                } catch (error) {
                    errorMessage = error.message;
                }
            }
            if (errorMessage) {
                this.uiSession.log.error(`Error while adding repetitions: ${errorMessage}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
        }
        _addGridVisualizationToWidget(uiSession, widget, clipboardItem) {
            let errorMessage;
            let xCount = 0, yCount = 0, zCount = 0;
            if (this.gridRepeatType.value === GridRepeatType.Uniform) {
                if (this.gridUniformRepeatX.value) {
                    xCount = this.gridUniformRepetitions.value;
                }
                if (this.gridUniformRepeatY.value) {
                    yCount = this.gridUniformRepetitions.value;
                }
                if (this.gridUniformRepeatZ.value) {
                    zCount = this.gridUniformRepetitions.value;
                }
            } else if (this.gridRepeatType.value === GridRepeatType.Separate) {
                xCount = this.gridSeparateRepetitionsX.value;
                yCount = this.gridSeparateRepetitionsY.value;
                zCount = this.gridSeparateRepetitionsZ.value;
            }
            if (!this._checkIfSeparateRepetitionsExceedMax()) {
                for (let xi = 0; xi < xCount + 1; xi++) {
                    for (let yi = 0; yi < yCount + 1; yi++) {
                        for (let zi = 0; zi < zCount + 1; zi++) {
                            const offset = {
                                x: this.spacing.value.x * xi,
                                y: this.spacing.value.y * yi,
                                z: this.spacing.value.z * zi
                            };
                            if (offset.x !== 0 || offset.y !== 0 || offset.z !== 0) {
                                try {
                                    widget.addClipboardComponent(`Visualization-${xi}-${yi}-${zi}`, clipboardItem, {
                                        showOutline: true,
                                        offset
                                    });
                                } catch (error) {
                                    errorMessage = error.message;
                                }
                            }
                        }
                    }
                }
            }
            if (errorMessage) {
                this.uiSession.log.error(`Error while adding repetitions: ${errorMessage}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
        }
        _getClipboardItemFromSelection(uiSession) {
            const selectionVolume = uiSession.extensionContext.selectionManager.volume.get();
            const clipboardItem = uiSession.extensionContext.clipboardManager.create();
            clipboardItem.readFromWorld(selectionVolume);
            return clipboardItem;
        }
        _buildTelemetryEventDataFromState() {
            if (this.toolMode.value === ToolMode.Line) {
                return {
                    [RepeaterTelemetry.Repeat]: {
                        [RepeaterTelemetry.Line]: {
                            repetitions: this.lineRepetitions.value,
                            spacing: this.spacing.value
                        }
                    }
                };
            } else if (this.toolMode.value === ToolMode.Grid) {
                if (this.gridRepeatType.value === GridRepeatType.Uniform) {
                    return {
                        [RepeaterTelemetry.Repeat]: {
                            [RepeaterTelemetry.Grid]: {
                                [RepeaterTelemetry.Uniform]: {
                                    repetitions: this.lineRepetitions.value,
                                    spacing: this.spacing.value,
                                    repeatX: this.gridUniformRepeatX.value,
                                    repeatY: this.gridUniformRepeatY.value,
                                    repeatZ: this.gridUniformRepeatZ.value
                                }
                            }
                        }
                    };
                } else if (this.gridRepeatType.value === GridRepeatType.Separate) {
                    return {
                        [RepeaterTelemetry.Repeat]: {
                            [RepeaterTelemetry.Grid]: {
                                [RepeaterTelemetry.Separate]: {
                                    spacing: this.spacing.value,
                                    repetitionsX: this.gridSeparateRepetitionsX.value,
                                    repetitionsY: this.gridSeparateRepetitionsY.value,
                                    repetitionsZ: this.gridSeparateRepetitionsZ.value
                                }
                            }
                        }
                    };
                }
            }
        }
        async _applyRepetition(uiSession) {
            if (!this.widget) {
                return;
            }
            const telemetryEventData = this._buildTelemetryEventDataFromState();
            if (telemetryEventData) {
                this.telemetryManager.fireTelemetryEvent(RepeaterTelemetry.Repeat, telemetryEventData[RepeaterTelemetry.Repeat]);
            }
            uiSession.extensionContext.transactionManager.openTransaction("Repeater Tool");
            const clipboardItem = this._getClipboardItemFromSelection(uiSession);
            const shapeOffset = this._getSelectionOffset(uiSession);
            let mostMinimalPos = {
                x: Number.MAX_SAFE_INTEGER,
                y: Number.MAX_SAFE_INTEGER,
                z: Number.MAX_SAFE_INTEGER
            };
            let mostMaximalPos = {
                x: Number.MIN_SAFE_INTEGER,
                y: Number.MIN_SAFE_INTEGER,
                z: Number.MIN_SAFE_INTEGER
            };
            for (const comp of this.widget.getComponents()) {
                const writeLocation = lib.Vector3Utils.subtract(comp.location, shapeOffset);
                const box = clipboardItem.getPredictedWriteVolume(writeLocation).getBoundingBox();
                mostMinimalPos = {
                    x: box.min.x < mostMinimalPos.x ? box.min.x : mostMinimalPos.x,
                    y: box.min.y < mostMinimalPos.y ? box.min.y : mostMinimalPos.y,
                    z: box.min.z < mostMinimalPos.z ? box.min.z : mostMinimalPos.z
                };
                mostMaximalPos = {
                    x: box.max.x > mostMaximalPos.x ? box.max.x : mostMaximalPos.x,
                    y: box.max.y > mostMaximalPos.y ? box.max.y : mostMaximalPos.y,
                    z: box.max.z > mostMaximalPos.z ? box.max.z : mostMaximalPos.z
                };
            }
            const volume = new server_namespaceObject.BlockVolume(mostMinimalPos, mostMaximalPos);
            await executeTickSafeOperation(uiSession.extensionContext, uiSession.log, volume.getBoundingBox(), (() => {
                if (this.widget) {
                    for (const comp of this.widget.getComponents()) {
                        const writeLocation = lib.Vector3Utils.subtract(comp.location, shapeOffset);
                        clipboardItem.writeToWorld(writeLocation);
                    }
                }
            }));
            uiSession.extensionContext.transactionManager.commitOpenTransaction();
            this._clearVisualization();
        }
        _getSelectionOffset(uiSession) {
            if (uiSession.extensionContext.selectionManager.volume.isEmpty) {
                return {
                    x: 0,
                    y: 0,
                    z: 0
                };
            }
            const startCoordinate = uiSession.extensionContext.selectionManager.volume.getBoundingBox().min;
            const endCoordinate = uiSession.extensionContext.selectionManager.volume.getBoundingBox().max;
            let shapeOffset = lib.Vector3Utils.subtract(endCoordinate, startCoordinate);
            shapeOffset = lib.Vector3Utils.scale(shapeOffset, .5);
            shapeOffset = {
                x: Math.ceil(shapeOffset.x),
                y: Math.ceil(shapeOffset.y),
                z: Math.ceil(shapeOffset.z)
            };
            return shapeOffset;
        }
        _createRootToolPane(uiSession) {
            const pane = uiSession.createPropertyPane({
                title: "resourcePack.editor.toolRail.RepeaterTool.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.toolRail.repeaterTool.tooltip", {
                        link: "https://aka.ms/BedrockEditorRepeaterTool",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this.statusMessagePane = pane.addText(this.statusMessage);
            this.commonPane = this._createCommonSubPane(uiSession, pane);
            this.linePane = this._createLineSubPane(uiSession, pane);
            this.gridPane = this._createGridSubPane(uiSession, pane);
            const applyAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => this._applyRepetition(uiSession)
            });
            pane.addButton(applyAction, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.Apply",
                visible: true
            });
            return pane;
        }
        _createCommonSubPane(uiSession, parentPane) {
            const pane = parentPane.createSubPane({
                hasExpander: false
            });
            pane.beginConstruct();
            pane.addDropdown(this.toolMode, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.Mode",
                tooltip: "resourcePack.editor.toolRail.RepeaterTool.pane.Mode.tooltip",
                entries: toolModeValues,
                onChange: () => {
                    this._showHidePanes();
                    this._queueVisualizationRedraw(uiSession);
                    this._saveSettings();
                }
            });
            pane.addVector3(this.spacing, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.Spacing",
                tooltip: "resourcePack.editor.toolRail.RepeaterTool.pane.Spacing.tooltip",
                isInteger: true,
                onChange: () => {
                    this._queueVisualizationRedraw(uiSession);
                    this._saveSettings();
                }
            });
            pane.endConstruct();
            return pane;
        }
        _createLineSubPane(uiSession, parentPane) {
            const pane = parentPane.createSubPane({
                hasExpander: false
            });
            pane.beginConstruct();
            pane.addNumber(this.lineRepetitions, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.Repetitions",
                tooltip: "resourcePack.editor.toolRail.RepeaterTool.pane.Repetitions.tooltip",
                min: RepeaterTool.DEFAULT_MIN_REPETITIONS,
                max: RepeaterTool.DEFAULT_MAX_REPETITIONS,
                isInteger: true,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: () => {
                    this._queueVisualizationRedraw(uiSession);
                    this._saveSettings();
                }
            });
            pane.endConstruct();
            return pane;
        }
        _createGridSubPane(uiSession, parentPane) {
            const pane = parentPane.createSubPane({
                hasExpander: false
            });
            pane.addDropdown(this.gridRepeatType, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.RepeatType",
                entries: gridRepeatValues,
                onChange: () => {
                    this._showHidePanes();
                    this._queueVisualizationRedraw(uiSession);
                    this._saveSettings();
                }
            });
            this.gridUniformSubPane = this._createGridUniformSubPane(uiSession, pane);
            this.gridSeparateSubPane = this._createGridSeparateSubPane(uiSession, pane);
            return pane;
        }
        _createGridUniformSubPane(uiSession, parentPane) {
            const pane = parentPane.createSubPane({
                hasExpander: false
            });
            pane.beginConstruct();
            this.gridUniformRepetitionsUIElement = pane.addNumber(this.gridUniformRepetitions, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.Repetitions",
                min: RepeaterTool.DEFAULT_MIN_REPETITIONS,
                max: RepeaterTool.DEFAULT_MAX_REPETITIONS,
                isInteger: true,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: (_, oldValue) => {
                    if (this._checkIfSeparateRepetitionsExceedMax()) {
                        this.gridUniformRepetitions.set(oldValue);
                    } else {
                        this._queueVisualizationRedraw(uiSession);
                    }
                    this._saveSettings();
                }
            });
            pane.addBool(this.gridUniformRepeatX, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.RepeatAlongX",
                onChange: (_, oldValue) => {
                    if (this._checkIfSeparateRepetitionsExceedMax()) {
                        this.gridUniformRepeatX.set(oldValue);
                    } else {
                        this._updateGridUniformLimit();
                        this._queueVisualizationRedraw(uiSession);
                    }
                    this._saveSettings();
                }
            });
            pane.addBool(this.gridUniformRepeatY, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.RepeatAlongY",
                onChange: (_, oldValue) => {
                    if (this._checkIfSeparateRepetitionsExceedMax()) {
                        this.gridUniformRepeatY.set(oldValue);
                    } else {
                        this._updateGridUniformLimit();
                        this._queueVisualizationRedraw(uiSession);
                    }
                    this._saveSettings();
                }
            });
            pane.addBool(this.gridUniformRepeatZ, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.RepeatAlongZ",
                onChange: (_, oldValue) => {
                    if (this._checkIfSeparateRepetitionsExceedMax()) {
                        this.gridUniformRepeatZ.set(oldValue);
                    } else {
                        this._updateGridUniformLimit();
                        this._queueVisualizationRedraw(uiSession);
                    }
                    this._saveSettings();
                }
            });
            pane.endConstruct();
            this._updateGridUniformLimit();
            return pane;
        }
        _updateGridUniformLimit() {
            let repeatCount = 0;
            if (this.gridUniformRepeatX.value) {
                repeatCount++;
            }
            if (this.gridUniformRepeatY.value) {
                repeatCount++;
            }
            if (this.gridUniformRepeatZ.value) {
                repeatCount++;
            }
            let newMax = RepeaterTool.DEFAULT_MAX_REPETITIONS;
            if (repeatCount === 3) {
                newMax = RepeaterTool.CUBE_ROOT_OF_MAX_WIDGETS;
            } else if (repeatCount === 2) {
                newMax = RepeaterTool.SQUARE_ROOT_OF_MAX_WIDGETS;
            }
            this.gridUniformRepetitionsUIElement?.updateLimits({
                min: RepeaterTool.DEFAULT_MIN_REPETITIONS,
                max: newMax
            });
        }
        _createGridSeparateSubPane(uiSession, parentPane) {
            const pane = parentPane.createSubPane({
                hasExpander: false
            });
            pane.beginConstruct();
            this.gridSeparateRepetitionsXUIElement = pane.addNumber(this.gridSeparateRepetitionsX, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.XCount",
                min: RepeaterTool.DEFAULT_MIN_SEPARATE_REPETITIONS,
                max: RepeaterTool.DEFAULT_MAX_REPETITIONS,
                isInteger: true,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: (_, oldValue) => {
                    if (this._checkIfSeparateRepetitionsExceedMax()) {
                        this.gridSeparateRepetitionsX.set(oldValue);
                    } else {
                        this._updateGridSeparateLimits(server_editor_namespaceObject.Axis.X);
                        this._queueVisualizationRedraw(uiSession);
                    }
                    this._saveSettings();
                }
            });
            this.gridSeparateRepetitionsYUIElement = pane.addNumber(this.gridSeparateRepetitionsY, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.YCount",
                min: RepeaterTool.DEFAULT_MIN_SEPARATE_REPETITIONS,
                max: RepeaterTool.DEFAULT_MAX_REPETITIONS,
                isInteger: true,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: (_, oldValue) => {
                    if (this._checkIfSeparateRepetitionsExceedMax()) {
                        this.gridSeparateRepetitionsY.set(oldValue);
                    } else {
                        this._updateGridSeparateLimits(server_editor_namespaceObject.Axis.Y);
                        this._queueVisualizationRedraw(uiSession);
                    }
                    this._saveSettings();
                }
            });
            this.gridSeparateRepetitionsZUIElement = pane.addNumber(this.gridSeparateRepetitionsZ, {
                title: "resourcePack.editor.toolRail.RepeaterTool.pane.ZCount",
                min: RepeaterTool.DEFAULT_MIN_SEPARATE_REPETITIONS,
                max: RepeaterTool.DEFAULT_MAX_REPETITIONS,
                isInteger: true,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: (_, oldValue) => {
                    if (this._checkIfSeparateRepetitionsExceedMax()) {
                        this.gridSeparateRepetitionsZ.set(oldValue);
                    } else {
                        this._updateGridSeparateLimits(server_editor_namespaceObject.Axis.Z);
                        this._queueVisualizationRedraw(uiSession);
                    }
                    this._saveSettings();
                }
            });
            pane.endConstruct();
            this._updateGridSeparateLimits(server_editor_namespaceObject.Axis.X);
            this._updateGridSeparateLimits(server_editor_namespaceObject.Axis.Y);
            return pane;
        }
        _updateGridSeparateLimits(axisChanged) {
            const currentX = this.gridSeparateRepetitionsX.value + 1;
            const currentY = this.gridSeparateRepetitionsY.value + 1;
            const currentZ = this.gridSeparateRepetitionsZ.value + 1;
            const currentMaxUsed = currentX * currentY * currentZ;
            const currentRoom = RepeaterTool.MAX_WIDGETS - currentMaxUsed;
            if (axisChanged !== server_editor_namespaceObject.Axis.X) {
                let newMaxX = currentX + Math.floor(currentRoom / (currentY * currentZ)) - 1;
                if (newMaxX <= 0) {
                    newMaxX = 1;
                    if (this.gridSeparateRepetitionsXUIElement) {
                        this.gridSeparateRepetitionsXUIElement.enable = false;
                    }
                } else {
                    if (this.gridSeparateRepetitionsXUIElement) {
                        this.gridSeparateRepetitionsXUIElement.enable = true;
                    }
                }
                this.gridSeparateRepetitionsXUIElement?.updateLimits({
                    min: RepeaterTool.DEFAULT_MIN_SEPARATE_REPETITIONS,
                    max: newMaxX
                });
            }
            if (axisChanged !== server_editor_namespaceObject.Axis.Y) {
                let newMaxY = currentY + Math.floor(currentRoom / (currentX * currentZ)) - 1;
                if (newMaxY <= 0) {
                    newMaxY = 1;
                    if (this.gridSeparateRepetitionsYUIElement) {
                        this.gridSeparateRepetitionsYUIElement.enable = false;
                    }
                } else {
                    if (this.gridSeparateRepetitionsYUIElement) {
                        this.gridSeparateRepetitionsYUIElement.enable = true;
                    }
                }
                this.gridSeparateRepetitionsYUIElement?.updateLimits({
                    min: RepeaterTool.DEFAULT_MIN_SEPARATE_REPETITIONS,
                    max: newMaxY
                });
            }
            if (axisChanged !== server_editor_namespaceObject.Axis.Z) {
                let newMaxZ = currentZ + Math.floor(currentRoom / (currentX * currentY)) - 1;
                if (newMaxZ <= 0) {
                    newMaxZ = 1;
                    if (this.gridSeparateRepetitionsZUIElement) {
                        this.gridSeparateRepetitionsZUIElement.enable = false;
                    }
                } else {
                    if (this.gridSeparateRepetitionsZUIElement) {
                        this.gridSeparateRepetitionsZUIElement.enable = true;
                    }
                }
                this.gridSeparateRepetitionsZUIElement?.updateLimits({
                    min: RepeaterTool.DEFAULT_MIN_SEPARATE_REPETITIONS,
                    max: newMaxZ
                });
            }
        }
        _calculateSeparateRepetitions() {
            let separateRepetitions = 0;
            if (this.toolMode.value === ToolMode.Grid) {
                if (this.gridRepeatType.value === GridRepeatType.Uniform) {
                    separateRepetitions = this.gridUniformRepetitions.value * (this.gridUniformRepeatX.value ? 1 : 0) * this.gridUniformRepetitions.value * (this.gridUniformRepeatY.value ? 1 : 0) * this.gridUniformRepetitions.value * (this.gridUniformRepeatZ.value ? 1 : 0);
                } else if (this.gridRepeatType.value === GridRepeatType.Separate) {
                    if (this.gridSeparateRepetitionsX.value > 0 || this.gridSeparateRepetitionsY.value > 0 || this.gridSeparateRepetitionsZ.value > 0) separateRepetitions = (this.gridSeparateRepetitionsX.value + 1) * (this.gridSeparateRepetitionsY.value + 1) * (this.gridSeparateRepetitionsZ.value + 1);
                }
            }
            return separateRepetitions;
        }
        _checkIfSeparateRepetitionsExceedMax() {
            if (this.toolMode.value === ToolMode.Grid) {
                const totalRepetitions = this._calculateSeparateRepetitions();
                if (totalRepetitions > RepeaterTool.MAX_WIDGETS) {
                    this.uiSession.log.error(`RepeaterTool: Total repetitions (${totalRepetitions}) exceeded threshold of ${RepeaterTool.MAX_WIDGETS}.`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    return true;
                }
            }
            return false;
        }
        _showHidePanes() {
            if (this.toolMode.value === ToolMode.Line) {
                this.rootToolPane.toggleSubPaneVisibility(this.linePane?.id);
            } else if (this.toolMode.value === ToolMode.Grid) {
                this.rootToolPane.toggleSubPaneVisibility(this.gridPane?.id);
                if (this.gridRepeatType.value === GridRepeatType.Uniform) {
                    this.gridPane?.toggleSubPaneVisibility(this.gridUniformSubPane?.id);
                } else if (this.gridRepeatType.value === GridRepeatType.Separate) {
                    this.gridPane?.toggleSubPaneVisibility(this.gridSeparateSubPane?.id);
                }
            }
            this.commonPane?.show();
        }
        _loadSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(RepeaterTool_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const storeItem = group.fetchItem(RepeaterTool_PERSISTENCE_GROUPITEM_NAME);
                if (storeItem && storeItem.value) {
                    try {
                        const storedSettings = storeItem.value;
                        if (storedSettings.mode !== undefined) {
                            this.toolMode.set(storedSettings.mode);
                        }
                        if (storedSettings.gridRepeatType !== undefined) {
                            this.gridRepeatType.set(storedSettings.gridRepeatType);
                        }
                        if (storedSettings.lineRepetitions !== undefined) {
                            this.lineRepetitions.set(storedSettings.lineRepetitions);
                        }
                        if (storedSettings.gridUniformRepetitions !== undefined) {
                            this.gridUniformRepetitions.set(storedSettings.gridUniformRepetitions);
                        }
                        if (storedSettings.gridUniformRepeatX !== undefined) {
                            this.gridUniformRepeatX.set(storedSettings.gridUniformRepeatX);
                        }
                        if (storedSettings.gridUniformRepeatY !== undefined) {
                            this.gridUniformRepeatY.set(storedSettings.gridUniformRepeatY);
                        }
                        if (storedSettings.gridUniformRepeatZ !== undefined) {
                            this.gridUniformRepeatZ.set(storedSettings.gridUniformRepeatZ);
                        }
                        if (storedSettings.gridSeparateRepetitionsX !== undefined) {
                            this.gridSeparateRepetitionsX.set(storedSettings.gridSeparateRepetitionsX);
                        }
                        if (storedSettings.gridSeparateRepetitionsY !== undefined) {
                            this.gridSeparateRepetitionsY.set(storedSettings.gridSeparateRepetitionsY);
                        }
                        if (storedSettings.gridSeparateRepetitionsZ !== undefined) {
                            this.gridSeparateRepetitionsZ.set(storedSettings.gridSeparateRepetitionsZ);
                        }
                    } catch (error) {
                        this.uiSession.log.error("Fail to load the settings, error: " + stringFromException(error));
                    }
                }
                group.dispose();
            }
        }
        _saveSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(RepeaterTool_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const settings = {
                    mode: this.toolMode.value,
                    lineRepetitions: this.lineRepetitions.value,
                    gridRepeatType: this.gridRepeatType.value,
                    gridUniformRepetitions: this.gridUniformRepetitions.value,
                    gridUniformRepeatX: this.gridUniformRepeatX.value,
                    gridUniformRepeatY: this.gridUniformRepeatY.value,
                    gridUniformRepeatZ: this.gridUniformRepeatZ.value,
                    gridSeparateRepetitionsX: this.gridSeparateRepetitionsX.value,
                    gridSeparateRepetitionsY: this.gridSeparateRepetitionsY.value,
                    gridSeparateRepetitionsZ: this.gridSeparateRepetitionsZ.value
                };
                const storeItem = group.getOrCreateItem(RepeaterTool_PERSISTENCE_GROUPITEM_NAME, settings);
                if (storeItem) {
                    storeItem.commit();
                }
                group.dispose();
                return;
            }
            this.uiSession.log.error("Fail to save settings for RepeaterTool");
        }
        teardown() {
            if (this.selectionChangeEventSubscriptionHandle) {
                this.session.extensionContext.afterEvents.SelectionChange.unsubscribe(this.selectionChangeEventSubscriptionHandle);
                this.selectionChangeEventSubscriptionHandle = undefined;
            }
            if (this.queueVisualizationsRedrawHandle) {
                server_namespaceObject.system.clearRun(this.queueVisualizationsRedrawHandle);
                this.queueVisualizationsRedrawHandle = undefined;
            }
            this._clearVisualization();
            this.uiSession.log.debug(`Shutting down ${RepeaterTool.BEHAVIOR_NAME}`);
        }
    }
    RepeaterTool.BEHAVIOR_NAME = "Repeat Tool";
    RepeaterTool.MAX_WIDGETS = 1e3;
    RepeaterTool.REDRAW_BATCH_DELAY = .5 * server_namespaceObject.TicksPerSecond;
    RepeaterTool.CUBE_ROOT_OF_MAX_WIDGETS = Math.floor(Math.cbrt(RepeaterTool.MAX_WIDGETS));
    RepeaterTool.SQUARE_ROOT_OF_MAX_WIDGETS = Math.floor(Math.sqrt(RepeaterTool.MAX_WIDGETS));
    RepeaterTool.DEFAULT_MIN_REPETITIONS = 1;
    RepeaterTool.DEFAULT_MAX_REPETITIONS = 100;
    RepeaterTool.DEFAULT_MIN_SEPARATE_REPETITIONS = 0;
    RepeaterTool.DEFAULT_REPETITIONS = 5;
    var FarmTelemetry;
    (function(FarmTelemetry) {
        FarmTelemetry["Place"] = "Place";
    })(FarmTelemetry || (FarmTelemetry = {}));
    const MinFarmWidth = 3;
    const MinFarmLength = 3;
    const MaxFarmWidth = 24;
    const MaxFarmLength = 24;
    const FarmGenerator_PERSISTENCE_GROUP_NAME = "editor:farmGenerator";
    const FarmGenerator_PERSISTENCE_GROUPITEM_NAME = "farm_generator_settings";
    class FarmGeneratorTool {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this._tool = this.addFarmGeneratorTool(uiSession);
            this._persistenceManager = getPersistenceManager(uiSession.extensionContext.player);
            this.telemetryManager = new TelemetryManager(uiSession.extensionContext.player, TelemetrySource.Farm);
            this._commonSettings = {
                farmWidth: (0, server_editor_namespaceObject.makeObservable)(10),
                farmLength: (0, server_editor_namespaceObject.makeObservable)(10),
                irrigation: (0, server_editor_namespaceObject.makeObservable)(false),
                fenceType: (0, server_editor_namespaceObject.makeObservable)(0)
            };
            this._cropSettings = {
                wheat: (0, server_editor_namespaceObject.makeObservable)(false),
                pumpkin: (0, server_editor_namespaceObject.makeObservable)(false),
                potato: (0, server_editor_namespaceObject.makeObservable)(false),
                carrot: (0, server_editor_namespaceObject.makeObservable)(false),
                beetroot: (0, server_editor_namespaceObject.makeObservable)(false)
            };
            this._animalSettings = {
                pig: (0, server_editor_namespaceObject.makeObservable)(false),
                sheep: (0, server_editor_namespaceObject.makeObservable)(false),
                cow: (0, server_editor_namespaceObject.makeObservable)(false)
            };
            this._cursorProperties = {
                outlineColor: {
                    red: 0,
                    green: .5,
                    blue: .5,
                    alpha: .2
                },
                controlMode: server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse,
                targetMode: server_editor_namespaceObject.CursorTargetMode.Face,
                visible: true,
                fixedModeDistance: 5
            };
            this.loadSettings();
            this.addFarmGeneratorSettingsPane(uiSession, this._tool);
            this._widgetGroup = uiSession.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.Single,
                visible: false
            });
            this._widget = this._widgetGroup.createWidget(this.uiSession.extensionContext.cursor.getPosition(), {
                snapToBlockLocation: true,
                visible: true,
                selectable: false,
                bindPositionToBlockCursor: true
            });
            this._widgetBoxComponent = this._widget.addBoundingBox("farmToolBoundingBox", {
                x: this._commonSettings.farmWidth.value,
                y: 2,
                z: this._commonSettings.farmLength.value
            }, {
                visible: true,
                showWorldIntersections: true,
                outlineColor: {
                    red: .64,
                    green: .35,
                    blue: .09,
                    alpha: .8
                },
                hullColor: {
                    red: .64,
                    green: .35,
                    blue: .09,
                    alpha: .2
                },
                limit: {
                    min: {
                        x: MinFarmWidth,
                        y: 2,
                        z: MinFarmLength
                    },
                    max: {
                        x: MaxFarmWidth,
                        y: 2,
                        z: MaxFarmLength
                    }
                },
                boundsOffset: {
                    x: (this._commonSettings.farmWidth.value - 1) / -2,
                    y: -1,
                    z: (this._commonSettings.farmLength.value - 1) / -2
                }
            });
        }
        teardown() {
            this._widget.deleteComponent(this._widgetBoxComponent);
            this._widget.delete();
            if (this._cursorModeControl?.isActive) {
                this._cursorModeControl.deactivateControl();
            }
            this._cursorModeControl?.shutdown();
        }
        addFarmGeneratorSettingsPane(uiSession, tool) {
            const windowPane = uiSession.createPropertyPane({
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.toolRail.FarmGenerator.tool.tooltip", {
                        link: "https://aka.ms/BedrockEditorFarmGenerator",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            const cursorControlHolderPane = windowPane.createSubPane({
                title: "Hidden Cursor Control Holder Pane",
                hasExpander: false
            });
            this._cursorModeControl = new CursorModeControl(uiSession, tool, cursorControlHolderPane, true, this._cursorProperties, {
                hasPaneMargins: false
            });
            this._cursorModeControl.initialize();
            const cropPane = windowPane.createSubPane({
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.crops.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.FarmGenerator.pane.crops.title",
                    description: [ "resourcePack.editor.toolRail.FarmGenerator.pane.crops.tooltip" ]
                }
            });
            const animalPane = windowPane.createSubPane({
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.animals.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.FarmGenerator.pane.animals.title",
                    description: [ "resourcePack.editor.toolRail.FarmGenerator.pane.animals.tooltip" ]
                }
            });
            const executeMouseAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton && mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown) {
                        this._onExecuteGenerator(mouseRay, uiSession);
                    }
                    this.saveSettings();
                }
            });
            tool.registerMouseButtonBinding(executeMouseAction);
            windowPane.addNumber(this._commonSettings.farmLength, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.length",
                tooltip: "resourcePack.editor.toolRail.FarmGenerator.pane.length.tooltip",
                min: MinFarmLength,
                max: MaxFarmLength,
                isInteger: true,
                onChange: () => {
                    this._widgetBoxComponent.size = {
                        x: this._commonSettings.farmWidth.value,
                        y: 2,
                        z: this._commonSettings.farmLength.value
                    };
                    this._widgetBoxComponent.boundsOffset = {
                        x: (this._commonSettings.farmWidth.value - 1) / -2,
                        y: -1,
                        z: (this._commonSettings.farmLength.value - 1) / -2
                    };
                }
            });
            windowPane.addNumber(this._commonSettings.farmWidth, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.width",
                tooltip: "resourcePack.editor.toolRail.FarmGenerator.pane.width.tooltip",
                min: MinFarmWidth,
                max: MaxFarmWidth,
                isInteger: true,
                onChange: () => {
                    this._widgetBoxComponent.size = {
                        x: this._commonSettings.farmWidth.value,
                        y: 2,
                        z: this._commonSettings.farmLength.value
                    };
                    this._widgetBoxComponent.boundsOffset = {
                        x: (this._commonSettings.farmWidth.value - 1) / -2,
                        y: -1,
                        z: (this._commonSettings.farmLength.value - 1) / -2
                    };
                    this.saveSettings();
                }
            });
            windowPane.addDropdown(this._commonSettings.fenceType, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.fence",
                tooltip: "resourcePack.editor.toolRail.FarmGenerator.pane.fence.tooltip",
                enable: true,
                entries: [ {
                    label: "resourcePack.editor.toolRail.FarmGenerator.pane.fence.oak",
                    value: 0
                }, {
                    label: "resourcePack.editor.toolRail.FarmGenerator.pane.fence.birch",
                    value: 1
                }, {
                    label: "resourcePack.editor.toolRail.FarmGenerator.pane.fence.acacia",
                    value: 2
                }, {
                    label: "resourcePack.editor.toolRail.FarmGenerator.pane.fence.bamboo",
                    value: 3
                }, {
                    label: "resourcePack.editor.toolRail.FarmGenerator.pane.fence.cherry",
                    value: 4
                }, {
                    label: "resourcePack.editor.toolRail.FarmGenerator.pane.fence.jungle",
                    value: 5
                }, {
                    label: "resourcePack.editor.toolRail.FarmGenerator.pane.fence.spruce",
                    value: 6
                }, {
                    label: "resourcePack.editor.toolRail.FarmGenerator.pane.fence.warped",
                    value: 7
                }, {
                    label: "resourcePack.editor.toolRail.FarmGenerator.pane.fence.crimson",
                    value: 8
                } ]
            });
            windowPane.addBool(this._commonSettings.irrigation, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.irrigation",
                tooltip: "resourcePack.editor.toolRail.FarmGenerator.pane.irrigation.tooltip",
                onChange: () => {
                    this.saveSettings();
                }
            });
            cropPane.addBool(this._cropSettings.wheat, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.crops.wheat",
                onChange: () => {
                    this.saveSettings();
                }
            });
            cropPane.addBool(this._cropSettings.potato, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.crops.potato",
                onChange: () => {
                    this.saveSettings();
                }
            });
            cropPane.addBool(this._cropSettings.beetroot, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.crops.beets",
                onChange: () => {
                    this.saveSettings();
                }
            });
            cropPane.addBool(this._cropSettings.pumpkin, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.crops.pumpkin",
                onChange: () => {
                    this.saveSettings();
                }
            });
            cropPane.addBool(this._cropSettings.carrot, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.crops.carrot",
                onChange: () => {
                    this.saveSettings();
                }
            });
            animalPane.addBool(this._animalSettings.cow, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.animals.cow",
                onChange: () => {
                    this.saveSettings();
                }
            });
            animalPane.addBool(this._animalSettings.sheep, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.animals.sheep",
                onChange: () => {
                    this.saveSettings();
                }
            });
            animalPane.addBool(this._animalSettings.pig, {
                title: "resourcePack.editor.toolRail.FarmGenerator.pane.animals.pig",
                onChange: () => {
                    this.saveSettings();
                }
            });
            tool.bindPropertyPane(windowPane);
        }
        _onExecuteGenerator(ray, uiSession) {
            const player = uiSession.extensionContext.player;
            const targetBlock = uiSession.extensionContext.cursor.getPosition();
            if (!targetBlock) {
                uiSession.log.error("Could not place a farm on an invalid block", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const targetCorner = {
                x: targetBlock.x + (this._commonSettings.farmWidth.value - 1) / 2,
                y: targetBlock.y,
                z: targetBlock.z - (this._commonSettings.farmLength.value - 1) / 2
            };
            const possibleCrops = [];
            if (this._cropSettings.beetroot.value) {
                possibleCrops.push(lib_vanilla_MinecraftBlockTypes.Beetroot);
            }
            if (this._cropSettings.carrot.value) {
                possibleCrops.push(lib_vanilla_MinecraftBlockTypes.Carrots);
            }
            if (this._cropSettings.pumpkin.value) {
                possibleCrops.push(lib_vanilla_MinecraftBlockTypes.Pumpkin);
            }
            if (this._cropSettings.wheat.value) {
                possibleCrops.push(lib_vanilla_MinecraftBlockTypes.Wheat);
            }
            if (this._cropSettings.potato.value) {
                possibleCrops.push(lib_vanilla_MinecraftBlockTypes.Potatoes);
            }
            const possibleAnimals = [];
            if (this._animalSettings.sheep.value) {
                possibleAnimals.push(MinecraftEntityTypes.Sheep);
            }
            if (this._animalSettings.cow.value) {
                possibleAnimals.push(MinecraftEntityTypes.Cow);
            }
            if (this._animalSettings.pig.value) {
                possibleAnimals.push(MinecraftEntityTypes.Pig);
            }
            this.telemetryManager.fireTelemetryEvent(FarmTelemetry.Place, {
                farmWidth: this._commonSettings.farmWidth.value,
                farmLength: this._commonSettings.farmLength.value,
                irrigation: this._commonSettings.irrigation.value,
                fenceType: this._commonSettings.fenceType.value,
                crops: possibleCrops,
                animals: possibleAnimals
            });
            this._buildFarm(targetCorner, possibleAnimals, possibleCrops, player, uiSession);
        }
        _buildFarm(targetCorner, possibleAnimals, possibleCrops, player, uiSession) {
            const region = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(uiSession.extensionContext.player).regionManager.getCursorRegion();
            const operation = () => {
                const x = -1;
                const z = 1;
                let didPlaceAnimal = false;
                for (let i = 0; i < this._commonSettings.farmWidth.value; i++) {
                    for (let j = 0; j < this._commonSettings.farmLength.value; j++) {
                        const xOffset = i * x;
                        const zOffset = j * z;
                        const location = {
                            x: targetCorner.x + xOffset,
                            y: targetCorner.y,
                            z: targetCorner.z + zOffset
                        };
                        const locationAbove = {
                            ...location,
                            y: targetCorner.y + 1
                        };
                        const isBorder = i === 0 || i === this._commonSettings.farmWidth.value - 1 || j === 0 || j === this._commonSettings.farmLength.value - 1;
                        uiSession.extensionContext.transactionManager.trackBlockChangeList([ location, locationAbove ]);
                        if (xOffset % 3 === 0 && !isBorder && this._commonSettings.irrigation.value) {
                            region.setBlockType(location, lib_vanilla_MinecraftBlockTypes.Water);
                        } else {
                            region.setBlockType(location, lib_vanilla_MinecraftBlockTypes.Farmland);
                        }
                        if (isBorder) {
                            region.setBlockType(locationAbove, fenceTypeToBlockType(this._commonSettings.fenceType.value));
                        } else if (possibleAnimals.length > 0 && getRandomInt(5) === 5) {
                            const animal = getRandomInt(possibleAnimals.length - 1);
                            const entityType = possibleAnimals[animal];
                            const entity = region.spawnEntity(entityType, locationAbove);
                            uiSession.extensionContext.transactionManager.addEntityOperation(entity, server_editor_namespaceObject.EntityOperationType.Create);
                            didPlaceAnimal = true;
                        } else if (region.isLiquidBlock(location) && possibleCrops.length > 0) {
                            const crop = getRandomInt(possibleCrops.length - 1);
                            const blockType = possibleCrops[crop];
                            region.setBlockType(locationAbove, blockType);
                        }
                    }
                }
                if (!didPlaceAnimal && possibleAnimals.length > 0 && this._commonSettings.farmWidth.value > 2 && this._commonSettings.farmLength.value > 2) {
                    const locationAbove = {
                        x: targetCorner.x + x,
                        y: targetCorner.y + 1,
                        z: targetCorner.z + z
                    };
                    const animal = getRandomInt(possibleAnimals.length - 1);
                    const entityType = possibleAnimals[animal];
                    const entity = region.spawnEntity(entityType, locationAbove);
                    uiSession.extensionContext.transactionManager.addEntityOperation(entity, server_editor_namespaceObject.EntityOperationType.Create);
                }
            };
            const min = lib.Vector3Utils.subtract(targetCorner, {
                x: this._commonSettings.farmWidth.value,
                y: 0,
                z: this._commonSettings.farmLength.value
            });
            const max = lib.Vector3Utils.add(targetCorner, {
                x: this._commonSettings.farmWidth.value,
                y: 1,
                z: this._commonSettings.farmLength.value
            });
            if (!region.isAreaAvailable({
                min,
                max
            })) {
                uiSession.log.error("Unable to place farm on an unavailable area", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
            try {
                uiSession.extensionContext.transactionManager.openTransaction(UniqueIdUtils_createUniqueEditorString("Farm Generator"));
            } catch (_e) {
                return;
            }
            operation();
            uiSession.extensionContext.transactionManager.commitTrackedChanges();
            uiSession.extensionContext.transactionManager.commitOpenTransaction();
        }
        addFarmGeneratorTool(uiSession) {
            const toolToggleAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    uiSession.toolRail.setSelectedToolId(tool.id);
                }
            });
            const tool = uiSession.toolRail.addTool(FarmGeneratorTool.MODAL_TOOL_ID, {
                title: "resourcePack.editor.toolRail.FarmGenerator.tool.title",
                icon: "pack://textures/editor/Farm.png?filtering=point",
                tooltip: {
                    description: "resourcePack.editor.toolRail.FarmGenerator.tool.tooltip",
                    image: "pack://textures/editor/FarmTool.gif"
                },
                action: toolToggleAction
            });
            tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    if (!this._cursorModeControl?.isActive) {
                        this._cursorModeControl?.activateControl();
                    }
                    this._widgetGroup.visible = true;
                    this._widgetGroup.visibleBounds = true;
                } else {
                    this._widgetGroup.visible = false;
                    this._widgetGroup.visibleBounds = false;
                    if (this._cursorModeControl?.isActive) {
                        this._cursorModeControl?.deactivateControl();
                    }
                }
            }));
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, toolToggleAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_P,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editorCore:farmGenerator:toggleTool",
                label: "resourcePack.editor.toolRail.FarmGenerator.keyBinding.toggleTool.title",
                tooltip: "resourcePack.editor.toolRail.FarmGenerator.keyBinding.toggleTool.tooltip"
            });
            return tool;
        }
        loadSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(FarmGenerator_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const storeItem = group.fetchItem(FarmGenerator_PERSISTENCE_GROUPITEM_NAME);
                if (storeItem && storeItem.value) {
                    try {
                        const storedSettings = storeItem.value;
                        this._commonSettings.farmLength.set(storedSettings.farmLength);
                        this._commonSettings.farmWidth.set(storedSettings.farmWidth);
                        this._commonSettings.irrigation.set(storedSettings.irrigation);
                        this._commonSettings.fenceType.set(storedSettings.fenceType);
                        this._cropSettings.wheat.set(storedSettings.wheat);
                        this._cropSettings.pumpkin.set(storedSettings.pumpkin);
                        this._cropSettings.potato.set(storedSettings.potato);
                        this._cropSettings.carrot.set(storedSettings.carrot);
                        this._cropSettings.beetroot.set(storedSettings.beetroot);
                        this._animalSettings.pig.set(storedSettings.pig);
                        this._animalSettings.sheep.set(storedSettings.sheep);
                        this._animalSettings.cow.set(storedSettings.cow);
                    } catch (error) {
                        this.uiSession.log.error("Fail to load the settings, error: " + stringFromException(error));
                    }
                }
                group.dispose();
            }
        }
        saveSettings() {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(FarmGenerator_PERSISTENCE_GROUP_NAME, option);
            if (group) {
                const settings = {
                    farmLength: this._commonSettings.farmLength.value,
                    farmWidth: this._commonSettings.farmWidth.value,
                    irrigation: this._commonSettings.irrigation.value,
                    fenceType: this._commonSettings.fenceType.value,
                    wheat: this._cropSettings.wheat.value,
                    pumpkin: this._cropSettings.pumpkin.value,
                    potato: this._cropSettings.potato.value,
                    carrot: this._cropSettings.carrot.value,
                    beetroot: this._cropSettings.beetroot.value,
                    pig: this._animalSettings.pig.value,
                    sheep: this._animalSettings.sheep.value,
                    cow: this._animalSettings.cow.value
                };
                const storeItem = group.getOrCreateItem(FarmGenerator_PERSISTENCE_GROUPITEM_NAME, settings);
                if (storeItem) {
                    storeItem.commit();
                }
                group.dispose();
                return;
            }
            this.uiSession.log.error("Fail to save settings for FarmGenerator");
        }
    }
    FarmGeneratorTool.MODAL_TOOL_ID = "editorCore:farmTool";
    function getRandomInt(upper) {
        return Math.floor(Math.random() * (upper + 1));
    }
    function fenceTypeToBlockType(fenceType) {
        switch (fenceType) {
          case 0:
            return lib_vanilla_MinecraftBlockTypes.OakFence;

          case 1:
            return lib_vanilla_MinecraftBlockTypes.BirchFence;

          case 2:
            return lib_vanilla_MinecraftBlockTypes.AcaciaFence;

          case 3:
            return lib_vanilla_MinecraftBlockTypes.BambooFence;

          case 4:
            return lib_vanilla_MinecraftBlockTypes.CherryFence;

          case 5:
            return lib_vanilla_MinecraftBlockTypes.JungleFence;

          case 6:
            return lib_vanilla_MinecraftBlockTypes.SpruceFence;

          case 7:
            return lib_vanilla_MinecraftBlockTypes.WarpedFence;

          case 8:
            return lib_vanilla_MinecraftBlockTypes.CrimsonFence;

          default:
            return lib_vanilla_MinecraftBlockTypes.OakFence;
        }
    }
    var SettingsTelemetry;
    (function(SettingsTelemetry) {
        SettingsTelemetry["ShowInvisibleBlocks"] = "ShowInvisibleBlocks";
        SettingsTelemetry["ShowChunkBoundaries"] = "ShowChunkBoundaries";
        SettingsTelemetry["FlySpeedMultiplier"] = "FlySpeedMultiplier";
        SettingsTelemetry["ShowCompass"] = "ShowCompass";
        SettingsTelemetry["NightVision"] = "NightVision";
        SettingsTelemetry["MuteMusic"] = "MuteMusic";
        SettingsTelemetry["MuteSounds"] = "MuteSounds";
        SettingsTelemetry["ShowToastNotifications"] = "ShowToastNotifications";
    })(SettingsTelemetry || (SettingsTelemetry = {}));
    const PERSISTENCE_GROUP = "editor:settings";
    const PERSISTENCE_GROUP_ITEM_KEY = "settings";
    class SettingsBehavior {
        persistSettings() {
            this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.NightVision, this.mNightVision.value);
            try {
                const option = {
                    scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ClientGlobal,
                    groupType: server_editor_private_bindings_namespaceObject.PersistenceGroupType.Replication,
                    version: 0
                };
                const group = this._persistenceManager.getOrCreateGroup(PERSISTENCE_GROUP, option);
                if (!group) {
                    this.session.log.error(`Failed to get persist group of settings`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    return;
                }
                const persistentDataItem = {
                    showInvisibleBlocks: this.mShowInvisibleBlocks.value,
                    showChunkBoundaries: this.mShowChunkBoundaries.value,
                    flySpeedMultiplier: this.mFlySpeedMultiplier.value,
                    showCompass: this.mShowCompass.value,
                    nightVision: this.mNightVision.value,
                    muteMusic: this.mMuteMusic.value,
                    muteSounds: this.mMuteSounds.value,
                    showToastNotifications: this.mShowToastNotifications.value
                };
                const groupItem = group.getOrCreateItem(PERSISTENCE_GROUP_ITEM_KEY, persistentDataItem);
                groupItem.commit();
                group.dispose();
            } catch (err) {
                this.session.log.error(`Failed to persist settings: ${(0, server_editor_namespaceObject.stringFromException)(err)}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
        }
        loadSettingsFromStorage() {
            try {
                const option = {
                    scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ClientGlobal,
                    version: 0
                };
                this._persistenceManager.requestClientGroup(PERSISTENCE_GROUP, option, (persistenceGroup => {
                    if (!persistenceGroup) {
                        return;
                    }
                    const persistentDataItem = persistenceGroup.fetchItem(PERSISTENCE_GROUP_ITEM_KEY);
                    if (!persistentDataItem || !persistentDataItem.value) {
                        return;
                    }
                    this.mShowInvisibleBlocks.set(persistentDataItem.value.showInvisibleBlocks);
                    this.mShowChunkBoundaries.set(persistentDataItem.value.showChunkBoundaries);
                    this.mFlySpeedMultiplier.set(persistentDataItem.value.flySpeedMultiplier);
                    this.mShowCompass.set(persistentDataItem.value.showCompass);
                    this.mNightVision.set(persistentDataItem.value.nightVision);
                    this.mMuteMusic.set(persistentDataItem.value.muteMusic);
                    this.mMuteSounds.set(persistentDataItem.value.muteSounds);
                    this.mShowToastNotifications.set(persistentDataItem.value.showToastNotifications);
                    persistenceGroup.dispose();
                    this.session.extensionContext.settings.audio.set(server_editor_namespaceObject.AudioSettingsProperty.IsMusicMuted, this.mMuteMusic.value);
                    this.session.extensionContext.settings.audio.set(server_editor_namespaceObject.AudioSettingsProperty.AreSoundsMuted, this.mMuteSounds.value);
                    this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.ShowInvisibleBlocks, this.mShowInvisibleBlocks.value);
                    this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.ShowChunkBoundaries, this.mShowChunkBoundaries.value);
                    this.session.extensionContext.settings.speed.set(server_editor_namespaceObject.SpeedSettingsProperty.FlySpeedMultiplier, this.mFlySpeedMultiplier.value);
                    this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.ShowCompass, this.mShowCompass.value);
                    this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.NightVision, this.mNightVision.value);
                    this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.ShowToastNotifications, this.mShowToastNotifications.value);
                }));
            } catch (err) {
                this.session.log.error(`Failed to load settings: ${(0, server_editor_namespaceObject.stringFromException)(err)}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }
        }
        setFlySpeed(session, newFlySpeed) {
            session.extensionContext.settings.speed.set(server_editor_namespaceObject.SpeedSettingsProperty.FlySpeedMultiplier, newFlySpeed);
            this.telemetryManager.fireTelemetryEvent(SettingsTelemetry.FlySpeedMultiplier, {
                value: newFlySpeed
            });
            this.persistSettings();
        }
        constructor(session, _parentMenu) {
            this.session = session;
            this.telemetryManager = new TelemetryManager(session.extensionContext.player, TelemetrySource.Settings);
            this._persistenceManager = getPersistenceManager(this.session.extensionContext.player);
            const showInvisibleBlocks = this.session.extensionContext.settings.graphics.get(server_editor_namespaceObject.GraphicsSettingsProperty.ShowInvisibleBlocks);
            const showChunkBoundaries = this.session.extensionContext.settings.graphics.get(server_editor_namespaceObject.GraphicsSettingsProperty.ShowChunkBoundaries);
            const flySpeedMultiplier = this.session.extensionContext.settings.speed.get(server_editor_namespaceObject.SpeedSettingsProperty.FlySpeedMultiplier);
            const showCompass = this.session.extensionContext.settings.graphics.get(server_editor_namespaceObject.GraphicsSettingsProperty.ShowCompass);
            const nightVision = this.session.extensionContext.settings.graphics.get(server_editor_namespaceObject.GraphicsSettingsProperty.NightVision);
            const showToastNotifications = this.session.extensionContext.settings.graphics.get(server_editor_namespaceObject.GraphicsSettingsProperty.ShowToastNotifications);
            const muteMusic = this.session.extensionContext.settings.audio.get(server_editor_namespaceObject.AudioSettingsProperty.IsMusicMuted);
            const muteSounds = this.session.extensionContext.settings.audio.get(server_editor_namespaceObject.AudioSettingsProperty.AreSoundsMuted);
            this.mShowInvisibleBlocks = (0, server_editor_namespaceObject.makeObservable)(showInvisibleBlocks ?? true);
            this.mShowChunkBoundaries = (0, server_editor_namespaceObject.makeObservable)(showChunkBoundaries ?? false);
            this.mFlySpeedMultiplier = (0, server_editor_namespaceObject.makeObservable)(flySpeedMultiplier ?? 4);
            this.mProjectCursorThroughLiquid = (0, server_editor_namespaceObject.makeObservable)(true);
            this.mShowCompass = (0, server_editor_namespaceObject.makeObservable)(showCompass ?? true);
            this.mNightVision = (0, server_editor_namespaceObject.makeObservable)(nightVision ?? true);
            this.mMuteMusic = (0, server_editor_namespaceObject.makeObservable)(muteMusic ?? true);
            this.mMuteSounds = (0, server_editor_namespaceObject.makeObservable)(muteSounds ?? false);
            this.mShowToastNotifications = (0, server_editor_namespaceObject.makeObservable)(showToastNotifications ?? false);
            this.loadSettingsFromStorage();
            this.rootPane = this.session.createPropertyPane({
                title: "resourcePack.editor.settingsPane.title",
                uniqueId: "editor:pane:settings",
                infoTooltip: {
                    description: [ "resourcePack.editor.settingsPane.tooltip" ]
                }
            });
            this._createControlSettings();
            this._createInterfaceSettings();
            this._createWorldViewSettings();
            this.mCursorChangeSubscriberHandle = this.session.extensionContext.afterEvents.cursorPropertyChange.subscribe((event => {
                if (event.properties.projectThroughLiquid !== undefined && this.mProjectCursorThroughLiquid) {
                    this.mProjectCursorThroughLiquid.set(event.properties.projectThroughLiquid);
                }
            }));
            const showSettingsPaneAction = session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.rootPane.show();
                }
            });
            _parentMenu.addItem({
                label: "resourcePack.editor.settingsPane.menu.title",
                tooltip: "resourcePack.editor.settingsPane.menu.tooltip"
            }, showSettingsPaneAction);
            this.session.actionBar.registerItem(server_editor_namespaceObject.CoreActionBarItemType.Settings, showSettingsPaneAction, {
                label: "resourcePack.editor.settingsPane.menu.title",
                icon: "settingsIcon",
                tooltipTitle: "resourcePack.editor.settingsPane.menu.title",
                tooltipDescription: "resourcePack.editor.settingsPane.actionBar.tooltip",
                enabled: true,
                executeOnAdd: true
            });
            const decrementFlySpeedAction = session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.mFlySpeedMultiplier.set(this.mFlySpeedMultiplier.value - 1);
                    this.setFlySpeed(session, this.mFlySpeedMultiplier.value);
                }
            });
            const incrementFlySpeedAction = session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.mFlySpeedMultiplier.set(this.mFlySpeedMultiplier.value + 1);
                    this.setFlySpeed(session, this.mFlySpeedMultiplier.value);
                }
            });
            session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, decrementFlySpeedAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_Q,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editor:viewportKeyBinding:decrementFlySpeed",
                label: "resourcePack.editor.viewport.keyBinding.decrementFlySpeed.title",
                tooltip: "resourcePack.editor.viewport.keyBinding.decrementFlySpeed.tooltip"
            });
            session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, incrementFlySpeedAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_E,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editor:viewportKeyBinding:incrementFlySpeed",
                label: "resourcePack.editor.viewport.keyBinding.incrementFlySpeed.title",
                tooltip: "resourcePack.editor.viewport.keyBinding.incrementFlySpeed.tooltip"
            });
        }
        _createControlSettings() {
            const controlPane = this.rootPane.createSubPane({
                title: "resourcePack.editor.settingsPane.control.title"
            });
            controlPane.addNumber(this.mFlySpeedMultiplier, {
                title: "resourcePack.editor.settingsPane.control.flySpeed.title",
                tooltip: "resourcePack.editor.settingsPane.control.flySpeed.tooltip",
                isInteger: true,
                min: 1,
                max: 10,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    this.setFlySpeed(this.session, newValue);
                }
            });
            controlPane.addDivider();
            const props = this.session.extensionContext.cursor.getProperties();
            this.mProjectCursorThroughLiquid.set(props.projectThroughLiquid ?? true);
            controlPane.addBool(this.mProjectCursorThroughLiquid, {
                title: "resourcePack.editor.settingsPane.control.projectThroughLiquid.title",
                tooltip: "resourcePack.editor.settingsPane.control.projectThroughLiquid.tooltip",
                onChange: newValue => {
                    const props = this.session.extensionContext.cursor.getProperties();
                    props.projectThroughLiquid = newValue;
                    this.session.extensionContext.cursor.setProperties(props);
                }
            });
        }
        _createInterfaceSettings() {
            const interfacePane = this.rootPane.createSubPane({
                title: "resourcePack.editor.settingsPane.interface.title"
            });
            interfacePane.addBool(this.mShowCompass, {
                title: "resourcePack.editor.settingsPane.interface.compass.title",
                tooltip: "resourcePack.editor.settingsPane.interface.compass.tooltip",
                onChange: newValue => {
                    this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.ShowCompass, newValue);
                    this.telemetryManager.fireTelemetryEvent(SettingsTelemetry.ShowCompass, {
                        value: newValue
                    });
                    this.persistSettings();
                }
            });
            interfacePane.addBool(this.mShowToastNotifications, {
                title: "resourcePack.editor.settingsPane.interface.toastNotifications.title",
                tooltip: "resourcePack.editor.settingsPane.interface.toastNotifications.tooltip",
                onChange: newValue => {
                    this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.ShowToastNotifications, newValue);
                    this.telemetryManager.fireTelemetryEvent(SettingsTelemetry.ShowToastNotifications, {
                        value: newValue
                    });
                    this.persistSettings();
                }
            });
            interfacePane.addBool(this.mMuteMusic, {
                title: "resourcePack.editor.settingsPane.interface.muteMusic.title",
                tooltip: "resourcePack.editor.settingsPane.interface.muteMusic.tooltip",
                onChange: newValue => {
                    this.session.extensionContext.settings.audio.set(server_editor_namespaceObject.AudioSettingsProperty.IsMusicMuted, newValue);
                    this.telemetryManager.fireTelemetryEvent(SettingsTelemetry.MuteMusic, {
                        value: newValue
                    });
                    this.persistSettings();
                }
            });
            interfacePane.addBool(this.mMuteSounds, {
                title: "resourcePack.editor.settingsPane.interface.muteSounds.title",
                tooltip: "resourcePack.editor.settingsPane.interface.muteSounds.tooltip",
                onChange: newValue => {
                    this.session.extensionContext.settings.audio.set(server_editor_namespaceObject.AudioSettingsProperty.AreSoundsMuted, newValue);
                    this.telemetryManager.fireTelemetryEvent(SettingsTelemetry.MuteSounds, {
                        value: newValue
                    });
                    this.persistSettings();
                }
            });
            interfacePane.addProxyPane("editor:paneClient:uiSettings");
        }
        _createWorldViewSettings() {
            const worldViewPane = this.rootPane.createSubPane({
                title: "resourcePack.editor.settingsPane.worldView.title"
            });
            worldViewPane.addBool(this.mNightVision, {
                title: "resourcePack.editor.settingsPane.worldView.nightVision.title",
                tooltip: "resourcePack.editor.settingsPane.worldView.nightVision.tooltip",
                onChange: newValue => {
                    this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.NightVision, newValue);
                    this.telemetryManager.fireTelemetryEvent(SettingsTelemetry.NightVision, {
                        value: newValue
                    });
                    this.persistSettings();
                }
            });
            worldViewPane.addBool(this.mShowInvisibleBlocks, {
                title: "resourcePack.editor.settingsPane.worldView.invisibleBlocks.title",
                tooltip: "resourcePack.editor.settingsPane.worldView.invisibleBlocks.tooltip",
                onChange: newValue => {
                    this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.ShowInvisibleBlocks, newValue);
                    this.telemetryManager.fireTelemetryEvent(SettingsTelemetry.ShowInvisibleBlocks, {
                        value: newValue
                    });
                    this.persistSettings();
                }
            });
            worldViewPane.addBool(this.mShowChunkBoundaries, {
                title: "resourcePack.editor.settingsPane.worldView.chunkBounds.title",
                tooltip: "resourcePack.editor.settingsPane.worldView.chunkBounds.tooltip",
                onChange: newValue => {
                    this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.ShowChunkBoundaries, newValue);
                    this.telemetryManager.fireTelemetryEvent(SettingsTelemetry.ShowChunkBoundaries, {
                        value: newValue
                    });
                    this.persistSettings();
                }
            });
        }
        teardown() {
            if (this.mCursorChangeSubscriberHandle !== undefined) {
                this.session.extensionContext.afterEvents.cursorPropertyChange.unsubscribe(this.mCursorChangeSubscriberHandle);
            }
        }
    }
    var SpecialBlockLogicNames;
    (function(SpecialBlockLogicNames) {
        SpecialBlockLogicNames[SpecialBlockLogicNames["UpdateStrippedBlockPrefix"] = 0] = "UpdateStrippedBlockPrefix";
        SpecialBlockLogicNames[SpecialBlockLogicNames["IncrementBlockSuffix"] = 1] = "IncrementBlockSuffix";
        SpecialBlockLogicNames[SpecialBlockLogicNames["SkipRestrictedBlockValues"] = 2] = "SkipRestrictedBlockValues";
    })(SpecialBlockLogicNames || (SpecialBlockLogicNames = {}));
    var DirectionProp;
    (function(DirectionProp) {
        DirectionProp["Up"] = "up";
        DirectionProp["Down"] = "down";
        DirectionProp["East"] = "east";
        DirectionProp["West"] = "west";
        DirectionProp["South"] = "south";
        DirectionProp["North"] = "north";
    })(DirectionProp || (DirectionProp = {}));
    var ClickType;
    (function(ClickType) {
        ClickType[ClickType["LeftClick"] = 0] = "LeftClick";
        ClickType[ClickType["ShiftLeftClick"] = 1] = "ShiftLeftClick";
        ClickType[ClickType["ControlLeftClick"] = 2] = "ControlLeftClick";
        ClickType[ClickType["ShiftControlLeftClick"] = 3] = "ShiftControlLeftClick";
    })(ClickType || (ClickType = {}));
    var WorkbenchTelemetry;
    (function(WorkbenchTelemetry) {
        WorkbenchTelemetry["BlockClicked"] = "BlockClicked";
        WorkbenchTelemetry["OverrideAdded"] = "CustomOverridesAdded";
        WorkbenchTelemetry["OverridesReset"] = "CustomOverridesReset";
        WorkbenchTelemetry["GlobalKeybindWorkbenchAction"] = "GlobalKeybindWorkbenchAction";
    })(WorkbenchTelemetry || (WorkbenchTelemetry = {}));
    class WorkbenchBehavior {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this._leftClickPropertiesOverrides = [];
            this._shiftLeftClickPropertiesOverrides = [];
            this._controlLeftClickPropertiesOverrides = [];
            this._controlShiftLeftClickPropertiesOverrides = [];
            this._blockInteractionMappingCache = new Map([]);
            this._bindGlobalActivationShortcuts = uiSession => {
                const defaultWorkbenchAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        const blockRaycast = this._getBlockFromCursorRayCast(uiSession);
                        if (blockRaycast?.block) {
                            const blocksToAlter = this._generateBlocksToAlterList(blockRaycast.block, uiSession);
                            blocksToAlter.forEach((block => {
                                this._autoAlignWithPlayerDirectionProperty(block);
                                this._processMouseClickAction(block, leftClickBlockCustomLogicMap, leftClickProperties, this._leftClickPropertiesOverrides);
                                this.telemetryManager.fireTelemetryEvent(WorkbenchTelemetry.GlobalKeybindWorkbenchAction, {
                                    blockName: block.typeId,
                                    keyboardModifiers: "None"
                                });
                            }));
                        }
                    }
                });
                const shiftWorkbenchAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        const blockRaycast = this._getBlockFromCursorRayCast(uiSession);
                        if (blockRaycast?.block) {
                            const blocksToAlter = this._generateBlocksToAlterList(blockRaycast.block, uiSession);
                            blocksToAlter.forEach((block => {
                                this._processMouseClickAction(block, shiftClickBlockCustomLogicMap, shiftLeftClickProperties, this._shiftLeftClickPropertiesOverrides);
                                this.telemetryManager.fireTelemetryEvent(WorkbenchTelemetry.GlobalKeybindWorkbenchAction, {
                                    blockName: block.typeId,
                                    keyboardModifiers: "Shift"
                                });
                            }));
                        }
                    }
                });
                const controlWorkbenchAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        const blockRaycast = this._getBlockFromCursorRayCast(uiSession);
                        if (blockRaycast?.block) {
                            const blocksToAlter = this._generateBlocksToAlterList(blockRaycast.block, uiSession);
                            blocksToAlter.forEach((block => {
                                this._processMouseClickAction(block, controlClickBlockCustomLogicMap, controlLeftClickProperties, this._controlLeftClickPropertiesOverrides);
                                this.telemetryManager.fireTelemetryEvent(WorkbenchTelemetry.GlobalKeybindWorkbenchAction, {
                                    blockName: block.typeId,
                                    keyboardModifiers: "Ctrl"
                                });
                            }));
                        }
                    }
                });
                const shiftControlWorkbenchAction = uiSession.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        const blockRaycast = this._getBlockFromCursorRayCast(uiSession);
                        if (blockRaycast?.block) {
                            const blocksToAlter = this._generateBlocksToAlterList(blockRaycast.block, uiSession);
                            blocksToAlter.forEach((block => {
                                this._updateBlockPermutations(block, controlShiftLeftClickProperties, this._controlShiftLeftClickPropertiesOverrides);
                                this.telemetryManager.fireTelemetryEvent(WorkbenchTelemetry.GlobalKeybindWorkbenchAction, {
                                    blockName: block.typeId,
                                    keyboardModifiers: "Shift + Ctrl"
                                });
                            }));
                        }
                    }
                });
                uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, defaultWorkbenchAction, {
                    key: server_editor_namespaceObject.KeyboardKey.NUMPAD_ADD
                }, {
                    uniqueId: "editor:toolModeKeyBinding:primaryWorkbenchAction",
                    label: "resourcePack.editor.workbenchTool.keyBinding.primaryAction.title",
                    tooltip: "resourcePack.editor.workbenchTool.keyBinding.primaryAction.tooltip"
                });
                uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, shiftWorkbenchAction, {
                    key: server_editor_namespaceObject.KeyboardKey.NUMPAD_ADD,
                    modifier: server_editor_namespaceObject.InputModifier.Shift
                }, {
                    uniqueId: "editor:toolModeKeyBinding:secondaryWorkbenchAction",
                    label: "resourcePack.editor.workbenchTool.keyBinding.secondaryAction.title",
                    tooltip: "resourcePack.editor.workbenchTool.keyBinding.secondaryAction.tooltip"
                });
                uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, controlWorkbenchAction, {
                    key: server_editor_namespaceObject.KeyboardKey.NUMPAD_ADD,
                    modifier: server_editor_namespaceObject.InputModifier.Control
                }, {
                    uniqueId: "editor:toolModeKeyBinding:tertiaryWorkbenchAction",
                    label: "resourcePack.editor.workbenchTool.keyBinding.tertiaryAction.title",
                    tooltip: "resourcePack.editor.workbenchTool.keyBinding.tertiaryAction.tooltip"
                });
                uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, shiftControlWorkbenchAction, {
                    key: server_editor_namespaceObject.KeyboardKey.NUMPAD_ADD,
                    modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
                }, {
                    uniqueId: "editor:toolModeKeyBinding:quaternaryWorkbenchAction",
                    label: "resourcePack.editor.workbenchTool.keyBinding.quaternaryAction.title",
                    tooltip: "resourcePack.editor.workbenchTool.keyBinding.quaternaryAction.tooltip"
                });
            };
            uiSession.log.debug(`Initializing ${WorkbenchBehavior.BEHAVIOR_NAME}`);
            this.telemetryManager = new TelemetryManager(uiSession.extensionContext.player, TelemetrySource.Workbench);
            this.cursorProperties = uiSession.extensionContext.cursor.getDefaultProperties();
            if (this.cursorProperties.fillColor) {
                delete this.cursorProperties.fillColor;
            }
            this.cursorProperties.outlineColor = {
                red: 1,
                green: 1,
                blue: 0,
                alpha: 1
            };
            this.cursorProperties.fillColor = {
                red: 1,
                green: 1,
                blue: 1,
                alpha: 0
            };
            this.cursorProperties.controlMode = server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse;
            this.cursorProperties.targetMode = server_editor_namespaceObject.CursorTargetMode.Block;
            this._props = {
                blockType: (0, server_editor_namespaceObject.makeObservable)("-"),
                leftClick: (0, server_editor_namespaceObject.makeObservable)("-"),
                shiftLeftClick: (0, server_editor_namespaceObject.makeObservable)("-"),
                controlLeftClick: (0, server_editor_namespaceObject.makeObservable)("-"),
                shiftControlLeftClick: (0, server_editor_namespaceObject.makeObservable)("-"),
                customOverrideString: (0, server_editor_namespaceObject.makeObservable)("")
            };
            this.tool = this._addTool(uiSession);
            this.pane = this._createToolPane();
            this._registerMouseAction(uiSession);
            this._bindGlobalActivationShortcuts(uiSession);
        }
        teardown() {
            this.uiSession.log.debug(`Shutting down ${WorkbenchBehavior.BEHAVIOR_NAME}`);
            if (this._cursorPropertyEventSub) {
                this.uiSession.extensionContext.afterEvents.cursorPropertyChange.unsubscribe(this._cursorPropertyEventSub);
            }
        }
        _addTool(uiSession) {
            const toolToggleAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    uiSession.toolRail.setSelectedToolId(tool.id);
                }
            });
            const tool = uiSession.toolRail.addTool(WorkbenchBehavior.MODAL_TOOL_ID, {
                title: "resourcePack.editor.toolRail.WorkbenchTool.title",
                icon: "pack://textures/editor/Workbench.png?filtering=point",
                tooltip: {
                    description: "resourcePack.editor.toolRail.WorkbenchTool.tooltip",
                    image: "pack://textures/editor/Workbench.gif"
                },
                action: toolToggleAction
            });
            tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    uiSession.extensionContext.cursor.pushPropertiesById(this.cursorProperties, WorkbenchBehavior.MODAL_TOOL_ID);
                    this._cursorPropertyEventSub = this.uiSession.extensionContext.afterEvents.cursorPropertyChange.subscribe((event => {
                        if (event.position !== undefined) {
                            this._highlightBlock(event.position.Position);
                        }
                    }));
                } else {
                    if (this._cursorPropertyEventSub) {
                        this.uiSession.extensionContext.afterEvents.cursorPropertyChange.unsubscribe(this._cursorPropertyEventSub);
                    }
                    uiSession.extensionContext.cursor.popPropertiesById(WorkbenchBehavior.MODAL_TOOL_ID);
                }
            }));
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, toolToggleAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_W,
                modifier: server_editor_namespaceObject.InputModifier.Control
            });
            return tool;
        }
        _highlightBlock(position) {
            const player = this.uiSession.extensionContext.player;
            const targetBlock = player.dimension.getBlock(position);
            const targetBlockStates = targetBlock?.permutation.getAllStates();
            let enableBlockHighlight = false;
            if (targetBlockStates && targetBlock) {
                if (!workbenchExcludedBlockList.includes(targetBlock.typeId)) {
                    for (const key of Object.keys(targetBlockStates)) {
                        if (highlightBlockProperties.findIndex((value => value === key)) !== -1 || this._leftClickPropertiesOverrides.findIndex((value => value === key)) !== -1 || this._shiftLeftClickPropertiesOverrides.findIndex((value => value === key)) !== -1 || this._controlLeftClickPropertiesOverrides.findIndex((value => value === key)) !== -1 || this._controlShiftLeftClickPropertiesOverrides.findIndex((value => value === key)) !== -1) {
                            enableBlockHighlight = true;
                            break;
                        }
                    }
                    for (const key of specialLogicBlockKeys) {
                        if (targetBlock.typeId.indexOf(key) !== -1) {
                            enableBlockHighlight = true;
                            break;
                        }
                    }
                }
                this._props.blockType.set(targetBlock.typeId);
                if (enableBlockHighlight) {
                    this.cursorProperties.visible = true;
                    this.uiSession.extensionContext.cursor.updatePropertiesById(this.cursorProperties, WorkbenchBehavior.MODAL_TOOL_ID);
                    this._updateBlockInteractionCache(targetBlock);
                    const blockInteractions = this._blockInteractionMappingCache.get(targetBlock.typeId);
                    this._props.leftClick.set(blockInteractions?.leftClickProperty ?? "-");
                    this._props.shiftLeftClick.set(blockInteractions?.shiftLeftClickProperty ?? "-");
                    this._props.controlLeftClick.set(blockInteractions?.controlLeftClickProperty ?? "-");
                    this._props.shiftControlLeftClick.set(blockInteractions?.shiftControlLeftClickProperty ?? "-");
                    if (this._leftClickTextItem && this._shiftLeftClickTextItem && this._controlLeftClickTextItem && this._shiftControlLeftClickTextItem) {
                        this._leftClickTextItem.visible = blockInteractions?.leftClickProperty ? true : false;
                        this._shiftLeftClickTextItem.visible = blockInteractions?.shiftLeftClickProperty ? true : false;
                        this._controlLeftClickTextItem.visible = blockInteractions?.controlLeftClickProperty ? true : false;
                        this._shiftControlLeftClickTextItem.visible = blockInteractions?.shiftControlLeftClickProperty ? true : false;
                    }
                } else {
                    this.cursorProperties.visible = false;
                    this._props.leftClick.set("-");
                    this._props.shiftLeftClick.set("-");
                    this._props.controlLeftClick.set("-");
                    this._props.shiftControlLeftClick.set("-");
                    if (this._leftClickTextItem && this._shiftLeftClickTextItem && this._controlLeftClickTextItem && this._shiftControlLeftClickTextItem) {
                        this._leftClickTextItem.visible = false;
                        this._shiftLeftClickTextItem.visible = false;
                        this._controlLeftClickTextItem.visible = false;
                        this._shiftControlLeftClickTextItem.visible = false;
                    }
                    this.uiSession.extensionContext.cursor.updatePropertiesById(this.cursorProperties, WorkbenchBehavior.MODAL_TOOL_ID);
                }
            }
        }
        _createToolPane() {
            const pane = this.uiSession.createPropertyPane({
                title: "resourcePack.editor.toolRail.WorkbenchTool.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.toolRail.WorkbenchTool.description", {
                        link: "https://aka.ms/BedrockEditorWorkbenchTool",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            pane.addText("resourcePack.editor.toolRail.workbenchTool.howToUse");
            pane.addText(this._props.blockType, {
                title: "resourcePack.editor.toolRail.WorkbenchTool.block",
                enable: false
            });
            this._leftClickTextItem = pane.addText(this._props.leftClick, {
                title: "resourcePack.editor.toolRail.WorkbenchTool.leftClick",
                enable: false,
                visible: false
            });
            this._shiftLeftClickTextItem = pane.addText(this._props.shiftLeftClick, {
                title: "resourcePack.editor.toolRail.WorkbenchTool.shiftLeftClick",
                enable: false,
                visible: false
            });
            this._controlLeftClickTextItem = pane.addText(this._props.controlLeftClick, {
                title: "resourcePack.editor.toolRail.WorkbenchTool.controlLeftClick",
                enable: false,
                visible: false
            });
            this._shiftControlLeftClickTextItem = pane.addText(this._props.shiftControlLeftClick, {
                title: "resourcePack.editor.toolRail.WorkbenchTool.shiftControlLeftClick",
                enable: false,
                visible: false
            });
            const customBindingsSubpane = pane.createSubPane({
                title: "resourcePack.editor.toolRail.workbenchTool.addCustomMapping",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.workbenchTool.addCustomMapping",
                    description: [ "resourcePack.editor.toolRail.workbenchTool.addCustomMapping.tooltip" ]
                },
                collapsed: true
            });
            customBindingsSubpane.addString(this._props.customOverrideString, {
                title: `resourcePack.editor.toolRail.workbenchTool.blockProperty`,
                tooltip: "resourcePack.editor.toolRail.workbenchTool.blockProperty.tooltip"
            });
            const clickBindingOptions = [ {
                label: "resourcePack.editor.toolRail.WorkbenchTool.leftClick",
                value: ClickType.LeftClick
            }, {
                label: "resourcePack.editor.toolRail.WorkbenchTool.shiftLeftClick",
                value: ClickType.ShiftLeftClick
            }, {
                label: "resourcePack.editor.toolRail.WorkbenchTool.controlLeftClick",
                value: ClickType.ControlLeftClick
            }, {
                label: "resourcePack.editor.toolRail.WorkbenchTool.shiftControlLeftClick",
                value: ClickType.ShiftControlLeftClick
            } ];
            this._customPropertyOverrideDropdown = customBindingsSubpane.addDropdown(0, {
                title: "resourcePack.editor.toolRail.workbenchTool.clickBinding",
                entries: clickBindingOptions,
                tooltip: "resourcePack.editor.toolRail.workbenchTool.clickBinding.tooltip"
            });
            const customBindingsButtonPane = customBindingsSubpane.addButtonPane();
            customBindingsButtonPane.addButton((() => {
                this._addCustomBlockPropertyOverride();
                this.telemetryManager.fireTelemetryEvent(WorkbenchTelemetry.OverrideAdded, {
                    propertyOverrideString: this._props.customOverrideString.value,
                    clickType: this._customPropertyOverrideDropdown.value
                });
            }), {
                title: "resourcePack.editor.toolRail.workbenchTool.addMapping",
                variant: server_editor_namespaceObject.ButtonVariant.Confirmation
            });
            customBindingsButtonPane.addButton((() => {
                this._resetCustomBlockOverrides();
                this.telemetryManager.fireTelemetryEvent(WorkbenchTelemetry.OverridesReset);
            }), {
                title: "resourcePack.editor.toolRail.workbenchTool.resetAllMappings",
                variant: server_editor_namespaceObject.ButtonVariant.Destructive
            });
            this.tool.bindPropertyPane(pane);
            return pane;
        }
        _addCustomBlockPropertyOverride() {
            switch (this._customPropertyOverrideDropdown.value) {
              case ClickType.LeftClick:
                {
                    this._processOverrideString(this._leftClickPropertiesOverrides);
                    break;
                }

              case ClickType.ShiftLeftClick:
                {
                    this._processOverrideString(this._shiftLeftClickPropertiesOverrides);
                    break;
                }

              case ClickType.ControlLeftClick:
                {
                    this._processOverrideString(this._controlLeftClickPropertiesOverrides);
                    break;
                }

              case ClickType.ShiftControlLeftClick:
                {
                    this._processOverrideString(this._controlShiftLeftClickPropertiesOverrides);
                    break;
                }
            }
        }
        _processOverrideString(overrideList) {
            this._props.customOverrideString.value.split(",").forEach((value => {
                if (value.trim() === "") {
                    return;
                }
                const index = overrideList.findIndex((v => v === value.trim()));
                if (index !== -1) {
                    overrideList.splice(index, 1);
                }
                overrideList.unshift(value.trim());
            }));
        }
        _resetCustomBlockOverrides() {
            this._leftClickPropertiesOverrides = [];
            this._shiftLeftClickPropertiesOverrides = [];
            this._controlLeftClickPropertiesOverrides = [];
            this._controlShiftLeftClickPropertiesOverrides = [];
            this._blockInteractionMappingCache.clear();
        }
        _updateBlockInteractionCache(targetBlock) {
            if (this._blockInteractionMappingCache.has(targetBlock.typeId)) {
                return;
            }
            const specialLogicNameLeftClick = this._isBlockWithSpecialLogic(targetBlock.typeId, leftClickBlockCustomLogicMap)?.specialLogicDescription;
            const specialLogicNameShiftLeftClick = this._isBlockWithSpecialLogic(targetBlock.typeId, shiftClickBlockCustomLogicMap)?.specialLogicDescription;
            const specialLogicNameControlLeftClick = this._isBlockWithSpecialLogic(targetBlock.typeId, controlClickBlockCustomLogicMap)?.specialLogicDescription;
            const specialLogicNameShiftControlLeftClick = this._isBlockWithSpecialLogic(targetBlock.typeId, shiftControlLeftClickBlockCustomLogicMap)?.specialLogicDescription;
            const blockInteractionMapping = {
                blockType: targetBlock.typeId,
                leftClickProperty: specialLogicNameLeftClick,
                shiftLeftClickProperty: specialLogicNameShiftLeftClick,
                controlLeftClickProperty: specialLogicNameControlLeftClick,
                shiftControlLeftClickProperty: specialLogicNameShiftControlLeftClick
            };
            for (const key of Object.keys(targetBlock.permutation.getAllStates())) {
                this._updateBlockInteractionCacheEntry(leftClickProperties, this._leftClickPropertiesOverrides, blockInteractionMapping, "leftClickProperty", key);
                this._updateBlockInteractionCacheEntry(shiftLeftClickProperties, this._shiftLeftClickPropertiesOverrides, blockInteractionMapping, "shiftLeftClickProperty", key);
                this._updateBlockInteractionCacheEntry(controlLeftClickProperties, this._controlLeftClickPropertiesOverrides, blockInteractionMapping, "controlLeftClickProperty", key);
                this._updateBlockInteractionCacheEntry(controlShiftLeftClickProperties, this._controlShiftLeftClickPropertiesOverrides, blockInteractionMapping, "shiftControlLeftClickProperty", key);
            }
            this._blockInteractionMappingCache.set(targetBlock.typeId, blockInteractionMapping);
        }
        _updateBlockInteractionCacheEntry(clickProperties, clickOverrides, interactionMapping, blockMappingProp, blockState) {
            const typeKey = blockMappingProp;
            let index = clickOverrides.findIndex((value => value === blockState));
            if (!interactionMapping[typeKey] && index !== -1) {
                const key = clickOverrides.at(index);
                if (key) {
                    interactionMapping[typeKey] = key;
                }
                return;
            }
            index = clickProperties.findIndex((value => value === blockState));
            if (!interactionMapping[typeKey] && index !== -1) {
                const key = clickProperties.at(index);
                if (key) {
                    interactionMapping[typeKey] = propertyTypeToLocFriendlyNameMapping.get(key) ?? "";
                    if (blockMappingProp === "controlLeftClickProperty") {
                        interactionMapping.leftClickProperty = autoAlignPropertyTypeToLocFriendlyNameMapping.get(key);
                    }
                }
                return;
            }
        }
        _registerMouseAction(uiSession) {
            const executeAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    const player = uiSession.extensionContext.player;
                    const targetBlock = player.dimension.getBlock(mouseRay.cursorBlockLocation);
                    if (targetBlock && mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown && this.tool.isActive && !workbenchExcludedBlockList.includes(targetBlock.typeId)) {
                        const blocksToAlter = this._generateBlocksToAlterList(targetBlock, uiSession);
                        blocksToAlter.forEach((block => {
                            if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton && mouseProps.modifiers.shift && mouseProps.modifiers.ctrl) {
                                this._updateBlockPermutations(block, controlShiftLeftClickProperties, this._controlShiftLeftClickPropertiesOverrides);
                                this.telemetryManager.fireTelemetryEvent(WorkbenchTelemetry.BlockClicked, {
                                    blockName: block.typeId,
                                    keyboardModifiers: "Shift + Ctrl"
                                });
                            } else if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton && mouseProps.modifiers.shift) {
                                this._processMouseClickAction(block, shiftClickBlockCustomLogicMap, shiftLeftClickProperties, this._shiftLeftClickPropertiesOverrides);
                                this.telemetryManager.fireTelemetryEvent(WorkbenchTelemetry.BlockClicked, {
                                    blockName: block.typeId,
                                    keyboardModifiers: "Shift"
                                });
                            } else if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton && mouseProps.modifiers.ctrl) {
                                this._processMouseClickAction(block, controlClickBlockCustomLogicMap, controlLeftClickProperties, this._controlLeftClickPropertiesOverrides);
                                this.telemetryManager.fireTelemetryEvent(WorkbenchTelemetry.BlockClicked, {
                                    blockName: block.typeId,
                                    keyboardModifiers: "Ctrl"
                                });
                            } else if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton) {
                                this._autoAlignWithPlayerDirectionProperty(block);
                                this._processMouseClickAction(block, leftClickBlockCustomLogicMap, leftClickProperties, this._leftClickPropertiesOverrides);
                                this.telemetryManager.fireTelemetryEvent(WorkbenchTelemetry.BlockClicked, {
                                    blockName: block.typeId,
                                    keyboardModifiers: "None"
                                });
                            }
                        }));
                    }
                }
            });
            this.tool.registerMouseButtonBinding(executeAction);
        }
        _getBlockFromCursorRayCast(uiSession) {
            const player = uiSession.extensionContext.player;
            const cursorRay = uiSession.extensionContext.cursor.getRay();
            const rayDirection = lib.Vector3Utils.subtract(cursorRay.end, cursorRay.start);
            const normalizedDirection = lib.Vector3Utils.normalize(rayDirection);
            const blockRaycast = player.dimension.getBlockFromRay(cursorRay.start, normalizedDirection);
            return blockRaycast;
        }
        _generateBlocksToAlterList(targetBlock, uiSession) {
            if (uiSession.extensionContext.selectionManager.volume.isEmpty) {
                return [ targetBlock ];
            }
            try {
                const selection = uiSession.extensionContext.selectionManager.volume.get();
                const iterator = selection.getBlockLocationIterator();
                const blocksToAlter = [];
                let foundTargetBlockInSelection = false;
                for (const position of iterator) {
                    const block = uiSession.extensionContext.player.dimension.getBlock(position);
                    if (block?.typeId === targetBlock.typeId) {
                        if (block.location.x === targetBlock.location.x && block.location.y === targetBlock.location.y && block.location.z === targetBlock.location.z) {
                            foundTargetBlockInSelection = true;
                        }
                        blocksToAlter.push(block);
                    }
                }
                if (foundTargetBlockInSelection) {
                    return blocksToAlter;
                } else {
                    uiSession.log.warning(`Limiting operation to a single block as it is outside of the current selection.`);
                    return [ targetBlock ];
                }
            } catch (_e) {
                return [ targetBlock ];
            }
        }
        _processMouseClickAction(targetBlock, specialLogicMap, clickProperties, clickOverrides) {
            const specialLogicParams = this._isBlockWithSpecialLogic(targetBlock.typeId, specialLogicMap);
            if (specialLogicParams) {
                this._processBlockSpecialLogic(targetBlock, specialLogicParams);
            } else {
                this._updateBlockPermutations(targetBlock, clickProperties, clickOverrides);
            }
        }
        _updateBlockPermutation(targetBlock, propertyName, propertyValue) {
            if (propertyValue !== undefined) {
                const newPermutation = targetBlock.permutation.withState(propertyName, propertyValue);
                targetBlock.setPermutation(newPermutation);
            }
        }
        _calculatePlayerDirection(useFourAxisOnly) {
            const playerDirectionVector = this.uiSession.extensionContext.player.getViewDirection();
            const absDirX = Math.abs(this.uiSession.extensionContext.player.getViewDirection().x);
            const absDirY = Math.abs(this.uiSession.extensionContext.player.getViewDirection().y);
            const absDirZ = Math.abs(this.uiSession.extensionContext.player.getViewDirection().z);
            let playerFacing = DirectionProp.West;
            if (useFourAxisOnly && absDirX > absDirZ || absDirX > absDirY && absDirX > absDirZ) {
                playerFacing = playerDirectionVector.x >= 0 ? DirectionProp.East : DirectionProp.West;
            } else if (useFourAxisOnly && absDirZ > absDirX || absDirZ > absDirX && absDirZ > absDirY) {
                playerFacing = playerDirectionVector.z >= 0 ? DirectionProp.South : DirectionProp.North;
            } else {
                playerFacing = playerDirectionVector.y >= 0 ? DirectionProp.Down : DirectionProp.Up;
            }
            return playerFacing;
        }
        _autoAlignWithPlayerDirectionProperty(targetBlock) {
            const playerDirection = new Map([ [ "direction", () => this._calculatePlayerDirection(true) ], [ "weirdo_direction", () => this._calculatePlayerDirection(true) ], [ "facing_direction", () => this._calculatePlayerDirection(false) ], [ "minecraft:cardinal_direction", () => this._calculatePlayerDirection(true) ], [ "minecraft:block_face", () => this._calculatePlayerDirection(false) ] ]);
            let propertyKey = undefined;
            let propertyValue = undefined;
            playerDirection.forEach(((value, key) => {
                if (targetBlock.permutation.getState(key) !== undefined) {
                    propertyKey = key;
                    propertyValue = playerDirection.get(propertyKey)?.();
                    return;
                }
            }));
            if (propertyKey !== undefined && propertyValue !== undefined) {
                propertyValue = propertyTypeToDirectionMapping.get(propertyKey)?.get(propertyValue);
                this._updateBlockPermutation(targetBlock, propertyKey, propertyValue);
            }
        }
        _updateBlockPermutations(targetBlock, validValues, overrideValues, restrictedValues) {
            let tag = undefined;
            overrideValues.forEach((element => {
                if (targetBlock.permutation.getState(element) !== undefined) {
                    tag = element;
                    return;
                }
            }));
            validValues.forEach((element => {
                if (targetBlock.permutation.getState(element) !== undefined) {
                    tag = element;
                    return;
                }
            }));
            if (tag) {
                const currentValue = targetBlock.permutation.getState(tag);
                const propertyType = server_namespaceObject.BlockStates.get(tag);
                const index = propertyType?.validValues.findIndex((value => value === currentValue));
                if (index !== undefined && index !== -1 && propertyType) {
                    let updatedIndex = (index + 1) % propertyType.validValues.length;
                    let updatedValue = propertyType.validValues[updatedIndex];
                    if (restrictedValues && restrictedValues.length > 0) {
                        while (restrictedValues.findIndex((value => value === updatedValue)) !== -1 && updatedIndex !== index) {
                            updatedIndex = (updatedIndex + 1) % propertyType.validValues.length;
                            updatedValue = propertyType.validValues[updatedIndex];
                        }
                    }
                    this._updateBlockPermutation(targetBlock, tag, updatedValue);
                }
            }
        }
        _isBlockWithSpecialLogic(blockType, blockSpecialLogicMap) {
            let specialLogicParams = undefined;
            blockSpecialLogicMap.forEach(((value, key) => {
                if (blockType.indexOf(key) !== -1) {
                    specialLogicParams = blockSpecialLogicMap.get(key);
                }
            }));
            return specialLogicParams;
        }
        _processBlockSpecialLogic(targetBlock, specialLogicParams) {
            switch (specialLogicParams.specialLogicType) {
              case SpecialBlockLogicNames.UpdateStrippedBlockPrefix:
                {
                    const pillarAxisPropertyName = "pillar_axis";
                    const strippedBlockPrefix = "stripped_";
                    const pillarAxisState = targetBlock.permutation.getState(pillarAxisPropertyName);
                    const blockTypeSplit = targetBlock.typeId.split(":");
                    if (blockTypeSplit.length === 2 && blockTypeSplit[1].startsWith(strippedBlockPrefix)) {
                        blockTypeSplit[1] = blockTypeSplit[1].substring(strippedBlockPrefix.length);
                    } else {
                        blockTypeSplit[1] = strippedBlockPrefix.concat(blockTypeSplit[1]);
                    }
                    targetBlock.setType(blockTypeSplit.join(":"));
                    this._props.blockType.set(targetBlock.typeId);
                    this._updateBlockPermutation(targetBlock, pillarAxisPropertyName, pillarAxisState);
                    break;
                }

              case SpecialBlockLogicNames.IncrementBlockSuffix:
                {
                    let updatedBlockType = targetBlock.typeId;
                    const splitBlockType = updatedBlockType.split("_");
                    const blockNumber = Number(splitBlockType[splitBlockType.length - 1]);
                    if (blockNumber !== undefined && specialLogicParams.numOfStates) {
                        const updatedBlockNumber = (blockNumber + 1) % specialLogicParams.numOfStates;
                        splitBlockType[splitBlockType.length - 1] = updatedBlockNumber.toString();
                        updatedBlockType = splitBlockType.join("_");
                        targetBlock.setType(updatedBlockType);
                        this._props.blockType.set(updatedBlockType);
                    }
                }
                break;

              case SpecialBlockLogicNames.SkipRestrictedBlockValues:
                {
                    if (specialLogicParams.propertyNameToUpdate) {
                        this._updateBlockPermutations(targetBlock, [ specialLogicParams.propertyNameToUpdate ], [], specialLogicParams.restrictedValues);
                    }
                }
            }
        }
    }
    WorkbenchBehavior.BEHAVIOR_NAME = "Block Changer";
    WorkbenchBehavior.MODAL_TOOL_ID = "editor:modalTool:Workbench";
    const leftClickProperties = [ "minecraft:vertical_half", "top_slot_bit", "pillar_axis", "height", "candles", "turtle_egg_count", "cluster_count", "hanging", "wall_post_bit" ];
    const shiftLeftClickProperties = [ "upside_down_bit", "open_bit", "lit", "dripstone_thickness" ];
    const controlLeftClickProperties = [ "direction", "weirdo_direction", "facing_direction", "minecraft:cardinal_direction", "minecraft:block_face" ];
    const controlShiftLeftClickProperties = [ "upside_down_bit" ];
    const highlightBlockProperties = [ ...leftClickProperties, ...shiftLeftClickProperties, ...controlLeftClickProperties, ...controlShiftLeftClickProperties ];
    const shiftClickBlockCustomLogicMap = new Map([ [ "_wood", {
        specialLogicType: SpecialBlockLogicNames.UpdateStrippedBlockPrefix,
        specialLogicDescription: "resourcePack.editor.toolRail.workbenchTool.stripWood"
    } ], [ "_log", {
        specialLogicType: SpecialBlockLogicNames.UpdateStrippedBlockPrefix,
        specialLogicDescription: "resourcePack.editor.toolRail.workbenchTool.stripWood"
    } ], [ "warped_stem", {
        specialLogicType: SpecialBlockLogicNames.UpdateStrippedBlockPrefix,
        specialLogicDescription: "resourcePack.editor.toolRail.workbenchTool.stripWood"
    } ], [ "crimson_stem", {
        specialLogicType: SpecialBlockLogicNames.UpdateStrippedBlockPrefix,
        specialLogicDescription: "resourcePack.editor.toolRail.workbenchTool.stripWood"
    } ] ]);
    const controlClickBlockCustomLogicMap = new Map([ [ "minecraft:ladder", {
        specialLogicType: SpecialBlockLogicNames.SkipRestrictedBlockValues,
        specialLogicDescription: "resourcePack.editor.toolRail.workbenchTool.ladderLocation",
        restrictedValues: [ 0, 1 ],
        propertyNameToUpdate: "facing_direction"
    } ] ]);
    const leftClickBlockCustomLogicMap = new Map([ [ "light_block", {
        specialLogicType: SpecialBlockLogicNames.IncrementBlockSuffix,
        specialLogicDescription: "light level",
        numOfStates: 16
    } ] ]);
    const specialLogicBlockKeys = [ ...Array.from(shiftClickBlockCustomLogicMap.keys()), ...Array.from(controlClickBlockCustomLogicMap.keys()), ...Array.from(leftClickBlockCustomLogicMap.keys()) ];
    const workbenchExcludedBlockList = [ "minecraft:ladder" ];
    const shiftControlLeftClickBlockCustomLogicMap = new Map([]);
    const directionPropertyMapping = new Map([ [ DirectionProp.East, 1 ], [ DirectionProp.West, 0 ], [ DirectionProp.South, 3 ], [ DirectionProp.North, 2 ] ]);
    const weirdoDirectionPropertyMapping = new Map([ [ DirectionProp.East, 0 ], [ DirectionProp.West, 1 ], [ DirectionProp.South, 2 ], [ DirectionProp.North, 3 ] ]);
    const facingDirectionPropertyMapping = new Map([ [ DirectionProp.Down, 0 ], [ DirectionProp.Up, 1 ], [ DirectionProp.East, 2 ], [ DirectionProp.West, 3 ], [ DirectionProp.North, 4 ], [ DirectionProp.South, 5 ] ]);
    const blockFacePropertyMapping = new Map([ [ DirectionProp.Down, DirectionProp.Down ], [ DirectionProp.Up, DirectionProp.Up ], [ DirectionProp.East, DirectionProp.East ], [ DirectionProp.West, DirectionProp.West ], [ DirectionProp.North, DirectionProp.North ], [ DirectionProp.South, DirectionProp.South ] ]);
    const cardinalDirectionPropertyMapping = new Map([ [ DirectionProp.East, DirectionProp.East ], [ DirectionProp.West, DirectionProp.West ], [ DirectionProp.North, DirectionProp.North ], [ DirectionProp.South, DirectionProp.South ] ]);
    const propertyTypeToDirectionMapping = new Map([ [ "direction", directionPropertyMapping ], [ "weirdo_direction", weirdoDirectionPropertyMapping ], [ "facing_direction", facingDirectionPropertyMapping ], [ "minecraft:block_face", blockFacePropertyMapping ], [ "minecraft:cardinal_direction", cardinalDirectionPropertyMapping ] ]);
    const propertyTypeToLocFriendlyNameMapping = new Map([ [ "top_slot_bit", "resourcePack.editor.toolRail.workbenchTool.topSlotBitProp" ], [ "minecraft:vertical_half", "resourcePack.editor.toolRail.workbenchTool.topSlotBitProp" ], [ "pillar_axis", "resourcePack.editor.toolRail.workbenchTool.pillarAxisProp" ], [ "height", "resourcePack.editor.toolRail.workbenchTool.heightProp" ], [ "candles", "resourcePack.editor.toolRail.workbenchTool.candlesProp" ], [ "turtle_egg_count", "resourcePack.editor.toolRail.workbenchTool.turtleEggCountProp" ], [ "cluster_count", "resourcePack.editor.toolRail.workbenchTool.clusterCountProp" ], [ "hanging", "resourcePack.editor.toolRail.workbenchTool.hangingProp" ], [ "wall_post_bit", "resourcePack.editor.toolRail.workbenchTool.wallPostBitProp" ], [ "upside_down_bit", "resourcePack.editor.toolRail.workbenchTool.upsideDownBitProp" ], [ "open_bit", "resourcePack.editor.toolRail.workbenchTool.openBitProp" ], [ "lit", "resourcePack.editor.toolRail.workbenchTool.litProp" ], [ "dripstone_thickness", "resourcePack.editor.toolRail.workbenchTool.dripstoneThicknessProp" ], [ "direction", "resourcePack.editor.toolRail.workbenchTool.directionProp" ], [ "weirdo_direction", "resourcePack.editor.toolRail.workbenchTool.weirdoDirectionProp" ], [ "facing_direction", "resourcePack.editor.toolRail.workbenchTool.facingDirectionProp" ], [ "facing_direction", "resourcePack.editor.toolRail.workbenchTool.facingDirectionProp" ], [ "minecraft:block_face", "resourcePack.editor.toolRail.workbenchTool.cardinalDirectionProp" ], [ "minecraft:cardinal_direction", "resourcePack.editor.toolRail.workbenchTool.cardinalDirectionProp" ] ]);
    const autoAlignPropertyTypeToLocFriendlyNameMapping = new Map([ [ "minecraft:block_face", "resourcePack.editor.toolRail.workbenchTool.autoAlignFacingDirection" ], [ "direction", "resourcePack.editor.toolRail.workbenchTool.autoAlignFacingDirection" ], [ "weirdo_direction", "resourcePack.editor.toolRail.workbenchTool.autoAlignRotation" ], [ "facing_direction", "resourcePack.editor.toolRail.workbenchTool.autoAlignFacingDirection" ], [ "minecraft:cardinal_direction", "resourcePack.editor.toolRail.workbenchTool.autoAlignFacingDirection" ] ]);
    class BlockFluidContainerComponentUI {
        constructor() {
            this._fillLevel = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.BlockFluidContainerComponent.componentId
            });
            this._fillLevel.set(this._component.fillLevel);
            componentPane.addNumber(this._fillLevel, {
                title: "fillLevel",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.fillLevel = newValue;
                    }
                }
            });
        }
    }
    class BlockPistonComponentUI {
        constructor() {
            this._isMoving = (0, server_editor_namespaceObject.makeObservable)(false);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.BlockPistonComponent.componentId
            });
            this._isMoving.set(this._component.isMoving);
            componentPane.addBool(this._isMoving, {
                title: "isMoving",
                enable: false
            });
        }
    }
    class BlockRedstoneProducerComponentUI {
        constructor() {
            this._power = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.BlockRedstoneProducerComponent.componentId
            });
            this._power.set(this._component.power);
            componentPane.addNumber(this._power, {
                title: "power",
                enable: false
            });
        }
    }
    class BlockSignComponentUI {
        constructor() {
            this._isWaxed = (0, server_editor_namespaceObject.makeObservable)(false);
            this._text = new Map([ [ server_namespaceObject.SignSide.Back, (0, server_editor_namespaceObject.makeObservable)("") ], [ server_namespaceObject.SignSide.Front, (0, 
            server_editor_namespaceObject.makeObservable)("") ] ]);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.BlockSignComponent.componentId
            });
            this._isWaxed.set(this._component.isWaxed);
            for (const elem of this._text) {
                const val = this._component.getText(elem[0]);
                if (val) {
                    elem[1].set(val);
                }
            }
            componentPane.addBool(this._isWaxed, {
                title: "isWaxed",
                enable: false
            });
            const textSubPane = componentPane.createSubPane({
                title: "text"
            });
            this._text.forEach(((value, key) => {
                textSubPane.addString(value, {
                    title: key,
                    enable: true,
                    onChange: newValue => {
                        this._component?.setText(newValue, key);
                    }
                });
            }));
        }
    }
    class EntityAddRiderComponentUI {
        constructor() {
            this._entityType = (0, server_editor_namespaceObject.makeObservable)("");
            this._spawnEvent = (0, server_editor_namespaceObject.makeObservable)("");
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityAddRiderComponent.componentId
            });
            this._entityType.set(this._component.entityType);
            this._spawnEvent.set(this._component.spawnEvent);
            componentPane.addString(this._entityType, {
                title: "entityType",
                enable: false
            });
            componentPane.addString(this._spawnEvent, {
                title: "spawnEvent",
                enable: false
            });
        }
    }
    class EntityAgeableComponentUI {
        constructor() {
            this._duration = (0, server_editor_namespaceObject.makeObservable)(0);
            this._transformToItem = (0, server_editor_namespaceObject.makeObservable)("");
            this._dropItems = [];
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityAgeableComponent.componentId
            });
            this._duration.set(this._component.duration);
            this._transformToItem.set(this._component.transformToItem);
            for (const elem of this._component.getDropItems()) {
                this._dropItems.push((0, server_editor_namespaceObject.makeObservable)(elem));
            }
            componentPane.addNumber(this._duration, {
                title: "duration",
                enable: false
            });
            componentPane.addString(this._transformToItem, {
                title: "transformToItem",
                enable: false
            });
            const dropItemsSubPane = componentPane.createSubPane({
                title: "dropItems"
            });
            this._dropItems.forEach((value => {
                dropItemsSubPane.addString(value, {
                    enable: false
                });
            }));
        }
    }
    class EntityBreathableComponentUI {
        constructor() {
            this._airSupply = (0, server_editor_namespaceObject.makeObservable)(0);
            this._breathesAir = (0, server_editor_namespaceObject.makeObservable)(false);
            this._breathesLava = (0, server_editor_namespaceObject.makeObservable)(false);
            this._breathesSolids = (0, server_editor_namespaceObject.makeObservable)(false);
            this._breathesWater = (0, server_editor_namespaceObject.makeObservable)(false);
            this._canBreathe = (0, server_editor_namespaceObject.makeObservable)(false);
            this._generatesBubbles = (0, server_editor_namespaceObject.makeObservable)(false);
            this._inhaleTime = (0, server_editor_namespaceObject.makeObservable)(0);
            this._suffocateTime = (0, server_editor_namespaceObject.makeObservable)(0);
            this._totalSupply = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityBreathableComponent.componentId
            });
            this._airSupply.set(this._component.airSupply);
            this._breathesAir.set(this._component.breathesAir);
            this._breathesLava.set(this._component.breathesLava);
            this._breathesSolids.set(this._component.breathesSolids);
            this._breathesWater.set(this._component.breathesWater);
            this._canBreathe.set(this._component.canBreathe);
            this._generatesBubbles.set(this._component.generatesBubbles);
            this._inhaleTime.set(this._component.inhaleTime);
            this._suffocateTime.set(this._component.suffocateTime);
            this._totalSupply.set(this._component.totalSupply);
            componentPane.addNumber(this._airSupply, {
                title: "airSupply",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.airSupply = newValue;
                    }
                }
            });
            componentPane.addBool(this._breathesAir, {
                title: "breathesAir",
                enable: false
            });
            componentPane.addBool(this._breathesLava, {
                title: "breathesLava",
                enable: false
            });
            componentPane.addBool(this._breathesSolids, {
                title: "breathesSolids",
                enable: false
            });
            componentPane.addBool(this._breathesWater, {
                title: "breathesWater",
                enable: false
            });
            componentPane.addBool(this._canBreathe, {
                title: "canBreathe",
                enable: false
            });
            componentPane.addBool(this._generatesBubbles, {
                title: "generatesBubbles",
                enable: false
            });
            componentPane.addNumber(this._inhaleTime, {
                title: "inhaleTime",
                enable: false
            });
            componentPane.addNumber(this._suffocateTime, {
                title: "suffocateTime",
                enable: false
            });
            componentPane.addNumber(this._totalSupply, {
                title: "totalSupply",
                enable: false
            });
        }
    }
    class EntityColorComponentUI {
        constructor() {
            this._value = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityColorComponent.componentId
            });
            this._value.set(this._component.value);
            componentPane.addNumber(this._value, {
                title: "value",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.value = newValue;
                    }
                }
            });
        }
    }
    class EntityEquippableComponentUI {
        constructor() {
            this._totalArmor = (0, server_editor_namespaceObject.makeObservable)(0);
            this._totalToughness = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityEquippableComponent.componentId
            });
            this._totalArmor.set(this._component.totalArmor);
            this._totalToughness.set(this._component.totalToughness);
            componentPane.addNumber(this._totalArmor, {
                title: "totalArmor",
                enable: false
            });
            componentPane.addNumber(this._totalToughness, {
                title: "totalToughness",
                enable: false
            });
        }
    }
    class EntityFlyingSpeedComponentUI {
        constructor() {
            this._value = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityFlyingSpeedComponent.componentId
            });
            this._value.set(this._component.value);
            componentPane.addNumber(this._value, {
                title: "value",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.value = newValue;
                    }
                }
            });
        }
    }
    class EntityFrictionModifierComponentUI {
        constructor() {
            this._value = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityFrictionModifierComponent.componentId
            });
            this._value.set(this._component.value);
            componentPane.addNumber(this._value, {
                title: "value",
                enable: false
            });
        }
    }
    class EntityHealableComponentUI {
        constructor() {
            this._forceUse = (0, server_editor_namespaceObject.makeObservable)(false);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityHealableComponent.componentId
            });
            this._forceUse.set(this._component.forceUse);
            componentPane.addBool(this._forceUse, {
                title: "forceUse",
                enable: false
            });
        }
    }
    class EntityInventoryComponentUI {
        constructor() {
            this._additionalSlotsPerStrength = (0, server_editor_namespaceObject.makeObservable)(0);
            this._canBeSiphonedFrom = (0, server_editor_namespaceObject.makeObservable)(false);
            this._containerType = (0, server_editor_namespaceObject.makeObservable)("");
            this._inventorySize = (0, server_editor_namespaceObject.makeObservable)(0);
            this._private = (0, server_editor_namespaceObject.makeObservable)(false);
            this._restrictToOwner = (0, server_editor_namespaceObject.makeObservable)(false);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityInventoryComponent.componentId
            });
            this._additionalSlotsPerStrength.set(this._component.additionalSlotsPerStrength);
            this._canBeSiphonedFrom.set(this._component.canBeSiphonedFrom);
            this._containerType.set(this._component.containerType);
            this._inventorySize.set(this._component.inventorySize);
            this._private.set(this._component.private);
            this._restrictToOwner.set(this._component.restrictToOwner);
            componentPane.addNumber(this._additionalSlotsPerStrength, {
                title: "additionalSlotsPerStrength",
                enable: false
            });
            componentPane.addBool(this._canBeSiphonedFrom, {
                title: "canBeSiphonedFrom",
                enable: false
            });
            componentPane.addString(this._containerType, {
                title: "containerType",
                enable: false
            });
            componentPane.addNumber(this._inventorySize, {
                title: "inventorySize",
                enable: false
            });
            componentPane.addBool(this._private, {
                title: "private",
                enable: false
            });
            componentPane.addBool(this._restrictToOwner, {
                title: "restrictToOwner",
                enable: false
            });
        }
    }
    class EntityLeashableComponentUI {
        constructor() {
            this._canBeStolen = (0, server_editor_namespaceObject.makeObservable)(false);
            this._hardDistance = (0, server_editor_namespaceObject.makeObservable)(0);
            this._isLeashed = (0, server_editor_namespaceObject.makeObservable)(false);
            this._leashHolderEntityId = (0, server_editor_namespaceObject.makeObservable)("");
            this._maxDistance = (0, server_editor_namespaceObject.makeObservable)(0);
            this._softDistance = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityLeashableComponent.componentId
            });
            this._canBeStolen.set(this._component.canBeStolen);
            this._hardDistance.set(this._component.hardDistance);
            this._isLeashed.set(this._component.isLeashed);
            if (this._component.leashHolderEntityId) {
                this._leashHolderEntityId.set(this._component.leashHolderEntityId);
            }
            this._maxDistance.set(this._component.maxDistance);
            this._softDistance.set(this._component.softDistance);
            componentPane.addBool(this._canBeStolen, {
                title: "canBeStolen",
                enable: false
            });
            componentPane.addNumber(this._hardDistance, {
                title: "hardDistance",
                enable: false
            });
            componentPane.addBool(this._isLeashed, {
                title: "isLeashed",
                enable: false
            });
            componentPane.addString(this._leashHolderEntityId, {
                title: "leashHolderEntityId",
                enable: false
            });
            componentPane.addNumber(this._maxDistance, {
                title: "maxDistance",
                enable: false
            });
            componentPane.addNumber(this._softDistance, {
                title: "softDistance",
                enable: false
            });
        }
    }
    class EntityMarkVariantComponentUI {
        constructor() {
            this._value = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityMarkVariantComponent.componentId
            });
            this._value.set(this._component.value);
            componentPane.addNumber(this._value, {
                title: "value",
                enable: false
            });
        }
    }
    class EntityNpcComponentUI {
        constructor() {
            this._defaultScene = (0, server_editor_namespaceObject.makeObservable)("");
            this._name = (0, server_editor_namespaceObject.makeObservable)("");
            this._skinIndex = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityNpcComponent.componentId
            });
            this._defaultScene.set(this._component.defaultScene);
            this._name.set(this._component.name);
            this._skinIndex.set(this._component.skinIndex);
            componentPane.addString(this._defaultScene, {
                title: "defaultScene",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.defaultScene = newValue;
                    }
                }
            });
            componentPane.addString(this._name, {
                title: "name",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.name = newValue;
                    }
                }
            });
            componentPane.addNumber(this._skinIndex, {
                title: "skinIndex",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.skinIndex = newValue;
                    }
                }
            });
        }
    }
    class EntityOnFireComponentUI {
        constructor() {
            this._onFireTicksRemaining = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityOnFireComponent.componentId
            });
            this._onFireTicksRemaining.set(this._component.onFireTicksRemaining);
            componentPane.addNumber(this._onFireTicksRemaining, {
                title: "onFireTicksRemaining",
                enable: false
            });
        }
    }
    class EntityProjectileComponentUI {
        constructor() {
            this._airInertia = (0, server_editor_namespaceObject.makeObservable)(0);
            this._catchFireOnHurt = (0, server_editor_namespaceObject.makeObservable)(false);
            this._critParticlesOnProjectileHurt = (0, server_editor_namespaceObject.makeObservable)(false);
            this._destroyOnProjectileHurt = (0, server_editor_namespaceObject.makeObservable)(false);
            this._gravity = (0, server_editor_namespaceObject.makeObservable)(0);
            this._hitEntitySound = (0, server_editor_namespaceObject.makeObservable)("");
            this._hitGroundSound = (0, server_editor_namespaceObject.makeObservable)("");
            this._hitParticle = (0, server_editor_namespaceObject.makeObservable)("");
            this._lightningStrikeOnHit = (0, server_editor_namespaceObject.makeObservable)(false);
            this._liquidInertia = (0, server_editor_namespaceObject.makeObservable)(0);
            this._onFireTime = (0, server_editor_namespaceObject.makeObservable)(0);
            this._shouldBounceOnHit = (0, server_editor_namespaceObject.makeObservable)(false);
            this._stopOnHit = (0, server_editor_namespaceObject.makeObservable)(false);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityProjectileComponent.componentId
            });
            this._airInertia.set(this._component.airInertia);
            this._catchFireOnHurt.set(this._component.catchFireOnHurt);
            this._critParticlesOnProjectileHurt.set(this._component.critParticlesOnProjectileHurt);
            this._destroyOnProjectileHurt.set(this._component.destroyOnProjectileHurt);
            this._gravity.set(this._component.gravity);
            if (this._component.hitEntitySound) {
                this._hitEntitySound.set(this._component.hitEntitySound);
            }
            if (this._component.hitGroundSound) {
                this._hitGroundSound.set(this._component.hitGroundSound);
            }
            if (this._component.hitParticle) {
                this._hitParticle.set(this._component.hitParticle);
            }
            this._lightningStrikeOnHit.set(this._component.lightningStrikeOnHit);
            this._liquidInertia.set(this._component.liquidInertia);
            this._onFireTime.set(this._component.onFireTime);
            this._shouldBounceOnHit.set(this._component.shouldBounceOnHit);
            this._stopOnHit.set(this._component.stopOnHit);
            componentPane.addNumber(this._airInertia, {
                title: "airInertia",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.airInertia = newValue;
                    }
                }
            });
            componentPane.addBool(this._catchFireOnHurt, {
                title: "catchFireOnHurt",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.catchFireOnHurt = newValue;
                    }
                }
            });
            componentPane.addBool(this._critParticlesOnProjectileHurt, {
                title: "critParticlesOnProjectileHurt",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.critParticlesOnProjectileHurt = newValue;
                    }
                }
            });
            componentPane.addBool(this._destroyOnProjectileHurt, {
                title: "destroyOnProjectileHurt",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.destroyOnProjectileHurt = newValue;
                    }
                }
            });
            componentPane.addNumber(this._gravity, {
                title: "gravity",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.gravity = newValue;
                    }
                }
            });
            componentPane.addString(this._hitEntitySound, {
                title: "hitEntitySound",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.hitEntitySound = newValue;
                    }
                }
            });
            componentPane.addString(this._hitGroundSound, {
                title: "hitGroundSound",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.hitGroundSound = newValue;
                    }
                }
            });
            componentPane.addString(this._hitParticle, {
                title: "hitParticle",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.hitParticle = newValue;
                    }
                }
            });
            componentPane.addBool(this._lightningStrikeOnHit, {
                title: "lightningStrikeOnHit",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.lightningStrikeOnHit = newValue;
                    }
                }
            });
            componentPane.addNumber(this._liquidInertia, {
                title: "liquidInertia",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.liquidInertia = newValue;
                    }
                }
            });
            componentPane.addNumber(this._onFireTime, {
                title: "onFireTime",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.onFireTime = newValue;
                    }
                }
            });
            componentPane.addBool(this._shouldBounceOnHit, {
                title: "shouldBounceOnHit",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.shouldBounceOnHit = newValue;
                    }
                }
            });
            componentPane.addBool(this._stopOnHit, {
                title: "stopOnHit",
                enable: true,
                onChange: newValue => {
                    if (this._component) {
                        this._component.stopOnHit = newValue;
                    }
                }
            });
        }
    }
    class EntityPushThroughComponentUI {
        constructor() {
            this._value = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityPushThroughComponent.componentId
            });
            this._value.set(this._component.value);
            componentPane.addNumber(this._value, {
                title: "value",
                enable: false
            });
        }
    }
    class EntityRideableComponentUI {
        constructor() {
            this._controllingSeat = (0, server_editor_namespaceObject.makeObservable)(0);
            this._crouchingSkipInteract = (0, server_editor_namespaceObject.makeObservable)(false);
            this._interactText = (0, server_editor_namespaceObject.makeObservable)("");
            this._passengerMaxWidth = (0, server_editor_namespaceObject.makeObservable)(0);
            this._pullInEntities = (0, server_editor_namespaceObject.makeObservable)(false);
            this._riderCanInteract = (0, server_editor_namespaceObject.makeObservable)(false);
            this._seatCount = (0, server_editor_namespaceObject.makeObservable)(0);
            this._familyTypes = [];
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityRideableComponent.componentId
            });
            this._controllingSeat.set(this._component.controllingSeat);
            this._crouchingSkipInteract.set(this._component.crouchingSkipInteract);
            this._interactText.set(this._component.interactText);
            this._passengerMaxWidth.set(this._component.passengerMaxWidth);
            this._pullInEntities.set(this._component.pullInEntities);
            this._riderCanInteract.set(this._component.riderCanInteract);
            this._seatCount.set(this._component.seatCount);
            for (const elem of this._component.getFamilyTypes()) {
                this._familyTypes.push((0, server_editor_namespaceObject.makeObservable)(elem));
            }
            componentPane.addNumber(this._controllingSeat, {
                title: "controllingSeat",
                enable: false
            });
            componentPane.addBool(this._crouchingSkipInteract, {
                title: "crouchingSkipInteract",
                enable: false
            });
            componentPane.addString(this._interactText, {
                title: "interactText",
                enable: false
            });
            componentPane.addNumber(this._passengerMaxWidth, {
                title: "passengerMaxWidth",
                enable: false
            });
            componentPane.addBool(this._pullInEntities, {
                title: "pullInEntities",
                enable: false
            });
            componentPane.addBool(this._riderCanInteract, {
                title: "riderCanInteract",
                enable: false
            });
            componentPane.addNumber(this._seatCount, {
                title: "seatCount",
                enable: false
            });
            const familyTypesSubPane = componentPane.createSubPane({
                title: "familyTypes"
            });
            this._familyTypes.forEach((value => {
                familyTypesSubPane.addString(value, {
                    enable: false
                });
            }));
        }
    }
    class EntityScaleComponentUI {
        constructor() {
            this._value = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityScaleComponent.componentId
            });
            this._value.set(this._component.value);
            componentPane.addNumber(this._value, {
                title: "value",
                enable: false
            });
        }
    }
    class EntitySkinIdComponentUI {
        constructor() {
            this._value = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntitySkinIdComponent.componentId
            });
            this._value.set(this._component.value);
            componentPane.addNumber(this._value, {
                title: "value",
                enable: false
            });
        }
    }
    class EntityStrengthComponentUI {
        constructor() {
            this._max = (0, server_editor_namespaceObject.makeObservable)(0);
            this._value = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityStrengthComponent.componentId
            });
            this._max.set(this._component.max);
            this._value.set(this._component.value);
            componentPane.addNumber(this._max, {
                title: "max",
                enable: false
            });
            componentPane.addNumber(this._value, {
                title: "value",
                enable: false
            });
        }
    }
    class EntityTameableComponentUI {
        constructor() {
            this._isTamed = (0, server_editor_namespaceObject.makeObservable)(false);
            this._probability = (0, server_editor_namespaceObject.makeObservable)(0);
            this._tamedToPlayerId = (0, server_editor_namespaceObject.makeObservable)("");
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityTameableComponent.componentId
            });
            this._isTamed.set(this._component.isTamed);
            this._probability.set(this._component.probability);
            if (this._component.tamedToPlayerId) {
                this._tamedToPlayerId.set(this._component.tamedToPlayerId);
            }
            componentPane.addBool(this._isTamed, {
                title: "isTamed",
                enable: false
            });
            componentPane.addNumber(this._probability, {
                title: "probability",
                enable: false
            });
            componentPane.addString(this._tamedToPlayerId, {
                title: "tamedToPlayerId",
                enable: false
            });
        }
    }
    class EntityTameMountComponentUI {
        constructor() {
            this._isTamed = (0, server_editor_namespaceObject.makeObservable)(false);
            this._isTamedToPlayer = (0, server_editor_namespaceObject.makeObservable)(false);
            this._tamedToPlayerId = (0, server_editor_namespaceObject.makeObservable)("");
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityTameMountComponent.componentId
            });
            this._isTamed.set(this._component.isTamed);
            this._isTamedToPlayer.set(this._component.isTamedToPlayer);
            if (this._component.tamedToPlayerId) {
                this._tamedToPlayerId.set(this._component.tamedToPlayerId);
            }
            componentPane.addBool(this._isTamed, {
                title: "isTamed",
                enable: false
            });
            componentPane.addBool(this._isTamedToPlayer, {
                title: "isTamedToPlayer",
                enable: false
            });
            componentPane.addString(this._tamedToPlayerId, {
                title: "tamedToPlayerId",
                enable: false
            });
        }
    }
    class EntityTypeFamilyComponentUI {
        constructor() {
            this._typeFamilies = [];
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityTypeFamilyComponent.componentId
            });
            for (const elem of this._component.getTypeFamilies()) {
                this._typeFamilies.push((0, server_editor_namespaceObject.makeObservable)(elem));
            }
            const typeFamiliesSubPane = componentPane.createSubPane({
                title: "typeFamilies"
            });
            this._typeFamilies.forEach((value => {
                typeFamiliesSubPane.addString(value, {
                    enable: false
                });
            }));
        }
    }
    class EntityVariantComponentUI {
        constructor() {
            this._value = (0, server_editor_namespaceObject.makeObservable)(0);
        }
        construct(parentPane, component) {
            this._component = component;
            const componentPane = parentPane.createSubPane({
                title: server_namespaceObject.EntityVariantComponent.componentId
            });
            this._value.set(this._component.value);
            componentPane.addNumber(this._value, {
                title: "value",
                enable: false
            });
        }
    }
    const ComponentUICreationMap = new Map([ [ server_namespaceObject.BlockComponentTypes.FluidContainer, () => new BlockFluidContainerComponentUI ], [ server_namespaceObject.BlockComponentTypes.Piston, () => new BlockPistonComponentUI ], [ server_namespaceObject.BlockComponentTypes.RedstoneProducer, () => new BlockRedstoneProducerComponentUI ], [ server_namespaceObject.BlockComponentTypes.Sign, () => new BlockSignComponentUI ], [ server_namespaceObject.EntityComponentTypes.AddRider, () => new EntityAddRiderComponentUI ], [ server_namespaceObject.EntityComponentTypes.Ageable, () => new EntityAgeableComponentUI ], [ server_namespaceObject.EntityComponentTypes.Breathable, () => new EntityBreathableComponentUI ], [ server_namespaceObject.EntityComponentTypes.Color, () => new EntityColorComponentUI ], [ server_namespaceObject.EntityComponentTypes.Equippable, () => new EntityEquippableComponentUI ], [ server_namespaceObject.EntityComponentTypes.FlyingSpeed, () => new EntityFlyingSpeedComponentUI ], [ server_namespaceObject.EntityComponentTypes.FrictionModifier, () => new EntityFrictionModifierComponentUI ], [ server_namespaceObject.EntityComponentTypes.Healable, () => new EntityHealableComponentUI ], [ server_namespaceObject.EntityComponentTypes.Inventory, () => new EntityInventoryComponentUI ], [ server_namespaceObject.EntityComponentTypes.Leashable, () => new EntityLeashableComponentUI ], [ server_namespaceObject.EntityComponentTypes.MarkVariant, () => new EntityMarkVariantComponentUI ], [ server_namespaceObject.EntityComponentTypes.Npc, () => new EntityNpcComponentUI ], [ server_namespaceObject.EntityComponentTypes.OnFire, () => new EntityOnFireComponentUI ], [ server_namespaceObject.EntityComponentTypes.Projectile, () => new EntityProjectileComponentUI ], [ server_namespaceObject.EntityComponentTypes.PushThrough, () => new EntityPushThroughComponentUI ], [ server_namespaceObject.EntityComponentTypes.Rideable, () => new EntityRideableComponentUI ], [ server_namespaceObject.EntityComponentTypes.Scale, () => new EntityScaleComponentUI ], [ server_namespaceObject.EntityComponentTypes.SkinId, () => new EntitySkinIdComponentUI ], [ server_namespaceObject.EntityComponentTypes.Strength, () => new EntityStrengthComponentUI ], [ server_namespaceObject.EntityComponentTypes.Tameable, () => new EntityTameableComponentUI ], [ server_namespaceObject.EntityComponentTypes.TameMount, () => new EntityTameMountComponentUI ], [ server_namespaceObject.EntityComponentTypes.TypeFamily, () => new EntityTypeFamilyComponentUI ], [ server_namespaceObject.EntityComponentTypes.Variant, () => new EntityVariantComponentUI ] ]);
    function getEntityBlockComponentUIForComponent(component) {
        const uiConstructionFunction = ComponentUICreationMap.get(component.typeId);
        return uiConstructionFunction ? uiConstructionFunction() : undefined;
    }
    var BlockInspectorTelemetry;
    (function(BlockInspectorTelemetry) {
        BlockInspectorTelemetry["BlockSelected"] = "BlockSelected";
        BlockInspectorTelemetry["BlockRefreshed"] = "BlockRefreshed";
        BlockInspectorTelemetry["BlockCleared"] = "BlockCleared";
        BlockInspectorTelemetry["BlockReset"] = "BlockReset";
        BlockInspectorTelemetry["BlockPropertyChanged"] = "BlockPropertyChanged";
    })(BlockInspectorTelemetry || (BlockInspectorTelemetry = {}));
    const notShownProperties = [ "upper_block_bit", "door_hinge_bit", "wall_connection_type_", "head_piece_bit" ];
    class BlockInspectorBehavior {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this.targetLocation = undefined;
            this.targetRegion = undefined;
            uiSession.log.debug(`Initializing ${BlockInspectorBehavior.BEHAVIOR_NAME}`);
            this.telemetryManager = new TelemetryManager(uiSession.extensionContext.player, TelemetrySource.BlockInspector);
            this.cursorProperties = uiSession.extensionContext.cursor.getDefaultProperties();
            if (this.cursorProperties.fillColor) {
                delete this.cursorProperties.fillColor;
            }
            this.cursorProperties.outlineColor = {
                red: 1,
                green: 1,
                blue: 0,
                alpha: 1
            };
            this.cursorProperties.controlMode = server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse;
            this.cursorProperties.targetMode = server_editor_namespaceObject.CursorTargetMode.Block;
            this.cursorProperties.visible = true;
            const player = uiSession.extensionContext.player;
            this._jigsawService = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(player).jigsawService;
            this._jigsawProps = {
                targetPool: (0, server_editor_namespaceObject.makeObservable)("-"),
                name: (0, server_editor_namespaceObject.makeObservable)("-"),
                targetName: (0, server_editor_namespaceObject.makeObservable)("-"),
                blockName: (0, server_editor_namespaceObject.makeObservable)("-"),
                selectionPriority: (0, server_editor_namespaceObject.makeObservable)(0),
                placementPriority: (0, server_editor_namespaceObject.makeObservable)(0),
                jointType: (0, server_editor_namespaceObject.makeObservable)(0)
            };
            this.tool = this.addTool(uiSession);
            this.pane = uiSession.createPropertyPane({
                title: "resourcePack.editor.toolRail.blockInspectorSettings.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.toolRail.blockInspectorTool.tooltip", {
                        link: "https://aka.ms/BedrockEditorBlockInspector",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this.bindings = {
                subPane: undefined,
                currentBlock: undefined
            };
            this.helpPane = this.pane.createSubPane({
                hasExpander: false,
                hasMargins: false
            });
            this.helpPane.addText("resourcePack.editor.toolRail.blockInspectorTool.pane.helpText");
            this.registerMouseAction(uiSession);
            this.tool.bindPropertyPane(this.pane);
            this.uiSession.eventSubscriptionCache.subscribeToBedrockEvent("playerDimensionChange", (event => {
                if (event.player.id === uiSession.extensionContext.player.id) {
                    this._disposeRegion();
                    this.helpPane.show();
                    this.targetLocation = undefined;
                }
            }));
        }
        teardown() {
            this.uiSession.log.debug(`Shutting down ${BlockInspectorBehavior.BEHAVIOR_NAME}`);
            this._disposeRegion();
        }
        addTool(uiSession) {
            const toolToggleAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    uiSession.toolRail.setSelectedToolId(tool.id);
                }
            });
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, toolToggleAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_B,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editorCore:blockInspector:toggleTool",
                label: "resourcePack.editor.toolRail.blockInspectorTool.keyBinding.toggleTool.title",
                tooltip: "resourcePack.editor.toolRail.blockInspectorTool.keyBinding.toggleTool.tooltip"
            });
            const tool = uiSession.toolRail.addTool(BlockInspectorBehavior.MODAL_TOOL_ID, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.title",
                icon: "pack://textures/editor/block-inspector.png?filtering=point",
                tooltip: {
                    description: "resourcePack.editor.toolRail.blockInspectorTool.tooltip",
                    image: "pack://textures/editor/BlockInspector.gif"
                },
                action: toolToggleAction
            });
            tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    uiSession.extensionContext.cursor.pushPropertiesById(this.cursorProperties, BlockInspectorBehavior.MODAL_TOOL_ID);
                    if (this.targetLocation) {
                        this._prepareRegion(this.targetLocation);
                    }
                } else {
                    uiSession.extensionContext.cursor.popPropertiesById(BlockInspectorBehavior.MODAL_TOOL_ID);
                    this._disposeRegion();
                }
            }));
            return tool;
        }
        registerMouseAction(uiSession) {
            const executeAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton && mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown && this.tool.isActive && mouseRay?.cursorBlockLocation) {
                        const cursorPos = uiSession.extensionContext.cursor.getPosition();
                        this._prepareRegion(cursorPos);
                    }
                }
            });
            this.tool.registerMouseButtonBinding(executeAction);
        }
        connectToBlock(targetBlock) {
            this.breakConnectionToBlock();
            this.helpPane.hide();
            const subPane = this.pane.createSubPane({
                title: targetBlock.localizationKey
            });
            this.bindings.subPane = subPane;
            this.bindings.currentBlock = targetBlock;
            const propBag = {};
            this.addBlockActions(targetBlock, subPane);
            this.addMainPanelData(subPane, targetBlock);
            const blockSpecificPane = subPane.createSubPane({
                title: "resourcePack.editor.toolRail.blockInspectorSettings.specifics"
            });
            this.addBlockTags(blockSpecificPane, propBag, targetBlock);
            this.addPermutationProperties(blockSpecificPane, propBag, targetBlock);
            if (targetBlock.typeId === lib_vanilla_MinecraftBlockTypes.Jigsaw) {
                this.addJigsawProperties(blockSpecificPane, targetBlock);
            }
            subPane.show();
            this.pane.show();
            this.initialBlockType = targetBlock.typeId;
        }
        breakConnectionToBlock() {
            if (this.bindings.subPane) {
                this.pane.removeSubPane(this.bindings.subPane);
            }
            this.bindings.subPane = undefined;
            this.bindings.currentBlock = undefined;
        }
        addBlockActions(targetBlock, subPane) {
            const refreshBlockToDefault = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.connectToBlock(targetBlock);
                    this.telemetryManager.fireTelemetryEvent(BlockInspectorTelemetry.BlockRefreshed);
                }
            });
            subPane.addButton(refreshBlockToDefault, {
                title: "resourcePack.editor.toolRail.blockInspectorSettings.actions.refresh"
            });
            const resetBlockToDefault = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    targetBlock.setType(this.initialBlockType);
                    this.connectToBlock(targetBlock);
                    this.telemetryManager.fireTelemetryEvent(BlockInspectorTelemetry.BlockReset);
                }
            });
            subPane.addButton(resetBlockToDefault, {
                title: "resourcePack.editor.toolRail.blockInspectorSettings.actions.reset"
            });
            const clearBlockAction = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._disposeRegion();
                    this.helpPane.show();
                    this.telemetryManager.fireTelemetryEvent(BlockInspectorTelemetry.BlockCleared);
                }
            });
            subPane.addButton(clearBlockAction, {
                title: "resourcePack.editor.toolRail.blockInspectorSettings.actions.clear"
            });
        }
        addMainPanelData(subPane, targetBlock) {
            const pos = targetBlock.location;
            const type = targetBlock.type;
            const dimId = targetBlock.dimension.id;
            subPane.addNumber(pos.x, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.posX",
                enable: false
            });
            subPane.addNumber(pos.y, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.posY",
                enable: false
            });
            subPane.addNumber(pos.z, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.posZ",
                enable: false
            });
            subPane.addString(type.id, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.blockType",
                tooltip: "resourcePack.editor.toolRail.blockInspectorTool.blockType.tooltip",
                enable: false
            });
            subPane.addString(dimId, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.dimension",
                tooltip: "resourcePack.editor.toolRail.blockInspectorTool.dimension.tooltip",
                enable: false
            });
            const componentPane = subPane.createSubPane({
                title: "resourcePack.editor.toolRail.blockInspectorTool.components",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.blockInspectorTool.components",
                    description: [ "resourcePack.editor.toolRail.blockInspectorTool.components.tooltip" ]
                }
            });
            Object.values(server_namespaceObject.BlockComponentTypes).forEach((value => {
                const blockComponent = targetBlock.getComponent(value);
                if (blockComponent) {
                    getEntityBlockComponentUIForComponent(blockComponent)?.construct(componentPane, blockComponent);
                }
            }));
        }
        addBlockTags(blockSpecificPane, propBag, targetBlock) {
            const permutationTags = targetBlock?.permutation?.getTags();
            if (permutationTags?.length !== 0) {
                const tagsPane = blockSpecificPane.createSubPane({
                    title: "resourcePack.editor.toolRail.blockInspectorSettings.blockTags"
                });
                for (let i = 0; i < permutationTags.length; ++i) {
                    tagsPane.addString(permutationTags[i], {
                        title: `${i}`,
                        enable: false
                    });
                }
            }
        }
        addPermutationProperties(blockSpecificPane, propBag, targetBlock) {
            const permutationProperties = targetBlock?.permutation?.getAllStates();
            const propertyCount = Object.keys(permutationProperties).length;
            if (propertyCount !== 0) {
                const propPane = blockSpecificPane.createSubPane({
                    title: "resourcePack.editor.toolRail.blockInspectorSettings.blockProperties"
                });
                let propertyIndex = 0;
                for (const propertyName in permutationProperties) {
                    const propertyType = server_namespaceObject.BlockStates.get(propertyName);
                    if (propertyType === undefined) {
                        throw new Error(`BlockStates.get returned undefined for property ${propertyName} that should have been defined`);
                    }
                    const propertyValue = permutationProperties[propertyName];
                    if (notShownProperties.some((prefix => propertyName.startsWith(prefix)))) {
                        continue;
                    }
                    propPane.addString(propertyName, {
                        title: "resourcePack.editor.toolRail.blockInspectorSettings.blockProperties.name",
                        enable: false
                    });
                    const validValues = propertyType.validValues;
                    const selectedValue = (0, server_editor_namespaceObject.makeObservable)(0);
                    const validDropDownItems = validValues.map(((validValue, j) => {
                        if (propertyValue === validValue) {
                            selectedValue.set(j);
                        }
                        const item = {
                            label: String(validValue),
                            value: j
                        };
                        return item;
                    }));
                    propPane.addDropdown(selectedValue, {
                        title: "resourcePack.editor.toolRail.blockInspectorSettings.blockProperties.value",
                        entries: validDropDownItems,
                        onChange: value => {
                            const newPermutation = targetBlock.permutation.withState(propertyName, validValues[value]);
                            targetBlock.setPermutation(newPermutation);
                            this.telemetryManager.fireTelemetryEvent(BlockInspectorTelemetry.BlockPropertyChanged, {
                                blockName: targetBlock.type.id,
                                propertyName,
                                propertyValue: String(validValues[value])
                            });
                        }
                    });
                    if (propertyIndex < propertyCount - 1) {
                        propPane.addDivider();
                    }
                    ++propertyIndex;
                }
            }
        }
        addJigsawProperties(blockSpecificPane, targetBlock) {
            const jigsawData = this._jigsawService.getJigsawBlockData({
                x: targetBlock.x,
                y: targetBlock.y,
                z: targetBlock.z
            });
            this._jigsawProps.targetName.set(jigsawData.target);
            this._jigsawProps.name.set(jigsawData.name);
            this._jigsawProps.targetPool.set(jigsawData.targetPool);
            this._jigsawProps.blockName.set(jigsawData.finalBlock);
            this._jigsawProps.placementPriority.set(jigsawData.placementPriority);
            this._jigsawProps.selectionPriority.set(jigsawData.selectionPriority);
            this._jigsawProps.jointType.set(jigsawData.jointType);
            const propPane = blockSpecificPane.createSubPane({
                title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.title",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.title",
                    description: [ "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.tooltip" ]
                }
            });
            propPane.addString(this._jigsawProps.targetName, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.targetName",
                tooltip: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.targetName.tooltip",
                enable: true,
                onChange: () => {
                    this._saveJigButton.enable = true;
                }
            });
            propPane.addString(this._jigsawProps.name, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.name",
                tooltip: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.name.tooltip",
                enable: true,
                onChange: () => {
                    this._saveJigButton.enable = true;
                }
            });
            propPane.addString(this._jigsawProps.targetPool, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.targetPool",
                tooltip: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.targetPool.tooltip",
                enable: true,
                onChange: () => {
                    this._saveJigButton.enable = true;
                }
            });
            propPane.addNumber(this._jigsawProps.placementPriority, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.placementPriority",
                tooltip: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.placementPriority.tooltip",
                enable: true,
                onChange: () => {
                    this._saveJigButton.enable = true;
                }
            });
            propPane.addNumber(this._jigsawProps.selectionPriority, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.selectionPriority",
                tooltip: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.selectionPriority.tooltip",
                enable: true,
                onChange: () => {
                    this._saveJigButton.enable = true;
                }
            });
            const jointTypes = [ {
                label: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.jointType.rollable",
                value: server_editor_private_bindings_namespaceObject.JigsawJointType.Rollable.valueOf()
            }, {
                label: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.jointType.aligned",
                value: server_editor_private_bindings_namespaceObject.JigsawJointType.Aligned.valueOf()
            } ];
            propPane.addDropdown(this._jigsawProps.jointType, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.jointType",
                tooltip: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.jointType.tooltip",
                entries: jointTypes,
                onChange: () => {
                    this._saveJigButton.enable = true;
                }
            });
            const saveJigsawBlockAction = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const jointType = this._jigsawProps.jointType.value === 0 ? server_editor_private_bindings_namespaceObject.JigsawJointType.Rollable : server_editor_private_bindings_namespaceObject.JigsawJointType.Aligned;
                    const updatedJigsawData = {
                        target: this._jigsawProps.targetName.value,
                        name: this._jigsawProps.name.value,
                        targetPool: this._jigsawProps.targetPool.value,
                        finalBlock: this._jigsawProps.blockName.value,
                        placementPriority: this._jigsawProps.placementPriority.value,
                        selectionPriority: this._jigsawProps.selectionPriority.value,
                        jointType,
                        jointTypeVisible: false
                    };
                    this._jigsawService.setJigsawBlockData({
                        x: targetBlock.x,
                        y: targetBlock.y,
                        z: targetBlock.z
                    }, updatedJigsawData);
                    this._saveJigButton.enable = false;
                    this.uiSession.log.info("Jigsaw block data updated.", {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
            });
            const turnIntoSubpane = propPane.createSubPane({
                layout: server_editor_namespaceObject.PaneLayoutType.Vertical,
                hasExpander: true,
                hasMargins: false,
                title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.turnsInto",
                infoTooltip: {
                    title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.turnsInto",
                    description: [ "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.turnsInto.tooltip" ]
                }
            });
            const listPane = turnIntoSubpane.addListPane({
                height: 5,
                defaultSlots: [ {
                    entries: [ {
                        type: server_editor_namespaceObject.ListPaneEntryType.Image,
                        value: {
                            path: this._jigsawProps.blockName.value,
                            type: server_editor_namespaceObject.ImageResourceType.Block
                        }
                    }, {
                        type: server_editor_namespaceObject.ListPaneEntryType.Text,
                        value: this._jigsawProps.blockName
                    }, {
                        type: server_editor_namespaceObject.ListPaneEntryType.Button,
                        onClick: () => {
                            const req = this.uiSession.dialogManager.activateDialog({
                                dialogId: server_editor_namespaceObject.CoreModalDialogType.DataPicker,
                                data: {
                                    default: this._jigsawProps.blockName.value,
                                    variant: server_editor_namespaceObject.DataPickerModalDialogVariant.Block
                                },
                                onResponse: resp => {
                                    if (resp.type === server_editor_namespaceObject.ModalDialogResponseType.Confirm) {
                                        let blockName = resp.selected;
                                        if (resp.selected.indexOf(":") < 0) {
                                            blockName = "minecraft:" + blockName;
                                        }
                                        this._jigsawProps.blockName.set(blockName);
                                        listPane.getSlotByIndex(0)?.getEntry(0, server_editor_namespaceObject.ListPaneEntryType.Image)?.setValue({
                                            path: this._jigsawProps.blockName.value,
                                            type: server_editor_namespaceObject.ImageResourceType.Block
                                        });
                                        this._saveJigButton.enable = true;
                                    } else if (resp.type === server_editor_namespaceObject.ModalDialogResponseType.Dismiss) {
                                        this.uiSession.log.info(`Dismissed block picker request with id:${req.id}`);
                                    }
                                }
                            });
                        },
                        title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.swap",
                        variant: server_editor_namespaceObject.ButtonVariant.Primary,
                        tooltip: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.swap.tooltip"
                    } ]
                } ],
                slotConfig: {
                    height: 4.4,
                    outline: true,
                    columns: 3,
                    entryLayout: [ {
                        type: server_editor_namespaceObject.ListPaneEntryType.Image,
                        size: {
                            value: 4,
                            type: server_editor_namespaceObject.LayoutSizeType.Default
                        }
                    }, {
                        type: server_editor_namespaceObject.ListPaneEntryType.Text,
                        size: server_editor_namespaceObject.LayoutFlex.Grow,
                        alignment: server_editor_namespaceObject.LayoutAlignment.Center
                    }, {
                        type: server_editor_namespaceObject.ListPaneEntryType.Button,
                        size: {
                            value: 30,
                            type: server_editor_namespaceObject.LayoutSizeType.Percentage
                        }
                    } ]
                }
            });
            this._saveJigButton = propPane.addButton(saveJigsawBlockAction, {
                title: "resourcePack.editor.toolRail.blockInspectorTool.jigsawProperties.saveJigsaw",
                enable: false,
                variant: server_editor_namespaceObject.ButtonVariant.Confirmation
            });
        }
        _prepareRegion(location) {
            this.targetLocation = location;
            if (this.targetRegion && !this.targetRegion.isLocationAvailable(location)) {
                this.targetRegion.dispose();
                this.targetRegion = undefined;
            }
            if (this.targetRegion === undefined) {
                const regionManager = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(this.uiSession.extensionContext.player).regionManager;
                this.targetRegion = regionManager.leaseRegion({
                    availabilityMode: server_editor_private_bindings_namespaceObject.ProjectRegionAvailabilityMode.Ticking,
                    extentX: {
                        min: location.x,
                        max: location.x
                    },
                    extentZ: {
                        min: location.z,
                        max: location.z
                    }
                });
            }
            this.targetRegion.waitUntilAvailable().then((() => {
                try {
                    if (this.targetRegion && this.targetRegion.isValid) {
                        const block = this.targetRegion.getBlock(location);
                        if (block) {
                            this.connectToBlock(block);
                            this.telemetryManager.fireTelemetryEvent(BlockInspectorTelemetry.BlockSelected);
                        }
                    }
                } catch {
                    this.uiSession.log.error(`Unable to inspect block at ${lib.Vector3Utils.toString(location)}`);
                }
            })).catch((() => {}));
        }
        _disposeRegion() {
            this.breakConnectionToBlock();
            if (this.targetRegion) {
                this.targetRegion.dispose();
                this.targetRegion = undefined;
            }
        }
    }
    BlockInspectorBehavior.BEHAVIOR_NAME = "Block Inspector";
    BlockInspectorBehavior.MODAL_TOOL_ID = "editor:modalTool:blockInspector";
    const PreviewColor = {
        red: 0,
        green: .5,
        blue: .5,
        alpha: .2
    };
    const HighlightColor = {
        red: .5,
        green: 1,
        blue: .5,
        alpha: 1
    };
    const FillColor = {
        red: 0,
        green: 0,
        blue: .5,
        alpha: .1
    };
    var EntityInspectorTelemetry;
    (function(EntityInspectorTelemetry) {
        EntityInspectorTelemetry["EntitySelected"] = "Entity Selected";
    })(EntityInspectorTelemetry || (EntityInspectorTelemetry = {}));
    class PreviewBoundingBox {
        constructor(uiSession) {
            this._session = uiSession;
            this._outlineColor = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeFill);
            this._hullColor = this.session.extensionContext.settings.theme.resolveColorKey(server_editor_namespaceObject.ThemeSettingsColorKey.SelectionVolumeBorder);
            const dimensionBounds = this.session.extensionContext.blockUtilities.getDimensionLocationBoundingBox();
            const center = server_namespaceObject.BlockBoundingBoxUtils.getCenter(dimensionBounds);
            this._widgetGroup = this.session.extensionContext.widgetManager.createGroup({
                visible: true
            });
            this._widget = this._widgetGroup.createWidget(center, {
                visible: false,
                selectable: false
            });
            this._widgetBoxComponent = this._widget.addBoundingBox("bounding box", lib.VECTOR3_ONE, {
                outlineColor: this._outlineColor,
                hullColor: this._hullColor,
                visible: true
            });
        }
        teardown() {
            this._widgetBoxComponent.delete();
            this._widget.delete();
            this._widgetGroup.delete();
        }
        get session() {
            return this._session;
        }
        get visible() {
            return this._widget.visible;
        }
        set visible(value) {
            this._widget.visible = value;
        }
        get location() {
            return this._widget.location;
        }
        set location(position) {
            this._widget.location = position;
        }
        set outlineColor(value) {
            this._outlineColor = value;
            this._widgetBoxComponent.outlineColor = value;
        }
        set hullColor(value) {
            this._hullColor = value;
            this._widgetBoxComponent.hullColor = value;
        }
    }
    class EntityInspector {
        constructor(session) {
            this._session = session;
            this.telemetryManager = new TelemetryManager(session.extensionContext.player, TelemetrySource.EntityInspector);
            this._cursorProperties = {
                outlineColor: {
                    red: 1,
                    green: 1,
                    blue: 0,
                    alpha: 1
                },
                controlMode: server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse,
                targetMode: server_editor_namespaceObject.CursorTargetMode.Face,
                visible: true,
                fixedModeDistance: 5
            };
            this._preview = new PreviewBoundingBox(this._session);
            this._preview.outlineColor = PreviewColor;
            this._preview.hullColor = FillColor;
            const activationAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._session.toolRail.setSelectedToolId(this._tool.id);
                }
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, activationAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_I,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editorCore:entityInspector:toggleTool",
                label: "resourcePack.editor.toolRail.entityInspector.keyBinding.toggleTool.title",
                tooltip: "resourcePack.editor.toolRail.entityInspector.keyBinding.toggleTool.tooltip"
            });
            this._tool = this._session.toolRail.addTool(EntityInspector.MODAL_TOOL_ID, {
                title: "resourcePack.editor.toolRail.entityInspector.tool.title",
                icon: "pack://textures/editor/Entity-Edit.png?filtering=point",
                tooltip: {
                    description: "resourcePack.editor.toolRail.entityInspector.tool.tip",
                    image: "pack://textures/editor/EntityInspector.gif"
                },
                action: activationAction
            });
            this._tool.onModalToolActivation.subscribe((evt => {
                if (evt.isActiveTool) {
                    this._session.extensionContext.cursor.pushPropertiesById(this._cursorProperties, EntityInspector.MODAL_TOOL_ID);
                } else {
                    this._session.extensionContext.cursor.popPropertiesById(EntityInspector.MODAL_TOOL_ID);
                }
            }));
            this._registerToolKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.clearSelection();
                    this.showHelpPane();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_D,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, "clear");
            {
                this._pane = this._session.createPropertyPane({
                    title: "resourcePack.editor.toolRail.entityInspector.pane.title",
                    infoTooltip: {
                        description: [ "resourcePack.editor.toolRail.entityInspector.tool.tip", {
                            link: "https://aka.ms/BedrockEditorEntityInspector",
                            text: "resourcePack.editor.help.learnMore"
                        } ]
                    }
                });
                this._tool.bindPropertyPane(this._pane);
                this.showHelpPane();
            }
            const executeMouseButtonAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction !== server_editor_namespaceObject.MouseActionType.LeftButton) {
                        return;
                    }
                    const buttonDown = mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown;
                    if (buttonDown) {
                        const player = this._session.extensionContext.player;
                        const dimension = player.dimension;
                        const entityHitList = dimension.getEntitiesFromRay(mouseRay.location, mouseRay.direction);
                        let hitEntity = undefined;
                        if (entityHitList.length > 1) {
                            hitEntity = entityHitList[1];
                            if (hitEntity.entity !== this._selectedEntity) {
                                this.selectEntity(hitEntity.entity);
                                this.telemetryManager.fireTelemetryEvent(EntityInspectorTelemetry.EntitySelected);
                            }
                        } else {
                            this.clearSelection();
                            this.showHelpPane();
                        }
                    }
                }
            });
            this._tool.registerMouseButtonBinding(executeMouseButtonAction);
        }
        selectEntity(entity) {
            if (this._helpPane) {
                this._pane.removeSubPane(this._helpPane);
            }
            this.clearSelection();
            this._selectedEntity = entity;
            this._entityComponents = entity.getComponents();
            this.updateSelectionPreview();
            this._generalPane = this._pane.createSubPane({
                hasExpander: false
            });
            this.addGeneralPaneData(this._generalPane, entity);
            this.addEntityComponents(this._pane, this._entityComponents);
        }
        addGeneralPaneData(generalDataPane, entity) {
            const id = entity.id;
            const typeId = entity.typeId;
            const name = entity.nameTag;
            const dimId = entity.dimension.id;
            const pos = entity.location;
            const rot = entity.getRotation();
            generalDataPane.beginConstruct();
            generalDataPane.addString(typeId, {
                title: "resourcePack.editor.toolRail.entityInspector.tool.type",
                tooltip: "resourcePack.editor.toolRail.entityInspector.tool.type",
                enable: false
            });
            generalDataPane.addString(id, {
                title: "resourcePack.editor.toolRail.entityInspector.tool.id",
                tooltip: "resourcePack.editor.toolRail.entityInspector.tool.id.tooltip",
                enable: false
            });
            generalDataPane.addString(name, {
                title: "resourcePack.editor.toolRail.entityInspector.tool.nametag",
                tooltip: "resourcePack.editor.toolRail.entityInspector.tool.nametag.tooltip",
                onChange: newValue => {
                    entity.nameTag = newValue;
                }
            });
            generalDataPane.addVector3(pos, {
                title: "resourcePack.editor.toolRail.entityInspector.tool.location",
                tooltip: "resourcePack.editor.toolRail.entityInspector.tool.location.tooltip",
                enable: false,
                isInteger: true
            });
            generalDataPane.addNumber(Math.round(rot.y), {
                title: "resourcePack.editor.toolRail.entityInspector.tool.rotation",
                tooltip: "resourcePack.editor.toolRail.entityInspector.tool.rotation.tooltip",
                isInteger: true,
                enable: false,
                min: -180,
                max: 180,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputField
            });
            const dim = dimId.split(":");
            generalDataPane.addString(dim[dim.length - 1], {
                title: "resourcePack.editor.toolRail.entityInspector.tool.dimension",
                tooltip: "resourcePack.editor.toolRail.entityInspector.tool.dimension.tooltip",
                enable: false
            });
            this.addEntityTags(generalDataPane, entity.getTags());
            this.addEntityEffects(generalDataPane, entity.getEffects());
            generalDataPane.endConstruct();
        }
        addEntityComponents(parentPane, entityComponents) {
            if (entityComponents.length !== 0) {
                const componentPane = parentPane.createSubPane({
                    title: "resourcePack.editor.toolRail.entityInspector.tool.components",
                    infoTooltip: {
                        title: "resourcePack.editor.toolRail.entityInspector.tool.components",
                        description: [ "resourcePack.editor.toolRail.entityInspector.tool.components.tooltip" ]
                    }
                });
                this._componentPane = componentPane;
                entityComponents.forEach((value => {
                    getEntityBlockComponentUIForComponent(value)?.construct(componentPane, value);
                }));
                this._componentPane.show();
            }
        }
        addEntityTags(parentPane, entityTags) {
            if (entityTags.length !== 0) {
                const tagsPane = parentPane.createSubPane({
                    title: "Entity Tags"
                });
                for (let i = 0; i < entityTags.length; ++i) {
                    const tagKey = `Tag ${i}`;
                    tagsPane.addString(entityTags[i], {
                        title: tagKey,
                        enable: false
                    });
                }
            }
        }
        addEntityEffects(parentPane, entityEffects) {
            if (entityEffects.length !== 0) {
                const effectsPane = parentPane.createSubPane({
                    title: "Effects"
                });
                for (let i = 0; i < entityEffects.length; ++i) {
                    const effectKey = `Effect ${i}`;
                    effectsPane.addString(entityEffects[i].displayName, {
                        title: effectKey,
                        enable: false
                    });
                }
            }
        }
        teardown() {
            this._preview.teardown();
        }
        clearSelection() {
            this._selectedEntity = undefined;
            this._entityComponents = undefined;
            this.updateSelectionPreview();
            if (this._generalPane) {
                this._pane.removeSubPane(this._generalPane);
            }
            if (this._componentPane) {
                this._pane.removeSubPane(this._componentPane);
            }
            this._generalPane = undefined;
            this._componentPane = undefined;
        }
        showHelpPane() {
            if (this._helpPane === undefined) {
                const subPane = this._pane.createSubPane({
                    hasExpander: false,
                    hasMargins: false
                });
                subPane.addText("resourcePack.editor.toolRail.entityInspector.pane.helpText");
                this._helpPane = subPane;
            }
        }
        updateSelectionPreview(highlight = false) {
            if (this._selectedEntity) {
                this._preview.visible = true;
                this._preview.location = this._selectedEntity.location;
                if (highlight) {
                    this._preview.outlineColor = HighlightColor;
                } else {
                    this._preview.outlineColor = PreviewColor;
                }
            } else {
                this._preview.visible = false;
            }
        }
        _registerToolKeyBinding(action, binding, tag) {
            this._tool.registerKeyBinding(action, binding, {
                uniqueId: `editor:entityInspectorKeyBinding:${tag}`,
                label: `resourcePack.editor.toolRail.entityInspector.keyBinding.${tag}.title`,
                tooltip: `resourcePack.editor.toolRail.entityInspector.keyBinding.${tag}.tooltip`
            });
        }
    }
    EntityInspector.MODAL_TOOL_ID = "editor:EntityInspector";
    var RealmsTelemetry;
    (function(RealmsTelemetry) {
        RealmsTelemetry["RealmUploadPaneOpened"] = "RealmUploadPaneOpened";
        RealmsTelemetry["FetchWorldsAttempt"] = "FetchWorldsAttempt";
        RealmsTelemetry["FetchWorldsSuccess"] = "FetchWorldsSuccess";
        RealmsTelemetry["FetchWorldsFailure"] = "FetchWorldsFailure";
        RealmsTelemetry["FetchWorldSlotsAttempt"] = "FetchWorldSlotsAttempt";
        RealmsTelemetry["FetchWorldSlotsSuccess"] = "FetchWorldSlotsSuccess";
        RealmsTelemetry["FetchWorldSlotsFailure"] = "FetchWorldSlotsFailure";
        RealmsTelemetry["RefreshButtonForNotLoggedInUserPressed"] = "RefreshButtonForNotLoggedInUserPressed";
        RealmsTelemetry["RealmsWorldDropdownChanged"] = "RealmsWorldDropdownChanged";
        RealmsTelemetry["RealmUploadCancelledOnConfirmationScreen"] = "RealmUploadCancelledOnConfirmationScreen";
        RealmsTelemetry["RealmUploadConfirmedOnConfirmationScreen"] = "RealmUploadConfirmedOnConfirmationScreen";
        RealmsTelemetry["RealmDownloadWorldSlotAttempt"] = "RealmDownloadWorldSlotAttempt";
        RealmsTelemetry["RealmDownloadWorldSlotSuccess"] = "RealmDownloadWorldSlotSuccess";
        RealmsTelemetry["RealmDownloadWorldSlotFailure"] = "RealmDownloadWorldSlotFailure";
        RealmsTelemetry["ConfirmationOptOutCheckboxChanged"] = "ConfirmationOptOutCheckboxChanged";
    })(RealmsTelemetry || (RealmsTelemetry = {}));
    class RealmsUpload {
        constructor(_uiSession, menu) {
            this._uiSession = _uiSession;
            this._userAuthState = server_editor_private_bindings_namespaceObject.EditorRealmsServiceAvailability.Unknown;
            this._currentSlots = [];
            const player = _uiSession.extensionContext.player;
            this._telemetryManager = new TelemetryManager(player, TelemetrySource.RealmsUpload);
            this._skipUserUploadConfirmation = (0, server_editor_namespaceObject.makeObservable)(false);
            this._uploadStatusMessage = (0, server_editor_namespaceObject.makeObservable)("");
            this._unauthorizedPaneMessage = (0, server_editor_namespaceObject.makeObservable)("");
            this._realmsService = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(player).realmsService;
            this._userAuthState = this._realmsService.isRealmsServiceAvailable();
            this._rootPropertyPane = _uiSession.createPropertyPane({
                title: `resourcePack.editor.realmsPublish.title`,
                uniqueId: "editor:pane:realms",
                infoTooltip: {
                    description: [ "resourcePack.editor.realmsPublish.tooltip", {
                        link: "https://aka.ms/BedrockEditorRealms",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this._uploadProcessingModalScreen = this._rootPropertyPane.createModalOverlayPane({
                title: "resourcePack.editor.realmsPublish.title"
            });
            this._downloadProcessingModalScreen = this._rootPropertyPane.createModalOverlayPane({
                title: "resourcePack.editor.realmsPublish.title"
            });
            this._uploadConfirmationModalScreen = this._rootPropertyPane.createModalOverlayPane({
                title: "resourcePack.editor.realmsPublish.title"
            });
            this._buildPropertyPane(this._uiSession);
            this._addActionBarItem();
            this.createMenuItem(menu);
            this._rootPropertyPane.onPropertyPaneVisibilityUpdated.subscribe((eventData => {
                if (eventData.isVisible) {
                    this._refreshAuthStateAndView();
                } else {
                    if (this.tickHandle !== undefined) {
                        server_namespaceObject.system.clearRun(this.tickHandle);
                    }
                }
            }));
        }
        createMenuItem(menu) {
            menu.addItem({
                label: "resourcePack.editor.menuBar.file.realmsPublish",
                tooltip: "resourcePack.editor.menuBar.file.realmsPublish.tooltip"
            }, this._uiSession?.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._activateRealmsUploadPane();
                }
            }));
        }
        _activateRealmsUploadPane() {
            this._rootPropertyPane.show();
            if (this._uploadStatusMessagePane) {
                this._uploadStatusMessagePane.visible = false;
            }
            this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.RealmUploadPaneOpened);
        }
        _addActionBarItem() {
            const showExportPaneAction = this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._activateRealmsUploadPane();
                }
            });
            this._uiSession.actionBar.registerItem(server_editor_namespaceObject.CoreActionBarItemType.Realms, showExportPaneAction, {
                label: "resourcePack.editor.menuBar.file.realmsPublish",
                icon: "pack://textures/editor/Realms.png",
                iconAnimation: {
                    frames: 15,
                    duration: 2e3,
                    delay: 5e3
                },
                tooltipTitle: "resourcePack.editor.menuBar.file.realmsPublish",
                tooltipDescription: "resourcePack.editor.menuBar.file.realmsPublish.tooltip",
                enabled: true,
                executeOnAdd: true
            });
        }
        _fetchUserAuthState() {
            this._userAuthState = this._realmsService.isRealmsServiceAvailable();
            if (this._userAuthState !== server_editor_private_bindings_namespaceObject.EditorRealmsServiceAvailability.Success) {
                if (this.tickHandle === undefined) {
                    this.tickHandle = server_namespaceObject.system.runInterval((() => {
                        this._fetchUserAuthState();
                        if (this._userAuthState === server_editor_private_bindings_namespaceObject.EditorRealmsServiceAvailability.Success && this.tickHandle !== undefined) {
                            this._updatePaneBasedOnAuthState();
                            server_namespaceObject.system.clearRun(this.tickHandle);
                        }
                    }), RealmsUpload.TICK_REFRESH_RATE);
                }
            }
            return this._userAuthState;
        }
        _updatePaneBasedOnAuthState() {
            switch (this._userAuthState) {
              case server_editor_private_bindings_namespaceObject.EditorRealmsServiceAvailability.NoRealmsSubscription:
                this._setUnauthorizedPane("resourcePack.editor.realmsPublish.noActiveRealmsSubscription", false, false);
                break;

              case server_editor_private_bindings_namespaceObject.EditorRealmsServiceAvailability.DedicatedServer:
                this._setUnauthorizedPane("resourcePack.editor.realmsPublish.dedicatedServerWarning", false, false);
                break;

              case server_editor_private_bindings_namespaceObject.EditorRealmsServiceAvailability.NotServerHost:
                this._setUnauthorizedPane("resourcePack.editor.realmsPublish.notSessionHostWarning", false, false);
                break;

              case server_editor_private_bindings_namespaceObject.EditorRealmsServiceAvailability.NotLoggedIn:
                this._setUnauthorizedPane("resourcePack.editor.realmsPublish.userNotLoggedIn", true, true);
                break;

              case server_editor_private_bindings_namespaceObject.EditorRealmsServiceAvailability.Success:
                this._fetchWorldsAndSlotsData();
                this._realmsLoggedInPane?.show();
                this._realmsNotLoggedInPane?.hide();
                break;

              case server_editor_private_bindings_namespaceObject.EditorRealmsServiceAvailability.Unknown:
              default:
                this._setUnauthorizedPane("resourcePack.editor.realmsPublish.genericRealmsIssue", false, true);
                break;
            }
            return this._userAuthState;
        }
        _refreshAuthStateAndView() {
            this._fetchUserAuthState();
            this._updatePaneBasedOnAuthState();
        }
        _setUnauthorizedPane(message, showLink, showRefreshButton) {
            if (this._unauthorizedPaneMessage && this._unauthorizedPaneLink && this._unauthorizedPaneButton) {
                this._unauthorizedPaneMessage.set(message);
                this._unauthorizedPaneButton.enable = showRefreshButton;
                this._unauthorizedPaneLink.enable = showLink;
            }
            this._realmsLoggedInPane?.hide();
            this._realmsNotLoggedInPane?.show();
        }
        _buildPropertyPane(uiSession) {
            this._createPaneForUnauthorizedUser(uiSession);
            this._createPaneForAuthorizedUser(uiSession);
        }
        _createPaneForUnauthorizedUser(uiSession) {
            if (this._realmsNotLoggedInPane) {
                return;
            }
            const realmsUploadPane = this._rootPropertyPane.createSubPane({
                hasExpander: false
            });
            realmsUploadPane.addText(this._unauthorizedPaneMessage, {
                visible: true
            });
            this._unauthorizedPaneLink = realmsUploadPane.addLink("https://www.minecraft.net/", {
                title: "resourcePack.editor.realmsPublish.goToMinecraftWebsite"
            });
            this._unauthorizedPaneButton = realmsUploadPane.addButton(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.RefreshButtonForNotLoggedInUserPressed);
                    this._refreshAuthStateAndView();
                }
            }), {
                title: `resourcePack.editor.realmsPublish.Refresh`
            });
            realmsUploadPane.hide();
            this._realmsNotLoggedInPane = realmsUploadPane;
        }
        _fetchWorldsAndSlotsData() {
            if (!this._realmsService.isRealmsServiceAvailable()) {
                return;
            }
            this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.FetchWorldsAttempt);
            this._realmsService.getRealmWorldlist().then((worlds => {
                this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.FetchWorldsSuccess, {
                    worlds
                });
                const realmsWorldsDropdownItems = worlds.map((world => {
                    const item = {
                        label: world.name,
                        value: Number(world.id)
                    };
                    return item;
                }));
                this._realmsWorldsDropdown?.updateEntries(realmsWorldsDropdownItems, realmsWorldsDropdownItems[0].value);
                this._uiSession.log.info(`Fetched ${worlds.length} realms`);
            })).catch((error => {
                this._uiSession.log.warning((0, server_editor_namespaceObject.stringFromException)(error));
                this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.FetchWorldsFailure, {
                    error: (0, server_editor_namespaceObject.stringFromException)(error)
                });
            }));
        }
        _updateSlotsForRealmId(realmId) {
            this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.FetchWorldSlotsAttempt, {
                realmId
            });
            this._realmsService.getSlots(String(realmId)).then((slots => {
                this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.FetchWorldSlotsSuccess, {
                    realmId,
                    slots
                });
                this._currentSlots = slots;
                const realmsWorldsSlotsDropdownItems = this._mapWorldSlotsToDropdownItemEntries(slots);
                this._realmsWorldsSlotsDropdown?.updateEntries(realmsWorldsSlotsDropdownItems);
                this._uiSession.log.info(`Fetched ${slots.length} slots for realm ${realmId}`);
            })).catch((error => {
                this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.FetchWorldSlotsFailure, {
                    realmId,
                    error: (0, server_editor_namespaceObject.stringFromException)(error)
                });
                this._uiSession.log.warning((0, server_editor_namespaceObject.stringFromException)(error));
            }));
        }
        _createPaneForAuthorizedUser(uiSession) {
            if (this._realmsLoggedInPane) {
                return;
            }
            this._realmsLoggedInPane = this._rootPropertyPane.createSubPane({
                hasExpander: false
            });
            this._realmsWorldsDropdown = this._realmsLoggedInPane.addDropdown(0, {
                title: `resourcePack.editor.realmsPublish.Realm`,
                tooltip: `resourcePack.editor.realmsPublish.Realm.tooltip`,
                entries: [],
                onChange: newValue => {
                    uiSession.log.info(`Selected Realm: ${newValue}`);
                    const realmId = String(newValue);
                    this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.RealmsWorldDropdownChanged, {
                        realmId
                    });
                    this._updateSlotsForRealmId(realmId);
                }
            });
            this._realmsWorldsSlotsDropdown = this._realmsLoggedInPane.addDropdown(0, {
                title: `resourcePack.editor.realmsPublish.RealmSlot`,
                tooltip: `resourcePack.editor.realmsPublish.RealmSlot.tooltip`,
                entries: [],
                onChange: newValue => {
                    if (newValue > this._currentSlots.length) {
                        this._uiSession.log.warning("Invalid slot selected");
                        return;
                    }
                    if (this._realmsDownloadButton) {
                        this._realmsDownloadButton.enable = this._currentSlots[newValue - 1].id !== -1;
                    }
                    if (this._realmsUploadButton) {
                        this._realmsUploadButton.enable = true;
                    }
                }
            });
            const versionNumber = this._uiSession.extensionContext.exportManager.getGameVersion();
            if (versionNumber) {
                const warningPane = this._realmsLoggedInPane.createSubPane({
                    title: `resourcePack.editor.exportProject.exportNotes`,
                    collapsed: true
                });
                warningPane.addText({
                    id: "resourcePack.editor.exportProject.exportNotes.warning",
                    props: [ `${versionNumber}` ]
                });
            }
            this._realmsLoggedInPane.addDivider();
            this._worldSettings = new WorldSettingsPane(uiSession, this._realmsLoggedInPane, false, false);
            this._worldSettings.BuildPropertyPane();
            this._realmsLoggedInPane.addDivider();
            const publishToRealmsButtonPane = this._realmsLoggedInPane.addButtonPane();
            this._realmsDownloadButton = publishToRealmsButtonPane.addButton(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._onDownloadFromRealmsButtonPress();
                }
            }), {
                title: `resourcePack.editor.realmsPublish.DownloadRealm`
            });
            this._realmsDownloadButton.enable = false;
            this._realmsUploadButton = publishToRealmsButtonPane.addButton(uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._onUploadToRealmsButtonPress();
                }
            }), {
                title: `resourcePack.editor.realmsPublish.PublishRealm`
            });
            this._realmsUploadButton.enable = false;
            this._uploadStatusMessagePane = this._realmsLoggedInPane.addText(this._uploadStatusMessage, {
                visible: false
            });
            this._realmsLoggedInPane.hide();
            this._createUploadModalPane();
        }
        _onDownloadFromRealmsButtonPress() {
            if (!this._realmsWorldsDropdown?.value) {
                this._uiSession.log.warning("Unable to publish to Realms. No Realm selected");
                return;
            }
            if (!this._realmsWorldsSlotsDropdown?.value) {
                this._uiSession.log.warning("Unable to publish to Realms. No Realm Slot selected");
                return;
            }
            this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.RealmDownloadWorldSlotAttempt, {
                worldSettings: this._worldSettings?.getGameOptions(),
                realmId: this._realmsWorldsDropdown?.value,
                realmSlotId: this._realmsWorldsSlotsDropdown?.value
            });
            this._rootPropertyPane.setActiveModalOverlay(this._downloadProcessingModalScreen.id);
            this._realmsService.beginDownloadFromRealms(this._realmsWorldsDropdown.value.toString(), this._realmsWorldsSlotsDropdown.value).then((() => {
                this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.RealmDownloadWorldSlotSuccess, {
                    worldSettings: this._worldSettings?.getGameOptions(),
                    realmId: this._realmsWorldsDropdown?.value,
                    realmSlotId: this._realmsWorldsSlotsDropdown?.value
                });
                this._uploadStatusMessage.set("resourcePack.editor.realmsPublish.DownloadSuccess");
                if (this._uploadStatusMessagePane) {
                    this._uploadStatusMessagePane.visible = true;
                }
            })).catch((() => {
                this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.RealmDownloadWorldSlotFailure, {
                    worldSettings: this._worldSettings?.getGameOptions(),
                    realmId: this._realmsWorldsDropdown?.value,
                    realmSlotId: this._realmsWorldsSlotsDropdown?.value
                });
                this._uiSession.log.warning("Download from Realms failed");
                this._uploadStatusMessage.set("resourcePack.editor.realmsPublish.DownloadFailed");
                if (this._uploadStatusMessagePane) {
                    this._uploadStatusMessagePane.visible = true;
                }
            })).finally((() => {
                this._downloadProcessingModalScreen.hide();
            }));
        }
        _onUploadToRealmsButtonPress() {
            if (!this._realmsWorldsDropdown?.value) {
                this._uiSession.log.warning("Unable to publish to Realms. No Realm selected");
                this._uploadStatusMessage.set("resourcePack.editor.realmsPublish.UnableToPublishMissingRealm");
                if (this._uploadStatusMessagePane) {
                    this._uploadStatusMessagePane.visible = true;
                }
                return;
            }
            if (!this._realmsWorldsSlotsDropdown?.value) {
                this._uiSession.log.warning("Unable to publish to Realms. No Realm Slot selected");
                this._uploadStatusMessage.set("resourcePack.editor.realmsPublish.UnableToPublishMissingRealmSlot");
                if (this._uploadStatusMessagePane) {
                    this._uploadStatusMessagePane.visible = true;
                }
                return;
            }
            if (this._skipUserUploadConfirmation.value) {
                this._rootPropertyPane.setActiveModalOverlay(this._uploadProcessingModalScreen.id);
                this._uploadToRealms();
            } else {
                this._rootPropertyPane.setActiveModalOverlay(this._uploadConfirmationModalScreen.id);
            }
        }
        _createUploadModalPane() {
            this._uploadConfirmationModalScreen.contentPane.addText("resourcePack.editor.realmsPublish.PublishConfirmationWarning", {
                border: false
            });
            this._uploadConfirmationModalScreen.controlPane.addBool(this._skipUserUploadConfirmation, {
                title: "resourcePack.editor.realmsPublish.PublishConfirmationOptOut",
                tooltip: "resourcePack.editor.realmsPublish.PublishConfirmationOptOut",
                onChange: newValue => {
                    this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.ConfirmationOptOutCheckboxChanged, {
                        newValue
                    });
                }
            });
            this._uploadConfirmationModalScreen.controlPane.addDivider();
            const confirmationScreenButtonPane = this._uploadConfirmationModalScreen.controlPane.addButtonPane();
            confirmationScreenButtonPane.addButton((() => {
                this._uploadConfirmationModalScreen.hide();
                this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.RealmUploadCancelledOnConfirmationScreen);
            }), {
                title: "resourcePack.editor.realmsPublish.Cancel"
            });
            confirmationScreenButtonPane.addButton((() => {
                this._uploadToRealms();
                this._uploadConfirmationModalScreen.hide();
                this._uploadProcessingModalScreen.show();
                this._telemetryManager.fireTelemetryEvent(RealmsTelemetry.RealmUploadConfirmedOnConfirmationScreen);
            }), {
                title: "resourcePack.editor.realmsPublish.Confirm",
                variant: server_editor_namespaceObject.ButtonVariant.Confirmation
            });
            this._uploadProcessingModalScreen = this._rootPropertyPane.createModalOverlayPane({
                title: "resourcePack.editor.menuBar.file.realmsPublish"
            });
            this._uploadProcessingModalScreen.contentPane.addText("resourcePack.editor.realmsPublish.PublishingToRealms", {
                border: false
            });
            this._uploadProcessingModalScreen.contentPane.addProgressIndicator();
            const processingScreenButtonPane = this._uploadProcessingModalScreen.controlPane.addButtonPane();
            processingScreenButtonPane.addButton((() => {
                this._uploadProcessingModalScreen.hide();
            }), {
                title: "resourcePack.editor.realmsPublish.Back"
            });
            this._downloadProcessingModalScreen = this._rootPropertyPane.createModalOverlayPane({
                title: "resourcePack.editor.menuBar.file.realmsPublish"
            });
            this._downloadProcessingModalScreen.contentPane.addText("resourcePack.editor.realmsPublish.DownloadingFromRealms", {
                border: false
            });
            this._downloadProcessingModalScreen.contentPane.addProgressIndicator();
        }
        _mapWorldSlotsToDropdownItemEntries(slots) {
            return slots.map(((slot, index) => {
                const item = {
                    label: slot.id === -1 ? "resourcePack.editor.realmsPublish.EmptySlot" : slot.name,
                    value: Number(index + 1),
                    imageData: slot.id === -1 ? {
                        path: "pack://textures/editor/Data-Empty.png?filtering=point",
                        type: server_editor_namespaceObject.ImageResourceType.Icon
                    } : undefined
                };
                return item;
            }));
        }
        _uploadToRealms() {
            if (this._worldSettings) {
                if (!this._realmsWorldsDropdown?.value) {
                    this._uiSession.log.warning("Unable to publish to Realms. No Realm selected");
                    return;
                }
                if (!this._realmsWorldsSlotsDropdown?.value) {
                    this._uiSession.log.warning("Unable to publish to Realms. No Realm Slot selected");
                    return;
                }
                if (this._realmsUploadButton) {
                    this._realmsUploadButton.enable = false;
                }
                fireTelemetryEvent(this._uiSession.extensionContext.player, TelemetrySource.RealmsUpload, "RealmUploadAttempt", {
                    worldSettings: this._worldSettings.getGameOptions(),
                    realmId: this._realmsWorldsDropdown.value,
                    realmSlotId: this._realmsWorldsSlotsDropdown.value
                });
                this._realmsService.beginUploadToRealms(this._realmsWorldsDropdown.value.toString(), this._realmsWorldsSlotsDropdown.value, this._worldSettings.getGameOptions()).then((status => {
                    switch (status) {
                      case server_editor_private_bindings_namespaceObject.RealmsWorldUploadResult.Success:
                        this._uiSession.log.warning("Publish to Realms was Successful");
                        this._uploadStatusMessage.set("resourcePack.editor.realmsPublish.PublishSuccess");
                        if (this._realmsWorldsDropdown?.value) {
                            const realmId = this._realmsWorldsDropdown.value.toString();
                            this._updateSlotsForRealmId(realmId);
                            fireTelemetryEvent(this._uiSession.extensionContext.player, TelemetrySource.RealmsUpload, "RealmUploadSuccess", {
                                worldSettings: this._worldSettings?.getGameOptions(),
                                realmId: this._realmsWorldsDropdown.value,
                                realmSlotId: this._realmsWorldsSlotsDropdown?.value
                            });
                        }
                        break;

                      case server_editor_private_bindings_namespaceObject.RealmsWorldUploadResult.WorldNameNonCompliant:
                        this._uiSession.log.error("Publish to Realms failed due to an invalid world name", {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        this._uploadStatusMessage.set("resourcePack.editor.realmsPublish.PublishFailedNonCompliantWorldName");
                        fireTelemetryEvent(this._uiSession.extensionContext.player, TelemetrySource.RealmsUpload, "RealmUploadFailure", {
                            worldSettings: this._worldSettings?.getGameOptions(),
                            realmId: this._realmsWorldsDropdown?.value,
                            realmSlotId: this._realmsWorldsSlotsDropdown?.value,
                            error: "WorldNameNonCompliant"
                        });
                        break;

                      default:
                        this._uiSession.log.error("Publish to Realms failed", {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        this._uploadStatusMessage.set("resourcePack.editor.realmsPublish.PublishFailed");
                        fireTelemetryEvent(this._uiSession.extensionContext.player, TelemetrySource.RealmsUpload, "RealmUploadFailure", {
                            worldSettings: this._worldSettings?.getGameOptions(),
                            realmId: this._realmsWorldsDropdown?.value,
                            realmSlotId: this._realmsWorldsSlotsDropdown?.value
                        });
                        break;
                    }
                })).catch((() => {
                    this._uiSession.log.warning("Publish to Realms failed");
                    this._uploadStatusMessage.set("resourcePack.editor.realmsPublish.PublishFailed");
                    fireTelemetryEvent(this._uiSession.extensionContext.player, TelemetrySource.RealmsUpload, "RealmUploadFailure", {
                        worldSettings: this._worldSettings?.getGameOptions(),
                        realmId: this._realmsWorldsDropdown?.value,
                        realmSlotId: this._realmsWorldsSlotsDropdown?.value
                    });
                })).finally((() => {
                    if (this._realmsUploadButton) {
                        this._realmsUploadButton.enable = true;
                    }
                    if (this._uploadStatusMessagePane) {
                        this._uploadStatusMessagePane.visible = true;
                    }
                    this._uploadProcessingModalScreen.hide();
                }));
            }
        }
        teardown() {
            if (this.tickHandle !== undefined) {
                server_namespaceObject.system.clearRun(this.tickHandle);
            }
        }
    }
    RealmsUpload.TICK_REFRESH_RATE = 5;
    var OrbitTurnDirection;
    (function(OrbitTurnDirection) {
        OrbitTurnDirection[OrbitTurnDirection["Left"] = 0] = "Left";
        OrbitTurnDirection[OrbitTurnDirection["Right"] = 1] = "Right";
    })(OrbitTurnDirection || (OrbitTurnDirection = {}));
    var OrbitTarget;
    (function(OrbitTarget) {
        OrbitTarget[OrbitTarget["Cursor"] = 0] = "Cursor";
        OrbitTarget[OrbitTarget["Selection"] = 1] = "Selection";
    })(OrbitTarget || (OrbitTarget = {}));
    const MAX_ORBIT_RADIUS = 200;
    class OrbitLocationBehavior {
        constructor(_session) {
            this._session = _session;
            this._tickHandle = undefined;
            this._prevCameraLocation = undefined;
            this._targetLocation = undefined;
            this._turnDirections = [];
            this._degreesPerSecond = 120;
            const turnCursorLeftAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.StatefulAction,
                onExecute: state => {
                    this._handleOrbit(OrbitTarget.Cursor, OrbitTurnDirection.Left, state);
                }
            });
            const turnCursorRightAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.StatefulAction,
                onExecute: state => {
                    this._handleOrbit(OrbitTarget.Cursor, OrbitTurnDirection.Right, state);
                }
            });
            const turnSelectionLeftAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.StatefulAction,
                onExecute: state => {
                    this._handleOrbit(OrbitTarget.Selection, OrbitTurnDirection.Left, state);
                }
            });
            const turnSelectionRightAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.StatefulAction,
                onExecute: state => {
                    this._handleOrbit(OrbitTarget.Selection, OrbitTurnDirection.Right, state);
                }
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, turnCursorLeftAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_Z
            }, {
                uniqueId: "editor:viewportKeyBinding:orbitCursorLeft",
                label: "resourcePack.editor.viewport.keyBinding.orbitCursorLeft.title",
                tooltip: "resourcePack.editor.viewport.keyBinding.orbitCursorLeft.tooltip"
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, turnCursorRightAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_C
            }, {
                uniqueId: "editor:viewportKeyBinding:orbitCursorRight",
                label: "resourcePack.editor.viewport.keyBinding.orbitCursorRight.title",
                tooltip: "resourcePack.editor.viewport.keyBinding.orbitCursorRight.tooltip"
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, turnSelectionLeftAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_Z,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editor:viewportKeyBinding:orbitSelectionLeft",
                label: "resourcePack.editor.viewport.keyBinding.orbitSelectionLeft.title",
                tooltip: "resourcePack.editor.viewport.keyBinding.orbitSelectionLeft.tooltip"
            });
            this._session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, turnSelectionRightAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_C,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editor:viewportKeyBinding:orbitSelectionRight",
                label: "resourcePack.editor.viewport.keyBinding.orbitSelectionRight.title",
                tooltip: "resourcePack.editor.viewport.keyBinding.orbitSelectionRight.tooltip"
            });
        }
        teardown() {
            this._resetState();
        }
        _handleOrbit(target, direction, state) {
            if (state) {
                if (!this._turnDirections.includes(direction)) {
                    this._turnDirections.push(direction);
                }
                this._tryStartOrbit(target);
            } else {
                this._turnDirections = this._turnDirections.filter((dir => dir !== direction));
                this._tryEndOrbit();
            }
        }
        _tryStartOrbit(target) {
            if (this._tickHandle !== undefined) {
                return;
            }
            this._targetLocation = this._getTargetLocation(target);
            if (this._targetLocation === undefined) {
                return;
            }
            const player = this._session.extensionContext.player;
            this._prevCameraLocation = player.getHeadLocation();
            this._tickHandle = server_namespaceObject.system.runInterval((() => {
                if (this._targetLocation) {
                    this._orbitAroundLookAt(this._degreesPerSecond / server_namespaceObject.TicksPerSecond, this._targetLocation);
                }
            }), 1);
        }
        _tryEndOrbit() {
            if (this._turnDirections.length === 0) {
                this._resetState();
            }
        }
        _resetState() {
            const player = this._session.extensionContext.player;
            if (this._tickHandle !== undefined) {
                server_namespaceObject.system.clearRun(this._tickHandle);
                this._tickHandle = undefined;
                player.camera.setCamera("minecraft:first_person");
            }
            if (this._prevCameraLocation && this._targetLocation) {
                const headOffset = lib.Vector3Utils.subtract(player.getHeadLocation(), player.location);
                player.teleport(lib.Vector3Utils.subtract(this._prevCameraLocation, headOffset), {
                    facingLocation: lib.Vector3Utils.subtract(this._targetLocation, headOffset)
                });
                this._prevCameraLocation = undefined;
                this._targetLocation = undefined;
            }
            this._turnDirections = [];
        }
        _orbitAroundLookAt(turnDegrees, targetLocation) {
            const player = this._session.extensionContext.player;
            if (!this._prevCameraLocation || this._turnDirections.length === 0) {
                return;
            }
            const activeTurnDirection = this._turnDirections[0];
            const degreeSign = activeTurnDirection === OrbitTurnDirection.Left ? -1 : 1;
            const dx = this._prevCameraLocation.x - targetLocation.x;
            const dz = this._prevCameraLocation.z - targetLocation.z;
            const orbitRadius = Math.min(Math.sqrt(dx * dx + dz * dz), MAX_ORBIT_RADIUS);
            const currentAngle = Math.atan2(dx, dz);
            const turnRadians = turnDegrees * degreeSign * (Math.PI / 180);
            const newAngle = currentAngle + turnRadians;
            const cameraLocation = {
                x: targetLocation.x + orbitRadius * Math.sin(newAngle),
                y: this._prevCameraLocation.y,
                z: targetLocation.z + orbitRadius * Math.cos(newAngle)
            };
            player.camera.setCamera("minecraft:free", {
                location: cameraLocation,
                facingLocation: targetLocation,
                easeOptions: {
                    easeTime: 1 / server_namespaceObject.TicksPerSecond,
                    easeType: server_namespaceObject.EasingType.Linear
                }
            });
            this._prevCameraLocation = {
                ...cameraLocation
            };
        }
        _getTargetLocation(target) {
            if (target === OrbitTarget.Cursor) {
                return this._session.extensionContext.cursor.getPosition();
            } else if (target === OrbitTarget.Selection) {
                try {
                    if (!this._session.extensionContext.selectionManager.volume.isEmpty) {
                        const volumeBounds = this._session.extensionContext.selectionManager.volume.getBoundingBox();
                        const center = server_namespaceObject.BlockBoundingBoxUtils.getCenter(volumeBounds);
                        return center;
                    }
                } catch (_) {}
                this._session.log.warning("Orbiting not performed due to invalid selection");
            }
            return undefined;
        }
    }
    var MinecraftBedColors;
    (function(MinecraftBedColors) {
        MinecraftBedColors[MinecraftBedColors["White"] = 0] = "White";
        MinecraftBedColors[MinecraftBedColors["Orange"] = 1] = "Orange";
        MinecraftBedColors[MinecraftBedColors["Magenta"] = 2] = "Magenta";
        MinecraftBedColors[MinecraftBedColors["LightBlue"] = 3] = "LightBlue";
        MinecraftBedColors[MinecraftBedColors["Yellow"] = 4] = "Yellow";
        MinecraftBedColors[MinecraftBedColors["Lime"] = 5] = "Lime";
        MinecraftBedColors[MinecraftBedColors["Pink"] = 6] = "Pink";
        MinecraftBedColors[MinecraftBedColors["Gray"] = 7] = "Gray";
        MinecraftBedColors[MinecraftBedColors["LightGray"] = 8] = "LightGray";
        MinecraftBedColors[MinecraftBedColors["Cyan"] = 9] = "Cyan";
        MinecraftBedColors[MinecraftBedColors["Purple"] = 10] = "Purple";
        MinecraftBedColors[MinecraftBedColors["Blue"] = 11] = "Blue";
        MinecraftBedColors[MinecraftBedColors["Brown"] = 12] = "Brown";
        MinecraftBedColors[MinecraftBedColors["Green"] = 13] = "Green";
        MinecraftBedColors[MinecraftBedColors["Red"] = 14] = "Red";
        MinecraftBedColors[MinecraftBedColors["Black"] = 15] = "Black";
    })(MinecraftBedColors || (MinecraftBedColors = {}));
    function buildDefaultObjectDatabaseEntries() {
        return [ {
            itemId: MinecraftItemTypes.AcaciaDoor
        }, {
            itemId: MinecraftItemTypes.BambooDoor
        }, {
            itemId: MinecraftItemTypes.BirchDoor
        }, {
            itemId: MinecraftItemTypes.CherryDoor
        }, {
            itemId: MinecraftItemTypes.CopperDoor
        }, {
            itemId: MinecraftItemTypes.CrimsonDoor
        }, {
            itemId: MinecraftItemTypes.DarkOakDoor
        }, {
            itemId: MinecraftItemTypes.ExposedCopperDoor
        }, {
            itemId: MinecraftItemTypes.IronDoor
        }, {
            itemId: MinecraftItemTypes.JungleDoor
        }, {
            itemId: MinecraftItemTypes.MangroveDoor
        }, {
            itemId: MinecraftItemTypes.OxidizedCopperDoor
        }, {
            itemId: MinecraftItemTypes.PaleOakDoor
        }, {
            itemId: MinecraftItemTypes.SpruceDoor
        }, {
            itemId: MinecraftItemTypes.WarpedDoor
        }, {
            itemId: MinecraftItemTypes.WaxedCopperDoor
        }, {
            itemId: MinecraftItemTypes.WaxedExposedCopperDoor
        }, {
            itemId: MinecraftItemTypes.WaxedOxidizedCopperDoor
        }, {
            itemId: MinecraftItemTypes.WaxedWeatheredCopperDoor
        }, {
            itemId: MinecraftItemTypes.WeatheredCopperDoor
        }, {
            itemId: MinecraftItemTypes.WoodenDoor
        }, {
            label: "item.bed.white.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.White
        }, {
            label: "item.bed.brown.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Brown
        }, {
            label: "item.bed.orange.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Orange
        }, {
            label: "item.bed.silver.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.LightGray
        }, {
            label: "item.bed.gray.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Gray
        }, {
            label: "item.bed.black.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Black
        }, {
            label: "item.bed.red.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Red
        }, {
            label: "item.bed.yellow.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Yellow
        }, {
            label: "item.bed.lime.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Lime
        }, {
            label: "item.bed.green.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Green
        }, {
            label: "item.bed.cyan.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Cyan
        }, {
            label: "item.bed.lightBlue.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.LightBlue
        }, {
            label: "item.bed.blue.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Blue
        }, {
            label: "item.bed.purple.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Purple
        }, {
            label: "item.bed.magenta.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Magenta
        }, {
            label: "item.bed.pink.name",
            itemId: MinecraftItemTypes.Bed,
            aux: MinecraftBedColors.Pink
        }, {
            itemId: MinecraftItemTypes.TallGrass
        }, {
            itemId: MinecraftItemTypes.TurtleEgg
        }, {
            itemId: MinecraftItemTypes.Sunflower
        }, {
            itemId: MinecraftItemTypes.Lilac
        }, {
            itemId: MinecraftItemTypes.Peony
        }, {
            itemId: MinecraftItemTypes.RoseBush
        }, {
            itemId: MinecraftItemTypes.TallDryGrass
        }, {
            itemId: MinecraftItemTypes.LargeFern
        }, {
            itemId: MinecraftItemTypes.PitcherPlant
        }, {
            itemId: MinecraftItemTypes.LeafLitter
        }, {
            itemId: MinecraftItemTypes.PinkPetals
        }, {
            itemId: MinecraftItemTypes.Wildflowers
        }, {
            itemId: MinecraftItemTypes.SeaPickle
        }, {
            itemId: MinecraftItemTypes.Torch
        }, {
            itemId: MinecraftItemTypes.SoulTorch
        }, {
            itemId: MinecraftItemTypes.Candle
        }, {
            itemId: MinecraftItemTypes.BlackCandle
        }, {
            itemId: MinecraftItemTypes.BlueCandle
        }, {
            itemId: MinecraftItemTypes.BrownCandle
        }, {
            itemId: MinecraftItemTypes.CyanCandle
        }, {
            itemId: MinecraftItemTypes.GrayCandle
        }, {
            itemId: MinecraftItemTypes.GreenCandle
        }, {
            itemId: MinecraftItemTypes.LightBlueCandle
        }, {
            itemId: MinecraftItemTypes.LightGrayCandle
        }, {
            itemId: MinecraftItemTypes.LimeCandle
        }, {
            itemId: MinecraftItemTypes.MagentaCandle
        }, {
            itemId: MinecraftItemTypes.OrangeCandle
        }, {
            itemId: MinecraftItemTypes.PinkCandle
        }, {
            itemId: MinecraftItemTypes.PurpleCandle
        }, {
            itemId: MinecraftItemTypes.RedCandle
        }, {
            itemId: MinecraftItemTypes.WhiteCandle
        }, {
            itemId: MinecraftItemTypes.YellowCandle
        }, {
            itemId: MinecraftItemTypes.Potato
        }, {
            itemId: MinecraftItemTypes.Carrot
        }, {
            itemId: MinecraftItemTypes.BeetrootSeeds
        }, {
            itemId: MinecraftItemTypes.MelonSeeds
        }, {
            itemId: MinecraftItemTypes.PumpkinSeeds
        }, {
            itemId: MinecraftItemTypes.TorchflowerSeeds
        }, {
            itemId: MinecraftItemTypes.WheatSeeds
        }, {
            itemId: MinecraftItemTypes.BoneMeal
        }, {
            itemId: MinecraftItemTypes.SweetBerries
        }, {
            itemId: MinecraftItemTypes.NetherWart
        } ];
    }
    class ObjectDatabase {
        constructor(session) {
            this._items = buildDefaultObjectDatabaseEntries();
            this._session = session;
        }
        getEntry(index) {
            return index < this._items.length ? this._items[index] : undefined;
        }
        buildComboboxEntries() {
            const returnList = [];
            for (let i = 0; i < this._items.length; ++i) {
                const entry = this._items[i];
                const label = entry.label ?? new server_namespaceObject.ItemStack(entry.itemId).localizationKey;
                if (entry.itemId.indexOf(ObjectDatabase._minecraftPrefix) !== 0) {
                    this._session.log.error(`Unexpected item id format.  Expect '${ObjectDatabase._minecraftPrefix}' at start.`);
                    return [];
                }
                const value = entry.itemId.substring(ObjectDatabase._minecraftPrefix.length) + (entry.aux ? ":" + entry.aux.toString() : "");
                returnList.push({
                    value,
                    label
                });
            }
            return returnList;
        }
        getDataEntryFromComboboxValue(comboboxData) {
            let itemName;
            let auxValue;
            if (comboboxData.includes(":")) {
                const pieces = comboboxData.split(`:`);
                itemName = ObjectDatabase._minecraftPrefix + pieces[0];
                auxValue = Number(pieces[1]);
            } else {
                itemName = ObjectDatabase._minecraftPrefix + comboboxData;
            }
            return {
                itemId: itemName,
                aux: auxValue
            };
        }
        static buildEncodedType(itemId) {
            if (itemId.includes(ObjectDatabase._minecraftPrefix)) {
                return itemId.substring(ObjectDatabase._minecraftPrefix.length);
            } else {
                return MinecraftItemTypes.AcaciaDoor.substring(ObjectDatabase._minecraftPrefix.length);
            }
        }
    }
    ObjectDatabase._minecraftPrefix = `minecraft:`;
    var PencilDrawType;
    (function(PencilDrawType) {
        PencilDrawType[PencilDrawType["Block"] = 0] = "Block";
        PencilDrawType[PencilDrawType["Object"] = 1] = "Object";
    })(PencilDrawType || (PencilDrawType = {}));
    const drawTypeToggleBindingId = "editor:pencil:toggleDrawMode";
    class PencilDrawTypeSettings {
        constructor(session, parent) {
            this._drawType = (0, server_editor_namespaceObject.makeObservable)(PencilDrawType.Block);
            this._objectTypeToPlace = (0, server_editor_namespaceObject.makeObservable)(ObjectDatabase.buildEncodedType(MinecraftItemTypes.AcaciaDoor));
            this._session = session;
            this._parent = parent;
            this._database = new ObjectDatabase(session);
            this.buildKeyboardShortcuts(parent.getTool());
        }
        addDrawModeToggle(pane) {
            pane.addToggleGroup(this._drawType, {
                title: "resourcePack.editor.pencil.drawtype.title",
                tooltip: "resourcePack.editor.pencil.drawtype.tooltip",
                hiddenLabel: false,
                entries: [ {
                    value: PencilDrawType.Block,
                    icon: "blocksIcon",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.pencil.drawtype.blocks.title",
                            props: [ getInputMarkup(drawTypeToggleBindingId) ]
                        },
                        description: {
                            id: "resourcePack.editor.pencil.drawtype.blocks.tooltip",
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup(drawTypeToggleBindingId) ]
                        }
                    }
                }, {
                    value: PencilDrawType.Object,
                    icon: "pack://textures/editor/ObjectTool.png?filtering=point",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.pencil.drawtype.objects.title",
                            props: [ getInputMarkup(drawTypeToggleBindingId) ]
                        },
                        description: {
                            id: "resourcePack.editor.pencil.drawtype.objects.tooltip",
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup(drawTypeToggleBindingId) ]
                        }
                    }
                } ],
                onChange: newValue => this.onDrawTypeChange(newValue)
            });
        }
        addObjectDropdown(pane) {
            this._objectCombobox = pane.addComboBox(this._objectTypeToPlace, {
                dataType: server_editor_namespaceObject.ComboBoxPropertyItemDataType.Custom,
                title: "resourcePack.editor.pencil.drawtype.objectpicker.title",
                tooltip: "resourcePack.editor.pencil.drawtype.objectpicker.tooltip",
                entries: this._database.buildComboboxEntries(),
                visible: this._drawType.value === PencilDrawType.Object,
                defaultValue: ObjectDatabase.buildEncodedType(MinecraftItemTypes.AcaciaDoor),
                onChange: newValue => {
                    if (this._drawType.value === PencilDrawType.Object) {
                        this.enableItemPlacementFromEncodedType(newValue);
                    }
                    this._parent.saveSettings();
                }
            });
        }
        activate() {
            if (this._drawType.value === PencilDrawType.Object) {
                this.enableItemPlacementFromEncodedType(this._objectTypeToPlace.value);
            }
        }
        deactivate() {
            this._session.extensionContext.brushShapeManager.disableItemPlacement();
        }
        setStorage(data) {
            this._drawType.set(data.drawType);
            this._objectTypeToPlace.set(data.objectTypeSelected);
        }
        getStorage() {
            return {
                drawType: this._drawType.value,
                objectTypeSelected: this._objectTypeToPlace.value
            };
        }
        getDrawType() {
            return this._drawType.value;
        }
        getSelectedObjectBlock() {
            const entry = this._database.getDataEntryFromComboboxValue(this._objectTypeToPlace.value);
            return entry.itemId;
        }
        onDrawTypeChange(newValue) {
            this._parent.onDrawTypeChanged();
            if (newValue === PencilDrawType.Block) {
                this._session.extensionContext.brushShapeManager.disableItemPlacement();
            } else {
                this.enableItemPlacementFromEncodedType(this._objectTypeToPlace.value);
            }
            if (this._objectCombobox) {
                this._objectCombobox.visible = newValue === PencilDrawType.Object;
            }
            this._parent.saveSettings();
        }
        enableItemPlacementFromEncodedType(encodedType) {
            const entry = this._database.getDataEntryFromComboboxValue(encodedType);
            const itemType = server_namespaceObject.ItemTypes.get(entry.itemId);
            if (!itemType) {
                return false;
            }
            if (entry.aux) {
                this._session.extensionContext.brushShapeManager.enableItemPlacement(itemType, entry.aux);
            } else {
                this._session.extensionContext.brushShapeManager.enableItemPlacement(itemType);
            }
            return true;
        }
        buildKeyboardShortcuts(parentTool) {
            const toggleDrawModeAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const newDrawMode = this._drawType.value === PencilDrawType.Block ? PencilDrawType.Object : PencilDrawType.Block;
                    this._drawType.set(newDrawMode);
                    this.onDrawTypeChange(newDrawMode);
                }
            });
            parentTool.registerKeyBinding(toggleDrawModeAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_D,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: drawTypeToggleBindingId,
                label: "resourcePack.editor.pencil.keybinding.toggledrawtype.title",
                tooltip: "resourcePack.editor.pencil.keybinding.toggledrawtype.tooltip"
            });
        }
    }
    class PencilBrush {
        constructor(session, brushOperationName, parentTool, parentPropertyPane, _brushSettings, _brushShapes, _options) {
            this._paintingActive = false;
            this._sharedBushControl = new BrushPaintSharedControl(session, parentTool, parentPropertyPane, _brushSettings, _brushShapes, _options);
            this._sharedBushControl.initialize();
            this._session = session;
            this._operationName = brushOperationName;
            const paintAction = session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (_mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton) {
                        if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown) {
                            _options?.onStartPainting?.();
                            this.beginPainting();
                        } else if (mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonUp && this._paintingActive) {
                            _options?.onEndPainting?.();
                            this.endPainting();
                        }
                    }
                }
            });
            parentTool.registerMouseButtonBinding(paintAction);
            const extensionContext = session.extensionContext;
            const log = session.log;
            const singlePressPaintAction = session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._paintingActive) {
                        return;
                    }
                    extensionContext.transactionManager.openTransaction(this._operationName);
                    extensionContext.brushShapeManager.singlePaint((state => {
                        if (state === server_editor_namespaceObject.PaintCompletionState.Success) {
                            extensionContext.transactionManager.commitOpenTransaction();
                        } else {
                            extensionContext.transactionManager.discardOpenTransaction();
                            log.error(`Error during operation:"${this._operationName}"`, {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                        }
                        this._paintingActive = false;
                    }));
                }
            });
            parentTool.registerKeyBinding(singlePressPaintAction, {
                key: server_editor_namespaceObject.KeyboardKey.ENTER
            }, {
                uniqueId: "editor:pencil:paintAtCursor",
                label: "resourcePack.editor.pencil.keybinding.oneshot.title",
                tooltip: "resourcePack.editor.pencil.keybinding.oneshot.tooltip"
            });
        }
        shutdown() {
            this._sharedBushControl.shutdown();
        }
        isControlActive() {
            return this._sharedBushControl.isActive;
        }
        isPaintingActive() {
            return this._paintingActive;
        }
        activateControl() {
            this._sharedBushControl.activateControl();
            this._sharedBushControl.activateVisualization();
        }
        deactivateControl() {
            if (this._paintingActive) {
                this.endPainting();
            }
            this._sharedBushControl.deactivateControl();
        }
        beginPainting() {
            if (this._session.extensionContext.brushShapeManager.isBrushPaintBusy() || this._session.extensionContext.transactionManager.isBusy()) {
                this._session.log.warning(`Brush already active`);
                return;
            }
            this._paintingActive = true;
            this._session.extensionContext.transactionManager.openTransaction(this._operationName);
            this._session.extensionContext.brushShapeManager.beginPainting((state => {
                if (state === server_editor_namespaceObject.PaintCompletionState.Success) {
                    this._session.extensionContext.transactionManager.commitOpenTransaction();
                } else {
                    this._session.extensionContext.transactionManager.discardOpenTransaction();
                    this._session.log.error(`Error during brush operation:${this._operationName}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
                this._paintingActive = false;
            }));
        }
        endPainting() {
            if (this._paintingActive) {
                this._session.extensionContext.brushShapeManager.endPainting(false);
            }
            this._paintingActive = false;
        }
    }
    var PencilTelemetry;
    (function(PencilTelemetry) {
        PencilTelemetry["StartPaining"] = "StartPaining";
        PencilTelemetry["EndPainting"] = "EndPainting";
    })(PencilTelemetry || (PencilTelemetry = {}));
    var BrushEditMode;
    (function(BrushEditMode) {
        BrushEditMode[BrushEditMode["Draw"] = 0] = "Draw";
        BrushEditMode[BrushEditMode["Erase"] = 1] = "Erase";
    })(BrushEditMode || (BrushEditMode = {}));
    var OrientationMode;
    (function(OrientationMode) {
        OrientationMode[OrientationMode["ByCamera"] = 0] = "ByCamera";
        OrientationMode[OrientationMode["Manual"] = 1] = "Manual";
        OrientationMode[OrientationMode["Default"] = 0] = "Default";
    })(OrientationMode || (OrientationMode = {}));
    const flipStates = [ "upside_down_bit", "minecraft:vertical_half" ];
    const threeAxesStates = [ "pillar_axis" ];
    function doesPermutationHaveAnyStates(permutation, queryStates) {
        for (const stateName of queryStates) {
            const stateValue = permutation.getState(stateName);
            if (stateValue !== undefined) {
                return stateName;
            }
        }
        return undefined;
    }
    const orientationModeBindingId = "editor:pencil:toggleOrientationMode";
    class OrientationSettings {
        constructor(session, parent) {
            this._orientationMode = (0, server_editor_namespaceObject.makeObservable)(OrientationMode.ByCamera);
            this._frontFaceSetting = (0, server_editor_namespaceObject.makeObservable)(server_editor_namespaceObject.BrushDirectionalPlacementMode.NormalCamera);
            this._flipSetting = (0, server_editor_namespaceObject.makeObservable)(false);
            this._lastManualFrontFace = server_editor_namespaceObject.BrushDirectionalPlacementMode.FrontFacePosX;
            this._lastCameraFrontFace = server_editor_namespaceObject.BrushDirectionalPlacementMode.NormalCamera;
            this._session = session;
            this._parent = parent;
            this._blockPaletteEventHandle = this._session.extensionContext.afterEvents.blockPaletteSelectedItemChange.subscribe((_ => {
                if (this._parent.isActive()) {
                    this.onPlacementTypeChange(this._parent.getPlacementType());
                }
            }));
            this.addShortcutKeyBindings(parent.getTool());
        }
        setStorage(data) {
            this._orientationMode.set(data.orientationMode);
            this._lastCameraFrontFace = data.frontFaceCamera;
            this._lastManualFrontFace = data.frontFaceManual;
            this._flipSetting.set(data.shouldFlip);
            const activeSetting = this._orientationMode.value === OrientationMode.ByCamera ? this._lastCameraFrontFace : this._lastManualFrontFace;
            this._frontFaceSetting.set(activeSetting);
        }
        getStorage() {
            return {
                orientationMode: this._orientationMode.value,
                frontFaceManual: this._lastManualFrontFace,
                frontFaceCamera: this._lastCameraFrontFace,
                shouldFlip: this._flipSetting.value
            };
        }
        activate() {
            this.onPlacementTypeChange(this._parent.getPlacementType());
        }
        deactivate() {
            const brush = this._session.extensionContext.brushShapeManager;
            brush.clearBlockStateOverrides();
            brush.setDirectionalPlacementMode(server_editor_namespaceObject.BrushDirectionalPlacementMode.IgnoreCamera);
            brush.setBlockFacePlacementBasedOnCamera(false);
        }
        teardown() {
            this._session.extensionContext.afterEvents.blockPaletteSelectedItemChange.unsubscribe(this._blockPaletteEventHandle);
        }
        setPlacementType(newType) {
            this.onPlacementTypeChange(newType);
        }
        addOrientationToggleGroup(root) {
            root.addToggleGroup(this._orientationMode, {
                title: "resourcePack.editor.pencil.orientation.title",
                tooltip: "resourcePack.editor.pencil.orientation.tooltip",
                entries: [ {
                    icon: "pack://textures/editor/Camera.png?filtering=point",
                    value: OrientationMode.ByCamera,
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.pencil.orientation.camera.title",
                            props: [ getInputMarkup(orientationModeBindingId) ]
                        },
                        description: {
                            id: "resourcePack.editor.pencil.orientation.camera.tooltip",
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup(orientationModeBindingId, {
                                showUnset: true
                            }) ]
                        }
                    }
                }, {
                    icon: "pack://textures/editor/Wrench-Angled.png?filtering=point",
                    value: OrientationMode.Manual,
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.pencil.orientation.manual.title",
                            props: [ getInputMarkup(orientationModeBindingId) ]
                        },
                        description: {
                            id: "resourcePack.editor.pencil.orientation.manual.tooltip",
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup(orientationModeBindingId, {
                                showUnset: true
                            }) ]
                        }
                    }
                } ],
                onChange: newValue => this.onOrientationModeChange(newValue)
            });
        }
        addFrontFaceDropdownAndFlipCheckbox(pane) {
            this._frontFaceDropdown = pane.addDropdown(this._frontFaceSetting, {
                title: "resourcePack.editor.pencil.orientation.frontface.title",
                tooltip: "resourcePack.editor.pencil.orientation.frontface.tooltip",
                onChange: newValue => {
                    if (this._orientationMode.value === OrientationMode.ByCamera) {
                        this._lastCameraFrontFace = newValue;
                    } else if (this._orientationMode.value === OrientationMode.Manual) {
                        this._lastManualFrontFace = newValue;
                    }
                    if (this._parent.isActive()) {
                        this.onSettingsChanged();
                    }
                }
            });
            this._flipCheckbox = pane.addBool(this._flipSetting, {
                title: "resourcePack.editor.pencil.orientation.verticalflip.title",
                tooltip: "resourcePack.editor.pencil.orientation.verticalflip.tooltip",
                onChange: () => {
                    if (!this._parent.isActive()) {
                        return;
                    }
                    this.onSettingsChanged();
                }
            });
            this.onOrientationModeChange(this._orientationMode.value);
        }
        static getDefaultFrontFaceValueFor(mode) {
            return mode === OrientationMode.ByCamera ? server_editor_namespaceObject.BrushDirectionalPlacementMode.NormalCamera : server_editor_namespaceObject.BrushDirectionalPlacementMode.FrontFacePosX;
        }
        static isValueInDropdownEntries(list, value) {
            for (const entry of list) {
                if (entry.value === value) {
                    return true;
                }
            }
            return false;
        }
        calculateNewFrontFaceValue(list) {
            const orientationMode = this._orientationMode.value;
            const naturalSelection = orientationMode === OrientationMode.ByCamera ? this._lastCameraFrontFace : this._lastManualFrontFace;
            if (OrientationSettings.isValueInDropdownEntries(list, naturalSelection)) {
                return naturalSelection;
            }
            if (naturalSelection === server_editor_namespaceObject.BrushDirectionalPlacementMode.Random2Axes && OrientationSettings.isValueInDropdownEntries(list, server_editor_namespaceObject.BrushDirectionalPlacementMode.Random3Axes)) {
                return server_editor_namespaceObject.BrushDirectionalPlacementMode.Random3Axes;
            } else if (naturalSelection === server_editor_namespaceObject.BrushDirectionalPlacementMode.Random3Axes && OrientationSettings.isValueInDropdownEntries(list, server_editor_namespaceObject.BrushDirectionalPlacementMode.Random2Axes)) {
                return server_editor_namespaceObject.BrushDirectionalPlacementMode.Random2Axes;
            } else {
                return OrientationSettings.getDefaultFrontFaceValueFor(orientationMode);
            }
        }
        onOrientationModeChange(newValue) {
            if (this._frontFaceDropdown) {
                const newEntries = newValue === OrientationMode.ByCamera ? this.buildCameraFrontFaceEntries() : this.buildManualFrontFaceEntries();
                const newSelection = this.calculateNewFrontFaceValue(newEntries);
                this._frontFaceDropdown.updateEntries(newEntries, newSelection);
            }
            if (this._parent.isActive()) {
                this.onSettingsChanged();
            }
        }
        buildCameraFrontFaceEntries() {
            const uses3Axes = this._curPlacementConfig?.uses3Axes ?? false;
            const entries = [ {
                label: "resourcePack.editor.pencil.orientation.camera.normal",
                value: server_editor_namespaceObject.BrushDirectionalPlacementMode.NormalCamera
            }, {
                label: "resourcePack.editor.pencil.orientation.camera.opposite",
                value: server_editor_namespaceObject.BrushDirectionalPlacementMode.OppositeCamera
            }, {
                label: "resourcePack.editor.pencil.orientation.camera.left",
                value: server_editor_namespaceObject.BrushDirectionalPlacementMode.CameraLeft
            }, {
                label: "resourcePack.editor.pencil.orientation.camera.right",
                value: server_editor_namespaceObject.BrushDirectionalPlacementMode.CameraRight
            } ];
            if (uses3Axes) {
                entries.push({
                    label: "resourcePack.editor.pencil.orientation.camera.up",
                    value: server_editor_namespaceObject.BrushDirectionalPlacementMode.CameraFromAbove
                });
                entries.push({
                    label: "resourcePack.editor.pencil.orientation.camera.down",
                    value: server_editor_namespaceObject.BrushDirectionalPlacementMode.CameraFromBelow
                });
                entries.push({
                    label: "resourcePack.editor.pencil.orientation.camera.random",
                    value: server_editor_namespaceObject.BrushDirectionalPlacementMode.Random3Axes
                });
            } else {
                entries.push({
                    label: "resourcePack.editor.pencil.orientation.camera.random",
                    value: server_editor_namespaceObject.BrushDirectionalPlacementMode.Random2Axes
                });
            }
            return entries;
        }
        buildManualFrontFaceEntries() {
            const entries = [];
            const uses3Axes = this._curPlacementConfig?.uses3Axes ?? false;
            entries.push({
                label: "resourcePack.editor.pencil.orientation.manual.positiveX",
                value: server_editor_namespaceObject.BrushDirectionalPlacementMode.FrontFacePosX
            });
            if (uses3Axes) {
                entries.push({
                    label: "resourcePack.editor.pencil.orientation.manual.positiveY",
                    value: server_editor_namespaceObject.BrushDirectionalPlacementMode.FrontFacePosY
                });
            }
            entries.push({
                label: "resourcePack.editor.pencil.orientation.manual.positiveZ",
                value: server_editor_namespaceObject.BrushDirectionalPlacementMode.FrontFacePosZ
            });
            entries.push({
                label: "resourcePack.editor.pencil.orientation.manual.negativeX",
                value: server_editor_namespaceObject.BrushDirectionalPlacementMode.FrontFaceNegX
            });
            if (uses3Axes) {
                entries.push({
                    label: "resourcePack.editor.pencil.orientation.manual.negativeY",
                    value: server_editor_namespaceObject.BrushDirectionalPlacementMode.FrontFaceNegY
                });
            }
            entries.push({
                label: "resourcePack.editor.pencil.orientation.manual.negativeZ",
                value: server_editor_namespaceObject.BrushDirectionalPlacementMode.FrontFaceNegZ
            });
            if (uses3Axes) {
                entries.push({
                    label: "resourcePack.editor.pencil.orientation.manual.random",
                    value: server_editor_namespaceObject.BrushDirectionalPlacementMode.Random3Axes
                });
            } else {
                entries.push({
                    label: "resourcePack.editor.pencil.orientation.manual.random",
                    value: server_editor_namespaceObject.BrushDirectionalPlacementMode.Random2Axes
                });
            }
            return entries;
        }
        onSettingsChanged() {
            if (!this._parent.isActive()) {
                return;
            }
            this._flipCheckbox.enable = this._curPlacementConfig.flipStateName.length > 0 && !this.randomIsSelected();
            const brush = this._session.extensionContext.brushShapeManager;
            brush.setDirectionalPlacementMode(this._frontFaceSetting.value);
            brush.clearBlockStateOverrides();
            if (this._curPlacementConfig.flipStateName.length > 0 && this._flipCheckbox.value && !this.randomIsSelected()) {
                for (const stateName of this._curPlacementConfig.flipStateName) {
                    const value = this.findFlipValue(stateName) ?? true;
                    brush.pushBlockStateOverride(stateName, value);
                }
            }
            brush.setBlockFacePlacementBasedOnCamera(this._curPlacementConfig.uses3Axes);
            this._parent.saveSettings();
        }
        findFlipValue(stateName) {
            switch (stateName) {
              case "upside_down_bit":
                return true;

              case "minecraft:vertical_half":
                return "top";

              default:
                return undefined;
            }
        }
        buildConfigForPlacementType(placementType) {
            if (placementType instanceof server_editor_namespaceObject.IBlockPaletteItem) {
                return this.buildConfigForPaletteItem(placementType);
            } else {
                return {
                    flipStateName: [],
                    uses3Axes: false
                };
            }
        }
        buildConfigForPaletteItem(slotInfo) {
            if (slotInfo.getType() === server_editor_namespaceObject.BlockPaletteItemType.Simple) {
                const simpleBlock = slotInfo.getBlock();
                if (simpleBlock) {
                    return this.buildConfigForBlock(simpleBlock);
                }
            } else {
                const probItem = slotInfo;
                const allBlocks = probItem.getBlocks();
                let has3Axes = true;
                let hasFlip = true;
                const flipStates = [];
                for (const weightedBlock of allBlocks) {
                    const nextConfig = this.buildConfigForBlock(weightedBlock.block);
                    has3Axes = has3Axes && nextConfig.uses3Axes;
                    hasFlip = hasFlip && nextConfig.flipStateName.length === 1;
                    if (hasFlip) {
                        const curState = nextConfig.flipStateName[0];
                        if (!flipStates.includes(curState)) {
                            flipStates.push(curState);
                        }
                    }
                }
                return {
                    flipStateName: hasFlip ? flipStates : [],
                    uses3Axes: has3Axes
                };
            }
            return {
                flipStateName: [],
                uses3Axes: false
            };
        }
        buildConfigForBlock(type) {
            const config = {
                flipStateName: [],
                uses3Axes: false
            };
            const blockPerm = server_namespaceObject.BlockPermutation.resolve(type.id);
            const flipState = doesPermutationHaveAnyStates(blockPerm, flipStates);
            if (flipState) {
                config.flipStateName = [ flipState ];
            }
            config.uses3Axes = doesPermutationHaveAnyStates(blockPerm, threeAxesStates) !== undefined;
            return config;
        }
        onPlacementTypeChange(item) {
            const oldConfig = this._curPlacementConfig;
            this._curPlacementConfig = this.buildConfigForPlacementType(item);
            if (this._orientationMode.value === OrientationMode.ByCamera) {
                this._frontFaceDropdown.updateEntries(this.buildCameraFrontFaceEntries());
            } else {
                this._frontFaceDropdown.updateEntries(this.buildManualFrontFaceEntries());
            }
            if (oldConfig && oldConfig.uses3Axes !== this._curPlacementConfig.uses3Axes && this.randomIsSelected()) {
                const newRandom = this._curPlacementConfig.uses3Axes ? server_editor_namespaceObject.BrushDirectionalPlacementMode.Random3Axes : server_editor_namespaceObject.BrushDirectionalPlacementMode.Random2Axes;
                this._frontFaceSetting.set(newRandom);
            } else if (this._frontFaceDropdown.getEntryByValue(this._frontFaceSetting.value) === undefined) {
                this._frontFaceSetting.set(OrientationSettings.getDefaultFrontFaceValueFor(this._orientationMode.value));
            } else {
                this.onSettingsChanged();
            }
        }
        randomIsSelected() {
            return this._frontFaceSetting.value === server_editor_namespaceObject.BrushDirectionalPlacementMode.Random2Axes || this._frontFaceSetting.value === server_editor_namespaceObject.BrushDirectionalPlacementMode.Random3Axes;
        }
        addShortcutKeyBindings(parentTool) {
            const toggleAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const newOrientationMode = this._orientationMode.value === OrientationMode.ByCamera ? OrientationMode.Manual : OrientationMode.ByCamera;
                    this._orientationMode.set(newOrientationMode);
                    this.onOrientationModeChange(newOrientationMode);
                }
            });
            parentTool.registerKeyBinding(toggleAction, {
                key: server_editor_namespaceObject.KeyboardKey.UNDEFINED
            }, {
                uniqueId: orientationModeBindingId,
                label: "resourcePack.editor.pencil.keybinding.toggleorientation.title",
                tooltip: `resourcePack.editor.pencil.keybinding.toggleorientation.tooltip`
            });
        }
    }
    const editModeBindingId = "editor:pencil:toggleEditMode";
    class PencilEditMode {
        constructor(session, parent) {
            this._editMode = (0, server_editor_namespaceObject.makeObservable)(BrushEditMode.Draw);
            this._switchToFaceTargetModeAtEndOfErase = false;
            this._isCtrlDown = false;
            this._pencilParent = parent;
            this._session = session;
            this.buildEditModeKeyboardShortcuts(session, parent.getTool());
            this.buildKeyBindingToEnsureErasingIsAlwaysDoneWithBlockTargetMode(session, parent.getTool());
        }
        addEditModeSetting(rootPane) {
            rootPane.addToggleGroup(this._editMode, {
                title: "resourcePack.editor.pencil.editmode.title",
                tooltip: "resourcePack.editor.pencil.editmode.tooltip",
                entries: [ {
                    value: BrushEditMode.Draw,
                    icon: "pack://textures/editor/Pencil.png?filtering=point",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.pencil.editmode.draw.title",
                            props: [ getInputMarkup(editModeBindingId) ]
                        },
                        description: {
                            id: "resourcePack.editor.pencil.editmode.draw.tooltip",
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup(editModeBindingId, {
                                showUnset: true
                            }) ]
                        }
                    }
                }, {
                    value: BrushEditMode.Erase,
                    label: "resourcePack.editor.pencil.editmode.erase.title",
                    icon: "pack://textures/editor/Erase.png?filtering=point",
                    tooltip: {
                        title: {
                            id: "resourcePack.editor.pencil.editmode.erase.title",
                            props: [ getInputMarkup(editModeBindingId) ]
                        },
                        description: {
                            id: "resourcePack.editor.pencil.editmode.erase.tooltip",
                            props: [ newLineMarkup + newLineMarkup, getInputMarkup(editModeBindingId, {
                                showUnset: true
                            }) ]
                        }
                    }
                } ],
                onChange: () => this.onEditModeChange()
            });
        }
        setStorage(editMode) {
            this._editMode.set(editMode);
        }
        getStorage() {
            return this._editMode.value;
        }
        activate() {
            this.applyBrushSettings();
        }
        deactivate() {
            this._session.extensionContext.brushShapeManager.setInverseEraseMode(false);
            this._switchToFaceTargetModeAtEndOfErase = false;
        }
        applyBrushSettings() {
            const eraseInversionMode = this._editMode.value === BrushEditMode.Erase;
            this._session.extensionContext.brushShapeManager.setInverseEraseMode(eraseInversionMode);
        }
        onEditModeChange() {
            this.applyBrushSettings();
            this.onErasingChange();
            this._pencilParent.saveSettings();
        }
        buildEditModeKeyboardShortcuts(session, tool) {
            const toggleDrawModeAction = session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const newEditMode = this._editMode.value === BrushEditMode.Draw ? BrushEditMode.Erase : BrushEditMode.Draw;
                    this._editMode.set(newEditMode);
                    this.onEditModeChange();
                }
            });
            tool.registerKeyBinding(toggleDrawModeAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_E,
                modifier: server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: editModeBindingId,
                label: "resourcePack.editor.pencil.keybinding.togglemode.title",
                tooltip: "resourcePack.editor.pencil.keybinding.togglemode.tooltip"
            });
        }
        onErasingChange() {
            const currentEditMode = this._editMode.value;
            const isErasingNow = currentEditMode === BrushEditMode.Draw && this._isCtrlDown || currentEditMode === BrushEditMode.Erase && !this._isCtrlDown;
            const isFaceSelectionMode = this._pencilParent.getCursorTargetMode() === server_editor_namespaceObject.CursorTargetMode.Face;
            if (!isErasingNow && this._switchToFaceTargetModeAtEndOfErase) {
                this._pencilParent.setCursorTargetMode(server_editor_namespaceObject.CursorTargetMode.Face);
            }
            if (isErasingNow && isFaceSelectionMode) {
                this._pencilParent.setCursorTargetMode(server_editor_namespaceObject.CursorTargetMode.Block);
                this._switchToFaceTargetModeAtEndOfErase = true;
            }
        }
        buildKeyBindingToEnsureErasingIsAlwaysDoneWithBlockTargetMode(session, tool) {
            const controlFunctor = buttonDown => {
                if (this._pencilParent.isActive() === false) {
                    return;
                }
                this._isCtrlDown = buttonDown;
                this.onErasingChange();
            };
            const controlAction = session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.StatefulAction,
                onExecute: controlFunctor
            });
            tool.registerKeyBinding(controlAction, {
                key: server_editor_namespaceObject.KeyboardKey.CTRL,
                modifier: server_editor_namespaceObject.InputModifier.Any
            });
        }
    }
    class StorageUtil {
        constructor(session, key) {
            this._session = session;
            this._key = key;
            this._persistenceManager = getPersistenceManager(session.extensionContext.player);
        }
        loadStorage(setter) {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getGroup(pencilPersistenceKey, option);
            const errorMsg = "No stored pencil settings found";
            if (group) {
                const storeItem = group.fetchItem(this._key);
                if (storeItem && storeItem.value) {
                    try {
                        setter(storeItem.value);
                    } catch (error) {
                        this._session.log.error("Fail to load the settings, error: " + stringFromException(error));
                    }
                } else {
                    this._session.log.info(errorMsg);
                }
                group.dispose();
            }
        }
        saveStorage(data) {
            const option = {
                scope: server_editor_private_bindings_namespaceObject.PersistenceScope.ServerProject,
                version: 0
            };
            const group = this._persistenceManager.getOrCreateGroup(pencilPersistenceKey, option);
            const errorMsg = "Fail to store pencil settings";
            if (!group) {
                this._session.log.info(errorMsg);
            } else {
                const storeItem = group.getOrCreateItem(this._key, data);
                if (storeItem && storeItem.value) {
                    storeItem.commit();
                } else {
                    this._session.log.info(errorMsg);
                }
                group.dispose();
            }
        }
    }
    const pencilPersistenceKey = "editor:pencil";
    class PencilToolBehavior {
        constructor(_session, brushToolId) {
            this._isActive = false;
            this._session = _session;
            this._telemetry = new TelemetryManager(_session.extensionContext.player, TelemetrySource.Pencil);
            const spaceBinding = _session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (!this._tool.isActive) {
                        _session.toolRail.setSelectedToolId(pencilToolId);
                    } else {
                        _session.toolRail.setSelectedToolId(brushToolId);
                    }
                }
            });
            const pencilToolId = "editor:modalTool:pencil";
            this._tool = this._initTool(pencilToolId, _session, this, {
                title: "resourcePack.editor.pencil.tool.title",
                icon: "pack://textures/editor/Pencil.png?filtering=point",
                tooltip: {
                    description: {
                        id: "resourcePack.editor.pencil.tool.tooltip",
                        props: [ getInputMarkup("editor:toolModeKeyBinding:togglePencilBrushMode") ]
                    },
                    image: "pack://textures/editor/Pencil.gif"
                },
                action: spaceBinding
            });
            this._drawTypeSettings = new PencilDrawTypeSettings(_session, this);
            this._orientationSettings = new OrientationSettings(_session, this);
            this._editMode = new PencilEditMode(_session, this);
            this._storage = new StorageUtil(_session, pencilPersistenceKey);
            this._storage.loadStorage((saveState => {
                this._drawTypeSettings.setStorage(saveState.drawTypeSettings);
                this._orientationSettings.setStorage(saveState.orientationSettings);
                this._editMode.setStorage(saveState.editMode);
            }));
            this._rootPane = _session.createPropertyPane({
                title: "resourcePack.editor.pencil.tool.title",
                infoTooltip: {
                    description: [ {
                        id: "resourcePack.editor.pencil.tool.tooltip",
                        props: [ getInputMarkup("editor:toolModeKeyBinding:togglePencilBrushMode") ]
                    }, {
                        link: "https://aka.ms/BedrockEditorPencilTool",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this._tool.bindPropertyPane(this._rootPane);
            const horizontalSubPane = this._rootPane.createSubPane({
                layout: server_editor_namespaceObject.PaneLayoutType.Wrapping,
                hasExpander: false
            });
            this._drawTypeSettings.addDrawModeToggle(horizontalSubPane);
            this._editMode.addEditModeSetting(horizontalSubPane);
            this._drawTypeSettings.addObjectDropdown(this._rootPane);
            this._orientationSettings.addOrientationToggleGroup(this._rootPane);
            this._orientationSettings.addFrontFaceDropdownAndFlipCheckbox(this._rootPane);
            this._rootPane.addDivider();
            const locMap = new Map([ [ BrushPaintControlStringKeys.OffsetTooltip, "resourcePack.editor.pencil.settings.offset.tooltip" ], [ BrushPaintControlStringKeys.RootPaneTitle, "resourcePack.editor.pencil.settings.title" ], [ BrushPaintControlStringKeys.RootPaneTooltip, "resourcePack.editor.pencil.settings.tooltip" ], [ BrushPaintControlStringKeys.FillConstraintsTooltip, "resourcePack.editor.pencil.settings.fillConstraints.tooltip" ], [ BrushPaintControlStringKeys.MaskModeTitle, "resourcePack.editor.pencil.settings.blockfilter.title" ] ]);
            this._brush = new PencilBrush(_session, "Pencil", this._tool, this._rootPane, {
                paintMode: server_editor_namespaceObject.PaintMode.BlockPaint
            }, [ new server_editor_namespaceObject.SingleBlockBrushShape ], {
                onStartPainting: () => {
                    this._telemetry.fireTelemetryEvent(PencilTelemetry.StartPaining);
                },
                onEndPainting: () => {
                    this._telemetry.fireTelemetryEvent(PencilTelemetry.EndPainting, {
                        offset: _session.extensionContext.brushShapeManager.getBrushShapeOffset()
                    });
                },
                locOverride: locMap
            });
            const bindManualControls = true;
            this._cursorMode = new CursorModeControl(_session, this._tool, this._rootPane, bindManualControls);
            this._cursorMode.initialize();
            _session.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, spaceBinding, {
                key: server_editor_namespaceObject.KeyboardKey.SPACE
            }, {
                uniqueId: "editor:toolModeKeyBinding:togglePencilBrushMode",
                label: "resourcePack.editor.pencil.keybinding.title",
                tooltip: "resourcePack.editor.pencil.keybinding.tooltip"
            });
        }
        saveSettings() {
            const newValues = {
                drawTypeSettings: this._drawTypeSettings.getStorage(),
                editMode: this._editMode.getStorage(),
                orientationSettings: this._orientationSettings.getStorage()
            };
            this._storage.saveStorage(newValues);
        }
        getPlacementType() {
            if (this._drawTypeSettings.getDrawType() === PencilDrawType.Block) {
                return this._session.extensionContext.blockPalette.getSelectedItem();
            } else {
                return this._drawTypeSettings.getSelectedObjectBlock();
            }
        }
        onDrawTypeChanged() {
            this._orientationSettings.setPlacementType(this.getPlacementType());
        }
        _initTool(id, uiSession, behavior, toolConfig) {
            const tool = uiSession.toolRail.addTool(id, toolConfig);
            tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    behavior.toolActivate();
                } else {
                    behavior.toolDeactivate();
                }
            }));
            return tool;
        }
        isActive() {
            return this._isActive;
        }
        toolActivate() {
            this._isActive = true;
            this._cursorMode.activateControl();
            this._brush.activateControl();
            this._orientationSettings.activate();
            this._drawTypeSettings.activate();
            this._editMode.activate();
        }
        toolDeactivate() {
            this._isActive = false;
            if (this._brush.isControlActive()) {
                this._brush.deactivateControl();
            }
            if (this._cursorMode.isActive) {
                this._cursorMode.deactivateControl();
            }
            this._orientationSettings.deactivate();
            this._drawTypeSettings.deactivate();
            this._editMode.deactivate();
        }
        teardown() {
            this.toolDeactivate();
            this._brush.shutdown();
            this._cursorMode.shutdown();
            this._orientationSettings.teardown();
        }
        getTool() {
            return this._tool;
        }
        setCursorTargetMode(targetMode) {
            this._cursorMode.forceTargetMode(targetMode);
        }
        getCursorTargetMode() {
            return this._cursorMode.cursorProperties.targetMode;
        }
    }
    var ScaleToolTelemetry;
    (function(ScaleToolTelemetry) {
        ScaleToolTelemetry["ScaleFactorChange"] = "ScaleFactorChange";
        ScaleToolTelemetry["ApplyScaling"] = "ApplyScaling";
    })(ScaleToolTelemetry || (ScaleToolTelemetry = {}));
    class ScaleToolBehavior {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this.isActiveTool = false;
            this.statusMessage = (0, server_editor_namespaceObject.makeObservable)("");
            this.x_axis = (0, server_editor_namespaceObject.makeObservable)(true);
            this.y_axis = (0, server_editor_namespaceObject.makeObservable)(true);
            this.z_axis = (0, server_editor_namespaceObject.makeObservable)(true);
            this.scaleFactor = (0, server_editor_namespaceObject.makeObservable)(ScaleToolBehavior.DEFAULT_SCALE_COEFFICIENT);
            this.scaledBlocks = [];
            this.visualizationWidgets = uiSession.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.Single,
                visible: true
            });
            this.telemetryManager = new TelemetryManager(uiSession.extensionContext.player, TelemetrySource.Scale);
            this.transactionHandler = (0, server_editor_namespaceObject.registerUserDefinedTransactionHandler)(this.uiSession.extensionContext.transactionManager, (payload => {
                try {
                    this.uiSession.extensionContext.selectionManager.volume.set(payload.previousBoundingBox);
                } catch (_) {
                    uiSession.log.error(`Error when undoing selection`);
                }
            }), (payload => {
                try {
                    this.uiSession.extensionContext.selectionManager.volume.set(payload.newBoundingBox);
                } catch (_) {
                    uiSession.log.error(`Error when redoing selection`);
                }
            }));
            const pane = this._createPropertyPane();
            this.tool = this._addTool(uiSession);
            this.tool.onModalToolActivation.subscribe((data => {
                this.isActiveTool = data.isActiveTool;
                if (data.isActiveTool) {
                    this._queueVisualizationRedraw(uiSession);
                } else {
                    this._clearVisualization();
                }
            }));
            this.selectionChangeEventSubscriptionHandle = uiSession.extensionContext.afterEvents.SelectionChange.subscribe((() => {
                this._redrawVisualization(this.uiSession);
            }));
            this.tool.bindPropertyPane(pane);
        }
        _createPropertyPane() {
            const pane = this.uiSession.createPropertyPane({
                title: "resourcePack.editor.ScaleTool.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.ScaleTool.tooltip", {
                        link: "https://aka.ms/BedrockEditorScaleTool",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this.statusMessagePane = pane.addText(this.statusMessage);
            pane.addBool(this.x_axis, {
                title: "resourcePack.editor.ScaleTool.pane.xAxis",
                tooltip: "resourcePack.editor.ScaleTool.pane.xAxis.tooltip",
                onChange: _ => {
                    if (!this.x_axis.value && !this.y_axis.value && !this.z_axis.value) {
                        this._clearVisualization();
                    }
                    this._queueVisualizationRedraw(this.uiSession);
                }
            });
            pane.addBool(this.y_axis, {
                title: "resourcePack.editor.ScaleTool.pane.yAxis",
                tooltip: "resourcePack.editor.ScaleTool.pane.yAxis.tooltip",
                onChange: _ => {
                    if (!this.x_axis.value && !this.y_axis.value && !this.z_axis.value) {
                        this._clearVisualization();
                    }
                    this._queueVisualizationRedraw(this.uiSession);
                }
            });
            pane.addBool(this.z_axis, {
                title: "resourcePack.editor.ScaleTool.pane.zAxis",
                tooltip: "resourcePack.editor.ScaleTool.pane.zAxis.tooltip",
                onChange: _ => {
                    if (!this.x_axis.value && !this.y_axis.value && !this.z_axis.value) {
                        this._clearVisualization();
                    }
                    this._queueVisualizationRedraw(this.uiSession);
                }
            });
            pane.addNumber(this.scaleFactor, {
                title: "resourcePack.editor.ScaleTool.pane.scaleFactor",
                tooltip: "resourcePack.editor.ScaleTool.pane.scaleFactor.tooltip",
                min: ScaleToolBehavior.MIN_SCALE_COEFFICIENT,
                max: ScaleToolBehavior.MAX_SCALE_COEFFICIENT,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                onChange: newValue => {
                    this.telemetryManager.fireTelemetryEvent(ScaleToolTelemetry.ScaleFactorChange, {
                        scaleFactor: newValue
                    });
                    this._queueVisualizationRedraw(this.uiSession);
                }
            });
            const applyAction = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: async () => {
                    this.telemetryManager.fireTelemetryEvent(ScaleToolTelemetry.ApplyScaling);
                    await this._applyScaling(this.uiSession);
                }
            });
            this.applyButton = pane.addButton(applyAction, {
                title: "resourcePack.editor.ScaleTool.pane.Apply",
                visible: true,
                enable: true
            });
            return pane;
        }
        _addTool(uiSession) {
            const tool = uiSession.toolRail.addTool("editor:modalTool:scaleTool", {
                title: "resourcePack.editor.ScaleTool.title",
                icon: "pack://textures/editor/ScaleTool.png",
                tooltip: {
                    description: "resourcePack.editor.ScaleTool.tooltip",
                    image: "pack://textures/editor/ScaleTool.gif"
                }
            });
            return tool;
        }
        _queueVisualizationRedraw(uiSession) {
            if (!this.queueVisualizationsRedrawHandle) {
                this.queueVisualizationsRedrawHandle = server_namespaceObject.system.runTimeout((() => {
                    this._redrawVisualization(uiSession);
                }), ScaleToolBehavior.REDRAW_BATCH_DELAY);
            }
        }
        _redrawVisualization(uiSession) {
            if (this.queueVisualizationsRedrawHandle) {
                this.queueVisualizationsRedrawHandle = undefined;
            }
            if (uiSession.extensionContext.selectionManager.volume.isEmpty) {
                this._clearVisualization();
                if (this.statusMessagePane) {
                    this.statusMessage.set({
                        id: "resourcePack.editor.ScaleTool.statusMessage.noSelection"
                    });
                    this.statusMessagePane.visible = true;
                }
                return;
            }
            if (!this.isActiveTool) {
                return;
            }
            if (this.statusMessagePane) {
                this.statusMessagePane.visible = false;
            }
            if (!this.x_axis.value && !this.y_axis.value && !this.z_axis.value) {
                return;
            }
            this._clearVisualization();
            const boundingBox = uiSession.extensionContext.selectionManager.volume.getBoundingBox();
            const originalCenter = {
                x: (boundingBox.min.x + boundingBox.max.x) / 2,
                y: (boundingBox.min.y + boundingBox.max.y) / 2,
                z: (boundingBox.min.z + boundingBox.max.z) / 2
            };
            const scale = this.scaleFactor.value;
            const scaleFactors = {
                x: this.x_axis.value ? scale : 1,
                y: this.y_axis.value ? scale : 1,
                z: this.z_axis.value ? scale : 1
            };
            const originalSize = {
                x: boundingBox.max.x - boundingBox.min.x + 1,
                y: boundingBox.max.y - boundingBox.min.y + 1,
                z: boundingBox.max.z - boundingBox.min.z + 1
            };
            const scaledSize = {
                x: Math.max(Math.floor(originalSize.x * scaleFactors.x), 1),
                y: Math.max(Math.floor(originalSize.y * scaleFactors.y), 1),
                z: Math.max(Math.floor(originalSize.z * scaleFactors.z), 1)
            };
            const newMin = {
                x: Math.floor(originalCenter.x - (scaledSize.x - 1) / 2),
                y: Math.floor(originalCenter.y - (scaledSize.y - 1) / 2),
                z: Math.floor(originalCenter.z - (scaledSize.z - 1) / 2)
            };
            const originalVolume = originalSize.x * originalSize.y * originalSize.z;
            const scaledVolume = scaledSize.x * scaledSize.y * scaledSize.z;
            if (scaledVolume > ScaleToolBehavior.MAX_ALLOWED_BLOCKS || originalVolume > ScaleToolBehavior.MAX_ALLOWED_BLOCKS) {
                if (this.applyButton) {
                    this.applyButton.enable = false;
                }
                this.uiSession.log.warning(`Volume exceeds the limit`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            } else {
                if (this.applyButton) {
                    this.applyButton.enable = true;
                }
            }
            const selectedBlocks = [];
            executeTickSafeOperation(uiSession.extensionContext, uiSession.log, boundingBox, (() => {
                for (let x = boundingBox.min.x; x <= boundingBox.max.x; x++) {
                    for (let y = boundingBox.min.y; y <= boundingBox.max.y; y++) {
                        for (let z = boundingBox.min.z; z <= boundingBox.max.z; z++) {
                            const pos = {
                                x,
                                y,
                                z
                            };
                            const block = uiSession.extensionContext.player.dimension.getBlock(pos);
                            selectedBlocks.push({
                                pos,
                                block: block?.permutation
                            });
                        }
                    }
                }
            })).then((() => {
                this.scaledBlocks = [];
                this.scaledBlocks = this._fractionalScaling(selectedBlocks, boundingBox, originalSize, scaledSize, scaleFactors, newMin);
            })).catch((e => {
                this.uiSession.log.error(`Error while retrieving selected blocks: ${e.message}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            }));
            let widget;
            try {
                widget = this.visualizationWidgets.createWidget(newMin, {});
                if (widget) {
                    widget.addBoundingBox(`scaledSizeBoundingBox`, scaledSize, ScaleToolBehavior.BOUNDING_BOX_STYLE);
                }
            } catch (error) {
                const errorMessage = error.message;
                this.uiSession.log.error(`Error while adding scaled object preview: ${errorMessage}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            } finally {
                this.widget = widget;
            }
        }
        async _applyScaling(uiSession) {
            if (uiSession.extensionContext.selectionManager.volume.isEmpty) {
                if (this.isActiveTool) {
                    uiSession.log.info(`Scale tool: No selection to visualize`);
                }
                return;
            }
            if (!this.x_axis.value && !this.y_axis.value && !this.z_axis.value) {
                return;
            }
            uiSession.extensionContext.transactionManager.openTransaction("Scale Tool");
            const boundingBox = uiSession.extensionContext.selectionManager.volume.getBoundingBox();
            const scaledBlockLocations = this.scaledBlocks.map((x => x.location));
            const boundingBoxBlockLocations = [];
            for (let x = boundingBox.min.x; x <= boundingBox.max.x; x++) {
                for (let y = boundingBox.min.y; y <= boundingBox.max.y; y++) {
                    for (let z = boundingBox.min.z; z <= boundingBox.max.z; z++) {
                        boundingBoxBlockLocations.push({
                            x,
                            y,
                            z
                        });
                    }
                }
            }
            const combined = [ ...scaledBlockLocations, ...boundingBoxBlockLocations ];
            const combinedWithoutDuplication = Array.from(new Map(combined.map((loc => [ `${loc.x},${loc.y},${loc.z}`, loc ]))).values());
            uiSession.extensionContext.transactionManager.trackBlockChangeList(combinedWithoutDuplication);
            await executeTickSafeOperation(uiSession.extensionContext, uiSession.log, boundingBox, (() => {
                for (let x = boundingBox.min.x; x <= boundingBox.max.x; x++) {
                    for (let y = boundingBox.min.y; y <= boundingBox.max.y; y++) {
                        for (let z = boundingBox.min.z; z <= boundingBox.max.z; z++) {
                            const block = uiSession.extensionContext.player.dimension.getBlock({
                                x,
                                y,
                                z
                            });
                            if (block) {
                                block.setType(lib_vanilla_MinecraftBlockTypes.Air);
                            }
                        }
                    }
                }
            })).catch((e => {
                this.uiSession.log.error(`Error while clearing original selection: ${e.message}`);
            }));
            if (scaledBlockLocations[0] === undefined) {
                uiSession.log.warning(`No blocks after scaling operation`);
                uiSession.extensionContext.transactionManager.commitOpenTransaction();
                this._clearVisualization();
                return;
            }
            let invalidBlockCount = 0;
            let minX = scaledBlockLocations[0].x, minY = scaledBlockLocations[0].y, minZ = scaledBlockLocations[0].z;
            let maxX = scaledBlockLocations[0].x, maxY = scaledBlockLocations[0].y, maxZ = scaledBlockLocations[0].z;
            for (const loc of scaledBlockLocations) {
                if (loc.x < minX) minX = loc.x;
                if (loc.y < minY) minY = loc.y;
                if (loc.z < minZ) minZ = loc.z;
                if (loc.x > maxX) maxX = loc.x;
                if (loc.y > maxY) maxY = loc.y;
                if (loc.z > maxZ) maxZ = loc.z;
            }
            const appliedVolume = new server_namespaceObject.BlockVolume({
                x: minX,
                y: minY,
                z: minZ
            }, {
                x: maxX,
                y: maxY,
                z: maxZ
            });
            await executeTickSafeOperation(uiSession.extensionContext, uiSession.log, appliedVolume.getBoundingBox(), (() => {
                this.scaledBlocks.forEach((item => {
                    const block = uiSession.extensionContext.player.dimension.getBlock(item.location);
                    if (block && item.newBlock) {
                        block.setPermutation(item.newBlock);
                    } else {
                        ++invalidBlockCount;
                    }
                }));
            })).catch((e => {
                this.uiSession.log.error(`Error while applying scaled options: ${e.message}`);
            }));
            const transactionPayload = {
                previousBoundingBox: this.uiSession.extensionContext.selectionManager.volume.get(),
                newBoundingBox: appliedVolume
            };
            this.transactionHandler.addUserDefinedOperation(transactionPayload, "ScaleToolSelectionChange");
            this.uiSession.extensionContext.selectionManager.volume.set(appliedVolume);
            if (invalidBlockCount > 0) {
                uiSession.log.warning(`There were ${invalidBlockCount} invalid blocks while scaling selection!`);
            }
            uiSession.extensionContext.transactionManager.commitOpenTransaction();
            this.scaleFactor.set(ScaleToolBehavior.DEFAULT_SCALE_COEFFICIENT);
            this._clearVisualization();
        }
        _fractionalScaling(selectedBlocks, boundingBox, originalSize, scaledSize, scaleFactors, newMin) {
            const blockMap = new Map;
            for (const {pos, block} of selectedBlocks) {
                const relPos = {
                    x: pos.x - boundingBox.min.x,
                    y: pos.y - boundingBox.min.y,
                    z: pos.z - boundingBox.min.z
                };
                blockMap.set(`${relPos.x},${relPos.y},${relPos.z}`, block);
            }
            const scaledBlocks = [];
            for (let x = 0; x < scaledSize.x; x++) {
                for (let y = 0; y < scaledSize.y; y++) {
                    for (let z = 0; z < scaledSize.z; z++) {
                        const sourcePos = {
                            x: Math.floor(x / scaleFactors.x),
                            y: Math.floor(y / scaleFactors.y),
                            z: Math.floor(z / scaleFactors.z)
                        };
                        sourcePos.x = Math.min(sourcePos.x, originalSize.x - 1);
                        sourcePos.y = Math.min(sourcePos.y, originalSize.y - 1);
                        sourcePos.z = Math.min(sourcePos.z, originalSize.z - 1);
                        const key = `${sourcePos.x},${sourcePos.y},${sourcePos.z}`;
                        const sourceBlockPermutation = blockMap.get(key);
                        const worldPos = {
                            x: newMin.x + x,
                            y: newMin.y + y,
                            z: newMin.z + z
                        };
                        scaledBlocks.push({
                            location: worldPos,
                            newBlock: sourceBlockPermutation
                        });
                    }
                }
            }
            return scaledBlocks;
        }
        _clearVisualization() {
            if (this.widget) {
                this.visualizationWidgets.deleteWidget(this.widget);
                this.widget = undefined;
            }
        }
        teardown() {
            if (this.selectionChangeEventSubscriptionHandle) {
                this.uiSession.extensionContext.afterEvents.SelectionChange.unsubscribe(this.selectionChangeEventSubscriptionHandle);
                this.selectionChangeEventSubscriptionHandle = undefined;
            }
            if (this.queueVisualizationsRedrawHandle) {
                server_namespaceObject.system.clearRun(this.queueVisualizationsRedrawHandle);
                this.queueVisualizationsRedrawHandle = undefined;
            }
            this._clearVisualization();
            this.uiSession.log.debug(`Shutting down Scale tool`);
        }
    }
    ScaleToolBehavior.REDRAW_BATCH_DELAY = .5 * server_namespaceObject.TicksPerSecond;
    ScaleToolBehavior.MIN_SCALE_COEFFICIENT = .1;
    ScaleToolBehavior.MAX_SCALE_COEFFICIENT = 5;
    ScaleToolBehavior.DEFAULT_SCALE_COEFFICIENT = 1;
    ScaleToolBehavior.MAX_ALLOWED_BLOCKS = 2e5;
    ScaleToolBehavior.BOUNDING_BOX_STYLE = {
        visible: true,
        showWorldIntersections: true,
        outlineColor: {
            red: 0,
            green: .8,
            blue: .2,
            alpha: .8
        },
        hullColor: {
            red: 0,
            green: .8,
            blue: .2,
            alpha: .2
        }
    };
    var JigsawTelemetry;
    (function(JigsawTelemetry) {
        JigsawTelemetry["JigsawPaneInitialized"] = "JigsawPaneInitialized";
        JigsawTelemetry["JigsawPaneOpened"] = "JigsawPaneOpened";
        JigsawTelemetry["JigsawPaneClosed"] = "JigsawPaneClosed";
        JigsawTelemetry["JigsawRegistryCreated"] = "JigsawRegistryCreated";
        JigsawTelemetry["JigsawRegistryDeleted"] = "JigsawRegistryDeleted";
        JigsawTelemetry["JigsawRegistrySelected"] = "JigsawRegistrySelected";
        JigsawTelemetry["JigsawRegistryCreationAttempted"] = "JigsawRegistryCreationAttempted";
        JigsawTelemetry["JigsawRegistryCreationFailed"] = "JigsawRegistryCreationFailed";
        JigsawTelemetry["JigsawRegistryDeletionAttempted"] = "JigsawRegistryDeletionAttempted";
        JigsawTelemetry["JigsawTemplatePoolCreated"] = "JigsawTemplatePoolCreated";
        JigsawTelemetry["JigsawTemplatePoolDeleted"] = "JigsawTemplatePoolDeleted";
        JigsawTelemetry["JigsawTemplatePoolSelected"] = "JigsawTemplatePoolSelected";
        JigsawTelemetry["JigsawTemplatePoolCreationAttempted"] = "JigsawTemplatePoolCreationAttempted";
        JigsawTelemetry["JigsawTemplatePoolCreationFailed"] = "JigsawTemplatePoolCreationFailed";
        JigsawTelemetry["JigsawTemplatePoolDeletionAttempted"] = "JigsawTemplatePoolDeletionAttempted";
        JigsawTelemetry["JigsawTemplatePoolEdited"] = "JigsawTemplatePoolEdited";
        JigsawTelemetry["JigsawTemplatePoolElementAdded"] = "JigsawTemplatePoolElementAdded";
        JigsawTelemetry["JigsawTemplatePoolElementDeleted"] = "JigsawTemplatePoolElementDeleted";
        JigsawTelemetry["JigsawTemplatePoolElementModified"] = "JigsawTemplatePoolElementModified";
        JigsawTelemetry["JigsawStructureAddedToPool"] = "JigsawStructureAddedToPool";
        JigsawTelemetry["JigsawGenerationAttempted"] = "JigsawGenerationAttempted";
        JigsawTelemetry["JigsawGenerationSucceeded"] = "JigsawGenerationSucceeded";
        JigsawTelemetry["JigsawGenerationFailed"] = "JigsawGenerationFailed";
        JigsawTelemetry["JigsawValidationError"] = "JigsawValidationError";
        JigsawTelemetry["JigsawFileCorruption"] = "JigsawFileCorruption";
    })(JigsawTelemetry || (JigsawTelemetry = {}));
    class JigsawModeBehavior {
        get currentRegistryName() {
            if (!this._regNameDropdown) {
                return "";
            }
            return this._regNameDropdown.getEntryByValue(this._regNameDropdown.value)?.label ?? "";
        }
        constructor(_uiSession) {
            this._uiSession = _uiSession;
            this._fileChanged = false;
            this._structuresIds = [];
            this._leaveVoidWorld = () => {};
            this._inVoidWorld = false;
            this.openMenuAction = this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawPaneOpened, {
                        source: "action_bar",
                        registryCount: this._regNameList.length,
                        activeRegistry: this.currentRegistryName
                    });
                    this._rootPropertyPane?.show();
                }
            });
            this.telemetryManager = new TelemetryManager(_uiSession.extensionContext.player, TelemetrySource.Jigsaw);
            this._widgetGroup = this._uiSession.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.Single,
                visible: true
            });
            this.refreshStructureIds();
            this._seed = {
                x: 0,
                y: 0,
                z: 0
            };
            this._props = {
                editTemplatePoolIndex: (0, server_editor_namespaceObject.makeObservable)(0),
                jigsawGenerationDepth: (0, server_editor_namespaceObject.makeObservable)(1),
                jigsawHorizontalSize: (0, server_editor_namespaceObject.makeObservable)(128),
                lockJigsawSeed: (0, server_editor_namespaceObject.makeObservable)(false),
                bypassValidation: (0, server_editor_namespaceObject.makeObservable)(false),
                fileName: (0, server_editor_namespaceObject.makeObservable)(""),
                startingTarget: (0, server_editor_namespaceObject.makeObservable)(""),
                skipValidationWarningConfirmation: (0, server_editor_namespaceObject.makeObservable)(false)
            };
            this._regNameList = [];
            _uiSession.log.debug(`Initializing ${JigsawModeBehavior.BEHAVIOR_NAME}`);
            const player = _uiSession.extensionContext.player;
            this._jigsawService = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(player).jigsawService;
            this._rootPropertyPane = _uiSession.createPropertyPane({
                title: `resourcePack.editor.jigsaw.pane.title`,
                uniqueId: "editor:pane:jigsaw",
                infoTooltip: {
                    description: [ "resourcePack.editor.jigsaw.pane.tooltip", {
                        link: "https://aka.ms/BedrockEditorJigsaws",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            this._rootPropertyPane.onPropertyPaneVisibilityUpdated.subscribe((evt => {
                if (!evt.isVisible) {
                    if (this._inVoidWorld) {
                        this._leaveVoidWorld();
                    }
                }
            }));
            this._newTemplateDialog = new ModalDialogStringInput(this._uiSession, this._rootPropertyPane, (name => this._validateTemplateName(name)));
            this._newRegistryDialog = new ModalDialogStringInput(this._uiSession, this._rootPropertyPane, (name => this._validateRegistryName(name)));
            this._skipValidationModal = this._rootPropertyPane.createModalOverlayPane({});
            this._generatingJigsawModal = this._rootPropertyPane.createModalOverlayPane({});
            this._init();
            this.cursorProperties = _uiSession.extensionContext.cursor.getProperties();
            if (this.cursorProperties.fillColor) {
                delete this.cursorProperties.fillColor;
            }
            this.cursorProperties.outlineColor = {
                red: 0,
                green: .95,
                blue: 1,
                alpha: .88
            };
            this.cursorProperties.controlMode = server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse;
            this.cursorProperties.targetMode = server_editor_namespaceObject.CursorTargetMode.Block;
            this.cursorProperties.projectThroughLiquid = false;
            this.cursorProperties.visible = true;
            this._uiSession.actionBar.registerItem("editor:actionBarItem:jigsawManager", this.openMenuAction, {
                label: "resourcePack.editor.jigsaw.actionBar.title",
                icon: "pack://textures/editor/Jigsaw-Large.png",
                tooltipTitle: "resourcePack.editor.jigsaw.actionBar.title",
                tooltipDescription: "resourcePack.editor.jigsaw.actionBar.tooltip",
                executeOnAdd: true
            });
        }
        teardown() {
            this._uiSession.log.debug(`Shutting down ${JigsawModeBehavior.BEHAVIOR_NAME}`);
            this._saveRegistryData(true);
            if (this._inVoidWorld) {
                this._leaveVoidWorld();
            }
        }
        _validateRegistryName(name) {
            const nameRegex = /^[A-Za-z0-9_]+$/;
            if (!nameRegex.test(name)) {
                this._uiSession.log.error("Invalid name", {
                    channelMask: server_editor_namespaceObject.LogChannel.Toast
                });
                this._uiSession.log.error("Jigsaw Collection name must be alphanumeric.");
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawValidationError, {
                    validationType: "registry_name",
                    inputValue: name,
                    context: "registry_creation_invalid_format"
                });
                return false;
            }
            if (this._regNameList.includes(name)) {
                this._uiSession.log.error("Invalid name", {
                    channelMask: server_editor_namespaceObject.LogChannel.Toast
                });
                this._uiSession.log.error(`Jigsaw Collection name "${name}" already exists. Please choose a different name.`);
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawValidationError, {
                    validationType: "registry_name",
                    inputValue: name,
                    context: "registry_creation_duplicate_name"
                });
                return false;
            }
            return true;
        }
        _validateTemplateName(name) {
            if (!name || name.trim() === "") {
                this._uiSession.log.error("Invalid name", {
                    channelMask: server_editor_namespaceObject.LogChannel.Toast
                });
                this._uiSession.log.error("Jigsaw Pool name cannot be empty.");
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawValidationError, {
                    validationType: "empty_field",
                    inputValue: name,
                    context: "template_pool_creation_empty_name"
                });
                return false;
            }
            const nameRegex = /^[A-Za-z0-9_]+:[A-Za-z0-9_/]+$/;
            if (!nameRegex.test(name)) {
                this._uiSession.log.error("Invalid name", {
                    channelMask: server_editor_namespaceObject.LogChannel.Toast
                });
                this._uiSession.log.error("Jigsaw Pool name must be alphanumeric be in the form of `namespace:name`");
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawValidationError, {
                    validationType: "template_name",
                    inputValue: name,
                    context: "template_pool_creation_invalid_format"
                });
                return false;
            }
            if (this._currentRegFiles !== undefined || this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool] !== undefined) {
                const existingNames = this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].map((file => file.fileName));
                if (existingNames.includes(name)) {
                    this._uiSession.log.error("Invalid name", {
                        channelMask: server_editor_namespaceObject.LogChannel.Toast
                    });
                    this._uiSession.log.error(`Jigsaw Pool name "${name}" already exists. Please choose a different name.`);
                    this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawValidationError, {
                        validationType: "template_name",
                        inputValue: name,
                        context: "template_pool_creation_duplicate_name"
                    });
                    return false;
                }
            }
            return true;
        }
        createMenuItem() {
            void this._uiSession.menuBar.getMenu(server_editor_namespaceObject.CoreMenuType.View).then((menu => {
                menu.addItem({
                    label: "resourcePack.editor.jigsaw.menuItem.title",
                    tooltip: "resourcePack.editor.jigsaw.menuItem.tooltip"
                }, this._uiSession?.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawPaneOpened, {
                            source: "menu",
                            registryCount: this._regNameList.length,
                            activeRegistry: this.currentRegistryName
                        });
                        this._rootPropertyPane.show();
                    }
                }));
            }));
        }
        _init() {
            this._createSkipValidationWarningModalPane();
            this.createGenerateSubpane();
            this._rootPropertyPane.addDivider();
            this._editingSubpane = this._rootPropertyPane.createSubPane({
                title: "resourcePack.editor.jigsaw.pane.edit.heading",
                infoTooltip: {
                    title: "resourcePack.editor.jigsaw.pane.edit.heading",
                    description: [ "resourcePack.editor.jigsaw.pane.edit.tooltip" ]
                },
                hasExpander: true,
                hasMargins: true
            });
            this.generateRegistrySelectionSubpane();
            this._regNameList = this._jigsawService.getRegistryList();
            this.updateJigsawRegistryDropdown();
            this.generateTemplatePoolSelectionSubpane();
            this._editingSubpane.addDivider();
            this.initializeFromRegistry(this.currentRegistryName);
            this.createMenuItem();
            this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawPaneInitialized, {
                registryCount: this._regNameList.length,
                templatePoolCount: this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool]?.length ?? 0
            });
        }
        initializeFromRegistry(regName) {
            this._currentRegFiles = this._jigsawService.getRegistryData(regName);
            if (this._currentRegFiles === undefined || this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool] === undefined) {
                this._currentRegFiles = {
                    [server_editor_private_bindings_namespaceObject.JigsawJsonType.Processor]: [],
                    [server_editor_private_bindings_namespaceObject.JigsawJsonType.Structure]: [],
                    [server_editor_private_bindings_namespaceObject.JigsawJsonType.StructureSet]: [],
                    [server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool]: []
                };
            }
            const jigsawFileNameDropdownItems = this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].map(((name, index) => {
                const file = JSON.parse(name.fileJson);
                const item = {
                    label: file["minecraft:template_pool"].description.identifier,
                    value: Number(index)
                };
                return item;
            }));
            this._editingTemplatePoolDropdown.updateEntries(jigsawFileNameDropdownItems, 0);
            this._generatingTemplatePoolDropdown.updateEntries(jigsawFileNameDropdownItems, 0);
            if (this._editingTemplatePoolSubpane) {
                this._editingSubpane.removeSubPane(this._editingTemplatePoolSubpane);
            }
            this._editingTemplatePoolSubpane = this._editingSubpane.createSubPane({
                hasExpander: true,
                hasMargins: true
            });
            this.refreshTemplatePoolEditorSubpane(0, undefined);
        }
        generateRegistrySelectionSubpane() {
            this._registryDropdownSubpane = this._editingSubpane.createSubPane({
                layout: server_editor_namespaceObject.PaneLayoutType.Wrapping,
                hasExpander: false,
                hasMargins: false
            });
            this._regNameDropdown = this._registryDropdownSubpane.addDropdown(0, {
                title: `resourcePack.editor.jigsaw.pane.registryDropdown.heading`,
                tooltip: `resourcePack.editor.jigsaw.pane.registryDropdown.tooltip`,
                entries: [],
                onChange: newValue => {
                    this.handleRegistryDropdownChange(newValue);
                }
            });
            this._registryDropdownSubpane.addButton((() => {
                this._saveRegistryData(true);
                this._newRegistryDialog.activate("", "resourcePack.editor.jigsaw.pane.registryCreation.title", "resourcePack.editor.jigsaw.pane.registryCreation.heading").then((name => {
                    this.handleRegistryCreateRequest(name);
                })).catch((reason => {
                    this._uiSession.log.error(`Error showing new Jigsaw Collection dialog: ${reason}`);
                }));
            }), {
                icon: "plusIcon",
                tooltip: "resourcePack.editor.jigsaw.pane.registryCreation.tooltip",
                shrinkToIcon: true
            });
            this._registryDropdownSubpane.addButton((() => {
                this.handleRegistryDeleteRequest();
            }), {
                icon: "trashCanIcon",
                tooltip: "resourcePack.editor.jigsaw.pane.registryDeletion.tooltip",
                shrinkToIcon: true
            });
        }
        updateJigsawRegistryDropdown() {
            const jigsawRegistryNameDropdownItems = this._regNameList.map(((name, index) => {
                const item = {
                    label: name,
                    value: Number(index)
                };
                return item;
            }));
            if (jigsawRegistryNameDropdownItems && jigsawRegistryNameDropdownItems.length > 0) {
                this._regNameDropdown.updateEntries(jigsawRegistryNameDropdownItems);
            }
        }
        generateTemplatePoolSelectionSubpane() {
            this._templatePoolDropdownSubpane = this._editingSubpane.createSubPane({
                layout: server_editor_namespaceObject.PaneLayoutType.Wrapping,
                hasExpander: false,
                hasMargins: false
            });
            this._editingTemplatePoolDropdown = this._templatePoolDropdownSubpane.addDropdown(this._props.editTemplatePoolIndex, {
                title: `resourcePack.editor.jigsaw.pane.templatePoolDropdown.title`,
                tooltip: `resourcePack.editor.jigsaw.pane.templatePoolDropdown.tooltip`,
                entries: [],
                onChange: (newValue, oldValue) => {
                    this.handleTemplatePoolDropdownChange(newValue, oldValue);
                }
            });
            this._templatePoolDropdownSubpane.addButton((() => {
                this._newTemplateDialog.activate("", "resourcePack.editor.jigsaw.pane.templatePoolCreation.title", "resourcePack.editor.jigsaw.pane.templatePoolCreation.heading").then((name => {
                    this.handleTemplatePoolCreateRequest(name);
                })).catch((reason => {
                    this._uiSession.log.error(`Error showing new Jigsaw Pool dialog: ${reason}`);
                }));
            }), {
                icon: "plusIcon",
                tooltip: "resourcePack.editor.jigsaw.pane.templatePoolCreation.tooltip"
            });
            this._templatePoolDropdownSubpane.addButton((() => {
                this.handleTemplatePoolDeleteRequest();
            }), {
                icon: "trashCanIcon",
                tooltip: "resourcePack.editor.jigsaw.pane.templatePoolDeletion.tooltip"
            });
        }
        createGenerateSubpane() {
            this._generateSubPane = this._rootPropertyPane.createSubPane({
                title: "resourcePack.editor.jigsaw.pane.generate.subpane.title",
                hasExpander: true,
                hasMargins: true
            });
            this._generateSubPane.addNumber(this._props.jigsawGenerationDepth, {
                title: "resourcePack.editor.jigsaw.pane.generate.depth.title",
                min: JigsawModeBehavior.MINIMUM_DEPTH,
                max: JigsawModeBehavior.MAXIMUM_DEPTH,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                tooltip: "resourcePack.editor.jigsaw.pane.generate.depth.tooltip"
            });
            this._generateSubPane.addNumber(this._props.jigsawHorizontalSize, {
                title: "resourcePack.editor.jigsaw.pane.generate.horizontalSize.title",
                min: JigsawModeBehavior.MINIMUM_HORIZONTAL_SIZE,
                max: JigsawModeBehavior.MAXIMUM_HORIZONTAL_SIZE,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider,
                isInteger: true,
                tooltip: "resourcePack.editor.jigsaw.pane.generate.horizontalSize.tooltip"
            });
            this._generateSubPane.addBool(this._props.lockJigsawSeed, {
                title: "resourcePack.editor.jigsaw.pane.generate.seed.title",
                tooltip: "resourcePack.editor.jigsaw.pane.generate.seed.tooltip"
            });
            this._generateSubPane.addBool(this._props.bypassValidation, {
                title: "resourcePack.editor.jigsaw.pane.generate.bypassValidation.title",
                tooltip: "resourcePack.editor.jigsaw.pane.generate.bypassValidation.tooltip"
            });
            this._generatingTemplatePoolDropdown = this._generateSubPane.addDropdown(0, {
                title: `resourcePack.editor.jigsaw.pane.generate.startPool.title`,
                tooltip: `resourcePack.editor.jigsaw.pane.generate.startPool.tooltip`,
                entries: []
            });
            this._generateSubPane.addString(this._props.startingTarget, {
                title: "resourcePack.editor.jigsaw.pane.generate.startTarget.title",
                tooltip: "resourcePack.editor.jigsaw.pane.generate.startTarget.tooltip"
            });
            this._buttonPane = this._generateSubPane.addButtonPane();
            this._buttonPane.addButton(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._props.bypassValidation.value && !this._props.skipValidationWarningConfirmation.value) {
                        this._rootPropertyPane.setActiveModalOverlay(this._skipValidationModal.id);
                    } else {
                        this.generateJigsaw();
                    }
                }
            }), {
                title: "resourcePack.editor.jigsaw.pane.generate.preview.title",
                tooltip: "resourcePack.editor.jigsaw.pane.generate.preview.tooltip"
            });
            this._buttonPane.addButton(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._inVoidWorld) {
                        this._leaveVoidWorld();
                    }
                }
            }), {
                title: "resourcePack.editor.jigsaw.misc.return.title",
                tooltip: "resourcePack.editor.jigsaw.misc.return.tooltip"
            });
            this._buttonPane.addButton(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const exportLocation = this._jigsawService.getExportLocation();
                    this._uiSession.log.info(`Jigsaw structures exported to: ${exportLocation}`);
                    this._uiSession.log.info(`Jigsaw structures exported to: ${exportLocation}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.Toast
                    });
                }
            }), {
                title: "resourcePack.editor.exportProject.export",
                tooltip: "resourcePack.editor.exportProject.export"
            });
        }
        refreshTemplatePoolEditorSubpane(newValue, oldValue) {
            this.refreshStructureIds();
            if (oldValue !== undefined) {
                const updatedFileName = this._editingTemplatePoolDropdown.getEntryByValue(oldValue)?.label ?? "";
                this._updateFile(updatedFileName);
                this._saveRegistryData(false);
            }
            this._fileChanged = false;
            this._editingSubpane.removeSubPane(this._editingTemplatePoolSubpane);
            this._editingTemplatePoolSubpane = this._editingSubpane.createSubPane({
                title: "resourcePack.editor.jigsaw.pane.poolSubpane.title",
                infoTooltip: {
                    title: "resourcePack.editor.jigsaw.pane.poolSubpane.title",
                    description: [ "resourcePack.editor.jigsaw.pane.poolSubpane.tooltip" ]
                },
                hasExpander: true,
                hasMargins: true
            });
            const itemName = this._editingTemplatePoolDropdown.getEntryByValue(newValue)?.label ?? "";
            const selectedFile = this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].find((item => item.fileName === itemName));
            if (selectedFile) {
                this._constructTemplatePoolSubpane(selectedFile);
            }
        }
        _constructTemplatePoolSubpane(json) {
            this._editingTemplatePoolSubpane.addButton(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.handleAddNewTemplatePoolElement();
                }
            }), {
                title: "resourcePack.editor.jigsaw.pane.poolSubpane.add.title",
                tooltip: "resourcePack.editor.jigsaw.pane.poolSubpane.add.tooltip"
            });
            try {
                this._loadedFile = JSON.parse(json.fileJson);
                this._loadedFile["minecraft:template_pool"].elements.forEach(((element, index) => {
                    this._addTemplatePoolElementSection(element, index);
                    this._editingTemplatePoolSubpane.addDivider();
                }));
            } catch (error) {
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawFileCorruption, {
                    fileName: json.fileName,
                    registryName: this.currentRegistryName,
                    corruptionType: "json_parse_error",
                    errorMessage: error?.message || "Unknown JSON parse error"
                });
                this._uiSession.log.error(`Failed to parse Jigsaw Pool file: ${json.fileName}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.Toast
                });
                throw error;
            }
        }
        _addTemplatePoolElementSection(element, index) {
            const elementSubpane = this._editingTemplatePoolSubpane.createSubPane({
                layout: server_editor_namespaceObject.PaneLayoutType.Wrapping,
                hasExpander: false
            });
            this.refreshStructureIds();
            let selectedId = this._structuresIds.findIndex((item => element.element?.location === item || element.element?.element_type === item));
            if (selectedId === -1) {
                selectedId = 0;
            }
            const entries = this._structuresIds.map(((structure, index) => {
                const item = {
                    label: structure,
                    value: index
                };
                return item;
            }));
            elementSubpane.addDropdown(selectedId, {
                title: `resourcePack.editor.jigsaw.pane.poolSubpane.structure.title`,
                tooltip: `resourcePack.editor.jigsaw.pane.poolSubpane.structure.tooltip`,
                entries,
                onChange: newValue => {
                    this.handleTemplatePoolElementStructureChange(index, newValue);
                }
            });
            elementSubpane.addNumber(element.weight ?? JigsawModeBehavior.MINIMUM_WEIGHT, {
                title: "resourcePack.editor.jigsaw.pane.poolSubpane.weight.title",
                min: JigsawModeBehavior.MINIMUM_WEIGHT,
                max: JigsawModeBehavior.MAXIMUM_WEIGHT,
                variant: server_editor_namespaceObject.NumberPropertyItemVariant.InputField,
                isInteger: true,
                tooltip: "resourcePack.editor.jigsaw.pane.poolSubpane.weight.tooltip",
                onChange: newValue => {
                    this.handleTemplatePoolElementWeightChange(index, newValue);
                }
            });
            elementSubpane.addButton(this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.handleDeleteTemplatePoolElementRequest(index);
                }
            }), {
                icon: "trashCanIcon",
                tooltip: "resourcePack.editor.jigsaw.pane.poolSubpane.delete.tooltip"
            });
        }
        handleRegistryDropdownChange(newValue) {
            this._uiSession.log.info(`Selected Jigsaw Collection: ${newValue}`);
            const previousRegistry = this.currentRegistryName;
            const regName = String(newValue);
            this._currentRegFiles = this._jigsawService.getRegistryData(regName);
            this.initializeFromRegistry(this.currentRegistryName);
            this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawRegistrySelected, {
                registryName: this.currentRegistryName,
                templatePoolCount: this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool]?.length || 0,
                previousRegistry: previousRegistry !== this.currentRegistryName ? previousRegistry : undefined
            });
        }
        handleRegistryCreateRequest(name) {
            if (name) {
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawRegistryCreationAttempted, {
                    registryName: name,
                    existingRegistryCount: this._regNameList.length
                });
                this._regNameList.push(name);
                this._regNameDropdown.updateEntries(this._regNameList.map(((name, index) => {
                    const item = {
                        label: name,
                        value: Number(index)
                    };
                    return item;
                })), this._regNameList.length - 1);
                this.initializeFromRegistry(name);
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawRegistryCreated, {
                    registryName: name,
                    existingRegistryCount: this._regNameList.length - 1
                });
            }
        }
        handleRegistryDeleteRequest() {
            if (this._regNameList.length > 0) {
                const removedIndex = this._regNameDropdown.value;
                const registryName = this._regNameList[removedIndex];
                this._jigsawService.deleteRegistryData(registryName);
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawRegistryDeletionAttempted, {
                    registryName,
                    templatePoolCount: this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool]?.length || 0
                });
                this._regNameList.splice(removedIndex, 1);
                this._regNameDropdown.updateEntries(this._regNameList.map(((name, index) => {
                    const item = {
                        label: name,
                        value: Number(index)
                    };
                    return item;
                })), 0);
                if (this._regNameList.length > 0) {
                    this.initializeFromRegistry(this._regNameList[0]);
                } else {
                    this._currentRegFiles = {
                        [server_editor_private_bindings_namespaceObject.JigsawJsonType.Processor]: [],
                        [server_editor_private_bindings_namespaceObject.JigsawJsonType.Structure]: [],
                        [server_editor_private_bindings_namespaceObject.JigsawJsonType.StructureSet]: [],
                        [server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool]: []
                    };
                    this._editingTemplatePoolDropdown.updateEntries([], -1);
                    this._generatingTemplatePoolDropdown.updateEntries([], -1);
                    this._editingSubpane.removeSubPane(this._editingTemplatePoolSubpane);
                }
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawRegistryDeleted, {
                    registryName,
                    templatePoolCount: this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool]?.length || 0
                });
            }
        }
        handleTemplatePoolDropdownChange(newValue, oldValue) {
            this.refreshTemplatePoolEditorSubpane(newValue, oldValue);
            const templatePoolName = this._editingTemplatePoolDropdown.getEntryByValue(newValue)?.label ?? "";
            const elementCount = this._loadedFile ? this._loadedFile["minecraft:template_pool"].elements.length : 0;
            this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawTemplatePoolSelected, {
                templatePoolName,
                elementCount,
                registryName: this.currentRegistryName
            });
        }
        handleTemplatePoolCreateRequest(templatePoolName) {
            if (templatePoolName) {
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawTemplatePoolCreationAttempted, {
                    templatePoolName,
                    registryName: this.currentRegistryName,
                    existingPoolCount: this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool]?.length || 0
                });
                if (this._fileChanged && this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].length > 0) {
                    const currentFileName = this._editingTemplatePoolDropdown.getEntryByValue(this._editingTemplatePoolDropdown.value)?.label ?? "";
                    if (currentFileName) {
                        this._updateFile(currentFileName);
                    }
                }
                const tempPool = {
                    format_version: "1.21.20",
                    "minecraft:template_pool": {
                        description: {
                            identifier: templatePoolName
                        },
                        elements: []
                    }
                };
                this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].push({
                    fileName: templatePoolName,
                    fileJson: JSON.stringify(tempPool)
                });
                const jigsawFileNameDropdownItems = this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].map(((name, index) => {
                    const file = JSON.parse(name.fileJson);
                    const item = {
                        label: file["minecraft:template_pool"].description.identifier,
                        value: Number(index)
                    };
                    return item;
                }));
                this._saveRegistryData(false);
                const newTemplatePoolIndex = jigsawFileNameDropdownItems.length - 1;
                this._editingTemplatePoolDropdown.updateEntries(jigsawFileNameDropdownItems, newTemplatePoolIndex);
                this._generatingTemplatePoolDropdown.updateEntries(jigsawFileNameDropdownItems, newTemplatePoolIndex);
                this.refreshTemplatePoolEditorSubpane(newTemplatePoolIndex, undefined);
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawTemplatePoolCreated, {
                    templatePoolName,
                    registryName: this.currentRegistryName,
                    existingPoolCount: this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].length - 1
                });
            }
        }
        handleTemplatePoolDeleteRequest() {
            if (this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].length > 0) {
                const removedIndex = this._editingTemplatePoolDropdown.value;
                const templatePoolName = this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool][removedIndex]?.fileName || "";
                const elementCount = this._loadedFile ? this._loadedFile["minecraft:template_pool"].elements.length : 0;
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawTemplatePoolDeletionAttempted, {
                    templatePoolName,
                    registryName: this.currentRegistryName,
                    elementCount
                });
                this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].splice(removedIndex, 1);
                const jigsawFileNameDropdownItems = this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].map(((name, index) => {
                    const file = JSON.parse(name.fileJson);
                    const item = {
                        label: file["minecraft:template_pool"].description.identifier,
                        value: Number(index)
                    };
                    return item;
                }));
                this._editingTemplatePoolDropdown.updateEntries(jigsawFileNameDropdownItems, 0);
                this._generatingTemplatePoolDropdown.updateEntries(jigsawFileNameDropdownItems, 0);
                this.refreshTemplatePoolEditorSubpane(0, undefined);
                this._saveRegistryData(false);
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawTemplatePoolDeleted, {
                    templatePoolName,
                    registryName: this.currentRegistryName,
                    elementCount
                });
            }
        }
        generateJigsaw() {
            const startTime = Date.now();
            if (!this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool] || this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].length === 0) {
                this._uiSession.log.error("Cannot generate jigsaw. The registry is empty. Please create at least one Jigsaw Pool first.", {
                    channelMask: server_editor_namespaceObject.LogChannel.Toast
                });
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawGenerationFailed, {
                    registryName: this.currentRegistryName,
                    templatePoolName: "",
                    failureReason: "invalid_pool",
                    errorMessage: "Registry is empty - no template pools available"
                });
                return;
            }
            const templatePoolName = this._generatingTemplatePoolDropdown.getEntryByValue(this._generatingTemplatePoolDropdown.value)?.label ?? "";
            const elementCount = this._loadedFile ? this._loadedFile["minecraft:template_pool"].elements.length : 0;
            if (!templatePoolName) {
                this._uiSession.log.error("Cannot generate jigsaw. No Jigsaw Pool selected.", {
                    channelMask: server_editor_namespaceObject.LogChannel.Toast
                });
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawGenerationFailed, {
                    registryName: this.currentRegistryName,
                    templatePoolName: "",
                    failureReason: "invalid_pool",
                    errorMessage: "No template pool selected"
                });
                return;
            }
            if (!this._props.lockJigsawSeed.value) {
                const x = Math.random() * 64e3 - 32e3;
                const y = Math.random() * 64e3 - 32e3;
                const z = Math.random() * 64e3 - 32e3;
                this._seed = {
                    x,
                    y,
                    z
                };
            }
            if (this._fileChanged) {
                const updatedFileName = this._editingTemplatePoolDropdown.getEntryByValue(this._editingTemplatePoolDropdown.value)?.label ?? "";
                this._updateFile(updatedFileName);
            }
            const templatePoolNames = this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].map((file => file.fileName));
            const hasDuplicates = templatePoolNames.some(((name, index) => templatePoolNames.indexOf(name) !== index));
            this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawGenerationAttempted, {
                registryName: this.currentRegistryName,
                templatePoolName,
                startingTarget: this._props.startingTarget.value,
                generationDepth: this._props.jigsawGenerationDepth.value,
                horizontalSize: this._props.jigsawHorizontalSize.value,
                bypassValidation: this._props.bypassValidation.value,
                seedLocked: this._props.lockJigsawSeed.value,
                templatePoolElementCount: elementCount,
                hasDuplicateNames: hasDuplicates
            });
            if (hasDuplicates) {
                this._uiSession.log.error("Cannot generate jigsaw. There are duplicate Jigsaw Pool names.", {
                    channelMask: server_editor_namespaceObject.LogChannel.Toast
                });
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawGenerationFailed, {
                    registryName: this.currentRegistryName,
                    templatePoolName,
                    failureReason: "duplicate_names",
                    errorMessage: "Duplicate Jigsaw Pool names found"
                });
                return;
            }
            this._fileChanged = false;
            this._saveRegistryData(false);
            this._jigsawService.generateJigsaw(this.currentRegistryName, templatePoolName.replace("-", ":"), this._props.startingTarget.value, this._seed, this._props.jigsawGenerationDepth.value, this._props.jigsawHorizontalSize.value, !this._props.bypassValidation.value, this._uiSession.extensionContext.clipboardManager.clipboard).then((() => {
                const executionTime = Date.now() - startTime;
                this._uiSession.log.info(`Successfully generated jigsaw and wrote to clipboard.`);
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawGenerationSucceeded, {
                    registryName: this.currentRegistryName,
                    templatePoolName,
                    generationDepth: this._props.jigsawGenerationDepth.value,
                    seedLocked: this._props.lockJigsawSeed.value,
                    executionTimeMs: executionTime
                });
                if (!this._inVoidWorld) {
                    this._setupTemplateEditingEnvironment();
                }
            })).catch((error => {
                this._uiSession.log.error(`Jigsaw Generation error : ${error}`);
                this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawGenerationFailed, {
                    registryName: this.currentRegistryName,
                    templatePoolName,
                    failureReason: "system_error",
                    errorMessage: error
                });
            }));
        }
        _updateFile(targetFile) {
            const updatedFileIndex = this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool].findIndex((item => item.fileName === targetFile));
            this._loadedFile["minecraft:template_pool"].elements.forEach(((element, index) => {
                if (element.element.location === "minecraft:empty_pool_element" && element.element.location !== undefined) {
                    const emptyElement = {
                        element_type: "minecraft:empty_pool_element"
                    };
                    this._loadedFile["minecraft:template_pool"].elements[index].element = emptyElement;
                }
            }));
            this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool][updatedFileIndex].fileJson = JSON.stringify(this._loadedFile);
        }
        handleAddNewTemplatePoolElement() {
            const emptyElement = {
                element_type: "minecraft:empty_pool_element"
            };
            const element = {
                element: emptyElement,
                weight: JigsawModeBehavior.MINIMUM_WEIGHT
            };
            const size = this._loadedFile["minecraft:template_pool"].elements.push(element);
            this._addTemplatePoolElementSection(element, size - 1);
            this._editingTemplatePoolSubpane.addDivider();
            this._saveRegistryData(true);
            this._fileChanged = true;
            this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawTemplatePoolElementAdded, {
                templatePoolName: this._editingTemplatePoolDropdown.getEntryByValue(this._editingTemplatePoolDropdown.value)?.label ?? "",
                structureLocation: "",
                weight: 1,
                totalElements: size,
                registryName: this.currentRegistryName
            });
        }
        handleTemplatePoolElementStructureChange(index, newValue) {
            const structureName = this._structuresIds[newValue];
            if (structureName === "minecraft:empty_pool_element") {
                const emptyElement = {
                    element_type: "minecraft:empty_pool_element"
                };
                this._loadedFile["minecraft:template_pool"].elements[index].element = emptyElement;
            } else {
                const singleElement = {
                    location: structureName,
                    element_type: "minecraft:single_pool_element"
                };
                this._loadedFile["minecraft:template_pool"].elements[index].element = singleElement;
            }
            this._fileChanged = true;
            this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawTemplatePoolElementModified, {
                templatePoolName: this._editingTemplatePoolDropdown.getEntryByValue(this._editingTemplatePoolDropdown.value)?.label ?? "",
                changeType: "structure_changed",
                newStructureLocation: this._structuresIds[newValue],
                registryName: this.currentRegistryName
            });
        }
        handleTemplatePoolElementWeightChange(index, newValue) {
            this._loadedFile["minecraft:template_pool"].elements[index].weight = newValue;
            this._fileChanged = true;
            this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawTemplatePoolElementModified, {
                templatePoolName: this._editingTemplatePoolDropdown.getEntryByValue(this._editingTemplatePoolDropdown.value)?.label ?? "",
                changeType: "weight_changed",
                newWeight: newValue,
                registryName: this.currentRegistryName
            });
        }
        handleDeleteTemplatePoolElementRequest(index) {
            const elementToDelete = this._loadedFile["minecraft:template_pool"].elements[index];
            const structureLocation = elementToDelete.element?.location || elementToDelete.element?.element_type || "";
            this.telemetryManager.fireTelemetryEvent(JigsawTelemetry.JigsawTemplatePoolElementDeleted, {
                templatePoolName: this._editingTemplatePoolDropdown.getEntryByValue(this._editingTemplatePoolDropdown.value)?.label ?? "",
                structureLocation,
                weight: elementToDelete.weight || JigsawModeBehavior.MINIMUM_WEIGHT,
                remainingElements: this._loadedFile["minecraft:template_pool"].elements.length - 1,
                registryName: this.currentRegistryName
            });
            this._loadedFile["minecraft:template_pool"].elements.splice(index, 1);
            this._fileChanged = true;
            this.refreshTemplatePoolEditorSubpane(this._editingTemplatePoolDropdown.value, this._editingTemplatePoolDropdown.value);
        }
        refreshStructureIds() {
            const structs = this._uiSession.extensionContext.structureManager.searchStructures({
                sources: [ server_editor_namespaceObject.StructureSource.EditorProject, server_editor_namespaceObject.StructureSource.BehaviorPack ]
            });
            const uniqueStructs = [ ...new Set(structs) ];
            this._structuresIds = uniqueStructs.map((structure => structure.structureFullName.replace(":", "/")));
            this._structuresIds.unshift("minecraft:empty_pool_element");
        }
        _setupTemplateEditingEnvironment() {
            this._inVoidWorld = true;
            this._uiSession.toolRail.setSelectedToolId(undefined);
            this._toolChangedEventToken = this._uiSession.toolRail.onSelectedToolChanged.subscribe((evt => {
                this._saveRegistryData(true);
                if (evt.tool !== undefined && this._inVoidWorld) {
                    this._leaveVoidWorld();
                }
            }));
            if (this._modeChangeEventSubscriptionHandle === undefined) {
                this._modeChangeEventSubscriptionHandle = this._uiSession.extensionContext.afterEvents.modeChange.subscribe((evt => {
                    this._saveRegistryData(true);
                    if (evt.mode !== server_editor_namespaceObject.EditorMode.Tool && this._inVoidWorld) {
                        this._leaveVoidWorld();
                    }
                }));
            }
            const newCursorProperties = this._uiSession.extensionContext.cursor.getProperties();
            newCursorProperties.visible = false;
            this._uiSession.extensionContext.cursor.pushPropertiesById(newCursorProperties, JigsawModeBehavior.CURSOR_STATE_ID);
            this._uiSession.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableTerrainRendering, true);
            this._uiSession.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableEntityRendering, false);
            this._uiSession.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableWeatherRendering, true);
            this._uiSession.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableParticleRendering, true);
            this._uiSession.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableBlockEntityRendering, true);
            requestWeatherChange(`EditorJigsaw-${this._uiSession.extensionContext.player.id}`, server_namespaceObject.WeatherType.Clear);
            requestTimeOfDayChange(`EditorJigsaw-${this._uiSession.extensionContext.player.id}`, server_namespaceObject.TimeOfDay.Sunrise);
            const oldPlayerLocation = this._uiSession.extensionContext.player.location;
            const oldPlayerRotation = this._uiSession.extensionContext.player.getRotation();
            this._uiSession.extensionContext.player.teleport({
                x: 0,
                y: 5,
                z: 24
            }, {
                rotation: {
                    x: 10,
                    y: 180
                },
                checkForBlocks: false,
                keepVelocity: false
            });
            const gridWidget = this._widgetGroup.createWidget({
                x: 0,
                y: 0,
                z: 0
            }, {
                selectable: false,
                visible: true
            });
            gridWidget.addGridComponent("grid", {
                color: {
                    red: .5,
                    green: .5,
                    blue: 0,
                    alpha: .5
                },
                offset: {
                    x: -8,
                    y: 0,
                    z: -8
                },
                gridSize: {
                    x: 1,
                    y: 1
                },
                gridCount: {
                    x: 17,
                    y: 17
                }
            });
            gridWidget.addClipboardComponent("JigsawPreview", this._uiSession.extensionContext.clipboardManager.clipboard, {
                showOutline: false,
                hullColor: {
                    red: 1,
                    green: 1,
                    blue: 1,
                    alpha: 1
                },
                highlightHullColor: {
                    red: 0,
                    green: 0,
                    blue: 0,
                    alpha: 0
                },
                highlightOutlineColor: {
                    red: 0,
                    green: 0,
                    blue: 0,
                    alpha: 0
                }
            });
            this._leaveVoidWorld = () => {
                if (this._toolChangedEventToken) {
                    this._toolChangedEventToken.unsubscribe();
                    this._toolChangedEventToken = undefined;
                }
                if (this._modeChangeEventSubscriptionHandle !== undefined) {
                    this._uiSession.extensionContext.afterEvents.modeChange.unsubscribe(this._modeChangeEventSubscriptionHandle);
                    this._modeChangeEventSubscriptionHandle = undefined;
                }
                restoreWeatherChange(`EditorJigsaw-${this._uiSession.extensionContext.player.id}`);
                restoreTimeOfDayChange(`EditorJigsaw-${this._uiSession.extensionContext.player.id}`);
                this._widgetGroup.deleteWidget(gridWidget);
                this._uiSession.extensionContext.player.teleport(oldPlayerLocation, {
                    rotation: oldPlayerRotation,
                    checkForBlocks: false,
                    keepVelocity: false
                });
                this._uiSession.extensionContext.cursor.popPropertiesById(JigsawModeBehavior.CURSOR_STATE_ID);
                this._uiSession.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableTerrainRendering, false);
                this._uiSession.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableEntityRendering, false);
                this._uiSession.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableWeatherRendering, false);
                this._uiSession.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableParticleRendering, false);
                this._uiSession.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableBlockEntityRendering, false);
                this._inVoidWorld = false;
            };
        }
        _createSkipValidationWarningModalPane() {
            this._skipValidationModal.contentPane.addText("resourcePack.editor.jigsaw.pane.skipValidationPane", {
                border: false
            });
            this._skipValidationModal.controlPane.addBool(this._props.skipValidationWarningConfirmation, {
                title: "resourcePack.editor.jigsaw.pane.skipValidationPaneSkip",
                tooltip: "resourcePack.editor.jigsaw.pane.skipValidationPaneSkip"
            });
            this._skipValidationModal.controlPane.addDivider();
            const confirmationScreenButtonPane = this._skipValidationModal.controlPane.addButtonPane();
            confirmationScreenButtonPane.addButton((() => {
                this._skipValidationModal.hide();
            }), {
                title: "resourcePack.editor.jigsaw.pane.skipValidationPaneCancel"
            });
            confirmationScreenButtonPane.addButton((() => {
                this._skipValidationModal.hide();
                this.generateJigsaw();
            }), {
                title: "resourcePack.editor.jigsaw.pane.skipValidationPaneConfirm",
                variant: server_editor_namespaceObject.ButtonVariant.Confirmation
            });
            this._generatingJigsawModal.contentPane.addText("resourcePack.editor.jigsaw.pane.generatingJigsaw", {
                border: false
            });
            this._generatingJigsawModal.contentPane.addProgressIndicator();
        }
        _saveRegistryData(updateFilePriorToSaving) {
            if (updateFilePriorToSaving) {
                const currentFileName = this._editingTemplatePoolDropdown.getEntryByValue(this._editingTemplatePoolDropdown.value)?.label;
                if (currentFileName) {
                    this._updateFile(currentFileName);
                }
            }
            if (this.currentRegistryName && this.currentRegistryName !== "") {
                const empty = [];
                this._jigsawService.setRegistryData(this.currentRegistryName, this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.Processor] ?? empty, this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.Structure] ?? empty, this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.StructureSet] ?? empty, this._currentRegFiles[server_editor_private_bindings_namespaceObject.JigsawJsonType.TemplatePool] ?? empty).then((regList => {
                    this._regNameList = regList;
                    this.updateJigsawRegistryDropdown();
                })).catch((error => {
                    this._uiSession.log.error(`Export error : ${error}`);
                    this._regNameList = [];
                }));
            }
        }
    }
    JigsawModeBehavior.BEHAVIOR_NAME = "JigsawMode";
    JigsawModeBehavior.CURSOR_STATE_ID = "editor:jigsaw";
    JigsawModeBehavior.TEMPLATE_POOL = "Template Pool";
    JigsawModeBehavior.MINIMUM_WEIGHT = 1;
    JigsawModeBehavior.MAXIMUM_WEIGHT = 20;
    JigsawModeBehavior.MINIMUM_DEPTH = 1;
    JigsawModeBehavior.MAXIMUM_DEPTH = 20;
    JigsawModeBehavior.MINIMUM_HORIZONTAL_SIZE = 16;
    JigsawModeBehavior.MAXIMUM_HORIZONTAL_SIZE = 1024;
    class PrefabTemplateManagerBehavior {
        get prefabManager() {
            return this._parent.prefabManager;
        }
        get currentSelectedTemplate() {
            return this._parent.currentSelectedTemplate;
        }
        set currentSelectedTemplate(value) {
            this._parent.currentSelectedTemplate = value;
        }
        showManagerWindow() {
            this._rootPropertyPane?.show();
        }
        constructor(uiSession, parent) {
            this.uiSession = uiSession;
            this._selectedTemplateIndex = (0, server_editor_namespaceObject.makeObservable)(0);
            this._parent = parent;
            this._session = uiSession;
            this._rootPropertyPane = this._createRootPropertyPane();
            this._registerActionBarItem();
            this._nameDialog = new ModalDialogMultiStringInput(this._session, this._rootPropertyPane);
            this._confirmationDialog = new ModalDialogConfirmation(this._session, this._rootPropertyPane);
        }
        get session() {
            return this._session;
        }
        teardown() {}
        _registerActionBarItem() {
            const showTemplateManagerAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => this.showManagerWindow()
            });
            this.session.actionBar.registerItem("editor:actionBar:prefabTemplateManager", showTemplateManagerAction, {
                label: "editor.prefabTemplateEditor.actionBar.title",
                icon: "pack://textures/editor/Play.png",
                tooltipTitle: "editor.prefabTemplateEditor.actionBar.tooltip",
                tooltipDescription: "editor.prefabTemplateEditor.actionBar.tooltip.description",
                enabled: true,
                executeOnAdd: false
            });
        }
        _updateTemplatesListControl() {
            if (!this._templateListUIControl) return;
            const prefabTemplateList = this.prefabManager.getTemplateList();
            const entries = prefabTemplateList.map(((template, index) => {
                const name = template.name.trim();
                const displayName = template.displayName.trim();
                const label = displayName === "" ? name : `${displayName} (${name})`;
                const item = {
                    label,
                    value: index
                };
                return item;
            }));
            this._templateListUIControl.updateEntries(entries);
        }
        _generateEmptyTemplateName(baseName = "NewTemplate") {
            const prefabTemplateList = this.prefabManager.getTemplateList();
            let index = 1;
            const regex = /_(\d+)$/;
            const match = baseName.match(regex);
            if (match) {
                index = parseInt(match[1], 10) + 1;
                baseName = baseName.replace(regex, "");
            }
            let newName = baseName;
            while (prefabTemplateList.some((template => template.name === newName))) {
                newName = `${baseName}_${index}`;
                index++;
            }
            return newName;
        }
        _validateTemplateName(name) {
            const prefabTemplateList = this.prefabManager.getTemplateList();
            if (!name || name.trim() === "") {
                return {
                    valid: false,
                    message: "Template name cannot be empty"
                };
            }
            if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
                return {
                    valid: false,
                    message: "Template name must start with a letter or underscore and contain only alphanumeric characters and underscores"
                };
            }
            if (prefabTemplateList.some((template => template.name === name))) {
                return {
                    valid: false,
                    message: `Template name "${name}" already exists`
                };
            }
            return {
                valid: true,
                message: ""
            };
        }
        _validateTemplateNamespace(name) {
            if (!name || name.trim() === "") {
                return {
                    valid: false,
                    message: "Template namespace cannot be empty"
                };
            }
            if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
                return {
                    valid: false,
                    message: "Template namespace must start with a letter or underscore and contain only alphanumeric characters and underscores"
                };
            }
            return {
                valid: true,
                message: ""
            };
        }
        _createRootPropertyPane() {
            const rootPropertyPane = this.session.createPropertyPane({
                uniqueId: "PrefabTemplateManager",
                title: "editor.prefabTemplateEditor.pane.templateManager.title"
            });
            rootPropertyPane.beginConstruct();
            this._templateListUIControl = rootPropertyPane.addDropdown(this._selectedTemplateIndex, {
                entries: [],
                title: "editor.prefabTemplateEditor.pane.templateManager.templates.title",
                onChange: _index => {
                    const prefabTemplateList = this.prefabManager.getTemplateList();
                    const template = prefabTemplateList[this._selectedTemplateIndex.value];
                    this.currentSelectedTemplate = template;
                }
            });
            this._updateTemplatesListControl();
            rootPropertyPane.addDivider();
            const updateButtonEnabledState = () => {
                const prefabTemplateList = this.prefabManager.getTemplateList();
                const enabled = this._selectedTemplateIndex.value >= 0 && this._selectedTemplateIndex.value < prefabTemplateList.length && prefabTemplateList.length > 0;
                newTemplateButton.enable = true;
                deleteTemplateButton.enable = enabled;
                copyTemplateButton.enable = enabled;
                editTemplateButton.enable = enabled;
            };
            const newTemplateButton = rootPropertyPane.addButton((() => {
                const inputFields = [ {
                    validator: this._validateTemplateName.bind(this),
                    title: "editor.prefabTemplateEditor.pane.templateManager.newTemplate.name",
                    initialValue: this._generateEmptyTemplateName(),
                    tooltip: "editor.prefabTemplateEditor.pane.templateManager.newTemplate.name.tooltip",
                    failedValidationMessage: "Invalid template name"
                }, {
                    validator: () => ({
                        valid: true,
                        message: ""
                    }),
                    title: "editor.prefabTemplateEditor.pane.templateManager.newTemplate.displayName",
                    initialValue: "",
                    tooltip: "editor.prefabTemplateEditor.pane.templateManager.newTemplate.displayName.tooltip",
                    failedValidationMessage: "Keep it clean!"
                } ];
                this._nameDialog.activate("editor.prefabTemplateEditor.pane.templateManager.newtemplate", inputFields).then((fields => {
                    if (fields.length === 0) {
                        throw new Error("Invalid return from dialog");
                    }
                    const name = fields[0];
                    let displayName = fields[1];
                    if (displayName.trim() === "") {
                        displayName = name;
                    }
                    const newTemplate = this.prefabManager.createTemplate(name, {
                        displayName
                    });
                    this.currentSelectedTemplate = newTemplate.getMetadata();
                    const prefabTemplateList = this.prefabManager.getTemplateList();
                    const newTemplateIndex = prefabTemplateList.findIndex((template => template.name === newTemplate.name));
                    this._updateTemplatesListControl();
                    this._selectedTemplateIndex.set(newTemplateIndex);
                    updateButtonEnabledState();
                })).catch((error => {
                    this.session.log.error(error.message);
                }));
            }), {
                title: "editor.prefabTemplateEditor.pane.templateManager.newtemplate"
            });
            const deleteTemplateButton = rootPropertyPane.addButton((() => {
                let prefabTemplateList = this.prefabManager.getTemplateList();
                const selectedTemplateMetadata = prefabTemplateList[this._selectedTemplateIndex.value];
                const name = selectedTemplateMetadata.name.trim();
                const displayName = selectedTemplateMetadata.displayName.trim();
                const selectedFullName = displayName === "" ? name : `${displayName} (${name})`;
                this._confirmationDialog.activate({
                    id: "editor.prefabTemplateEditor.pane.templateManager.templates.deleteTemplate.title",
                    props: [ selectedFullName ]
                }).then((() => {
                    let selectedIndex = this._selectedTemplateIndex.value;
                    let newSelectedTemplate = undefined;
                    this.prefabManager.deleteTemplate(selectedTemplateMetadata);
                    prefabTemplateList = this.prefabManager.getTemplateList();
                    this._updateTemplatesListControl();
                    if (prefabTemplateList.length > 0) {
                        if (selectedIndex >= prefabTemplateList.length) {
                            selectedIndex = prefabTemplateList.length - 1;
                        }
                        this._selectedTemplateIndex.set(selectedIndex);
                        newSelectedTemplate = prefabTemplateList[this._selectedTemplateIndex.value];
                    } else {
                        this._selectedTemplateIndex.set(-1);
                        newSelectedTemplate = undefined;
                    }
                    this.session.log.info(`Deleted layout template: ${selectedFullName}`, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    updateButtonEnabledState();
                    this.currentSelectedTemplate = newSelectedTemplate;
                    if (newSelectedTemplate === undefined || selectedTemplateMetadata.name === newSelectedTemplate.name) {
                        const selectedTool = this.session.toolRail.getSelectedToolId();
                        if (selectedTool === "editor:tool:prefabTemplateEditor") {
                            this.session.toolRail.setSelectedToolId(undefined);
                            this.session.toolRail.setSelectedToolId("editor:tool:prefabTemplateEditor");
                        }
                    }
                })).catch((error => {
                    this.session.log.error(error.message);
                }));
            }), {
                title: "editor.prefabTemplateEditor.pane.templateManager.deleteTemplate"
            });
            const copyTemplateButton = rootPropertyPane.addButton((() => {
                let prefabTemplateList = this.prefabManager.getTemplateList();
                if (this._selectedTemplateIndex.value < 0 || this._selectedTemplateIndex.value >= prefabTemplateList.length) {
                    this.session.log.error("Select a template to copy first", {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    return;
                }
                const selectedTemplateMetadata = prefabTemplateList[this._selectedTemplateIndex.value];
                if (selectedTemplateMetadata.displayName.trim() === selectedTemplateMetadata.name) {
                    selectedTemplateMetadata.displayName = "";
                }
                const selectedFullName = selectedTemplateMetadata.name;
                const inputFields = [ {
                    validator: this._validateTemplateName.bind(this),
                    title: "editor.prefabTemplateEditor.pane.templateManager.newTemplate.name",
                    initialValue: this._generateEmptyTemplateName(selectedTemplateMetadata.name),
                    tooltip: "editor.prefabTemplateEditor.pane.templateManager.newTemplate.name.tooltip",
                    failedValidationMessage: "Invalid template name"
                }, {
                    validator: () => ({
                        valid: true,
                        message: ""
                    }),
                    title: "editor.prefabTemplateEditor.pane.templateManager.newTemplate.displayName",
                    initialValue: selectedTemplateMetadata.displayName,
                    tooltip: "editor.prefabTemplateEditor.pane.templateManager.newTemplate.displayName.tooltip",
                    failedValidationMessage: "Keep it clean!"
                } ];
                this._nameDialog.activate(`Copy Existing Template (${selectedFullName}) ?`, inputFields).then((fields => {
                    if (fields.length === 0) {
                        throw new Error("Invalid return from dialog");
                    }
                    const name = fields[0];
                    let displayName = fields[1];
                    if (displayName.trim() === "") {
                        displayName = name;
                    }
                    const templateToCopy = this.prefabManager.getTemplate(selectedTemplateMetadata);
                    const clonedTemplate = this.prefabManager.cloneTemplate(templateToCopy, name, displayName);
                    prefabTemplateList = this.prefabManager.getTemplateList();
                    this.currentSelectedTemplate = clonedTemplate.getMetadata();
                    const newSelectedIndex = prefabTemplateList.findIndex((template => template.name === name));
                    this._updateTemplatesListControl();
                    this._selectedTemplateIndex.set(newSelectedIndex);
                    updateButtonEnabledState();
                })).catch((error => {
                    this.session.log.error(error.message);
                }));
            }), {
                title: "editor.prefabTemplateEditor.pane.templateManager.copyTemplate"
            });
            const editTemplateButton = rootPropertyPane.addButton((() => {
                const prefabTemplateList = this.prefabManager.getTemplateList();
                const selectedTemplate = prefabTemplateList[this._selectedTemplateIndex.value];
                if (selectedTemplate !== undefined) {
                    this.currentSelectedTemplate = selectedTemplate;
                }
                const selectedTool = this.session.toolRail.getSelectedToolId();
                if (selectedTool === "editor:tool:prefabTemplateEditor") {
                    this.session.toolRail.setSelectedToolId(undefined);
                    server_namespaceObject.system.runTimeout((() => {
                        this.session.toolRail.setSelectedToolId("editor:tool:prefabTemplateEditor");
                    }), 5);
                } else {
                    this.session.toolRail.setSelectedToolId("editor:tool:prefabTemplateEditor");
                }
            }), {
                title: "editor.prefabTemplateEditor.pane.templateManager.editTemplate"
            });
            updateButtonEnabledState();
            rootPropertyPane.endConstruct();
            return rootPropertyPane;
        }
    }
    class MockPrefabTemplateStructureRef {
        constructor(id, structureId, offset, rotation, mirror) {
            this._id = id;
            this._structureId = structureId;
            this._offset = offset || {
                x: 0,
                y: 0,
                z: 0
            };
            this._rotation = rotation || server_namespaceObject.StructureRotation.None;
            this._mirror = mirror || server_namespaceObject.StructureMirrorAxis.None;
            this._size = {
                x: 1,
                y: 1,
                z: 1
            };
        }
        get id() {
            return this._id;
        }
        get structureId() {
            return this._structureId;
        }
        get offset() {
            return this._offset;
        }
        get size() {
            return this._size;
        }
        set size(value) {
            this._size = value;
        }
        get rotation() {
            return this._rotation;
        }
        get mirror() {
            return this._mirror;
        }
        set offset(value) {
            this._offset = value;
        }
        set rotation(value) {
            this._rotation = value;
        }
        set mirror(value) {
            this._mirror = value;
        }
        clone() {
            return new MockPrefabTemplateStructureRef(guid(), this._structureId, {
                ...this._offset
            }, this._rotation, this._mirror);
        }
        get structureRotation() {
            return this._rotation;
        }
        set structureRotation(value) {
            this._rotation = value;
        }
        get structureMirror() {
            return this._mirror;
        }
        set structureMirror(value) {
            this._mirror = value;
        }
    }
    class MockPrefabTemplate {
        constructor(name, description, displayName, notes, tags) {
            this._tags = [];
            this._structureRefs = [];
            this._id = guid();
            this._name = name;
            this._description = description;
            this._displayName = displayName;
            this._notes = notes;
            this._tags = tags;
        }
        get id() {
            return this._id;
        }
        get name() {
            return this._name;
        }
        get description() {
            return this._description;
        }
        get displayName() {
            return this._displayName;
        }
        get notes() {
            return this._notes;
        }
        get tags() {
            return this._tags;
        }
        set name(value) {
            this._name = value;
        }
        set description(value) {
            this._description = value;
        }
        set displayName(value) {
            this._displayName = value;
        }
        set notes(value) {
            this._notes = value;
        }
        set tags(value) {
            this._tags = value;
        }
        get structureRefs() {
            return this._structureRefs;
        }
        addStructureRef(structureRef) {
            this._structureRefs.push(structureRef);
        }
        removeStructureRef(id) {
            this._structureRefs = this._structureRefs.filter((ref => ref.id !== id));
        }
        clone(newName, newDisplayName) {
            const clonedTemplate = new MockPrefabTemplate(newName ?? this._name, this._description, newDisplayName ?? this._displayName, this._notes, this._tags);
            this._structureRefs.forEach((ref => {
                clonedTemplate.addStructureRef(ref.clone());
            }));
            return clonedTemplate;
        }
    }
    class MockPrefabDB {
        constructor() {
            this._templates = [];
        }
        addTemplate(template) {
            this._templates.push(template);
        }
        removeTemplate(id) {
            this._templates = this._templates.filter((template => template.id !== id));
        }
        clearTemplates() {
            this._templates = [];
        }
        copyTemplate(template, newName) {
            const existing = this.findTemplateByName(newName);
            if (existing) {
                throw new Error(`Template with name "${newName}" already exists.`);
            }
            const copiedTemplate = template.clone(newName);
            this.addTemplate(copiedTemplate);
            return copiedTemplate;
        }
        get templates() {
            return this._templates;
        }
        findTemplateByName(name) {
            return this._templates.find((template => template.name === name));
        }
        findTemplateById(id) {
            return this._templates.find((template => template.id === id));
        }
        get currentSelectedId() {
            return this._currentSelectedId;
        }
        set currentSelectedId(id) {
            this._currentSelectedId = id;
        }
        loadTemplate(_templateMetadata, _prefabManager) {
            this._templates = [];
            const inTemplate = _prefabManager.getTemplate(_templateMetadata);
            const newName = inTemplate.name;
            const newTemplate = new MockPrefabTemplate(newName, inTemplate.description, inTemplate.displayName, inTemplate.notes, inTemplate.getTags());
            const inStructureRefs = inTemplate.getTemplateStructures();
            inStructureRefs.forEach((ref => {
                const templateStructureRefId = ref.id;
                const structure = ref.getStructure();
                const structureId = structure.id;
                const instanceRotation = ref.instanceRotation;
                const instanceMirror = ref.instanceMirror;
                const instanceOffset = ref.instanceOffset;
                const newRef = new MockPrefabTemplateStructureRef(templateStructureRefId, structureId, instanceOffset, instanceRotation, instanceMirror);
                newTemplate.addStructureRef(newRef);
            }));
            this.addTemplate(newTemplate);
        }
        saveTemplate(_session, _outTemplateMetadata, _prefabManager) {
            if (this._templates.length !== 1) {
                throw new Error("No template to save or multiple templates present.");
            }
            const outTemplate = _prefabManager.getTemplate(_outTemplateMetadata);
            const templateToSave = this._templates[0];
            outTemplate.description = templateToSave.description;
            outTemplate.displayName = templateToSave.displayName;
            outTemplate.notes = templateToSave.notes;
            outTemplate.setTags(templateToSave.tags);
            const outTemplateStructures = outTemplate.getTemplateStructures();
            templateToSave.structureRefs.forEach((ref => {
                const templateStructureRefId = ref.id;
                const structureId = ref.structureId;
                const offset = ref.offset;
                const rotation = ref.rotation;
                const mirror = ref.mirror;
                const existingRef = outTemplateStructures.find((r => r.id === templateStructureRefId));
                if (existingRef) {
                    existingRef.instanceMirror = mirror;
                    existingRef.instanceOffset = offset;
                    existingRef.instanceRotation = rotation;
                } else {
                    const editorStructure = _session.extensionContext.structureManager.getStructure(structureId);
                    outTemplate.addStructure(editorStructure, {
                        offset,
                        rotation,
                        mirror
                    });
                }
            }));
            outTemplateStructures.forEach((ref => {
                const templateStructureRefId = ref.id;
                const existsInMock = templateToSave.structureRefs.some((r => r.id === templateStructureRefId));
                if (!existsInMock) {
                    outTemplate.removeStructure(ref);
                }
            }));
        }
    }
    const rotationOrder = [ server_namespaceObject.StructureRotation.None, server_namespaceObject.StructureRotation.Rotate90, server_namespaceObject.StructureRotation.Rotate180, server_namespaceObject.StructureRotation.Rotate270 ];
    function getRotationOrderIndex(rotation) {
        const index = rotationOrder.indexOf(rotation);
        return index;
    }
    function getRotationOrderFromIndex(index) {
        return rotationOrder[index];
    }
    function getMirrorAxisFromBooleans(mirrorX, mirrorZ) {
        if (mirrorX && mirrorZ) {
            return server_namespaceObject.StructureMirrorAxis.XZ;
        } else if (mirrorX) {
            return server_namespaceObject.StructureMirrorAxis.X;
        } else if (mirrorZ) {
            return server_namespaceObject.StructureMirrorAxis.Z;
        }
        return server_namespaceObject.StructureMirrorAxis.None;
    }
    function getBooleansFromMirrorAxis(mirrorAxis) {
        switch (mirrorAxis) {
          case server_namespaceObject.StructureMirrorAxis.XZ:
            return {
                mirrorX: true,
                mirrorZ: true
            };

          case server_namespaceObject.StructureMirrorAxis.X:
            return {
                mirrorX: true,
                mirrorZ: false
            };

          case server_namespaceObject.StructureMirrorAxis.Z:
            return {
                mirrorX: false,
                mirrorZ: true
            };

          default:
            return {
                mirrorX: false,
                mirrorZ: false
            };
        }
    }
    class ModalStructurePicker {
        get selectedStructureId() {
            return this._selectedStructureId;
        }
        get selectedStructureDisplayName() {
            return this._editorStructures.find((structure => structure.id === this._selectedStructureId))?.displayName;
        }
        constructor(session, parentPane) {
            this._selectedStructureIndex = (0, server_editor_namespaceObject.makeObservable)(-1);
            this._editorStructures = [];
            this._session = session;
            this._parentPane = parentPane;
            this._pane = this._parentPane.createModalOverlayPane({
                title: "editor.prefabTemplateEditor.structurePicker.title"
            });
            this._selectedStructureId = undefined;
            this._pane.contentPane.addText("editor.prefabTemplateEditor.structurePicker.instruction", {
                alignment: server_editor_namespaceObject.LayoutAlignment.Center
            });
            this._selectedStructureIndex.set(-1);
            this._structureDropdown = this._pane.contentPane.addDropdown(this._selectedStructureIndex, {
                entries: [],
                title: "editor.prefabTemplateEditor.structurePicker.picker.title",
                onChange: _index => {
                    this._selectedStructureId = this._editorStructures[_index].id;
                }
            });
            this._updateStructureList();
            this._pane.contentPane.addDivider();
            this._pane.contentPane.addButton((() => {
                this._pane.hide();
                this._parentPane.setActiveModalOverlay("");
                this._resolve?.();
                this._reject = undefined;
                this._resolve = undefined;
            }), {
                title: "editor.prefabTemplateEditor.structurePicker.picker.select",
                variant: server_editor_namespaceObject.ButtonVariant.Primary
            });
            this._pane.contentPane.addButton((() => {
                this._pane.hide();
                this._parentPane.setActiveModalOverlay("");
                this._reject?.(new Error("Cancelled"));
                this._reject = undefined;
                this._resolve = undefined;
            }), {
                title: "editor.prefabTemplateEditor.structurePicker.picker.cancel"
            });
            this._parentPane.onPropertyPaneVisibilityUpdated.subscribe((eventData => {
                if (this._resolve !== undefined || this._reject !== undefined) {
                    if (eventData.isVisible) {
                        throw new Error("Something went wrong - dialog is being activated while promises are still pending");
                    } else {
                        if (this._resolve !== undefined || this._reject !== undefined) {
                            this._reject?.(new Error("Parent pane closed while dialog was active"));
                            this._reject = undefined;
                            this._resolve = undefined;
                        }
                        this._pane.hide();
                        this._parentPane.setActiveModalOverlay("");
                    }
                }
            }));
        }
        _updateStructureList() {
            this._editorStructures = this._session.extensionContext.structureManager.searchStructures({
                sources: [ server_editor_namespaceObject.StructureSource.EditorProject ]
            });
            const entries = this._editorStructures.map(((structure, index) => {
                const item = {
                    label: `${structure.displayName} (${structure.structureFullName})`,
                    value: index
                };
                return item;
            }));
            if (entries.length > 0) {
                this._selectedStructureId = this._editorStructures[0].id;
                this._selectedStructureIndex.set(0);
            }
            this._structureDropdown.updateEntries(entries);
        }
        async activate() {
            if (this._parentPane.getActiveModalOverlayId() !== undefined) {
                this._pane.hide();
                throw new Error("Another modal overlay is already active");
            }
            this._updateStructureList();
            this._parentPane.setActiveModalOverlay(this._pane.id);
            this._pane.show();
            return new Promise(((resolve, reject) => {
                this._resolve = resolve;
                this._reject = reject;
            }));
        }
    }
    class Line3D {
        dispose() {
            this._widget.delete();
        }
        show() {
            this._widget.visible = true;
        }
        hide() {
            this._widget.visible = false;
        }
        constructor(widgetGroup, start, end) {
            this._start = lib.Vector3Utils.add(start, {
                x: .5,
                y: 0,
                z: .5
            });
            this._end = lib.Vector3Utils.add(end, {
                x: .5,
                y: 0,
                z: .5
            });
            this._length = lib.Vector3Utils.subtract(this._end, this._start);
            this._widget = widgetGroup.createWidget(this._start, {
                selectable: false,
                visible: true
            });
            const h = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeLine({
                x: 0,
                y: 0,
                z: 0
            }, this._length, {
                red: 1,
                green: 1,
                blue: 0,
                alpha: 1
            });
            h.renderPriority = 10;
            this._linePrim = this._widget.addRenderPrimitiveComponent("h", h, {});
            this._linePrim.visible = false;
            const xPlaceholder = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeLine({
                x: 0,
                y: 0,
                z: 0
            }, {
                x: 0,
                y: 0,
                z: 0
            }, {
                red: 1,
                green: 0,
                blue: 0,
                alpha: 1
            });
            xPlaceholder.renderPriority = 10;
            this._xPrim = this._widget.addRenderPrimitiveComponent("x", xPlaceholder, {
                visible: false
            });
            this._xText = this._widget.addTextComponent("tx", "0", {
                color: {
                    red: 1,
                    green: 1,
                    blue: 1,
                    alpha: 1
                }
            });
            const yPlaceholder = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeLine({
                x: 0,
                y: 0,
                z: 0
            }, {
                x: 0,
                y: 0,
                z: 0
            }, {
                red: 0,
                green: 1,
                blue: 0,
                alpha: 1
            });
            yPlaceholder.renderPriority = 10;
            this._yPrim = this._widget.addRenderPrimitiveComponent("y", yPlaceholder, {
                visible: false
            });
            this._yText = this._widget.addTextComponent("ty", "0", {
                color: {
                    red: 1,
                    green: 1,
                    blue: 1,
                    alpha: 1
                }
            });
            const zPlaceholder = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeLine({
                x: 0,
                y: 0,
                z: 0
            }, {
                x: 0,
                y: 0,
                z: 0
            }, {
                red: 0,
                green: 0,
                blue: 1,
                alpha: 1
            });
            zPlaceholder.renderPriority = 10;
            this._zPrim = this._widget.addRenderPrimitiveComponent("z", zPlaceholder, {
                visible: false
            });
            this._zText = this._widget.addTextComponent("tz", "0", {
                color: {
                    red: 1,
                    green: 1,
                    blue: 1,
                    alpha: 1
                }
            });
            this._calculateAxisPrimitives();
        }
        set end(value) {
            this._end = lib.Vector3Utils.add(value, {
                x: .5,
                y: 0,
                z: .5
            });
            this._length = lib.Vector3Utils.subtract(this._end, this._start);
            const h = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeLine({
                x: 0,
                y: 0,
                z: 0
            }, this._length, {
                red: 1,
                green: 1,
                blue: 0,
                alpha: 1
            });
            h.renderPriority = 10;
            this._linePrim.setPrimitive(h);
            this._linePrim.visible = false;
            this._calculateAxisPrimitives();
        }
        _calculateAxisPrimitives() {
            if (Math.abs(this._length.x) > .001) {
                const xPrim = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeLine({
                    x: 0,
                    y: 0,
                    z: 0
                }, {
                    x: this._length.x,
                    y: 0,
                    z: 0
                }, {
                    red: 1,
                    green: 0,
                    blue: 0,
                    alpha: 1
                });
                xPrim.renderPriority = 10;
                this._xPrim.setPrimitive(xPrim);
                this._xPrim.visible = true;
                this._xText.visible = true;
                this._xText.label = this._length.x.toFixed(0);
                this._xText.offset = {
                    x: this._length.x / 2,
                    y: 0,
                    z: 0
                };
            } else {
                this._xPrim.visible = false;
                this._xText.visible = false;
            }
            if (Math.abs(this._length.z) > .001) {
                const zPrim = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeLine({
                    x: this._length.x,
                    y: 0,
                    z: 0
                }, {
                    x: this._length.x,
                    y: 0,
                    z: this._length.z
                }, {
                    red: 0,
                    green: 0,
                    blue: 1,
                    alpha: 1
                });
                zPrim.renderPriority = 10;
                this._zPrim.setPrimitive(zPrim);
                this._zPrim.visible = true;
                this._zText.visible = true;
                this._zText.label = this._length.z.toFixed(0);
                this._zText.offset = {
                    x: this._length.x,
                    y: 0,
                    z: this._length.z / 2
                };
            } else {
                this._zPrim.visible = false;
                this._zText.visible = false;
            }
            if (Math.abs(this._length.y) > .001) {
                const yPrim = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeLine({
                    x: this._length.x,
                    y: 0,
                    z: this._length.z
                }, {
                    x: this._length.x,
                    y: this._length.y,
                    z: this._length.z
                }, {
                    red: 0,
                    green: 1,
                    blue: 0,
                    alpha: 1
                });
                yPrim.renderPriority = 10;
                this._yPrim.setPrimitive(yPrim);
                this._yPrim.visible = true;
                this._yText.visible = true;
                this._yText.label = this._length.y.toFixed(0);
                this._yText.offset = {
                    x: this._length.x,
                    y: this._length.y / 2,
                    z: this._length.z
                };
            } else {
                this._yPrim.visible = false;
                this._yText.visible = false;
            }
        }
        get start() {
            return this._start;
        }
        get end() {
            return this._end;
        }
        get length() {
            return this._length;
        }
        setAxisVisibility(showX, showY, showZ) {
            if (Math.abs(this._length.x) > .001) this._xPrim.visible = showX;
            if (Math.abs(this._length.y) > .001) this._yPrim.visible = showY;
            if (Math.abs(this._length.z) > .001) this._zPrim.visible = showZ;
        }
        updateLine(start, end) {
            this._start = start;
            this._end = end;
            this._length = lib.Vector3Utils.subtract(end, start);
            this._widget.location = start;
            const h = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeLine({
                x: 0,
                y: 0,
                z: 0
            }, this._length, {
                red: 1,
                green: 1,
                blue: 0,
                alpha: 1
            });
            h.renderPriority = 10;
            this._linePrim.setPrimitive(h);
            this._calculateAxisPrimitives();
        }
    }
    class StructureRefUIControl {
        dispose() {
            this._line.dispose();
            this._widget.delete();
        }
        get pane() {
            return this._pane;
        }
        get structureRef() {
            return this._structureRef;
        }
        focus() {
            this._line.show();
            this._structurePreview.showOutline = true;
            this._gizmo.activated = true;
            this._widget.selected = true;
            this._pane.expand();
        }
        unfocus() {
            this._line.hide();
            this._structurePreview.showOutline = false;
            this._gizmo.activated = false;
            this._widget.selected = false;
            this._pane.collapse();
        }
        constructor(parentPane, session, template, structureRef, widgetGroup, onFocusGain, onFocusLoss, onDeleteRequest) {
            this._offset = (0, server_editor_namespaceObject.makeObservable)({
                x: 0,
                y: 0,
                z: 0
            });
            this._rotationIndex = (0, server_editor_namespaceObject.makeObservable)(getRotationOrderIndex(server_namespaceObject.StructureRotation.None));
            this._mirrorX = (0, server_editor_namespaceObject.makeObservable)(false);
            this._mirrorZ = (0, server_editor_namespaceObject.makeObservable)(false);
            this._parentPane = parentPane;
            this._session = session;
            this._template = template;
            this._structureRef = structureRef;
            this._widgetGroup = widgetGroup;
            this._fnOnFocusGain = onFocusGain;
            this._fnOnFocusLoss = onFocusLoss;
            this._fnOnDeleteRequest = onDeleteRequest;
            const editorStructure = this._session.extensionContext.structureManager.getStructure(structureRef.structureId);
            if (!editorStructure) {
                throw new Error(`Structure with ID ${structureRef.structureId} not found`);
            }
            const absoluteOrigin = {
                x: Math.round((editorStructure.normalizedOrigin.x + 1) * ((editorStructure.size.x - 1) / 2)),
                y: Math.round((editorStructure.normalizedOrigin.y + 1) * ((editorStructure.size.y - 1) / 2)),
                z: Math.round((editorStructure.normalizedOrigin.z + 1) * ((editorStructure.size.z - 1) / 2))
            };
            this._widget = this._widgetGroup.createWidget({
                x: structureRef.offset.x,
                y: structureRef.offset.y,
                z: structureRef.offset.z
            }, {
                selectable: true,
                visible: true,
                collisionType: server_editor_namespaceObject.WidgetCollisionType.Bounds,
                stateChangeEvent: _eventData => {
                    if (_eventData.selected !== undefined) {
                        if (_eventData.selected) {
                            this._fnOnFocusGain(this);
                        } else {
                            this._fnOnFocusLoss(this);
                        }
                    }
                }
            });
            const gizmoOptions = {
                axes: server_editor_namespaceObject.Axis.X | server_editor_namespaceObject.Axis.Z | server_editor_namespaceObject.Axis.Y,
                enablePlanes: true,
                offset: {
                    x: .5,
                    y: 0,
                    z: .5
                },
                stateChangeEvent: data => {
                    if (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.CornerMoved || data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginMoved) {
                        if (!lib.Vector3Utils.equals(this._offset.value, data.widget.location)) {
                            this._offset.set(data.widget.location);
                            this._structureRef.offset = data.widget.location;
                            this._line.end = data.widget.location;
                        }
                    } else if (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginActivated) {
                        this._fnOnFocusGain(this);
                    } else if (data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginDeactivated) {
                        this._fnOnFocusLoss(this);
                    }
                }
            };
            this._gizmo = this._widget.addGizmoComponent("gizmo", gizmoOptions);
            this._structurePreview = this._widget.addClipboardComponent("clipboard", editorStructure, {
                clipboardOffset: editorStructure.offset,
                highlightHullColor: {
                    red: 0,
                    green: 0,
                    blue: 0,
                    alpha: 0
                },
                highlightOutlineColor: {
                    red: 0,
                    green: 0,
                    blue: 0,
                    alpha: 0
                },
                normalizedOrigin: editorStructure.normalizedOrigin,
                showOutline: false
            });
            this._offset.set(structureRef.offset);
            this._rotationIndex.set(getRotationOrderIndex(structureRef.structureRotation));
            const mirrorBooleans = getBooleansFromMirrorAxis(structureRef.structureMirror);
            this._mirrorX.set(mirrorBooleans.mirrorX);
            this._mirrorZ.set(mirrorBooleans.mirrorZ);
            this._pane = this._parentPane.createSubPane({
                hasExpander: true,
                title: "Structure"
            });
            this._pane.addVector3(editorStructure.size, {
                title: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.size",
                enable: false
            });
            this._pane.addVector3(editorStructure.offset, {
                title: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.offset",
                enable: false
            });
            this._pane.addVector3(absoluteOrigin, {
                title: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.origin",
                enable: false
            });
            this._pane.addVector3(this._offset, {
                title: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.rootoffset",
                min: {
                    x: -32,
                    y: -32,
                    z: -32
                },
                max: {
                    x: 32,
                    y: 32,
                    z: 32
                },
                onChange: _value => {
                    this._structureRef.offset = _value;
                    this._widget.location = _value;
                    this._line.end = _value;
                }
            });
            this._pane.addDropdown(this._rotationIndex, {
                title: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.rotation",
                entries: [ {
                    value: 0,
                    label: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.rotation.none"
                }, {
                    value: 1,
                    label: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.rotation.90"
                }, {
                    value: 2,
                    label: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.rotation.180"
                }, {
                    value: 3,
                    label: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.rotation.270"
                } ],
                onChange: (_newValue, _oldValue) => {
                    this._structureRef.structureRotation = getRotationOrderFromIndex(_newValue);
                    this._structurePreview.rotation = this._structureRef.structureRotation;
                }
            });
            this._pane.addBool(this._mirrorX, {
                enable: true,
                title: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.mirrorX",
                onChange: (_newValue, _oldValue) => {
                    const mirrorAxis = getMirrorAxisFromBooleans(_newValue, this._mirrorZ.value);
                    this._structureRef.structureMirror = mirrorAxis;
                    this._structurePreview.mirror = mirrorAxis;
                }
            });
            this._pane.addBool(this._mirrorZ, {
                enable: true,
                title: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.mirrorZ",
                onChange: (_newValue, _oldValue) => {
                    const mirrorAxis = getMirrorAxisFromBooleans(this._mirrorX.value, _newValue);
                    this._structureRef.structureMirror = mirrorAxis;
                    this._structurePreview.mirror = mirrorAxis;
                }
            });
            this._pane.addButton((() => {
                this._fnOnFocusGain(this);
            }), {
                title: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.focus"
            });
            this._pane.addButton((() => {
                this._fnOnDeleteRequest(this);
            }), {
                title: "editor.prefabTemplateEditor.pane.prefabTemplate.structure.remove"
            });
            this._pane.show();
            this._line = new Line3D(this._widgetGroup, {
                x: 0,
                y: 0,
                z: 0
            }, this._offset.value);
            this._line.hide();
        }
    }
    class PrefabTemplateEditorBehavior {
        get prefabManager() {
            return this._parent.prefabManager;
        }
        get currentSelectedTemplate() {
            return this._parent.currentSelectedTemplate;
        }
        set currentSelectedTemplate(value) {
            this._parent.currentSelectedTemplate = value;
        }
        constructor(uiSession, parent) {
            this.uiSession = uiSession;
            this._onToolFocusLoss = () => {};
            this._structureRefControls = [];
            this._session = uiSession;
            this._parent = parent;
            this._templateDB = new MockPrefabDB;
            const newTemplate = new MockPrefabTemplate("name", "description", "displayName", "notes", []);
            this._templateDB.addTemplate(newTemplate);
            this.currentSelectedTemplate = undefined;
            this._widgetGroup = uiSession.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.Single,
                visible: true
            });
            this._tool = this._addTool();
            this._rootPropertyPane = this._createRootPropertyPane();
            this._rootPaneContent = this._rebuildUIPanes();
            this._structurePicker = new ModalStructurePicker(this._session, this._rootPropertyPane);
        }
        get session() {
            return this._session;
        }
        teardown() {
            this._widgetGroup.delete();
        }
        _addTool() {
            const tool = this.session.toolRail.addTool("editor:tool:prefabTemplateEditor", {
                title: "editor.prefabTemplateEditor.tool.title",
                icon: "gridIcon",
                tooltip: "editor.prefabTemplateEditor.tool.tooltip"
            });
            tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    if (this.currentSelectedTemplate !== undefined) {
                        this._templateDB.loadTemplate(this.currentSelectedTemplate, this.prefabManager);
                    }
                    this._rootPaneContent = this._rebuildUIPanes();
                    this._rootPaneContent.show();
                } else {
                    if (this._onToolFocusLoss) {
                        this._onToolFocusLoss();
                        this._onToolFocusLoss = () => {};
                    }
                }
            }));
            return tool;
        }
        _rebuildUIPanes() {
            let pane = undefined;
            if (this._rootPaneContent) {
                this._rootPaneContent.hide();
                this._rootPropertyPane.removeSubPane(this._rootPaneContent);
                this._rootPaneContent = undefined;
            }
            if (this.currentSelectedTemplate === undefined) {
                pane = this._createEmptyTemplateEditorPane();
            } else {
                pane = this._setupTemplateEditingEnvironment();
            }
            return pane;
        }
        _constructStructureRefControl(pane, newRef, takeFocus) {
            const onStructureRefFocusGain = control => {
                this._structureRefControls.forEach((c => {
                    if (c !== control) {
                        c.unfocus();
                    }
                }));
                control.focus();
            };
            const onStructureRefFocusLoss = control => {
                control.unfocus();
            };
            const onDeleteRequest = control => {
                pane.removeSubPane(control.pane);
                this._structureRefControls = this._structureRefControls.filter((c => c !== control));
                this._template?.removeStructureRef(control.structureRef.id);
                control.dispose();
            };
            const control = new StructureRefUIControl(pane, this._session, this._template, newRef, this._widgetGroup, onStructureRefFocusGain, onStructureRefFocusLoss, onDeleteRequest);
            this._structureRefControls.push(control);
            if (takeFocus) {
                onStructureRefFocusGain(control);
            }
            return control;
        }
        _addStructureRef(pane, structureId) {
            if (this._template === undefined) {
                throw new Error("No template selected");
            }
            const newRef = new MockPrefabTemplateStructureRef(guid(), structureId);
            this._template?.addStructureRef(newRef);
            this._constructStructureRefControl(pane, newRef, true);
        }
        _setupTemplateEditingEnvironment() {
            if (this.currentSelectedTemplate === undefined) {
                throw new Error("No template selected");
            }
            this._template = this._templateDB.templates[0];
            if (!this._template) {
                throw new Error(`Template with ID ${this.currentSelectedTemplate.name} (${this.currentSelectedTemplate.displayName}) not found`);
            }
            const pane = this._createTemplateEditorPane();
            const newCursorProperties = this.session.extensionContext.cursor.getProperties();
            newCursorProperties.visible = false;
            this.session.extensionContext.cursor.pushPropertiesById(newCursorProperties, PrefabTemplateEditorBehavior.CURSOR_STATE_ID);
            this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableTerrainRendering, true);
            this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableEntityRendering, false);
            this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableWeatherRendering, true);
            this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableParticleRendering, true);
            this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableBlockEntityRendering, true);
            requestWeatherChange(`PrefabTemplateEditor-${this.session.extensionContext.player.id}`, server_namespaceObject.WeatherType.Clear);
            requestTimeOfDayChange(`PrefabTemplateEditor-${this.session.extensionContext.player.id}`, server_namespaceObject.TimeOfDay.Sunrise);
            const oldPlayerLocation = this.session.extensionContext.player.location;
            const oldPlayerRotation = this.session.extensionContext.player.getRotation();
            this.session.extensionContext.player.teleport({
                x: 0,
                y: 5,
                z: 24
            }, {
                rotation: {
                    x: 10,
                    y: 180
                },
                checkForBlocks: false,
                keepVelocity: false
            });
            const gridWidget = this._widgetGroup.createWidget({
                x: 0,
                y: 0,
                z: 0
            }, {
                selectable: false,
                visible: true
            });
            gridWidget.addGridComponent("grid", {
                color: {
                    red: .5,
                    green: .5,
                    blue: 0,
                    alpha: .5
                },
                offset: {
                    x: -8,
                    y: 0,
                    z: -8
                },
                gridSize: {
                    x: 1,
                    y: 1
                },
                gridCount: {
                    x: 17,
                    y: 17
                }
            });
            gridWidget.addEntityComponent("root-node", "editor:ruler_idle", {
                isClickable: false,
                visible: true,
                offset: {
                    x: .5,
                    y: 0,
                    z: .5
                }
            });
            pane.addButton((() => {
                this._structurePicker.activate().then((() => {
                    if (this._structurePicker.selectedStructureId !== undefined) {
                        this._addStructureRef(pane, this._structurePicker.selectedStructureId);
                    }
                })).catch((_error => {}));
            }), {
                title: "editor.prefabTemplateEditor.tool.addStructure"
            });
            pane.addButton((() => {
                if (this.currentSelectedTemplate !== undefined) {
                    this._templateDB.saveTemplate(this._session, this.currentSelectedTemplate, this.prefabManager);
                    this.session.log.info("Layout template changes saved", {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                } else {
                    this.session.log.error("No template selected - cannot save changes", {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
            }), {
                title: "editor.prefabTemplateEditor.tool.button.save"
            });
            const structuresToRemove = [];
            this._template.structureRefs.forEach((structureRef => {
                try {
                    this._constructStructureRefControl(pane, structureRef, false);
                } catch (_e) {
                    this.session.log.warning(`Structure reference with ID ${structureRef.id} not found in the structure DB. Removing it from the template.`);
                    structuresToRemove.push(structureRef.id);
                }
            }));
            structuresToRemove.forEach((structureId => {
                this._template?.removeStructureRef(structureId);
            }));
            this._onToolFocusLoss = () => {
                restoreWeatherChange(`PrefabTemplateEditor-${this.session.extensionContext.player.id}`);
                restoreTimeOfDayChange(`PrefabTemplateEditor-${this.session.extensionContext.player.id}`);
                this._structureRefControls.forEach((control => control.dispose()));
                this._structureRefControls = [];
                this._widgetGroup.deleteWidget(gridWidget);
                this.session.extensionContext.player.teleport(oldPlayerLocation, {
                    rotation: oldPlayerRotation,
                    checkForBlocks: false,
                    keepVelocity: false
                });
                this.session.extensionContext.cursor.popPropertiesById(PrefabTemplateEditorBehavior.CURSOR_STATE_ID);
                this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableTerrainRendering, false);
                this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableEntityRendering, false);
                this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableWeatherRendering, false);
                this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableParticleRendering, false);
                this.session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.DisableBlockEntityRendering, false);
            };
            return pane;
        }
        _createTemplateEditorPane() {
            if (this._template === undefined) {
                throw new Error("No template selected");
            }
            const pane = this._rootPropertyPane.createSubPane({
                hasExpander: false,
                title: "editor.prefabTemplateEditor.pane.prefabTemplate.title",
                hasMargins: false
            });
            pane.addText(`Editing Template: ${this._template?.name ?? "Unknown"}`, {
                alignment: server_editor_namespaceObject.LayoutAlignment.Center,
                border: true
            });
            return pane;
        }
        _createEmptyTemplateEditorPane() {
            const pane = this._rootPropertyPane.createSubPane({
                hasExpander: false,
                title: "editor.prefabTemplateEditor.pane.prefabInstance.title"
            });
            pane.addText("No Layout Template or Instance Selected", {
                alignment: server_editor_namespaceObject.LayoutAlignment.Center,
                border: true
            });
            pane.addButton((() => {
                this._parent.showTemplateManager();
            }), {
                title: "Open Template Manager"
            });
            return pane;
        }
        _createRootPropertyPane() {
            const rootPropertyPane = this.session.createPropertyPane({
                uniqueId: "editor:pane:prefabTemplateEditor",
                title: "editor.prefabTemplateEditor.pane.root.title"
            });
            this._tool.bindPropertyPane(rootPropertyPane);
            return rootPropertyPane;
        }
    }
    PrefabTemplateEditorBehavior.CURSOR_STATE_ID = "editor:prefabTemplateEditor";
    const _rotationOrder = [ server_namespaceObject.StructureRotation.None, server_namespaceObject.StructureRotation.Rotate90, server_namespaceObject.StructureRotation.Rotate180, server_namespaceObject.StructureRotation.Rotate270 ];
    function _getRotationFromOrderedIndex(index) {
        return _rotationOrder[index];
    }
    function _getOrderedIndexFromRotation(rotation) {
        return _rotationOrder.indexOf(rotation);
    }
    const _mirrorOrder = [ server_namespaceObject.StructureMirrorAxis.None, server_namespaceObject.StructureMirrorAxis.X, server_namespaceObject.StructureMirrorAxis.Z, server_namespaceObject.StructureMirrorAxis.XZ ];
    function _getMirrorFromOrderedIndex(index) {
        return _mirrorOrder[index];
    }
    function _getOrderedIndexFromMirror(mirror) {
        return _mirrorOrder.indexOf(mirror);
    }
    class ModalTemplatePicker {
        get selectedTemplate() {
            return this._selectedTemplateMetadata;
        }
        get selectedTemplateDisplayName() {
            return this._selectedTemplateMetadata?.displayName;
        }
        constructor(session, parentPane, prefabBehavior) {
            this._selectedTemplateIndex = (0, server_editor_namespaceObject.makeObservable)(-1);
            this._templateList = [];
            this._templateComboBoxSelectedId = (0, server_editor_namespaceObject.makeObservable)("");
            this._session = session;
            this._parentPane = parentPane;
            this._prefabBehavior = prefabBehavior;
            this._pane = this._parentPane.createModalOverlayPane({
                title: "editor.prefabInstanceEditor.templatePicker.window.title"
            });
            this._selectedTemplateMetadata = undefined;
            this._selectedTemplateIndex.set(-1);
            this._pane.contentPane.addText("editor.prefabInstanceEditor.templatePicker.window.hint", {
                alignment: server_editor_namespaceObject.LayoutAlignment.Center
            });
            this._templateDropdown = this._pane.contentPane.addDropdown(this._selectedTemplateIndex, {
                entries: [],
                title: "editor.prefabInstanceEditor.templatePicker.dropdown.title",
                onChange: _index => {
                    this._selectedTemplateMetadata = this._templateList[_index];
                }
            });
            this._updateTemplateList();
            this._pane.contentPane.addDivider();
            this._pane.contentPane.addButton((() => {
                this._pane.hide();
                this._parentPane.setActiveModalOverlay("");
                this._resolve?.();
                this._reject = undefined;
                this._resolve = undefined;
            }), {
                title: "editor.prefabTemplateEditor.structurePicker.picker.select",
                variant: server_editor_namespaceObject.ButtonVariant.Primary
            });
            this._pane.contentPane.addButton((() => {
                this._pane.hide();
                this._parentPane.setActiveModalOverlay("");
                this._reject?.(new Error("Cancelled"));
                this._reject = undefined;
                this._resolve = undefined;
            }), {
                title: "editor.prefabTemplateEditor.structurePicker.picker.cancel"
            });
            this._parentPane.onPropertyPaneVisibilityUpdated.subscribe((eventData => {
                if (this._resolve !== undefined || this._reject !== undefined) {
                    if (eventData.isVisible) {
                        throw new Error("Something went wrong - dialog is being activated while promises are still pending");
                    } else {
                        if (this._resolve !== undefined || this._reject !== undefined) {
                            this._reject?.(new Error("Parent pane closed while dialog was active"));
                            this._reject = undefined;
                            this._resolve = undefined;
                        }
                        this._pane.hide();
                        this._parentPane.setActiveModalOverlay("");
                    }
                }
            }));
        }
        _updateTemplateList() {
            this._templateList = this._prefabBehavior.prefabManager.getTemplateList();
            const entries = this._templateList.map(((template, index) => {
                const item = {
                    label: `${template.displayName} (${template.name})`,
                    value: index
                };
                return item;
            }));
            if (entries.length > 0) {
                this._selectedTemplateMetadata = this._templateList[0];
                this._selectedTemplateIndex.set(0);
            }
            this._templateDropdown.updateEntries(entries);
        }
        async activate() {
            if (this._parentPane.getActiveModalOverlayId() !== undefined) {
                this._pane.hide();
                throw new Error("Another modal overlay is already active");
            }
            this._updateTemplateList();
            this._parentPane.setActiveModalOverlay(this._pane.id);
            this._pane.show();
            return new Promise(((resolve, reject) => {
                this._resolve = resolve;
                this._reject = reject;
            }));
        }
    }
    var PrefabInstanceEditorState;
    (function(PrefabInstanceEditorState) {
        PrefabInstanceEditorState[PrefabInstanceEditorState["Invalid"] = -1] = "Invalid";
        PrefabInstanceEditorState[PrefabInstanceEditorState["Picker"] = 0] = "Picker";
        PrefabInstanceEditorState[PrefabInstanceEditorState["Placer"] = 1] = "Placer";
    })(PrefabInstanceEditorState || (PrefabInstanceEditorState = {}));
    class IStateImpl {
        get session() {
            return this._session;
        }
        get parentPane() {
            return this._parentPane;
        }
        get behavior() {
            return this._behavior;
        }
        get instanceBehavior() {
            return this._instanceBehavior;
        }
        constructor(_session, _parentPane, behavior, instanceBehavior) {
            this._session = _session;
            this._parentPane = _parentPane;
            this._behavior = behavior;
            this._instanceBehavior = instanceBehavior;
        }
    }
    class PlacerState extends IStateImpl {
        get currentSelectedTemplate() {
            return this._selectedTemplateMetadata;
        }
        set currentSelectedTemplate(value) {
            this._selectedTemplateMetadata = value;
        }
        get pane() {
            if (this._pane === undefined) {
                throw new Error("Pane not initialized");
            }
            return this._pane;
        }
        constructor(_session, _parentPane, behavior, instanceBehavior) {
            super(_session, _parentPane, behavior, instanceBehavior);
            this.uniqueId = "editor:state:prefabInstanceEditor:placer";
            this._onInstanceInteractionEvent = _event => {
                switch (_event.eventType) {
                  case server_editor_private_bindings_namespaceObject.PrefabInstanceInteractionEventType.Moved:
                    {
                        const newLocation = _event.eventData.location;
                        this.session.log.info(`Layout instance moved to ${lib.Vector3Utils.toString(newLocation)}`, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        break;
                    }
                }
            };
            this._templatePicker = new ModalTemplatePicker(this._session, _parentPane, behavior);
            this._selectedTemplateMetadata = undefined;
            this._widgetGroup = this.session.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.Single,
                visible: true
            });
        }
        teardown() {
            this._widgetGroup.delete();
        }
        initialize() {
            this._pane = this.parentPane.createSubPane({
                uniqueId: this.uniqueId,
                title: "editor.prefabInstanceEditor.infoPanel.placer.title",
                hasExpander: true
            });
            this._pane.addButton((() => {
                this._templatePicker.activate().then((() => {
                    if (this._templatePicker.selectedTemplate !== undefined) {
                        this._session.log.info(`Selected template: ${this._templatePicker.selectedTemplate.displayName}`, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        this.currentSelectedTemplate = this._templatePicker.selectedTemplate;
                        this._constructPrefabInstanceWidgets();
                    }
                })).catch((_error => {}));
            }), {
                title: "editor.prefabInstanceEditor.templatePicker.button.choose"
            });
            return this._pane;
        }
        activate() {
            this.behavior.prefabManager.clearSelectedInstances();
            this._constructPrefabInstanceWidgets();
            this.behavior.prefabManager.instanceInteractionEvents.subscribe(this._onInstanceInteractionEvent);
            this._widgetGroup.visible = true;
        }
        deactivate() {
            this._widgetGroup.visible = false;
            this.behavior.prefabManager.instanceInteractionEvents.unsubscribe(this._onInstanceInteractionEvent);
            if (this._previewWidget !== undefined) {
                this._previewWidget.delete();
                this._previewWidget = undefined;
            }
        }
        _constructPrefabInstanceWidgets() {
            if (this._previewWidget !== undefined) {
                this._previewWidget.delete();
                this._previewWidget = undefined;
            }
            if (this.currentSelectedTemplate === undefined) {
                return;
            }
            this._previewWidget = this._widgetGroup.createWidget({
                x: 0,
                y: 0,
                z: 0
            }, {
                collisionType: server_editor_namespaceObject.WidgetCollisionType.None,
                visible: true,
                bindPositionToBlockCursor: true
            });
            try {
                const prefabTemplate = this.behavior.prefabManager.getTemplate(this.currentSelectedTemplate);
                const prefabStructures = prefabTemplate.getTemplateStructures();
                let index = 0;
                for (const structure of prefabStructures) {
                    const _mirror = structure.instanceMirror;
                    const _rotation = structure.instanceRotation;
                    const instanceOffset = structure.instanceOffset;
                    const normalizedOrigin = structure.structureNormalizedOrigin;
                    const editorStructure = structure.getStructure();
                    const structureOffset = editorStructure.offset;
                    const _clipboardComponent = this._previewWidget.addClipboardComponent(`${index}:${editorStructure.displayName}`, editorStructure, {
                        offset: instanceOffset,
                        clipboardOffset: structureOffset,
                        normalizedOrigin,
                        showOutline: false,
                        highlightHullColor: {
                            red: 1,
                            green: 1,
                            blue: 1,
                            alpha: 0
                        },
                        highlightOutlineColor: {
                            red: 1,
                            green: 1,
                            blue: 1,
                            alpha: 0
                        }
                    });
                    ++index;
                }
            } catch (e) {
                const err = e;
                this._session.log.error(`Failed to load layout template: ${err.message}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                this._previewWidget.delete();
                this._previewWidget = undefined;
                return;
            }
        }
        onMouseClick(_mouseRay, _mouseProps) {
            if (this.currentSelectedTemplate === undefined || this._previewWidget === undefined) {
                return;
            }
            if (_mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown) {
                if (_mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton) {
                    const blockLocation = this.session.extensionContext.cursor.getPosition();
                    this._placeInstanceAtLocation(blockLocation);
                }
            }
        }
        _placeInstanceAtLocation(_location) {
            if (this.currentSelectedTemplate === undefined || this._previewWidget === undefined) {
                return;
            }
            try {
                const prefabTemplate = this.behavior.prefabManager.getTemplate(this.currentSelectedTemplate);
                prefabTemplate.createInstance(_location, {
                    rotation: server_namespaceObject.StructureRotation.None,
                    mirror: server_namespaceObject.StructureMirrorAxis.None
                });
            } catch (e) {
                const err = e;
                this._session.log.error(`Failed to load layout template for placement: ${err.message}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
        }
        deleteInstance() {}
        deselectInstance() {}
    }
    class PickerStateInstanceStructureRefUI {
        constructor(_structureRef, _parentPane) {
            this._rotationIndex = (0, server_editor_namespaceObject.makeObservable)(0);
            this._mirrorIndex = (0, server_editor_namespaceObject.makeObservable)(0);
            this._structureRef = _structureRef;
            this._parentPane = _parentPane;
            this._pane = this._parentPane.createSubPane({
                title: {
                    id: "editor.prefabInstanceEditor.instanceSubPane.title",
                    props: [ this._structureRef.getTemplateStructure().getStructure().displayName ]
                },
                hasExpander: true,
                collapsed: false
            });
            this._rotationIndex.set(_getOrderedIndexFromRotation(this._structureRef.instanceRotation));
            this._mirrorIndex.set(_getOrderedIndexFromMirror(this._structureRef.instanceMirror));
            this._pane.addDropdown(this._rotationIndex, {
                title: "editor.prefabInstanceEditor.rotation.title",
                entries: [ {
                    value: 0,
                    label: "editor.prefabInstanceEditor.rotation.none"
                }, {
                    value: 1,
                    label: "editor.prefabInstanceEditor.rotation.90"
                }, {
                    value: 2,
                    label: "editor.prefabInstanceEditor.rotation.180"
                }, {
                    value: 3,
                    label: "editor.prefabInstanceEditor.rotation.270"
                } ],
                onChange: _index => {
                    this._structureRef.instanceRotation = _getRotationFromOrderedIndex(_index);
                }
            });
            this._pane.addDropdown(this._mirrorIndex, {
                title: "editor.prefabInstanceEditor.mirror.title",
                entries: [ {
                    value: 0,
                    label: "editor.prefabInstanceEditor.mirror.none"
                }, {
                    value: 1,
                    label: "editor.prefabInstanceEditor.mirror.x"
                }, {
                    value: 2,
                    label: "editor.prefabInstanceEditor.mirror.z"
                }, {
                    value: 3,
                    label: "editor.prefabInstanceEditor.mirror.xz"
                } ],
                onChange: _index => {
                    this._structureRef.instanceMirror = _getMirrorFromOrderedIndex(_index);
                }
            });
        }
    }
    class PickerState extends IStateImpl {
        get pane() {
            if (this._pane === undefined) {
                throw new Error("Pane not initialized");
            }
            return this._pane;
        }
        constructor(_session, _parentPane, behavior, instanceBehavior) {
            super(_session, _parentPane, behavior, instanceBehavior);
            this._structureRefUIs = [];
            this.uniqueId = "editor:state:prefabInstanceEditor:picker";
            this.propertyPaneUniqueId = "editor:state:prefabInstanceEditor:picker:selectedInstance";
            this._selectedInstanceProperty_CompositeName = (0, server_editor_namespaceObject.makeObservable)("");
            this._selectedInstanceProperty_Name = (0, server_editor_namespaceObject.makeObservable)("");
            this._selectedInstanceProperty_DisplayName = (0, server_editor_namespaceObject.makeObservable)("");
            this._selectedInstanceProperty_Description = (0, server_editor_namespaceObject.makeObservable)("");
            this._selectedInstanceProperty_Notes = (0, server_editor_namespaceObject.makeObservable)("");
            this._selectedInstanceProperty_Location = (0, server_editor_namespaceObject.makeObservable)({
                x: 0,
                y: 0,
                z: 0
            });
            this._selectedInstanceProperty_RotationIndex = (0, server_editor_namespaceObject.makeObservable)(0);
            this._selectedInstanceProperty_MirrorIndex = (0, server_editor_namespaceObject.makeObservable)(0);
            this._onInstanceInteractionEvent = _event => {
                if (this._selectedInstance === undefined || _event.eventType === server_editor_private_bindings_namespaceObject.PrefabInstanceInteractionEventType.Clicked) {
                    this.behavior.prefabManager.selectInstance(_event.instance, false);
                    this._selectedInstance = _event.instance;
                    this._populateSelectedInstanceUI();
                    this._selectedPropertyPane?.show();
                }
                if (_event.eventType === server_editor_private_bindings_namespaceObject.PrefabInstanceInteractionEventType.Moved) {
                    this._selectedInstanceProperty_Location.set(this._selectedInstance.location);
                }
            };
            this._selectedInstance = undefined;
        }
        teardown() {}
        initialize() {
            this._pane = this.parentPane.createSubPane({
                uniqueId: this.uniqueId,
                title: "editor.prefabInstanceEditor.infoPanel.picker.title",
                hasExpander: true
            });
            const offsetNudgeUpAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._nudgeOffset(lib.VECTOR3_UP);
                }
            });
            const offsetNudgeDownAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._nudgeOffset(lib.VECTOR3_DOWN);
                }
            });
            const offsetNudgeForwardAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Forward);
                    this._nudgeOffset(nudgeVector);
                }
            });
            const offsetNudgeBackAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Back);
                    this._nudgeOffset(nudgeVector);
                }
            });
            const offsetNudgeLeftAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Left);
                    this._nudgeOffset(nudgeVector);
                }
            });
            const offsetNudgeRightAction = this.session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    const nudgeVector = this._getRelativeNudgeDirection(direction_Direction.Right);
                    this._nudgeOffset(nudgeVector);
                }
            });
            this.instanceBehavior.registerToolKeyBinding(offsetNudgeUpAction, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_UP,
                modifier: server_editor_namespaceObject.InputModifier.None
            }, "nudgeOffsetUp");
            this.instanceBehavior.registerToolKeyBinding(offsetNudgeDownAction, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_DOWN,
                modifier: server_editor_namespaceObject.InputModifier.None
            }, "nudgeOffsetDown");
            this.instanceBehavior.registerToolKeyBinding(offsetNudgeForwardAction, {
                key: server_editor_namespaceObject.KeyboardKey.UP,
                modifier: server_editor_namespaceObject.InputModifier.None
            }, "nudgeOffsetForward");
            this.instanceBehavior.registerToolKeyBinding(offsetNudgeBackAction, {
                key: server_editor_namespaceObject.KeyboardKey.DOWN,
                modifier: server_editor_namespaceObject.InputModifier.None
            }, "nudgeOffsetBack");
            this.instanceBehavior.registerToolKeyBinding(offsetNudgeLeftAction, {
                key: server_editor_namespaceObject.KeyboardKey.LEFT,
                modifier: server_editor_namespaceObject.InputModifier.None
            }, "nudgeOffsetLeft");
            this.instanceBehavior.registerToolKeyBinding(offsetNudgeRightAction, {
                key: server_editor_namespaceObject.KeyboardKey.RIGHT,
                modifier: server_editor_namespaceObject.InputModifier.None
            }, "nudgeOffsetRight");
            this._selectedPropertyPane = this._pane.createSubPane({
                hasExpander: false,
                uniqueId: this.propertyPaneUniqueId
            });
            this._selectedPropertyPane.addText(this._selectedInstanceProperty_CompositeName);
            this._selectedPropertyPane.addDivider();
            this._selectedPropertyPane.addVector3(this._selectedInstanceProperty_Location, {
                title: "editor.prefabInstanceEditor.templatePicker.properties.location",
                isInteger: true,
                onChange: _value => {
                    if (this._selectedInstance === undefined) {
                        return;
                    }
                    this._selectedInstance.location = _value;
                }
            });
            this._selectedPropertyPane.addButton((() => {
                if (this._selectedInstance !== undefined) {
                    this._selectedInstance.bakeInstance();
                    this.session.log.info("Baking complete", {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                }
            }), {
                title: "editor.prefabInstanceEditor.placer.bake.button.title",
                variant: server_editor_namespaceObject.ButtonVariant.Primary
            });
            if (this._selectedInstance !== undefined) {
                this._selectedInstanceProperty_RotationIndex.set(_getOrderedIndexFromRotation(this._selectedInstance.instanceRotation));
                this._selectedInstanceProperty_MirrorIndex.set(_getOrderedIndexFromMirror(this._selectedInstance.instanceMirror));
            }
            this._selectedPropertyPane.addDropdown(this._selectedInstanceProperty_RotationIndex, {
                title: "editor.prefabInstanceEditor.rotation.title",
                entries: [ {
                    value: 0,
                    label: "editor.prefabInstanceEditor.rotation.none"
                }, {
                    value: 1,
                    label: "editor.prefabInstanceEditor.rotation.90"
                }, {
                    value: 2,
                    label: "editor.prefabInstanceEditor.rotation.180"
                }, {
                    value: 3,
                    label: "editor.prefabInstanceEditor.rotation.270"
                } ],
                onChange: _index => {
                    if (this._selectedInstance !== undefined) {
                        this._selectedInstance.instanceRotation = _getRotationFromOrderedIndex(_index);
                    }
                }
            });
            this._selectedPropertyPane.addDropdown(this._selectedInstanceProperty_MirrorIndex, {
                title: "editor.prefabInstanceEditor.mirror.title",
                entries: [ {
                    value: 0,
                    label: "editor.prefabInstanceEditor.mirror.none"
                }, {
                    value: 1,
                    label: "editor.prefabInstanceEditor.mirror.x"
                }, {
                    value: 2,
                    label: "editor.prefabInstanceEditor.mirror.z"
                }, {
                    value: 3,
                    label: "editor.prefabInstanceEditor.mirror.xz"
                } ],
                onChange: _index => {
                    if (this._selectedInstance !== undefined) {
                        this._selectedInstance.instanceMirror = _getMirrorFromOrderedIndex(_index);
                    }
                }
            });
            const infoPane = this._selectedPropertyPane.createSubPane({
                hasExpander: true,
                collapsed: true,
                title: "editor.prefabInstanceEditor.templatePicker.properties.title"
            });
            infoPane.addString(this._selectedInstanceProperty_DisplayName, {
                title: "editor.prefabInstanceEditor.templatePicker.properties.displayName",
                enable: false
            });
            infoPane.addString(this._selectedInstanceProperty_Name, {
                title: "editor.prefabInstanceEditor.templatePicker.properties.name",
                enable: false
            });
            infoPane.addString(this._selectedInstanceProperty_Description, {
                title: "editor.prefabInstanceEditor.templatePicker.properties.description",
                enable: false
            });
            infoPane.addString(this._selectedInstanceProperty_Notes, {
                title: "editor.prefabInstanceEditor.templatePicker.properties.notes",
                enable: false
            });
            this._selectedPropertyPane.hide();
            return this._pane;
        }
        _rebuildSelectedStructurePanes() {
            if (this._selectedPropertyPane === undefined) {
                return;
            }
            if (this._selectedStructurePaneContainer !== undefined) {
                this._selectedPropertyPane.beginConstruct();
                this._selectedPropertyPane.removeSubPane(this._selectedStructurePaneContainer);
                this._selectedPropertyPane.endConstruct();
                this._selectedStructurePaneContainer = undefined;
            }
            this._selectedStructurePaneContainer = this._selectedPropertyPane.createSubPane({
                title: "editor.prefabInstanceEditor.placer.structures.title",
                hasExpander: true,
                collapsed: false
            });
            const structureRefs = this._selectedInstance?.getStructureRefs() ?? [];
            this._selectedStructurePaneContainer.beginConstruct();
            for (const structureRef of structureRefs) {
                const ui = new PickerStateInstanceStructureRefUI(structureRef, this._selectedStructurePaneContainer);
                this._structureRefUIs.push(ui);
            }
            this._selectedStructurePaneContainer.endConstruct();
            this._selectedStructurePaneContainer.show();
        }
        _populateSelectedInstanceUI() {
            if (this._selectedInstance !== undefined) {
                const prefabTemplate = this._selectedInstance.getTemplate();
                const name = prefabTemplate.name.trim();
                const displayName = prefabTemplate.displayName.trim();
                const displayNameString = displayName === "" ? name : `${displayName} (${name})`;
                this._selectedInstanceProperty_CompositeName.set(displayNameString);
                this._selectedInstanceProperty_Location.set(this._selectedInstance.location);
                this._selectedInstanceProperty_Name.set(name);
                this._selectedInstanceProperty_DisplayName.set(displayName);
                this._selectedInstanceProperty_Description.set(prefabTemplate.description);
                this._selectedInstanceProperty_Notes.set(prefabTemplate.notes);
                this._selectedInstanceProperty_RotationIndex.set(_getOrderedIndexFromRotation(this._selectedInstance.instanceRotation));
                this._selectedInstanceProperty_MirrorIndex.set(_getOrderedIndexFromMirror(this._selectedInstance.instanceMirror));
                this._rebuildSelectedStructurePanes();
            }
        }
        activate() {
            this.behavior.prefabManager.clearSelectedInstances();
            this.behavior.prefabManager.beginCapturingMouseClicks();
            this.behavior.prefabManager.instanceInteractionEvents.subscribe(this._onInstanceInteractionEvent);
            for (const tag of [ "nudgeOffsetUp", "nudgeOffsetDown", "nudgeOffsetForward", "nudgeOffsetBack", "nudgeOffsetLeft", "nudgeOffsetRight" ]) {
                this.instanceBehavior.enableToolKeyBinding(tag);
            }
        }
        deactivate() {
            this.behavior.prefabManager.instanceInteractionEvents.unsubscribe(this._onInstanceInteractionEvent);
            this.behavior.prefabManager.endCapturingMouseClicks();
            this.behavior.prefabManager.clearSelectedInstances();
            for (const tag of [ "nudgeOffsetUp", "nudgeOffsetDown", "nudgeOffsetForward", "nudgeOffsetBack", "nudgeOffsetLeft", "nudgeOffsetRight" ]) {
                this.instanceBehavior.disableToolKeyBinding(tag);
            }
        }
        onMouseClick(_mouseRay, _mouseProps) {}
        deleteInstance() {
            if (this._selectedInstance !== undefined) {
                this._selectedPropertyPane?.hide();
                this.behavior.prefabManager.deleteInstance(this._selectedInstance);
                this._selectedInstance = undefined;
            }
        }
        deselectInstance() {
            this._selectedPropertyPane?.hide();
            this.behavior.prefabManager.clearSelectedInstances();
            this._selectedInstance = undefined;
        }
        _getRelativeNudgeDirection(direction) {
            const rotationY = this.session.extensionContext.player.getRotation().y;
            const rotationCorrectedVector = getRotationCorrectedDirectionVector(rotationY, direction);
            return rotationCorrectedVector;
        }
        _nudgeOffset(_nudgeVector) {
            if (!this._selectedInstance) {
                return;
            }
            const location = this._selectedInstance.location;
            const newLocation = lib.Vector3Utils.add(location, _nudgeVector);
            this._selectedInstance.location = newLocation;
        }
    }
    class PrefabInstanceEditorBehavior {
        get prefabManager() {
            return this._parent.prefabManager;
        }
        get session() {
            return this._session;
        }
        get stateData() {
            switch (this._activeState) {
              case PrefabInstanceEditorState.Picker:
                return this._stateDataPicker;

              case PrefabInstanceEditorState.Placer:
                return this._stateDataPlacer;

              default:
                throw new Error("Invalid state type");
            }
        }
        get activeState() {
            return this._activeState;
        }
        constructor(uiSession, parent) {
            this.uiSession = uiSession;
            this._onToolFocusGain = () => {};
            this._onToolFocusLoss = () => {};
            this._activeState = PrefabInstanceEditorState.Picker;
            this._stateTypeToggle = (0, server_editor_namespaceObject.makeObservable)(PrefabInstanceEditorState.Placer);
            this._registeredKeyBindings = new Map;
            this._session = uiSession;
            this._parent = parent;
            this._tool = this._addTool();
            this._rootPropertyPane = this._createRootPropertyPane();
            this._setupEditingEnvironment();
            this._stateTypeToggle.set(PrefabInstanceEditorState.Picker);
            this._activeState = PrefabInstanceEditorState.Picker;
            this._stateDataPicker = new PickerState(this.session, this._rootPropertyPane, this._parent, this);
            this._pickerPane = this._stateDataPicker.initialize();
            this._stateDataPlacer = new PlacerState(this.session, this._rootPropertyPane, this._parent, this);
            this._placerPane = this._stateDataPlacer.initialize();
            this.registerToolKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.stateData.deselectInstance();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.KEY_D,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, "deselectAll");
            this.registerToolKeyBinding(this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this.stateData.deleteInstance();
                }
            }), {
                key: server_editor_namespaceObject.KeyboardKey.DELETE,
                modifier: server_editor_namespaceObject.InputModifier.None
            }, "deleteInstance");
            this._activeState = PrefabInstanceEditorState.Invalid;
        }
        teardown() {}
        _activateState(state, force = false) {
            if (this._activeState === state && !force) {
                return;
            }
            this.stateData.deactivate();
            this._activeState = state;
            this.stateData.activate();
            this._rootPropertyPane.toggleSubPaneVisibility(this.stateData.uniqueId);
        }
        _addTool() {
            const tool = this.session.toolRail.addTool(PrefabInstanceEditorBehavior.MODAL_TOOL_ID, {
                title: "editor.prefabInstanceEditor.templatePicker.tool.rootPane",
                icon: "blocksIcon",
                tooltip: "editor.prefabTemplateEditor.tool.tooltip"
            });
            tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    if (this._onToolFocusGain) {
                        this._onToolFocusGain();
                    }
                } else {
                    if (this._onToolFocusLoss) {
                        this._onToolFocusLoss();
                    }
                }
            }));
            const singleClickAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    this._onMouseClick(mouseRay, mouseProps);
                }
            });
            tool.registerMouseButtonBinding(singleClickAction);
            return tool;
        }
        _createRootPropertyPane() {
            const rootPropertyPane = this.session.createPropertyPane({
                uniqueId: "editor:pane:prefabInstanceEditor",
                title: "editor.prefabInstanceEditor.templatePicker.tool.rootPane"
            });
            this._tool.bindPropertyPane(rootPropertyPane);
            rootPropertyPane.addToggleGroup(this._stateTypeToggle, {
                title: "editor.prefabInstanceEditor.quickAction.title",
                tooltip: "editor.prefabInstanceEditor.quickAction.tooltip",
                hiddenLabel: false,
                entries: [ {
                    value: PrefabInstanceEditorState.Picker,
                    label: {
                        id: "editor.prefabInstanceEditor.state.picker"
                    },
                    icon: "objectSelectIcon",
                    tooltip: "editor.prefabInstanceEditor.infoPanel.picker.tooltip"
                }, {
                    value: PrefabInstanceEditorState.Placer,
                    label: {
                        id: "editor.prefabInstanceEditor.state.placer"
                    },
                    icon: "editIcon",
                    tooltip: "editor.prefabInstanceEditor.templatePicker.tool.quickAction.placeMode.tooltip"
                } ],
                onChange: _newValue => {
                    switch (_newValue) {
                      case PrefabInstanceEditorState.Picker:
                        {
                            this._activateState(PrefabInstanceEditorState.Picker);
                            break;
                        }

                      case PrefabInstanceEditorState.Placer:
                        {
                            this._activateState(PrefabInstanceEditorState.Placer);
                            break;
                        }
                    }
                }
            });
            return rootPropertyPane;
        }
        _setupEditingEnvironment() {
            const _setupCursor = () => {
                const newCursorProperties = this.session.extensionContext.cursor.getDefaultProperties();
                newCursorProperties.visible = true;
                newCursorProperties.targetMode = server_editor_namespaceObject.CursorTargetMode.Face;
                newCursorProperties.outlineColor = {
                    red: 0,
                    green: 1,
                    blue: 0,
                    alpha: 1
                };
                this.session.extensionContext.cursor.pushPropertiesById(newCursorProperties, PrefabInstanceEditorBehavior.MODAL_TOOL_ID);
            };
            const _restoreCursor = () => {
                this.session.extensionContext.cursor.popPropertiesById(PrefabInstanceEditorBehavior.MODAL_TOOL_ID);
            };
            _setupCursor();
            this._onToolFocusGain = () => {
                if (this._activeState === PrefabInstanceEditorState.Invalid) {
                    this._activeState = PrefabInstanceEditorState.Picker;
                }
                _setupCursor();
                this._activateState(this.activeState, true);
            };
            this._onToolFocusLoss = () => {
                this.stateData.deactivate();
                _restoreCursor();
            };
        }
        _onMouseClick(_mouseRay, _mouseProps) {
            this.stateData.onMouseClick(_mouseRay, _mouseProps);
        }
        registerToolKeyBinding(action, binding, tag) {
            const registeredBinding = this._tool.registerKeyBinding(action, binding, {
                uniqueId: `editor:prefabInstanceEditor:${tag}`,
                label: `editor.toolRail.prefabInstanceEditor.keyBinding.${tag}.title`,
                tooltip: `editor.toolRail.prefabInstanceEditor.keyBinding.${tag}.tooltip`
            });
            this._registeredKeyBindings.set(tag, registeredBinding);
        }
        enableToolKeyBinding(tag) {
            const registeredBinding = this._registeredKeyBindings.get(tag);
            if (registeredBinding) {
                registeredBinding.setProcessingState(undefined);
            }
        }
        disableToolKeyBinding(tag) {
            const registeredBinding = this._registeredKeyBindings.get(tag);
            if (registeredBinding) {
                registeredBinding.setProcessingState(server_editor_namespaceObject.KeyProcessingState.Disabled);
            }
        }
    }
    PrefabInstanceEditorBehavior.MODAL_TOOL_ID = "editor:tool:prefabInstanceEditor";
    class PrefabBehavior {
        get prefabManager() {
            return this._prefabManager;
        }
        get currentSelectedTemplate() {
            return this._currentSelectedTemplate;
        }
        set currentSelectedTemplate(value) {
            this._currentSelectedTemplate = value;
        }
        showTemplateManager() {
            this._templateManager?.showManagerWindow();
        }
        constructor(uiSession) {
            this.uiSession = uiSession;
            this._templateDB = new MockPrefabDB;
            this._session = uiSession;
            this._prefabManager = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(uiSession.extensionContext.player).prefabManager;
            this._templateManager = new PrefabTemplateManagerBehavior(this.uiSession, this);
            this._templateEditor = new PrefabTemplateEditorBehavior(this.uiSession, this);
            this._instanceEditor = new PrefabInstanceEditorBehavior(this.uiSession, this);
        }
        get session() {
            return this._session;
        }
        get templateManager() {
            return this._templateManager;
        }
        get templateEditor() {
            return this._templateEditor;
        }
        teardown() {
            this._templateManager?.teardown();
            this._templateManager = undefined;
            this._templateEditor?.teardown();
            this._templateEditor = undefined;
            this._instanceEditor?.teardown();
            this._instanceEditor = undefined;
        }
    }
    var ChunkOperationMode;
    (function(ChunkOperationMode) {
        ChunkOperationMode[ChunkOperationMode["Regeneration"] = 0] = "Regeneration";
        ChunkOperationMode[ChunkOperationMode["Delete"] = 1] = "Delete";
    })(ChunkOperationMode || (ChunkOperationMode = {}));
    var ChunkRegenerationType;
    (function(ChunkRegenerationType) {
        ChunkRegenerationType[ChunkRegenerationType["List"] = 0] = "List";
        ChunkRegenerationType[ChunkRegenerationType["World"] = 1] = "World";
    })(ChunkRegenerationType || (ChunkRegenerationType = {}));
    var ChunkManagerTelemetry;
    (function(ChunkManagerTelemetry) {
        ChunkManagerTelemetry["Regenerate"] = "Regenerate";
        ChunkManagerTelemetry["Delete"] = "Delete";
    })(ChunkManagerTelemetry || (ChunkManagerTelemetry = {}));
    const CHUNK_SIZE = 16;
    const PROGRESS_TICK_INTERVAL = server_namespaceObject.TicksPerSecond / 4;
    class ChunkManagerBehavior {
        constructor(_uiSession) {
            this._uiSession = _uiSession;
            this._operationMode = (0, server_editor_namespaceObject.makeObservable)(ChunkOperationMode.Regeneration);
            this._regenerationPane = undefined;
            this._regenerationType = (0, server_editor_namespaceObject.makeObservable)(ChunkRegenerationType.List);
            this._listRegenerationExclusive = (0, server_editor_namespaceObject.makeObservable)(false);
            this._deletePane = undefined;
            this._progressModalText = (0, server_editor_namespaceObject.makeObservable)("");
            this._newBoundsMin = (0, server_editor_namespaceObject.makeObservable)({
                x: 0,
                y: 0,
                z: 0
            });
            this._newBoundsMax = (0, server_editor_namespaceObject.makeObservable)({
                x: 0,
                y: 0,
                z: 0
            });
            this._tickHandle = undefined;
            this._waitRegion = undefined;
            this._operationRegions = [];
            this._activeTelemetry = undefined;
            this.telemetryManager = new TelemetryManager(this._uiSession.extensionContext.player, TelemetrySource.ChunkManagement);
            this._regionManager = server_editor_private_bindings_namespaceObject.editorInternal.regionManager;
            this._playerRegionManager = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(this._uiSession.extensionContext.player).regionManager;
            this._widgetGroup = this._uiSession.extensionContext.widgetManager.createGroup({
                visible: true
            });
            this._progressModal = this._uiSession.dialogManager.registerDialog({
                canUserDismiss: false,
                uniqueId: "editor:dialog:chunkManagementProgress"
            });
            this._progressModal.contentPane.addText(this._progressModalText);
            this._progressModal.contentPane.addProgressIndicator({
                progress: server_editor_namespaceObject.ProgressIndicatorPropertyItemVariant.Spinner,
                hiddenLabel: true
            });
            this._pane = _uiSession.createPropertyPane({
                title: ChunkManagerBehavior.BEHAVIOR_NAME,
                uniqueId: "editor:pane:chunkManagement",
                infoTooltip: {
                    description: [ "resourcePack.editor.chunkManagement.tooltip", {
                        link: "https://aka.ms/BedrockEditorChunkManagement",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            const showPaneAction = this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._pane.show();
                }
            });
            this._uiSession.actionBar.registerItem("editor:actionBarItem:chunkManagement", showPaneAction, {
                label: "resourcePack.editor.chunkManagement.title",
                icon: "worldIcon",
                tooltipTitle: "resourcePack.editor.chunkManagement.title",
                tooltipDescription: "resourcePack.editor.chunkManagement.tooltip",
                enabled: true,
                executeOnAdd: true
            });
            this._pane.onPropertyPaneVisibilityUpdated.subscribe((payload => {
                this._widgetGroup.visible = payload.isVisible;
            }));
            this._modalOverlay = this._pane.createModalOverlayPane({
                title: "resourcePack.editor.chunkManagement.warningModal.title"
            });
            this._modalOverlay.contentPane.addText("resourcePack.editor.chunkManagement.warningModal.message", {
                border: false,
                alignment: server_editor_namespaceObject.LayoutAlignment.Center
            });
            this._modalOverlay.controlPane.addButton((() => {
                this._modalOverlay.hide();
                this._prepareOperation();
            }), {
                title: "resourcePack.editor.chunkManagement.warningModal.confirm",
                variant: server_editor_namespaceObject.ButtonVariant.Confirmation
            });
            this._modalOverlay.controlPane.addButton((() => {
                this._modalOverlay.hide();
            }), {
                title: "resourcePack.editor.chunkManagement.warningModal.cancel",
                variant: server_editor_namespaceObject.ButtonVariant.Destructive
            });
            this._buildUI();
            this._uiSession.eventSubscriptionCache.subscribeToBedrockEvent("playerDimensionChange", (event => {
                if (event.player.id === this._uiSession.extensionContext.player.id) {
                    this._widgetGroup.delete();
                    this._widgetGroup = this._uiSession.extensionContext.widgetManager.createGroup({
                        visible: true
                    });
                    this._boundsListPane.updateSlots([]);
                    this._updateUIState();
                }
            }));
        }
        teardown() {
            if (this.selectionChangeEventSubscriptionHandle) {
                this._uiSession.extensionContext.afterEvents.SelectionChange.unsubscribe(this.selectionChangeEventSubscriptionHandle);
                this.selectionChangeEventSubscriptionHandle = undefined;
            }
            if (this._tickHandle !== undefined) {
                server_namespaceObject.system.clearRun(this._tickHandle);
                this._tickHandle = undefined;
            }
            this._clearOperationRegions();
            if (this._waitRegion) {
                this._waitRegion.dispose();
                this._waitRegion = undefined;
            }
            this._activeTelemetry = undefined;
            this._executedOperation = undefined;
        }
        createMenuItem(menu) {
            const openMenuAction = this._uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._pane.show();
                }
            });
            this._menuItem = menu.addItem({
                label: ChunkManagerBehavior.BEHAVIOR_NAME
            }, openMenuAction);
        }
        _buildUI() {
            this._pane.addToggleGroup(this._operationMode, {
                title: "resourcePack.editor.chunkManagement.pane.operationMode.title",
                tooltip: "resourcePack.editor.chunkManagement.pane.operationMode.tooltip",
                hiddenEntryLabels: false,
                entries: [ {
                    value: ChunkOperationMode.Regeneration,
                    icon: "worldIcon",
                    label: "resourcePack.editor.chunkManagement.pane.chunkRegeneration.title",
                    tooltip: "resourcePack.editor.chunkManagement.pane.chunkRegeneration.tooltip"
                }, {
                    value: ChunkOperationMode.Delete,
                    icon: "trashCanIcon",
                    label: "resourcePack.editor.chunkManagement.pane.chunkDelete.title",
                    tooltip: "resourcePack.editor.chunkManagement.pane.chunkDelete.tooltip"
                } ],
                onChange: mode => {
                    if (mode === ChunkOperationMode.Regeneration) {
                        this._regenerationPane?.show();
                        this._deletePane?.hide();
                    } else if (mode === ChunkOperationMode.Delete) {
                        this._regenerationPane?.hide();
                        this._deletePane?.show();
                    }
                    this._updateUIState();
                }
            });
            this._buildOperationPane();
            this._pane.addDivider();
            this._buildRegionListPane();
            this._updateUIState();
            this.selectionChangeEventSubscriptionHandle = this._uiSession.extensionContext.afterEvents.SelectionChange.subscribe((() => {
                if (this._addBoundsFromSelectionButtonItem) {
                    this._addBoundsFromSelectionButtonItem.enable = !this._uiSession.extensionContext.selectionManager.volume.isEmpty;
                }
            }));
        }
        _buildOperationPane() {
            this._regenerationPane = this._pane.createSubPane({
                title: "resourcePack.editor.chunkManagement.pane.chunkRegeneration.title",
                hasExpander: false
            });
            this._regenerationPane.addDropdown(this._regenerationType, {
                title: "resourcePack.editor.chunkManagement.pane.chunkRegeneration.target.title",
                tooltip: "resourcePack.editor.chunkManagement.pane.chunkRegeneration.target.tooltip",
                entries: [ {
                    label: "resourcePack.editor.chunkManagement.pane.chunkRegeneration.target.list",
                    value: ChunkRegenerationType.List
                }, {
                    label: "resourcePack.editor.chunkManagement.pane.chunkRegeneration.target.world",
                    value: ChunkRegenerationType.World
                } ],
                onChange: () => {
                    this._updateUIState();
                }
            });
            this._listRegenerationExclusivePropItem = this._regenerationPane.addBool(this._listRegenerationExclusive, {
                title: "resourcePack.editor.chunkManagement.pane.chunkRegeneration.excludeList.title",
                tooltip: "resourcePack.editor.chunkManagement.pane.chunkRegeneration.excludeList.tooltip",
                visible: this._regenerationType.value === ChunkRegenerationType.World
            });
            this._regenerateButton = this._regenerationPane.addButton((() => this._showConfirmationModal()), {
                title: "resourcePack.editor.chunkManagement.pane.chunkRegeneration.action",
                variant: server_editor_namespaceObject.ButtonVariant.Confirmation
            });
            this._deletePane = this._pane.createSubPane({
                title: "resourcePack.editor.chunkManagement.pane.chunkDelete.title",
                hasExpander: false
            });
            this._deletePane.hide();
            this._deleteButton = this._deletePane.addButton((() => this._showConfirmationModal()), {
                title: "resourcePack.editor.chunkManagement.pane.chunkDelete.action",
                variant: server_editor_namespaceObject.ButtonVariant.Confirmation
            });
        }
        _buildRegionListPane() {
            this._regionPane = this._pane.createSubPane({
                title: "resourcePack.editor.chunkManagement.pane.regionList.title",
                infoTooltip: {
                    title: "resourcePack.editor.chunkManagement.pane.regionList.title",
                    description: [ "resourcePack.editor.chunkManagement.pane.regionList.tooltip" ]
                }
            });
            const newRegionPane = this._regionPane.createSubPane({
                title: "resourcePack.editor.chunkManagement.pane.regionList.newRegion.title",
                infoTooltip: {
                    title: "resourcePack.editor.chunkManagement.pane.regionList.newRegion.title",
                    description: [ "resourcePack.editor.chunkManagement.pane.regionList.newRegion.tooltip" ]
                }
            });
            newRegionPane.addVector3(this._newBoundsMin, {
                title: "resourcePack.editor.chunkManagement.pane.regionList.minBounds.title",
                tooltip: "resourcePack.editor.chunkManagement.pane.regionList.minBounds.tooltip",
                hasClearButton: false,
                hideYAxis: true
            });
            newRegionPane.addVector3(this._newBoundsMax, {
                title: "resourcePack.editor.chunkManagement.pane.regionList.maxBounds.title",
                tooltip: "resourcePack.editor.chunkManagement.pane.regionList.maxBounds.tooltip",
                hasClearButton: false,
                hideYAxis: true
            });
            newRegionPane.addButton((() => {
                if (this._newBoundsMin.value.x > this._newBoundsMax.value.x || this._newBoundsMin.value.z > this._newBoundsMax.value.z) {
                    this._uiSession.log.error("Minimum region bounds cannot be larger than maximum", {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    return;
                }
                this._addNewRegion(this._newBoundsMin.value.x, this._newBoundsMin.value.z, this._newBoundsMax.value.x, this._newBoundsMax.value.z);
            }), {
                title: "resourcePack.editor.chunkManagement.pane.regionList.addRegion.title",
                tooltip: "resourcePack.editor.chunkManagement.pane.regionList.addRegion.tooltip"
            });
            this._addBoundsFromSelectionButtonItem = newRegionPane.addButton((() => {
                if (this._uiSession.extensionContext.selectionManager.volume.isEmpty) {
                    this._uiSession.log.warning("No selection volume available");
                    return;
                }
                const selectionBounds = this._uiSession.extensionContext.selectionManager.volume.getBoundingBox();
                this._addNewRegion(selectionBounds.min.x, selectionBounds.min.z, selectionBounds.max.x, selectionBounds.max.z);
            }), {
                title: "resourcePack.editor.chunkManagement.pane.regionList.addFromSelection.title",
                tooltip: "resourcePack.editor.chunkManagement.pane.regionList.addFromSelection.tooltip",
                enable: !this._uiSession.extensionContext.selectionManager.volume.isEmpty
            });
            this._regionPane.addDivider();
            this._boundsListPane = this._regionPane.addListPane({
                height: 50,
                defaultSlots: [],
                onSlotClicked: slot => {
                    const slotData = slot.getUserData();
                    if (slotData) {
                        const widget = slotData.widget;
                        if (widget) {
                            const dimensionRange = this._uiSession.extensionContext.player.dimension.heightRange;
                            const teleportYPos = (dimensionRange.max - dimensionRange.min) / 2 - 64;
                            const teleportLocation = {
                                ...widget.location,
                                y: teleportYPos
                            };
                            this._uiSession.extensionContext.player.teleport(lib.Vector3Utils.subtract(teleportLocation, lib.Vector3Utils.scale(lib.VECTOR3_ONE, 5)), {
                                facingLocation: lib.Vector3Utils.add(widget.location, {
                                    x: CHUNK_SIZE / 2,
                                    y: teleportYPos,
                                    z: CHUNK_SIZE / 2
                                })
                            });
                        }
                    }
                },
                slotConfig: {
                    height: 4.4,
                    clickable: true,
                    entryLayout: [ {
                        type: server_editor_namespaceObject.ListPaneEntryType.Text,
                        size: server_editor_namespaceObject.LayoutFlex.Grow,
                        alignment: server_editor_namespaceObject.LayoutAlignment.Start
                    }, {
                        type: server_editor_namespaceObject.ListPaneEntryType.Button,
                        size: 4
                    } ]
                }
            });
        }
        _prepareOperation() {
            if (this._tickHandle !== undefined) {
                return;
            }
            switch (this._operationMode.value) {
              case ChunkOperationMode.Regeneration:
                {
                    const requestData = {
                        operationId: guid(),
                        state: "requested",
                        target: this._regenerationType.value === ChunkRegenerationType.World ? "world" : "list",
                        excludeBounds: this._shouldExcludeRegenerationBounds()
                    };
                    this.telemetryManager.fireTelemetryEvent(ChunkManagerTelemetry.Regenerate, requestData);
                    this._activeTelemetry = [ ChunkManagerTelemetry.Regenerate, requestData ];
                }
                break;

              case ChunkOperationMode.Delete:
                {
                    try {
                        this._getBoundsList().forEach((bounds => {
                            const operationRegion = this._playerRegionManager.leaseRegion({
                                extentX: bounds.x,
                                extentZ: bounds.z
                            });
                            this._operationRegions.push(operationRegion);
                        }));
                    } catch (e) {
                        this._uiSession.log.error(e.message, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        return;
                    }
                    const requestData = {
                        operationId: guid(),
                        state: "requested"
                    };
                    this.telemetryManager.fireTelemetryEvent(ChunkManagerTelemetry.Delete, requestData);
                    this._activeTelemetry = [ ChunkManagerTelemetry.Delete, requestData ];
                }
                break;

              default:
                {
                    throw Error("Chunk Operation is not defined");
                }
                break;
            }
            this._showProgressModal();
        }
        _executeOperation() {
            let executed = true;
            switch (this._operationMode.value) {
              case ChunkOperationMode.Regeneration:
                {
                    const bounds = this._regenerationType.value === ChunkRegenerationType.List ? this._getBoundsList() : [];
                    try {
                        this._regionManager.regenerateRegion(this._uiSession.extensionContext.player.dimension.id, bounds, this._shouldExcludeRegenerationBounds()).then((state => {
                            if (state.isCompleted) {
                                this._finalProcessedChunkCount = state.chunksProcessed;
                                this._progressModalText.set(this._getProgressMessage(true));
                            }
                        })).catch((e => {
                            this._uiSession.log.error(e.message, {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                            executed = false;
                        }));
                    } catch (e) {
                        this._uiSession.log.error(e.message, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        executed = false;
                    }
                }
                break;

              case ChunkOperationMode.Delete:
                {
                    this._regionManager.pruneRegion(this._uiSession.extensionContext.player.dimension.id, this._getBoundsList()).then((state => {
                        if (state.isCompleted) {
                            this._finalProcessedChunkCount = state.chunksProcessed;
                            this._progressModalText.set(this._getProgressMessage(true));
                        }
                    })).catch((e => {
                        this._uiSession.log.error(e.message, {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        executed = false;
                    }));
                }
                break;

              default:
                {
                    throw Error("Chunk Operation is not defined");
                }
                break;
            }
            return executed;
        }
        _showConfirmationModal() {
            if (this._tickHandle !== undefined || this._regionManager.isProcessingChunks) {
                this._uiSession.log.error("There is an active ongoing chunk operation", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const boundsList = this._getBoundsList();
            if (boundsList.length === 0) {
                if (this._operationMode.value === ChunkOperationMode.Regeneration && this._regenerationType.value === ChunkRegenerationType.List || this._operationMode.value === ChunkOperationMode.Delete) {
                    this._uiSession.log.error("Chunk operation requires region list entries", {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    return;
                }
            }
            this._modalOverlay.show();
        }
        _shouldExcludeRegenerationBounds() {
            return this._regenerationType.value === ChunkRegenerationType.World || this._listRegenerationExclusive.value;
        }
        _clearOperationRegions() {
            this._operationRegions.forEach((region => region.dispose()));
            this._operationRegions = [];
        }
        _showProgressModal() {
            this._executedOperation = false;
            this._progressModalText.set(this._getProgressMessage(true));
            this._uiSession.dialogManager.activateDialog({
                dialogId: this._progressModal.id
            });
            this._tickHandle = server_namespaceObject.system.runInterval((() => this._progressTick()), PROGRESS_TICK_INTERVAL);
        }
        _endProgressTick() {
            if (this._tickHandle !== undefined) {
                server_namespaceObject.system.clearRun(this._tickHandle);
                this._tickHandle = undefined;
                this._progressModal.sendDismiss();
                this._finalProcessedChunkCount = undefined;
                this._clearOperationRegions();
                this._executedOperation = undefined;
            }
            if (this._progressEndTimeout !== undefined) {
                server_namespaceObject.system.clearRun(this._progressEndTimeout);
                this._progressEndTimeout = undefined;
            }
        }
        _progressTick() {
            if (this._tickHandle !== undefined) {
                let isErrored = false;
                if (!this._executedOperation) {
                    let shouldExecute = false;
                    if (this._operationRegions.length > 0 && !this._regionManager.isProcessingChunks) {
                        shouldExecute = this._operationRegions.every((region => region.isAvailable()));
                    } else {
                        shouldExecute = true;
                    }
                    if (shouldExecute) {
                        isErrored = !this._executeOperation();
                        this._executedOperation = true;
                    }
                }
                if (!this._waitRegion && !this._regionManager.isProcessingChunks && this._executedOperation) {
                    this._clearOperationRegions();
                    const playerPos = this._uiSession.extensionContext.player.location;
                    this._waitRegion = this._playerRegionManager.leaseRegion({
                        extentX: {
                            min: playerPos.x - 100,
                            max: playerPos.x + 100
                        },
                        extentZ: {
                            min: playerPos.z - 100,
                            max: playerPos.z + 100
                        },
                        availabilityMode: server_editor_private_bindings_namespaceObject.ProjectRegionAvailabilityMode.Loaded
                    });
                }
                this._progressModalText.set(this._getProgressMessage(this._regionManager.isProcessingChunks));
                if (this._waitRegion && this._waitRegion.isAvailable()) {
                    if (this._activeTelemetry) {
                        this.telemetryManager.fireTelemetryEvent(this._activeTelemetry[0], {
                            ...this._activeTelemetry[1],
                            state: "completed",
                            processedChunks: this._finalProcessedChunkCount
                        });
                        this._activeTelemetry = undefined;
                    }
                    this._waitRegion.dispose();
                    this._waitRegion = undefined;
                    this._progressEndTimeout = server_namespaceObject.system.runTimeout((() => {
                        this._endProgressTick();
                    }), server_namespaceObject.TicksPerSecond * 2);
                }
                if (isErrored) {
                    if (this._activeTelemetry) {
                        this.telemetryManager.fireTelemetryEvent(this._activeTelemetry[0], {
                            ...this._activeTelemetry[1],
                            state: "error"
                        });
                        this._activeTelemetry = undefined;
                    }
                    this._uiSession.log.error("Chunk operation encountered an error", {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    this._endProgressTick();
                }
            }
        }
        _addNewRegion(minX, minZ, maxX, maxZ) {
            const heightRange = this._uiSession.extensionContext.player.dimension.heightRange;
            const extents = {
                x: {
                    min: Math.floor(minX / CHUNK_SIZE) * CHUNK_SIZE,
                    max: Math.floor(maxX / CHUNK_SIZE) * CHUNK_SIZE
                },
                z: {
                    min: Math.floor(minZ / CHUNK_SIZE) * CHUNK_SIZE,
                    max: Math.floor(maxZ / CHUNK_SIZE) * CHUNK_SIZE
                }
            };
            const widget = this._widgetGroup.createWidget({
                x: extents.x.min,
                y: heightRange.min,
                z: extents.z.min
            }, {
                visible: true,
                selectable: false
            });
            const prim = new server_editor_namespaceObject.WidgetComponentRenderPrimitiveTypeBox({
                x: 0,
                y: 0,
                z: 0
            }, {
                red: 0,
                green: 1,
                blue: 0,
                alpha: 1
            }, {
                x: extents.x.max + CHUNK_SIZE - extents.x.min,
                y: heightRange.max - heightRange.min,
                z: extents.z.max + CHUNK_SIZE - extents.z.min
            });
            widget.addRenderPrimitiveComponent("outline", prim, {
                visible: true
            });
            this._boundsListPane.addSlot({
                entries: [ {
                    type: server_editor_namespaceObject.ListPaneEntryType.Text
                }, {
                    type: server_editor_namespaceObject.ListPaneEntryType.Button,
                    onClick: entry => {
                        const slotData = entry.slot.getUserData();
                        if (slotData) {
                            slotData.widget?.delete();
                        }
                        this._boundsListPane.removeSlot(entry.slot.id);
                        this._updateUIState();
                    },
                    icon: "trashCanIcon",
                    variant: server_editor_namespaceObject.ButtonVariant.Destructive,
                    tooltip: "resourcePack.editor.chunkManagement.pane.regionList.removeFromList.title"
                } ],
                options: {
                    title: `X:${extents.x.min},${extents.x.max + CHUNK_SIZE} | Z:${extents.z.min},${extents.z.max + CHUNK_SIZE}`,
                    userData: {
                        extents,
                        widget
                    }
                }
            });
            this._updateUIState();
        }
        _updateUIState() {
            let canUseRegionList = true;
            const hasListItem = this._boundsListPane.slotCount > 0;
            if (this._operationMode.value === ChunkOperationMode.Delete) {
                this._deleteButton.enable = hasListItem;
                this._regionPane.show();
            } else if (this._operationMode.value === ChunkOperationMode.Regeneration) {
                this._regenerateButton.enable = this._regenerationType.value === ChunkRegenerationType.List ? hasListItem : true;
                if (this._listRegenerationExclusivePropItem) {
                    this._listRegenerationExclusivePropItem.visible = this._regenerationType.value === ChunkRegenerationType.List;
                }
                canUseRegionList = this._regenerationType.value !== ChunkRegenerationType.World;
            }
            if (this._widgetGroup) {
                this._widgetGroup.visible = canUseRegionList;
            }
            canUseRegionList ? this._regionPane.show() : this._regionPane.hide();
        }
        _getProgressMessage(processing) {
            if (processing || this._executedOperation === false) {
                const processingState = this._regionManager.getChunkProcessingState();
                const processedChunkCount = processingState?.chunksProcessed ?? 0;
                if (processedChunkCount === 0) {
                    return `resourcePack.editor.chunkManagement.operationModal.processingChunks`;
                }
                return {
                    id: `resourcePack.editor.chunkManagement.operationModal.processingChunksCount`,
                    props: [ `${processedChunkCount}` ]
                };
            } else {
                if (this._waitRegion) {
                    if (this._finalProcessedChunkCount === undefined) {
                        return `resourcePack.editor.chunkManagement.operationModal.reloading`;
                    }
                    return {
                        id: "resourcePack.editor.chunkManagement.operationModal.reloadingCount",
                        props: [ `${this._finalProcessedChunkCount}` ]
                    };
                }
                return "resourcePack.editor.chunkManagement.operationModal.completed";
            }
        }
        _getBoundsList() {
            const boundsList = [];
            for (let i = 0; i < this._boundsListPane.slotCount; ++i) {
                const slot = this._boundsListPane.getSlotByIndex(i);
                const slotData = slot?.getUserData();
                if (slotData) {
                    boundsList.push(slotData.extents);
                }
            }
            return boundsList;
        }
    }
    ChunkManagerBehavior.BEHAVIOR_NAME = "resourcePack.editor.chunkManagement.title";
    const FLOOD_REGION_SIDE = 1024;
    var FloodToolTelemetry;
    (function(FloodToolTelemetry) {
        FloodToolTelemetry["WidgetCreated"] = "WidgetCreated";
        FloodToolTelemetry["WidgetDeleted"] = "WidgetDeleted";
        FloodToolTelemetry["WidgetRaised"] = "WidgetRaised";
        FloodToolTelemetry["WidgetLowered"] = "WidgetLowered";
        FloodToolTelemetry["FloodCalculated"] = "FloodCalculated";
        FloodToolTelemetry["FloodApplied"] = "FloodApplied";
        FloodToolTelemetry["FloodCanceled"] = "FloodCanceled";
        FloodToolTelemetry["FluidTypeChanged"] = "FluidTypeChanged";
        FloodToolTelemetry["BlockLimitReached"] = "BlockLimitReached";
    })(FloodToolTelemetry || (FloodToolTelemetry = {}));
    class FloodToolBehavior {
        constructor(uiSession) {
            this._blockLimitReached = false;
            this._loweringWater = false;
            this._currentYWaterLevel = 0;
            this._raiseFluidBlockCheck = (region, block) => {
                const perm = region.getBlockPermutation(block);
                const blockId = region.getBlockTypeId(block);
                if ((blockId === lib_vanilla_MinecraftBlockTypes.Air.toString() || !perm.isLiquidBlocking(server_namespaceObject.LiquidType.Water) || perm.canContainLiquid(server_namespaceObject.LiquidType.Water)) && blockId !== lib_vanilla_MinecraftBlockTypes.Water.toString()) {
                    return true;
                }
                return false;
            };
            this._raiseFluidUpdateBlock = (region, block, waterlogged) => {
                if (!waterlogged || region.getBlockTypeId(block) === lib_vanilla_MinecraftBlockTypes.Air.toString()) {
                    region.setBlockType(block, this._props.fluidBlockType.value === 0 ? lib_vanilla_MinecraftBlockTypes.Water : lib_vanilla_MinecraftBlockTypes.Lava);
                }
            };
            this._lowerFluidBlockCheck = (region, block) => {
                if (region.getBlockTypeId(block) === lib_vanilla_MinecraftBlockTypes.Water.toString() || region.getBlockTypeId(block) === lib_vanilla_MinecraftBlockTypes.Lava.toString() || region.isBlockWaterLogged(block)) {
                    return true;
                }
                return false;
            };
            this._lowerFluidUpdateBlock = (region, block, waterlogged) => {
                if (waterlogged && region.getBlockTypeId(block) !== lib_vanilla_MinecraftBlockTypes.Air.toString()) {
                    region.setBlockWaterlogged(block, false);
                } else {
                    region.setBlockType(block, lib_vanilla_MinecraftBlockTypes.Air.toString());
                }
            };
            this._uiSession = uiSession;
            this._progressNumber = (0, server_editor_namespaceObject.makeObservable)(0);
            this._progressMessage = (0, server_editor_namespaceObject.makeObservable)("");
            this._uiSession.log.debug(`Initializing ${FloodToolBehavior.BEHAVIOR_NAME}`);
            this._telemetryManager = new TelemetryManager(this._uiSession.extensionContext.player, TelemetrySource.FloodTool);
            this._props = {
                fluidBlockType: (0, server_editor_namespaceObject.makeObservable)(0),
                ignoreBlockLimit: (0, server_editor_namespaceObject.makeObservable)(false)
            };
            this._cursorProperties = this._uiSession.extensionContext.cursor.getProperties();
            if (this._cursorProperties.fillColor) {
                delete this._cursorProperties.fillColor;
            }
            this._cursorProperties.outlineColor = FloodToolBehavior.CURSOR_OUTLINE_COLOR;
            this._cursorProperties.controlMode = server_editor_namespaceObject.CursorControlMode.KeyboardAndMouse;
            this._cursorProperties.targetMode = server_editor_namespaceObject.CursorTargetMode.Block;
            this._cursorProperties.projectThroughLiquid = false;
            this._cursorProperties.visible = true;
            this._uiSession.extensionContext.cursor.setProperties(this._cursorProperties);
            this._tool = this.addTool(this._uiSession);
            this.registerMouseAction(this._uiSession);
            this._propertyPane = this.addFloodToolSettingsPane(this._uiSession);
            this._tool.bindPropertyPane(this._propertyPane);
            this._widgetGroup = this._uiSession.extensionContext.widgetManager.createGroup({
                showBounds: false
            });
        }
        teardown() {
            if (this._widgetGizmo) {
                this._widgetGizmo.delete();
            }
            if (this._widgetComponentBoundingBox) {
                this._widgetComponentBoundingBox.delete();
            }
            if (this._widget) {
                this._widget.delete();
            }
            if (this._calcFloodHandle) {
                server_namespaceObject.system.clearJob(this._calcFloodHandle);
            }
            if (this._commitFloodHandle) {
                server_namespaceObject.system.clearJob(this._commitFloodHandle);
            }
            this._uiSession.log.debug(`Shutting down ${FloodToolBehavior.BEHAVIOR_NAME}`);
        }
        addTool(uiSession) {
            const toolToggleAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    uiSession.toolRail.setSelectedToolId(tool.id);
                }
            });
            const tool = uiSession.toolRail.addTool("editor:modalTool:flood", {
                title: "resourcePack.editor.toolRail.floodTool.title",
                icon: "pack://textures/editor/Flood-tool.png?filtering=point",
                tooltip: "resourcePack.editor.toolRail.floodTool.tooltip"
            });
            tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    if (this._widgetGizmo) {
                        this._createFloodRegion(this._widgetGizmo.location);
                    }
                    this._widgetGroup.visible = true;
                    this._widgetGroup.visibleBounds = true;
                    uiSession.extensionContext.cursor.setProperties(this._cursorProperties);
                } else {
                    this._widgetGroup.visible = false;
                    this._widgetGroup.visibleBounds = false;
                    if (this._floodRegion) {
                        this._floodRegion.dispose();
                        this._floodRegion = undefined;
                    }
                    if (this._calcFloodHandle) {
                        server_namespaceObject.system.clearJob(this._calcFloodHandle);
                    }
                    if (this._commitFloodHandle) {
                        server_namespaceObject.system.clearJob(this._commitFloodHandle);
                    }
                }
            }));
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, toolToggleAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_F,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            });
            const deleteGizmo = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._widgetGizmo) {
                        this._widgetGizmo.delete();
                        this._telemetryManager.fireTelemetryEvent(FloodToolTelemetry.WidgetDeleted);
                    }
                    if (this._widgetComponentBoundingBox) {
                        this._widgetComponentBoundingBox.delete();
                    }
                }
            });
            tool.registerKeyBinding(deleteGizmo, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_D,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:floodToolKeyBinding:deleteWidget",
                label: "resourcePack.editor.toolRail.floodTool.keyBinding.deleteWidget.title",
                tooltip: "resourcePack.editor.toolRail.floodTool.keyBinding.deleteWidget.tooltip"
            });
            const raiseGizmo = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._widgetGizmo) {
                        this._widgetGizmo.widget.location = {
                            x: this._widgetGizmo.widget.location.x,
                            y: this._widgetGizmo.widget.location.y + 1,
                            z: this._widgetGizmo.widget.location.z
                        };
                        this._calculateFlood(this._widgetGizmo.widget.location);
                        this._telemetryManager.fireTelemetryEvent(FloodToolTelemetry.WidgetRaised);
                    }
                }
            });
            tool.registerKeyBinding(raiseGizmo, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_UP
            }, {
                uniqueId: "editor:floodToolKeyBinding:raiseWidget",
                label: "resourcePack.editor.toolRail.floodTool.keyBinding.raiseWidget.title",
                tooltip: "resourcePack.editor.toolRail.floodTool.keyBinding.raiseWidget.tooltip"
            });
            const lowerGizmo = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._widgetGizmo) {
                        this._widgetGizmo.widget.location = {
                            x: this._widgetGizmo.widget.location.x,
                            y: this._widgetGizmo.widget.location.y - 1,
                            z: this._widgetGizmo.widget.location.z
                        };
                        this._calculateFlood(this._widgetGizmo.widget.location);
                        this._telemetryManager.fireTelemetryEvent(FloodToolTelemetry.WidgetLowered);
                    }
                }
            });
            tool.registerKeyBinding(lowerGizmo, {
                key: server_editor_namespaceObject.KeyboardKey.PAGE_DOWN
            }, {
                uniqueId: "editor:floodToolKeyBinding:lowerWidget",
                label: "resourcePack.editor.toolRail.floodTool.keyBinding.lowerWidget.title",
                tooltip: "resourcePack.editor.toolRail.floodTool.keyBinding.lowerWidget.tooltip"
            });
            return tool;
        }
        registerMouseAction(uiSession) {
            const executeAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.MouseRayCastAction,
                onExecute: (mouseRay, mouseProps) => {
                    if (mouseProps.mouseAction === server_editor_namespaceObject.MouseActionType.LeftButton && mouseProps.inputType === server_editor_namespaceObject.MouseInputType.ButtonDown && this._tool.isActive && mouseRay?.cursorBlockLocation) {
                        const player = this._uiSession.extensionContext.player;
                        const location = this._uiSession.extensionContext.cursor.getPosition();
                        const cursorRegion = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(player).regionManager.getCursorRegion();
                        let hasAirAround = false;
                        try {
                            hasAirAround = cursorRegion.getBlockTypeId(lib.Vector3Utils.add(location, lib.VECTOR3_UP)) === lib_vanilla_MinecraftBlockTypes.Air && cursorRegion.getBlockTypeId(lib.Vector3Utils.subtract(location, lib.VECTOR3_UP)) !== lib_vanilla_MinecraftBlockTypes.Air;
                        } catch (e) {
                            this._uiSession.log.error(`Could not create flood origin: ${stringFromException(e)}`, {
                                channelMask: server_editor_namespaceObject.LogChannel.All
                            });
                            return;
                        }
                        if (hasAirAround && location) {
                            if (this._widget) {
                                this._widget.delete();
                            }
                            this._createFloodRegion(location);
                            this._widget = this._widgetGroup.createWidget({
                                x: location.x,
                                y: location.y,
                                z: location.z
                            }, {
                                visible: true,
                                widgetName: "Flood Tool - Water Level Indicator"
                            });
                            this._widgetGizmo = this._widget.addGizmoComponent("floodToolGizmo", {
                                enablePlanes: true,
                                offset: {
                                    x: 1,
                                    y: 1,
                                    z: 1
                                },
                                stateChangeEvent: data => {
                                    if (data.eventType !== undefined && data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginReleased) {
                                        this._calculateFlood(data.widget.location);
                                    }
                                    if (data.eventType !== undefined && data.eventType === server_editor_namespaceObject.WidgetGizmoEventType.OriginGrabbed) {
                                        this._widgetComponentBoundingBox.size = {
                                            x: 100,
                                            y: 1,
                                            z: 100
                                        };
                                        this._widgetComponentBoundingBox.offset = {
                                            x: -50,
                                            y: -.2,
                                            z: -50
                                        };
                                        this._widgetComponentBoundingBox.hullColor = FloodToolBehavior.VALID_OUTLINE_COLOR;
                                    }
                                }
                            });
                            this._widgetComponentBoundingBox = this._widget.addBoundingBox("floodToolBoundingBox", {
                                x: 100,
                                y: 1,
                                z: 100
                            }, {
                                hullColor: FloodToolBehavior.VALID_OUTLINE_COLOR,
                                offset: {
                                    x: -50,
                                    y: -.2,
                                    z: -50
                                },
                                visible: true,
                                showWorldIntersections: true
                            });
                            this._currentYWaterLevel = location.y;
                            this._telemetryManager.fireTelemetryEvent(FloodToolTelemetry.WidgetCreated);
                        }
                    }
                }
            });
            this._tool.registerMouseButtonBinding(executeAction);
        }
        addFloodToolSettingsPane(uiSession) {
            const pane = uiSession.createPropertyPane({
                title: "resourcePack.editor.toolRail.floodTool.pane.title",
                infoTooltip: {
                    description: [ "resourcePack.editor.toolRail.floodTool.pane.description", {
                        link: "https://aka.ms/BedrockEditorFlood",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            const activateProcessingFlood = () => {
                const req = this._uiSession.dialogManager.activateDialog({
                    dialogId: FloodToolBehavior.MODAL_DIALOG_ID,
                    onResponse: resp => {
                        if (resp.type === server_editor_namespaceObject.ModalDialogResponseType.Dismiss) {
                            this._uiSession.log.debug(`Dismissing Flood modal dialog with id:${req.id}`);
                        }
                    }
                });
            };
            pane.beginConstruct();
            pane.addDropdown(this._props.fluidBlockType, {
                title: "resourcePack.editor.toolRail.floodTool.pane.fluidType.title",
                entries: [ {
                    value: 0,
                    label: "resourcePack.editor.toolRail.floodTool.pane.fluidType.water",
                    imageData: {
                        type: server_editor_namespaceObject.ImageResourceType.Block,
                        path: "water"
                    }
                }, {
                    value: 1,
                    label: "resourcePack.editor.toolRail.floodTool.pane.fluidType.lava",
                    imageData: {
                        type: server_editor_namespaceObject.ImageResourceType.Block,
                        path: "lava"
                    }
                } ],
                onChange: () => {
                    this._telemetryManager.fireTelemetryEvent(FloodToolTelemetry.FluidTypeChanged);
                }
            });
            pane.addBool(this._props.ignoreBlockLimit, {
                title: "resourcePack.editor.toolRail.floodTool.pane.ignoreBlockLimit.title",
                tooltip: "resourcePack.editor.toolRail.floodTool.pane.ignoreBlockLimit.tooltip"
            });
            const applyFloodAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this._calcPromise === undefined) {
                        return;
                    }
                    if (this._blockLimitReached && !this._props.ignoreBlockLimit.value) {
                        this._uiSession.log.warning("Unable to change water level due to number of blocks that need updated.", {
                            channelMask: server_editor_namespaceObject.LogChannel.All
                        });
                        return;
                    }
                    this._calcPromise.then((async () => {
                        await new Promise(((resolve, reject) => {
                            if (this._commitFloodHandle) {
                                server_namespaceObject.system.clearJob(this._commitFloodHandle);
                            }
                            this._commitFloodHandle = server_namespaceObject.system.runJob(this._commitFluidLevel(resolve, reject, this._blockLimitReached, this._loweringWater ? this._lowerFluidUpdateBlock : this._raiseFluidUpdateBlock));
                        }));
                        this._telemetryManager.fireTelemetryEvent(FloodToolTelemetry.FloodApplied);
                    })).catch((() => {}));
                    activateProcessingFlood();
                    this._rootPropertyPane.setActiveModalOverlay(this._processingCommitFlood.id);
                }
            });
            pane.addButton(applyFloodAction, {
                title: "resourcePack.editor.toolRail.floodTool.pane.applyFlood.title"
            });
            this._tool.registerKeyBinding(applyFloodAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_F,
                modifier: server_editor_namespaceObject.InputModifier.Control
            }, {
                uniqueId: "editor:floodToolKeyBinding:applyFlood",
                label: "resourcePack.editor.toolRail.floodTool.keyBinding.applyFlood.title",
                tooltip: "resourcePack.editor.toolRail.floodTool.keyBinding.applyFlood.tooltip"
            });
            pane.endConstruct();
            this._rootPropertyPane = pane;
            this._createProcessingCommitFloodModalPane();
            return pane;
        }
        _createProcessingCommitFloodModalPane() {
            this._processingCommitFlood = this._uiSession.dialogManager.registerDialog({
                title: "resourcePack.editor.toolRail.floodTool.modal.title",
                uniqueId: FloodToolBehavior.MODAL_DIALOG_ID,
                width: 75,
                height: 20
            });
            this._processingCommitFlood.contentPane.addText(this._progressMessage, {
                border: false,
                alignment: server_editor_namespaceObject.LayoutAlignment.Center
            });
            this._processingCommitFlood.contentPane.addProgressIndicator({
                variant: server_editor_namespaceObject.ProgressIndicatorPropertyItemVariant.ProgressBar,
                progress: this._progressNumber
            });
            this._processingCommitFlood.contentPane.addButton((() => {
                if (this._calcFloodHandle) {
                    server_namespaceObject.system.clearJob(this._calcFloodHandle);
                }
                if (this._commitFloodHandle) {
                    server_namespaceObject.system.clearJob(this._commitFloodHandle);
                }
                this._uiSession.extensionContext.transactionManager.commitTrackedChanges();
                this._uiSession.extensionContext.transactionManager.commitOpenTransaction();
                this._uiSession.extensionContext.transactionManager.undo();
                this._uiSession.dialogManager.dismissActiveDialog();
                this._telemetryManager.fireTelemetryEvent(FloodToolTelemetry.FloodCanceled);
            }), {
                variant: server_editor_namespaceObject.ButtonVariant.Destructive,
                title: "resourcePack.editor.toolRail.floodTool.modal.cancel"
            });
        }
        _createFloodRegion(location) {
            if (this._floodRegion) {
                this._floodRegion.dispose();
            }
            this._floodRegion = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(this._uiSession.extensionContext.player).regionManager.leaseRegion({
                extentX: {
                    min: location.x - FLOOD_REGION_SIDE / 2,
                    max: location.x + FLOOD_REGION_SIDE / 2
                },
                extentZ: {
                    min: location.z - FLOOD_REGION_SIDE / 2,
                    max: location.z + FLOOD_REGION_SIDE / 2
                }
            });
        }
        _calculateFlood(location) {
            if (!this._floodRegion) {
                this._uiSession.log.error("Flood region not available", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            this._floodRegion.waitUntilAvailable().then((() => {
                if (location.y < this._currentYWaterLevel) {
                    this._uiSession.log.debug("Attempting to lower the water level...");
                    const aboveLocation = lib.Vector3Utils.add(location, {
                        x: 0,
                        y: 1,
                        z: 0
                    });
                    if (this._floodRegion?.getBlockPermutation(aboveLocation).canContainLiquid(server_namespaceObject.LiquidType.Water) || this._floodRegion?.getBlockTypeId(aboveLocation) === lib_vanilla_MinecraftBlockTypes.Water.toString() || this._floodRegion?.getBlockTypeId(aboveLocation) === lib_vanilla_MinecraftBlockTypes.Lava.toString()) {
                        this._calcPromise = new Promise(((resolve, reject) => {
                            if (this._calcFloodHandle) {
                                server_namespaceObject.system.clearJob(this._calcFloodHandle);
                            }
                            this._calcFloodHandle = server_namespaceObject.system.runJob(this._calculateFluidLevel(resolve, reject, {
                                x: location.x,
                                y: location.y + 1,
                                z: location.z
                            }, true, this._lowerFluidBlockCheck));
                        }));
                    }
                } else if (location.y > this._currentYWaterLevel) {
                    this._uiSession.log.debug("Attempting to raise the water level...");
                    this._calcPromise = new Promise(((resolve, reject) => {
                        if (this._calcFloodHandle) {
                            server_namespaceObject.system.clearJob(this._calcFloodHandle);
                        }
                        this._calcFloodHandle = server_namespaceObject.system.runJob(this._calculateFluidLevel(resolve, reject, {
                            x: location.x,
                            y: location.y,
                            z: location.z
                        }, false, this._raiseFluidBlockCheck));
                    }));
                }
            })).catch((error => {
                this._uiSession.log.warning(`Flood operation: ${stringFromException(error)}`);
            }));
        }
        * _calculateFluidLevel(jobCompleted, jobFailed, startingLocation, loweringWater, addBlockFunct) {
            if (!this._floodRegion || !this._floodRegion.isAvailable()) {
                jobFailed("Flood region failure");
                return;
            }
            this._targetLocation = startingLocation;
            this._minX = startingLocation.x;
            this._minZ = startingLocation.z;
            this._maxX = startingLocation.x;
            this._maxZ = startingLocation.z;
            if (loweringWater) {
                this._progressMessage.set("resourcePack.editor.toolRail.floodTool.progress.friendlyCalculatingDrainMessage");
            } else {
                this._progressMessage.set("resourcePack.editor.toolRail.floodTool.progress.friendlyCalculatingFloodMessage");
            }
            let iterations = 0;
            const q = [ startingLocation ];
            this._visitedBlocks = new Map;
            while (q.length > 0 && this._visitedBlocks.size < FloodToolBehavior.MAX_BFS_SIZE) {
                const currentBlock = q.shift();
                if (currentBlock && !this._visitedBlocks.get(lib.Vector3Utils.toString(currentBlock))?.visited) {
                    if (currentBlock.y === startingLocation.y) {
                        if (currentBlock.x > this._maxX) {
                            this._maxX = currentBlock.x;
                        }
                        if (currentBlock.x < this._minX) {
                            this._minX = currentBlock.x;
                        }
                        if (currentBlock.z > this._maxZ) {
                            this._maxZ = currentBlock.z;
                        }
                        if (currentBlock.z < this._minZ) {
                            this._minZ = currentBlock.z;
                        }
                    }
                    iterations++;
                    const permutation = this._floodRegion.getBlockPermutation(currentBlock);
                    this._visitedBlocks.set(lib.Vector3Utils.toString(currentBlock), {
                        visited: true,
                        waterlogged: permutation.canContainLiquid(server_namespaceObject.LiquidType.Water) ?? false,
                        loc: currentBlock
                    });
                    const targetBlockPlusX = {
                        x: currentBlock.x + 1,
                        y: currentBlock.y,
                        z: currentBlock.z
                    };
                    const targetBlockMinusX = {
                        x: currentBlock.x - 1,
                        y: currentBlock.y,
                        z: currentBlock.z
                    };
                    const targetBlockPlusZ = {
                        x: currentBlock.x,
                        y: currentBlock.y,
                        z: currentBlock.z + 1
                    };
                    const targetBlockMinusZ = {
                        x: currentBlock.x,
                        y: currentBlock.y,
                        z: currentBlock.z - 1
                    };
                    const targetBlockYChange = loweringWater ? lib.Vector3Utils.add(currentBlock, lib.VECTOR3_UP) : lib.Vector3Utils.subtract(currentBlock, lib.VECTOR3_UP);
                    const blocks = [ targetBlockYChange, targetBlockMinusX, targetBlockMinusZ, targetBlockPlusX, targetBlockPlusZ ];
                    for (const block of blocks) {
                        if (this._floodRegion && addBlockFunct(this._floodRegion, block)) {
                            q.push(block);
                        }
                    }
                    if (iterations % FloodToolBehavior.GENERATOR_ITERATIONS_BEFORE_YIELD === 0) {
                        const progress = this._visitedBlocks.size / FloodToolBehavior.MAX_BFS_SIZE * 50 / 100;
                        this._progressNumber.set(progress);
                        yield;
                    }
                }
            }
            this._blockLimitReached = q.length > 0;
            this._loweringWater = loweringWater;
            if (this._blockLimitReached) {
                this._telemetryManager.fireTelemetryEvent(FloodToolTelemetry.BlockLimitReached);
            }
            this._telemetryManager.fireTelemetryEvent(FloodToolTelemetry.FloodCalculated);
            if (this._widgetComponentBoundingBox) {
                const sizeX = Math.max(1, Math.abs(this._maxX - this._minX) + 1);
                const sizeZ = Math.max(1, Math.abs(this._maxZ - this._minZ) + 1);
                if (sizeX > 100 || sizeZ > 100) {
                    this._widgetComponentBoundingBox.size = {
                        x: 100,
                        y: 1,
                        z: 100
                    };
                    this._widgetComponentBoundingBox.offset = {
                        x: -50,
                        y: -.2,
                        z: -50
                    };
                } else {
                    this._widgetComponentBoundingBox.size = {
                        x: sizeX,
                        y: 1,
                        z: sizeZ
                    };
                    this._widgetComponentBoundingBox.offset = {
                        x: this._minX - startingLocation.x,
                        y: -.2,
                        z: this._minZ - startingLocation.z
                    };
                }
                if (this._blockLimitReached) {
                    this._widgetComponentBoundingBox.hullColor = FloodToolBehavior.WARNING_OUTLINE_COLOR;
                }
            }
            this._progressNumber.set(.5);
            jobCompleted();
        }
        * _commitFluidLevel(jobCompleted, jobFailed, blockLimitReached, updateBlockFunct) {
            if (!this._floodRegion || !this._floodRegion.isAvailable()) {
                jobFailed("Flood Region not available");
                this._processingCommitFlood.sendDismiss();
                return;
            }
            if (this._loweringWater) {
                this._progressMessage.set("resourcePack.editor.toolRail.floodTool.progress.friendlyDrainingMessage");
            } else if (this._props.fluidBlockType.value === 0) {
                this._progressMessage.set("resourcePack.editor.toolRail.floodTool.progress.friendlyFloodingWaterMessage");
            } else {
                this._progressMessage.set("resourcePack.editor.toolRail.floodTool.progress.friendlyFloodingLavaMessage");
            }
            let iterations = 0;
            if (blockLimitReached && !this._props.ignoreBlockLimit.value) {
                this._uiSession.log.warning("Unable to change water level due to number of blocks that need updated.", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                this._processingCommitFlood.sendDismiss();
                jobFailed();
            } else {
                try {
                    this._uiSession.extensionContext.transactionManager.openTransaction(UniqueIdUtils_createUniqueEditorString("Flood Tool"));
                } catch (_e) {
                    this._processingCommitFlood.sendDismiss();
                    jobFailed(_e);
                }
                for (const value of this._visitedBlocks.values()) {
                    iterations++;
                    if (this._floodRegion) {
                        this._uiSession.extensionContext.transactionManager.trackBlockChangeList([ value.loc ]);
                        updateBlockFunct(this._floodRegion, value.loc, value.waterlogged);
                    }
                    if (iterations % FloodToolBehavior.GENERATOR_ITERATIONS_BEFORE_YIELD === 0) {
                        const progress = (iterations / this._visitedBlocks.size * 50 + 50) / 100;
                        this._progressNumber.set(progress);
                        yield;
                    }
                }
                this._uiSession.extensionContext.transactionManager.commitTrackedChanges();
                this._uiSession.extensionContext.transactionManager.commitOpenTransaction();
                this._uiSession.dialogManager.dismissActiveDialog();
                this._currentYWaterLevel = this._loweringWater ? this._targetLocation.y - 1 : this._targetLocation.y;
                this._visitedBlocks.clear();
                jobCompleted();
            }
        }
    }
    FloodToolBehavior.BEHAVIOR_NAME = "Flood Tool";
    FloodToolBehavior.MODAL_DIALOG_ID = "ProcessingFloodModalId";
    FloodToolBehavior.MAX_BFS_SIZE = 12e4;
    FloodToolBehavior.GENERATOR_ITERATIONS_BEFORE_YIELD = 1e3;
    FloodToolBehavior.FLUID_BLOCKS = [ "water", "lava" ];
    FloodToolBehavior.VALID_OUTLINE_COLOR = {
        red: .5,
        green: .5,
        blue: .5,
        alpha: 1
    };
    FloodToolBehavior.WARNING_OUTLINE_COLOR = {
        red: .5,
        green: .5,
        blue: 0,
        alpha: 1
    };
    FloodToolBehavior.CURSOR_OUTLINE_COLOR = {
        red: 0,
        green: .95,
        blue: 1,
        alpha: .88
    };
    function VibrantVisualsBiome_stringFromException(e) {
        if (typeof e === "string") {
            return e;
        } else if (typeof e === "object" && e !== null && "message" in e) {
            return e.message;
        }
        return "Unknown exception";
    }
    var ObservableUIControlType;
    (function(ObservableUIControlType) {
        ObservableUIControlType[ObservableUIControlType["Number"] = 0] = "Number";
        ObservableUIControlType[ObservableUIControlType["String"] = 1] = "String";
        ObservableUIControlType[ObservableUIControlType["Slider"] = 2] = "Slider";
        ObservableUIControlType[ObservableUIControlType["Checkbox"] = 3] = "Checkbox";
        ObservableUIControlType[ObservableUIControlType["ColorRGB"] = 4] = "ColorRGB";
        ObservableUIControlType[ObservableUIControlType["ColorRGBA"] = 5] = "ColorRGBA";
        ObservableUIControlType[ObservableUIControlType["Vector3"] = 6] = "Vector3";
        ObservableUIControlType[ObservableUIControlType["Dropdown"] = 7] = "Dropdown";
        ObservableUIControlType[ObservableUIControlType["ColorTimeline"] = 8] = "ColorTimeline";
        ObservableUIControlType[ObservableUIControlType["NumberTimeline"] = 9] = "NumberTimeline";
    })(ObservableUIControlType || (ObservableUIControlType = {}));
    class DataItemGroupUIControlBase {
        get type() {
            throw new Error("Not implemented in base");
        }
        get group() {
            throw new Error("Not implemented in base");
        }
        _insertDataIntoOriginalObject(_propertyPath, _newValue, _actualData, _observableUIControlType, _originalType) {
            const fnInsertDataIntoObjectByPath = (_path, _value) => {
                const pathParts = _path.split("/").filter(Boolean);
                let data = _actualData;
                for (let i = 0; i < pathParts.length; i++) {
                    const part = pathParts[i];
                    if (data[part] === undefined) {
                        throw new Error(`Failed to find path element ${part}`);
                    }
                    if (i === pathParts.length - 1) {
                        data[part] = _value;
                        return true;
                    }
                    data = data[part];
                }
                throw new Error(`Failed to find path element ${_path}`);
            };
            switch (_observableUIControlType) {
              case ObservableUIControlType.Number:
              case ObservableUIControlType.Slider:
                {
                    if (typeof _newValue !== "number") {
                        throw new Error(`Invalid number value for property ${_propertyPath}`);
                    }
                    switch (_originalType) {
                      case OpNodeSourceType.INTEGER:
                        fnInsertDataIntoObjectByPath(_propertyPath, Math.round(_newValue));
                        break;

                      case OpNodeSourceType.NUMBER:
                        fnInsertDataIntoObjectByPath(_propertyPath, _newValue);
                        break;

                      default:
                        throw new Error(`Invalid original type for property ${_propertyPath}`);
                    }
                }
                break;

              case ObservableUIControlType.Checkbox:
                {
                    if (typeof _newValue !== "boolean") {
                        throw new Error(`Invalid number value for property ${_propertyPath}`);
                    }
                    fnInsertDataIntoObjectByPath(_propertyPath, _newValue);
                }
                break;

              case ObservableUIControlType.String:
                {
                    if (typeof _newValue !== "string") {
                        throw new Error(`Invalid string value for property ${_propertyPath}`);
                    }
                    if (_originalType !== OpNodeSourceType.STRING) {
                        throw new Error(`Invalid original type for property ${_propertyPath}`);
                    }
                    fnInsertDataIntoObjectByPath(_propertyPath, _newValue);
                }
                break;

              case ObservableUIControlType.ColorRGB:
              case ObservableUIControlType.ColorRGBA:
                {
                    if (typeof _newValue !== "object") {
                        throw new Error(`Invalid color value for property ${_propertyPath}`);
                    }
                    if (_originalType === OpNodeSourceType.ARRAY || _originalType === OpNodeSourceType.MAP) {
                        if ("red" in _newValue && "green" in _newValue && "blue" in _newValue) {
                            if (_originalType === OpNodeSourceType.ARRAY) {
                                const colorComponents = [];
                                colorComponents.push(Number(_newValue.red));
                                colorComponents.push(Number(_newValue.green));
                                colorComponents.push(Number(_newValue.blue));
                                if (_observableUIControlType === ObservableUIControlType.ColorRGBA && "alpha" in _newValue) {
                                    colorComponents.push(Number(_newValue.alpha));
                                }
                                for (let i = 0; i < colorComponents.length; i++) {
                                    const keyName = `${_propertyPath}/${i}`;
                                    fnInsertDataIntoObjectByPath(keyName, Math.round(colorComponents[i] * 255));
                                }
                            } else if (_originalType === OpNodeSourceType.MAP) {
                                throw new Error(`Associative container of named RGB values not yet implemented`);
                            }
                        } else {
                            throw new Error(`Invalid color value for property ${_propertyPath}`);
                        }
                    } else if (_originalType === OpNodeSourceType.STRING) {
                        if ("red" in _newValue && "green" in _newValue && "blue" in _newValue) {
                            const toHex = n => {
                                const hex = Math.max(0, Math.min(255, Math.round(n * 255))).toString(16);
                                return hex.length === 1 ? "0" + hex : hex;
                            };
                            const red = Number(_newValue.red);
                            const green = Number(_newValue.green);
                            const blue = Number(_newValue.blue);
                            let hexString = "";
                            if (_observableUIControlType === ObservableUIControlType.ColorRGBA && "alpha" in _newValue) {
                                const alpha = Number(_newValue.alpha);
                                hexString = `#${toHex(red)}${toHex(green)}${toHex(blue)}${toHex(alpha)}`;
                            } else {
                                hexString = `#${toHex(red)}${toHex(green)}${toHex(blue)}`;
                            }
                            fnInsertDataIntoObjectByPath(_propertyPath, hexString);
                        } else {
                            throw new Error(`Invalid color value for property ${_propertyPath}`);
                        }
                    } else {
                        throw new Error(`Invalid original type for property ${_propertyPath}`);
                    }
                }
                break;

              case ObservableUIControlType.Vector3:
                {
                    if (typeof _newValue !== "object" && !Array.isArray(_newValue)) {
                        throw new Error(`Invalid color value for property ${_propertyPath}`);
                    }
                    if (_originalType !== OpNodeSourceType.ARRAY && _originalType !== OpNodeSourceType.MAP) {
                        throw new Error(`Invalid original type for property ${_propertyPath}`);
                    }
                    if ("x" in _newValue && "y" in _newValue && "z" in _newValue) {
                        if (_originalType === OpNodeSourceType.ARRAY) {
                            const vectorComponents = [];
                            vectorComponents.push(Number(_newValue.x));
                            vectorComponents.push(Number(_newValue.y));
                            vectorComponents.push(Number(_newValue.z));
                            for (let i = 0; i < vectorComponents.length; i++) {
                                const keyName = `${_propertyPath}/${i}`;
                                fnInsertDataIntoObjectByPath(keyName, vectorComponents[i]);
                            }
                        } else if (_originalType === OpNodeSourceType.MAP) {
                            throw new Error(`Associative container of named XYZ values not yet implemented`);
                        }
                    } else {
                        throw new Error(`Invalid color value for property ${_propertyPath}`);
                    }
                }
                break;

              case ObservableUIControlType.Dropdown:
                {
                    if (typeof _newValue !== "string") {
                        throw new Error(`Invalid dropdown value for property ${_propertyPath}`);
                    }
                    if (_originalType !== OpNodeSourceType.STRING) {
                        throw new Error(`Invalid original type for property ${_propertyPath}`);
                    }
                    fnInsertDataIntoObjectByPath(_propertyPath, _newValue);
                }
                break;

              case ObservableUIControlType.ColorTimeline:
                {
                    if (typeof _newValue !== "object") {
                        throw new Error(`Invalid colorTimeline value for property ${_propertyPath}`);
                    }
                    if (_originalType !== OpNodeSourceType.MAP) {
                        throw new Error(`Invalid original type for property ${_propertyPath}`);
                    }
                    fnInsertDataIntoObjectByPath(_propertyPath, _newValue);
                }
                break;

              case ObservableUIControlType.NumberTimeline:
                {
                    if (typeof _newValue !== "object") {
                        throw new Error(`Invalid numberTimeline value for property ${_propertyPath}`);
                    }
                    if (_originalType !== OpNodeSourceType.MAP) {
                        throw new Error(`Invalid original type for property ${_propertyPath}`);
                    }
                    fnInsertDataIntoObjectByPath(_propertyPath, _newValue);
                }
                break;

              default:
                throw new Error(`Invalid property bag type for property ${_propertyPath}`);
            }
            return true;
        }
    }
    class DataItemGroupUIControlPropertyPane extends DataItemGroupUIControlBase {
        get type() {
            return DataItemGroupType.PropertyPane;
        }
        get group() {
            return this._group;
        }
        get propertyPane() {
            return this._uiPropertyPane;
        }
        constructor(group, _hasParentPane, _rootPane, _observables, _actualData, _schemaInterface, _dataItemChangedCallback, _helpString) {
            super();
            this._group = group;
            this._helpString = _helpString;
            const displayName = this.group.displayName;
            const displayExpander = this.group.displayName.length > 0 && _hasParentPane;
            const toolTip = {
                title: displayName,
                description: [ _helpString ?? "" ]
            };
            this._uiPropertyPane = this.group.logicalGroupOnly ? _rootPane : _rootPane.createSubPane({
                title: displayName,
                hasExpander: displayExpander,
                hasMargins: displayExpander,
                collapsed: true,
                infoTooltip: _helpString !== undefined ? toolTip : undefined
            });
            if (!this._uiPropertyPane) {
                throw new Error("Failed to create property pane");
            }
            const unsorted = group.tags.find((tag => tag === "unsorted")) !== undefined;
            if (!unsorted) {
                this.group.dataItems.sort(((a, b) => a._displayName.localeCompare(b._displayName)));
            }
            for (const item of this.group.dataItems) {
                const localizedTitle = `${item._displayName}`;
                const updateOriginalJSONData = newValue => {
                    const observableControlType = item._observableControlType;
                    const originalType = item._originalType;
                    const isJSONDataInserted = this._insertDataIntoOriginalObject(item._observableName, newValue, _actualData, observableControlType, originalType);
                    if (isJSONDataInserted && _dataItemChangedCallback) {
                        _dataItemChangedCallback();
                    }
                };
                switch (item._observableControlType) {
                  case ObservableUIControlType.Number:
                  case ObservableUIControlType.Slider:
                    {
                        const showSlider = item._observableControlType === ObservableUIControlType.Slider;
                        _schemaInterface.debug(`Adding number property: ${item._observableName} as ${showSlider ? "slider" : "number"}`);
                        const propItemOptions = {
                            title: localizedTitle
                        };
                        if (item._min !== undefined && item._max !== undefined) {
                            propItemOptions.min = item._min;
                            propItemOptions.max = item._max;
                            propItemOptions.variant = showSlider ? server_editor_namespaceObject.NumberPropertyItemVariant.InputFieldAndSlider : server_editor_namespaceObject.NumberPropertyItemVariant.InputField;
                        }
                        if (item._readonly) {
                            propItemOptions.enable = false;
                        }
                        propItemOptions.onChange = (newValue, _oldValue) => {
                            updateOriginalJSONData(newValue);
                        };
                        item._setOriginalJSONData = (observableTypes, propertyPath, newValue) => {
                            observableTypes[propertyPath].set(newValue);
                            updateOriginalJSONData(newValue);
                        };
                        if (item._helpString) {
                            propItemOptions.tooltip = item._helpString;
                        }
                        const currentObservable = _observables[item._observableName];
                        this._uiPropertyPane.addNumber(currentObservable, propItemOptions);
                    }
                    break;

                  case ObservableUIControlType.String:
                    {
                        _schemaInterface.debug(`Adding string property: ${item._observableName}`);
                        const propItemOptions = {
                            title: localizedTitle,
                            onChange: (newValue, _oldValue) => {
                                updateOriginalJSONData(newValue);
                            }
                        };
                        if (item._readonly) {
                            propItemOptions.enable = false;
                        }
                        if (item._displayName === "format_version") {
                            break;
                        }
                        item._setOriginalJSONData = (observableTypes, propertyPath, newValue) => {
                            observableTypes[propertyPath].set(newValue);
                            updateOriginalJSONData(newValue);
                        };
                        if (item._helpString) {
                            propItemOptions.tooltip = item._helpString;
                        }
                        const currentObservable = _observables[item._observableName];
                        this._uiPropertyPane.addString(currentObservable, propItemOptions);
                    }
                    break;

                  case ObservableUIControlType.ColorRGB:
                  case ObservableUIControlType.ColorRGBA:
                    {
                        _schemaInterface.debug(`Adding color property: ${item._observableName}`);
                        const propItemOptions = {
                            title: localizedTitle,
                            hiddenAlpha: item._observableControlType === ObservableUIControlType.ColorRGBA,
                            variant: server_editor_namespaceObject.ColorPickerPropertyItemVariant.Inline,
                            onChange: (newValue, _oldValue) => {
                                updateOriginalJSONData(newValue);
                            }
                        };
                        if (item._readonly) {
                            propItemOptions.enable = false;
                        }
                        item._setOriginalJSONData = (observableTypes, propertyPath, newValue) => {
                            observableTypes[propertyPath].set(newValue);
                            updateOriginalJSONData(newValue);
                        };
                        if (item._helpString) {
                            propItemOptions.tooltip = item._helpString;
                        }
                        const currentObservable = _observables[item._observableName];
                        this._uiPropertyPane.addColorPicker(currentObservable, propItemOptions);
                    }
                    break;

                  case ObservableUIControlType.Vector3:
                    {
                        _schemaInterface.debug(`Adding vector property: ${item._observableName}`);
                        const propItemOptions = {
                            title: localizedTitle,
                            onChange: (newValue, _oldValue) => {
                                updateOriginalJSONData(newValue);
                            }
                        };
                        if (item._min !== undefined) {
                            propItemOptions.min = {
                                x: item._min,
                                y: item._min,
                                z: item._min
                            };
                        }
                        if (item._max !== undefined) {
                            propItemOptions.max = {
                                x: item._max,
                                y: item._max,
                                z: item._max
                            };
                        }
                        if (item._readonly) {
                            propItemOptions.enable = false;
                        }
                        item._setOriginalJSONData = (observableTypes, propertyPath, newValue) => {
                            observableTypes[propertyPath].set(newValue);
                            updateOriginalJSONData(newValue);
                        };
                        if (item._helpString) {
                            propItemOptions.tooltip = item._helpString;
                        }
                        const currentObservable = _observables[item._observableName];
                        this._uiPropertyPane.addVector3(currentObservable, propItemOptions);
                    }
                    break;

                  case ObservableUIControlType.Dropdown:
                    {
                        _schemaInterface.debug(`Adding dropdown property: ${item._observableName}`);
                        if (item._enums === undefined || item._prettyEnums === undefined) {
                            throw new Error("Dropdown property must have enums defined");
                        }
                        const comboDropdownItems = item._prettyEnums?.map(((v, i) => {
                            const dropItem = {
                                label: v,
                                value: i
                            };
                            return dropItem;
                        }));
                        const propItemOptions = {
                            title: localizedTitle,
                            entries: comboDropdownItems,
                            onChange: (newValue, _oldValue, _items) => {
                                const dropDownNewValue = item._enums !== undefined ? item._enums[newValue] : newValue;
                                updateOriginalJSONData(dropDownNewValue);
                            }
                        };
                        if (item._readonly) {
                            propItemOptions.enable = false;
                        }
                        item._setOriginalJSONData = (observableTypes, propertyPath, newValue) => {
                            if (item._enums !== undefined) {
                                const index = item._enums.indexOf(item._enums[newValue]);
                                if (index !== -1) {
                                    observableTypes[propertyPath].set(index);
                                }
                            }
                            const dropDownNewValue = item._enums !== undefined ? item._enums[newValue] : "";
                            updateOriginalJSONData(dropDownNewValue);
                        };
                        if (item._helpString) {
                            propItemOptions.tooltip = item._helpString;
                        }
                        const currentObservable = _observables[item._observableName];
                        this._uiPropertyPane.addDropdown(currentObservable, propItemOptions);
                    }
                    break;

                  case ObservableUIControlType.Checkbox:
                    {
                        _schemaInterface.debug(`Adding checkbox property: ${item._observableName}`);
                        const propItemOptions = {
                            title: localizedTitle,
                            onChange: (newValue, _oldValue) => {
                                updateOriginalJSONData(newValue);
                            }
                        };
                        if (item._readonly) {
                            propItemOptions.enable = false;
                        }
                        item._setOriginalJSONData = (observableTypes, propertyPath, newValue) => {
                            observableTypes[propertyPath].set(newValue);
                            updateOriginalJSONData(newValue);
                        };
                        if (item._helpString) {
                            propItemOptions.tooltip = item._helpString;
                        }
                        const currentObservable = _observables[item._observableName];
                        this._uiPropertyPane.addBool(currentObservable, propItemOptions);
                    }
                    break;

                  case ObservableUIControlType.ColorTimeline:
                    throw new Error("ColorTimeline control cannot be used in a property pane");

                  case ObservableUIControlType.NumberTimeline:
                    throw new Error("NumberTimeline control cannot be used in a property pane");

                  default:
                    throw new Error(`invalid control type: ${item._observableControlType}`);
                }
            }
        }
    }
    class DataItemGroupUIControlColorTimeline extends DataItemGroupUIControlBase {
        get type() {
            return DataItemGroupType.ColorTimeline;
        }
        get group() {
            return this._group;
        }
        constructor(group, _rootPane, _observables, _actualData, _schemaInterface, _dataItemChangedCallback, _helpString) {
            super();
            this._isTimelinePreview = false;
            this._group = group;
            const displayName = group.displayName;
            const displayExpander = true;
            const toolTip = {
                title: displayName,
                description: [ _helpString ?? "" ]
            };
            this._uiPropertyPane = _rootPane.createSubPane({
                title: displayName,
                hasExpander: displayExpander,
                collapsed: true,
                infoTooltip: _helpString !== undefined ? toolTip : undefined
            });
            if (!this._uiPropertyPane) {
                throw new Error("Failed to create property pane");
            }
            this._isTimelinePreview = group.tags.find((tag => tag === "previewTime")) !== undefined;
            const unsorted = group.tags.find((tag => tag === "unsorted")) !== undefined;
            if (!unsorted) {
                this.group.dataItems.sort(((a, b) => a._displayName.localeCompare(b._displayName)));
            }
            const dataTable = [];
            let colorValueTypes = undefined;
            let itemIndex = 0;
            for (const item of this.group.dataItems) {
                if (item._observableControlType !== ObservableUIControlType.ColorRGBA && item._observableControlType !== ObservableUIControlType.ColorRGB) {
                    throw new Error(`ColorTimeline control can only contain color data items.  Item ${item._observableName} is a ${item._observableControlType}`);
                }
                if (colorValueTypes === undefined) {
                    colorValueTypes = item._observableControlType;
                }
                if (colorValueTypes !== item._observableControlType) {
                    throw new Error("ColorTimeline control can only handle a container of the same color types - you can't mix RGB and RGBA value types");
                }
                item._setOriginalJSONData = (_o, _p, _v) => {};
                const itemName = group.path + "/" + itemIndex.toString();
                const currentObservable = _observables[item._observableName];
                try {
                    let time = parseFloat(item._displayName);
                    if (time < 0 || time > 1) {
                        _schemaInterface.error(`Warning: Time value in the ColorTimeline container should be between 0 and 1 [${itemName} = ${time}]`);
                        time = Math.max(0, Math.min(1, time));
                    }
                    dataTable.push({
                        id: itemName,
                        time,
                        value: currentObservable.value
                    });
                    _schemaInterface.debug(`Adding Key/Color property: ${itemName} -- [${time} = ${JSON.stringify(currentObservable.value)}]`);
                } catch (_e) {
                    _schemaInterface.error(`Failed to parse time value for item ${item._observableName} - ${VibrantVisualsBiome_stringFromException(_e)}`);
                    throw new Error("ColorTimeline control only supports numeric key values");
                }
                ++itemIndex;
            }
            const _rebuildContainerObject = _dataItems => {
                const outMap = {};
                for (const item of _dataItems) {
                    const time = item.time;
                    const colorValue = item.value;
                    const red = Math.max(0, Math.min(255, Math.round(colorValue.red * 255)));
                    const green = Math.max(0, Math.min(255, Math.round(colorValue.green * 255)));
                    const blue = Math.max(0, Math.min(255, Math.round(colorValue.blue * 255)));
                    const alpha = Math.max(0, Math.min(255, Math.round(colorValue.alpha * 255)));
                    if (colorValueTypes === ObservableUIControlType.ColorRGBA) {
                        outMap[time] = [ red, green, blue, alpha ];
                    } else {
                        outMap[time] = [ red, green, blue ];
                    }
                }
                const outJSON = JSON.stringify(outMap);
                _schemaInterface.debug(`Rebuilding container object: ${outJSON}`);
                const isInserted = this._insertDataIntoOriginalObject(group.path, outMap, _actualData, ObservableUIControlType.ColorTimeline, OpNodeSourceType.MAP);
                if (isInserted && _dataItemChangedCallback) {
                    _dataItemChangedCallback();
                }
            };
            this._uiCurrentTime = (0, server_editor_namespaceObject.makeObservable)(.4);
            this._uiControl = this._uiPropertyPane.addColorTimeline(this._uiCurrentTime, {
                entries: dataTable,
                onNodeAdded: node => {
                    _schemaInterface._debug?.(`Node added: ${node.id}`);
                    _rebuildContainerObject(this._uiControl.getData());
                },
                onNodeChanged: node => {
                    _schemaInterface._debug?.(`Node changed: ${node.id}`);
                    _rebuildContainerObject(this._uiControl.getData());
                },
                onNodeRemoved: node => {
                    _schemaInterface._debug?.(`Node removed: ${node.id}`);
                    _rebuildContainerObject(this._uiControl.getData());
                },
                onTimeChanged: (time, _prev) => {
                    _schemaInterface._debug?.(`Time changed: ${time}`);
                    if (this._isTimelinePreview) {
                        let gameTime = (time * 24e3 + 6e3) % 24e3;
                        if (gameTime < 0) {
                            gameTime += 24e3;
                        }
                        server_namespaceObject.system.sendScriptEvent("editor:agfxPreview:timeChanged", gameTime.toString());
                    }
                }
            });
        }
    }
    class DataItemGroupUIControlNumberTimeline extends DataItemGroupUIControlBase {
        get type() {
            return DataItemGroupType.NumberTimeline;
        }
        get group() {
            return this._group;
        }
        constructor(group, _rootPane, _observables, _actualData, _schemaInterface, _dataItemChangedCallback, _helpString) {
            super();
            this._isTimelinePreview = false;
            this._group = group;
            const displayName = group.displayName;
            const displayExpander = true;
            const toolTip = {
                title: displayName,
                description: [ _helpString ?? "" ]
            };
            this._uiPropertyPane = _rootPane.createSubPane({
                title: displayName,
                hasExpander: displayExpander,
                collapsed: true,
                infoTooltip: _helpString !== undefined ? toolTip : undefined
            });
            if (!this._uiPropertyPane) {
                throw new Error("Failed to create property pane");
            }
            this._isTimelinePreview = group.tags.find((tag => tag === "previewTime")) !== undefined;
            const unsorted = group.tags.find((tag => tag === "unsorted")) !== undefined;
            if (!unsorted) {
                this.group.dataItems.sort(((a, b) => a._displayName.localeCompare(b._displayName)));
            }
            const dataTable = [];
            let itemIndex = 0;
            let minValueBounds;
            let maxValueBounds;
            let minValueFound = Number.MAX_SAFE_INTEGER;
            let maxValueFound = Number.MIN_SAFE_INTEGER;
            for (const item of this.group.dataItems) {
                if (item._observableControlType !== ObservableUIControlType.Number) {
                    throw new Error(`NumberTimeline control can only contain number data items.  Item ${item._observableName} is a ${item._observableControlType}`);
                }
                item._setOriginalJSONData = (_o, _p, _v) => {};
                if (item._min !== undefined) {
                    if (item._min < minValueFound) {
                        minValueBounds = item._min;
                    }
                }
                if (item._max !== undefined) {
                    if (item._max > maxValueFound) {
                        maxValueBounds = item._max;
                    }
                }
                const itemName = group.path + "/" + itemIndex.toString();
                const currentObservable = _observables[item._observableName];
                try {
                    let time = parseFloat(item._displayName);
                    if (time < 0 || time > 1) {
                        _schemaInterface.error(`Warning: Time value in the NumberTimeline container should be between 0 and 1 [${itemName} = ${time}]`);
                        time = Math.max(0, Math.min(1, time));
                    }
                    const itemValue = currentObservable.value;
                    if (itemValue < minValueFound) {
                        minValueFound = itemValue;
                    }
                    if (itemValue > maxValueFound) {
                        maxValueFound = itemValue;
                    }
                    dataTable.push({
                        id: itemName,
                        time,
                        value: currentObservable.value
                    });
                    _schemaInterface.debug(`Adding Key/Number property: ${itemName} -- [${time} = ${JSON.stringify(currentObservable.value)}]`);
                } catch (_e) {
                    _schemaInterface.error(`Failed to parse time value for item ${item._observableName} - ${VibrantVisualsBiome_stringFromException(_e)}`);
                    throw new Error("NumberTimeline control only supports numeric key values");
                }
                ++itemIndex;
            }
            const _rebuildContainerObject = _dataItems => {
                const outMap = {};
                for (const item of _dataItems) {
                    const time = item.time;
                    const value = item.value;
                    outMap[time] = value;
                }
                const outJSON = JSON.stringify(outMap);
                _schemaInterface.debug(`Rebuilding container object: ${outJSON}`);
                const isInserted = this._insertDataIntoOriginalObject(group.path, outMap, _actualData, ObservableUIControlType.NumberTimeline, OpNodeSourceType.MAP);
                if (isInserted && _dataItemChangedCallback) {
                    _dataItemChangedCallback();
                }
            };
            this._uiCurrentTime = (0, server_editor_namespaceObject.makeObservable)(.4);
            if (minValueBounds === undefined) {
                minValueBounds = minValueFound;
            }
            if (maxValueBounds === undefined) {
                maxValueBounds = maxValueFound;
            }
            this._uiControl = this._uiPropertyPane.addNumberTimeline(this._uiCurrentTime, {
                entries: dataTable,
                bounds: {
                    minValue: minValueBounds,
                    maxValue: maxValueBounds
                },
                gridSeparatorStepCount: {
                    x: .1,
                    y: 10
                },
                gridSeparatorSliceCount: {
                    x: 5,
                    y: 5
                },
                onNodeAdded: node => {
                    _schemaInterface._debug?.(`Node added: ${node.id}`);
                    _rebuildContainerObject(this._uiControl.getData());
                },
                onNodeChanged: node => {
                    _schemaInterface._debug?.(`Node changed: ${node.id}`);
                    _rebuildContainerObject(this._uiControl.getData());
                },
                onNodeRemoved: node => {
                    _schemaInterface._debug?.(`Node removed: ${node.id}`);
                    _rebuildContainerObject(this._uiControl.getData());
                },
                onTimeChanged: (time, _prev) => {
                    _schemaInterface._debug?.(`Time changed: ${time}`);
                    if (this._isTimelinePreview) {
                        server_namespaceObject.system.sendScriptEvent("editor:agfxPreview:timeChanged", (time * 24e3).toString());
                    }
                }
            });
        }
    }
    var DataItemGroupType;
    (function(DataItemGroupType) {
        DataItemGroupType[DataItemGroupType["PropertyPane"] = 0] = "PropertyPane";
        DataItemGroupType[DataItemGroupType["ColorTimeline"] = 1] = "ColorTimeline";
        DataItemGroupType[DataItemGroupType["NumberTimeline"] = 2] = "NumberTimeline";
    })(DataItemGroupType || (DataItemGroupType = {}));
    class DataItemGroup {
        constructor(_displayName, _path, _parentGroup, _type, _tags, _editorControlType, _helpString) {
            this._tags = [];
            this._displayName = _displayName;
            this._path = _path;
            this._dataItems = [];
            this._parentGroup = _parentGroup;
            this._logicalGroupOnly = false;
            this._type = _type;
            this._tags = _tags;
            this._helpString = _helpString;
            switch (_editorControlType ?? OpNodeEditorUIControlType.UNKNOWN) {
              case OpNodeEditorUIControlType.COLOR_TIMELINE:
                this._groupType = DataItemGroupType.ColorTimeline;
                break;

              case OpNodeEditorUIControlType.NUMBER_TIMELINE:
                this._groupType = DataItemGroupType.NumberTimeline;
                break;

              default:
                this._groupType = DataItemGroupType.PropertyPane;
            }
        }
        get displayName() {
            return this._displayName;
        }
        get path() {
            return this._path;
        }
        get containerBounds() {
            return this._containerBounds;
        }
        set containerBounds(value) {
            this._containerBounds = value;
        }
        get propertyPane() {
            if (this._UIControl && this._UIControl.type === DataItemGroupType.PropertyPane) {
                return this._UIControl.propertyPane;
            }
            return undefined;
        }
        get logicalGroupOnly() {
            return this._logicalGroupOnly;
        }
        set logicalGroupOnly(value) {
            this._logicalGroupOnly = value;
        }
        get type() {
            return this._type;
        }
        get groupType() {
            return this._groupType;
        }
        get dataItems() {
            return this._dataItems;
        }
        get tags() {
            return this._tags;
        }
        createPropertyPane(_rootPane, _observables, _actualData, _schemaInterface, _dataItemChangedCallback) {
            if (this._parentGroup) {
                if (this._parentGroup.propertyPane) {
                    _rootPane = this._parentGroup.propertyPane;
                }
            }
            if (!_rootPane) {
                throw new Error(`Missing parent property pane`);
            }
            if (this._UIControl) {
                throw new Error("Property pane already created");
            }
            this._UIControl = new DataItemGroupUIControlPropertyPane(this, this._parentGroup !== undefined, _rootPane, _observables, _actualData, _schemaInterface, _dataItemChangedCallback, this._helpString);
        }
        createColorTimeline(_rootPane, _observables, _actualData, _schemaInterface, _dataItemChangedCallback) {
            if (this._parentGroup) {
                if (this._parentGroup.propertyPane) {
                    _rootPane = this._parentGroup.propertyPane;
                }
            }
            if (!_rootPane) {
                throw new Error(`Missing parent property pane`);
            }
            if (this._UIControl) {
                throw new Error("Property pane already created");
            }
            this._UIControl = new DataItemGroupUIControlColorTimeline(this, _rootPane, _observables, _actualData, _schemaInterface, _dataItemChangedCallback, this._helpString);
        }
        createNumberTimeline(_rootPane, _observables, _actualData, _schemaInterface, _dataItemChangedCallback) {
            if (this._parentGroup) {
                if (this._parentGroup.propertyPane) {
                    _rootPane = this._parentGroup.propertyPane;
                }
            }
            if (!_rootPane) {
                throw new Error(`Missing parent property pane`);
            }
            if (this._UIControl) {
                throw new Error("Property pane already created");
            }
            this._UIControl = new DataItemGroupUIControlNumberTimeline(this, _rootPane, _observables, _actualData, _schemaInterface, _dataItemChangedCallback, this._helpString);
        }
        addNumberDataItem(_displayName, _observableName, _originalType, _min, _max, _readonly, _helpString) {
            this._dataItems.push({
                _displayName,
                _observableName,
                _observableControlType: ObservableUIControlType.Number,
                _min,
                _max,
                _originalType,
                _uiCollectionComponent: false,
                _readonly: _readonly ?? false,
                _helpString
            });
        }
        addStringDataItem(_displayName, _observableName, _validationRegex, _readonly, _helpString) {
            this._dataItems.push({
                _displayName,
                _observableName,
                _observableControlType: ObservableUIControlType.String,
                _validationRegex,
                _originalType: OpNodeSourceType.STRING,
                _uiCollectionComponent: false,
                _readonly: _readonly ?? false,
                _helpString
            });
        }
        addSliderDataItem(_displayName, _observableName, _originalType, _min, _max, _helpString) {
            this._dataItems.push({
                _displayName,
                _observableName,
                _observableControlType: ObservableUIControlType.Slider,
                _min,
                _max,
                _originalType,
                _uiCollectionComponent: false,
                _readonly: false,
                _helpString
            });
        }
        addColorDataItem(_displayName, _observableName, size, _originalType, _uiCollectionComponent, _helpString) {
            this._dataItems.push({
                _displayName,
                _observableName,
                _observableControlType: size === 4 ? ObservableUIControlType.ColorRGBA : ObservableUIControlType.ColorRGB,
                _originalType,
                _uiCollectionComponent,
                _readonly: false,
                _helpString
            });
        }
        addVector3DataItem(_displayName, _observableName, _originalType, _min, _max, _readonly, _helpString) {
            this._dataItems.push({
                _displayName,
                _observableName,
                _observableControlType: ObservableUIControlType.Vector3,
                _originalType,
                _min,
                _max,
                _uiCollectionComponent: true,
                _readonly: _readonly ?? false,
                _helpString
            });
        }
        addDropdownDataItem(_displayName, _observableName, _originalType, _enums, _prettyEnums, _readonly, _helpString) {
            this._dataItems.push({
                _displayName,
                _observableName,
                _observableControlType: ObservableUIControlType.Dropdown,
                _originalType,
                _uiCollectionComponent: false,
                _readonly: _readonly ?? false,
                _enums,
                _prettyEnums,
                _helpString
            });
        }
        addCheckboxDataItem(_displayName, _observableName, _originalType, _readonly, _helpString) {
            this._dataItems.push({
                _displayName,
                _observableName,
                _observableControlType: ObservableUIControlType.Checkbox,
                _originalType,
                _uiCollectionComponent: false,
                _readonly: _readonly ?? false,
                _helpString
            });
        }
        restoreData(_observables, _defaultObservable) {
            for (const item of this._dataItems) {
                const path = item._observableName;
                const newValue = _defaultObservable[path];
                if (item._setOriginalJSONData) {
                    item._setOriginalJSONData(_observables, path, newValue);
                }
            }
        }
    }
    class UIComponentMap {
        constructor(session, data) {
            this._editableProperties = {};
            this._groups = [];
            this._session = session;
            this._dirty = false;
            this._reverting = false;
            this._currentData = JSON.parse(JSON.stringify(data));
        }
        get dirty() {
            return this._dirty;
        }
        set dirty(value) {
            this._dirty = value;
        }
        get reverting() {
            return this._reverting;
        }
        set reverting(value) {
            this._reverting = value;
        }
        get currentData() {
            return this._currentData;
        }
        _findGroupFromPath(path) {
            const lastSlash = path.lastIndexOf("/");
            if (lastSlash <= 0) {
                return undefined;
            }
            const parentPath = path.slice(0, lastSlash);
            for (const group of this._groups) {
                if (group.path === parentPath) {
                    return group;
                }
            }
            throw new Error(`Failed to find a parent group for a non-root data item (${path})`);
            return undefined;
        }
        addDataItem(_path, _key, _type, _data, _properties) {
            let parentGroup = this._findGroupFromPath(_path);
            const fnConvertNodeTypeToDefaultEditor = _type => {
                switch (_type) {
                  case OpNodeSourceType.STRING:
                    return OpNodeEditorUIControlType.TEXT;

                  case OpNodeSourceType.NUMBER:
                  case OpNodeSourceType.INTEGER:
                    return OpNodeEditorUIControlType.FLOAT;

                  case OpNodeSourceType.BOOLEAN:
                    return OpNodeEditorUIControlType.CHECKBOX;

                  default:
                    return OpNodeEditorUIControlType.UNKNOWN;
                }
            };
            let editorControl = fnConvertNodeTypeToDefaultEditor(_type);
            const editorProperty = _properties.getProperty("OpPropertyEditorUIControl");
            if (editorProperty) {
                editorControl = editorProperty.controlType;
            }
            const labelAliases = _properties.getProperty("OpPropertyLabelAliases");
            const prettify = _properties.getProperty("OpPropertyPrettifier");
            const tagsProperty = _properties.getProperty("OpPropertyTags");
            const helpProperty = _properties.getProperty("OpPropertyHelp");
            const helpString = helpProperty?.help ?? undefined;
            const aliasAndPrettify = _key => {
                const alias = labelAliases?.getLabelAlias(_key) ?? _key;
                const displayName = prettify?.prettify(alias) ?? alias;
                return displayName;
            };
            const displayName = aliasAndPrettify(_key);
            if (_type === OpNodeSourceType.NULL) {
                throw new Error("I don't know what to do with nulls");
            } else if (_type === OpNodeSourceType.OBJECT || _type === OpNodeSourceType.ARRAY || _type === OpNodeSourceType.MAP) {
                const tags = tagsProperty?.tags ?? [];
                this._groups.push(new DataItemGroup(displayName, _path, parentGroup, _type, tags, editorControl, helpString));
                const containerBounds = {
                    min: 0,
                    max: 0
                };
                const arrayBoundsProperty = _properties.getProperty("OpPropertyArrayBounds");
                if (arrayBoundsProperty) {
                    if (arrayBoundsProperty.minItems !== undefined) {
                        containerBounds.min = arrayBoundsProperty.minItems;
                    }
                    if (arrayBoundsProperty.maxItems !== undefined) {
                        containerBounds.max = arrayBoundsProperty.maxItems;
                    }
                } else {
                    const mapBoundsProperty = _properties.getProperty("OpPropertyMapBounds");
                    if (mapBoundsProperty) {
                        if (mapBoundsProperty.minProperties !== undefined) {
                            containerBounds.min = mapBoundsProperty.minProperties;
                        }
                        if (mapBoundsProperty.maxProperties !== undefined) {
                            containerBounds.max = mapBoundsProperty.maxProperties;
                        }
                    }
                }
                if (editorControl === OpNodeEditorUIControlType.COLOR || editorControl === OpNodeEditorUIControlType.VECTOR3) {
                    if (containerBounds.min !== containerBounds.max || containerBounds.min !== 3 && containerBounds.min !== 4) {
                        throw new Error(`Container bounds not specified - Path(${_path}), Key(${_key}) -- minItems and maxItems MUST be specified in the schema`);
                    }
                }
                if (editorControl === OpNodeEditorUIControlType.COLOR) {
                    this._groups[this._groups.length - 1].containerBounds = containerBounds;
                    this._groups[this._groups.length - 1].logicalGroupOnly = true;
                    const color = {
                        Red: 0,
                        Green: 0,
                        Blue: 0,
                        Alpha: 0
                    };
                    this._editableProperties[_path] = (0, server_editor_namespaceObject.makeObservable)(color);
                } else if (editorControl === OpNodeEditorUIControlType.VECTOR3) {
                    this._groups[this._groups.length - 1].containerBounds = containerBounds;
                    this._groups[this._groups.length - 1].logicalGroupOnly = true;
                    const vec3 = {
                        x: 0,
                        y: 0,
                        z: 0
                    };
                    this._editableProperties[_path] = (0, server_editor_namespaceObject.makeObservable)(vec3);
                } else if (editorControl === OpNodeEditorUIControlType.COLOR_TIMELINE) {
                    this._groups[this._groups.length - 1].containerBounds = containerBounds;
                    this._groups[this._groups.length - 1].logicalGroupOnly = true;
                } else if (editorControl === OpNodeEditorUIControlType.NUMBER_TIMELINE) {
                    this._groups[this._groups.length - 1].containerBounds = containerBounds;
                    this._groups[this._groups.length - 1].logicalGroupOnly = true;
                }
            } else {
                if (!parentGroup) {
                    const tags = tagsProperty?.tags ?? [];
                    const groupIndex = this._groups.push(new DataItemGroup("", _path, undefined, OpNodeSourceType.NULL, tags, OpNodeEditorUIControlType.UNKNOWN));
                    parentGroup = this._groups[groupIndex - 1];
                }
                if (_type !== OpNodeSourceType.STRING && _type !== OpNodeSourceType.NUMBER && _type !== OpNodeSourceType.INTEGER && _type !== OpNodeSourceType.BOOLEAN) {
                    return;
                }
                this._editableProperties[_path] = (0, server_editor_namespaceObject.makeObservable)(_data);
                const regexValidator = _properties.getProperty("OpPropertyPattern")?.pattern;
                const valueMin = _properties.getProperty("OpPropertyValueRange")?.min;
                const valueMax = _properties.getProperty("OpPropertyValueRange")?.max;
                const readonly = _properties.hasProperty("OpPropertyReadOnly");
                switch (editorControl) {
                  case OpNodeEditorUIControlType.COLOR_TIMELINE:
                  case OpNodeEditorUIControlType.NUMBER_TIMELINE:
                    break;

                  case OpNodeEditorUIControlType.FLOAT:
                    parentGroup.addNumberDataItem(displayName, _path, _type, valueMin, valueMax, readonly, helpString);
                    break;

                  case OpNodeEditorUIControlType.SLIDER:
                    parentGroup.addSliderDataItem(displayName, _path, _type, valueMin, valueMax, helpString);
                    break;

                  case OpNodeEditorUIControlType.TEXT:
                    parentGroup.addStringDataItem(displayName, _path, regexValidator, readonly, helpString);
                    break;

                  case OpNodeEditorUIControlType.CHECKBOX:
                    parentGroup.addCheckboxDataItem(displayName, _path, _type, readonly, helpString);
                    break;

                  case OpNodeEditorUIControlType.COLOR:
                    {
                        const parentPath = parentGroup.path;
                        if (_type === OpNodeSourceType.NUMBER || _type === OpNodeSourceType.INTEGER) {
                            if (parentGroup.type !== OpNodeSourceType.ARRAY) {
                                throw new Error(`Associative container of named RGB values not yet implemented`);
                            }
                            const colorSize = parentGroup.containerBounds?.max;
                            if (!colorSize) {
                                throw new Error(`Array bounds not specified - Path(${_path}), Key(${_key})`);
                            }
                            const index = Number(_key);
                            if (index >= colorSize || index < 0) {
                                throw new Error(`Array bounds exceeded - Path(${_path}), Key(${_key})`);
                            } else if (index === colorSize - 1) {
                                const componentData = [];
                                for (let i = 0; i < colorSize; i++) {
                                    const colorComponentPath = `${parentPath}/${i}`;
                                    const colorComponent = this._editableProperties[colorComponentPath].value;
                                    if (typeof colorComponent !== "number") {
                                        throw new Error(`Invalid color component value at path ${colorComponentPath}`);
                                    }
                                    componentData.push(colorComponent / 255);
                                }
                                if (colorSize === 3) {
                                    componentData.push(1);
                                }
                                const color = {
                                    red: componentData[0],
                                    green: componentData[1],
                                    blue: componentData[2],
                                    alpha: componentData[3]
                                };
                                this._editableProperties[parentPath] = (0, server_editor_namespaceObject.makeObservable)(color);
                                const groupDisplayName = aliasAndPrettify(parentGroup.displayName);
                                const _grandparentGroup = this._findGroupFromPath(parentPath) ?? parentGroup;
                                _grandparentGroup.addColorDataItem(groupDisplayName, parentPath, colorSize, parentGroup.type, true, helpString);
                            }
                        } else if (_type === OpNodeSourceType.STRING) {
                            const colorString = String(_data);
                            const hexPattern = /^#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
                            if (!hexPattern.test(colorString)) {
                                throw new Error("Invalid color string format");
                            }
                            const componentData = [];
                            let colorSize = 0;
                            for (let i = 1; i < colorString.length; i += 2) {
                                const component = parseInt(colorString.substring(i, i + 2), 16);
                                componentData.push(component / 255);
                                ++colorSize;
                            }
                            if (colorSize === 3) {
                                componentData.push(1);
                            }
                            const color = {
                                red: componentData[0],
                                green: componentData[1],
                                blue: componentData[2],
                                alpha: componentData[3]
                            };
                            this._editableProperties[parentPath] = (0, server_editor_namespaceObject.makeObservable)(color);
                            const groupDisplayName = aliasAndPrettify(parentGroup.displayName);
                            const grandparentGroup = this._findGroupFromPath(parentPath) ?? parentGroup;
                            grandparentGroup.addColorDataItem(groupDisplayName, parentPath, colorSize, parentGroup.type, true, helpString);
                        }
                    }
                    break;

                  case OpNodeEditorUIControlType.VECTOR3:
                    {
                        const parentPath = parentGroup.path;
                        if (_type === OpNodeSourceType.NUMBER || _type === OpNodeSourceType.INTEGER) {
                            if (parentGroup.type !== OpNodeSourceType.ARRAY) {
                                throw new Error(`Associative container of named XYZ values not yet implemented`);
                            }
                            const index = Number(_key);
                            if (index >= 3 || index < 0) {
                                throw new Error(`Array bounds exceeded - Path(${_path}), Key(${_key})`);
                            } else if (index === 2) {
                                const componentData = [];
                                for (let i = 0; i < 3; i++) {
                                    const componentPath = `${parentPath}/${i}`;
                                    const componentValue = this._editableProperties[componentPath].value;
                                    if (typeof componentValue !== "number") {
                                        throw new Error(`Invalid vector3 component value at path ${componentPath}`);
                                    }
                                    componentData.push(componentValue);
                                }
                                const vec3 = {
                                    x: componentData[0],
                                    y: componentData[1],
                                    z: componentData[2]
                                };
                                this._editableProperties[parentPath] = (0, server_editor_namespaceObject.makeObservable)(vec3);
                                const groupDisplayName = aliasAndPrettify(parentGroup.displayName);
                                const _grandparentGroup = this._findGroupFromPath(parentPath) ?? parentGroup;
                                _grandparentGroup.addVector3DataItem(groupDisplayName, parentPath, parentGroup.type, valueMin, valueMax, readonly, helpString);
                            }
                        }
                    }
                    break;

                  case OpNodeEditorUIControlType.DROPDOWN:
                    {
                        const enumProperty = _properties.getProperty("OpPropertyEnum");
                        if (enumProperty === undefined) {
                            throw new Error("Control type is dropdown, but no enum values specified in schema");
                        }
                        enumProperty.prettifyEnums(aliasAndPrettify);
                        const comboItems = enumProperty.enums ?? [];
                        const prettyComboItems = enumProperty.prettyEnums ?? [];
                        const index = enumProperty.getIndexOf(String(_data));
                        if (index === -1) {
                            throw new Error("Invalid enum value in data");
                        }
                        this._editableProperties[_path] = (0, server_editor_namespaceObject.makeObservable)(index);
                        parentGroup.addDropdownDataItem(displayName, _path, _type, comboItems, prettyComboItems, readonly, helpString);
                    }
                    break;

                  default:
                    throw new Error(`Unknown control type encountered - ${JSON.stringify(editorControl)}`);
                }
            }
        }
        constructUIComponents(_rootPane, _schemaInterface) {
            if (this._currentData === undefined) {
                throw new Error("No data object to build UI components from");
            }
            if (_rootPane === undefined) {
                throw new Error("No root pane to build UI components in");
            }
            for (const group of this._groups) {
                switch (group.groupType) {
                  case DataItemGroupType.PropertyPane:
                    group.createPropertyPane(_rootPane, this._editableProperties, this._currentData, _schemaInterface, (() => {
                        this._dirty = true;
                    }));
                    break;

                  case DataItemGroupType.ColorTimeline:
                    group.createColorTimeline(_rootPane, this._editableProperties, this._currentData, _schemaInterface, (() => {
                        this._dirty = true;
                    }));
                    break;

                  case DataItemGroupType.NumberTimeline:
                    group.createNumberTimeline(_rootPane, this._editableProperties, this._currentData, _schemaInterface, (() => {
                        this._dirty = true;
                    }));
                    break;
                }
            }
        }
        saveDefaultProperties() {
            this._backupProperties = {};
            for (const prop in this._editableProperties) {
                this._backupProperties[prop] = this._editableProperties[prop].value;
            }
        }
        restoreProperties() {
            if (!this._backupProperties) {
                throw new Error(`back up properties are not defined`);
            }
            for (const group of this._groups) {
                group.restoreData(this._editableProperties, this._backupProperties);
            }
        }
    }
    var DeferredLightingTelemetry;
    (function(DeferredLightingTelemetry) {
        DeferredLightingTelemetry["ModeChanged"] = "ModeChanged";
        DeferredLightingTelemetry["ResetSettings"] = "ResetSettings";
        DeferredLightingTelemetry["ExportSettings"] = "ExportSettings";
        DeferredLightingTelemetry["ErrorDataTransfer"] = "ErrorDataTransfer";
    })(DeferredLightingTelemetry || (DeferredLightingTelemetry = {}));
    const USE_MCTOOLS_STAGING = false;
    const GLOBAL_ACCESSOR_CONFIGURATIONS = [ "deferred_lighting::shadows" ];
    class VibrantVisualsPerBiomeBehavior {
        _logInfo(message) {
            this._session.log.info(message);
        }
        _logError(message) {
            this._session.log.error(message, {
                channelMask: server_editor_namespaceObject.LogChannel.All
            });
        }
        _logDebug(message) {
            this._session.log.debug(message);
        }
        constructor(session) {
            this._errorCollection = [];
            this._collectionNamespaces = [];
            this._collectionNamespacesIndex = (0, server_editor_namespaceObject.makeObservable)(-1);
            this._collectionIdentifiers = [];
            this._newConfigDialogDropdownNamespaceIndex = (0, server_editor_namespaceObject.makeObservable)(-1);
            this._newConfigNewNamespace = (0, server_editor_namespaceObject.makeObservable)("");
            this._newConfigIdentifier = (0, server_editor_namespaceObject.makeObservable)("");
            this._importFieldText = (0, server_editor_namespaceObject.makeObservable)("");
            this._targetBiomeDropdownList = [];
            this._targetBiomeDropdownIndex = (0, server_editor_namespaceObject.makeObservable)(-1);
            this._targetBiomesByCurrentLocation = (0, server_editor_namespaceObject.makeObservable)(false);
            this._session = session;
            this._tickHandle = -1;
            this._asyncOperationWorking = false;
            this.telemetryManager = new TelemetryManager(session.extensionContext.player, TelemetrySource.DeferredLighting);
            this._schemaInterface = new logInterface;
            this._schemaInterface._debug = _msg => {};
            this._schemaInterface._error = _msg => {
                this._logError(_msg);
                this._errorCollection.push(_msg);
            };
            this._schemaInterface._onStep = (_path, _key, _type, _data, _properties) => {
                this._schemaInterface.debug(`Step: Path(${_path}) - Key(${_key}) - Type(${_type}) - Data(${JSON.stringify(_data)}), Properties(${_properties.toString()})`);
                this._uiComponentMap?.addDataItem(_path, _key, _type, _data, _properties);
            };
            this._transferManager = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(this._session.extensionContext.player).dataTransfer;
            this._accessorList = this._transferManager.getRegisteredAccessors();
            this._rootPane = this._session.createPropertyPane({
                title: "resourcePack.editor.agfx.pane.title",
                uniqueId: "editor:pane:agfxSettingsBiome",
                infoTooltip: {
                    description: [ {
                        link: "https://aka.ms/BedrockEditorDeferredLighting",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            const currentGraphicsMode = this._session.extensionContext.settings.graphics.get(server_editor_namespaceObject.GraphicsSettingsProperty.GraphicsMode);
            const isDeferredRenderingEnabled = (0, server_editor_namespaceObject.makeObservable)(currentGraphicsMode === server_namespaceObject.GraphicsMode.Deferred);
            const loadingOverlay = this._rootPane.createModalOverlayPane();
            loadingOverlay.contentPane.addText("editor.vibrantVisuals.pane.graphicsProgress", {
                alignment: server_editor_namespaceObject.LayoutAlignment.Center,
                border: false
            });
            this._rootPane.addBool(isDeferredRenderingEnabled, {
                title: "resourcePack.editor.agfx.pane.deferredToggle",
                onChange: isDeferred => {
                    if (this._graphicsChangeHandle !== undefined) {
                        return;
                    }
                    loadingOverlay.show();
                    this._graphicsChangeHandle = server_namespaceObject.system.runTimeout((() => {
                        this._session.extensionContext.settings.graphics.set(server_editor_namespaceObject.GraphicsSettingsProperty.GraphicsMode, isDeferred ? server_namespaceObject.GraphicsMode.Deferred : server_namespaceObject.GraphicsMode.Fancy);
                    }), server_namespaceObject.TicksPerSecond);
                },
                variant: server_editor_namespaceObject.BoolPropertyItemVariant.ToggleSwitch,
                tooltip: "resourcePack.editor.agfx.pane.deferredToggle.tooltip"
            });
            this._rootPane.addText("resourcePack.editor.agfx.pane.enableText", {
                visible: !isDeferredRenderingEnabled.value
            });
            this._currentSettingNotPerBiomeText = this._rootPane.addText("The current Setting Group is a global configuration and is not configurable on a per-biome basis", {
                visible: isDeferredRenderingEnabled.value && this._currentAccessor !== undefined && this._isAccessorGlobalConfiguration(this._currentAccessor)
            });
            this._rootPane.addText("");
            this._rootSelectedAccessorIndex = (0, server_editor_namespaceObject.makeObservable)(-1);
            this._collectionIdentifierIndex = (0, server_editor_namespaceObject.makeObservable)(-1);
            this._targetBiomeDropdownList = server_namespaceObject.BiomeTypes.getAll();
            const listOfBiomes = server_namespaceObject.BiomeTypes.getAll().map(((v, index) => {
                const id = v.id.replace("minecraft:", "");
                const item = {
                    label: id.split("_").map((word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())).join(" "),
                    value: index
                };
                return item;
            }));
            this._rootSelectedAccessorIndex.set(this._accessorList.findIndex((value => value.uniqueId.includes("lighting_group"))));
            const accessor = this._accessorList[this._rootSelectedAccessorIndex.value];
            this._currentAccessor = accessor.uniqueId;
            this._targetBiomeDropdownIndex.set(listOfBiomes.findIndex((value => value.label.includes("Plains"))));
            this._currentBiome = "minecraft:plains";
            if (isDeferredRenderingEnabled.value) {
                this._fetchAndApplyBiomeConfig(this._targetBiomeDropdownList[this._targetBiomeDropdownIndex.value].id);
            }
            this._targetBiomeDropdownItem = this._rootPane.addDropdown(this._targetBiomeDropdownIndex, {
                title: "resourcePack.editor.vibrantVisuals.biome.targetBiome.title",
                tooltip: "resourcePack.editor.vibrantVisuals.biome.targetBiome.tooltip",
                enable: isDeferredRenderingEnabled.value,
                visible: isDeferredRenderingEnabled.value,
                entries: listOfBiomes,
                onChange: newValue => {
                    this._fetchAndApplyBiomeConfig(this._targetBiomeDropdownList[newValue].id);
                    this._currentBiome = this._targetBiomeDropdownList[newValue].id;
                }
            });
            this._targetBiomeCheckbox = this._rootPane.addBool(this._targetBiomesByCurrentLocation, {
                title: "resourcePack.editor.vibrantVisuals.biome.targetBiomeByLocation.title",
                tooltip: "resourcePack.editor.vibrantVisuals.biome.targetBiomeByLocation.tooltip",
                visible: isDeferredRenderingEnabled.value,
                onChange: newValue => {
                    this._targetBiomeDropdownItem.enable = !newValue;
                }
            });
            this._locationUpdateHandle = server_namespaceObject.system.runInterval((() => {
                if (!isDeferredRenderingEnabled.value) {
                    return;
                }
                if (!this._targetBiomesByCurrentLocation.value) {
                    return;
                }
                const playerLocation = lib.Vector3Utils.floor(this._session.extensionContext.player.location);
                const biome = server_namespaceObject.world.getDimension(this._session.extensionContext.player.dimension.id).getBiome(playerLocation);
                if (this._targetBiomeDropdownIndex.value !== -1 && this._targetBiomeDropdownList[this._targetBiomeDropdownIndex.value].id === biome.id) {
                    return;
                }
                const index = this._targetBiomeDropdownList.findIndex((val => val.id === biome.id));
                this._targetBiomeDropdownIndex.set(index);
                this._fetchAndApplyBiomeConfig(this._targetBiomeDropdownList[index].id);
            }), 20);
            this._collectionNamespacesDropdownElement = this._rootPane.addDropdown(this._collectionNamespacesIndex, {
                title: "resourcePack.editor.vibrantVisuals.biome.nameSpaceForBiomeSelector.title",
                tooltip: "resourcePack.editor.vibrantVisuals.biome.nameSpaceForBiomeSelector.tooltip",
                entries: [],
                enable: false,
                visible: isDeferredRenderingEnabled.value,
                onChange: newValue => {
                    this._currentCollectionNamespace = this._collectionNamespaces[newValue];
                    if (this._currentAccessor) {
                        const elements = this._collectionIdentifiers.filter((value => {
                            if (this._currentCollectionNamespace) {
                                return this._getNamespace(value) === this._currentCollectionNamespace;
                            }
                            return this._currentAccessor && this._isAccessorGlobalConfiguration(this._currentAccessor);
                        }));
                        const mappedElements = elements.map(((name, index) => {
                            const item = {
                                label: this._cleanIdentifierString(name),
                                value: Number(index)
                            };
                            return item;
                        }));
                        if (elements && elements.length > 0 && this._currentAccessor) {
                            this._collectionIdentifiersElement?.updateEntries(mappedElements);
                            this._collectionIdentifierIndex.set(0);
                            this._changeCollectionIdentifier(this._transferManager, this._currentAccessor, elements[0]);
                            this._changeBiomeMapping();
                        }
                    }
                }
            });
            this._collectionIdentifiersElement = this._rootPane.addDropdown(this._collectionIdentifierIndex, {
                title: "resourcePack.editor.vibrantVisuals.biome.configSetForBiomeSelector.title",
                tooltip: "resourcePack.editor.vibrantVisuals.biome.configSetForBiomeSelector.tooltip",
                entries: [],
                visible: isDeferredRenderingEnabled.value,
                enable: false,
                onChange: (newValue, oldValue) => {
                    const oldIndex = oldValue;
                    const newIndex = newValue;
                    if (oldIndex === newIndex) {
                        return;
                    }
                    if (!this._currentAccessor) {
                        return;
                    }
                    if (this._asyncOperationWorking) {
                        this._logInfo("Async operation already in progress - ignoring request for now");
                        this._collectionIdentifierIndex.set(oldIndex);
                        return;
                    }
                    if (this._collectionIdentifierIndex.value < 0 || this._collectionIdentifierIndex.value >= this._collectionIdentifiers.length) {
                        this._logError("Invalid accessor index selected - this shouldn't be possible");
                        return;
                    }
                    const label = this._collectionIdentifiersElement.getEntryByIndex(newValue)?.label;
                    if (!label) {
                        return;
                    }
                    let identifier = this._prettyToProperIdentifierString(label);
                    identifier = `${this._currentCollectionNamespace}:${identifier}`;
                    const accessor = this._accessorList[this._rootSelectedAccessorIndex.value];
                    this._currentAccessor = accessor.uniqueId;
                    this._currentIdentifier = identifier;
                    this._changeCollectionIdentifier(this._transferManager, accessor.uniqueId, identifier);
                    this._changeBiomeMapping();
                    this.telemetryManager.fireTelemetryEvent(DeferredLightingTelemetry.ModeChanged, {
                        mode: accessor.uniqueId
                    });
                }
            });
            this._exportBiomeConfigMapping = this._rootPane.addButton((() => {
                if (this._biomeConfigData !== undefined) {
                    this._logInfo("Exporting current biome mappings to clipboard");
                    const data = JSON.stringify(this._buildBiomeJSON(this._currentBiome, this._biomeConfigData), undefined, 2);
                    this._transferManager.sendDataToClipboard(data);
                    this.telemetryManager.fireTelemetryEvent(DeferredLightingTelemetry.ExportSettings);
                }
            }), {
                title: "resourcePack.editor.vibrantVisuals.pane.exportBiomeToClipboard.title",
                tooltip: "resourcePack.editor.vibrantVisuals.pane.exportBiomeToClipboard.tooltip",
                visible: isDeferredRenderingEnabled.value && this._currentAccessor !== undefined && !this._isAccessorGlobalConfiguration(this._currentAccessor),
                icon: "pack://textures/editor/VV-Copy-Clipboard.png?filtering=point",
                shrinkToIcon: true
            });
            this._rootPane.addDivider().visible = isDeferredRenderingEnabled.value;
            this._rootPane.onPropertyPaneVisibilityUpdated.subscribe((eventData => {
                if (eventData.isVisible && this._currentAccessor !== undefined) {
                    const accessorName = this._currentAccessor;
                    this._startDirtyWatcher(this._transferManager, accessorName);
                } else {
                    this._stopDirtyWatcher(this._transferManager, this._currentAccessor);
                }
            }));
            const accessorDropdownItems = this._accessorList.map(((v, i) => {
                const item = {
                    label: v.nameStringId,
                    value: i
                };
                return item;
            }));
            this._accessorListPropertyItem = this._rootPane.addDropdown(this._rootSelectedAccessorIndex, {
                title: "resourcePack.editor.vibrantVisuals.biome.settingGroup.title",
                tooltip: "resourcePack.editor.vibrantVisuals.biome.settingGroup.tooltip",
                entries: accessorDropdownItems,
                visible: isDeferredRenderingEnabled.value,
                enable: false,
                onChange: (newValue, oldValue, items) => {
                    const oldIndex = oldValue;
                    const newIndex = newValue;
                    if (oldIndex === newIndex) {
                        return;
                    }
                    if (this._asyncOperationWorking) {
                        this._logInfo("Async operation already in progress - ignoring request for now");
                        this._rootSelectedAccessorIndex.set(oldIndex);
                        return;
                    }
                    if (this._rootSelectedAccessorIndex.value < 0 || this._rootSelectedAccessorIndex.value >= this._accessorList.length) {
                        this._logError("Invalid accessor index selected - this shouldn't be possible");
                        return;
                    }
                    const accessor = this._accessorList[this._rootSelectedAccessorIndex.value];
                    this._currentAccessor = accessor.uniqueId;
                    this._changeDataAccessor(this._transferManager, accessor.uniqueId);
                    this.telemetryManager.fireTelemetryEvent(DeferredLightingTelemetry.ModeChanged, {
                        mode: accessor.uniqueId
                    });
                }
            });
            this._rootPane.addDivider().visible = isDeferredRenderingEnabled.value;
            const buttonPane = this._rootPane.addButtonPane({
                itemMinWidth: 2
            });
            const validateNamespace = namespace => {
                if (namespace.includes("minecraft")) {
                    return {
                        valid: false,
                        message: "Cannot use minecraft as a namespace"
                    };
                }
                return validateIdentifierString(namespace);
            };
            this._newConfigDialog = this._session.dialogManager.registerDialog({
                uniqueId: "vvbiome:newConfigDialog",
                width: 80,
                title: "resourcePack.editor.vibrantVisuals.newDialogPane.title"
            });
            this._newConfigDialogNamespacesDropdownElement = this._newConfigDialog.contentPane.addDropdown(this._newConfigDialogDropdownNamespaceIndex, {
                title: "resourcePack.editor.vibrantVisuals.newDialogPane.namespaceDropdown.title",
                entries: [],
                enable: true,
                visible: isDeferredRenderingEnabled.value,
                inlineLabel: false,
                onChange: newValue => {
                    this._newConfigNewNamespace.set("");
                }
            });
            this._newConfigDialog.contentPane.addString(this._newConfigNewNamespace, {
                title: "resourcePack.editor.vibrantVisuals.newDialogPane.newNamespace.title",
                inlineLabel: false,
                tooltip: "resourcePack.editor.vibrantVisuals.newDialogPane.newNamespace.tooltip",
                onChange: newValue => {
                    if (newValue !== "") {
                        this._newConfigDialogDropdownNamespaceIndex.set(-1);
                        this._newConfigDialogNamespacesDropdownElement.enable = false;
                    } else {
                        this._newConfigDialogNamespacesDropdownElement.enable = true;
                    }
                }
            });
            this._newConfigDialog.contentPane.addString(this._newConfigIdentifier, {
                title: "resourcePack.editor.vibrantVisuals.newDialogPane.newConfig.title",
                inlineLabel: false,
                tooltip: "resourcePack.editor.vibrantVisuals.newDialogPane.newConfig.tooltip"
            });
            this._importField = this._newConfigDialog.contentPane.addString(this._importFieldText, {
                title: "resourcePack.editor.vibrantVisuals.newDialogPane.newConfig.importJSON.title",
                tooltip: "resourcePack.editor.vibrantVisuals.newDialogPane.newConfig.importJSON.tooltip",
                inlineLabel: false,
                visible: false,
                enable: false
            });
            const newConfigDialogButtonPane = this._newConfigDialog.controlPane.addButtonPane();
            newConfigDialogButtonPane.addButton((() => {
                const dialogDropdownNamespace = this._newConfigDialogNamespacesDropdownElement.getEntryByIndex(this._newConfigDialogDropdownNamespaceIndex.value)?.label;
                const namespaceString = dialogDropdownNamespace ?? this._newConfigNewNamespace.value;
                const identifierString = this._newConfigIdentifier.value;
                const validNamespaceRes = validateNamespace(namespaceString);
                const validIdentifierRes = validateIdentifierString(identifierString);
                if (!validNamespaceRes.valid && validNamespaceRes.message) {
                    this._session.log.error(validNamespaceRes.message, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    return;
                }
                if (!validIdentifierRes.valid && validIdentifierRes.message) {
                    this._session.log.error(validIdentifierRes.message, {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                    return;
                }
                if (!this._uiComponentMap || !this._currentAccessor) {
                    return;
                }
                let data = "";
                const importing = this._importField.visible && this._importField.enable;
                if (importing) {
                    data = this._importFieldText.value;
                } else {
                    data = JSON.stringify(this._uiComponentMap.currentData);
                }
                const fullIdentifier = `${namespaceString}:${identifierString}`;
                this._transferManager.createSetting(this._currentAccessor, fullIdentifier, data, false).then((resp => {
                    if (resp.success) {
                        if (!this._currentAccessor) {
                            return;
                        }
                        this._transferManager.requestIdentifiers(this._currentAccessor).then((data => {
                            if (!this._currentAccessor) {
                                return;
                            }
                            this._collectionIdentifiers = data.identifiers;
                            this._collectionNamespaces.length = 0;
                            this._collectionIdentifiersElement.enable = true;
                            this._newSettingButton.enable = true;
                            for (const identifier of this._collectionIdentifiers) {
                                const charIndex = identifier.indexOf(":");
                                const str = identifier.substring(0, charIndex);
                                if (!this._collectionNamespaces.includes(str)) {
                                    this._collectionNamespaces.push(str);
                                }
                            }
                            this._collectionNamespacesDropdownElement.updateEntries(this._collectionNamespaces.map(((value, index) => {
                                const item = {
                                    label: value,
                                    value: index
                                };
                                return item;
                            })));
                            const creatableEntries = this._collectionNamespaces.filter((value => !value.includes("minecraft")));
                            this._newConfigDialogNamespacesDropdownElement.updateEntries(creatableEntries.map(((value, index) => {
                                const item = {
                                    label: value,
                                    value: index
                                };
                                return item;
                            })));
                            this._newConfigDialogNamespacesDropdownElement.enable = creatableEntries.length !== 0;
                            const initialIndex = this._collectionNamespaces.findIndex((value => value === namespaceString));
                            this._collectionNamespacesIndex.set(initialIndex);
                            this._currentCollectionNamespace = this._collectionNamespaces[initialIndex];
                            this._collectionNamespacesDropdownElement.enable = true;
                            const elements = this._collectionIdentifiers.filter((value => {
                                if (this._currentCollectionNamespace) {
                                    return this._getNamespace(value) === this._currentCollectionNamespace;
                                }
                                return this._currentAccessor && this._isAccessorGlobalConfiguration(this._currentAccessor);
                            }));
                            const mappedElements = elements.map(((name, index) => {
                                const item = {
                                    label: this._cleanIdentifierString(name),
                                    value: Number(index)
                                };
                                return item;
                            }));
                            if (elements && elements.length > 0 && this._currentAccessor) {
                                this._collectionIdentifiersElement?.updateEntries(mappedElements);
                                const index = elements.findIndex((value => value === fullIdentifier));
                                this._collectionIdentifierIndex.set(index);
                                this._currentIdentifier = fullIdentifier;
                                this._changeCollectionIdentifier(this._transferManager, this._currentAccessor, fullIdentifier);
                                this._changeBiomeMapping();
                            }
                        })).catch((e => {
                            this._schemaInterface.error(`Failed to transfer data from client - ${VibrantVisualsBiome_stringFromException(e)}`);
                        }));
                    } else {
                        if (importing) {
                            this._schemaInterface.error(`Failed to create new setting - unable to read provided JSON for the current setting group.`);
                        } else {
                            this._schemaInterface.error(`Failed to transfer data from client - ${resp.message}`);
                        }
                    }
                })).catch((err => {
                    this._schemaInterface.error(`Failed to create new setting - ${VibrantVisualsBiome_stringFromException(err)}`);
                }));
                this._newConfigDialog.sendDismiss();
            }), {
                title: "resourcePack.editor.vibrantVisuals.newDialogPane.newConfig.save.title"
            });
            newConfigDialogButtonPane.addButton((() => {
                this._newConfigDialog.sendDismiss();
            }), {
                title: "resourcePack.editor.vibrantVisuals.newDialogPane.newConfig.cancel.title"
            });
            this._newSettingButton = buttonPane.addButton((() => {
                this._newConfigDialogDropdownNamespaceIndex.set(-1);
                this._newConfigNewNamespace.set("");
                this._newConfigIdentifier.set("");
                this._importFieldText.set("");
                this._importField.enable = false;
                this._importField.visible = false;
                this._session.dialogManager.activateDialog({
                    dialogId: "vvbiome:newConfigDialog"
                });
            }), {
                title: "resourcePack.editor.vibrantVisuals.pane.newButton.title",
                tooltip: "resourcePack.editor.vibrantVisuals.pane.newButton.tooltip",
                icon: "plusIcon",
                enable: false,
                visible: isDeferredRenderingEnabled.value,
                shrinkToIcon: true
            });
            this._importButton = buttonPane.addButton((() => {
                this._newConfigDialogDropdownNamespaceIndex.set(-1);
                this._newConfigNewNamespace.set("");
                this._newConfigIdentifier.set("");
                this._importFieldText.set("");
                this._importField.enable = true;
                this._importField.visible = true;
                this._session.dialogManager.activateDialog({
                    dialogId: "vvbiome:newConfigDialog"
                });
            }), {
                title: "resourcePack.editor.vibrantVisuals.pane.importButton.title",
                tooltip: "resourcePack.editor.vibrantVisuals.newDialogPane.newConfig.importJSON.tooltip",
                visible: isDeferredRenderingEnabled.value,
                icon: "pack://textures/editor/VV-Import.png?filtering=point",
                shrinkToIcon: true,
                enable: false
            });
            buttonPane.addButton((() => {
                if (this._uiComponentMap !== undefined) {
                    this._logInfo("Exporting current settings to clipboard");
                    const data = JSON.stringify(this._uiComponentMap.currentData, undefined, 2);
                    this._transferManager.sendDataToClipboard(data);
                    this.telemetryManager.fireTelemetryEvent(DeferredLightingTelemetry.ExportSettings);
                }
            }), {
                tooltip: "resourcePack.editor.agfx.pane.settings.export_to_clipboard",
                visible: isDeferredRenderingEnabled.value,
                icon: "pack://textures/editor/VV-Copy-Clipboard.png?filtering=point",
                shrinkToIcon: true
            });
            buttonPane.addButton((() => {
                if (!this._biomeConfigData) {
                    return;
                }
                this._generateResourcePackPayload(this._transferManager, this._biomeConfigData).then((payload => {
                    const base64Payload = toBase64(payload);
                    const domain = USE_MCTOOLS_STAGING ? "https://silver-guide-3a7f4789.pages.github.io" : "https://mctools.dev";
                    const url = domain + "/#open=gp/dlStarter&updatesJson=" + base64Payload;
                    this._packPayload.set(url);
                    this._packLink.visible = true;
                })).catch((e => {
                    this._logError("Failed to cook resource pack payload - " + VibrantVisualsBiome_stringFromException(e));
                    this._buildErrorUI("Failed to cook resource pack payload");
                }));
            }), {
                tooltip: "resourcePack.editor.vibrantVisuals.pane.generatePacks",
                visible: isDeferredRenderingEnabled.value,
                icon: "pack://textures/editor/VV-Export.png?filtering=point",
                shrinkToIcon: true
            });
            this._packPayload = (0, server_editor_namespaceObject.makeObservable)("");
            this._packLink = this._rootPane.addLink(this._packPayload, {
                title: "Download Resource Pack"
            });
            this._packLink.visible = false;
            this._resetButton = buttonPane.addButton((() => {
                if (this._currentAccessor !== undefined && this._uiComponentMap !== undefined) {
                    this._destroySettingsPane();
                    this._uiComponentMap.reverting = true;
                    this._transferManager.requestData(this._currentAccessor, {
                        useSnapshot: true,
                        identifier: this._currentIdentifier
                    }).then((resp => {
                        if (resp.collectionName === this._currentAccessor) {
                            this._transferManager.sendData(this._currentAccessor, resp.data, {
                                identifier: this._currentIdentifier
                            });
                            this._buildSettingsPane(resp);
                        }
                    })).catch((() => {
                        this._buildErrorUI("Unable to revert Vibrant Visuals configuration");
                    }));
                    this.telemetryManager.fireTelemetryEvent(DeferredLightingTelemetry.ResetSettings);
                }
            }), {
                tooltip: "resourcePack.editor.vibrantVisuals.pane.settings.restoreDefault",
                enable: false,
                visible: isDeferredRenderingEnabled.value,
                icon: "pack://textures/editor/VV-Reset.png?filtering=point",
                shrinkToIcon: true
            });
            this._session.menuBar.getMenu(server_editor_namespaceObject.CoreMenuType.WorldOptions).then((menu => {
                this._menu = menu.addItem({
                    label: "resourcePack.editor.menuBar.vibrantVisuals.title",
                    uniqueId: "DeferredLightingSettingsMenuItem",
                    tooltip: "resourcePack.editor.menuBar.vibrantVisualsBiome.tooltip"
                }, this._session.actionManager.createAction({
                    actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                    onExecute: () => {
                        this._rootPane.show();
                    }
                }));
            })).catch((() => {
                this._logError("Failed to add root menu item for this tool");
            }));
            this._addActionBarItem();
        }
        _fetchAndApplyBiomeConfig(biomeId) {
            this._transferManager.requestBiomeConfig(biomeId).then((val => {
                this._biomeConfigData = {
                    ...val,
                    color_grading: val.colorGrading,
                    lighting_group: val.lightingGroup
                };
                if (this._rootSelectedAccessorIndex.value === -1) {
                    this._rootSelectedAccessorIndex.set(0);
                }
                this._accessorListPropertyItem.enable = true;
                const accessor = this._accessorList[this._rootSelectedAccessorIndex.value];
                this._currentAccessor = accessor.uniqueId;
                this._changeDataAccessor(this._transferManager, accessor.uniqueId);
            })).catch((err => {
                this._schemaInterface.error(`Failed to fetch biome config for ${biomeId}: ${VibrantVisualsBiome_stringFromException(err)}`);
            }));
        }
        _isAccessorGlobalConfiguration(accessor) {
            return GLOBAL_ACCESSOR_CONFIGURATIONS.includes(accessor);
        }
        async _generateResourcePackPayload(transferManager, biomeConfigData) {
            const rp = new Map;
            const prefix = "/resource_packs/samp_dlstarter/";
            const filepath_map = new Map([ [ "deferred_lighting::water_parameters", prefix + "water/water.json" ], [ "deferred_lighting::lighting_group", prefix + "lighting/global.json" ], [ "deferred_lighting::atmospheric_scattering", prefix + "atmospherics/atmospherics.json" ], [ "deferred_lighting::color_grading_parameters", prefix + "color_grading/color_grading.json" ], [ "deferred_lighting::point_lights", prefix + "point_lights/global.json" ], [ "deferred_lighting::shadows", prefix + "shadows/global.json" ], [ "deferred_lighting::cubemap", prefix + "cubemaps/cubemap.json" ] ]);
            const accessorList = transferManager.getRegisteredAccessors();
            for (const accessor of accessorList) {
                const accessorString = accessor.uniqueId.replace("deferred_lighting::", "");
                const accessorToConfigKeyMap = {
                    atmospheric_scattering: "atmospheric",
                    color_grading_parameters: "color_grading",
                    lighting_group: "lighting_group",
                    cubemap: "cubemap",
                    water_parameters: "water"
                };
                const configKey = accessorToConfigKeyMap[accessorString];
                let identifier = "";
                if (configKey && configKey in biomeConfigData) {
                    identifier = biomeConfigData[configKey];
                }
                try {
                    const agfxData = await transferManager.requestData(accessor.uniqueId, {
                        identifier
                    });
                    const destinationPath = filepath_map.get(accessor.uniqueId);
                    if (destinationPath === undefined) {
                        this._logError(`No destination path found for accessor ${accessor.uniqueId}`);
                        continue;
                    }
                    rp.set(destinationPath, agfxData.data);
                } catch (e) {
                    this._logError(`Failed to get data for accessor ${accessor.uniqueId} - ${VibrantVisualsBiome_stringFromException(e)}`);
                }
            }
            return JSON.stringify(Object.fromEntries(rp));
        }
        _buildErrorUI(msg) {
            if (this._settingsPane) {
                this._rootPane.removeSubPane(this._settingsPane);
                this._settingsPane = undefined;
            }
            this._settingsPane = this._rootPane.createSubPane({
                title: "resourcePack.editor.agfx.settings.error.title"
            });
            const errorMessages = msg.split("\n");
            for (const msg of errorMessages) {
                this._settingsPane.addText(msg, {
                    border: false
                });
            }
            this._asyncOperationWorking = false;
        }
        _changeDataAccessor(_transferManager, _accessorName) {
            if (this._asyncOperationWorking) {
                this._logError("Async operation already in progress - ignoring request");
                return;
            }
            this._errorCollection = [];
            this._destroySettingsPane();
            const isGlobalConfig = this._isAccessorGlobalConfiguration(_accessorName);
            this._currentSettingNotPerBiomeText.visible = isGlobalConfig;
            this._collectionIdentifiersElement.visible = !isGlobalConfig;
            this._targetBiomeCheckbox.visible = !isGlobalConfig;
            this._targetBiomeDropdownItem.visible = !isGlobalConfig;
            this._collectionNamespacesDropdownElement.visible = !isGlobalConfig;
            this._importButton.enable = !isGlobalConfig;
            this._exportBiomeConfigMapping.visible = !isGlobalConfig;
            _transferManager.requestIdentifiers(_accessorName).then((data => {
                this._collectionIdentifiers = data.identifiers;
                this._collectionNamespaces.length = 0;
                this._processCollectionChanges(_accessorName);
            })).catch((e => {
                this._schemaInterface.error(`Failed to transfer data from client - ${VibrantVisualsBiome_stringFromException(e)}`);
                this.telemetryManager.fireTelemetryEvent(DeferredLightingTelemetry.ErrorDataTransfer);
                this._buildErrorUI(this._errorCollection.join("\n"));
            }));
        }
        _processCollectionChanges(_accessorName) {
            this._collectionIdentifiersElement.enable = true;
            this._newSettingButton.enable = true;
            for (const identifier of this._collectionIdentifiers) {
                const namespace = this._getNamespace(identifier);
                if (!this._collectionNamespaces.includes(namespace)) {
                    this._collectionNamespaces.push(namespace);
                }
            }
            this._collectionNamespacesDropdownElement.updateEntries(this._collectionNamespaces.map(((value, index) => {
                const item = {
                    label: value,
                    value: index
                };
                return item;
            })));
            const creatableEntries = this._collectionNamespaces.filter((value => !value.includes("minecraft")));
            this._newConfigDialogNamespacesDropdownElement.updateEntries(creatableEntries.map(((value, index) => {
                const item = {
                    label: value,
                    value: index
                };
                return item;
            })));
            this._newConfigDialogNamespacesDropdownElement.enable = creatableEntries.length !== 0;
            if (!this._biomeConfigData) {
                return;
            }
            const accessorIndex = this._rootSelectedAccessorIndex.value;
            const currentAccessor = this._accessorList[accessorIndex];
            const biomeConfigIdentifier = Object.entries(this._biomeConfigData).find((val => currentAccessor.uniqueId.replace("deferred_lighting::", "").includes(val[0])))?.[1];
            let initialIndex = 0;
            if (!this._isAccessorGlobalConfiguration(_accessorName)) {
                initialIndex = this._collectionNamespaces.findIndex((value => value === this._getNamespace(biomeConfigIdentifier)));
            }
            this._collectionNamespacesIndex.set(initialIndex);
            this._currentCollectionNamespace = this._collectionNamespaces[initialIndex];
            this._collectionNamespacesDropdownElement.enable = true;
            const elements = this._collectionIdentifiers.filter((value => {
                if (this._currentCollectionNamespace) {
                    return value.includes(this._currentCollectionNamespace);
                }
                return this._currentAccessor && this._isAccessorGlobalConfiguration(this._currentAccessor);
            }));
            const mappedElements = elements.map(((name, index) => {
                const item = {
                    label: this._cleanIdentifierString(name),
                    value: Number(index)
                };
                return item;
            }));
            if (elements && elements.length > 0 && this._currentAccessor) {
                this._collectionIdentifiersElement?.updateEntries(mappedElements);
                let index = 0;
                if (!this._isAccessorGlobalConfiguration(_accessorName)) {
                    index = elements.findIndex((value => value === biomeConfigIdentifier));
                }
                this._collectionIdentifierIndex.set(index);
                const identifier = this._isAccessorGlobalConfiguration(_accessorName) ? "" : biomeConfigIdentifier;
                this._changeCollectionIdentifier(this._transferManager, _accessorName, identifier);
            }
        }
        _cleanIdentifierString(_identifier) {
            let cleanedIdentifier = _identifier;
            const charIndex = cleanedIdentifier.indexOf(":") + 1;
            cleanedIdentifier = cleanedIdentifier.substring(charIndex, cleanedIdentifier.length);
            cleanedIdentifier = cleanedIdentifier.replace(/_/g, " ");
            cleanedIdentifier = cleanedIdentifier.replace(/\b\w/g, (function(l) {
                return l.toUpperCase();
            }));
            return cleanedIdentifier;
        }
        _prettyToProperIdentifierString(_prettyIdentifier) {
            let identifier = _prettyIdentifier.toLocaleLowerCase();
            identifier = identifier.replace(/ /g, "_");
            return identifier;
        }
        _changeCollectionIdentifier(_transferManager, _accessorName, _identifier) {
            if (this._asyncOperationWorking) {
                this._logError("Async operation already in progress - ignoring request");
                return;
            }
            this._errorCollection = [];
            this._destroySettingsPane();
            this._currentIdentifier = _identifier;
            this._resetButton.enable = true;
            this._asyncOperationWorking = true;
            _transferManager.requestData(_accessorName, {
                identifier: _identifier
            }).then((data => {
                this._buildSettingsPane(data);
                this._startDirtyWatcher(_transferManager, _accessorName);
                _transferManager.sendData(_accessorName, data.data, {
                    identifier: _identifier
                });
            })).catch((e => {
                this._schemaInterface.error(`Failed to transfer data from client - ${VibrantVisualsBiome_stringFromException(e)}`);
                this.telemetryManager.fireTelemetryEvent(DeferredLightingTelemetry.ErrorDataTransfer);
                this._buildErrorUI(this._errorCollection.join("\n"));
            }));
        }
        _buildSettingsPane(data) {
            this._schemaInterface.debug("Received data from transfer manager");
            this._asyncOperationWorking = false;
            let dataObject;
            let schemaObject;
            this._errorCollection = [];
            this._uiComponentMap = undefined;
            try {
                dataObject = JSON.parse(data.data);
                this._schemaInterface.debug("Parsed incoming JSON object - OK");
                schemaObject = JSON.parse(data.schema);
                this._schemaInterface.debug("Parsed incoming JSON schema - OK");
                this._schemaInterface.debug(`Schema:\n$${String(data.schema)}\n-----------------------------------------------------------------------------`);
                this._schemaInterface.debug(`Data:\n$${String(data.data)}\n-----------------------------------------------------------------------------`);
            } catch (e) {
                this._schemaInterface.error(`Failed to parse incoming JSON object - ${VibrantVisualsBiome_stringFromException(e)}`);
                this._buildErrorUI(this._errorCollection.join("\n"));
                return;
            }
            this._uiComponentMap = new UIComponentMap(this._session, dataObject);
            try {
                const schemaBuilder = new SchemaValidatorBuilder(this._schemaInterface);
                const builtSchema = schemaBuilder.build(schemaObject);
                const validatedFlag = schemaBuilder.validate(dataObject);
                if (!validatedFlag) {
                    throw new Error("Failed to validate incoming JSON object");
                }
                this._uiComponentMap.saveDefaultProperties();
            } catch (e) {
                this._schemaInterface.error(`Failed to validate schema - ${VibrantVisualsBiome_stringFromException(e)}`);
                this._buildErrorUI(this._errorCollection.join("\n"));
                this._uiComponentMap = undefined;
                return;
            }
            try {
                this._settingsPane = this._rootPane.createSubPane({
                    title: "resourcePack.editor.agfx.pane.settings.title",
                    hasExpander: false
                });
                this._uiComponentMap?.constructUIComponents(this._settingsPane, this._schemaInterface);
                this._settingsPane.addDivider();
            } catch (e) {
                this._schemaInterface.error(`Failed to build UI components - ${VibrantVisualsBiome_stringFromException(e)}`);
                this._buildErrorUI(this._errorCollection.join("\n"));
                return;
            }
        }
        _destroySettingsPane() {
            if (this._settingsPane) {
                this._rootPane.removeSubPane(this._settingsPane);
                this._settingsPane = undefined;
            }
        }
        _stopDirtyWatcher(_transferManager, _accessorName) {
            if (this._tickHandle !== -1) {
                server_namespaceObject.system.clearRun(this._tickHandle);
                this._tickHandle = -1;
            }
            if (_accessorName !== undefined) {
                this._schemaInterface.debug("closing session");
                _transferManager.closeSession(_accessorName);
            } else {
                this._schemaInterface.debug("closing session - no accessor name");
            }
        }
        _startDirtyWatcher(_transferManager, _accessorName) {
            if (this._tickHandle !== -1) {
                this._stopDirtyWatcher(_transferManager, this._currentAccessor);
            }
            if (this._tickHandle === -1) {
                this._schemaInterface.debug("Starting dirty - opening session client");
                _transferManager.openSession(_accessorName);
                this._tickHandle = server_namespaceObject.system.runInterval((() => {
                    if (this._uiComponentMap && this._uiComponentMap.dirty && !this._uiComponentMap.reverting) {
                        this._uiComponentMap.dirty = false;
                        this._schemaInterface.debug("Data is dirty - pushing to client");
                        const data = JSON.stringify(this._uiComponentMap.currentData);
                        _transferManager.sendData(_accessorName, data, {
                            identifier: this._currentIdentifier
                        });
                        this._packLink.visible = false;
                    }
                }), 1);
            }
        }
        _addActionBarItem() {
            const showVibrantVisualsPaneAction = this._session.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    this._rootPane.show();
                }
            });
            this._session.actionBar.registerItem("editor:actionBarItem:vibrantVisualsBiome", showVibrantVisualsPaneAction, {
                label: "resourcePack.editor.menuBar.vibrantVisuals.title",
                icon: "pack://textures/editor/Vibrant-Visuals.png?filtering=point",
                tooltipTitle: "resourcePack.editor.menuBar.vibrantVisuals.title",
                tooltipDescription: "resourcePack.editor.menuBar.vibrantVisualsBiome.tooltip",
                enabled: true,
                executeOnAdd: true
            });
        }
        _getNamespace(fullIdentifier) {
            const charIndex = fullIdentifier.indexOf(":");
            const str = fullIdentifier.substring(0, charIndex);
            return str;
        }
        _changeBiomeMapping() {
            const currentBiome = this._targetBiomeDropdownList[this._targetBiomeDropdownIndex.value].id;
            if (this._biomeConfigData && this._currentAccessor && this._currentIdentifier) {
                this._transferManager.changeBiomeMapping(currentBiome, this._currentAccessor, this._currentIdentifier);
                const accessorString = this._currentAccessor.replace("deferred_lighting::", "");
                const accessorToConfigKeyMap = {
                    atmospheric_scattering: "atmospheric",
                    color_grading_parameters: "color_grading",
                    lighting_group: "lighting_group",
                    cubemap: "cubemap",
                    water_parameters: "water"
                };
                const configKey = accessorToConfigKeyMap[accessorString];
                if (configKey && configKey in this._biomeConfigData) {
                    this._biomeConfigData[configKey] = this._currentIdentifier;
                }
            }
        }
        _buildBiomeJSON(currentBiome, biomeConfigData) {
            const data = {
                description: {
                    identifier: currentBiome
                },
                components: {
                    "minecraft:atmosphere_identifier": {
                        atmosphere_identifier: biomeConfigData.atmospheric
                    },
                    "minecraft:color_grading_identifier": {
                        color_grading_identifier: biomeConfigData.color_grading
                    },
                    "minecraft:lighting_identifier": {
                        lighting_identifier: biomeConfigData.lighting_group
                    },
                    "minecraft:water_identifier": {
                        water_identifier: biomeConfigData.water
                    },
                    "minecraft:cubemap_identifier": {
                        cubemap_identifier: biomeConfigData.cubemap
                    }
                }
            };
            const json = {
                format_version: "1.21.90",
                "minecraft:client_biome": data
            };
            return json;
        }
        teardown() {
            const transferManager = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(this._session.extensionContext.player).dataTransfer;
            if (this._locationUpdateHandle) {
                server_namespaceObject.system.clearRun(this._locationUpdateHandle);
            }
            this._stopDirtyWatcher(transferManager, this._currentAccessor);
            if (this._graphicsChangeHandle !== undefined) {
                server_namespaceObject.system.clearRun(this._graphicsChangeHandle);
            }
        }
    }
    const MIN_TIME_DIFFERENCE_SECONDS = .05;
    const STORED_CINEMATIC_PLAYER_PROPERTY_NAME = "cinematic:storedControlPoints";
    const WIDGET_SHOW_DISTANCE = 2;
    var SplineTypeDropdownSelection;
    (function(SplineTypeDropdownSelection) {
        SplineTypeDropdownSelection[SplineTypeDropdownSelection["CatmullRom"] = 0] = "CatmullRom";
        SplineTypeDropdownSelection[SplineTypeDropdownSelection["Linear"] = 1] = "Linear";
    })(SplineTypeDropdownSelection || (SplineTypeDropdownSelection = {}));
    var CinematicTool_QuickActionMode;
    (function(QuickActionMode) {
        QuickActionMode[QuickActionMode["None"] = 0] = "None";
        QuickActionMode[QuickActionMode["SelectAll"] = 1] = "SelectAll";
        QuickActionMode[QuickActionMode["DeleteSelected"] = 2] = "DeleteSelected";
    })(CinematicTool_QuickActionMode || (CinematicTool_QuickActionMode = {}));
    const SPLINE_TYPE_CONFIGS = {
        [SplineTypeDropdownSelection.CatmullRom]: {
            minPoints: 4,
            displayName: "CatmullRom",
            splineClass: server_namespaceObject.CatmullRomSpline,
            widgetSplineType: server_editor_namespaceObject.SplineType.Hermite
        },
        [SplineTypeDropdownSelection.Linear]: {
            minPoints: 3,
            displayName: "Linear",
            splineClass: server_namespaceObject.LinearSpline,
            widgetSplineType: server_editor_namespaceObject.SplineType.Line
        }
    };
    class CinematicToolBehavior {
        constructor(uiSession) {
            this.uiSession = uiSession;
            this.PROXIMITY_CHECK_INTERVAL_TICKS = 5;
            this.controlPoints = [];
            this.selectedControlPointIndex = -1;
            this.nextControlPointId = 1;
            this.quickActionMode = (0, server_editor_namespaceObject.makeObservable)(CinematicTool_QuickActionMode.None);
            this.totalDuration = (0, server_editor_namespaceObject.makeObservable)(10);
            this.selectedSplineTypeIndex = (0, server_editor_namespaceObject.makeObservable)(SplineTypeDropdownSelection.CatmullRom);
            this.isAnimating = false;
            this.SPLINE_UPDATE_DELAY_MS = 100;
            uiSession.log.debug(`Initializing ${CinematicToolBehavior.BEHAVIOR_NAME}`);
            this.widgetGroup = uiSession.extensionContext.widgetManager.createGroup({
                groupSelectionMode: server_editor_namespaceObject.WidgetGroupSelectionMode.Multiple,
                visible: false
            });
            this.loadControlPointsFromWorld();
            this.pane = this._createPropertyPane();
            this.tool = this._addTool(uiSession);
            this.tool.bindPropertyPane(this.pane);
            this._bindKeyboardShortcuts();
            this._updatePlayAnimationButtonState();
        }
        teardown() {
            this.uiSession.log.debug(`Shutting down ${CinematicToolBehavior.BEHAVIOR_NAME}`);
            if (this.animationTimeoutId !== undefined) {
                server_namespaceObject.system.clearRun(this.animationTimeoutId);
                this.animationTimeoutId = undefined;
            }
            if (this.splineUpdateTimeoutId !== undefined) {
                server_namespaceObject.system.clearRun(this.splineUpdateTimeoutId);
                this.splineUpdateTimeoutId = undefined;
            }
            if (this.proximityCheckIntervalId !== undefined) {
                server_namespaceObject.system.clearRun(this.proximityCheckIntervalId);
                this.proximityCheckIntervalId = undefined;
            }
            if (this.moveToPointCameraTimeoutId !== undefined) {
                server_namespaceObject.system.clearRun(this.moveToPointCameraTimeoutId);
                this.moveToPointCameraTimeoutId = undefined;
            }
            if (this.moveToPointTeleportTimeoutId !== undefined) {
                server_namespaceObject.system.clearRun(this.moveToPointTeleportTimeoutId);
                this.moveToPointTeleportTimeoutId = undefined;
            }
            this._restoreHiddenWidget();
            if (this.isAnimating) {
                this._restoreCamera();
            }
            this._destroyAllWidgets();
            try {
                this.uiSession.extensionContext.widgetManager.deleteGroup(this.widgetGroup);
            } catch {}
        }
        loadControlPointsFromWorld() {
            try {
                const player = this.uiSession.extensionContext.player;
                const storedData = player.getDynamicProperty(STORED_CINEMATIC_PLAYER_PROPERTY_NAME);
                if (!storedData) {
                    return;
                }
                const data = JSON.parse(storedData);
                if (data.controlPoints && Array.isArray(data.controlPoints)) {
                    this.controlPoints = data.controlPoints.map((stored => ({
                        id: stored.id,
                        name: stored.name,
                        position: stored.position,
                        viewDirection: stored.viewDirection,
                        playerRotation: stored.playerRotation,
                        easingType: stored.easingType,
                        timeSeconds: stored.timeSeconds,
                        widget: undefined
                    })));
                    this.totalDuration.set(data.totalDuration || 10);
                    this.selectedSplineTypeIndex.set(data.splineType || SplineTypeDropdownSelection.CatmullRom);
                    if (this.controlPoints.length > 0) {
                        const maxId = Math.max(...this.controlPoints.map((cp => {
                            const match = cp.id.match(/cp_(\d+)/);
                            return match ? parseInt(match[1]) : 0;
                        })));
                        this.nextControlPointId = maxId + 1;
                    }
                }
            } catch (error) {
                this.uiSession.log.info(`Failed to load control points from storage : ${(0, server_editor_namespaceObject.stringFromException)(error)}`);
            }
        }
        storeControlPointsToWorld() {
            const data = {
                controlPoints: this.controlPoints.map((cp => ({
                    id: cp.id,
                    name: cp.name,
                    position: cp.position,
                    viewDirection: cp.viewDirection,
                    playerRotation: cp.playerRotation,
                    easingType: cp.easingType,
                    timeSeconds: cp.timeSeconds
                }))),
                totalDuration: this.totalDuration.value,
                splineType: this.selectedSplineTypeIndex.value
            };
            const player = this.uiSession.extensionContext.player;
            player.setDynamicProperty(STORED_CINEMATIC_PLAYER_PROPERTY_NAME, JSON.stringify(data));
        }
        _bindKeyboardShortcuts() {
            const deleteSelectedPointAction = this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this.selectedControlPointIndex < 0 || this.selectedControlPointIndex >= this.controlPoints.length) {
                        return;
                    }
                    this.uiSession.dialogManager.activateDialog({
                        dialogId: "cinematic:singleDeleteConfirm"
                    });
                }
            });
            this.tool.registerKeyBinding(deleteSelectedPointAction, {
                key: server_editor_namespaceObject.KeyboardKey.DELETE
            }, {
                uniqueId: "cinematic:keyBinding:deletePoint",
                label: "resourcePack.editor.CinematicTool.keyBinding.deletePoint.title",
                tooltip: "resourcePack.editor.CinematicTool.keyBinding.deletePoint.tooltip"
            });
        }
        _addTool(uiSession) {
            const tool = uiSession.toolRail.addTool("Cinematic Tool", {
                title: "resourcePack.editor.CinematicTool.title",
                icon: "pack://textures/editor/Camera.png?filtering=point",
                tooltip: "resourcePack.editor.CinematicTool.tooltip"
            });
            let isFirstActivation = true;
            tool.onModalToolActivation.subscribe((eventData => {
                if (eventData.isActiveTool) {
                    this.widgetGroup.visible = true;
                    if (isFirstActivation) {
                        this._createAllControlPointWidgets();
                        this._updateSplineVisualization();
                        this._refreshControlPointsList();
                        isFirstActivation = false;
                    }
                } else {
                    this.widgetGroup.visible = false;
                    if (this.moveToPointCameraTimeoutId !== undefined) {
                        server_namespaceObject.system.clearRun(this.moveToPointCameraTimeoutId);
                        this.moveToPointCameraTimeoutId = undefined;
                    }
                    if (this.moveToPointTeleportTimeoutId !== undefined) {
                        server_namespaceObject.system.clearRun(this.moveToPointTeleportTimeoutId);
                        this.moveToPointTeleportTimeoutId = undefined;
                    }
                    if (this.splineUpdateTimeoutId !== undefined) {
                        server_namespaceObject.system.clearRun(this.splineUpdateTimeoutId);
                        this.splineUpdateTimeoutId = undefined;
                    }
                    if (this.isAnimating) {
                        this._stopAnimation();
                    }
                    this._restoreHiddenWidget();
                }
            }));
            return tool;
        }
        _createPropertyPane() {
            const pane = this.uiSession.createPropertyPane({
                title: "resourcePack.editor.CinematicTool.title",
                uniqueId: "editor:pane:cinematicTool",
                infoTooltip: {
                    description: [ "resourcePack.editor.CinematicTool.tooltip", {
                        link: "https://aka.ms/BedrockEditorCameraTool",
                        text: "resourcePack.editor.help.learnMore"
                    } ]
                }
            });
            pane.addDropdown(this.selectedSplineTypeIndex, {
                title: "resourcePack.editor.CinematicTool.pane.splineType",
                tooltip: "resourcePack.editor.CinematicTool.pane.splineType.tooltip",
                entries: [ {
                    label: "resourcePack.editor.CinematicTool.pane.splineType.catmullRom",
                    value: SplineTypeDropdownSelection.CatmullRom
                }, {
                    label: "resourcePack.editor.CinematicTool.pane.splineType.linear",
                    value: SplineTypeDropdownSelection.Linear
                } ],
                onChange: _ => {
                    this._updatePlayAnimationButtonState();
                    this._updateSplineVisualization();
                    this.storeControlPointsToWorld();
                }
            });
            pane.addNumber(this.totalDuration, {
                title: "resourcePack.editor.CinematicTool.pane.totalDuration",
                tooltip: "resourcePack.editor.CinematicTool.pane.totalDuration.tooltip",
                min: 1,
                max: 300,
                onChange: _ => {
                    this._redistributeTimeValues();
                    this.storeControlPointsToWorld();
                }
            });
            this.playAnimationButton = pane.addButton(this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => this._playAnimation()
            }), {
                title: "resourcePack.editor.CinematicTool.pane.playAnimation",
                variant: server_editor_namespaceObject.ButtonVariant.Primary,
                visible: true,
                enable: false
            });
            this.stopAnimationButton = pane.addButton(this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => this._stopAnimation()
            }), {
                title: "resourcePack.editor.CinematicTool.pane.stopAnimation",
                variant: server_editor_namespaceObject.ButtonVariant.Secondary,
                visible: false
            });
            this.exportCodeButton = pane.addButton(this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => this._exportAnimationCode()
            }), {
                title: "resourcePack.editor.CinematicTool.pane.exportCode",
                variant: server_editor_namespaceObject.ButtonVariant.Secondary,
                visible: true
            });
            pane.addDivider();
            const pointDetailsPane = pane.createSubPane({
                title: "resourcePack.editor.CinematicTool.pane.pointDetails.title",
                collapsed: false
            });
            this._buildControlPointsList(pointDetailsPane);
            this.controlPointDetailsPane = pane.drawerPane;
            this.controlPointDetailsPane.onPropertyPaneVisibilityUpdated.subscribe((data => {
                if (!data.isVisible) {
                    this.controlPointsList?.selectSlot("", true);
                }
            }));
            this._updateControlPointDetails();
            return pane;
        }
        _buildControlPointsList(parentPane) {
            this.deleteConfirmDialog = this.uiSession.dialogManager.registerDialog({
                uniqueId: "cinematic:deleteConfirm",
                width: 80
            });
            this.deleteConfirmDialog.contentPane.addText({
                id: "resourcePack.editor.CinematicTool.dialog.deleteConfirm"
            }, {
                border: false
            });
            this.deleteConfirmDialog.controlPane.addButton((() => {
                this._performBulkDelete();
                this.deleteConfirmDialog?.sendDismiss();
            }), {
                title: "resourcePack.editor.CinematicTool.dialog.yes",
                variant: server_editor_namespaceObject.ButtonVariant.Primary
            });
            this.deleteConfirmDialog.controlPane.addButton((() => {
                this.deleteConfirmDialog?.sendDismiss();
            }), {
                title: "resourcePack.editor.CinematicTool.dialog.cancel",
                variant: server_editor_namespaceObject.ButtonVariant.Secondary
            });
            this.singleDeleteConfirmDialog = this.uiSession.dialogManager.registerDialog({
                uniqueId: "cinematic:singleDeleteConfirm",
                width: 80
            });
            this.singleDeleteConfirmDialog.contentPane.addText({
                id: "resourcePack.editor.CinematicTool.dialog.deleteSingle"
            }, {
                border: false
            });
            this.singleDeleteConfirmDialog.controlPane.addButton((() => {
                this._deleteCurrentControlPoint();
                this.singleDeleteConfirmDialog?.sendDismiss();
            }), {
                title: "resourcePack.editor.CinematicTool.dialog.yes",
                variant: server_editor_namespaceObject.ButtonVariant.Primary
            });
            this.singleDeleteConfirmDialog.controlPane.addButton((() => this.singleDeleteConfirmDialog?.sendDismiss()), {
                title: "resourcePack.editor.CinematicTool.dialog.cancel",
                variant: server_editor_namespaceObject.ButtonVariant.Secondary
            });
            parentPane.addToggleGroup(this.quickActionMode, {
                entries: [ {
                    icon: "pack://textures/editor/Activate.png",
                    tooltip: "resourcePack.editor.CinematicTool.pane.selectAll.tooltip",
                    value: CinematicTool_QuickActionMode.SelectAll
                }, {
                    icon: "trashCanIcon",
                    tooltip: "resourcePack.editor.CinematicTool.pane.deleteSelected.tooltip",
                    value: CinematicTool_QuickActionMode.DeleteSelected
                } ],
                onChange: newValue => {
                    switch (newValue) {
                      case CinematicTool_QuickActionMode.SelectAll:
                        this._toggleSelectAll();
                        break;

                      case CinematicTool_QuickActionMode.DeleteSelected:
                        this._deleteSelectedControlPoints();
                        break;
                    }
                    this.quickActionMode.set(CinematicTool_QuickActionMode.None);
                }
            });
            const controlPointListHeaderPane = parentPane.createSubPane({
                hasExpander: false,
                hasMargins: false,
                layout: server_editor_namespaceObject.PaneLayoutType.Horizontal
            });
            controlPointListHeaderPane.addText("", {
                style: {
                    width: server_editor_namespaceObject.LayoutFlex.Grow,
                    minWidth: 0,
                    verticalAlignment: server_editor_namespaceObject.LayoutAlignment.End
                },
                title: "resourcePack.editor.CinematicTool.pane.controlPoints",
                tooltip: "resourcePack.editor.CinematicTool.pane.controlPoints.tooltip",
                border: false
            });
            controlPointListHeaderPane.addButton((() => {
                this._addControlPoint();
            }), {
                tooltip: "resourcePack.editor.CinematicTool.pane.addPoint.tooltip",
                hiddenLabel: true,
                shrinkToIcon: true,
                icon: "pack://textures/editor/plus.png"
            });
            parentPane.addDivider();
            this.controlPointsList = parentPane.addListPane({
                height: 20,
                onSlotClicked: slot => {
                    const userData = slot.getUserData();
                    this.selectedControlPointIndex = userData;
                    this._updateControlPointDetails();
                    if (!slot.selected) {
                        this.controlPointsList?.selectSlot(slot.id, true);
                        this.controlPointDetailsPane?.show();
                    } else {
                        slot.setSelected(false);
                        this.controlPointDetailsPane?.hide();
                    }
                },
                defaultSlots: this._createControlPointSlots(),
                slotConfig: {
                    height: 4.4,
                    clickable: true,
                    entryLayout: [ {
                        type: server_editor_namespaceObject.ListPaneEntryType.Bool,
                        size: 6
                    }, {
                        type: server_editor_namespaceObject.ListPaneEntryType.Text,
                        size: server_editor_namespaceObject.LayoutFlex.Grow,
                        alignment: server_editor_namespaceObject.LayoutAlignment.Start
                    }, {
                        type: server_editor_namespaceObject.ListPaneEntryType.Button,
                        size: 4
                    } ]
                }
            });
        }
        _createControlPointSlots() {
            return this.controlPoints.map(((cp, index) => ({
                entries: [ {
                    type: server_editor_namespaceObject.ListPaneEntryType.Bool,
                    value: false
                }, {
                    type: server_editor_namespaceObject.ListPaneEntryType.Text,
                    value: cp.name
                }, {
                    type: server_editor_namespaceObject.ListPaneEntryType.Button,
                    tooltip: "resourcePack.editor.CinematicTool.pane.moveToPoint",
                    icon: "pack://textures/editor/Teleport.png",
                    onClick: () => {
                        this.selectedControlPointIndex = index;
                        this._moveToSelectedPoint();
                    }
                } ],
                options: {
                    userData: index
                }
            })));
        }
        _updatePlayAnimationButtonState() {
            const config = SPLINE_TYPE_CONFIGS[this.selectedSplineTypeIndex.value];
            const hasEnoughPoints = this.controlPoints.length >= config.minPoints;
            if (this.playAnimationButton) {
                this.playAnimationButton.enable = hasEnoughPoints;
            }
        }
        _updateControlPointDetails() {
            if (!this.controlPointDetailsPane) {
                return;
            }
            this._cleanupDetailInputs();
            if (this.controlPoints.length === 0 || this.selectedControlPointIndex < 0) {
                this.controlPointDetailsPane.hide();
                return;
            }
            if (this.selectedControlPointIndex >= this.controlPoints.length) {
                this.selectedControlPointIndex = this.controlPoints.length - 1;
            }
            const selectedPoint = this.controlPoints[this.selectedControlPointIndex];
            if (!selectedPoint) {
                this.controlPointDetailsPane.hide();
                return;
            }
            this.nameObservable = (0, server_editor_namespaceObject.makeObservable)(selectedPoint.name);
            this.positionObservable = (0, server_editor_namespaceObject.makeObservable)(selectedPoint.position);
            this.viewDirectionObservable = (0, server_editor_namespaceObject.makeObservable)(selectedPoint.viewDirection);
            this.timeObservable = (0, server_editor_namespaceObject.makeObservable)(selectedPoint.timeSeconds);
            const easingTypes = Object.values(server_namespaceObject.EasingType);
            const easingIndex = easingTypes.indexOf(selectedPoint.easingType);
            this.easingIndexObservable = (0, server_editor_namespaceObject.makeObservable)(easingIndex);
            this.nameInput = this.controlPointDetailsPane.addString(this.nameObservable, {
                title: "resourcePack.editor.CinematicTool.pane.pointName",
                tooltip: "resourcePack.editor.CinematicTool.pane.pointName.tooltip",
                onChange: value => {
                    selectedPoint.name = value;
                    this._refreshControlPointsList();
                    this._updateSelectedWidgetText();
                    this.storeControlPointsToWorld();
                }
            });
            const player = this.uiSession.extensionContext.player;
            const heightRangeMin = player.dimension.heightRange.min;
            const heightRangeMax = player.dimension.heightRange.max;
            this.positionInput = this.controlPointDetailsPane.addVector3(this.positionObservable, {
                title: "resourcePack.editor.CinematicTool.pane.position",
                tooltip: "resourcePack.editor.CinematicTool.pane.position.tooltip",
                isInteger: true,
                min: {
                    x: -3e6,
                    y: heightRangeMin,
                    z: -3e6
                },
                max: {
                    x: 3e6,
                    y: heightRangeMax,
                    z: 3e6
                },
                onChange: value => {
                    selectedPoint.position = {
                        ...value
                    };
                    this._updateSelectedWidget();
                    this._updateSplineVisualization();
                    this.storeControlPointsToWorld();
                }
            });
            this.viewDirectionInput = this.controlPointDetailsPane.addVector2(this.viewDirectionObservable, {
                title: "resourcePack.editor.CinematicTool.pane.rotation",
                tooltip: "resourcePack.editor.CinematicTool.pane.rotation.tooltip",
                min: {
                    x: -90,
                    y: 0
                },
                max: {
                    x: 90,
                    y: 360
                },
                onChange: value => {
                    selectedPoint.viewDirection = {
                        x: Math.round(value.x * 100) / 100,
                        y: Math.round(value.y * 100) / 100
                    };
                    this._updateSelectedWidgetText();
                    this.storeControlPointsToWorld();
                }
            });
            const easingEntries = [];
            easingTypes.forEach(((type, index) => {
                easingEntries.push({
                    label: type,
                    value: index
                });
            }));
            this.easingDropdown = this.controlPointDetailsPane.addDropdown(this.easingIndexObservable, {
                title: "resourcePack.editor.CinematicTool.pane.easingType",
                tooltip: "resourcePack.editor.CinematicTool.pane.easingType.tooltip",
                entries: easingEntries,
                onChange: value => {
                    selectedPoint.easingType = easingTypes[value];
                    this.storeControlPointsToWorld();
                }
            });
            this.timeInput = this.controlPointDetailsPane.addNumber(this.timeObservable, {
                title: "resourcePack.editor.CinematicTool.pane.timestamp",
                tooltip: "resourcePack.editor.CinematicTool.pane.timestamp.tooltip",
                min: 0,
                max: this.totalDuration.value,
                onChange: value => {
                    selectedPoint.timeSeconds = Math.round(value * 100) / 100;
                    this._sortControlPointTimes();
                    this._refreshControlPointsList();
                    this._updateAllWidgets();
                    this.storeControlPointsToWorld();
                }
            });
            this.updateLocationButton = this.controlPointDetailsPane.addButton(this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => this._updatePointToPlayerLocation()
            }), {
                title: "resourcePack.editor.CinematicTool.pane.updateLocation",
                variant: server_editor_namespaceObject.ButtonVariant.Secondary,
                visible: true
            });
            this.moveToPointButton = this.controlPointDetailsPane.addButton(this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => this._moveToSelectedPoint()
            }), {
                title: "resourcePack.editor.CinematicTool.pane.moveToPoint",
                visible: true
            });
            this.deleteButton = this.controlPointDetailsPane.addButton(this.uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (this.selectedControlPointIndex < 0 || this.selectedControlPointIndex >= this.controlPoints.length) {
                        this.uiSession.log.info("No selected control point to delete");
                        return;
                    }
                    this.uiSession.dialogManager.activateDialog({
                        dialogId: "cinematic:singleDeleteConfirm"
                    });
                }
            }), {
                title: "resourcePack.editor.CinematicTool.pane.deletePoint",
                visible: true
            });
        }
        _toggleSelectAll() {
            if (!this.controlPointsList) {
                return;
            }
            let hasUnchecked = false;
            for (let i = 0; i < this.controlPoints.length; i++) {
                const slot = this.controlPointsList.getSlotByIndex(i);
                if (slot) {
                    const checkbox = slot.getEntry(0);
                    if (checkbox && !checkbox.value) {
                        hasUnchecked = true;
                        break;
                    }
                }
            }
            for (let i = 0; i < this.controlPoints.length; i++) {
                const slot = this.controlPointsList.getSlotByIndex(i);
                if (slot) {
                    const checkbox = slot.getEntry(0);
                    if (checkbox) {
                        checkbox.setValue(hasUnchecked);
                    }
                }
            }
        }
        _deleteSelectedControlPoints() {
            const selectedIndices = this._getSelectedControlPointIndices();
            if (selectedIndices.length === 0) {
                this.uiSession.log.info("No control points selected for deletion");
                return;
            }
            this.uiSession.dialogManager.activateDialog({
                dialogId: "cinematic:deleteConfirm"
            });
        }
        _performBulkDelete() {
            const selectedIndices = this._getSelectedControlPointIndices();
            if (selectedIndices.length === 0) {
                return;
            }
            for (let i = selectedIndices.length - 1; i >= 0; i--) {
                const index = selectedIndices[i];
                const cp = this.controlPoints[index];
                if (cp.widget) {
                    try {
                        cp.widget.delete();
                    } catch {}
                }
                this.controlPoints.splice(index, 1);
            }
            this.selectedControlPointIndex = this.controlPoints.length > 0 ? 0 : -1;
            this._refreshUIState();
            this.uiSession.log.info(`Deleted ${selectedIndices.length} control points`);
        }
        _deleteCurrentControlPoint() {
            if (this.selectedControlPointIndex < 0 || this.selectedControlPointIndex >= this.controlPoints.length) {
                this.uiSession.log.info("No selected control point to delete");
                return;
            }
            const deleted = this.controlPoints[this.selectedControlPointIndex];
            if (deleted.widget) {
                try {
                    deleted.widget.delete();
                } catch {}
            }
            this.controlPoints.splice(this.selectedControlPointIndex, 1);
            if (this.controlPoints.length === 0) {
                this.selectedControlPointIndex = -1;
            } else if (this.selectedControlPointIndex >= this.controlPoints.length) {
                this.selectedControlPointIndex = this.controlPoints.length - 1;
            }
            this._refreshUIState();
            this.uiSession.log.info(`Deleted control point: ${deleted.name}`);
        }
        _getSelectedControlPointIndices() {
            const selectedIndices = [];
            if (!this.controlPointsList) {
                return selectedIndices;
            }
            for (let i = 0; i < this.controlPoints.length; i++) {
                const slot = this.controlPointsList.getSlotByIndex(i);
                if (slot) {
                    const checkbox = slot.getEntry(0);
                    if (checkbox?.value) {
                        selectedIndices.push(i);
                    }
                }
            }
            return selectedIndices;
        }
        _refreshControlPointsList() {
            if (!this.controlPointsList) {
                return;
            }
            this.controlPointsList.updateSlots(this._createControlPointSlots());
            const slot = this.controlPointsList.getSlotByIndex(this.selectedControlPointIndex);
            if (slot) {
                this.controlPointsList.selectSlot(slot.id, true);
                this.controlPointDetailsPane?.show();
            }
        }
        _createControlPointWidget(controlPoint) {
            const widget = this.widgetGroup.createWidget(controlPoint.position, {
                selectable: true,
                snapToBlockLocation: false,
                visible: true,
                collisionRadius: .5,
                widgetName: `Cinematic Control Point - ${controlPoint.name}`,
                stateChangeEvent: data => {
                    const currentIndex = this.controlPoints.findIndex((cp => cp.id === controlPoint.id));
                    if (currentIndex === -1) {
                        return;
                    }
                    if (data.mouseEvent !== undefined) {
                        const isMousePress = data.mouseEvent.action === server_editor_namespaceObject.WidgetMouseButtonActionType.Pressed;
                        const isLeftClick = !data.mouseEvent.shiftPressed && !data.mouseEvent.controlPressed && !data.mouseEvent.altPressed;
                        if (isMousePress && isLeftClick) {
                            if (this.selectedControlPointIndex !== currentIndex) {
                                this.selectedControlPointIndex = currentIndex;
                                this._updateControlPointDetails();
                                const slot = this.controlPointsList?.getSlotByIndex(currentIndex);
                                if (slot) {
                                    this.controlPointsList?.selectSlot(slot.id, true);
                                    this.controlPointDetailsPane?.show();
                                }
                            }
                        }
                    }
                    if (data.location !== undefined) {
                        controlPoint.position = {
                            ...data.location
                        };
                        const textComponent = widget.getComponent("info_text");
                        if (textComponent) {
                            const infoText = this._formatControlPointInfo(controlPoint);
                            textComponent.label = infoText;
                        }
                        if (currentIndex === this.selectedControlPointIndex && this.positionObservable) {
                            this.positionObservable.set({
                                ...data.location
                            });
                        }
                        this._debouncedSplineUpdate();
                        this.storeControlPointsToWorld();
                    }
                    if (data.selected !== undefined) {
                        if (data.selected) {
                            if (this.selectedControlPointIndex !== currentIndex) {
                                this.selectedControlPointIndex = currentIndex;
                                this._updateControlPointDetails();
                                const slot = this.controlPointsList?.getSlotByIndex(currentIndex);
                                if (slot) {
                                    this.controlPointsList?.selectSlot(slot.id, true);
                                    this.controlPointDetailsPane?.show();
                                }
                            }
                        }
                    }
                }
            });
            widget.addGizmoComponent("control_point_gizmo", {
                offset: {
                    x: 0,
                    y: 0,
                    z: 0
                },
                visible: true
            });
            const infoText = this._formatControlPointInfo(controlPoint);
            widget.addTextComponent("info_text", infoText, {
                offset: {
                    x: 0,
                    y: 1,
                    z: 0
                },
                visible: true
            });
            widget.addGuideComponent("control_point_guide");
            return widget;
        }
        _debouncedSplineUpdate() {
            if (this.splineUpdateTimeoutId !== undefined) {
                server_namespaceObject.system.clearRun(this.splineUpdateTimeoutId);
            }
            this.splineUpdateTimeoutId = server_namespaceObject.system.runTimeout((() => {
                this._updateSplineVisualization();
                this.splineUpdateTimeoutId = undefined;
            }), this.SPLINE_UPDATE_DELAY_MS / 1e3 * server_namespaceObject.TicksPerSecond);
        }
        _formatControlPointInfo(controlPoint) {
            const pos = lib.Vector3Utils.toString(controlPoint.position, {
                decimals: 1
            });
            const rot = `Pitch:${controlPoint.viewDirection.x.toFixed(2)}° Yaw:${controlPoint.viewDirection.y.toFixed(2)}°`;
            const time = `T:${controlPoint.timeSeconds.toFixed(2)}s`;
            return `${controlPoint.name}\n${pos}\n${rot}\n${time}`;
        }
        _createAllControlPointWidgets() {
            this._destroyAllControlPointWidgets();
            this.controlPoints.forEach((cp => {
                cp.widget = this._createControlPointWidget(cp);
            }));
        }
        _destroyAllControlPointWidgets() {
            this.controlPoints.forEach((cp => {
                if (cp.widget) {
                    try {
                        cp.widget.delete();
                    } catch {}
                    cp.widget = undefined;
                }
            }));
        }
        _updateSplineVisualization() {
            if (this.splineWidget) {
                try {
                    this.splineWidget.delete();
                } catch {}
                this.splineWidget = undefined;
                this.splineComponent = undefined;
            }
            if (this.controlPoints.length < 2) {
                return;
            }
            const firstPoint = this.controlPoints[0];
            this.splineWidget = this.widgetGroup.createWidget(firstPoint.position, {
                selectable: false,
                snapToBlockLocation: false,
                visible: true,
                collisionRadius: 0,
                widgetName: "Cinematic Spline Path"
            });
            const config = SPLINE_TYPE_CONFIGS[this.selectedSplineTypeIndex.value];
            this.splineComponent = this.splineWidget.addSplineComponent("path_spline", {
                splineType: config.widgetSplineType,
                controlPoints: [],
                offset: {
                    x: 0,
                    y: 0,
                    z: 0
                }
            });
            const widgetList = this.controlPoints.map((cp => cp.widget)).filter((widget => widget !== undefined));
            if (widgetList.length > 0) {
                this.splineComponent.setControlPoints(widgetList);
            }
        }
        _updateAllWidgets() {
            this.controlPoints.forEach((cp => {
                if (cp.widget) {
                    cp.widget.location = cp.position;
                    const textComponent = cp.widget.getComponent("info_text");
                    if (textComponent) {
                        const infoText = this._formatControlPointInfo(cp);
                        textComponent.label = infoText;
                    }
                } else {
                    cp.widget = this._createControlPointWidget(cp);
                }
            }));
            this._updateSplineVisualization();
        }
        _destroyAllWidgets() {
            this._destroyAllControlPointWidgets();
            if (this.splineWidget) {
                try {
                    this.splineWidget.delete();
                } catch {}
                this.splineWidget = undefined;
                this.splineComponent = undefined;
            }
        }
        _updateSelectedWidget() {
            const selectedPoint = this.controlPoints[this.selectedControlPointIndex];
            if (selectedPoint && selectedPoint.widget) {
                selectedPoint.widget.location = selectedPoint.position;
                this._updateSelectedWidgetText();
            }
        }
        _updateSelectedWidgetText() {
            const selectedPoint = this.controlPoints[this.selectedControlPointIndex];
            if (selectedPoint && selectedPoint.widget) {
                const textComponent = selectedPoint.widget.getComponent("info_text");
                if (textComponent) {
                    const infoText = this._formatControlPointInfo(selectedPoint);
                    textComponent.label = infoText;
                }
            }
        }
        _refreshUIState(recreateWidgets = true) {
            this._refreshControlPointsList();
            this._updateControlPointDetails();
            if (recreateWidgets) {
                this._createAllControlPointWidgets();
            }
            this._updateSplineVisualization();
            this._updatePlayAnimationButtonState();
            this.storeControlPointsToWorld();
        }
        _normalizeYaw(angle) {
            return (angle % 360 + 360) % 360;
        }
        _addControlPoint() {
            const player = this.uiSession.extensionContext.player;
            const playerRotation = player.getRotation();
            const viewDirection = player.getViewDirection();
            const yaw = Math.atan2(-viewDirection.x, -viewDirection.z) * (180 / Math.PI);
            const horizontalDistance = Math.sqrt(viewDirection.x * viewDirection.x + viewDirection.z * viewDirection.z);
            const pitch = Math.atan2(viewDirection.y, horizontalDistance) * (180 / Math.PI);
            const baseName = "Point";
            const uniqueName = this._handleDuplicatePointName(baseName);
            const newPoint = {
                id: `cp_${this.nextControlPointId++}`,
                name: uniqueName,
                position: {
                    ...player.location
                },
                viewDirection: {
                    x: Math.round(pitch * 100) / 100,
                    y: Math.round(this._normalizeYaw(yaw) * 100) / 100
                },
                playerRotation: {
                    x: Math.round(playerRotation.x * 100) / 100,
                    y: Math.round(playerRotation.y * 100) / 100
                },
                easingType: server_namespaceObject.EasingType.Linear,
                timeSeconds: Math.round(this.totalDuration.value * 100) / 100
            };
            this.controlPoints.push(newPoint);
            newPoint.widget = this._createControlPointWidget(newPoint);
            this.selectedControlPointIndex = this.controlPoints.length - 1;
            this._refreshUIState(false);
            this.uiSession.log.info(`Added control point: ${newPoint.name}`);
        }
        _hideControlPointWidget(controlPointId) {
            const controlPoint = this.controlPoints.find((cp => cp.id === controlPointId));
            if (controlPoint?.widget) {
                const gizmoComponent = controlPoint.widget.getComponent("control_point_gizmo");
                if (gizmoComponent) {
                    gizmoComponent.visible = false;
                }
                this.hiddenWidgetControlPointId = controlPointId;
            }
        }
        _restoreHiddenWidget() {
            if (this.hiddenWidgetControlPointId) {
                const controlPoint = this.controlPoints.find((cp => cp.id === this.hiddenWidgetControlPointId));
                if (controlPoint?.widget) {
                    const gizmoComponent = controlPoint.widget.getComponent("control_point_gizmo");
                    if (gizmoComponent) {
                        gizmoComponent.visible = true;
                    }
                }
                this.hiddenWidgetControlPointId = undefined;
            }
            if (this.proximityCheckIntervalId !== undefined) {
                server_namespaceObject.system.clearRun(this.proximityCheckIntervalId);
                this.proximityCheckIntervalId = undefined;
            }
        }
        _startProximityCheck(targetPosition) {
            if (this.proximityCheckIntervalId !== undefined) {
                server_namespaceObject.system.clearRun(this.proximityCheckIntervalId);
            }
            this.proximityCheckIntervalId = server_namespaceObject.system.runInterval((() => {
                const player = this.uiSession.extensionContext.player;
                const delta = lib.Vector3Utils.subtract(player.location, targetPosition);
                const distance = lib.Vector3Utils.magnitude(delta);
                if (distance > WIDGET_SHOW_DISTANCE) {
                    this._restoreHiddenWidget();
                }
            }), this.PROXIMITY_CHECK_INTERVAL_TICKS);
        }
        _moveToSelectedPoint() {
            const selectedPoint = this.controlPoints[this.selectedControlPointIndex];
            if (!selectedPoint) return;
            if (this.moveToPointCameraTimeoutId !== undefined) {
                server_namespaceObject.system.clearRun(this.moveToPointCameraTimeoutId);
                this.moveToPointCameraTimeoutId = undefined;
            }
            if (this.moveToPointTeleportTimeoutId !== undefined) {
                server_namespaceObject.system.clearRun(this.moveToPointTeleportTimeoutId);
                this.moveToPointTeleportTimeoutId = undefined;
            }
            this._restoreHiddenWidget();
            this._hideControlPointWidget(selectedPoint.id);
            const player = this.uiSession.extensionContext.player;
            const playerPosition = player.location;
            const playerHeadPosition = player.getHeadLocation();
            const cameraHeadOffset = {
                x: 0,
                y: .1,
                z: 0
            };
            const playerCameraPosition = lib.Vector3Utils.add(playerHeadPosition, cameraHeadOffset);
            const playerCameraDelta = lib.Vector3Utils.subtract(playerCameraPosition, playerPosition);
            const easeTimeInSeconds = .75;
            const targetPosition = selectedPoint.position;
            const targetRotation = selectedPoint.playerRotation;
            this.moveToPointCameraTimeoutId = server_namespaceObject.system.runTimeout((() => {
                this.moveToPointCameraTimeoutId = undefined;
                const cameraPositionOptions = {
                    easeOptions: {
                        easeTime: easeTimeInSeconds,
                        easeType: server_namespaceObject.EasingType.InOutQuad
                    },
                    rotation: {
                        x: targetRotation.x,
                        y: targetRotation.y
                    },
                    location: targetPosition
                };
                player.camera.setCamera("minecraft:free", cameraPositionOptions);
            }), .1 * server_namespaceObject.TicksPerSecond);
            const newPlayerPositionTarget = lib.Vector3Utils.subtract(targetPosition, playerCameraDelta);
            this.moveToPointTeleportTimeoutId = server_namespaceObject.system.runTimeout((() => {
                this.moveToPointTeleportTimeoutId = undefined;
                player.camera.setCamera("minecraft:first_person");
                player.teleport(newPlayerPositionTarget, {
                    rotation: {
                        x: targetRotation.x,
                        y: targetRotation.y
                    }
                });
                this._startProximityCheck(targetPosition);
            }), easeTimeInSeconds * server_namespaceObject.TicksPerSecond);
        }
        _updatePointToPlayerLocation() {
            const selectedPoint = this.controlPoints[this.selectedControlPointIndex];
            if (!selectedPoint) {
                this.uiSession.log.info("No control point selected");
                return;
            }
            const player = this.uiSession.extensionContext.player;
            selectedPoint.position = {
                ...player.location
            };
            const viewDirection = player.getViewDirection();
            const yaw = Math.atan2(-viewDirection.x, -viewDirection.z) * (180 / Math.PI);
            const horizontalDistance = Math.sqrt(viewDirection.x * viewDirection.x + viewDirection.z * viewDirection.z);
            const pitch = Math.atan2(viewDirection.y, horizontalDistance) * (180 / Math.PI);
            selectedPoint.viewDirection = {
                x: Math.round(pitch * 100) / 100,
                y: Math.round(this._normalizeYaw(yaw) * 100) / 100
            };
            const playerRotation = player.getRotation();
            selectedPoint.playerRotation = {
                x: Math.round(playerRotation.x * 100) / 100,
                y: Math.round(playerRotation.y * 100) / 100
            };
            if (this.positionObservable) {
                this.positionObservable.set({
                    ...selectedPoint.position
                });
            }
            if (this.viewDirectionObservable) {
                this.viewDirectionObservable.set({
                    ...selectedPoint.viewDirection
                });
            }
            this._updateSelectedWidget();
            this._updateSelectedWidgetText();
            this._updateSplineVisualization();
            this.storeControlPointsToWorld();
        }
        _sortControlPointTimes() {
            this.controlPoints.sort(((a, b) => a.timeSeconds - b.timeSeconds));
        }
        _sortAndNormalizeControlPointTimes() {
            this.controlPoints.sort(((a, b) => a.timeSeconds - b.timeSeconds));
            if (this.controlPoints.length > 0) {
                this.controlPoints[0].timeSeconds = 0;
                if (this.controlPoints.length > 1) {
                    this.controlPoints[this.controlPoints.length - 1].timeSeconds = Math.round(this.totalDuration.value * 100) / 100;
                }
            }
            this.storeControlPointsToWorld();
            this.controlPoints.forEach((cp => {
                if (cp.widget) {
                    const textComponent = cp.widget.getComponent("info_text");
                    if (textComponent) {
                        const infoText = this._formatControlPointInfo(cp);
                        textComponent.label = infoText;
                    }
                }
            }));
            this._updateControlPointDetails();
        }
        _handleDuplicatePointName(baseName) {
            let newName = baseName;
            let increment = 1;
            while (this.controlPoints.some((cp => cp.name === newName))) {
                newName = `${baseName}_${increment}`;
                increment++;
            }
            return newName;
        }
        _redistributeTimeValues() {
            const duration = this.totalDuration.value;
            const pointCount = this.controlPoints.length;
            if (pointCount <= 1) {
                if (pointCount === 1) {
                    this.controlPoints[0].timeSeconds = 0;
                }
                this._updateControlPointDetails();
                return;
            }
            this.controlPoints.forEach(((point, index) => {
                const rawTime = duration * index / (pointCount - 1);
                point.timeSeconds = Math.round(rawTime * 100) / 100;
            }));
            this._updateControlPointDetails();
        }
        _shortestYawDelta(fromYaw, toYaw) {
            let delta = this._normalizeYaw(toYaw) - this._normalizeYaw(fromYaw);
            if (delta > 180) {
                delta -= 360;
            } else if (delta < -180) {
                delta += 360;
            }
            return delta;
        }
        _unwrapRotationKeyframes(keyframes) {
            if (keyframes.length <= 1) {
                return keyframes;
            }
            const unwrapped = [];
            let accumulatedYaw = keyframes[0].rotation.y;
            unwrapped.push({
                ...keyframes[0],
                rotation: {
                    ...keyframes[0].rotation
                }
            });
            for (let i = 1; i < keyframes.length; i++) {
                accumulatedYaw += this._shortestYawDelta(accumulatedYaw, keyframes[i].rotation.y);
                unwrapped.push({
                    ...keyframes[i],
                    rotation: {
                        x: keyframes[i].rotation.x,
                        y: accumulatedYaw,
                        z: keyframes[i].rotation.z
                    }
                });
            }
            return unwrapped;
        }
        _playAnimation() {
            if (!this._validateMinimumControlPoints("Animation failed")) {
                return;
            }
            this._sortAndNormalizeControlPointTimes();
            const validation = this._validateControlPointTimes();
            if (!validation.valid) {
                this.uiSession.log.error(`Animation failed: ${validation.errorMessage}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const lengthValidation = this._validateSplineLength();
            if (!lengthValidation.valid) {
                this.uiSession.log.error(`Animation failed: ${lengthValidation.errorMessage}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const player = this.uiSession.extensionContext.player;
            const currentRotation = player.getRotation();
            this.previousCameraState = {
                location: {
                    ...player.location
                },
                rotation: currentRotation
            };
            const config = SPLINE_TYPE_CONFIGS[this.selectedSplineTypeIndex.value];
            const SplineClass = config.splineClass;
            const spline = new SplineClass;
            spline.controlPoints = this.controlPoints.map((cp => cp.position));
            const progressKeyFrames = this.controlPoints.map(((cp, index) => ({
                alpha: this.controlPoints.length > 1 ? index / (this.controlPoints.length - 1) : 0,
                timeSeconds: cp.timeSeconds,
                easingFunc: cp.easingType
            })));
            const rotationKeyFrames = this.controlPoints.map((cp => ({
                rotation: {
                    x: cp.viewDirection.x,
                    y: cp.viewDirection.y,
                    z: 0
                },
                timeSeconds: cp.timeSeconds,
                easingFunc: cp.easingType
            })));
            const unwrappedRotationKeyFrames = this._unwrapRotationKeyframes(rotationKeyFrames);
            const animationOptions = {
                totalTimeSeconds: this.totalDuration.value,
                animation: {
                    progressKeyFrames,
                    rotationKeyFrames: unwrappedRotationKeyFrames
                }
            };
            player.camera.setCamera("minecraft:free", {
                location: this.controlPoints[0].position,
                rotation: this.controlPoints[0].viewDirection
            });
            player.camera.playAnimation(spline, animationOptions);
            this.isAnimating = true;
            if (this.playAnimationButton) {
                this.playAnimationButton.visible = false;
            }
            if (this.stopAnimationButton) {
                this.stopAnimationButton.visible = true;
            }
            if (this.animationTimeoutId !== undefined) {
                server_namespaceObject.system.clearRun(this.animationTimeoutId);
            }
            this.animationTimeoutId = server_namespaceObject.system.runTimeout((() => {
                this._restoreCamera();
            }), (this.totalDuration.value + .1) * server_namespaceObject.TicksPerSecond);
        }
        _stopAnimation() {
            const player = this.uiSession.extensionContext.player;
            if (this.animationTimeoutId !== undefined) {
                server_namespaceObject.system.clearRun(this.animationTimeoutId);
                this.animationTimeoutId = undefined;
            }
            player.camera.clear();
            this._restoreCamera();
        }
        _restoreCamera() {
            const player = this.uiSession.extensionContext.player;
            player.camera.setCamera("minecraft:first_person");
            if (this.previousCameraState) {
                player.teleport(this.previousCameraState.location, {
                    rotation: this.previousCameraState.rotation
                });
            }
            this.isAnimating = false;
            this.animationTimeoutId = undefined;
            this.previousCameraState = undefined;
            if (this.playAnimationButton) {
                this.playAnimationButton.visible = true;
            }
            if (this.stopAnimationButton) {
                this.stopAnimationButton.visible = false;
            }
        }
        _calculateUnwrappedYaws() {
            if (this.controlPoints.length === 0) {
                return [];
            }
            const unwrappedYaws = [ this.controlPoints[0].viewDirection.y ];
            let accumulatedYaw = this.controlPoints[0].viewDirection.y;
            for (let i = 1; i < this.controlPoints.length; i++) {
                accumulatedYaw += this._shortestYawDelta(accumulatedYaw, this.controlPoints[i].viewDirection.y);
                unwrappedYaws.push(accumulatedYaw);
            }
            return unwrappedYaws;
        }
        _exportAnimationCode() {
            if (!this._validateMinimumControlPoints("Export failed")) {
                return;
            }
            this._sortAndNormalizeControlPointTimes();
            const validation = this._validateControlPointTimes();
            if (!validation.valid) {
                this.uiSession.log.error(`Export failed: ${validation.errorMessage}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const lengthValidation = this._validateSplineLength();
            if (!lengthValidation.valid) {
                this.uiSession.log.error(`Export failed: ${lengthValidation.errorMessage}`, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return;
            }
            const config = SPLINE_TYPE_CONFIGS[this.selectedSplineTypeIndex.value];
            const splineType = config.splineClass.name;
            const controlPointsCode = this.controlPoints.map((cp => `        { x: ${cp.position.x}, y: ${cp.position.y}, z: ${cp.position.z} }, // ${cp.name}`)).join("\n");
            const progressKeyFramesCode = this.controlPoints.map(((cp, index) => {
                const alpha = this.controlPoints.length > 1 ? index / (this.controlPoints.length - 1) : 0;
                return `        { alpha: ${alpha}, timeSeconds: ${cp.timeSeconds.toFixed(2)}, easingFunc: EasingType.${cp.easingType} }`;
            })).join(",\n");
            const unwrappedYaws = this._calculateUnwrappedYaws();
            const rotationKeyFramesCode = this.controlPoints.map(((cp, index) => `        { rotation: { x: ${cp.viewDirection.x.toFixed(2)}, y: ${unwrappedYaws[index].toFixed(2)}, z: 0 }, timeSeconds: ${cp.timeSeconds.toFixed(2)}, easingFunc: EasingType.${cp.easingType} }`)).join(",\n");
            const code = `// Generated Cinematic Animation Function\nimport { Player, ${splineType}, AnimationOptions, EasingType } from '@minecraft/server';\n\n/**\n * Plays a cinematic camera animation for the specified player\n * @param player - The player to play the animation for\n * @returns void\n */\nexport function playCinematicAnimation(player: Player): void {\n    const spline = new ${splineType}();\n    spline.controlPoints = [\n${controlPointsCode}\n    ];\n\n    const progressKeyFrames = [\n${progressKeyFramesCode}\n    ];\n\n    const rotationKeyFrames = [\n${rotationKeyFramesCode}\n    ];\n\n    const animationOptions: AnimationOptions = {\n        totalTimeSeconds: ${this.totalDuration.value.toFixed(2)},\n        animation: {\n            progressKeyFrames: progressKeyFrames,\n            rotationKeyFrames: rotationKeyFrames\n        }\n    };\n\n    // Set initial camera position and rotation\n    player.camera.setCamera('minecraft:free', {\n        location: { x: ${this.controlPoints[0].position.x}, y: ${this.controlPoints[0].position.y}, z: ${this.controlPoints[0].position.z} },\n        rotation: { x: ${this.controlPoints[0].viewDirection.x.toFixed(2)}, y: ${this.controlPoints[0].viewDirection.y.toFixed(2)} }\n    });\n\n    // Play the animation\n    player.camera.playAnimation(spline, animationOptions);\n}`;
            const transferManager = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(this.uiSession.extensionContext.player).dataTransfer;
            transferManager.sendDataToClipboard(code);
            this.uiSession.log.info("Animation function has been copied to clipboard.", {
                channelMask: server_editor_namespaceObject.LogChannel.All
            });
        }
        _validateMinimumControlPoints(actionName) {
            const config = SPLINE_TYPE_CONFIGS[this.selectedSplineTypeIndex.value];
            if (this.controlPoints.length < config.minPoints) {
                const errorMessage = actionName ? `${actionName}: ${config.displayName} spline requires at least ${config.minPoints} control points` : `${config.displayName} spline requires at least ${config.minPoints} control points`;
                this.uiSession.log.error(errorMessage, {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
                return false;
            }
            return true;
        }
        _validateControlPointTimes(excludeIndex) {
            const sortedPoints = [ ...this.controlPoints ].filter(((_, index) => index !== excludeIndex)).sort(((a, b) => a.timeSeconds - b.timeSeconds));
            for (let i = 1; i < sortedPoints.length; i++) {
                const timeDiff = sortedPoints[i].timeSeconds - sortedPoints[i - 1].timeSeconds;
                if (timeDiff < MIN_TIME_DIFFERENCE_SECONDS) {
                    const errorMessage = timeDiff === 0 ? `Multiple control points have the same time value (${sortedPoints[i].timeSeconds.toFixed(2)}s). Each control point must have a unique time value with at least ${MIN_TIME_DIFFERENCE_SECONDS}s difference.` : `Time difference between "${sortedPoints[i - 1].name}" and "${sortedPoints[i].name}" is ${timeDiff.toFixed(2)}s. Minimum required is ${MIN_TIME_DIFFERENCE_SECONDS}s.`;
                    return {
                        valid: false,
                        errorMessage
                    };
                }
            }
            return {
                valid: true
            };
        }
        _validateSplineLength() {
            let totalLength = 0;
            for (let i = 0; i < this.controlPoints.length - 1; i++) {
                const delta = lib.Vector3Utils.subtract(this.controlPoints[i + 1].position, this.controlPoints[i].position);
                totalLength += lib.Vector3Utils.magnitude(delta);
            }
            if (totalLength < .001) {
                return {
                    valid: false,
                    errorMessage: "Control points are too close together. The spline path must have a non-zero length."
                };
            }
            return {
                valid: true
            };
        }
        _cleanupDetailInputs() {
            const inputs = [ this.nameInput, this.positionInput, this.viewDirectionInput, this.easingDropdown, this.timeInput, this.moveToPointButton, this.deleteButton, this.updateLocationButton ];
            inputs.forEach((input => {
                if (input) input.visible = false;
            }));
        }
    }
    CinematicToolBehavior.BEHAVIOR_NAME = "Cinematic Tool";
    function createCoreUI(uiSession) {
        if (!uiSession.scratchStorage) {
            throw new Error("Core UI initialization order incorrect");
        }
        const pauseScreenAction = uiSession.actionManager.createAction({
            actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
            onExecute: () => {
                uiSession.builtInUIManager.navigateToPauseScreen();
            }
        });
        const showLoggingPaneAction = uiSession.actionManager.createAction({
            actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
            onExecute: () => {
                uiSession.builtInUIManager.updateLogPanelVisibility(true);
            }
        });
        const tutorialAction = uiSession.actionManager.createAction({
            actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
            onExecute: () => {
                uiSession.builtInUIManager.activateTutorial();
            }
        });
        const quickStartAction = uiSession.actionManager.createAction({
            actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
            onExecute: () => {
                uiSession.builtInUIManager.updateWelcomePanelVisibility(true);
            }
        });
        const documentationAction = uiSession.actionManager.createAction({
            actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
            onExecute: () => {
                uiSession.builtInUIManager.navigateToDocumentation();
            }
        });
        const feedbackAction = uiSession.actionManager.createAction({
            actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
            onExecute: () => {
                uiSession.builtInUIManager.navigateToFeedback();
            }
        });
        const sampleAction = uiSession.actionManager.createAction({
            actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
            onExecute: () => {
                uiSession.builtInUIManager.navigateToSamples();
            }
        });
        uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, pauseScreenAction, {
            key: server_editor_namespaceObject.KeyboardKey.KEY_Q,
            modifier: server_editor_namespaceObject.InputModifier.Control
        }, {
            uniqueId: "editor:toolModeKeyBinding:showGameMenu",
            label: "resourcePack.editor.core.keyBinding.showGameMenu.title",
            tooltip: "resourcePack.editor.core.keyBinding.showGameMenu.tooltip"
        });
        uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.GlobalToolMode, showLoggingPaneAction, {
            key: server_editor_namespaceObject.KeyboardKey.KEY_H,
            modifier: server_editor_namespaceObject.InputModifier.Control
        }, {
            uniqueId: "editor:toolModeKeyBinding:showLogPanel",
            label: "resourcePack.editor.core.keyBinding.showLogPanel.title",
            tooltip: "resourcePack.editor.core.keyBinding.showLogPanel.tooltip"
        });
        const file = uiSession.menuBar.createMenu({
            label: "resourcePack.editor.menuBar.file",
            uniqueId: server_editor_namespaceObject.CoreMenuType.File,
            tooltip: "resourcePack.editor.menuBar.file.tooltip"
        });
        const edit = uiSession.menuBar.createMenu({
            label: "resourcePack.editor.menuBar.edit",
            uniqueId: server_editor_namespaceObject.CoreMenuType.Edit,
            tooltip: "resourcePack.editor.menuBar.edit.tooltip"
        });
        const extensions = uiSession.menuBar.createMenu({
            label: "resourcePack.editor.menuBar.extensions",
            uniqueId: server_editor_namespaceObject.CoreMenuType.Extensions
        });
        const view = uiSession.menuBar.createMenu({
            label: "resourcePack.editor.menuBar.view",
            uniqueId: server_editor_namespaceObject.CoreMenuType.View,
            tooltip: "resourcePack.editor.menuBar.view.tooltip"
        });
        const worldOptions = uiSession.menuBar.createMenu({
            label: "resourcePack.editor.menuBar.worldOptions",
            uniqueId: server_editor_namespaceObject.CoreMenuType.WorldOptions,
            tooltip: "resourcePack.editor.menuBar.worldOptions.tooltip"
        });
        const experimental = uiSession.menuBar.createMenu({
            label: "resourcePack.editor.menuBar.experimental",
            uniqueId: server_editor_namespaceObject.CoreMenuType.Experimental
        });
        const help = uiSession.menuBar.createMenu({
            label: "resourcePack.editor.menuBar.help",
            uniqueId: server_editor_namespaceObject.CoreMenuType.Help,
            tooltip: "resourcePack.editor.menuBar.help.tooltip"
        });
        view.addItem({
            label: "resourcePack.editor.menuBar.file.pauseScreen",
            tooltip: "resourcePack.editor.menuBar.file.pauseScreen.tooltip"
        }, pauseScreenAction);
        view.addItem({
            label: "resourcePack.editor.menuBar.view.logging",
            tooltip: "resourcePack.editor.menuBar.view.logging.tooltip"
        }, showLoggingPaneAction);
        if (!uiSession.scratchStorage.pauseBehavior) {
            throw new Error("pauseBehavior undefined - Core UI initialization order incorrect");
        }
        uiSession.scratchStorage.pauseBehavior.createPauseMenu(worldOptions);
        help.addItem({
            label: "resourcePack.editor.menuBar.help.tutorial",
            tooltip: "resourcePack.editor.menuBar.help.tutorial.tooltip"
        }, tutorialAction);
        help.addItem({
            label: "resourcePack.editor.menuBar.help.quickStart",
            tooltip: "resourcePack.editor.menuBar.help.quickStart.tooltip"
        }, quickStartAction);
        help.addItem({
            label: "resourcePack.editor.menuBar.help.documentation",
            tooltip: "resourcePack.editor.menuBar.help.documentation.tooltip",
            icon: "externalLinkIcon"
        }, documentationAction);
        help.addItem({
            label: "resourcePack.editor.menuBar.help.feedback",
            icon: "externalLinkIcon",
            tooltip: "resourcePack.editor.menuBar.help.feedback.tooltip"
        }, feedbackAction);
        help.addItem({
            label: "resourcePack.editor.menuBar.help.samples",
            icon: "externalLinkIcon",
            tooltip: "resourcePack.editor.menuBar.help.samples.tooltip"
        }, sampleAction);
        return {
            file,
            edit,
            extensions,
            view,
            worldOptions,
            experimental,
            help
        };
    }
    function addDimensionsMenuItems(uiSession, parentMenu) {
        const player = uiSession.extensionContext.player;
        const overworldAction = uiSession.actionManager.createAction({
            actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
            onExecute: () => {
                const rotation = player.getRotation();
                player.teleport(player.location, {
                    dimension: server_namespaceObject.world.getDimension("overworld"),
                    rotation,
                    keepVelocity: false
                });
            }
        });
        const netherAction = uiSession.actionManager.createAction({
            actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
            onExecute: () => {
                const rotation = player.getRotation();
                player.teleport(player.location, {
                    dimension: server_namespaceObject.world.getDimension("nether"),
                    rotation,
                    keepVelocity: false
                });
            }
        });
        const endAction = uiSession.actionManager.createAction({
            actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
            onExecute: () => {
                uiSession.extensionContext.transactionManager.openTransaction("Transaction dimension change");
                const rotation = player.getRotation();
                player.teleport(player.location, {
                    dimension: server_namespaceObject.world.getDimension("the_end"),
                    rotation,
                    keepVelocity: false
                });
                uiSession.extensionContext.transactionManager.commitOpenTransaction();
            }
        });
        const changeDimension = parentMenu.addItem({
            label: "resourcePack.editor.menuBar.worldOptions.changeDimension",
            tooltip: "resourcePack.editor.menuBar.worldOptions.changeDimension.tooltip"
        });
        changeDimension.addItem({
            label: "resourcePack.editor.menuBar.worldOptions.changeDimension.overworld"
        }, overworldAction);
        changeDimension.addItem({
            label: "resourcePack.editor.menuBar.worldOptions.changeDimension.nether"
        }, netherAction);
        changeDimension.addItem({
            label: "resourcePack.editor.menuBar.worldOptions.changeDimension.end"
        }, endAction);
    }
    function registerCoreEditorExtension() {
        (0, server_editor_namespaceObject.registerEditorExtension)("CoreEditor", (uiSession => {
            const baseSession = uiSession;
            uiSession.log.debug(`Initializing ${uiSession.extensionContext.extensionInfo.name} extension`);
            uiSession.scratchStorage = {
                cleanupHandles: []
            };
            uiSession.scratchStorage.pauseBehavior = new PauseBehavior(uiSession);
            uiSession.scratchStorage.coreMenuItems = createCoreUI(uiSession);
            const transactions = new UndoRedoBehavior(uiSession, uiSession.scratchStorage.coreMenuItems);
            const selectionBehavior = new SelectionBehavior(uiSession);
            const brushPainter = new BrushPainterBehavior(uiSession);
            const pencilTool = new PencilToolBehavior(uiSession, brushPainter.tool.id);
            uiSession.scratchStorage.copyPasteBehavior = new CopyPasteBehavior(uiSession, uiSession.scratchStorage.coreMenuItems.edit);
            uiSession.scratchStorage.newPastePreview = new PastePreviewBehavior(uiSession, selectionBehavior.toolId);
            uiSession.scratchStorage.deleteBehavior = new DeleteBehavior(uiSession, uiSession.scratchStorage.coreMenuItems);
            selectionBehavior.addDeselectAndFillMenuItems(uiSession);
            uiSession.scratchStorage.playerCountBehavior = new PlayerCountBehavior(uiSession);
            const playtest = new PlaytestBehavior(uiSession);
            const navigationStack = new NavigationStackBehavior(uiSession);
            const line = new LineBehavior(uiSession);
            const rulerTool = new RulerToolBehavior(uiSession);
            const navigation = new NavigationBehavior(uiSession, uiSession.scratchStorage.coreMenuItems.worldOptions);
            const locateTool = new LocateTool(uiSession, uiSession.scratchStorage.coreMenuItems.worldOptions);
            const timeOfDay = new TimeOfDayBehavior(uiSession, uiSession.scratchStorage.coreMenuItems.worldOptions);
            const vvBiomeBehavior = new VibrantVisualsPerBiomeBehavior(uiSession);
            const jigsawMode = new JigsawModeBehavior(uiSession);
            const prefabBehavior = new PrefabBehavior(uiSession);
            const weather = new WeatherBehavior(uiSession, uiSession.scratchStorage.coreMenuItems.worldOptions);
            addDimensionsMenuItems(uiSession, uiSession.scratchStorage.coreMenuItems.worldOptions);
            const chunkManager = new ChunkManagerBehavior(baseSession);
            chunkManager.createMenuItem(uiSession.scratchStorage.coreMenuItems.worldOptions);
            const exportBehavior = new ExportBehavior(uiSession, uiSession.scratchStorage.coreMenuItems.file);
            const smartFill = new SmartFillToolBehavior(uiSession);
            const terrain = new TerrainBehavior(uiSession);
            const extrudeTool = new ExtrudeTool(uiSession);
            const repeaterTool = new RepeaterTool(uiSession);
            const summonTool = new SummonTool(uiSession);
            const entityInspector = new EntityInspector(uiSession);
            const workbench = new WorkbenchBehavior(uiSession);
            const farmGeneratorTool = new FarmGeneratorTool(uiSession);
            const blockInspector = new BlockInspectorBehavior(uiSession);
            const floodTool = new FloodToolBehavior(uiSession);
            const scaleTool = new ScaleToolBehavior(uiSession);
            const cinematicTool = new CinematicToolBehavior(uiSession);
            const realmsUploadPane = new RealmsUpload(uiSession, uiSession.scratchStorage.coreMenuItems.file);
            const viewSettings = new SettingsBehavior(uiSession, uiSession.scratchStorage.coreMenuItems.file);
            const orbitLocation = new OrbitLocationBehavior(uiSession);
            const saveAndExitAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    uiSession.builtInUIManager.saveAndExit();
                }
            });
            uiSession.scratchStorage.coreMenuItems.file.addItem({
                label: "resourcePack.editor.menuBar.file.saveAndExit",
                tooltip: "resourcePack.editor.menuBar.file.saveAndExit.tooltip"
            }, saveAndExitAction);
            uiSession.log.debug("CoreEditor Extension Initialized\n");
            return [ selectionBehavior, uiSession.scratchStorage.deleteBehavior, uiSession.scratchStorage.playerCountBehavior, uiSession.scratchStorage.pauseBehavior, uiSession.scratchStorage.newPastePreview, uiSession.scratchStorage.copyPasteBehavior, transactions, playtest, navigationStack, line, summonTool, timeOfDay, navigation, weather, vvBiomeBehavior, jigsawMode, prefabBehavior, rulerTool, exportBehavior, brushPainter, locateTool, smartFill, terrain, extrudeTool, repeaterTool, farmGeneratorTool, viewSettings, workbench, blockInspector, entityInspector, realmsUploadPane, orbitLocation, pencilTool, floodTool, scaleTool, cinematicTool ];
        }), (uiSession => {
            uiSession.log.debug(`Shutting down ${uiSession.extensionContext.extensionInfo.name} Extension\n`);
            if (uiSession.scratchStorage) {
                uiSession.scratchStorage.cleanupHandles.forEach((handle => handle()));
            }
        }), {
            description: "Minecraft Core Editor Built-in Extensions",
            notes: "https://github.com/Mojang/minecraft-editor"
        });
    }
    function flyCameraToTarget(uiSession, target, viewTarget) {
        if (uiSession.scratchStorage) {
            const easeTimeInSeconds = uiSession.scratchStorage.easeTimeInSeconds;
            const player = uiSession.extensionContext.player;
            const playerPosition = player.location;
            const playerHeadPosition = player.getHeadLocation();
            const playerCameraPosition = lib.Vector3Utils.add(playerHeadPosition, uiSession.scratchStorage.cameraHeadOffset);
            const playerCameraDelta = lib.Vector3Utils.subtract(playerCameraPosition, playerPosition);
            const desiredDistance = 0;
            const direction = lib.Vector3Utils.subtract(target, playerCameraPosition);
            const normalizedDirection = lib.Vector3Utils.normalize(direction);
            const offset = lib.Vector3Utils.scale(normalizedDirection, desiredDistance);
            uiSession.scratchStorage.latestRunId = server_namespaceObject.system.runTimeout((() => {
                const cameraPositionOptions = {
                    easeOptions: {
                        easeTime: easeTimeInSeconds,
                        easeType: server_namespaceObject.EasingType.InOutQuad
                    },
                    facingLocation: viewTarget,
                    location: lib.Vector3Utils.add(target, offset)
                };
                player.camera.setCamera("minecraft:free", cameraPositionOptions);
            }), .1 * server_namespaceObject.TicksPerSecond);
            const newPlayerRotationTarget = lib.Vector3Utils.subtract(viewTarget, playerCameraDelta);
            const newPlayerPositionTarget = lib.Vector3Utils.subtract(target, playerCameraDelta);
            uiSession.scratchStorage.latestRunId = server_namespaceObject.system.runTimeout((() => {
                player.camera.setCamera("minecraft:first_person");
                player.teleport(newPlayerPositionTarget, {
                    facingLocation: newPlayerRotationTarget
                });
                if (uiSession.scratchStorage) {
                    uiSession.scratchStorage.latestRunId = undefined;
                }
            }), easeTimeInSeconds * server_namespaceObject.TicksPerSecond);
        }
    }
    function euclideanToManhattanDistance(euclideanDistance) {
        return euclideanDistance * Math.sqrt(3);
    }
    function registerGrappleExtension() {
        (0, server_editor_namespaceObject.registerEditorExtension)("Grapple", (uiSession => {
            uiSession.log.debug(`Initializing ${uiSession.extensionContext.extensionInfo.name} extension`);
            uiSession.scratchStorage = {
                latestRunId: undefined,
                easeTimeInSeconds: .75,
                playerFOV: 66,
                grappleDistance: uiSession.extensionContext.cursor.maxViewBlockDistance,
                cameraHeadOffset: {
                    x: 0,
                    y: .1,
                    z: 0
                }
            };
            const grappleAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (uiSession.scratchStorage?.latestRunId || !uiSession.scratchStorage?.grappleDistance) {
                        return;
                    }
                    const playerCameraPosition = lib.Vector3Utils.add(uiSession.extensionContext.player.getHeadLocation(), uiSession.scratchStorage.cameraHeadOffset);
                    const cursorRay = uiSession.extensionContext.cursor.getRay();
                    const rayDirection = lib.Vector3Utils.subtract(cursorRay.end, cursorRay.start);
                    const normalizedDirection = lib.Vector3Utils.normalize(rayDirection);
                    let cameraTarget = uiSession.extensionContext.player.location;
                    let positionTarget = uiSession.extensionContext.player.location;
                    if (cursorRay.hit === true) {
                        const blockHit = uiSession.extensionContext.player.dimension.getBlockFromRay(cursorRay.start, normalizedDirection, {
                            includePassableBlocks: true,
                            maxDistance: euclideanToManhattanDistance(uiSession.extensionContext.cursor.maxViewBlockDistance)
                        });
                        if (blockHit?.block) {
                            cameraTarget = blockHit.block.center();
                            positionTarget = lib.Vector3Utils.subtract(cameraTarget, lib.Vector3Utils.scale(lib.Vector3Utils.normalize(lib.Vector3Utils.subtract(cameraTarget, playerCameraPosition)), 3));
                            fireTelemetryEvent(uiSession.extensionContext.player, TelemetrySource.Grapple, "GrappleToBlock");
                        }
                    } else {
                        const length = lib.Vector3Utils.magnitude(rayDirection);
                        if (length < uiSession.scratchStorage.grappleDistance) {
                            cameraTarget = cursorRay.end;
                            positionTarget = cameraTarget;
                        } else {
                            cameraTarget = lib.Vector3Utils.add(cursorRay.start, lib.Vector3Utils.scale(normalizedDirection, uiSession.scratchStorage.grappleDistance + 2));
                            positionTarget = lib.Vector3Utils.add(cursorRay.start, lib.Vector3Utils.scale(normalizedDirection, uiSession.scratchStorage.grappleDistance));
                        }
                        fireTelemetryEvent(uiSession.extensionContext.player, TelemetrySource.Grapple, "GrappleDistance");
                    }
                    flyCameraToTarget(uiSession, positionTarget, cameraTarget);
                }
            });
            const frameAction = uiSession.actionManager.createAction({
                actionType: server_editor_namespaceObject.ActionTypes.NoArgsAction,
                onExecute: () => {
                    if (uiSession.scratchStorage?.latestRunId || !uiSession.scratchStorage) {
                        return;
                    }
                    if (uiSession.extensionContext.selectionManager.volume.isEmpty) {
                        return;
                    }
                    const bounds = uiSession.extensionContext.selectionManager.volume.getBoundingBox();
                    if (!bounds) {
                        return;
                    }
                    bounds.max = lib.Vector3Utils.add(bounds.max, {
                        x: 1,
                        y: 1,
                        z: 1
                    });
                    const cameraTarget = lib.Vector3Utils.scale(lib.Vector3Utils.add(bounds.min, bounds.max), .5);
                    const xEdge = (bounds.max.x - bounds.min.x) / 2;
                    const yEdge = (bounds.max.y - bounds.min.y) / 2;
                    const zEdge = (bounds.max.z - bounds.min.z) / 2;
                    const radiusToUse = (xEdge + yEdge + zEdge) / 3;
                    const halfFOV = uiSession.scratchStorage.playerFOV / 2;
                    const thetaInRadians = halfFOV / 2 * Math.PI / 180;
                    const targetDistanceDelta = radiusToUse / Math.tan(thetaInRadians);
                    const playerCameraPosition = lib.Vector3Utils.add(uiSession.extensionContext.player.getHeadLocation(), uiSession.scratchStorage.cameraHeadOffset);
                    const cameraDirection = lib.Vector3Utils.subtract(cameraTarget, playerCameraPosition);
                    const normalizedDirection = lib.Vector3Utils.normalize(cameraDirection);
                    const fullDistance = lib.Vector3Utils.magnitude(cameraDirection);
                    const desiredDistance = fullDistance - targetDistanceDelta;
                    const offset = lib.Vector3Utils.scale(normalizedDirection, desiredDistance);
                    const positionTarget = lib.Vector3Utils.add(playerCameraPosition, offset);
                    fireTelemetryEvent(uiSession.extensionContext.player, TelemetrySource.Grapple, "GrappleToSelection");
                    flyCameraToTarget(uiSession, positionTarget, cameraTarget);
                }
            });
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, grappleAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_G
            }, {
                uniqueId: "editor:viewportKeyBinding:flyToCursor",
                label: "resourcePack.editor.grapple.keyBinding.flyToCursor.title",
                tooltip: "resourcePack.editor.grapple.keyBinding.flyToCursor.tooltip"
            });
            uiSession.inputManager.registerKeyBinding(server_editor_namespaceObject.EditorInputContext.Viewport, frameAction, {
                key: server_editor_namespaceObject.KeyboardKey.KEY_F,
                modifier: server_editor_namespaceObject.InputModifier.Control | server_editor_namespaceObject.InputModifier.Shift
            }, {
                uniqueId: "editor:viewportKeyBinding:flyToSelection",
                label: "resourcePack.editor.grapple.keyBinding.flyToSelection.title",
                tooltip: "resourcePack.editor.grapple.keyBinding.flyToSelection.tooltip"
            });
            return [];
        }), (uiSession => {
            uiSession.log.debug(`Shutting down ${uiSession.extensionContext.extensionInfo.name} extension`);
            if (uiSession.scratchStorage?.latestRunId) {
                server_namespaceObject.system.clearRun(uiSession.scratchStorage.latestRunId);
                uiSession.scratchStorage.latestRunId = undefined;
            }
        }));
    }
    const TicksRefreshRate = 5;
    const UnknownBlockType = `--`;
    function getDeltaPosFormat(_delta) {
        return `Δ (${_delta?.x ?? UnknownBlockType},${_delta?.y ?? UnknownBlockType},${_delta?.z ?? UnknownBlockType})`;
    }
    const updateStatusBarText = (statusBarItem, playerLocation, extensionContext) => {
        let cursorDeltaFromPlayerText = "";
        let blockTypeText = UnknownBlockType;
        const cursorLocation = extensionContext.cursor.getPosition();
        if (extensionContext.cursor.isVisible) {
            cursorDeltaFromPlayerText = getDeltaPosFormat(lib.Vector3Utils.subtract(cursorLocation, playerLocation));
            try {
                const region = server_editor_private_bindings_namespaceObject.editorInternal.getPlayerServices(extensionContext.player).regionManager.getCursorRegion();
                blockTypeText = region.getBlockTypeId(cursorLocation) ?? UnknownBlockType;
            } catch {
                blockTypeText = UnknownBlockType;
            }
        } else {
            cursorDeltaFromPlayerText = getDeltaPosFormat();
        }
        statusBarItem.setText(`P (${Math.floor(playerLocation.x)},${Math.floor(playerLocation.y)},${Math.floor(playerLocation.z)}) | ${cursorDeltaFromPlayerText} | C (${Math.floor(cursorLocation.x)},${Math.floor(cursorLocation.y)},${Math.floor(cursorLocation.z)}) | ${blockTypeText}`);
    };
    function registerPlayerPositionExtension() {
        (0, server_editor_namespaceObject.registerEditorExtension)("PlayerPosition", (uiSession => {
            uiSession.log.debug(`Initializing ${uiSession.extensionContext.extensionInfo.name} extension`);
            uiSession.scratchStorage = {
                tickHandle: undefined
            };
            const player = uiSession.extensionContext.player;
            let currentPlayerLocation = player.location;
            let currentCursorLocation = uiSession.extensionContext.cursor.getPosition();
            const positionStatusItem = uiSession.statusBar.createItem({
                alignment: server_editor_namespaceObject.StatusBarAlignment.Left,
                icon: "informationIcon",
                size: 70
            });
            updateStatusBarText(positionStatusItem, currentPlayerLocation, uiSession.extensionContext);
            const onTick = () => {
                const playerLoc = lib.Vector3Utils.floor(player.location);
                const cursorLoc = lib.Vector3Utils.floor(uiSession.extensionContext.cursor.getPosition());
                if (!lib.Vector3Utils.equals(playerLoc, currentPlayerLocation) || !lib.Vector3Utils.equals(cursorLoc, currentCursorLocation)) {
                    currentPlayerLocation = playerLoc;
                    currentCursorLocation = cursorLoc;
                    updateStatusBarText(positionStatusItem, currentPlayerLocation, uiSession.extensionContext);
                }
            };
            if (uiSession.scratchStorage) {
                uiSession.scratchStorage.tickHandle = server_namespaceObject.system.runInterval(onTick, TicksRefreshRate);
            }
            return [];
        }), (uiSession => {
            if (uiSession.scratchStorage && uiSession.scratchStorage.tickHandle !== undefined) {
                server_namespaceObject.system.clearRun(uiSession.scratchStorage.tickHandle);
            }
            uiSession.log.debug(`Shutting down ${uiSession.extensionContext.extensionInfo.name} extension`);
        }), {
            description: "Keeps track of player position and allow to modify it into the pane."
        });
    }
    function waitForBlockLoaded(dimension, location, checkIntervalTicks = 20, timeoutTries = 20) {
        return new Promise(((resolve, reject) => {
            let tries = 0;
            const job = server_namespaceObject.system.runInterval((() => {
                tries++;
                if (timeoutTries !== undefined && tries > timeoutTries) {
                    server_namespaceObject.system.clearRun(job);
                    reject(new Error("Failed to load"));
                }
                try {
                    const block = dimension.getBlock(location);
                    if (block !== undefined) {
                        server_namespaceObject.system.clearRun(job);
                        resolve(block);
                    }
                } catch (e) {
                    server_namespaceObject.system.clearRun(job);
                    reject(e);
                }
            }), checkIntervalTicks);
        }));
    }
    function _setupTimeOfDay() {
        try {
            server_namespaceObject.world.getDimension("overworld").runCommand("alwaysday true");
            server_namespaceObject.world.setTimeOfDay(server_namespaceObject.TimeOfDay.Noon);
        } catch (_err) {
            server_editor_namespaceObject.editor.log.error("Editor::GlobalInitialize - Unable to adjust daylight cycle due to unknown error.", {
                channelMask: server_editor_namespaceObject.LogChannel.All
            });
        }
    }
    function _setupDefaultWeatherCycle() {
        const errorString = "Editor::GlobalInitialize - Unable to adjust weather cycle due to unknown error.";
        try {
            server_namespaceObject.world.gameRules.doWeatherCycle = false;
            server_namespaceObject.world.getDimension("overworld").setWeather(server_namespaceObject.WeatherType.Clear, 1e6);
        } catch (_err) {
            server_editor_namespaceObject.editor.log.error(errorString, {
                channelMask: server_editor_namespaceObject.LogChannel.All
            });
        }
    }
    function _setupVoidWorldPlatform() {
        if (server_editor_namespaceObject.editor.worldGeneratorType === server_editor_namespaceObject.WorldGeneratorType.Void) {
            server_editor_namespaceObject.editor.log.debug("Creating a courtesy platform for the void world");
            const overworld = server_namespaceObject.world.getDimension("overworld");
            const from = {
                x: -2,
                y: 0,
                z: -2
            };
            const to = {
                x: 2,
                y: 0,
                z: 4
            };
            const groundVolume = new server_namespaceObject.BlockVolume(from, to);
            const tickingAreaName = "void_world_platform";
            const tickFrom = "-1 0 -1";
            const tickTo = "1 0 1";
            const addResult = overworld.runCommand(`/tickingarea add ${tickFrom} ${tickTo} ${tickingAreaName}`);
            if (addResult.successCount === 0) {
                server_editor_namespaceObject.editor.log.error("Failed to create void world courtesy platform", {
                    channelMask: server_editor_namespaceObject.LogChannel.All
                });
            } else {
                waitForBlockLoaded(overworld, from).then((() => {
                    const quickCheck = overworld.getBlock(from);
                    if (quickCheck !== undefined && !quickCheck.matches(lib_vanilla_MinecraftBlockTypes.Air)) {
                        return;
                    }
                    overworld.fillBlocks(groundVolume, server_namespaceObject.BlockPermutation.resolve(lib_vanilla_MinecraftBlockTypes.GrassBlock));
                    const signLocation = {
                        x: 0,
                        y: 1,
                        z: 3
                    };
                    const signBlock = overworld.getBlock(signLocation);
                    if (signBlock === undefined) {
                        server_editor_namespaceObject.editor.log.warning("Failed to create the sign on the courtesy platform");
                        return;
                    }
                    const signPermutation = server_namespaceObject.BlockPermutation.resolve(lib_vanilla_MinecraftBlockTypes.StandingSign);
                    signBlock.setPermutation(signPermutation);
                    const signComponent = signBlock.getComponent("minecraft:sign");
                    if (signComponent && "setText" in signComponent) {
                        signComponent.setText({
                            rawtext: [ {
                                translate: "resourcePack.editor.voidWorld.signMessage1"
                            }, {
                                text: "\n"
                            }, {
                                translate: "resourcePack.editor.voidWorld.signMessage2"
                            } ]
                        }, server_namespaceObject.SignSide.Back);
                    }
                })).catch((() => {
                    server_editor_namespaceObject.editor.log.error("Failed to write the courtesy platform blocks to the world", {
                        channelMask: server_editor_namespaceObject.LogChannel.All
                    });
                })).finally((() => {
                    overworld.runCommand(`/tickingarea remove ${tickingAreaName}`);
                }));
            }
        }
    }
    function _setupSimulationState() {
        const propKey = "editor:simulationState";
        const foundSimulationState = server_namespaceObject.world.getDynamicProperty(propKey);
        if (foundSimulationState !== undefined && typeof foundSimulationState === "boolean") {
            server_editor_namespaceObject.editor.simulation.setPaused(foundSimulationState);
        }
        server_editor_namespaceObject.editor.afterEvents.simulationStateChange.subscribe((evt => {
            server_namespaceObject.world.setDynamicProperty(propKey, evt.paused);
        }));
    }
    function runOnceEditorInitialization() {
        if (server_editor_private_bindings_namespaceObject.editorInternal.isNewLevel) {
            _setupTimeOfDay();
            _setupDefaultWeatherCycle();
            _setupVoidWorldPlatform();
        }
        _setupSimulationState();
    }
    server_namespaceObject.world.afterEvents.worldLoad.subscribe((() => {
        runOnceEditorInitialization();
    }));
    registerCoreEditorExtension();
    registerPlayerPositionExtension();
    registerGrappleExtension();
})();