(() => { var e = { 77: (e, t, n) => { "use strict"; e.exports = n.p + "images/rotation_axis_x_positive.svg" }, 493: (e, t, n) => { "use strict"; e.exports = n.p + "images/empty.svg" }, 516: (e, t, n) => { "use strict"; e.exports = n.p + "images/arrow_down.svg" }, 540: e => { "use strict"; e.exports = function(e) { var t = document.createElement("style"); return e.setAttributes(t, e.attributes), e.insert(t, e.options), t } }, 813: (e, t, n) => { "use strict"; e.exports = n.p + "images/winter.svg" }, 853: (e, t, n) => { "use strict"; e.exports = n.p + "images/icon.svg" }, 858: (e, t, n) => { "use strict"; e.exports = n.p + "images/discord.svg" }, 1113: e => { "use strict"; e.exports = function(e, t) { if (t.styleSheet) t.styleSheet.cssText = e; else { for (; t.firstChild;) t.removeChild(t.firstChild); t.appendChild(document.createTextNode(e)) } } }, 1312: (e, t, n) => { var i; /** * [js-sha256]{@link https://github.com/emn178/js-sha256} * * @version 0.11.0 * @author Chen, Yi-Cyuan [emn178@gmail.com] * @copyright Chen, Yi-Cyuan 2014-2024 * @license MIT */ ! function() { "use strict"; var t = "input is invalid type", r = "object" == typeof window, a = r ? window : {}; a.JS_SHA256_NO_WINDOW && (r = !1); var s = !r && "object" == typeof self, o = !a.JS_SHA256_NO_NODE_JS && "object" == typeof process && process.versions && process.versions.node; o ? a = n.g : s && (a = self); var l = !a.JS_SHA256_NO_COMMON_JS && e.exports, c = n.amdO, h = !a.JS_SHA256_NO_ARRAY_BUFFER && "undefined" != typeof ArrayBuffer, d = "0123456789abcdef".split(""), u = [-2147483648, 8388608, 32768, 128], p = [24, 16, 8, 0], f = [1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298], m = ["hex", "array", "digest", "arrayBuffer"], g = []; !a.JS_SHA256_NO_NODE_JS && Array.isArray || (Array.isArray = function(e) { return "[object Array]" === Object.prototype.toString.call(e) }), !h || !a.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW && ArrayBuffer.isView || (ArrayBuffer.isView = function(e) { return "object" == typeof e && e.buffer && e.buffer.constructor === ArrayBuffer }); var v = function(e, t) { return function(n) { return new x(t, !0).update(n)[e]() } }, w = function(e) { var t = v("hex", e); o && (t = y(t, e)), t.create = function() { return new x(e) }, t.update = function(e) { return t.create().update(e) }; for (var n = 0; n < m.length; ++n) { var i = m[n]; t[i] = v(i, e) } return t }, y = function(e, i) { var r, s = n(4394), o = n(1903).Buffer, l = i ? "sha224" : "sha256"; r = o.from && !a.JS_SHA256_NO_BUFFER_FROM ? o.from : function(e) { return new o(e) }; return function(n) { if ("string" == typeof n) return s.createHash(l).update(n, "utf8").digest("hex"); if (null == n) throw new Error(t); return n.constructor === ArrayBuffer && (n = new Uint8Array(n)), Array.isArray(n) || ArrayBuffer.isView(n) || n.constructor === o ? s.createHash(l).update(r(n)).digest("hex") : e(n) } }, A = function(e, t) { return function(n, i) { return new k(n, t, !0).update(i)[e]() } }, b = function(e) { var t = A("hex", e); t.create = function(t) { return new k(t, e) }, t.update = function(e, n) { return t.create(e).update(n) }; for (var n = 0; n < m.length; ++n) { var i = m[n]; t[i] = A(i, e) } return t }; function x(e, t) { t ? (g[0] = g[16] = g[1] = g[2] = g[3] = g[4] = g[5] = g[6] = g[7] = g[8] = g[9] = g[10] = g[11] = g[12] = g[13] = g[14] = g[15] = 0, this.blocks = g) : this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], e ? (this.h0 = 3238371032, this.h1 = 914150663, this.h2 = 812702999, this.h3 = 4144912697, this.h4 = 4290775857, this.h5 = 1750603025, this.h6 = 1694076839, this.h7 = 3204075428) : (this.h0 = 1779033703, this.h1 = 3144134277, this.h2 = 1013904242, this.h3 = 2773480762, this.h4 = 1359893119, this.h5 = 2600822924, this.h6 = 528734635, this.h7 = 1541459225), this.block = this.start = this.bytes = this.hBytes = 0, this.finalized = this.hashed = !1, this.first = !0, this.is224 = e } function k(e, n, i) { var r, a = typeof e; if ("string" === a) { var s, o = [], l = e.length, c = 0; for (r = 0; r < l; ++r)(s = e.charCodeAt(r)) < 128 ? o[c++] = s : s < 2048 ? (o[c++] = 192 | s >>> 6, o[c++] = 128 | 63 & s) : s < 55296 || s >= 57344 ? (o[c++] = 224 | s >>> 12, o[c++] = 128 | s >>> 6 & 63, o[c++] = 128 | 63 & s) : (s = 65536 + ((1023 & s) << 10 | 1023 & e.charCodeAt(++r)), o[c++] = 240 | s >>> 18, o[c++] = 128 | s >>> 12 & 63, o[c++] = 128 | s >>> 6 & 63, o[c++] = 128 | 63 & s); e = o } else { if ("object" !== a) throw new Error(t); if (null === e) throw new Error(t); if (h && e.constructor === ArrayBuffer) e = new Uint8Array(e); else if (!(Array.isArray(e) || h && ArrayBuffer.isView(e))) throw new Error(t) } e.length > 64 && (e = new x(n, !0).update(e).array()); var d = [], u = []; for (r = 0; r < 64; ++r) { var p = e[r] || 0; d[r] = 92 ^ p, u[r] = 54 ^ p } x.call(this, n, i), this.update(u), this.oKeyPad = d, this.inner = !0, this.sharedMemory = i } x.prototype.update = function(e) { if (!this.finalized) { var n, i = typeof e; if ("string" !== i) { if ("object" !== i) throw new Error(t); if (null === e) throw new Error(t); if (h && e.constructor === ArrayBuffer) e = new Uint8Array(e); else if (!(Array.isArray(e) || h && ArrayBuffer.isView(e))) throw new Error(t); n = !0 } for (var r, a, s = 0, o = e.length, l = this.blocks; s < o;) { if (this.hashed && (this.hashed = !1, l[0] = this.block, this.block = l[16] = l[1] = l[2] = l[3] = l[4] = l[5] = l[6] = l[7] = l[8] = l[9] = l[10] = l[11] = l[12] = l[13] = l[14] = l[15] = 0), n) for (a = this.start; s < o && a < 64; ++s) l[a >>> 2] |= e[s] << p[3 & a++]; else for (a = this.start; s < o && a < 64; ++s)(r = e.charCodeAt(s)) < 128 ? l[a >>> 2] |= r << p[3 & a++] : r < 2048 ? (l[a >>> 2] |= (192 | r >>> 6) << p[3 & a++], l[a >>> 2] |= (128 | 63 & r) << p[3 & a++]) : r < 55296 || r >= 57344 ? (l[a >>> 2] |= (224 | r >>> 12) << p[3 & a++], l[a >>> 2] |= (128 | r >>> 6 & 63) << p[3 & a++], l[a >>> 2] |= (128 | 63 & r) << p[3 & a++]) : (r = 65536 + ((1023 & r) << 10 | 1023 & e.charCodeAt(++s)), l[a >>> 2] |= (240 | r >>> 18) << p[3 & a++], l[a >>> 2] |= (128 | r >>> 12 & 63) << p[3 & a++], l[a >>> 2] |= (128 | r >>> 6 & 63) << p[3 & a++], l[a >>> 2] |= (128 | 63 & r) << p[3 & a++]); this.lastByteIndex = a, this.bytes += a - this.start, a >= 64 ? (this.block = l[16], this.start = a - 64, this.hash(), this.hashed = !0) : this.start = a } return this.bytes > 4294967295 && (this.hBytes += this.bytes / 4294967296 | 0, this.bytes = this.bytes % 4294967296), this } }, x.prototype.finalize = function() { if (!this.finalized) { this.finalized = !0; var e = this.blocks, t = this.lastByteIndex; e[16] = this.block, e[t >>> 2] |= u[3 & t], this.block = e[16], t >= 56 && (this.hashed || this.hash(), e[0] = this.block, e[16] = e[1] = e[2] = e[3] = e[4] = e[5] = e[6] = e[7] = e[8] = e[9] = e[10] = e[11] = e[12] = e[13] = e[14] = e[15] = 0), e[14] = this.hBytes << 3 | this.bytes >>> 29, e[15] = this.bytes << 3, this.hash() } }, x.prototype.hash = function() { var e, t, n, i, r, a, s, o, l, c = this.h0, h = this.h1, d = this.h2, u = this.h3, p = this.h4, m = this.h5, g = this.h6, v = this.h7, w = this.blocks; for (e = 16; e < 64; ++e) t = ((r = w[e - 15]) >>> 7 | r << 25) ^ (r >>> 18 | r << 14) ^ r >>> 3, n = ((r = w[e - 2]) >>> 17 | r << 15) ^ (r >>> 19 | r << 13) ^ r >>> 10, w[e] = w[e - 16] + t + w[e - 7] + n | 0; for (l = h & d, e = 0; e < 64; e += 4) this.first ? (this.is224 ? (a = 300032, v = (r = w[0] - 1413257819) - 150054599 | 0, u = r + 24177077 | 0) : (a = 704751109, v = (r = w[0] - 210244248) - 1521486534 | 0, u = r + 143694565 | 0), this.first = !1) : (t = (c >>> 2 | c << 30) ^ (c >>> 13 | c << 19) ^ (c >>> 22 | c << 10), i = (a = c & h) ^ c & d ^ l, v = u + (r = v + (n = (p >>> 6 | p << 26) ^ (p >>> 11 | p << 21) ^ (p >>> 25 | p << 7)) + (p & m ^ ~p & g) + f[e] + w[e]) | 0, u = r + (t + i) | 0), t = (u >>> 2 | u << 30) ^ (u >>> 13 | u << 19) ^ (u >>> 22 | u << 10), i = (s = u & c) ^ u & h ^ a, g = d + (r = g + (n = (v >>> 6 | v << 26) ^ (v >>> 11 | v << 21) ^ (v >>> 25 | v << 7)) + (v & p ^ ~v & m) + f[e + 1] + w[e + 1]) | 0, t = ((d = r + (t + i) | 0) >>> 2 | d << 30) ^ (d >>> 13 | d << 19) ^ (d >>> 22 | d << 10), i = (o = d & u) ^ d & c ^ s, m = h + (r = m + (n = (g >>> 6 | g << 26) ^ (g >>> 11 | g << 21) ^ (g >>> 25 | g << 7)) + (g & v ^ ~g & p) + f[e + 2] + w[e + 2]) | 0, t = ((h = r + (t + i) | 0) >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10), i = (l = h & d) ^ h & u ^ o, p = c + (r = p + (n = (m >>> 6 | m << 26) ^ (m >>> 11 | m << 21) ^ (m >>> 25 | m << 7)) + (m & g ^ ~m & v) + f[e + 3] + w[e + 3]) | 0, c = r + (t + i) | 0, this.chromeBugWorkAround = !0; this.h0 = this.h0 + c | 0, this.h1 = this.h1 + h | 0, this.h2 = this.h2 + d | 0, this.h3 = this.h3 + u | 0, this.h4 = this.h4 + p | 0, this.h5 = this.h5 + m | 0, this.h6 = this.h6 + g | 0, this.h7 = this.h7 + v | 0 }, x.prototype.hex = function() { this.finalize(); var e = this.h0, t = this.h1, n = this.h2, i = this.h3, r = this.h4, a = this.h5, s = this.h6, o = this.h7, l = d[e >>> 28 & 15] + d[e >>> 24 & 15] + d[e >>> 20 & 15] + d[e >>> 16 & 15] + d[e >>> 12 & 15] + d[e >>> 8 & 15] + d[e >>> 4 & 15] + d[15 & e] + d[t >>> 28 & 15] + d[t >>> 24 & 15] + d[t >>> 20 & 15] + d[t >>> 16 & 15] + d[t >>> 12 & 15] + d[t >>> 8 & 15] + d[t >>> 4 & 15] + d[15 & t] + d[n >>> 28 & 15] + d[n >>> 24 & 15] + d[n >>> 20 & 15] + d[n >>> 16 & 15] + d[n >>> 12 & 15] + d[n >>> 8 & 15] + d[n >>> 4 & 15] + d[15 & n] + d[i >>> 28 & 15] + d[i >>> 24 & 15] + d[i >>> 20 & 15] + d[i >>> 16 & 15] + d[i >>> 12 & 15] + d[i >>> 8 & 15] + d[i >>> 4 & 15] + d[15 & i] + d[r >>> 28 & 15] + d[r >>> 24 & 15] + d[r >>> 20 & 15] + d[r >>> 16 & 15] + d[r >>> 12 & 15] + d[r >>> 8 & 15] + d[r >>> 4 & 15] + d[15 & r] + d[a >>> 28 & 15] + d[a >>> 24 & 15] + d[a >>> 20 & 15] + d[a >>> 16 & 15] + d[a >>> 12 & 15] + d[a >>> 8 & 15] + d[a >>> 4 & 15] + d[15 & a] + d[s >>> 28 & 15] + d[s >>> 24 & 15] + d[s >>> 20 & 15] + d[s >>> 16 & 15] + d[s >>> 12 & 15] + d[s >>> 8 & 15] + d[s >>> 4 & 15] + d[15 & s]; return this.is224 || (l += d[o >>> 28 & 15] + d[o >>> 24 & 15] + d[o >>> 20 & 15] + d[o >>> 16 & 15] + d[o >>> 12 & 15] + d[o >>> 8 & 15] + d[o >>> 4 & 15] + d[15 & o]), l }, x.prototype.toString = x.prototype.hex, x.prototype.digest = function() { this.finalize(); var e = this.h0, t = this.h1, n = this.h2, i = this.h3, r = this.h4, a = this.h5, s = this.h6, o = this.h7, l = [e >>> 24 & 255, e >>> 16 & 255, e >>> 8 & 255, 255 & e, t >>> 24 & 255, t >>> 16 & 255, t >>> 8 & 255, 255 & t, n >>> 24 & 255, n >>> 16 & 255, n >>> 8 & 255, 255 & n, i >>> 24 & 255, i >>> 16 & 255, i >>> 8 & 255, 255 & i, r >>> 24 & 255, r >>> 16 & 255, r >>> 8 & 255, 255 & r, a >>> 24 & 255, a >>> 16 & 255, a >>> 8 & 255, 255 & a, s >>> 24 & 255, s >>> 16 & 255, s >>> 8 & 255, 255 & s]; return this.is224 || l.push(o >>> 24 & 255, o >>> 16 & 255, o >>> 8 & 255, 255 & o), l }, x.prototype.array = x.prototype.digest, x.prototype.arrayBuffer = function() { this.finalize(); var e = new ArrayBuffer(this.is224 ? 28 : 32), t = new DataView(e); return t.setUint32(0, this.h0), t.setUint32(4, this.h1), t.setUint32(8, this.h2), t.setUint32(12, this.h3), t.setUint32(16, this.h4), t.setUint32(20, this.h5), t.setUint32(24, this.h6), this.is224 || t.setUint32(28, this.h7), e }, k.prototype = new x, k.prototype.finalize = function() { if (x.prototype.finalize.call(this), this.inner) { this.inner = !1; var e = this.array(); x.call(this, this.is224, this.sharedMemory), this.update(this.oKeyPad), this.update(e), x.prototype.finalize.call(this) } }; var E = w(); E.sha256 = E, E.sha224 = w(!0), E.sha256.hmac = b(), E.sha224.hmac = b(!0), l ? e.exports = E : (a.sha256 = E.sha256, a.sha224 = E.sha224, c && (void 0 === (i = function() { return E }.call(E, n, E, e)) || (e.exports = i))) }() }, 1333: (e, t, n) => { "use strict"; e.exports = n.p + "images/helmet.svg" }, 1465: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.input-visualizer {\n position: absolute;\n left: 0;\n bottom: 64px;\n margin: 10px;\n padding: 0;\n --size: 96px;\n width: calc(var(--size) * 3);\n height: calc(var(--size) * 2);\n opacity: 0.9;\n}\n\n.input-visualizer > div {\n position: absolute;\n margin: 0;\n padding: 0;\n width: var(--size);\n height: var(--size);\n background-color: var(--surface-color);\n}\n\n.input-visualizer > .arrow-up {\n left: var(--size);\n top: 0;\n}\n\n.input-visualizer > .arrow-right {\n left: calc(var(--size) * 2);\n top: var(--size);\n}\n\n.input-visualizer > .arrow-down {\n left: var(--size);\n top: var(--size);\n}\n\n.input-visualizer > .arrow-left {\n left: 0;\n top: var(--size);\n}\n\n.input-visualizer > div.active {\n background-color: var(--surface-tertiary-color);\n}\n\n.input-visualizer > div > img {\n margin: 0;\n padding: 20px;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n}\n.input-visualizer > div.active > img {\n padding: 25px;\n}", ""]); const o = s }, 1601: e => { "use strict"; e.exports = function(e) { return e[1] } }, 1643: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, '\n.settings-menu {\n\tposition: absolute;\n\tleft: calc(50% - 800px / 2);\n\ttop: 0;\n\tz-index: 2;\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 800px;\n\theight: 100%;\n\ttext-align: left;\n\tdisplay: flex;\n\tflex-direction: column;\n\tbackground-color: var(--surface-color);\n}\n\n.settings-menu > h2 {\n\tmargin: 10px;\n\tpadding: 0;\n\tfont-weight: normal;\n\tfont-size: 38px;\n\ttext-align: center;\n\tcolor: var(--text-color);\n}\n\n.settings-menu > .container {\n\tmargin: 0;\n\tpadding: 0;\n\tflex-grow: 1;\n\tbackground-color: var(--surface-secondary-color);\n\toverflow-y: scroll;\n\tpointer-events: auto;\n}\n\n.settings-menu > .container > h2 {\n\tmargin: 10px;\n\tpadding: 4px;\n\tfont-weight: normal;\n\tfont-size: 24px;\n\tcolor: var(--text-color);\n\tborder-bottom: 2px solid var(--text-color);\n}\n\n.settings-menu > .container > h3 {\n\tmargin: 10px 10px 10px 15px;\n\tpadding: 4px;\n\tfont-weight: normal;\n\tfont-size: 22px;\n\tcolor: var(--text-color);\n\tborder-bottom: 2px solid var(--text-color);\n}\n\n.settings-menu > .container > .setting {\n\tmargin: 10px;\n\tdisplay: flex;\n}\n\n.settings-menu > .container > .setting > p {\n\tdisplay: inline-block;\n\tmargin: 10px;\n\tpadding: 0;\n\tmin-width: 0;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\tflex-grow: 1;\n\tfont-size: 28px;\n\ttext-align: left;\n\tcolor: var(--text-color);\n}\n\n.settings-menu > .container > .setting > .button-wrapper {\n\twhite-space: nowrap;\n}\n.settings-menu > .container > .setting.wrappable > .button-wrapper {\n\twhite-space: normal;\n}\n.settings-menu > .container > .setting.wrappable > .button-wrapper > button {\n\tmargin-bottom: 8px;\n\twidth: calc(100% / 4);\n\tfont-size: 23px;\n}\n\n.settings-menu > .container > .setting > .button-wrapper > button {\n\theight: 48px;\n\twhite-space: nowrap;\n}\n.settings-menu > .container > .setting > .button-wrapper > button.selected {\n\tbackground-color: var(--button-hover-color);\n}\n.settings-menu > .container > .setting > .button-wrapper > button.key-binding {\n\twidth: 210px;\n\tfont-size: 22px;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\tvertical-align: top;\n}\n\n.settings-menu > .container > .setting > input[type="range"] {\n\tmargin: 0 20px;\n\twidth: 390px;\n}\n\n.settings-menu > .button-wrapper > .button {\n\tmargin: 10px 0;\n}\n\n.settings-menu > .button-wrapper > .button:first-of-type {\n\tmargin-left: 10px;\n}\n\n.settings-menu > .button-wrapper > .button:last-of-type {\n\tmargin-right: 10px;\n}\n\n.settings-menu > .button-wrapper > .button > img {\n\tmargin-top: -3px;\n}\n\n.settings-menu > .button-wrapper > .apply {\n\tfloat: right;\n}\n', ""]); const o = s }, 1705: (e, t, n) => { "use strict"; e.exports = n.p + "images/desert.svg" }, 1719: (e, t, n) => { "use strict"; e.exports = n.p + "images/reset.svg" }, 1734: (e, t, n) => { "use strict"; e.exports = n.p + "images/test.svg" }, 1758: (e, t, n) => { "use strict"; e.exports = n.p + "images/desert_colored.svg" }, 1784: (e, t, n) => { "use strict"; e.exports = n.p + "images/cancel.svg" }, 1903: () => {}, 1925: (e, t, n) => { "use strict"; e.exports = n.p + "images/copy.svg" }, 1936: (e, t, n) => { "use strict"; e.exports = n.p + "images/erase.svg" }, 1997: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, '\n.editor-track-settings > .background {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\tz-index: 1;\n\twidth: 100%;\n\theight: 100%;\n\tbackground-color: rgba(20, 20, 30, 0.5);\n\tpointer-events: auto;\n}\n\n.editor-track-settings > .container {\n\tposition: absolute;\n\tleft: calc(50% - 600px / 2);\n\ttop: 0;\n\tz-index: 2;\n\tdisplay: flex;\n\tflex-direction: column;\n\tbox-sizing: border-box;\n\twidth: 600px;\n\theight: 100%;\n\tbackground-color: var(--surface-color);\n}\n\n.editor-track-settings > .container > h1 {\n\tmargin: 10px;\n\tpadding: 0;\n\tfont-weight: normal;\n\tfont-size: 38px;\n\ttext-align: center;\n\tcolor: var(--text-color);\n}\n\n.editor-track-settings > .container > .content {\n\tflex-grow: 1;\n\tbackground-color: var(--surface-secondary-color);\n\toverflow-y: auto;\n\tpointer-events: auto;\n}\n\n.editor-track-settings > .container > .content > .setting {\n\tmargin: 20px;\n\tpadding: 20px;\n\tbackground-color: var(--surface-color);\n\toutline: 2px solid transparent;\n\ttransition: outline 0.25s ease-in-out;\n}\n\n.editor-track-settings > .container > .content > .setting.error {\n\toutline: 2px solid #e34c4c;\n}\n\n.editor-track-settings > .container > .content > .setting > .title {\n\tdisplay: block;\n\tmargin: 0;\n\tpadding: 0;\n\tfont-size: 30px;\n\tcolor: var(--text-color);\n}\n.editor-track-settings > .container > .content > .setting > input[type="text"] {\n\twidth: calc(100% - 20px);\n\tfont-weight: normal;\n\tfont-size: 30px;\n}\n\n.editor-track-settings > .container > .content > .setting > .environment-button {\n\tdisplay: inline-block;\n\tmargin: 10px 0;\n\tpadding: 10px;\n\twidth: calc(100% / 3);\n\tcolor: var(--text-color);\n\tfont-size: 27px;\n}\n.editor-track-settings > .container > .content > .setting > .environment-button.selected {\n\tbackground-color: var(--button-hover-color);\n}\n.editor-track-settings > .container > .content > .setting > .environment-button > img {\n\tmargin: 0;\n\tpadding: 10px 30px;\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpointer-events: none;\n}\n\n.editor-track-settings > .container > .content > .setting > input[type="range"] {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n\theight: 64px;\n\t-webkit-appearance: none;\n\tappearance: none;\n\tbackground: transparent;\n\tcursor: pointer;\n\taccent-color: var(--text-color);\n}\n.editor-track-settings > .container > .content > .setting > input[type="range"]::-webkit-slider-runnable-track {\n\tbackground-color: var(--surface-tertiary-color);\n\theight: 10px;\n}\n.editor-track-settings > .container > .content > .setting > input[type="range"]::-moz-range-track {\n\tbackground-color: var(--surface-tertiary-color);\n\theight: 10px;\n}\n.editor-track-settings > .container > .content > .setting > input[type="range"]::-webkit-slider-thumb {\n\t-webkit-appearance: none;\n\tappearance: none;\n\tborder-radius: 0;\n\tbackground: var(--text-color);\n\twidth: 32px;\n\theight: 32px;\n\tmargin: -13px 0 0 0;\n\tborder: 4px solid var(--button-color);\n\toutline: 2px solid var(--text-color);\n}\n.editor-track-settings > .container > .content > .setting > input[type="range"]::-webkit-slider-thumb:hover {\n\tborder: 4px solid var(--button-hover-color);\n}\n@media (hover: none) {\n\t.editor-track-settings > .container > .content > .setting > input[type="range"]::-webkit-slider-thumb:hover {\n\t\tborder: 4px solid var(--button-color);\n\t}\n}\n.editor-track-settings > .container > .content > .setting > input[type="range"]::-webkit-slider-thumb:active {\n\tborder: 4px solid var(--button-active-color);\n}\n.editor-track-settings > .container > .content > .setting > input[type="range"]::-moz-range-thumb {\n\t-webkit-appearance: none;\n\tappearance: none;\n\tborder-radius: 0;\n\tbackground: var(--text-color);\n\twidth: 24px;\n\theight: 24px;\n\tborder: 4px solid var(--button-color);\n\toutline: 2px solid var(--text-color);\n}\n.editor-track-settings > .container > .content > .setting > input[type="range"]::-moz-range-thumb:hover {\n\tborder: 4px solid var(--button-hover-color);\n}\n@media (hover: none) {\n\t.editor-track-settings > .container > .content > .setting > input[type="range"]::-moz-range-thumb:hover {\n\t\tborder: 4px solid var(--button-color);\n\t}\n}\n.editor-track-settings > .container > .content > .setting > input[type="range"]::-moz-range-thumb:active {\n\tborder: 4px solid var(--button-active-color);\n}\n\n\n.editor-track-settings > .container > .button-wrapper > button {\n\tmargin: 10px;\n}\n\n.editor-track-settings > .container > .button-wrapper > button:not(:first-child) {\n\tfloat: right;\n}\n', ""]); const o = s }, 2175: (e, t, n) => { "use strict"; e.exports = n.p + "images/random.svg" }, 2207: (e, t, n) => { "use strict"; e.exports = n.p + "images/arrow_up.svg" }, 2208: (e, t, n) => { "use strict"; e.exports = n.p + "2e5b7bff10d7782e539c.woff" }, 2319: (e, t, n) => { "use strict"; e.exports = n.p + "images/delete.svg" }, 2344: (e, t, n) => { "use strict"; e.exports = n.p + "images/car_stripe.svg" }, 2346: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.editor-side-toolbar {\n\tdisplay: flex;\n\tflex-direction: column;\n\tposition: absolute;\n\tbottom: 40px;\n\tleft: 0;\n}\n.editor-side-toolbar.touch {\n\tbottom: 176px;\n}\n\n.editor-side-toolbar > .accordion {\n\tdisplay: flex;\n\tflex-direction: row;\n\twidth: 100px;\n\toverflow: hidden; /* Use hidden if clip is not supported */\n\toverflow: clip;\n\ttransition: width 0.25s ease-out;\n}\n.editor-side-toolbar.touch > .accordion {\n\twidth: 120px;\n}\n.editor-side-toolbar > .accordion.open {\n\twidth: auto;\n}\n\n.editor-side-toolbar button {\n\tposition: relative;\n\tflex-shrink: 0;\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100px;\n\theight: 100px;\n\tbackground-color: rgba(17, 32, 82, 0.48);\n\tborder: none;\n\tpointer-events: auto;\n\tcursor: pointer;\n\ttransition: background-color 0.25s ease-out;\n}\n.editor-side-toolbar button:hover {\n\tbackground-color: rgba(37, 54, 105, 0.48);\n}\n.editor-side-toolbar > .accordion > button:not(:first-of-type) {\n\tbackground-color: rgba(17, 32, 82, 0.35);\n}\n.editor-side-toolbar > .accordion > button:not(:first-of-type):hover {\n\tbackground-color: rgba(37, 54, 105, 0.35);\n}\n.editor-side-toolbar > .accordion > button:not(:first-of-type).selected {\n\tbackground-color: rgba(17, 32, 82, 0.55);\n}\n.editor-side-toolbar > .accordion > button:not(:first-of-type):active {\n\tbackground-color: rgba(17, 32, 82, 0.6);\n}\n@media (hover: none) {\n\t.editor-side-toolbar button:hover {\n\t\tbackground-color: rgba(17, 32, 82, 0.48);\n\t}\n}\n.editor-side-toolbar button:active {\n\tbackground-color: rgba(17, 32, 82, 0.6);\n\ttransition: none;\n}\n\n.editor-side-toolbar.touch button {\n\twidth: 120px;\n\theight: 120px;\n}\n\n.editor-side-toolbar button img {\n\tmargin: 0;\n\tpadding: 20%;\n\tvertical-align: top;\n\twidth: 100%;\n height: 100%;\n\tbox-sizing: border-box;\n\tpointer-events: none;\n\ttransition: transform 0.25s ease-out;\n\tfilter: drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.5));\n}\n.editor-side-toolbar button:active img {\n\ttransition: none;\n\ttransform: scale(0.9);\n}\n\n.editor-side-toolbar button.rotate > span {\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 1px;\n\twidth: 100%;\n\theight: 100%;\n\tcolor: var(--text-color);\n\tfont-size: 16px;\n\ttext-shadow: 0 0 2px #000;\n\tpointer-events: none;\n\ttransition: transform 0.25s ease-out;\n}\n.editor-side-toolbar button.rotate:active > span {\n\ttransition: none;\n\ttransform: scale(0.9);\n}\n", ""]); const o = s }, 2493: (e, t, n) => { "use strict"; e.exports = n.p + "images/overlapping_enabled.svg" }, 2553: (e, t, n) => { "use strict"; e.exports = n.p + "images/state_invalid.svg" }, 2709: (e, t, n) => { "use strict"; e.exports = n.p + "images/custom_tracks.jpg" }, 2796: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, '\n.verifier-ui {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\tz-index: 2;\n\tmargin: 0;\n\tpadding: 16px;\n\twidth: 100%;\n\theight: 100%;\n\toverflow-y: scroll;\n\tbox-sizing: border-box;\n\tbackground-color: var(--surface-color);\n\tpointer-events: auto;\n}\n\n.verifier-ui > p {\n\tmargin: 16px 4px 0 4px;\n\tpadding: 0;\n\tfont-size: 20px;\n\tcolor: var(--text-color);\n\twhite-space: pre-wrap;\n}\n\n.verifier-ui > input[type="range"] {\n\tmargin: 16px 0;\n\twidth: 390px;\n}\n\n.verifier-ui > table {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n\tborder-collapse: collapse;\n\ttable-layout: fixed;\n\tcolor: var(--text-color);\n}\n\n.verifier-ui > table > thead > tr > th {\n\ttext-align: left;\n\tborder-bottom: 2px solid var(--text-color);\n}\n\n.verifier-ui > table > thead > tr > th, .verifier-ui > table > tbody > tr > td {\n\tpadding: 8px 0;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.verifier-ui > button {\n\tdisplay: inline-block;\n\tmargin: 16px 0 0 0;\n}\n', ""]); const o = s }, 2817: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.time-announcer {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 35%;\n\twidth: 100%;\n\toverflow: hidden;\n}\n\n.time-announcer > .record {\n\tmargin: 0;\n\tpadding: 0;\n\tfont-size: 48px;\n\ttext-shadow: 0 0 5px #000;\n\tcolor: #5f5;\n\ttext-align: center;\n\topacity: 0;\n\tanimation: 0.3s ease-out 0.8s 1 normal forwards running time-announcer-record-animation;\n}\n\n.time-announcer > .track-name {\n\tmargin: 0 0 10px 0;\n\tpadding: 4px 20px;\n\tbox-sizing: border-box;\n\twidth: 100%;\n\tbackground-color: var(--surface-secondary-color);\n\tfont-size: 60px;\n\tcolor: var(--text-color);\n\ttext-align: center;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\tanimation: 0.3s ease-out 0s 1 normal forwards running time-announcer-animation;\n}\n\n.time-announcer > .current {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 0;\n\tbackground-color: var(--surface-color);\n\tfont-size: 48px;\n\tcolor: var(--text-color);\n\ttext-align: center;\n\tanimation: 0.5s ease-out 0s 1 normal forwards running time-announcer-animation;\n}\n.time-announcer > .difference > p {\n\tmargin: 0 0 0 auto;\n\tpadding: 0;\n\twidth: 0;\n\tbackground-color: var(--surface-secondary-color);\n\tcolor: #5f5;\n\tfont-size: 30px;\n\ttext-align: center;\n\tanimation: 0.4s ease-out 0.5s 1 normal forwards running time-announcer-animation;\n}\n.time-announcer > .difference.red > p {\n\tcolor: #f55;\n}\n.time-announcer > .difference > p.title {\n\tmargin-top: 30px;\n\tbackground-color: transparent;\n\ttext-shadow: 0 0 3px #000;\n}\n\n@keyframes time-announcer-record-animation {\n\tfrom {\n\t\topacity: 0;\n\t\ttransform: translateY(10px);\n\t}\n\n\tto {\n\t\topacity: 1;\n\t}\n}\n\n@keyframes time-announcer-animation {\n\tfrom {\n\t\twidth: 0;\n\t\topacity: 0;\n\t}\n\n\tto {\n\t\twidth: 100%;\n\t\topacity: 1;\n\t}\n}\n", ""]); const o = s }, 2832: (e, t, n) => { "use strict"; e.exports = n.p + "4e75ed8189c5a7b6fbf8.ttf" }, 2915: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.menu {\n\tdisplay: flex;\n\tflex-direction: column;\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\twidth: 100%;\n\theight: 100%;\n\tbackground-color: rgba(10, 10, 20, 0.8);\n\ttext-align: center;\n\ttransition: background-color 1s ease-out;\n}\n.menu.loading-screen {\n\tbackground-color: var(--surface-tertiary-color);\n}\n\n.menu > .logo {\n\tdisplay: block;\n\tmargin: 80px auto 0 auto;\n\tpadding: 0;\n\twidth: 1000px;\n\theight: 200px;\n\t-webkit-filter: drop-shadow(0 0 3px #000);\n\tfilter: drop-shadow(0 0 3px #000);\n}\n\n@media (max-width: 1300px) {\n\t.menu > .logo {\n\t\twidth: calc(100vw * (1000 / 1300));\n\t}\n}\n@media (max-width: 975px) {\n\t.menu > .logo {\n\t\twidth: calc(975px * (1000 / 1300));\n\t}\n}\n\n.menu > .warning-message {\n\tmargin: 16px auto 0 auto;\n\tmax-width: 900px;\n\tfont-size: 26px;\n\tcolor: #f66;\n}\n.menu > .warning-message > a {\n\tmargin: 0 auto;\n\tdisplay: block;\n\twidth: max-content;\n\tcolor: var(--text-color);\n\tpointer-events: auto;\n}\n\n.menu > .main-buttons-container {\n\tmargin: 0 0 140px 0;\n\tdisplay: flex;\n\tflex-grow: 1;\n\talign-items: center;\n\tjustify-content: center;\n}\n.menu > .main-buttons-container.hidden {\n\tdisplay: none;\n}\n\n.menu .button-image {\n\tdisplay: inline-block;\n\tmargin: 10px 0;\n\tpadding: 0;\n\twidth: 200px;\n\theight: 200px;\n\tpointer-events: auto;\n}\n.menu .button-image > img {\n\tmargin: 40px 40px 0 40px;\n\tpadding: 0;\n\twidth: 96px;\n\theight: 96px;\n\ttransition: transform 0.2s ease-in-out;\n\tpointer-events: none;\n}\n.menu .button-image:not(:disabled):hover > img {\n\ttransform: translateY(-10px);\n}\n@media (hover: none) {\n\t.menu .button-image:not(:disabled):hover > img {\n\t\ttransform: none;\n\t}\n}\n.menu .button-image > p {\n\tmargin: 0;\n\tpadding: 0;\n\tcolor: var(--text-color);\n\tfont-size: 27px;\n}\n\n.menu .button-image.button-spawn {\n\tanimation: button-spawn 0.5s ease-out forwards;\n\topacity: 0;\n}\n\n@keyframes button-spawn {\n\t0% {\n\t\ttransform: translateY(50px) scale(0.8);\n\t\topacity: 0;\n\t}\n\t70% {\n\t\ttransform: translateY(-10px) scale(1);\n\t\topacity: 1;\n\t}\n\t100% {\n\t\ttransform: translateY(0) scale(1);\n\t\topacity: 1;\n\t}\n}\n\n.menu > .bottom-buttons {\n\tmargin: 4px;\n\tpadding: 0;\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n}\n\n.menu > .bottom-buttons > .small {\n\tpadding: 6px 12px;\n\tclip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%);\n\tfont-size: 22px;\n}\n.menu > .bottom-buttons > .small > img {\n\tvertical-align: middle;\n\twidth: 24px;\n\theight: 24px;\n}\n\n.menu > .discord-link {\n\tdisplay: block;\n\tposition: absolute;\n\tright: 0;\n\tbottom: 0;\n\tmargin: 0;\n\tpadding: 0;\n\tpointer-events: auto;\n}\n.menu > .discord-link > img {\n\tmargin: 8px 16px;\n\tpadding: 0;\n\theight: 40px;\n}\n\n.menu > .info {\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n}\n.menu > .info > a {\n\tdisplay: block;\n\tmargin: 0 auto;\n\tpadding: 5px;\n\twidth: fit-content;\n\tcolor: var(--text-color);\n\ttext-decoration: none;\n\tfont-size: 20px;\n\tpointer-events: auto;\n}\n.menu > .info > a[href]:hover, .menu > .info > a[href]:focus-visible {\n\ttext-decoration: underline;\n\toutline: none;\n}\n", ""]); const o = s }, 2927: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.loading-ui {\n\tmargin: 200px 0 0 0;\n\tpadding: 0;\n}\n.loading-ui.fade-out {\n\topacity: 0;\n\ttransition: opacity 0.25s ease-out;\n}\n\n.loading-ui > p {\n\tmargin: 5px;\n\tpadding: 0;\n\tcolor: var(--text-color);\n\tfont-size: 32px;\n}\n\n.loading-ui > div {\n\tmargin: 0 auto;\n\tpadding: 0;\n\twidth: 600px;\n\theight: 50px;\n\tbackground-color: var(--surface-color);\n\tclip-path: polygon(9px 0, 100% 0, calc(100% - 9px) 100%, 0 100%);\n\toverflow: hidden;\n}\n\n.loading-ui > div > div {\n\tmargin: 15px 20px;\n\tpadding: 0;\n\twidth: 560px;\n\theight: 20px;\n\tclip-path: polygon(3px 0, 100% 0, calc(100% - 3px) 100%, 0 100%);\n\tbackground-color: #224;\n\tbox-shadow: inset 0 0 6px #000;\n}\n\n.loading-ui > div > div > div {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 0;\n\theight: 100%;\n\tclip-path: polygon(2px 0, 100% 0, calc(100% - 2px) 100%, 0 100%);\n\tbackground-color: #fff;\n\tbox-shadow: inset 0 0 6px #000;\n\ttransition: width 0.1s ease-in-out;\n}\n", ""]); const o = s }, 3223: (e, t, n) => { "use strict"; e.exports = n.p + "images/pending.svg" }, 3518: (e, t, n) => { "use strict"; e.exports = n.p + "images/grid_large.svg" }, 3571: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.touch-controls {\n\tpointer-events: none;\n}\n\n.touch-controls > button {\n\tposition: absolute;\n\ttop: calc(1.5cm + 50px);\n\tmargin: 10px;\n\tpadding: 0;\n\twidth: 160px;\n\theight: 160px;\n\tbackground-color: var(--button-color);\n\tborder: none;\n\topacity: 0.6;\n\tpointer-events: auto;\n\ttouch-action: none;\n}\n.touch-controls > button > img {\n\tmargin: 0;\n\tpadding: 30px;\n\tvertical-align: top;\n\twidth: 100%;\n height: 100%;\n\tbox-sizing: border-box;\n\tpointer-events: none;\n\ttransition: padding 0.25s ease-out;\n}\n.touch-controls > button.active > img {\n padding: 40px;\n}\n\n.touch-controls > .reset {\n\tright: 1.5cm;\n}\n\n.touch-controls > .left-container {\n\tposition: absolute;\n\tleft: 1.5cm;\n\tbottom: 1.5cm;\n}\n\n.touch-controls > .right-container {\n\tposition: absolute;\n\tright: 1.5cm;\n\tbottom: 1.5cm;\n}\n.touch-controls > .right-container > div {\n\tdisplay: inline-block;\n}\n\n.touch-controls > div > div {\n\tmargin: 10px;\n\tpadding: 0;\n\twidth: 160px;\n\theight: 160px;\n\tbackground-color: var(--button-color);\n\topacity: 0.5;\n\tpointer-events: auto;\n\ttouch-action: none;\n}\n.touch-controls > div > div.active {\n\tbackground-color: var(--button-active-color);\n\topacity: 0.6;\n}\n\n.touch-controls > div > div > img {\n\tmargin: 0;\n\tpadding: 40px;\n\tvertical-align: top;\n\twidth: 100%;\n height: 100%;\n\tbox-sizing: border-box;\n\tpointer-events: none;\n}\n.touch-controls > div > div.active > img {\n padding: 50px;\n}\n", ""]); const o = s }, 3682: (e, t, n) => { "use strict"; e.exports = n.p + "a82f15d48dbc61b6edeb.woff2" }, 3755: (e, t, n) => { "use strict"; e.exports = n.p + "images/share.svg" }, 3895: (e, t, n) => { "use strict"; e.exports = n.p + "images/rotation_axis_z_negative.svg" }, 3901: (e, t, n) => { "use strict"; e.exports = n.p + "images/summer.svg" }, 3902: (e, t, n) => { "use strict"; e.exports = n.p + "images/verified.svg" }, 4239: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, ".ghost-loading-ui {\n\tposition: absolute;\n\tright: 0;\n\ttop: 0;\n\tmargin: 4px;\n\tcolor: var(--text-color);\n\tfont-size: 22px;\n\tfont-weight: normal;\n\ttext-shadow: 1px 1px 1px var(--surface-color), -1px 1px 1px var(--surface-color), -1px -1px 1px var(--surface-color), 1px -1px 1px var(--surface-color);\n\ttransition: opacity 0.25s ease-in-out;\n}\n.ghost-loading-ui.hide {\n\topacity: 0;\n\ttransform: translateX(20px);\n\ttransition: opacity 0.25s ease-in-out 0.5s, transform 0.25s ease-in-out 0.5s;\n}\n.ghost-loading-ui.down {\n\ttop: initial;\n\tbottom: 0;\n}\n\n.ghost-loading-ui > .percentage {\n\tdisplay: inline-block;\n\twidth: 60px;\n\ttext-align: center;\n}\n", ""]); const o = s }, 4309: (e, t, n) => { "use strict"; e.exports = n.p + "images/save.svg" }, 4344: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.debug {\n\tmargin: 0.25em;\n\tpadding: 0;\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n\tfont-size: 28px;\n\ttext-shadow: 0 0 5px #000;\n\tcolor: #fff;\n\tz-index: 10;\n}\n", ""]); const o = s }, 4394: () => {}, 4411: (e, t, n) => { "use strict"; e.exports = n.p + "images/rotation_axis_z_positive.svg" }, 4417: e => { "use strict"; e.exports = function(e, t) { return t || (t = {}), e ? (e = String(e.__esModule ? e.default : e), /^['"].*['"]$/.test(e) && (e = e.slice(1, -1)), t.hash && (e += t.hash), /["'() \t\n]|(%20)/.test(e) || t.needQuotes ? '"'.concat(e.replace(/"/g, '\\"').replace(/\n/g, "\\n"), '"') : e) : e } }, 4538: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.pause-screen {\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\tbackground-color: rgba(0, 0, 0, 0.75);\n\tanimation: fade-in 0.25s forwards;\n}\n.pause-screen.fade-out {\n\topacity: 0;\n\ttransition: opacity 0.25s;\n}\n\n@keyframes fade-in {\n\tfrom {\n\t\tbackground-color: rgba(0, 0, 0, 0);\n\t}\n\tto {\n\t\tbackground-color: rgba(0, 0, 0, 0.75);\n\t}\n}\n\n\n.pause-screen > .title {\n\tposition: absolute;\n\ttop: 40%;\n\tleft: 50%;\n\ttransform: translate(-50%, -50%);\n\tfont-size: 100px;\n\tcolor: var(--text-color);\n\tanimation: slide-fade-in 0.5s 0.3s forwards;\n\topacity: 0;\n}\n\n@keyframes slide-fade-in {\n\tfrom {\n\t\ttransform: translate(-60%, -50%);\n\t\topacity: 0;\n\t}\n\tto {\n\t\ttransform: translate(-50%, -50%);\n\t\topacity: 1;\n\t}\n}\n", ""]); const o = s }, 4543: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.time-bar {\n\tdisplay: flex;\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n\tbackground-color: var(--surface-color);\n}\n\n.time-bar > button {\n\tmargin: 6px;\n\tpadding: 4px 12px;\n}\n.time-bar > button > img {\n\tmargin: 0 0 2px 0;\n\tpadding: 0;\n\tvertical-align: middle;\n\twidth: 28px;\n\theight: 28px;\n\tpointer-events: none;\n}\n\n.time-bar > .bar {\n\tposition: relative;\n\tmargin: 6px 6px 6px -8px;\n\tpadding: 0;\n\tflex-grow: 1;\n\theight: 40px;\n\tbackground-color: var(--surface-secondary-color);\n\tclip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n\ttouch-action: none;\n\tpointer-events: auto;\n}\n.time-bar > .bar > div {\n\tposition: relative;\n\twidth: calc(100% - 8px);\n\theight: 100%;\n}\n.time-bar > .bar > div > .unloaded-fill {\n\tposition: absolute;\n\tright: -8px;\n\ttop: 0;\n\tmargin: 0;\n\tpadding: 0;\n\theight: 100%;\n\tbackground-color: rgba(255, 255, 255, 0.1);\n\tclip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n\twill-change: width;\n}\n.time-bar > .bar > div > .fill {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\tmargin: 0;\n\tpadding: 0;\n\theight: 100%;\n\tbackground-color: #7272c2;\n\tclip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n\twill-change: width;\n}\n.time-bar > .bar > div > .dash-container {\n\tpointer-events: none;\n}\n.time-bar > .bar > div > .dash-container > .dash {\n\tposition: absolute;\n\tz-index: 1;\n\tbottom: 0;\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 2px;\n\theight: 25%;\n\tbackground-color: rgba(0,0,0,0.25);\n}\n.time-bar > .bar > div > .dash-container > .dash.long {\n\theight: 50%;\n\tbackground-color: rgba(0,0,0,0.35);\n}\n", ""]); const o = s }, 4563: (e, t, n) => { "use strict"; e.exports = n.p + "images/rotate.svg" }, 4593: (e, t, n) => { "use strict"; e.exports = n.p + "images/reset_settings.svg" }, 4804: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.game-toolbar {\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n\tz-index: 1;\n\tpadding: 8px 10px 8px 8px;\n\tbackground-color: var(--surface-color);\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n\topacity: 0;\n\ttransform: translateX(-10px);\n\ttransition: opacity ease-in-out 0.2s, transform ease-in-out 0.2s;\n\tpointer-events: none;\n}\n\n.game-toolbar.up {\n\tposition: absolute;\n\tbottom: auto;\n\ttop: 0;\n}\n\n.game-toolbar.touch > .button {\n\tfont-size: 24px;\n}\n.game-toolbar.touch > .button > img {\n\twidth: 24px;\n\theight: 24px;\n}\n\n.game-toolbar.visible {\n\topacity: 1;\n\ttransform: translateX(0);\n\ttransition: opacity 0.2s ease-in-out 0.5s, transform 0.2s ease-in-out 0.5s;\n\tpointer-events: auto;\n}\n", ""]); const o = s }, 4930: (e, t, n) => { "use strict"; e.exports = n.p + "images/grid_small.svg" }, 5001: (e, t, n) => { "use strict"; e.exports = n.p + "images/rotation_axis_x_negative.svg" }, 5007: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.editor-height-selector {\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n}\n\n.editor-height-selector > .buttons {\n\tdisplay: inline-block;\n\tvertical-align: bottom;\n}\n.editor-height-selector > .buttons > button {\n\tdisplay: block;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: none;\n\tbackground-color: var(--button-color);\n\tpointer-events: auto;\n\tcursor: pointer;\n}\n.editor-height-selector > .buttons > button:hover {\n\tbackground-color: var(--button-hover-color);\n}\n@media (hover: none) {\n\t.editor-height-selector > .buttons > button:hover {\n\t\tbackground-color: var(--button-color);\n\t}\n}\n.editor-height-selector > .buttons > button:active {\n\tbackground-color: var(--button-active-color);\n}\n\n.editor-height-selector > .buttons > button > img { \n\tmargin: 0;\n\tpadding: 0 6px;\n\twidth: 20px;\n\theight: 20px;\n\tvertical-align: bottom;\n\tpointer-events: none;\n}\n.editor-height-selector.touch > .buttons > button > img {\n\tpadding: 24px;\n\twidth: 40px;\n\theight: 40px;\n}\n\n.editor-height-selector > p {\n\tmargin: 0;\n\tpadding: 0 10px;\n\tdisplay: inline-block;\n\tvertical-align: bottom;\n\tline-height: 40px;\n\tmin-width: 140px;\n\tfont-size: 26px;\n\ttext-align: center;\n\tbackground-color: var(--surface-transparent-color);\n\tcolor: var(--text-color);\n}\n.editor-height-selector.touch > p {\n\tline-height: calc((40px + 2 * 24px) * 2);\n}\n", ""]); const o = s }, 5010: (e, t, n) => { "use strict"; e.exports = n.p + "images/winter_colored.svg" }, 5031: (e, t, n) => { "use strict"; e.exports = n.p + "images/help.svg" }, 5056: (e, t, n) => { "use strict"; e.exports = function(e) { var t = n.nc; t && e.setAttribute("nonce", t) } }, 5072: e => { "use strict"; var t = []; function n(e) { for (var n = -1, i = 0; i < t.length; i++) if (t[i].identifier === e) { n = i; break } return n } function i(e, i) { for (var a = {}, s = [], o = 0; o < e.length; o++) { var l = e[o], c = i.base ? l[0] + i.base : l[0], h = a[c] || 0, d = "".concat(c, " ").concat(h); a[c] = h + 1; var u = n(d), p = { css: l[1], media: l[2], sourceMap: l[3], supports: l[4], layer: l[5] }; if (-1 !== u) t[u].references++, t[u].updater(p); else { var f = r(p, i); i.byIndex = o, t.splice(o, 0, { identifier: d, updater: f, references: 1 }) } s.push(d) } return s } function r(e, t) { var n = t.domAPI(t); n.update(e); return function(t) { if (t) { if (t.css === e.css && t.media === e.media && t.sourceMap === e.sourceMap && t.supports === e.supports && t.layer === e.layer) return; n.update(e = t) } else n.remove() } } e.exports = function(e, r) { var a = i(e = e || [], r = r || {}); return function(e) { e = e || []; for (var s = 0; s < a.length; s++) { var o = n(a[s]); t[o].references-- } for (var l = i(e, r), c = 0; c < a.length; c++) { var h = n(a[c]); 0 === t[h].references && (t[h].updater(), t.splice(h, 1)) } a = l } } }, 5086: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.loading-spinner {\n\twidth: 40px;\n\theight: 40px;\n\tborder-radius: 50%;\n\tborder: 5px solid var(--surface-tertiary-color);\n\tborder-left-color: var(--text-color);\n\n\tanimation: 1s linear infinite forwards loading-spinner-spin;\n}\n\n@keyframes loading-spinner-spin {\n\tfrom {\n\t\ttransform: rotate(0);\n\t}\n\tto {\n\t\ttransform: rotate(360deg);\n\t}\n}\n", ""]); const o = s }, 5140: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.profile-selection {\n\tposition: absolute;\n\tleft: calc(50% - 500px / 2);\n\ttop: 40%;\n\tz-index: 2;\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 500px;\n\tbox-sizing: border-box;\n\tbackground-color: var(--surface-secondary-color);\n}\n\n.profile-selection > .top-bar {\n\tmargin: 0;\n\tpadding: 10px;\n\tbackground-color: var(--surface-color);\n}\n\n.profile-selection > .top-bar > h2 {\n\tmargin: 0;\n\tpadding: 0;\n\tfont-weight: normal;\n\tfont-size: 38px;\n\ttext-align: center;\n\tcolor: var(--text-color);\n}\n\n.profile-selection > .slot {\n\tposition: relative;\n\tmargin: 10px 10px 0 10px;\n\tpadding: 0;\n}\n\n.profile-selection > .slot > button.main {\n\tmargin: 0;\n\tpadding: 0;\n\tvertical-align: top;\n\twidth: 100%;\n\theight: 100px;\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n\ttext-align: left;\n\twhite-space: nowrap;\n}\n\n.profile-selection > .slot > button.main.selected {\n\tbackground-color: var(--button-hover-color);\n}\n\n.profile-selection > .slot > button.main > .image-container {\n\tdisplay: inline-block;\n\tposition: relative;\n\tbackground-color: rgba(0, 0, 0, 0.1);\n\twidth: 100px;\n\theight: 100px;\n}\n\n.profile-selection > .slot > button.main > .image-container > img {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\twidth: 100%;\n\theight: 100%;\n\tpointer-events: none;\n\topacity: 0;\n\ttransition: opacity 0.5s ease-out;\n}\n.profile-selection > .slot > button.main > .image-container > img.show {\n\topacity: 1;\n}\n\n.profile-selection > .slot > button.main > .name {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tmargin: 0;\n\tpadding: 12px;\n\tfont-size: 28px;\n\tcolor: var(--text-color);\n\ttext-overflow: ellipsis;\n\toverflow: hidden;\n\twidth: 320px;\n}\n.profile-selection > .slot > button.main > .name.empty {\n\tcolor: #000;\n\topacity: 0.2;\n}\n\n.profile-selection > .bottom-bar {\n\tmargin: 10px 0 0 0;\n\tpadding: 10px;\n\tbackground-color: var(--surface-color);\n}\n\n.profile-selection > .bottom-bar > .button.right {\n\tfloat: right;\n}\n", ""]); const o = s }, 5148: (e, t, n) => { "use strict"; e.exports = n.p + "images/checkpoint.svg" }, 5151: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.speedometer {\n\tposition: absolute;\n\tbottom: 0;\n\tright: 0;\n\tmargin: 0;\n\tpadding: 8px 8px 8px 10px;\n\tmin-width: 140px;\n\tline-height: 0;\n\tfont-size: 40px;\n\tcolor: var(--text-color);\n\ttext-align: right;\n\topacity: 0.9;\n\tclip-path: polygon(8px 0, 100% 0, 100% 100%, 0 100%);\n\tbackground-color: var(--surface-color);\n}\n.speedometer.up {\n\tbottom: auto;\n\ttop: 0;\n\tclip-path: polygon(0 0, 100% 0, 100% 100%, 8px 100%);\n}\n.speedometer.hidden {\n\tdisplay: none;\n}\n\n.speedometer > div {\n\tmargin: 0;\n\tpadding: 0 0 0 16px;\n\tclip-path: polygon(6px 0, 100% 0, 100% 100%, 0 100%);\n\tbackground-color: var(--surface-tertiary-color);\n}\n.speedometer.up > div {\n\tclip-path: polygon(0 0, 100% 0, 100% 100%, 6px 100%);\n}\n\n.speedometer > div > span:last-of-type {\n\topacity: 0.5;\n\tmargin: 0 0.3em 0 0.25em;\n\tpadding: 0;\n\tfont-size: 0.5em;\n}\n.speedometer > div > span > span {\n\tdisplay: inline-block;\n\twidth: 0.5em;\n\ttext-align: center;\n}\n", ""]); const o = s }, 5437: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.message-box {\n\tmargin: 0;\n\tpadding: 0;\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\tz-index: 1;\n\tmax-width: unset;\n\tmax-height: unset;\n\twidth: 100%;\n\theight: 100%;\n\tbackground-color: rgba(20, 20, 30, 0.5);\n\tborder: none;\n\tpointer-events: auto;\n}\n\n.message-box > div {\n\tposition: absolute;\n\tleft: calc(50% - 500px / 2);\n\ttop: 30%;\n\tz-index: 2;\n\tmargin: 0;\n\tpadding: 16px;\n\twidth: 500px;\n\tbox-sizing: border-box;\n\tborder: none;\n\tbackground-color: var(--surface-color);\n\toutline: none;\n\ttext-align: center;\n}\n\n.message-box > div > p {\n\tmargin: 5px 0 20px 0;\n\tpadding: 0;\n\tmin-height: 50px;\n\tline-height: 0.9;\n\tfont-size: 32px;\n\toverflow-wrap: break-word;\n\twhite-space: pre-wrap;\n\tcolor: var(--text-color);\n}\n\n.message-box > div > button {\n\tmin-width: 140px;\n}\n\n.message-box.message > div > button:first-of-type {\n\tdisplay: none;\n}\n\n.message-box.confirm > div > button:first-of-type {\n\tfloat: left;\n}\n.message-box.confirm > div > button:last-of-type {\n\tfloat: right;\n}\n\n.message-box.no-buttons > div > button {\n\tdisplay: none;\n}\n", ""]); const o = s }, 5586: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.track-info {\n\tposition: absolute;\n\tleft: calc(50% - 1050px / 2);\n\ttop: 0;\n\tz-index: 2;\n\tdisplay: flex;\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 1000px;\n\theight: 100%;\n}\n.track-info.hidden {\n\tdisplay: none;\n}\n\n.track-info > .side-panel {\n\tposition: relative;\n\tdisplay: flex;\n\tflex-direction: column;\n\tmin-height: 0;\n\tmargin-left: 50px;\n\twidth: 400px;\n\tbackground-color: var(--surface-color);\n}\n\n.track-info > .side-panel > h2 {\n\tmargin: 10px 10px 0 10px;\n\tpadding: 0;\n\tflex-shrink: 0;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\tfont-weight: normal;\n\tfont-size: 38px;\n\ttext-align: center;\n\tcolor: var(--text-color);\n}\n\n\n.track-info > .side-panel > .thumbnail {\n\tposition: relative;\n\tmargin: 10px 0 0 0;\n\tpadding: 45px;\n\tflex-grow: 1;\n\tmin-height: 0;\n\tmax-height: 300px;\n\tbox-sizing: border-box;\n\tbackground-color: var(--surface-secondary-color);\n}\n\n.track-info > .side-panel > .thumbnail > canvas {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n\theight: 100%;\n\tobject-fit: contain;\n\t-webkit-filter: drop-shadow(0 0 3px #000);\n\tfilter: drop-shadow(0 0 3px #000);\n\timage-rendering: pixelated;\n}\n\n.track-info > .side-panel > .thumbnail > .share {\n\tdisplay: inline-block;\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n\tmargin: 8px;\n\tpadding: 0 9px;\n\tclip-path: polygon(3px 0, 100% 0, calc(100% - 3px) 100%, 0 100%);\n}\n.track-info > .side-panel > .thumbnail > .share > img {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 16px;\n\tpointer-events: none;\n}\n\n.track-info > .side-panel > .thumbnail > .environment {\n\tposition: absolute;\n\tright: 0;\n\tbottom: 0;\n\tmargin: 8px;\n\twidth: 32px;\n\topacity: 0.2;\n\tpointer-events: none;\n}\n\n.track-info > .side-panel > .track-author {\n\tmargin: 8px 0;\n\tfont-size: 18px;\n\tcolor: var(--text-color);\n\toverflow-wrap: anywhere;\n}\n\n.track-info > .side-panel > .divider {\n\tborder-top: 1px solid var(--text-color);\n}\n\n.track-info > .side-panel > .personal-best-title, .track-info > .side-panel > .opponents-title {\n\tmargin: 16px 0 0 0;\n\tfont-size: 36px;\n\tcolor: var(--text-color);\n}\n\n.track-info > .side-panel > .personal-best {\n\tmargin: 0 0 16px 0;\n\tfont-size: 32px;\n\tcolor: var(--text-color);\n}\n.track-info > .side-panel > .personal-best.no-record {\n\topacity: 0.5;\n}\n\n.track-info > .side-panel > .opponents-container {\n\tmargin: 8px 16px 16px 16px;\n\tflex-grow: 1;\n\tmin-height: 50px;\n\tfont-size: 18px;\n\tcolor: var(--text-color);\n\topacity: 0.5;\n}\n\n.track-info > .side-panel > .opponents-container.no-opponents {\n\tmargin: 8px 16px 16px 16px;\n\tfont-size: 18px;\n\tcolor: var(--text-color);\n\topacity: 0.5;\n}\n\n.track-info > .side-panel > .button.watch, .track-info > .side-panel > .button.play {\n\tflex-shrink: 0;\n\tmargin: 0 10px 10px 10px;\n\tpadding: 0 0 0 30px;\n\tbox-sizing: border-box;\n\twidth: calc(100% - 2 * 10px);\n\theight: 100px;\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n\ttext-align: center;\n\tfont-size: 50px;\n}\n.track-info > .side-panel > .button.watch {\n\theight: 50px;\n\tfont-size: 40px;\n}\n\n.track-info > .side-panel > .button.watch > img, .track-info > .side-panel > .button.play > img {\n\tmargin: 0 0 0 10px;\n\tpadding: 0;\n\tvertical-align: middle;\n\twidth: 48px;\n\theight: 48px;\n\ttransition: transform 0.2s ease-in-out;\n\tpointer-events: none;\n}\n.track-info > .side-panel > .button.watch > img {\n\twidth: 36px;\n\theight: 36px;\n}\n.track-info > .side-panel > .button.watch:disabled > img {\n\topacity: 0.3;\n}\n\n.track-info > .side-panel > .button.watch:hover > img, .track-info > .side-panel > .button.play:hover > img {\n\ttransform: translateX(10px);\n}\n.track-info > .side-panel > .button.watch:disabled:hover > img {\n\ttransform: none;\n}\n\n@media (hover: none) {\n\t.track-info > .side-panel > .button.watch:hover > img, .track-info > .side-panel > .button.play:hover > img {\n\t\ttransform: none;\n\t}\n}\n\n.track-info > .side-panel > .back {\n\tmargin: 10px;\n}\n\n.track-info > .side-panel > .leaderboard-button {\n\tmargin: 10px;\n\tfloat: right;\n}\n", ""]); const o = s }, 5739: (e, t, n) => { "use strict"; e.exports = n.p + "images/quit.svg" }, 5769: (e, t, n) => { "use strict"; e.exports = n.p + "images/state_pending.svg" }, 5798: (e, t, n) => { "use strict"; e.exports = n.p + "images/rotation_axis_y_negative.svg" }, 5811: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.checkpoint {\n\tposition: absolute;\n\tbottom: 0;\n\tleft: 0;\n\tmargin: 0;\n\tpadding: 8px 10px 8px 8px;\n\tline-height: 0;\n\tfont-size: 40px;\n\tcolor: var(--text-color);\n\ttext-align: left;\n\topacity: 0.9;\n\tclip-path: polygon(0 0, calc(100% - 8px) 0, 100% 100%, 0 100%);\n\tbackground-color: var(--surface-color);\n}\n.checkpoint.up {\n\tposition: absolute;\n\tbottom: auto;\n\ttop: 0;\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n}\n.checkpoint.hidden {\n\tdisplay: none;\n}\n\n.checkpoint > div {\n\tmargin: 0;\n\tpadding: 0 16px 0 16px;\n\tclip-path: polygon(0 0, calc(100% - 6px) 0, 100% 100%, 0 100%);\n\tbackground-color: var(--surface-tertiary-color);\n}\n.checkpoint.up > div {\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 6px) 100%, 0 100%);\n}\n\n.checkpoint > div > img {\n\tmargin: 0 12px 5px 0;\n\tpadding: 0;\n\twidth: 24px;\n\theight: 24px;\n\tvertical-align: middle;\n}\n", ""]); const o = s }, 5848: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.color-picker {\n\tmargin: 8px;\n}\n\n.color-picker > .value-saturation-picker {\n\tposition: relative;\n\tmargin: 0 0 8px 0;\n\twidth: 140px;\n\theight: 140px;\n\tbackground-color: #fff;\n\toverflow: hidden;\n}\n\n.color-picker > .value-saturation-picker > .marker {\n\tposition: absolute;\n\twidth: 12px;\n\theight: 12px;\n\tbackground-image: radial-gradient(closest-side, transparent, #000, #fff, #000, transparent);\n}\n\n.color-picker > .hue-picker {\n\tposition: relative;\n\twidth: 140px;\n\theight: 30px;\n\tbackground-image: linear-gradient(to right, \n\t\thsl(0, 100%, 50%),\n\t\thsl(60, 100%, 50%),\n\t\thsl(120, 100%, 50%),\n\t\thsl(180, 100%, 50%),\n\t\thsl(240, 100%, 50%),\n\t\thsl(300, 100%, 50%),\n\t\thsl(0, 100%, 50%)\n\t);\n\toverflow: hidden;\n}\n\n.color-picker > .hue-picker > .marker {\n\tposition: absolute;\n\ttop: 0;\n\theight: 100%;\n\twidth: 3px;\n\tbackground-image: linear-gradient(to right, #000, #fff, #000);\n}\n", ""]); const o = s }, 5918: (e, t, n) => { "use strict"; e.exports = n.p + "images/load.svg" }, 5959: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.customization {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n\theight: 100%;\n}\n\n.customization > .top {\n\tdisplay: block;\n\tmargin: 0;\n\tpadding: 0;\n\tbackground-color: var(--surface-color);\n}\n.customization > .top > .button {\n\tdisplay: inline-block;\n\tmargin: 8px 0;\n}\n.customization > .top > .button:first-of-type {\n\tmargin-left: 8px;\n}\n\n.customization > .save-message {\n\tmargin: 10px;\n\tpadding: 0;\n\tposition: absolute;\n\tfont-size: 30px;\n\tcolor: #96ff96;\n\ttext-shadow: 0 0 5px #000;\n\tpointer-events: none;\n\n\tleft: -10px;\n\topacity: 0;\n}\n.customization > .save-message.show {\n\tleft: 0;\n\topacity: 1;\n\ttransition: opacity 0.25s ease-in-out, left 0.25s ease-in-out;\n}\n.customization > .save-message.hide {\n\tleft: 0;\n\topacity: 0;\n\ttransition: opacity 0.25s ease-in-out, left 0.25s ease-in-out;\n}\n\n.customization > .colors {\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 100%;\n\ttext-align: center;\n\twhite-space: nowrap;\n}\n\n.customization > .colors > div {\n\tdisplay: inline-block;\n\tmargin: 0 10px;\n\tpadding: 0;\n\ttext-align: center;\n\tbackground: var(--surface-color);\n\tpointer-events: auto;\n}\n.customization > .colors > div > h2 {\n\tmargin: 0;\n\tpadding: 2px;\n\tfont-size: 26px;\n\tfont-weight: normal;\n\tbackground-color: var(--surface-secondary-color);\n\tcolor: var(--text-color);\n}\n.customization > .colors > div > input {\n\tmargin: 8px 8px 0 8px;\n\twidth: calc(140px - 8px * 2);\n\tfont-weight: normal;\n\tclip-path: none;\n\ttext-align: center;\n}\n", ""]); const o = s }, 6027: (e, t, n) => { "use strict"; e.exports = n.p + "images/pin.svg" }, 6057: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.editor {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n\theight: 100%;\n}\n\n.editor > .top {\n\tdisplay: block;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.editor > .top > .button-bar {\n\tdisplay: flex;\n\tmargin: 0;\n\tpadding: 0 8px;\n\theight: 68px;\n\tbackground-color: var(--surface-color);\n\twhite-space: nowrap;\n}\n.editor > .top > .button-bar > .button {\n\tmargin: 8px 0;\n\tmin-width: 0;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n.editor > .top > .track-settings-container {\n\tdisplay: inline-block;\n\tmargin: 0;\n\tpadding: 6px 7px;\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 10px) 100%, 0 100%);\n\tfont-size: 30px;\n\tcolor: var(--text-color);\n\tbackground: var(--surface-secondary-color);\n}\n.editor > .top > .track-settings-container > button {\n\ttext-align: left;\n\tmin-width: 150px;\n\tmax-width: 450px;\n\twhite-space: nowrap;\n\ttext-overflow: ellipsis;\n\toverflow: hidden;\n}\n\n.editor > .side {\n\tposition: absolute;\n\ttop: 68px;\n\tright: 0;\n\tmargin: 0;\n\tpadding: 0;\n\theight: calc(100% - 68px);\n\tdisplay: flex;\n\talign-items: end;\n}\n\n.editor > .side > .side-panel {\n\theight: 100%;\n\tbackground-color: var(--surface-secondary-color);\n\tpointer-events: auto;\n}\n\n.editor > .side > .side-panel > .category-panel, .editor > .side > .side-panel > .part-panel, .editor > .side > .side-panel > .color-panel {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tpadding: 2px 2px 0 2px;\n\theight: 100%;\n\tbox-sizing: border-box;\n\toverflow-x: hidden;\n\toverflow-y: scroll;\n\tscrollbar-width: thin;\n}\n.editor > .side > .side-panel > .category-panel > button > img {\n\twidth: 96px;\n\theight: 96px;\n}\n.editor > .side > .side-panel > .part-panel.hidden {\n\tdisplay: none;\n}\n.editor > .side > .side-panel > .color-panel.hidden {\n\tdisplay: none;\n}\n\n.editor > .side > .side-panel button {\n\tdisplay: block;\n\tmargin: 0 0 2px 0;\n\tpadding: 5px;\n\tbackground-color: var(--button-color);\n\tborder: 2px solid rgb(38, 31, 88);\n\tcursor: pointer;\n}\n.editor > .side > .side-panel button:hover {\n\tbackground-color: var(--button-hover-color);\n}\n@media (hover: none) {\n\t.editor > .side > .side-panel button:hover {\n\t\tbackground-color: var(--button-color);\n\t}\n}\n.editor > .side > .side-panel button:active {\n\tbackground-color: var(--button-active-color);\n}\n.editor > .side > .side-panel button.selected {\n\tbackground-color: var(--button-hover-color);\n\tbox-shadow: inset 0 0 5px #fff;\n\tborder: 2px solid #fff;\n}\n.editor > .side > .side-panel button > img {\n\tdisplay: block;\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 64px;\n\theight: 64px;\n\t-webkit-filter: drop-shadow(0 0 2px #000);\n\tfilter: drop-shadow(0 0 2px #000);\n\tpointer-events: none;\n\ttransition: opacity 0.25s ease-out;\n}\n.editor > .side > .side-panel button > img.loading {\n\topacity: 0;\n\ttransition: none;\n}\n\n.editor > .message {\n\tmargin: 10px;\n\tpadding: 0;\n\tposition: absolute;\n\tfont-size: 30px;\n\tcolor: #ff9696;\n\ttext-shadow: 0 0 5px #000;\n\tpointer-events: none;\n\n\tleft: -10px;\n\topacity: 0;\n}\n.editor > .message.green {\n\tcolor: #96ff96;\n}\n.editor > .message.show {\n\tleft: 0;\n\topacity: 1;\n\ttransition: opacity 0.25s ease-in-out, left 0.25s ease-in-out;\n}\n.editor > .message.hide {\n\tleft: 0;\n\topacity: 0;\n\ttransition: opacity 0.25s ease-in-out, left 0.25s ease-in-out;\n}\n", ""]); const o = s }, 6099: (e, t, n) => { "use strict"; e.exports = n.p + "images/arrow_left.svg" }, 6150: (e, t, n) => { "use strict"; e.exports = n.p + "images/arrow_right.svg" }, 6168: (e, t, n) => { "use strict"; e.exports = n.p + "images/export.svg" }, 6244: (e, t, n) => { "use strict"; e.exports = n.p + "images/state_verified.svg" }, 6314: e => { "use strict"; e.exports = function(e) { var t = []; return t.toString = function() { return this.map((function(t) { var n = "", i = void 0 !== t[5]; return t[4] && (n += "@supports (".concat(t[4], ") {")), t[2] && (n += "@media ".concat(t[2], " {")), i && (n += "@layer".concat(t[5].length > 0 ? " ".concat(t[5]) : "", " {")), n += e(t), i && (n += "}"), t[2] && (n += "}"), t[4] && (n += "}"), n })).join("") }, t.i = function(e, n, i, r, a) { "string" == typeof e && (e = [ [null, e, void 0] ]); var s = {}; if (i) for (var o = 0; o < this.length; o++) { var l = this[o][0]; null != l && (s[l] = !0) } for (var c = 0; c < e.length; c++) { var h = [].concat(e[c]); i && s[h[0]] || (void 0 !== a && (void 0 === h[5] || (h[1] = "@layer".concat(h[5].length > 0 ? " ".concat(h[5]) : "", " {").concat(h[1], "}")), h[5] = a), n && (h[2] ? (h[1] = "@media ".concat(h[2], " {").concat(h[1], "}"), h[2] = n) : h[2] = n), r && (h[4] ? (h[1] = "@supports (".concat(h[4], ") {").concat(h[1], "}"), h[4] = r) : h[4] = "".concat(r)), t.push(h)) } }, t } }, 6366: (e, t, n) => { "use strict"; e.exports = n.p + "images/apply.svg" }, 6474: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.nickname {\n\tposition: absolute;\n\tleft: calc(50% - 500px / 2);\n\ttop: 40%;\n\tz-index: 2;\n\tmargin: 0;\n\tpadding: 16px;\n\twidth: 500px;\n\tbox-sizing: border-box;\n\tbackground-color: var(--surface-color);\n}\n\n.nickname > h1 {\n\tmargin: 0 4px 0 4px;\n\tpadding: 0;\n\tfont-size: 35px;\n\tfont-weight: normal;\n\tcolor: var(--text-color);\n}\n\n.nickname > input[type=text] {\n\tdisplay: block;\n\tmargin: 0;\n\tpadding: 0.25em;\n\tbox-sizing: border-box;\n\twidth: 100%;\n\tfont-size: 36px;\n\tfont-weight: normal;\n}\n\n.nickname > p {\n\tmargin: 16px 4px 0 4px;\n\tpadding: 0;\n\tfont-size: 20px;\n\tcolor: var(--text-color);\n}\n\n.nickname > button {\n\tdisplay: inline-block;\n\tmargin: 16px 0 0 0;\n}\n.nickname > button:last-of-type {\n\tfloat: right;\n}\n\n.nickname > button.delete {\n\tposition: absolute;\n\tright: 8px;\n\ttop: 0;\n\tfont-size: 16px;\n\tpadding: 8px 16px;\n}\n\n.nickname > button.delete > img.button-icon {\n\tmargin: -5px 0 -2px -3px;\n\twidth: 16px;\n\theight: 16px;\n}\n\nbutton.nickname-verifier-button {\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 22px;\n\tmargin: 0 4px;\n}\n\n.nickname-user-token {\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n\tmargin: 0 4px;\n\ttext-align: left;\n\tfont-size: 18px;\n\topacity: 0.5;\n\tcolor: var(--text-color);\n\tpointer-events: all;\n\t-webkit-user-select: all;\n\t-moz-user-select: all;\n\t-ms-user-select: all;\n\tuser-select: all;\n}\n", ""]); const o = s }, 6657: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.leaderboard {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 600px;\n\theight: 100%;\n\ttext-align: left;\n\tdisplay: flex;\n\tflex-shrink: 0;\n\tflex-direction: column;\n\tbackground-color: var(--surface-color);\n}\n\n.leaderboard > h2 {\n\tmargin: 10px 10px 0 10px;\n\tpadding: 0;\n\tfont-weight: normal;\n\tfont-size: 38px;\n\ttext-align: center;\n\tcolor: var(--text-color);\n}\n\n.leaderboard > h3 {\n\tmargin: 0 10px 10px 10px;\n\tpadding: 0;\n\tfont-weight: normal;\n\tfont-size: 18px;\n\ttext-align: center;\n\tcolor: var(--text-color);\n\topacity: 0.5;\n}\n\n.leaderboard > .container {\n\tmargin: 0;\n\tpadding: 0;\n\tflex-grow: 1;\n\tbackground-color: var(--surface-secondary-color);\n\toverflow-x: hidden;\n\toverflow-y: scroll;\n\tpointer-events: auto;\n}\n\n.leaderboard > .container > .loading-spinner-container {\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\twidth: 100%;\n\theight: 100%;\n}\n\n.leaderboard > .container > .error-message {\n\tfont-size: 20px;\n\ttext-align: center;\n\tcolor: var(--text-color);\n}\n\n.leaderboard > .container > button.main {\n\tmargin: 10px 10px 0 10px;\n\tpadding: 0;\n\tvertical-align: top;\n\twidth: calc(100% - 10px * 2);\n\theight: 100px;\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n\ttext-align: left;\n\twhite-space: nowrap;\n}\n.leaderboard > .container > button.main:last-of-type {\n\tmargin-bottom: 10px;\n}\n\n.leaderboard > .container > button.main.self:not(:focus-visible) {\n\tbackground-color: #2e4182;\n}\n\n.leaderboard > .container > button.main.selected {\n\tbackground-color: var(--button-hover-color);\n}\n.leaderboard > .container > button.main.selected::after {\n\twidth: 100%;\n}\n\n.leaderboard > .container > button.main > .checkmark {\n\tdisplay: none;\n}\n\n.leaderboard > .container > button.main.selected > .checkmark {\n\tdisplay: block;\n\tposition: absolute;\n\tright: 0;\n\ttop: 0;\n\tmargin: 6px;\n\twidth: 12px;\n\tanimation: leaderboard-checkmark-spawn 0.15s ease-out;\n}\n\n@keyframes leaderboard-checkmark-spawn {\n\t0% {\n\t\ttransform: scale(0);\n\t}\n\t90% {\n\t\ttransform: scale(1.2);\n\t}\n\t100% {\n\t\ttransform: scale(1);\n\t}\n}\n\n.leaderboard > .container > button.main > .image-container {\n\tdisplay: inline-block;\n\tposition: relative;\n\tbackground-color: rgba(0, 0, 0, 0.1);\n\twidth: 100px;\n\theight: 100px;\n}\n\n.leaderboard > .container > button.main > .image-container > img {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\twidth: 100%;\n\theight: 100%;\n\tpointer-events: none;\n\topacity: 0;\n\ttransition: opacity 0.5s ease-out;\n}\n.leaderboard > .container > button.main > .image-container > img.show {\n\topacity: 1;\n}\n\n.leaderboard > .container > button.main > .left, .leaderboard > .container > button.main > .right {\n\tdisplay: inline-block;\n\tvertical-align: top;\n}\n\n.leaderboard > .container > button.main > div > p {\n\tmargin: 0;\n\tpadding: 12px;\n\tfont-size: 28px;\n\tcolor: var(--text-color);\n}\n\n.leaderboard > .container > button.main > div > .position > span {\n\tfont-size: 20px;\n\topacity: 0.3;\n}\n\n.leaderboard > .container > button.main > div > .name-container {\n\tmargin: 0;\n\tpadding: 0;\n\tfont-size: 28px;\n\tdisplay: flex;\n\talign-items: center;\n\twidth: 360px;\n}\n\n.leaderboard > .container > button.main > div > .name-container > .name {\n\tpadding: 12px;\n\ttext-overflow: ellipsis;\n\toverflow: hidden;\n}\n.leaderboard > .container > button.main:focus-visible > div > .name-container > .name {\n\ttext-decoration: underline;\n}\n\n.leaderboard > .container > button.main > div > .name-container > .self {\n\tmargin-left: -16px;\n\tpadding: 12px;\n\topacity: 0.5;\n\tfont-size: 16px;\n\tfont-style: normal;\n}\n\n.leaderboard > .container > button.main > div > .verified-state {\n\topacity: 0.8;\n\tposition: absolute;\n\tright: 6px;\n\tmargin: 6px 0 0 0;\n\tfont-size: 18px;\n}\n.leaderboard > .container > button.main > div > .verified-state > img {\n\tmargin: 0 0 0 2px;\n\tpadding: 0;\n\theight: 12px;\n\tvertical-align: middle;\n}\n.leaderboard > .container > button.main > div > .verified-state.verified {\n\tcolor: #5f5;\n}\n.leaderboard > .container > button.main > div > .verified-state.invalid {\n\tcolor: #f55;\n}\n.leaderboard > .container > button.main > div > .verified-state.pending {\n\tcolor: #ff5;\n}\n\n.leaderboard > .pages {\n\tmargin: 10px 10px 0 10px;\n\tdisplay: flex;\n\tflex-direction: row;\n}\n.leaderboard > .pages > button.page {\n\tpadding: 0;\n\twidth: 0;\n\tflex-grow: 1;\n}\n.leaderboard > .pages > button.selected {\n\tbackground-color: var(--button-hover-color);\n}\n\n.leaderboard > .button-wrapper > .back {\n\tmargin: 10px;\n}\n\n.leaderboard > .button-wrapper > .button.only-verified {\n\tmargin: 10px 0;\n\tfloat: right;\n\tfont-size: 20px;\n\tline-height: 32px;\n}\n.leaderboard > .button-wrapper > .button.only-verified.disabled {\n\tcolor: rgba(255, 255, 255, 0.25);\n}\n\n.leaderboard > .button-wrapper > .button.only-verified > img {\n\tmargin-left: 6px;\n\tmargin-bottom: -4px;\n\twidth: 26px;\n}\n.leaderboard > .button-wrapper > .button.only-verified.disabled > img {\n\topacity: 0.25;\n}\n\n.leaderboard > .button-wrapper > .icon-button {\n\tmargin: 10px 0;\n\tfloat: right;\n}\n.leaderboard > .button-wrapper > .icon-button.first {\n\tmargin: 10px 10px 10px 0;\n}\n\n.leaderboard > .button-wrapper > .icon-button > img {\n\twidth: 28px;\n}\n.leaderboard > .button-wrapper > .icon-button.disabled > img, .leaderboard > .button-wrapper > .icon-button:disabled > img {\n\topacity: 0.25;\n}\n", ""]); const o = s }, 6838: (e, t, n) => { "use strict"; e.exports = n.p + "images/smoke.png" }, 6925: () => { "use strict"; function e(e) { throw new Error(e + ": No deterministic implementation") } const t = new WebAssembly.Instance(new WebAssembly.Module(Uint8Array.from(atob("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"), (e => e.charCodeAt(0))))).exports; Math = { E: 2.718281828459045, LN10: 2.302585092994046, LN2: .6931471805599453, LOG2E: 1.4426950408889634, LOG10E: .4342944819032518, PI: 3.141592653589793, SQRT1_2: .7071067811865476, SQRT2: 1.4142135623730951, abs: Math.abs, acos: t.acos, asin: t.asin, atan: t.atan, atan2: t.atan2, ceil: Math.ceil, cos: function(e) { return Math.sin(e + Math.PI / 2) }, exp: t.exp, floor: Math.floor, log: t.log, max: Math.max, min: Math.min, pow: t.pow, random: Math.random, round: Math.round, sin: function(e) { if (!Number.isFinite(e)) return NaN; const t = (e = function(e) { return (e %= 2 * Math.PI) < 0 && (e += 2 * Math.PI), e }(e)) / (2 * Math.PI) * n.length, i = Math.floor(t), r = (i + 1) % n.length, a = t - i; return n[i] * (1 - a) + n[r] * a }, sqrt: t.sqrt, tan: t.tan, clz32: () => e("clz32"), imul: () => e("imul"), sign: Math.sign, log10: t.log10, log2: t.log2, log1p: () => e("log1p"), expm1: () => e("expm1"), cosh: () => e("cosh"), sinh: () => e("sinh"), tanh: () => e("tanh"), acosh: () => e("acosh"), asinh: () => e("asinh"), atanh: () => e("atanh"), hypot: () => e("hypot"), trunc: Math.trunc, cbrt: () => e("cbrt"), fround: Math.fround, [Symbol.toStringTag]: "Math" }; const n = [0, .01745240643728351, .03489949670250097, .05233595624294383, .0697564737441253, .08715574274765817, .10452846326765346, .12186934340514748, .13917310096006544, .15643446504023087, .17364817766693033, .1908089953765448, .20791169081775931, .22495105434386498, .24192189559966773, .25881904510252074, .27563735581699916, .2923717047227367, .3090169943749474, .3255681544571567, .3420201433256687, .35836794954530027, .374606593415912, .3907311284892737, .40673664307580015, .42261826174069944, .4383711467890774, .45399049973954675, .4694715627858908, .48480962024633706, .49999999999999994, .5150380749100542, .5299192642332049, .544639035015027, .5591929034707468, .573576436351046, .5877852522924731, .6018150231520483, .6156614753256583, .6293203910498375, .6427876096865393, .6560590289905073, .6691306063588582, .6819983600624985, .6946583704589973, .7071067811865475, .7193398003386511, .7313537016191705, .7431448254773942, .7547095802227719, .766044443118978, .7771459614569708, .7880107536067219, .7986355100472928, .8090169943749475, .8191520442889918, .8290375725550417, .8386705679454239, .848048096156426, .8571673007021122, .8660254037844386, .8746197071393957, .8829475928589269, .8910065241883678, .898794046299167, .9063077870366499, .9135454576426009, .9205048534524404, .9271838545667873, .9335804264972017, .9396926207859083, .9455185755993167, .9510565162951535, .9563047559630354, .9612616959383189, .9659258262890683, .9702957262759965, .9743700647852352, .9781476007338057, .981627183447664, .984807753012208, .9876883405951378, .9902680687415704, .992546151641322, .9945218953682733, .9961946980917455, .9975640502598242, .9986295347545738, .9993908270190958, .9998476951563913, 1, .9998476951563913, .9993908270190958, .9986295347545738, .9975640502598242, .9961946980917455, .9945218953682734, .9925461516413221, .9902680687415704, .9876883405951377, .984807753012208, .981627183447664, .9781476007338057, .9743700647852352, .9702957262759965, .9659258262890683, .9612616959383189, .9563047559630355, .9510565162951536, .9455185755993168, .9396926207859084, .9335804264972017, .9271838545667874, .9205048534524404, .913545457642601, .90630778703665, .8987940462991669, .8910065241883679, .8829475928589271, .8746197071393959, .8660254037844387, .8571673007021123, .8480480961564261, .8386705679454239, .8290375725550417, .819152044288992, .8090169943749475, .7986355100472927, .788010753606722, .777145961456971, .766044443118978, .7547095802227721, .7431448254773945, .7313537016191706, .7193398003386511, .7071067811865476, .6946583704589975, .6819983600624986, .669130606358858, .6560590289905073, .6427876096865395, .6293203910498374, .6156614753256584, .6018150231520486, .5877852522924732, .5735764363510459, .5591929034707469, .5446390350150273, .5299192642332049, .5150380749100544, .49999999999999994, .48480962024633717, .4694715627858907, .45399049973954686, .4383711467890777, .4226182617406995, .40673664307580004, .39073112848927377, .37460659341591224, .35836794954530066, .3420201433256689, .3255681544571566, .3090169943749475, .29237170472273705, .2756373558169992, .258819045102521, .24192189559966773, .2249510543438652, .20791169081775931, .19080899537654497, .1736481776669307, .15643446504023098, .13917310096006533, .12186934340514755, .10452846326765373, .0871557427476582, .06975647374412552, .05233595624294425, .03489949670250114, .01745240643728344, 12246467991473532e-32, -.017452406437283192, -.0348994967025009, -.052335956242943564, -.06975647374412483, -.08715574274765794, -.1045284632676535, -.12186934340514774, -.13917310096006552, -.15643446504023073, -.17364817766693047, -.19080899537654472, -.20791169081775907, -.22495105434386498, -.2419218955996675, -.25881904510252035, -.2756373558169986, -.29237170472273677, -.30901699437494773, -.32556815445715676, -.34202014332566866, -.35836794954530043, -.374606593415912, -.39073112848927355, -.4067366430757998, -.4226182617406993, -.43837114678907707, -.45399049973954625, -.4694715627858905, -.48480962024633734, -.5000000000000001, -.5150380749100542, -.5299192642332048, -.5446390350150271, -.5591929034707467, -.5735764363510458, -.587785252292473, -.601815023152048, -.6156614753256578, -.6293203910498372, -.6427876096865393, -.6560590289905074, -.6691306063588582, -.6819983600624984, -.6946583704589974, -.7071067811865475, -.7193398003386509, -.7313537016191705, -.743144825477394, -.7547095802227717, -.7660444431189779, -.7771459614569711, -.7880107536067221, -.7986355100472928, -.8090169943749473, -.8191520442889916, -.8290375725550414, -.838670567945424, -.848048096156426, -.8571673007021121, -.8660254037844384, -.8746197071393955, -.882947592858927, -.8910065241883678, -.8987940462991668, -.90630778703665, -.913545457642601, -.9205048534524403, -.9271838545667873, -.9335804264972016, -.9396926207859082, -.9455185755993168, -.9510565162951535, -.9563047559630353, -.961261695938319, -.9659258262890683, -.9702957262759965, -.9743700647852351, -.9781476007338056, -.981627183447664, -.984807753012208, -.9876883405951377, -.9902680687415703, -.992546151641322, -.9945218953682733, -.9961946980917455, -.9975640502598242, -.9986295347545739, -.9993908270190958, -.9998476951563913, -1, -.9998476951563913, -.9993908270190958, -.9986295347545739, -.9975640502598243, -.9961946980917455, -.9945218953682733, -.992546151641322, -.9902680687415704, -.9876883405951378, -.9848077530122081, -.9816271834476641, -.9781476007338056, -.9743700647852352, -.9702957262759966, -.9659258262890684, -.961261695938319, -.9563047559630354, -.9510565162951536, -.945518575599317, -.9396926207859083, -.9335804264972017, -.9271838545667874, -.9205048534524405, -.9135454576426011, -.9063077870366503, -.898794046299167, -.8910065241883679, -.8829475928589271, -.8746197071393956, -.8660254037844386, -.8571673007021123, -.8480480961564262, -.8386705679454243, -.8290375725550416, -.8191520442889918, -.8090169943749476, -.798635510047293, -.7880107536067223, -.7771459614569713, -.7660444431189781, -.7547095802227722, -.743144825477394, -.7313537016191703, -.7193398003386512, -.7071067811865477, -.6946583704589976, -.6819983600624989, -.6691306063588588, -.6560590289905074, -.6427876096865396, -.6293203910498372, -.6156614753256582, -.6018150231520483, -.5877852522924734, -.5735764363510465, -.5591929034707473, -.544639035015027, -.529919264233205, -.5150380749100545, -.5000000000000004, -.48480962024633767, -.4694715627858908, -.45399049973954697, -.4383711467890778, -.4226182617406992, -.40673664307580015, -.3907311284892739, -.37460659341591235, -.35836794954530077, -.34202014332566943, -.3255681544571567, -.3090169943749477, -.29237170472273716, -.27563735581699894, -.2588190451025207, -.24192189559966787, -.22495105434386534, -.20791169081775987, -.19080899537654467, -.1736481776669304, -.15643446504023112, -.13917310096006588, -.12186934340514811, -.1045284632676543, -.08715574274765832, -.06975647374412564, -.05233595624294348, -.034899496702500823, -.01745240643728356] }, 7173: (e, t, n) => { "use strict"; e.exports = n.p + "images/windowed.svg" }, 7404: (e, t, n) => { "use strict"; e.exports = n.p + "images/car_thumbnail_placeholder.png" }, 7479: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.timer {\n\tposition: absolute;\n\tbottom: 0;\n\tleft: 0;\n\twidth: 100%;\n\ttext-align: center;\n\topacity: 0.9;\n}\n.timer.up {\n\tbottom: auto;\n\ttop: 0;\n}\n.timer.hidden {\n\tdisplay: none;\n}\n\n.timer > div {\n\tmargin: 0;\n\tpadding: 0;\n\tdisplay: inline-flex;\n\tflex-direction: column;\n\twidth: 240px;\n\tvertical-align: bottom;\n}\n.timer.up > div {\n\tflex-direction: column-reverse;\n\tvertical-align: top;\n}\n.timer > div > .title-container {\n\tposition: relative;\n\tmargin: 0 auto;\n\twidth: 220px;\n\theight: 32px;\n}\n.timer > div > .title-container > h2 {\n\tposition: absolute;\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\tcolor: var(--text-color);\n\tfont-size: 26px;\n\tfont-weight: normal;\n\ttext-shadow: 1px 1px 1px var(--surface-color), -1px 1px 1px var(--surface-color), -1px -1px 1px var(--surface-color), 1px -1px 1px var(--surface-color);\n}\n.timer:not(.up) > div > .title-container > .title {\n\tmargin-top: 8px;\n}\n.timer > div > .title-container > .checkpoint-time {\n\topacity: 0;\n\tfont-size: 32px;\n}\n.timer > div > .title-container > .checkpoint-time.green {\n\tcolor: #5f5;\n}\n.timer > div > .title-container > .checkpoint-time.red {\n\tcolor: #f55;\n}\n\n.timer > div > .time {\n\tmargin: 0;\n\tpadding: 0;\n\tbackground-color: var(--surface-color);\n}\n.timer > .left > .time {\n\tpadding: 8px 4px 8px 10px;\n\tclip-path: polygon(8px 0, 100% 0, 100% 100%, 0 100%);\n}\n.timer.up > .left > .time {\n\tclip-path: polygon(0 0, 100% 0, 100% 100%, 8px 100%);\n}\n.timer > .center > .time {\n\tposition: relative;\n\tz-index: 1;\n\tmargin: 0 -12px;\n\tpadding: 8px 10px;\n\tclip-path: polygon(8px 0, calc(100% - 8px) 0, 100% 100%, 0 100%);\n}\n.timer.up > .center > .time {\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 8px 100%);\n}\n.timer > .right > .time {\n\tpadding: 8px 10px 8px 4px;\n\tclip-path: polygon(0 0, calc(100% - 8px) 0, 100% 100%, 0 100%);\n}\n.timer.up > .right > .time {\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n}\n\n.timer > div > .time > p {\n\tmargin: 0;\n\tpadding: 0;\n\tbackground-color: var(--surface-tertiary-color);\n\tcolor: var(--text-color);\n\tfont-size: 34px;\n}\n.timer > .left > .time > p {\n\tclip-path: polygon(6px 0, 100% 0, 100% 100%, 0 100%);\n}\n.timer.up > .left > .time > p {\n\tclip-path: polygon(0 0, 100% 0, 100% 100%, 6px 100%);\n}\n.timer > .center > .time > p {\n\tfont-size: 46px;\n\tclip-path: polygon(6px 0, calc(100% - 6px) 0, 100% 100%, 0 100%);\n}\n.timer.up > .center > .time > p {\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 6px) 100%, 6px 100%);\n}\n.timer > .right > .time > p {\n\tclip-path: polygon(0 0, calc(100% - 6px) 0, 100% 100%, 0 100%);\n}\n.timer.up > .right > .time > p {\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 6px) 100%, 0 100%);\n}\n\n.timer > div > .time > p.green {\n\tcolor: #5f5;\n}\n.timer > div > .time > p.red {\n\tcolor:#f55;\n}\n\n.timer > div > .time > p > span {\n\tdisplay: inline-block;\n\twidth: 0.5em;\n\ttext-align: center;\n}\n.timer > div > .time > p > span.sign {\n\tmargin-left: -4px;\n\twidth: 0.7em;\n}\n", ""]); const o = s }, 7581: (e, t, n) => { "use strict"; e.exports = n.p + "images/fullscreen.svg" }, 7659: e => { "use strict"; var t = {}; e.exports = function(e, n) { var i = function(e) { if (void 0 === t[e]) { var n = document.querySelector(e); if (window.HTMLIFrameElement && n instanceof window.HTMLIFrameElement) try { n = n.contentDocument.head } catch (e) { n = null } t[e] = n } return t[e] }(e); if (!i) throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."); i.appendChild(n) } }, 7687: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.track-export > .background {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\tz-index: 1;\n\twidth: 100%;\n\theight: 100%;\n\tbackground-color: rgba(20, 20, 30, 0.5);\n\tpointer-events: auto;\n}\n\n.track-export > .box {\n\tposition: absolute;\n\tleft: calc(50% - 80% / 2);\n\ttop: 20px;\n\tz-index: 2;\n\tmargin: 0;\n\tpadding: 10px;\n\tbox-sizing: border-box;\n\twidth: 80%;\n\theight: calc(100% - 20px * 2);\n\tbackground-color: var(--surface-color);\n}\n\n.track-export > .box > .bar {\n\ttext-align: left;\n\tpointer-events: auto;\n}\n.track-export > .box > .bar > .button.right {\n\tfloat: right;\n}\n\n.track-export > .box > textarea {\n\tmargin: 10px 0 0 0;\n\tpadding: 10px;\n\tbox-sizing: border-box;\n\tmin-width: 100%;\n\tmax-width: 100%;\n\tmin-height: calc(100% - 52px - 10px);\n\tmax-height: calc(100% - 52px - 10px);\n\tpointer-events: auto;\n\tbackground-color: var(--surface-tertiary-color);\n\tborder: none;\n\tresize: none;\n\tcolor: var(--text-color);\n\tword-break: break-all;\n\tfont-size: 20px;\n}\n.track-export > .box > textarea:focus-visible {\n\toutline: none;\n}\n", ""]); const o = s }, 7780: (e, t, n) => { var i = { "./apply.svg": 6366, "./arrow_down.svg": 516, "./arrow_left.svg": 6099, "./arrow_right.svg": 6150, "./arrow_up.svg": 2207, "./back.svg": 8787, "./cancel.svg": 1784, "./car_stripe.svg": 2344, "./car_thumbnail_placeholder.png": 7404, "./checkmark.svg": 9809, "./checkpoint.svg": 5148, "./clouds.jpg": 8875, "./community_tracks.jpg": 8115, "./copy.svg": 1925, "./custom_tracks.jpg": 2709, "./customize.svg": 9027, "./delete.svg": 2319, "./desert.svg": 1705, "./desert_colored.svg": 1758, "./discord.svg": 858, "./editor.svg": 8889, "./empty.svg": 493, "./erase.svg": 1936, "./export.svg": 6168, "./fullscreen.svg": 7581, "./grid_large.svg": 3518, "./grid_small.svg": 4930, "./helmet.svg": 1333, "./help.svg": 5031, "./icon.svg": 853, "./import.svg": 9077, "./load.svg": 5918, "./logo.svg": 8903, "./official_tracks.jpg": 9391, "./overlapping_disabled.svg": 8358, "./overlapping_enabled.svg": 2493, "./pause.svg": 9708, "./pending.svg": 3223, "./pin.svg": 6027, "./play.svg": 9236, "./preview.svg": 9570, "./quit.svg": 5739, "./random.svg": 2175, "./reset.svg": 1719, "./reset_settings.svg": 4593, "./rotate.svg": 4563, "./rotation_axis_x_negative.svg": 5001, "./rotation_axis_x_positive.svg": 77, "./rotation_axis_y_negative.svg": 5798, "./rotation_axis_y_positive.svg": 9062, "./rotation_axis_z_negative.svg": 3895, "./rotation_axis_z_positive.svg": 4411, "./save.svg": 4309, "./search.svg": 8718, "./settings.svg": 8237, "./share.svg": 3755, "./smoke.png": 6838, "./state_invalid.svg": 2553, "./state_pending.svg": 5769, "./state_verified.svg": 6244, "./summer.svg": 3901, "./test.svg": 1734, "./verified.svg": 3902, "./windowed.svg": 7173, "./winter.svg": 813, "./winter_colored.svg": 5010 }; function r(e) { var t = a(e); return n(t) } function a(e) { if (!n.o(i, e)) { var t = new Error("Cannot find module '" + e + "'"); throw t.code = "MODULE_NOT_FOUND", t } return i[e] } r.keys = function() { return Object.keys(i) }, r.resolve = a, e.exports = r, r.id = 7780 }, 7818: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.user-export {\n\tposition: absolute;\n\tleft: calc(50% - 500px / 2);\n\ttop: 35%;\n\tz-index: 2;\n\tmargin: 0;\n\tpadding: 10px;\n\tbox-sizing: border-box;\n\twidth: 500px;\n\theight: 150px;\n\tbackground-color: var(--surface-color);\n}\n\n.user-export > textarea {\n\tmargin: 0;\n\tpadding: 10px;\n\tbox-sizing: border-box;\n\tmin-width: 100%;\n\tmax-width: 100%;\n\tmin-height: calc(100% - 52px - 10px);\n\tmax-height: calc(100% - 52px - 10px);\n\tpointer-events: auto;\n\tbackground-color: var(--surface-tertiary-color);\n\tborder: none;\n\tresize: none;\n\tcolor: var(--text-color);\n\tword-break: break-all;\n\tfont-size: 20px;\n}\n.user-export > textarea:focus-visible {\n\toutline: none;\n}\n\n.user-export > .bar {\n\tmargin: 8px 0 0 0;\n}\n\n.user-export > .bar > .button.right {\n\tfloat: right;\n}\n", ""]); const o = s }, 7825: e => { "use strict"; e.exports = function(e) { if ("undefined" == typeof document) return { update: function() {}, remove: function() {} }; var t = e.insertStyleElement(e); return { update: function(n) { ! function(e, t, n) { var i = ""; n.supports && (i += "@supports (".concat(n.supports, ") {")), n.media && (i += "@media ".concat(n.media, " {")); var r = void 0 !== n.layer; r && (i += "@layer".concat(n.layer.length > 0 ? " ".concat(n.layer) : "", " {")), i += n.css, r && (i += "}"), n.media && (i += "}"), n.supports && (i += "}"); var a = n.sourceMap; a && "undefined" != typeof btoa && (i += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a)))), " */")), t.styleTagTransform(i, e, t.options) }(t, e, n) }, remove: function() { ! function(e) { if (null === e.parentNode) return !1; e.parentNode.removeChild(e) }(t) } } } }, 8115: (e, t, n) => { "use strict"; e.exports = n.p + "images/community_tracks.jpg" }, 8229: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.hint {\n\tpadding: 0 280px;\n\tposition: absolute;\n\tleft: 0;\n\ttop: 150px;\n\twidth: 100%;\n\tbox-sizing: border-box;\n\ttext-align: center;\n\tcolor: #fff;\n\ttext-shadow: 0 0 5px #000;\n\tpointer-events: none;\n\topacity: 0;\n}\n.hint.show {\n\ttop: 150px;\n\topacity: 1;\n\ttransition: opacity 0.25s ease-in-out, top 0.25s ease-in-out;\n}\n.hint.hide {\n\ttop: 160px;\n\topacity: 0;\n\ttransition: opacity 0.25s ease-in-out, top 0.25s ease-in-out;\n}\n\n.hint > .title {\n\tfont-size: 32px;\n}\n\n.hint > .subtitle {\n\tmargin: 16px 0 0 0;\n\tfont-size: 24px;\n}\n", ""]); const o = s }, 8237: (e, t, n) => { "use strict"; e.exports = n.p + "images/settings.svg" }, 8353: (e, t, n) => { "use strict"; n.d(t, { A: () => g }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a), o = n(4417), l = n.n(o), c = new URL(n(9391), n.b), h = new URL(n(8115), n.b), d = new URL(n(2709), n.b), u = s()(r()), p = l()(c), f = l()(h), m = l()(d); u.push([e.id, `\n.track-selection {\n\tposition: absolute;\n\tbottom: 0;\n\tdisplay: flex;\n\tflex-direction: column;\n\twidth: 100%;\n\theight: 100%;\n\ttext-align: left;\n}\n\n.track-selection > .bar {\n\tdisplay: flex;\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n\tbackground-color: var(--surface-color);\n\ttext-align: left;\n\n\tpointer-events:auto;\n}\n.track-selection > .bar > .button {\n\tmargin: 8px 12px;\n}\n\n.track-selection > .bar > .search-bar-container {\n\tposition: relative;\n\tdisplay: flex;\n\tflex-grow: 1;\n}\n.track-selection > .bar > .search-bar-container > input {\n\tmargin: 8px -10px;\n\tpadding: 0 20px;\n\tflex-grow: 1;\n\tclip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n\tcolor: var(--text-color);\n\ttext-indent: 2px; /* Without this the italic text will be cut off on the left side. */\n}\n.track-selection > .bar > .search-bar-container > img {\n\tmargin: 8px -10px 8px 0;\n\tpadding: 0 16px;\n\twidth: 24px;\n\tbackground-color: var(--button-hover-color);\n\tclip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n}\n\n.track-selection .category-container {\n\tdisplay: flex;\n\tbackground-color: var(--surface-secondary-color);\n}\n.track-selection .category-container > button {\n\tposition: relative;\n\tmargin: 0 -3px;\n\tpadding: 0.6em 0;\n\tflex-grow: 1;\n\tbackground-color: transparent;\n\tfont-size: 2.8vw;\n\tfont-weight: bold;\n\ttext-shadow: 2px 2px 0 #112052, 0 0 10px #000, 0 0 10px #000;\n\tclip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n}\n.track-selection .category-container > button:first-of-type {\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n}\n.track-selection .category-container > button:last-of-type {\n\tclip-path: polygon(8px 0, 100% 0, 100% 100%, 0 100%);\n}\n.track-selection .category-container > button::before {\n\tcontent: "";\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tz-index: -1;\n\twidth: 100%;\n\theight: 100%;\n\tbackground-position: center;\n\tbackground-size: cover;\n\tfilter: blur(2px);\n\ttransition: filter 0.2s ease-in-out, 0.2s ease-in-out;\n}\n.track-selection .category-container > button.official::before {\n\tbackground-image: url(${p});\n}\n.track-selection .category-container > button.community::before {\n\tbackground-image: url(${f});\n}\n.track-selection .category-container > button.custom::before {\n\tbackground-image: url(${m});\n}\n.track-selection .category-container > button:hover::before {\n\tfilter: none;\n\ttransform: scale(1.1);\n}\n@media (hover: none) {\n\t.track-selection .category-container > button:hover::before {\n\t\tfilter: blur(2px);\n\t\ttransform: none;\n\t}\n\n\t.track-selection .category-container > button:active::before {\n\t\tfilter: none;\n\t\ttransform: scale(1.1);\n\t}\n}\n.track-selection .category-container > button.selected::before {\n\tfilter: none;\n}\n.track-selection .category-container > button::after {\n\tbackground-color: transparent;\n}\n.track-selection .category-container > button.selected::after {\n\twidth: 100%;\n}\n\n.track-selection .category-container > button > .cover {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tz-index: -1;\n\twidth: 100%;\n\theight: 100%;\n\tbackground-color: rgba(17, 32, 82, 0.75);\n\ttransition: background-color 0.2s ease-in-out;\n}\n.track-selection .category-container > button:hover > .cover {\n\tbackground-color: rgba(51, 75, 119, 0.5);\n}\n@media (hover: none) {\n\t.track-selection .category-container > button:hover > .cover {\n\t\tbackground-color: rgba(17, 32, 82, 0.75);\n\t}\n}\n.track-selection .category-container > button:active > .cover {\n\tbackground-color: rgba(21, 31, 65, 0.5);\n}\n.track-selection .category-container > button.selected > .cover {\n\tbackground-color: transparent;\n}\n\n@media (max-width: 1150px) {\n\t.track-selection .category-container > button {\n\t\tfont-size: 32.2px;\n\t}\n}\n\n.track-selection .tracks-container {\n\tmargin: 0;\n\tpadding: 20px 60px;\n\tbox-sizing: border-box;\n\twidth: 100%;\n\tflex-grow: 1;\n\toverflow-y: auto;\n\tpointer-events: auto;\n\tdisplay: none;\n}\n.track-selection .tracks-container.open {\n\tdisplay: block;\n}\n.track-selection.editor-track-selection .tracks-container {\n\tbackground-color: rgba(20, 20, 45, 0.8);\n}\n\n.track-selection .tracks-container > .empty {\n\tmargin: 100px;\n\tcolor: var(--text-color);\n\ttext-align: center;\n}\n.track-selection .tracks-container > .empty > .title {\n\tfont-size: 48px;\n}\n.track-selection .tracks-container > .empty > .description {\n\tmargin: 20px 0 0 0;\n\tfont-size: 32px;\n\topacity: 0.75;\n}\n\n.track-selection .environment-title {\n\tmargin: 0.5em 0.4em;\n\tpadding: 0;\n\tfont-size: 50px;\n\tfont-weight: normal;\n\tborder-bottom-width: 4px;\n\tborder-bottom-style: solid;\n\t\n}\n.track-selection .environment-title.summer {\n\tcolor: var(--text-color);\n\tborder-image: linear-gradient(to right, var(--text-color), transparent) 1;\n}\n.track-selection .environment-title.winter {\n\tcolor: #bed8f7;\n\tborder-image: linear-gradient(to right, #bed8f7, transparent) 1;\n}\n.track-selection .environment-title.desert {\n\tcolor: #ede2af;\n\tborder-image: linear-gradient(to right, #ede2af, transparent) 1;\n}\n\n.track-selection .environment-title > img {\n\tmargin: 6px 8px;\n\twidth: 36px;\n\theight: 36px;\n\tvertical-align: bottom;\n}\n\n.track-selection .tracks-container .track {\n\tposition: relative;\n\tdisplay: inline-block;\n}\n\n.track-selection .tracks-container .track button {\n\tmargin: 10px;\n\tpadding: 0;\n\tcolor: var(--text-color);\n\tfont-size: 32px;\n}\n.track-selection .tracks-container .track button:after {\n\tborder-bottom: none;\n}\n.track-selection .tracks-container .track button:focus-visible {\n\ttext-decoration: none;\n}\n\n.track-selection .track-title {\n\tmargin: 0;\n\tpadding: 4px;\n\tfont-size: 25px;\n\tbackground-color: var(--surface-secondary-color);\n}\n.track-selection .tracks-container .track button:focus-visible .track-title {\n\ttext-decoration: underline;\n}\n.track-selection .track-title > p {\n\tmargin: 0;\n\tpadding: 0 22px;\n\twidth: 208px;\n\tbox-sizing: border-box;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n\n.track-selection .track canvas {\n\tmargin: 0;\n\tpadding: 20px 40px;\n\twidth: 128px;\n\theight: 128px;\n\tobject-fit: contain;\n\t-webkit-filter: drop-shadow(0 0 3px #000);\n\tfilter: drop-shadow(0 0 3px #000);\n\timage-rendering: pixelated;\n}\n\n.track-selection .track .environment {\n\tposition: absolute;\n\tright: 14px;\n\tbottom: 40px;\n\twidth: 24px;\n\topacity: 0.2;\n\tpointer-events: none;\n}\n\n.track-selection .record {\n\tmargin: 0;\n\tpadding: 4px;\n\tfont-size: 24px;\n\tbackground-color: var(--surface-secondary-color);\n\tcolor: var(--text-color);\n}\n\n.track-selection .delete-button {\n\tposition: absolute;\n\ttop: 7px;\n\tright: 6px;\n\tmargin: 0;\n\tpadding: 0;\n\tline-height: 0;\n\tborder-radius: 2px;\n\tborder: none;\n\tbackground-color: var(--button-color);\n\n\tpointer-events: auto;\n\tcursor: pointer;\n}\n.track-selection .delete-button:hover {\n\tbackground-color: var(--button-hover-color);\n}\n@media (hover: none) {\n\t.track-selection .delete-button:hover {\n\t\tbackground-color: var(--button-color);\n\t}\n}\n.track-selection .delete-button:active {\n\tbackground-color: var(--button-active-color);\n}\n.track-selection .delete-button > img {\n\tmargin: 0;\n\tpadding: 0;\n\theight: 20px;\n\tvertical-align: top;\n\tpointer-events: none;\n}\n`, ""]); const g = u }, 8358: (e, t, n) => { "use strict"; e.exports = n.p + "images/overlapping_disabled.svg" }, 8419: (e, t, n) => { "use strict"; n.d(t, { A: () => g }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a), o = n(4417), l = n.n(o), c = new URL(n(3682), n.b), h = new URL(n(2208), n.b), d = new URL(n(2832), n.b), u = s()(r()), p = l()(c), f = l()(h), m = l()(d); u.push([e.id, `\n:root {\n\tinterpolate-size: allow-keywords; \n\n\t--text-color: #fff;\n\t--text-disabled-color: #5d6a7c;\n\t--surface-color: #28346a;\n\t--surface-secondary-color: #212b58;\n\t--surface-tertiary-color: #192042;\n\t--surface-transparent-color: rgba(40, 52, 106, 0.5);\n\t--button-color: #112052;\n\t--button-hover-color: #334b77;\n\t--button-active-color: #151f41;\n\t--button-disabled-color: #313d53;\n}\n\n@font-face {\n\tfont-family: ForcedSquare;\n\tsrc:\n\t\turl(${p}) format("woff2"),\n\t\turl(${f}) format("woff"),\n\t\turl(${m}) format("truetype");\n}\n\nhtml, body {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n\theight: 100%;\n\toverflow: hidden;\n\toverscroll-behavior: none;\n\n\tbackground: #000;\n}\n\nbody {\n\tscrollbar-color: #7272c2 #223;\n\ttouch-action: none;\n}\n\n* {\n\tfont-style: italic;\n\tfont-family: ForcedSquare, Arial, sans-serif;\n\tline-height: 1;\n}\n\n#screen {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n\theight: 100%;\n\t-webkit-tap-highlight-color: transparent;\n\t-webkit-touch-callout: none;\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n\ttouch-action: none;\n}\n\n#ui {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\twidth: 100%;\n\theight: 100%;\n\ttransform-origin: 0 0;\n\tpointer-events: none;\n\t-webkit-tap-highlight-color: transparent;\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n}\n\n::-webkit-scrollbar {\n\twidth: 8px;\n\tbackground-color: #223;\n}\n::-webkit-scrollbar-thumb {\n\tborder-radius: 4px;\n\tbackground-color: #7272c2;\n}\n\n::selection {\n\tbackground-color: #5936d6;\n\tcolor: #fff;\n}\n\n.hide-cursor {\n\tcursor: none;\n}\n\n.hidden {\n\tdisplay: none;\n}\n\ninput[type="text"] {\n\tmargin: 0;\n\tpadding: 4px 8px;\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n\tfont-size: 24px;\n\tfont-weight: bold;\n\ttext-indent: 6px; /* Fixes italic text being cut off. */\n\tcolor: var(--text-color);\n\tbackground-color: var(--surface-tertiary-color);\n\tborder: none;\n\tpointer-events: auto;\n}\ninput[type="text"]::placeholder {\n\tcolor: var(--text-color);\n\topacity: 0.25;\n}\ninput[type="text"]:focus-visible {\n\toutline: none;\n}\n\ninput[type="range"] {\n\tmargin: 0;\n\tpadding: 0;\n\t-webkit-appearance: none;\n\tappearance: none;\n\tbackground: transparent;\n\tcursor: pointer;\n\taccent-color: var(--text-color);\n}\ninput[type="range"]::-webkit-slider-runnable-track {\n\tbackground-color: var(--surface-tertiary-color);\n\theight: 10px;\n}\ninput[type="range"]::-moz-range-track {\n\tbackground-color: var(--surface-tertiary-color);\n\theight: 10px;\n}\ninput[type="range"]::-webkit-slider-thumb {\n\t-webkit-appearance: none;\n\tappearance: none;\n\tborder-radius: 0;\n\tbackground: var(--text-color);\n\twidth: 32px;\n\theight: 32px;\n\tmargin: -13px 0 0 0;\n\tborder: 4px solid var(--button-color);\n\toutline: 2px solid var(--text-color);\n}\ninput[type="range"]::-webkit-slider-thumb:hover {\n\tborder: 4px solid var(--button-hover-color);\n}\n@media (hover: none) {\n\tinput[type="range"]::-webkit-slider-thumb:hover {\n\t\tborder: 4px solid var(--button-color);\n\t}\n}\ninput[type="range"]::-webkit-slider-thumb:active {\n\tborder: 4px solid var(--button-active-color);\n}\ninput[type="range"]::-moz-range-thumb {\n\t-webkit-appearance: none;\n\tappearance: none;\n\tborder-radius: 0;\n\tbackground: var(--text-color);\n\twidth: 24px;\n\theight: 24px;\n\tborder: 4px solid var(--button-color);\n\toutline: 2px solid var(--text-color);\n}\ninput[type="range"]::-moz-range-thumb:hover {\n\tborder: 4px solid var(--button-hover-color);\n}\n@media (hover: none) {\n\tinput[type="range"]::-moz-range-thumb:hover {\n\t\tborder: 4px solid var(--button-color);\n\t}\n}\ninput[type="range"]::-moz-range-thumb:active {\n\tborder: 4px solid var(--button-active-color);\n}\n\n.button {\n\tposition: relative;\n\tmargin: 0;\n\tpadding: 8px 18px;\n\tbackground-color: var(--button-color);\n\tborder: none;\n\tclip-path: polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n\tcolor: var(--text-color);\n\tfont-size: 32px;\n\n\tpointer-events: auto;\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n\tcursor: pointer;\n}\n.button::after {\n\tcontent: "";\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n\tz-index: -1;\n\twidth: 0;\n\theight: 100%;\n\tbackground-color: var(--button-hover-color);\n\tborder-bottom: 2px solid var(--text-color);\n\ttransition: width 0.1s ease-in-out;\n}\n.button:hover::after {\n\twidth: 100%;\n}\n@media (hover: none) {\n\t.button::after {\n\t\tbackground-color: var(--button-active-color);\n\t}\n\n\t.button:hover::after {\n\t\twidth: 0;\n\t}\n}\n.button:active::after {\n\tbackground-color: var(--button-active-color);\n\twidth: 100%;\n}\n.button:focus-visible {\n\tbackground-color: var(--button-hover-color);\n\ttext-decoration: underline;\n\toutline: none;\n}\n.button > img.button-icon {\n\tmargin: -6px -4px 0 -4px;\n\tpadding: 0;\n\twidth: 32px;\n\theight: 32px;\n\tvertical-align: middle;\n\tpointer-events: none;\n}\n.button:disabled {\n\tbackground-color: var(--button-disabled-color);\n\tcolor: var(--text-disabled-color);\n\tcursor: default;\n}\n.button:disabled:after {\n\tcontent: none;\n}\n.button:disabled > img.button-icon {\n\topacity: 0.3;\n}\n`, ""]); const g = u }, 8718: (e, t, n) => { "use strict"; e.exports = n.p + "images/search.svg" }, 8768: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.preview-toolbar {\n\tposition: absolute;\n\tleft: 0;\n\tbottom: 0;\n\tpadding: 8px 10px 8px 8px;\n\tbackground-color: var(--surface-color);\n\tclip-path: polygon(0 0, 100% 0, calc(100% - 8px) 100%, 0 100%);\n}\n", ""]); const o = s }, 8787: (e, t, n) => { "use strict"; e.exports = n.p + "images/back.svg" }, 8875: (e, t, n) => { "use strict"; e.exports = n.p + "images/clouds.jpg" }, 8889: (e, t, n) => { "use strict"; e.exports = n.p + "images/editor.svg" }, 8903: (e, t, n) => { "use strict"; e.exports = n.p + "images/logo.svg" }, 8909: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.editor-checkpoint-order > .buttons {\n\tdisplay: inline-block;\n\tvertical-align: bottom;\n}\n.editor-checkpoint-order > .buttons > button {\n\tdisplay: block;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: none;\n\tbackground-color: var(--button-color);\n\tpointer-events: auto;\n\tcursor: pointer;\n}\n.editor-checkpoint-order > .buttons > button:hover {\n\tbackground-color: var(--button-hover-color);\n}\n@media (hover: none) {\n\t.editor-checkpoint-order > .buttons > button:hover {\n\t\tbackground-color: var(--button-color);\n\t}\n}\n.editor-checkpoint-order > .buttons > button:active {\n\tbackground-color: var(--button-active-color);\n}\n\n.editor-checkpoint-order > .buttons > button > img {\n\tmargin: 0;\n\tpadding: 0 6px;\n\twidth: 20px;\n\theight: 20px;\n\tvertical-align: bottom;\n\tpointer-events: none;\n}\n.editor-checkpoint-order.touch > .buttons > button > img {\n\tpadding: 24px;\n\twidth: 40px;\n\theight: 40px;\n}\n\n.editor-checkpoint-order > p {\n\tmargin: 0;\n\tpadding: 0 10px;\n\tdisplay: inline-block;\n\tvertical-align: bottom;\n\tline-height: 40px;\n\tmin-width: 275px;\n\tfont-size: 26px;\n\ttext-align: center;\n\tbackground-color: var(--surface-transparent-color);\n\tcolor: var(--text-color);\n}\n.editor-checkpoint-order.touch > p {\n\tline-height: calc((40px + 2 * 24px) * 2);\n}\n", ""]); const o = s }, 9027: (e, t, n) => { "use strict"; e.exports = n.p + "images/customize.svg" }, 9062: (e, t, n) => { "use strict"; e.exports = n.p + "images/rotation_axis_y_positive.svg" }, 9077: (e, t, n) => { "use strict"; e.exports = n.p + "images/import.svg" }, 9207: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n#transition-layer {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\tz-index: 1;\n\twidth: 100%;\n\theight: 100%;\n\tbackground-color: #000;\n\tpointer-events: none;\n\n\topacity: 0;\n\ttransition: 0.25s ease-in-out opacity;\n}\n", ""]); const o = s }, 9236: (e, t, n) => { "use strict"; e.exports = n.p + "images/play.svg" }, 9242: (e, t, n) => { "use strict"; n.d(t, { A: () => o }); var i = n(1601), r = n.n(i), a = n(6314), s = n.n(a)()(r()); s.push([e.id, "\n.editor-help > .background {\n\tposition: absolute;\n\tleft: 0;\n\ttop: 0;\n\tz-index: 1;\n\twidth: 100%;\n\theight: 100%;\n\tbackground-color: rgba(20, 20, 30, 0.5);\n\tpointer-events: auto;\n}\n\n.editor-help > .container {\n\tposition: absolute;\n\tleft: calc(50% - 80% / 2);\n\ttop: 0;\n\tz-index: 2;\n\tdisplay: flex;\n\tflex-direction: column;\n\tbox-sizing: border-box;\n\twidth: 80%;\n\theight: 100%;\n\tbackground-color: var(--surface-color);\n}\n\n.editor-help > .container > h1 {\n\tmargin: 10px;\n\tpadding: 0;\n\tfont-weight: normal;\n\tfont-size: 38px;\n\ttext-align: center;\n\tcolor: var(--text-color);\n}\n\n.editor-help > .container > .content {\n\tflex-grow: 1;\n\tpadding: 40px;\n\tbackground-color: var(--surface-secondary-color);\n\toverflow-y: auto;\n\tpointer-events: auto;\n}\n\n.editor-help > .container > .content > h2 {\n\tmargin: 32px 0 16px 0;\n\tpadding: 0;\n\tfont-weight: normal;\n\tfont-size: 30px;\n\tcolor: var(--text-color);\n\tborder-bottom: 2px solid var(--text-color);\n}\n.editor-help > .container > .content > h2:first-of-type {\n\tmargin-top: 0;\n}\n\n.editor-help > .container > .content > p {\n\tmargin: 0;\n\tpadding: 0;\n\tfont-size: 20px;\n\tcolor: var(--text-color);\n\twhite-space: pre-wrap;\n}\n\n.editor-help > .container > .content > .part-images {\n\tdisplay: flex;\n\tjustify-content: space-around;\n}\n\n.editor-help > .container > .content > .part-images > div {\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.editor-help > .container > .content > .part-images > div > img {\n\twidth: 128px;\n\theight: 128px;\n\tfilter: drop-shadow(0 4px 5px rgba(0, 0, 0, 0.4));\n\tpointer-events: none;\n\ttransition: opacity 0.25s ease-out;\n}\n.editor-help > .container > .content > .part-images > div > img.loading {\n\topacity: 0;\n}\n\n.editor-help > .container > .content > .part-images > div > span {\n\tmargin: 0;\n\tpadding: 0;\n\tfont-size: 20px;\n\tcolor: var(--text-color);\n\ttext-align: center;\n}\n\n.editor-help > .container > .button-wrapper > button {\n\tmargin: 10px;\n}\n", ""]); const o = s }, 9391: (e, t, n) => { "use strict"; e.exports = n.p + "images/official_tracks.jpg" }, 9570: (e, t, n) => { "use strict"; e.exports = n.p + "images/preview.svg" }, 9708: (e, t, n) => { "use strict"; e.exports = n.p + "images/pause.svg" }, 9809: (e, t, n) => { "use strict"; e.exports = n.p + "images/checkmark.svg" } }, t = {}; function n(i) { var r = t[i]; if (void 0 !== r) return r.exports; var a = t[i] = { id: i, exports: {} }; return e[i](a, a.exports, n), a.exports } n.m = e, n.amdO = {}, n.n = e => { var t = e && e.__esModule ? () => e.default : () => e; return n.d(t, { a: t }), t }, n.d = (e, t) => { for (var i in t) n.o(t, i) && !n.o(e, i) && Object.defineProperty(e, i, { enumerable: !0, get: t[i] }) }, n.g = function() { if ("object" == typeof globalThis) return globalThis; try { return this || new Function("return this")() } catch (e) { if ("object" == typeof window) return window } }(), n.o = (e, t) => Object.prototype.hasOwnProperty.call(e, t), (() => { var e; n.g.importScripts && (e = n.g.location + ""); var t = n.g.document; if (!e && t && (t.currentScript && "SCRIPT" === t.currentScript.tagName.toUpperCase() && (e = t.currentScript.src), !e)) { var i = t.getElementsByTagName("script"); if (i.length) for (var r = i.length - 1; r > -1 && (!e || !/^http(s?):/.test(e));) e = i[r--].src } if (!e) throw new Error("Automatic publicPath is not supported in this browser"); e = e.replace(/^blob:/, "").replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/"), n.p = e })(), n.b = document.baseURI || self.location.href, n.nc = void 0, (() => { "use strict"; n(6925); var e = n(5072), t = n.n(e), i = n(7825), r = n.n(i), a = n(7659), s = n.n(a), o = n(5056), l = n.n(o), c = n(540), h = n.n(c), d = n(1113), u = n.n(d), p = n(8419), f = {}; f.styleTagTransform = u(), f.setAttributes = l(), f.insert = s().bind(null, "head"), f.domAPI = r(), f.insertStyleElement = h(); t()(p.A, f); p.A && p.A.locals && p.A.locals; const m = "174", g = 0, v = 1, w = 2, y = 0, A = 1, b = 2, x = 3, k = 0, E = 1, S = 2, M = 100, T = 101, _ = 102, C = 200, P = 201, I = 202, R = 203, L = 204, D = 205, N = 206, B = 207, U = 208, z = 209, O = 210, F = 211, W = 212, V = 213, H = 214, G = 0, j = 1, Q = 2, Y = 3, K = 4, q = 5, X = 6, Z = 7, J = "attached", $ = 301, ee = 302, te = 303, ne = 304, ie = 306, re = 1e3, ae = 1001, se = 1002, oe = 1003, le = 1004, ce = 1005, he = 1006, de = 1007, ue = 1008, pe = 1009, fe = 1010, me = 1011, ge = 1012, ve = 1013, we = 1014, ye = 1015, Ae = 1016, be = 1017, xe = 1018, ke = 1020, Ee = 35902, Se = 1023, Me = 1026, Te = 1027, _e = 1028, Ce = 1029, Pe = 1031, Ie = 1033, Re = 33776, Le = 33777, De = 33778, Ne = 33779, Be = 35840, Ue = 35841, ze = 35842, Oe = 35843, Fe = 36196, We = 37492, Ve = 37496, He = 37808, Ge = 37809, je = 37810, Qe = 37811, Ye = 37812, Ke = 37813, qe = 37814, Xe = 37815, Ze = 37816, Je = 37817, $e = 37818, et = 37819, tt = 37820, nt = 37821, it = 36492, rt = 36494, at = 36495, st = 36284, ot = 36285, lt = 36286, ct = 2300, ht = 2301, dt = 2302, ut = 2400, pt = 2401, ft = 2402, mt = "", gt = "srgb", vt = "srgb-linear", wt = "linear", yt = "srgb", At = 7680, bt = 512, xt = 513, kt = 514, Et = 515, St = 516, Mt = 517, Tt = 518, _t = 519, Ct = 35044, Pt = "300 es", It = 2e3, Rt = 2001; class Lt { addEventListener(e, t) { void 0 === this._listeners && (this._listeners = {}); const n = this._listeners; void 0 === n[e] && (n[e] = []), -1 === n[e].indexOf(t) && n[e].push(t) } hasEventListener(e, t) { const n = this._listeners; return void 0 !== n && (void 0 !== n[e] && -1 !== n[e].indexOf(t)) } removeEventListener(e, t) { const n = this._listeners; if (void 0 === n) return; const i = n[e]; if (void 0 !== i) { const e = i.indexOf(t); - 1 !== e && i.splice(e, 1) } } dispatchEvent(e) { const t = this._listeners; if (void 0 === t) return; const n = t[e.type]; if (void 0 !== n) { e.target = this; const t = n.slice(0); for (let n = 0, i = t.length; n < i; n++) t[n].call(this, e); e.target = null } } } const Dt = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"]; let Nt = 1234567; const Bt = Math.PI / 180, Ut = 180 / Math.PI; function zt() { const e = 4294967295 * Math.random() | 0, t = 4294967295 * Math.random() | 0, n = 4294967295 * Math.random() | 0, i = 4294967295 * Math.random() | 0; return (Dt[255 & e] + Dt[e >> 8 & 255] + Dt[e >> 16 & 255] + Dt[e >> 24 & 255] + "-" + Dt[255 & t] + Dt[t >> 8 & 255] + "-" + Dt[t >> 16 & 15 | 64] + Dt[t >> 24 & 255] + "-" + Dt[63 & n | 128] + Dt[n >> 8 & 255] + "-" + Dt[n >> 16 & 255] + Dt[n >> 24 & 255] + Dt[255 & i] + Dt[i >> 8 & 255] + Dt[i >> 16 & 255] + Dt[i >> 24 & 255]).toLowerCase() } function Ot(e, t, n) { return Math.max(t, Math.min(n, e)) } function Ft(e, t) { return (e % t + t) % t } function Wt(e, t, n) { return (1 - n) * e + n * t } function Vt(e, t) { switch (t.constructor) { case Float32Array: return e; case Uint32Array: return e / 4294967295; case Uint16Array: return e / 65535; case Uint8Array: return e / 255; case Int32Array: return Math.max(e / 2147483647, -1); case Int16Array: return Math.max(e / 32767, -1); case Int8Array: return Math.max(e / 127, -1); default: throw new Error("Invalid component type.") } } function Ht(e, t) { switch (t.constructor) { case Float32Array: return e; case Uint32Array: return Math.round(4294967295 * e); case Uint16Array: return Math.round(65535 * e); case Uint8Array: return Math.round(255 * e); case Int32Array: return Math.round(2147483647 * e); case Int16Array: return Math.round(32767 * e); case Int8Array: return Math.round(127 * e); default: throw new Error("Invalid component type.") } } const Gt = { DEG2RAD: Bt, RAD2DEG: Ut, generateUUID: zt, clamp: Ot, euclideanModulo: Ft, mapLinear: function(e, t, n, i, r) { return i + (e - t) * (r - i) / (n - t) }, inverseLerp: function(e, t, n) { return e !== t ? (n - e) / (t - e) : 0 }, lerp: Wt, damp: function(e, t, n, i) { return Wt(e, t, 1 - Math.exp(-n * i)) }, pingpong: function(e, t = 1) { return t - Math.abs(Ft(e, 2 * t) - t) }, smoothstep: function(e, t, n) { return e <= t ? 0 : e >= n ? 1 : (e = (e - t) / (n - t)) * e * (3 - 2 * e) }, smootherstep: function(e, t, n) { return e <= t ? 0 : e >= n ? 1 : (e = (e - t) / (n - t)) * e * e * (e * (6 * e - 15) + 10) }, randInt: function(e, t) { return e + Math.floor(Math.random() * (t - e + 1)) }, randFloat: function(e, t) { return e + Math.random() * (t - e) }, randFloatSpread: function(e) { return e * (.5 - Math.random()) }, seededRandom: function(e) { void 0 !== e && (Nt = e); let t = Nt += 1831565813; return t = Math.imul(t ^ t >>> 15, 1 | t), t ^= t + Math.imul(t ^ t >>> 7, 61 | t), ((t ^ t >>> 14) >>> 0) / 4294967296 }, degToRad: function(e) { return e * Bt }, radToDeg: function(e) { return e * Ut }, isPowerOfTwo: function(e) { return !(e & e - 1) && 0 !== e }, ceilPowerOfTwo: function(e) { return Math.pow(2, Math.ceil(Math.log(e) / Math.LN2)) }, floorPowerOfTwo: function(e) { return Math.pow(2, Math.floor(Math.log(e) / Math.LN2)) }, setQuaternionFromProperEuler: function(e, t, n, i, r) { const a = Math.cos, s = Math.sin, o = a(n / 2), l = s(n / 2), c = a((t + i) / 2), h = s((t + i) / 2), d = a((t - i) / 2), u = s((t - i) / 2), p = a((i - t) / 2), f = s((i - t) / 2); switch (r) { case "XYX": e.set(o * h, l * d, l * u, o * c); break; case "YZY": e.set(l * u, o * h, l * d, o * c); break; case "ZXZ": e.set(l * d, l * u, o * h, o * c); break; case "XZX": e.set(o * h, l * f, l * p, o * c); break; case "YXY": e.set(l * p, o * h, l * f, o * c); break; case "ZYZ": e.set(l * f, l * p, o * h, o * c); break; default: console.warn("THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: " + r) } }, normalize: Ht, denormalize: Vt }; class jt { constructor(e = 0, t = 0) { jt.prototype.isVector2 = !0, this.x = e, this.y = t } get width() { return this.x } set width(e) { this.x = e } get height() { return this.y } set height(e) { this.y = e } set(e, t) { return this.x = e, this.y = t, this } setScalar(e) { return this.x = e, this.y = e, this } setX(e) { return this.x = e, this } setY(e) { return this.y = e, this } setComponent(e, t) { switch (e) { case 0: this.x = t; break; case 1: this.y = t; break; default: throw new Error("index is out of range: " + e) } return this } getComponent(e) { switch (e) { case 0: return this.x; case 1: return this.y; default: throw new Error("index is out of range: " + e) } } clone() { return new this.constructor(this.x, this.y) } copy(e) { return this.x = e.x, this.y = e.y, this } add(e) { return this.x += e.x, this.y += e.y, this } addScalar(e) { return this.x += e, this.y += e, this } addVectors(e, t) { return this.x = e.x + t.x, this.y = e.y + t.y, this } addScaledVector(e, t) { return this.x += e.x * t, this.y += e.y * t, this } sub(e) { return this.x -= e.x, this.y -= e.y, this } subScalar(e) { return this.x -= e, this.y -= e, this } subVectors(e, t) { return this.x = e.x - t.x, this.y = e.y - t.y, this } multiply(e) { return this.x *= e.x, this.y *= e.y, this } multiplyScalar(e) { return this.x *= e, this.y *= e, this } divide(e) { return this.x /= e.x, this.y /= e.y, this } divideScalar(e) { return this.multiplyScalar(1 / e) } applyMatrix3(e) { const t = this.x, n = this.y, i = e.elements; return this.x = i[0] * t + i[3] * n + i[6], this.y = i[1] * t + i[4] * n + i[7], this } min(e) { return this.x = Math.min(this.x, e.x), this.y = Math.min(this.y, e.y), this } max(e) { return this.x = Math.max(this.x, e.x), this.y = Math.max(this.y, e.y), this } clamp(e, t) { return this.x = Ot(this.x, e.x, t.x), this.y = Ot(this.y, e.y, t.y), this } clampScalar(e, t) { return this.x = Ot(this.x, e, t), this.y = Ot(this.y, e, t), this } clampLength(e, t) { const n = this.length(); return this.divideScalar(n || 1).multiplyScalar(Ot(n, e, t)) } floor() { return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this } ceil() { return this.x = Math.ceil(this.x), this.y = Math.ceil(this.y), this } round() { return this.x = Math.round(this.x), this.y = Math.round(this.y), this } roundToZero() { return this.x = Math.trunc(this.x), this.y = Math.trunc(this.y), this } negate() { return this.x = -this.x, this.y = -this.y, this } dot(e) { return this.x * e.x + this.y * e.y } cross(e) { return this.x * e.y - this.y * e.x } lengthSq() { return this.x * this.x + this.y * this.y } length() { return Math.sqrt(this.x * this.x + this.y * this.y) } manhattanLength() { return Math.abs(this.x) + Math.abs(this.y) } normalize() { return this.divideScalar(this.length() || 1) } angle() { return Math.atan2(-this.y, -this.x) + Math.PI } angleTo(e) { const t = Math.sqrt(this.lengthSq() * e.lengthSq()); if (0 === t) return Math.PI / 2; const n = this.dot(e) / t; return Math.acos(Ot(n, -1, 1)) } distanceTo(e) { return Math.sqrt(this.distanceToSquared(e)) } distanceToSquared(e) { const t = this.x - e.x, n = this.y - e.y; return t * t + n * n } manhattanDistanceTo(e) { return Math.abs(this.x - e.x) + Math.abs(this.y - e.y) } setLength(e) { return this.normalize().multiplyScalar(e) } lerp(e, t) { return this.x += (e.x - this.x) * t, this.y += (e.y - this.y) * t, this } lerpVectors(e, t, n) { return this.x = e.x + (t.x - e.x) * n, this.y = e.y + (t.y - e.y) * n, this } equals(e) { return e.x === this.x && e.y === this.y } fromArray(e, t = 0) { return this.x = e[t], this.y = e[t + 1], this } toArray(e = [], t = 0) { return e[t] = this.x, e[t + 1] = this.y, e } fromBufferAttribute(e, t) { return this.x = e.getX(t), this.y = e.getY(t), this } rotateAround(e, t) { const n = Math.cos(t), i = Math.sin(t), r = this.x - e.x, a = this.y - e.y; return this.x = r * n - a * i + e.x, this.y = r * i + a * n + e.y, this } random() { return this.x = Math.random(), this.y = Math.random(), this }*[Symbol.iterator]() { yield this.x, yield this.y } } class Qt { constructor(e, t, n, i, r, a, s, o, l) { Qt.prototype.isMatrix3 = !0, this.elements = [1, 0, 0, 0, 1, 0, 0, 0, 1], void 0 !== e && this.set(e, t, n, i, r, a, s, o, l) } set(e, t, n, i, r, a, s, o, l) { const c = this.elements; return c[0] = e, c[1] = i, c[2] = s, c[3] = t, c[4] = r, c[5] = o, c[6] = n, c[7] = a, c[8] = l, this } identity() { return this.set(1, 0, 0, 0, 1, 0, 0, 0, 1), this } copy(e) { const t = this.elements, n = e.elements; return t[0] = n[0], t[1] = n[1], t[2] = n[2], t[3] = n[3], t[4] = n[4], t[5] = n[5], t[6] = n[6], t[7] = n[7], t[8] = n[8], this } extractBasis(e, t, n) { return e.setFromMatrix3Column(this, 0), t.setFromMatrix3Column(this, 1), n.setFromMatrix3Column(this, 2), this } setFromMatrix4(e) { const t = e.elements; return this.set(t[0], t[4], t[8], t[1], t[5], t[9], t[2], t[6], t[10]), this } multiply(e) { return this.multiplyMatrices(this, e) } premultiply(e) { return this.multiplyMatrices(e, this) } multiplyMatrices(e, t) { const n = e.elements, i = t.elements, r = this.elements, a = n[0], s = n[3], o = n[6], l = n[1], c = n[4], h = n[7], d = n[2], u = n[5], p = n[8], f = i[0], m = i[3], g = i[6], v = i[1], w = i[4], y = i[7], A = i[2], b = i[5], x = i[8]; return r[0] = a * f + s * v + o * A, r[3] = a * m + s * w + o * b, r[6] = a * g + s * y + o * x, r[1] = l * f + c * v + h * A, r[4] = l * m + c * w + h * b, r[7] = l * g + c * y + h * x, r[2] = d * f + u * v + p * A, r[5] = d * m + u * w + p * b, r[8] = d * g + u * y + p * x, this } multiplyScalar(e) { const t = this.elements; return t[0] *= e, t[3] *= e, t[6] *= e, t[1] *= e, t[4] *= e, t[7] *= e, t[2] *= e, t[5] *= e, t[8] *= e, this } determinant() { const e = this.elements, t = e[0], n = e[1], i = e[2], r = e[3], a = e[4], s = e[5], o = e[6], l = e[7], c = e[8]; return t * a * c - t * s * l - n * r * c + n * s * o + i * r * l - i * a * o } invert() { const e = this.elements, t = e[0], n = e[1], i = e[2], r = e[3], a = e[4], s = e[5], o = e[6], l = e[7], c = e[8], h = c * a - s * l, d = s * o - c * r, u = l * r - a * o, p = t * h + n * d + i * u; if (0 === p) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0); const f = 1 / p; return e[0] = h * f, e[1] = (i * l - c * n) * f, e[2] = (s * n - i * a) * f, e[3] = d * f, e[4] = (c * t - i * o) * f, e[5] = (i * r - s * t) * f, e[6] = u * f, e[7] = (n * o - l * t) * f, e[8] = (a * t - n * r) * f, this } transpose() { let e; const t = this.elements; return e = t[1], t[1] = t[3], t[3] = e, e = t[2], t[2] = t[6], t[6] = e, e = t[5], t[5] = t[7], t[7] = e, this } getNormalMatrix(e) { return this.setFromMatrix4(e).invert().transpose() } transposeIntoArray(e) { const t = this.elements; return e[0] = t[0], e[1] = t[3], e[2] = t[6], e[3] = t[1], e[4] = t[4], e[5] = t[7], e[6] = t[2], e[7] = t[5], e[8] = t[8], this } setUvTransform(e, t, n, i, r, a, s) { const o = Math.cos(r), l = Math.sin(r); return this.set(n * o, n * l, -n * (o * a + l * s) + a + e, -i * l, i * o, -i * (-l * a + o * s) + s + t, 0, 0, 1), this } scale(e, t) { return this.premultiply(Yt.makeScale(e, t)), this } rotate(e) { return this.premultiply(Yt.makeRotation(-e)), this } translate(e, t) { return this.premultiply(Yt.makeTranslation(e, t)), this } makeTranslation(e, t) { return e.isVector2 ? this.set(1, 0, e.x, 0, 1, e.y, 0, 0, 1) : this.set(1, 0, e, 0, 1, t, 0, 0, 1), this } makeRotation(e) { const t = Math.cos(e), n = Math.sin(e); return this.set(t, -n, 0, n, t, 0, 0, 0, 1), this } makeScale(e, t) { return this.set(e, 0, 0, 0, t, 0, 0, 0, 1), this } equals(e) { const t = this.elements, n = e.elements; for (let e = 0; e < 9; e++) if (t[e] !== n[e]) return !1; return !0 } fromArray(e, t = 0) { for (let n = 0; n < 9; n++) this.elements[n] = e[n + t]; return this } toArray(e = [], t = 0) { const n = this.elements; return e[t] = n[0], e[t + 1] = n[1], e[t + 2] = n[2], e[t + 3] = n[3], e[t + 4] = n[4], e[t + 5] = n[5], e[t + 6] = n[6], e[t + 7] = n[7], e[t + 8] = n[8], e } clone() { return (new this.constructor).fromArray(this.elements) } } const Yt = new Qt; function Kt(e) { for (let t = e.length - 1; t >= 0; --t) if (e[t] >= 65535) return !0; return !1 } Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array; function qt(e) { return document.createElementNS("http://www.w3.org/1999/xhtml", e) } function Xt() { const e = qt("canvas"); return e.style.display = "block", e } const Zt = {}; function Jt(e) { e in Zt || (Zt[e] = !0, console.warn(e)) } const $t = (new Qt).set(.4123908, .3575843, .1804808, .212639, .7151687, .0721923, .0193308, .1191948, .9505322), en = (new Qt).set(3.2409699, -1.5373832, -.4986108, -.9692436, 1.8759675, .0415551, .0556301, -.203977, 1.0569715); function tn() { const e = { enabled: !0, workingColorSpace: vt, spaces: {}, convert: function(e, t, n) { return !1 !== this.enabled && t !== n && t && n ? (this.spaces[t].transfer === yt && (e.r = rn(e.r), e.g = rn(e.g), e.b = rn(e.b)), this.spaces[t].primaries !== this.spaces[n].primaries && (e.applyMatrix3(this.spaces[t].toXYZ), e.applyMatrix3(this.spaces[n].fromXYZ)), this.spaces[n].transfer === yt && (e.r = an(e.r), e.g = an(e.g), e.b = an(e.b)), e) : e }, fromWorkingColorSpace: function(e, t) { return this.convert(e, this.workingColorSpace, t) }, toWorkingColorSpace: function(e, t) { return this.convert(e, t, this.workingColorSpace) }, getPrimaries: function(e) { return this.spaces[e].primaries }, getTransfer: function(e) { return e === mt ? wt : this.spaces[e].transfer }, getLuminanceCoefficients: function(e, t = this.workingColorSpace) { return e.fromArray(this.spaces[t].luminanceCoefficients) }, define: function(e) { Object.assign(this.spaces, e) }, _getMatrix: function(e, t, n) { return e.copy(this.spaces[t].toXYZ).multiply(this.spaces[n].fromXYZ) }, _getDrawingBufferColorSpace: function(e) { return this.spaces[e].outputColorSpaceConfig.drawingBufferColorSpace }, _getUnpackColorSpace: function(e = this.workingColorSpace) { return this.spaces[e].workingColorSpaceConfig.unpackColorSpace } }, t = [.64, .33, .3, .6, .15, .06], n = [.2126, .7152, .0722], i = [.3127, .329]; return e.define({ [vt]: { primaries: t, whitePoint: i, transfer: wt, toXYZ: $t, fromXYZ: en, luminanceCoefficients: n, workingColorSpaceConfig: { unpackColorSpace: gt }, outputColorSpaceConfig: { drawingBufferColorSpace: gt } }, [gt]: { primaries: t, whitePoint: i, transfer: yt, toXYZ: $t, fromXYZ: en, luminanceCoefficients: n, outputColorSpaceConfig: { drawingBufferColorSpace: gt } } }), e } const nn = tn(); function rn(e) { return e < .04045 ? .0773993808 * e : Math.pow(.9478672986 * e + .0521327014, 2.4) } function an(e) { return e < .0031308 ? 12.92 * e : 1.055 * Math.pow(e, .41666) - .055 } let sn; class on { static getDataURL(e) { if (/^data:/i.test(e.src)) return e.src; if ("undefined" == typeof HTMLCanvasElement) return e.src; let t; if (e instanceof HTMLCanvasElement) t = e; else { void 0 === sn && (sn = qt("canvas")), sn.width = e.width, sn.height = e.height; const n = sn.getContext("2d"); e instanceof ImageData ? n.putImageData(e, 0, 0) : n.drawImage(e, 0, 0, e.width, e.height), t = sn } return t.toDataURL("image/png") } static sRGBToLinear(e) { if ("undefined" != typeof HTMLImageElement && e instanceof HTMLImageElement || "undefined" != typeof HTMLCanvasElement && e instanceof HTMLCanvasElement || "undefined" != typeof ImageBitmap && e instanceof ImageBitmap) { const t = qt("canvas"); t.width = e.width, t.height = e.height; const n = t.getContext("2d"); n.drawImage(e, 0, 0, e.width, e.height); const i = n.getImageData(0, 0, e.width, e.height), r = i.data; for (let e = 0; e < r.length; e++) r[e] = 255 * rn(r[e] / 255); return n.putImageData(i, 0, 0), t } if (e.data) { const t = e.data.slice(0); for (let e = 0; e < t.length; e++) t instanceof Uint8Array || t instanceof Uint8ClampedArray ? t[e] = Math.floor(255 * rn(t[e] / 255)) : t[e] = rn(t[e]); return { data: t, width: e.width, height: e.height } } return console.warn("THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied."), e } } let ln = 0; class cn { constructor(e = null) { this.isSource = !0, Object.defineProperty(this, "id", { value: ln++ }), this.uuid = zt(), this.data = e, this.dataReady = !0, this.version = 0 } set needsUpdate(e) { !0 === e && this.version++ } toJSON(e) { const t = void 0 === e || "string" == typeof e; if (!t && void 0 !== e.images[this.uuid]) return e.images[this.uuid]; const n = { uuid: this.uuid, url: "" }, i = this.data; if (null !== i) { let e; if (Array.isArray(i)) { e = []; for (let t = 0, n = i.length; t < n; t++) i[t].isDataTexture ? e.push(hn(i[t].image)) : e.push(hn(i[t])) } else e = hn(i); n.url = e } return t || (e.images[this.uuid] = n), n } } function hn(e) { return "undefined" != typeof HTMLImageElement && e instanceof HTMLImageElement || "undefined" != typeof HTMLCanvasElement && e instanceof HTMLCanvasElement || "undefined" != typeof ImageBitmap && e instanceof ImageBitmap ? on.getDataURL(e) : e.data ? { data: Array.from(e.data), width: e.width, height: e.height, type: e.data.constructor.name } : (console.warn("THREE.Texture: Unable to serialize Texture."), {}) } let dn = 0; class un extends Lt { constructor(e = un.DEFAULT_IMAGE, t = un.DEFAULT_MAPPING, n = 1001, i = 1001, r = 1006, a = 1008, s = 1023, o = 1009, l = un.DEFAULT_ANISOTROPY, c = "") { super(), this.isTexture = !0, Object.defineProperty(this, "id", { value: dn++ }), this.uuid = zt(), this.name = "", this.source = new cn(e), this.mipmaps = [], this.mapping = t, this.channel = 0, this.wrapS = n, this.wrapT = i, this.magFilter = r, this.minFilter = a, this.anisotropy = l, this.format = s, this.internalFormat = null, this.type = o, this.offset = new jt(0, 0), this.repeat = new jt(1, 1), this.center = new jt(0, 0), this.rotation = 0, this.matrixAutoUpdate = !0, this.matrix = new Qt, this.generateMipmaps = !0, this.premultiplyAlpha = !1, this.flipY = !0, this.unpackAlignment = 4, this.colorSpace = c, this.userData = {}, this.version = 0, this.onUpdate = null, this.renderTarget = null, this.isRenderTargetTexture = !1, this.pmremVersion = 0 } get image() { return this.source.data } set image(e = null) { this.source.data = e } updateMatrix() { this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y) } clone() { return (new this.constructor).copy(this) } copy(e) { return this.name = e.name, this.source = e.source, this.mipmaps = e.mipmaps.slice(0), this.mapping = e.mapping, this.channel = e.channel, this.wrapS = e.wrapS, this.wrapT = e.wrapT, this.magFilter = e.magFilter, this.minFilter = e.minFilter, this.anisotropy = e.anisotropy, this.format = e.format, this.internalFormat = e.internalFormat, this.type = e.type, this.offset.copy(e.offset), this.repeat.copy(e.repeat), this.center.copy(e.center), this.rotation = e.rotation, this.matrixAutoUpdate = e.matrixAutoUpdate, this.matrix.copy(e.matrix), this.generateMipmaps = e.generateMipmaps, this.premultiplyAlpha = e.premultiplyAlpha, this.flipY = e.flipY, this.unpackAlignment = e.unpackAlignment, this.colorSpace = e.colorSpace, this.renderTarget = e.renderTarget, this.isRenderTargetTexture = e.isRenderTargetTexture, this.userData = JSON.parse(JSON.stringify(e.userData)), this.needsUpdate = !0, this } toJSON(e) { const t = void 0 === e || "string" == typeof e; if (!t && void 0 !== e.textures[this.uuid]) return e.textures[this.uuid]; const n = { metadata: { version: 4.6, type: "Texture", generator: "Texture.toJSON" }, uuid: this.uuid, name: this.name, image: this.source.toJSON(e).uuid, mapping: this.mapping, channel: this.channel, repeat: [this.repeat.x, this.repeat.y], offset: [this.offset.x, this.offset.y], center: [this.center.x, this.center.y], rotation: this.rotation, wrap: [this.wrapS, this.wrapT], format: this.format, internalFormat: this.internalFormat, type: this.type, colorSpace: this.colorSpace, minFilter: this.minFilter, magFilter: this.magFilter, anisotropy: this.anisotropy, flipY: this.flipY, generateMipmaps: this.generateMipmaps, premultiplyAlpha: this.premultiplyAlpha, unpackAlignment: this.unpackAlignment }; return Object.keys(this.userData).length > 0 && (n.userData = this.userData), t || (e.textures[this.uuid] = n), n } dispose() { this.dispatchEvent({ type: "dispose" }) } transformUv(e) { if (300 !== this.mapping) return e; if (e.applyMatrix3(this.matrix), e.x < 0 || e.x > 1) switch (this.wrapS) { case re: e.x = e.x - Math.floor(e.x); break; case ae: e.x = e.x < 0 ? 0 : 1; break; case se: 1 === Math.abs(Math.floor(e.x) % 2) ? e.x = Math.ceil(e.x) - e.x : e.x = e.x - Math.floor(e.x) } if (e.y < 0 || e.y > 1) switch (this.wrapT) { case re: e.y = e.y - Math.floor(e.y); break; case ae: e.y = e.y < 0 ? 0 : 1; break; case se: 1 === Math.abs(Math.floor(e.y) % 2) ? e.y = Math.ceil(e.y) - e.y : e.y = e.y - Math.floor(e.y) } return this.flipY && (e.y = 1 - e.y), e } set needsUpdate(e) { !0 === e && (this.version++, this.source.needsUpdate = !0) } set needsPMREMUpdate(e) { !0 === e && this.pmremVersion++ } } un.DEFAULT_IMAGE = null, un.DEFAULT_MAPPING = 300, un.DEFAULT_ANISOTROPY = 1; class pn { constructor(e = 0, t = 0, n = 0, i = 1) { pn.prototype.isVector4 = !0, this.x = e, this.y = t, this.z = n, this.w = i } get width() { return this.z } set width(e) { this.z = e } get height() { return this.w } set height(e) { this.w = e } set(e, t, n, i) { return this.x = e, this.y = t, this.z = n, this.w = i, this } setScalar(e) { return this.x = e, this.y = e, this.z = e, this.w = e, this } setX(e) { return this.x = e, this } setY(e) { return this.y = e, this } setZ(e) { return this.z = e, this } setW(e) { return this.w = e, this } setComponent(e, t) { switch (e) { case 0: this.x = t; break; case 1: this.y = t; break; case 2: this.z = t; break; case 3: this.w = t; break; default: throw new Error("index is out of range: " + e) } return this } getComponent(e) { switch (e) { case 0: return this.x; case 1: return this.y; case 2: return this.z; case 3: return this.w; default: throw new Error("index is out of range: " + e) } } clone() { return new this.constructor(this.x, this.y, this.z, this.w) } copy(e) { return this.x = e.x, this.y = e.y, this.z = e.z, this.w = void 0 !== e.w ? e.w : 1, this } add(e) { return this.x += e.x, this.y += e.y, this.z += e.z, this.w += e.w, this } addScalar(e) { return this.x += e, this.y += e, this.z += e, this.w += e, this } addVectors(e, t) { return this.x = e.x + t.x, this.y = e.y + t.y, this.z = e.z + t.z, this.w = e.w + t.w, this } addScaledVector(e, t) { return this.x += e.x * t, this.y += e.y * t, this.z += e.z * t, this.w += e.w * t, this } sub(e) { return this.x -= e.x, this.y -= e.y, this.z -= e.z, this.w -= e.w, this } subScalar(e) { return this.x -= e, this.y -= e, this.z -= e, this.w -= e, this } subVectors(e, t) { return this.x = e.x - t.x, this.y = e.y - t.y, this.z = e.z - t.z, this.w = e.w - t.w, this } multiply(e) { return this.x *= e.x, this.y *= e.y, this.z *= e.z, this.w *= e.w, this } multiplyScalar(e) { return this.x *= e, this.y *= e, this.z *= e, this.w *= e, this } applyMatrix4(e) { const t = this.x, n = this.y, i = this.z, r = this.w, a = e.elements; return this.x = a[0] * t + a[4] * n + a[8] * i + a[12] * r, this.y = a[1] * t + a[5] * n + a[9] * i + a[13] * r, this.z = a[2] * t + a[6] * n + a[10] * i + a[14] * r, this.w = a[3] * t + a[7] * n + a[11] * i + a[15] * r, this } divide(e) { return this.x /= e.x, this.y /= e.y, this.z /= e.z, this.w /= e.w, this } divideScalar(e) { return this.multiplyScalar(1 / e) } setAxisAngleFromQuaternion(e) { this.w = 2 * Math.acos(e.w); const t = Math.sqrt(1 - e.w * e.w); return t < 1e-4 ? (this.x = 1, this.y = 0, this.z = 0) : (this.x = e.x / t, this.y = e.y / t, this.z = e.z / t), this } setAxisAngleFromRotationMatrix(e) { let t, n, i, r; const a = .01, s = .1, o = e.elements, l = o[0], c = o[4], h = o[8], d = o[1], u = o[5], p = o[9], f = o[2], m = o[6], g = o[10]; if (Math.abs(c - d) < a && Math.abs(h - f) < a && Math.abs(p - m) < a) { if (Math.abs(c + d) < s && Math.abs(h + f) < s && Math.abs(p + m) < s && Math.abs(l + u + g - 3) < s) return this.set(1, 0, 0, 0), this; t = Math.PI; const e = (l + 1) / 2, o = (u + 1) / 2, v = (g + 1) / 2, w = (c + d) / 4, y = (h + f) / 4, A = (p + m) / 4; return e > o && e > v ? e < a ? (n = 0, i = .707106781, r = .707106781) : (n = Math.sqrt(e), i = w / n, r = y / n) : o > v ? o < a ? (n = .707106781, i = 0, r = .707106781) : (i = Math.sqrt(o), n = w / i, r = A / i) : v < a ? (n = .707106781, i = .707106781, r = 0) : (r = Math.sqrt(v), n = y / r, i = A / r), this.set(n, i, r, t), this } let v = Math.sqrt((m - p) * (m - p) + (h - f) * (h - f) + (d - c) * (d - c)); return Math.abs(v) < .001 && (v = 1), this.x = (m - p) / v, this.y = (h - f) / v, this.z = (d - c) / v, this.w = Math.acos((l + u + g - 1) / 2), this } setFromMatrixPosition(e) { const t = e.elements; return this.x = t[12], this.y = t[13], this.z = t[14], this.w = t[15], this } min(e) { return this.x = Math.min(this.x, e.x), this.y = Math.min(this.y, e.y), this.z = Math.min(this.z, e.z), this.w = Math.min(this.w, e.w), this } max(e) { return this.x = Math.max(this.x, e.x), this.y = Math.max(this.y, e.y), this.z = Math.max(this.z, e.z), this.w = Math.max(this.w, e.w), this } clamp(e, t) { return this.x = Ot(this.x, e.x, t.x), this.y = Ot(this.y, e.y, t.y), this.z = Ot(this.z, e.z, t.z), this.w = Ot(this.w, e.w, t.w), this } clampScalar(e, t) { return this.x = Ot(this.x, e, t), this.y = Ot(this.y, e, t), this.z = Ot(this.z, e, t), this.w = Ot(this.w, e, t), this } clampLength(e, t) { const n = this.length(); return this.divideScalar(n || 1).multiplyScalar(Ot(n, e, t)) } floor() { return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this.z = Math.floor(this.z), this.w = Math.floor(this.w), this } ceil() { return this.x = Math.ceil(this.x), this.y = Math.ceil(this.y), this.z = Math.ceil(this.z), this.w = Math.ceil(this.w), this } round() { return this.x = Math.round(this.x), this.y = Math.round(this.y), this.z = Math.round(this.z), this.w = Math.round(this.w), this } roundToZero() { return this.x = Math.trunc(this.x), this.y = Math.trunc(this.y), this.z = Math.trunc(this.z), this.w = Math.trunc(this.w), this } negate() { return this.x = -this.x, this.y = -this.y, this.z = -this.z, this.w = -this.w, this } dot(e) { return this.x * e.x + this.y * e.y + this.z * e.z + this.w * e.w } lengthSq() { return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w } length() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w) } manhattanLength() { return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w) } normalize() { return this.divideScalar(this.length() || 1) } setLength(e) { return this.normalize().multiplyScalar(e) } lerp(e, t) { return this.x += (e.x - this.x) * t, this.y += (e.y - this.y) * t, this.z += (e.z - this.z) * t, this.w += (e.w - this.w) * t, this } lerpVectors(e, t, n) { return this.x = e.x + (t.x - e.x) * n, this.y = e.y + (t.y - e.y) * n, this.z = e.z + (t.z - e.z) * n, this.w = e.w + (t.w - e.w) * n, this } equals(e) { return e.x === this.x && e.y === this.y && e.z === this.z && e.w === this.w } fromArray(e, t = 0) { return this.x = e[t], this.y = e[t + 1], this.z = e[t + 2], this.w = e[t + 3], this } toArray(e = [], t = 0) { return e[t] = this.x, e[t + 1] = this.y, e[t + 2] = this.z, e[t + 3] = this.w, e } fromBufferAttribute(e, t) { return this.x = e.getX(t), this.y = e.getY(t), this.z = e.getZ(t), this.w = e.getW(t), this } random() { return this.x = Math.random(), this.y = Math.random(), this.z = Math.random(), this.w = Math.random(), this }*[Symbol.iterator]() { yield this.x, yield this.y, yield this.z, yield this.w } } class fn extends Lt { constructor(e = 1, t = 1, n = {}) { super(), this.isRenderTarget = !0, this.width = e, this.height = t, this.depth = 1, this.scissor = new pn(0, 0, e, t), this.scissorTest = !1, this.viewport = new pn(0, 0, e, t); const i = { width: e, height: t, depth: 1 }; n = Object.assign({ generateMipmaps: !1, internalFormat: null, minFilter: he, depthBuffer: !0, stencilBuffer: !1, resolveDepthBuffer: !0, resolveStencilBuffer: !0, depthTexture: null, samples: 0, count: 1 }, n); const r = new un(i, n.mapping, n.wrapS, n.wrapT, n.magFilter, n.minFilter, n.format, n.type, n.anisotropy, n.colorSpace); r.flipY = !1, r.generateMipmaps = n.generateMipmaps, r.internalFormat = n.internalFormat, this.textures = []; const a = n.count; for (let e = 0; e < a; e++) this.textures[e] = r.clone(), this.textures[e].isRenderTargetTexture = !0, this.textures[e].renderTarget = this; this.depthBuffer = n.depthBuffer, this.stencilBuffer = n.stencilBuffer, this.resolveDepthBuffer = n.resolveDepthBuffer, this.resolveStencilBuffer = n.resolveStencilBuffer, this._depthTexture = null, this.depthTexture = n.depthTexture, this.samples = n.samples } get texture() { return this.textures[0] } set texture(e) { this.textures[0] = e } set depthTexture(e) { null !== this._depthTexture && (this._depthTexture.renderTarget = null), null !== e && (e.renderTarget = this), this._depthTexture = e } get depthTexture() { return this._depthTexture } setSize(e, t, n = 1) { if (this.width !== e || this.height !== t || this.depth !== n) { this.width = e, this.height = t, this.depth = n; for (let i = 0, r = this.textures.length; i < r; i++) this.textures[i].image.width = e, this.textures[i].image.height = t, this.textures[i].image.depth = n; this.dispose() } this.viewport.set(0, 0, e, t), this.scissor.set(0, 0, e, t) } clone() { return (new this.constructor).copy(this) } copy(e) { this.width = e.width, this.height = e.height, this.depth = e.depth, this.scissor.copy(e.scissor), this.scissorTest = e.scissorTest, this.viewport.copy(e.viewport), this.textures.length = 0; for (let t = 0, n = e.textures.length; t < n; t++) { this.textures[t] = e.textures[t].clone(), this.textures[t].isRenderTargetTexture = !0, this.textures[t].renderTarget = this; const n = Object.assign({}, e.textures[t].image); this.textures[t].source = new cn(n) } return this.depthBuffer = e.depthBuffer, this.stencilBuffer = e.stencilBuffer, this.resolveDepthBuffer = e.resolveDepthBuffer, this.resolveStencilBuffer = e.resolveStencilBuffer, null !== e.depthTexture && (this.depthTexture = e.depthTexture.clone()), this.samples = e.samples, this } dispose() { this.dispatchEvent({ type: "dispose" }) } } class mn extends fn { constructor(e = 1, t = 1, n = {}) { super(e, t, n), this.isWebGLRenderTarget = !0 } } class gn extends un { constructor(e = null, t = 1, n = 1, i = 1) { super(null), this.isDataArrayTexture = !0, this.image = { data: e, width: t, height: n, depth: i }, this.magFilter = oe, this.minFilter = oe, this.wrapR = ae, this.generateMipmaps = !1, this.flipY = !1, this.unpackAlignment = 1, this.layerUpdates = new Set } addLayerUpdate(e) { this.layerUpdates.add(e) } clearLayerUpdates() { this.layerUpdates.clear() } } class vn extends un { constructor(e = null, t = 1, n = 1, i = 1) { super(null), this.isData3DTexture = !0, this.image = { data: e, width: t, height: n, depth: i }, this.magFilter = oe, this.minFilter = oe, this.wrapR = ae, this.generateMipmaps = !1, this.flipY = !1, this.unpackAlignment = 1 } } class wn { constructor(e = 0, t = 0, n = 0, i = 1) { this.isQuaternion = !0, this._x = e, this._y = t, this._z = n, this._w = i } static slerpFlat(e, t, n, i, r, a, s) { let o = n[i + 0], l = n[i + 1], c = n[i + 2], h = n[i + 3]; const d = r[a + 0], u = r[a + 1], p = r[a + 2], f = r[a + 3]; if (0 === s) return e[t + 0] = o, e[t + 1] = l, e[t + 2] = c, void(e[t + 3] = h); if (1 === s) return e[t + 0] = d, e[t + 1] = u, e[t + 2] = p, void(e[t + 3] = f); if (h !== f || o !== d || l !== u || c !== p) { let e = 1 - s; const t = o * d + l * u + c * p + h * f, n = t >= 0 ? 1 : -1, i = 1 - t * t; if (i > Number.EPSILON) { const r = Math.sqrt(i), a = Math.atan2(r, t * n); e = Math.sin(e * a) / r, s = Math.sin(s * a) / r } const r = s * n; if (o = o * e + d * r, l = l * e + u * r, c = c * e + p * r, h = h * e + f * r, e === 1 - s) { const e = 1 / Math.sqrt(o * o + l * l + c * c + h * h); o *= e, l *= e, c *= e, h *= e } } e[t] = o, e[t + 1] = l, e[t + 2] = c, e[t + 3] = h } static multiplyQuaternionsFlat(e, t, n, i, r, a) { const s = n[i], o = n[i + 1], l = n[i + 2], c = n[i + 3], h = r[a], d = r[a + 1], u = r[a + 2], p = r[a + 3]; return e[t] = s * p + c * h + o * u - l * d, e[t + 1] = o * p + c * d + l * h - s * u, e[t + 2] = l * p + c * u + s * d - o * h, e[t + 3] = c * p - s * h - o * d - l * u, e } get x() { return this._x } set x(e) { this._x = e, this._onChangeCallback() } get y() { return this._y } set y(e) { this._y = e, this._onChangeCallback() } get z() { return this._z } set z(e) { this._z = e, this._onChangeCallback() } get w() { return this._w } set w(e) { this._w = e, this._onChangeCallback() } set(e, t, n, i) { return this._x = e, this._y = t, this._z = n, this._w = i, this._onChangeCallback(), this } clone() { return new this.constructor(this._x, this._y, this._z, this._w) } copy(e) { return this._x = e.x, this._y = e.y, this._z = e.z, this._w = e.w, this._onChangeCallback(), this } setFromEuler(e, t = !0) { const n = e._x, i = e._y, r = e._z, a = e._order, s = Math.cos, o = Math.sin, l = s(n / 2), c = s(i / 2), h = s(r / 2), d = o(n / 2), u = o(i / 2), p = o(r / 2); switch (a) { case "XYZ": this._x = d * c * h + l * u * p, this._y = l * u * h - d * c * p, this._z = l * c * p + d * u * h, this._w = l * c * h - d * u * p; break; case "YXZ": this._x = d * c * h + l * u * p, this._y = l * u * h - d * c * p, this._z = l * c * p - d * u * h, this._w = l * c * h + d * u * p; break; case "ZXY": this._x = d * c * h - l * u * p, this._y = l * u * h + d * c * p, this._z = l * c * p + d * u * h, this._w = l * c * h - d * u * p; break; case "ZYX": this._x = d * c * h - l * u * p, this._y = l * u * h + d * c * p, this._z = l * c * p - d * u * h, this._w = l * c * h + d * u * p; break; case "YZX": this._x = d * c * h + l * u * p, this._y = l * u * h + d * c * p, this._z = l * c * p - d * u * h, this._w = l * c * h - d * u * p; break; case "XZY": this._x = d * c * h - l * u * p, this._y = l * u * h - d * c * p, this._z = l * c * p + d * u * h, this._w = l * c * h + d * u * p; break; default: console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: " + a) } return !0 === t && this._onChangeCallback(), this } setFromAxisAngle(e, t) { const n = t / 2, i = Math.sin(n); return this._x = e.x * i, this._y = e.y * i, this._z = e.z * i, this._w = Math.cos(n), this._onChangeCallback(), this } setFromRotationMatrix(e) { const t = e.elements, n = t[0], i = t[4], r = t[8], a = t[1], s = t[5], o = t[9], l = t[2], c = t[6], h = t[10], d = n + s + h; if (d > 0) { const e = .5 / Math.sqrt(d + 1); this._w = .25 / e, this._x = (c - o) * e, this._y = (r - l) * e, this._z = (a - i) * e } else if (n > s && n > h) { const e = 2 * Math.sqrt(1 + n - s - h); this._w = (c - o) / e, this._x = .25 * e, this._y = (i + a) / e, this._z = (r + l) / e } else if (s > h) { const e = 2 * Math.sqrt(1 + s - n - h); this._w = (r - l) / e, this._x = (i + a) / e, this._y = .25 * e, this._z = (o + c) / e } else { const e = 2 * Math.sqrt(1 + h - n - s); this._w = (a - i) / e, this._x = (r + l) / e, this._y = (o + c) / e, this._z = .25 * e } return this._onChangeCallback(), this } setFromUnitVectors(e, t) { let n = e.dot(t) + 1; return n < Number.EPSILON ? (n = 0, Math.abs(e.x) > Math.abs(e.z) ? (this._x = -e.y, this._y = e.x, this._z = 0, this._w = n) : (this._x = 0, this._y = -e.z, this._z = e.y, this._w = n)) : (this._x = e.y * t.z - e.z * t.y, this._y = e.z * t.x - e.x * t.z, this._z = e.x * t.y - e.y * t.x, this._w = n), this.normalize() } angleTo(e) { return 2 * Math.acos(Math.abs(Ot(this.dot(e), -1, 1))) } rotateTowards(e, t) { const n = this.angleTo(e); if (0 === n) return this; const i = Math.min(1, t / n); return this.slerp(e, i), this } identity() { return this.set(0, 0, 0, 1) } invert() { return this.conjugate() } conjugate() { return this._x *= -1, this._y *= -1, this._z *= -1, this._onChangeCallback(), this } dot(e) { return this._x * e._x + this._y * e._y + this._z * e._z + this._w * e._w } lengthSq() { return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w } length() { return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w) } normalize() { let e = this.length(); return 0 === e ? (this._x = 0, this._y = 0, this._z = 0, this._w = 1) : (e = 1 / e, this._x = this._x * e, this._y = this._y * e, this._z = this._z * e, this._w = this._w * e), this._onChangeCallback(), this } multiply(e) { return this.multiplyQuaternions(this, e) } premultiply(e) { return this.multiplyQuaternions(e, this) } multiplyQuaternions(e, t) { const n = e._x, i = e._y, r = e._z, a = e._w, s = t._x, o = t._y, l = t._z, c = t._w; return this._x = n * c + a * s + i * l - r * o, this._y = i * c + a * o + r * s - n * l, this._z = r * c + a * l + n * o - i * s, this._w = a * c - n * s - i * o - r * l, this._onChangeCallback(), this } slerp(e, t) { if (0 === t) return this; if (1 === t) return this.copy(e); const n = this._x, i = this._y, r = this._z, a = this._w; let s = a * e._w + n * e._x + i * e._y + r * e._z; if (s < 0 ? (this._w = -e._w, this._x = -e._x, this._y = -e._y, this._z = -e._z, s = -s) : this.copy(e), s >= 1) return this._w = a, this._x = n, this._y = i, this._z = r, this; const o = 1 - s * s; if (o <= Number.EPSILON) { const e = 1 - t; return this._w = e * a + t * this._w, this._x = e * n + t * this._x, this._y = e * i + t * this._y, this._z = e * r + t * this._z, this.normalize(), this } const l = Math.sqrt(o), c = Math.atan2(l, s), h = Math.sin((1 - t) * c) / l, d = Math.sin(t * c) / l; return this._w = a * h + this._w * d, this._x = n * h + this._x * d, this._y = i * h + this._y * d, this._z = r * h + this._z * d, this._onChangeCallback(), this } slerpQuaternions(e, t, n) { return this.copy(e).slerp(t, n) } random() { const e = 2 * Math.PI * Math.random(), t = 2 * Math.PI * Math.random(), n = Math.random(), i = Math.sqrt(1 - n), r = Math.sqrt(n); return this.set(i * Math.sin(e), i * Math.cos(e), r * Math.sin(t), r * Math.cos(t)) } equals(e) { return e._x === this._x && e._y === this._y && e._z === this._z && e._w === this._w } fromArray(e, t = 0) { return this._x = e[t], this._y = e[t + 1], this._z = e[t + 2], this._w = e[t + 3], this._onChangeCallback(), this } toArray(e = [], t = 0) { return e[t] = this._x, e[t + 1] = this._y, e[t + 2] = this._z, e[t + 3] = this._w, e } fromBufferAttribute(e, t) { return this._x = e.getX(t), this._y = e.getY(t), this._z = e.getZ(t), this._w = e.getW(t), this._onChangeCallback(), this } toJSON() { return this.toArray() } _onChange(e) { return this._onChangeCallback = e, this } _onChangeCallback() {}*[Symbol.iterator]() { yield this._x, yield this._y, yield this._z, yield this._w } } class yn { constructor(e = 0, t = 0, n = 0) { yn.prototype.isVector3 = !0, this.x = e, this.y = t, this.z = n } set(e, t, n) { return void 0 === n && (n = this.z), this.x = e, this.y = t, this.z = n, this } setScalar(e) { return this.x = e, this.y = e, this.z = e, this } setX(e) { return this.x = e, this } setY(e) { return this.y = e, this } setZ(e) { return this.z = e, this } setComponent(e, t) { switch (e) { case 0: this.x = t; break; case 1: this.y = t; break; case 2: this.z = t; break; default: throw new Error("index is out of range: " + e) } return this } getComponent(e) { switch (e) { case 0: return this.x; case 1: return this.y; case 2: return this.z; default: throw new Error("index is out of range: " + e) } } clone() { return new this.constructor(this.x, this.y, this.z) } copy(e) { return this.x = e.x, this.y = e.y, this.z = e.z, this } add(e) { return this.x += e.x, this.y += e.y, this.z += e.z, this } addScalar(e) { return this.x += e, this.y += e, this.z += e, this } addVectors(e, t) { return this.x = e.x + t.x, this.y = e.y + t.y, this.z = e.z + t.z, this } addScaledVector(e, t) { return this.x += e.x * t, this.y += e.y * t, this.z += e.z * t, this } sub(e) { return this.x -= e.x, this.y -= e.y, this.z -= e.z, this } subScalar(e) { return this.x -= e, this.y -= e, this.z -= e, this } subVectors(e, t) { return this.x = e.x - t.x, this.y = e.y - t.y, this.z = e.z - t.z, this } multiply(e) { return this.x *= e.x, this.y *= e.y, this.z *= e.z, this } multiplyScalar(e) { return this.x *= e, this.y *= e, this.z *= e, this } multiplyVectors(e, t) { return this.x = e.x * t.x, this.y = e.y * t.y, this.z = e.z * t.z, this } applyEuler(e) { return this.applyQuaternion(bn.setFromEuler(e)) } applyAxisAngle(e, t) { return this.applyQuaternion(bn.setFromAxisAngle(e, t)) } applyMatrix3(e) { const t = this.x, n = this.y, i = this.z, r = e.elements; return this.x = r[0] * t + r[3] * n + r[6] * i, this.y = r[1] * t + r[4] * n + r[7] * i, this.z = r[2] * t + r[5] * n + r[8] * i, this } applyNormalMatrix(e) { return this.applyMatrix3(e).normalize() } applyMatrix4(e) { const t = this.x, n = this.y, i = this.z, r = e.elements, a = 1 / (r[3] * t + r[7] * n + r[11] * i + r[15]); return this.x = (r[0] * t + r[4] * n + r[8] * i + r[12]) * a, this.y = (r[1] * t + r[5] * n + r[9] * i + r[13]) * a, this.z = (r[2] * t + r[6] * n + r[10] * i + r[14]) * a, this } applyQuaternion(e) { const t = this.x, n = this.y, i = this.z, r = e.x, a = e.y, s = e.z, o = e.w, l = 2 * (a * i - s * n), c = 2 * (s * t - r * i), h = 2 * (r * n - a * t); return this.x = t + o * l + a * h - s * c, this.y = n + o * c + s * l - r * h, this.z = i + o * h + r * c - a * l, this } project(e) { return this.applyMatrix4(e.matrixWorldInverse).applyMatrix4(e.projectionMatrix) } unproject(e) { return this.applyMatrix4(e.projectionMatrixInverse).applyMatrix4(e.matrixWorld) } transformDirection(e) { const t = this.x, n = this.y, i = this.z, r = e.elements; return this.x = r[0] * t + r[4] * n + r[8] * i, this.y = r[1] * t + r[5] * n + r[9] * i, this.z = r[2] * t + r[6] * n + r[10] * i, this.normalize() } divide(e) { return this.x /= e.x, this.y /= e.y, this.z /= e.z, this } divideScalar(e) { return this.multiplyScalar(1 / e) } min(e) { return this.x = Math.min(this.x, e.x), this.y = Math.min(this.y, e.y), this.z = Math.min(this.z, e.z), this } max(e) { return this.x = Math.max(this.x, e.x), this.y = Math.max(this.y, e.y), this.z = Math.max(this.z, e.z), this } clamp(e, t) { return this.x = Ot(this.x, e.x, t.x), this.y = Ot(this.y, e.y, t.y), this.z = Ot(this.z, e.z, t.z), this } clampScalar(e, t) { return this.x = Ot(this.x, e, t), this.y = Ot(this.y, e, t), this.z = Ot(this.z, e, t), this } clampLength(e, t) { const n = this.length(); return this.divideScalar(n || 1).multiplyScalar(Ot(n, e, t)) } floor() { return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this.z = Math.floor(this.z), this } ceil() { return this.x = Math.ceil(this.x), this.y = Math.ceil(this.y), this.z = Math.ceil(this.z), this } round() { return this.x = Math.round(this.x), this.y = Math.round(this.y), this.z = Math.round(this.z), this } roundToZero() { return this.x = Math.trunc(this.x), this.y = Math.trunc(this.y), this.z = Math.trunc(this.z), this } negate() { return this.x = -this.x, this.y = -this.y, this.z = -this.z, this } dot(e) { return this.x * e.x + this.y * e.y + this.z * e.z } lengthSq() { return this.x * this.x + this.y * this.y + this.z * this.z } length() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z) } manhattanLength() { return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) } normalize() { return this.divideScalar(this.length() || 1) } setLength(e) { return this.normalize().multiplyScalar(e) } lerp(e, t) { return this.x += (e.x - this.x) * t, this.y += (e.y - this.y) * t, this.z += (e.z - this.z) * t, this } lerpVectors(e, t, n) { return this.x = e.x + (t.x - e.x) * n, this.y = e.y + (t.y - e.y) * n, this.z = e.z + (t.z - e.z) * n, this } cross(e) { return this.crossVectors(this, e) } crossVectors(e, t) { const n = e.x, i = e.y, r = e.z, a = t.x, s = t.y, o = t.z; return this.x = i * o - r * s, this.y = r * a - n * o, this.z = n * s - i * a, this } projectOnVector(e) { const t = e.lengthSq(); if (0 === t) return this.set(0, 0, 0); const n = e.dot(this) / t; return this.copy(e).multiplyScalar(n) } projectOnPlane(e) { return An.copy(this).projectOnVector(e), this.sub(An) } reflect(e) { return this.sub(An.copy(e).multiplyScalar(2 * this.dot(e))) } angleTo(e) { const t = Math.sqrt(this.lengthSq() * e.lengthSq()); if (0 === t) return Math.PI / 2; const n = this.dot(e) / t; return Math.acos(Ot(n, -1, 1)) } distanceTo(e) { return Math.sqrt(this.distanceToSquared(e)) } distanceToSquared(e) { const t = this.x - e.x, n = this.y - e.y, i = this.z - e.z; return t * t + n * n + i * i } manhattanDistanceTo(e) { return Math.abs(this.x - e.x) + Math.abs(this.y - e.y) + Math.abs(this.z - e.z) } setFromSpherical(e) { return this.setFromSphericalCoords(e.radius, e.phi, e.theta) } setFromSphericalCoords(e, t, n) { const i = Math.sin(t) * e; return this.x = i * Math.sin(n), this.y = Math.cos(t) * e, this.z = i * Math.cos(n), this } setFromCylindrical(e) { return this.setFromCylindricalCoords(e.radius, e.theta, e.y) } setFromCylindricalCoords(e, t, n) { return this.x = e * Math.sin(t), this.y = n, this.z = e * Math.cos(t), this } setFromMatrixPosition(e) { const t = e.elements; return this.x = t[12], this.y = t[13], this.z = t[14], this } setFromMatrixScale(e) { const t = this.setFromMatrixColumn(e, 0).length(), n = this.setFromMatrixColumn(e, 1).length(), i = this.setFromMatrixColumn(e, 2).length(); return this.x = t, this.y = n, this.z = i, this } setFromMatrixColumn(e, t) { return this.fromArray(e.elements, 4 * t) } setFromMatrix3Column(e, t) { return this.fromArray(e.elements, 3 * t) } setFromEuler(e) { return this.x = e._x, this.y = e._y, this.z = e._z, this } setFromColor(e) { return this.x = e.r, this.y = e.g, this.z = e.b, this } equals(e) { return e.x === this.x && e.y === this.y && e.z === this.z } fromArray(e, t = 0) { return this.x = e[t], this.y = e[t + 1], this.z = e[t + 2], this } toArray(e = [], t = 0) { return e[t] = this.x, e[t + 1] = this.y, e[t + 2] = this.z, e } fromBufferAttribute(e, t) { return this.x = e.getX(t), this.y = e.getY(t), this.z = e.getZ(t), this } random() { return this.x = Math.random(), this.y = Math.random(), this.z = Math.random(), this } randomDirection() { const e = Math.random() * Math.PI * 2, t = 2 * Math.random() - 1, n = Math.sqrt(1 - t * t); return this.x = n * Math.cos(e), this.y = t, this.z = n * Math.sin(e), this }*[Symbol.iterator]() { yield this.x, yield this.y, yield this.z } } const An = new yn, bn = new wn; class xn { constructor(e = new yn(1 / 0, 1 / 0, 1 / 0), t = new yn(-1 / 0, -1 / 0, -1 / 0)) { this.isBox3 = !0, this.min = e, this.max = t } set(e, t) { return this.min.copy(e), this.max.copy(t), this } setFromArray(e) { this.makeEmpty(); for (let t = 0, n = e.length; t < n; t += 3) this.expandByPoint(En.fromArray(e, t)); return this } setFromBufferAttribute(e) { this.makeEmpty(); for (let t = 0, n = e.count; t < n; t++) this.expandByPoint(En.fromBufferAttribute(e, t)); return this } setFromPoints(e) { this.makeEmpty(); for (let t = 0, n = e.length; t < n; t++) this.expandByPoint(e[t]); return this } setFromCenterAndSize(e, t) { const n = En.copy(t).multiplyScalar(.5); return this.min.copy(e).sub(n), this.max.copy(e).add(n), this } setFromObject(e, t = !1) { return this.makeEmpty(), this.expandByObject(e, t) } clone() { return (new this.constructor).copy(this) } copy(e) { return this.min.copy(e.min), this.max.copy(e.max), this } makeEmpty() { return this.min.x = this.min.y = this.min.z = 1 / 0, this.max.x = this.max.y = this.max.z = -1 / 0, this } isEmpty() { return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z } getCenter(e) { return this.isEmpty() ? e.set(0, 0, 0) : e.addVectors(this.min, this.max).multiplyScalar(.5) } getSize(e) { return this.isEmpty() ? e.set(0, 0, 0) : e.subVectors(this.max, this.min) } expandByPoint(e) { return this.min.min(e), this.max.max(e), this } expandByVector(e) { return this.min.sub(e), this.max.add(e), this } expandByScalar(e) { return this.min.addScalar(-e), this.max.addScalar(e), this } expandByObject(e, t = !1) { e.updateWorldMatrix(!1, !1); const n = e.geometry; if (void 0 !== n) { const i = n.getAttribute("position"); if (!0 === t && void 0 !== i && !0 !== e.isInstancedMesh) for (let t = 0, n = i.count; t < n; t++) !0 === e.isMesh ? e.getVertexPosition(t, En) : En.fromBufferAttribute(i, t), En.applyMatrix4(e.matrixWorld), this.expandByPoint(En); else void 0 !== e.boundingBox ? (null === e.boundingBox && e.computeBoundingBox(), Sn.copy(e.boundingBox)) : (null === n.boundingBox && n.computeBoundingBox(), Sn.copy(n.boundingBox)), Sn.applyMatrix4(e.matrixWorld), this.union(Sn) } const i = e.children; for (let e = 0, n = i.length; e < n; e++) this.expandByObject(i[e], t); return this } containsPoint(e) { return e.x >= this.min.x && e.x <= this.max.x && e.y >= this.min.y && e.y <= this.max.y && e.z >= this.min.z && e.z <= this.max.z } containsBox(e) { return this.min.x <= e.min.x && e.max.x <= this.max.x && this.min.y <= e.min.y && e.max.y <= this.max.y && this.min.z <= e.min.z && e.max.z <= this.max.z } getParameter(e, t) { return t.set((e.x - this.min.x) / (this.max.x - this.min.x), (e.y - this.min.y) / (this.max.y - this.min.y), (e.z - this.min.z) / (this.max.z - this.min.z)) } intersectsBox(e) { return e.max.x >= this.min.x && e.min.x <= this.max.x && e.max.y >= this.min.y && e.min.y <= this.max.y && e.max.z >= this.min.z && e.min.z <= this.max.z } intersectsSphere(e) { return this.clampPoint(e.center, En), En.distanceToSquared(e.center) <= e.radius * e.radius } intersectsPlane(e) { let t, n; return e.normal.x > 0 ? (t = e.normal.x * this.min.x, n = e.normal.x * this.max.x) : (t = e.normal.x * this.max.x, n = e.normal.x * this.min.x), e.normal.y > 0 ? (t += e.normal.y * this.min.y, n += e.normal.y * this.max.y) : (t += e.normal.y * this.max.y, n += e.normal.y * this.min.y), e.normal.z > 0 ? (t += e.normal.z * this.min.z, n += e.normal.z * this.max.z) : (t += e.normal.z * this.max.z, n += e.normal.z * this.min.z), t <= -e.constant && n >= -e.constant } intersectsTriangle(e) { if (this.isEmpty()) return !1; this.getCenter(Rn), Ln.subVectors(this.max, Rn), Mn.subVectors(e.a, Rn), Tn.subVectors(e.b, Rn), _n.subVectors(e.c, Rn), Cn.subVectors(Tn, Mn), Pn.subVectors(_n, Tn), In.subVectors(Mn, _n); let t = [0, -Cn.z, Cn.y, 0, -Pn.z, Pn.y, 0, -In.z, In.y, Cn.z, 0, -Cn.x, Pn.z, 0, -Pn.x, In.z, 0, -In.x, -Cn.y, Cn.x, 0, -Pn.y, Pn.x, 0, -In.y, In.x, 0]; return !!Bn(t, Mn, Tn, _n, Ln) && (t = [1, 0, 0, 0, 1, 0, 0, 0, 1], !!Bn(t, Mn, Tn, _n, Ln) && (Dn.crossVectors(Cn, Pn), t = [Dn.x, Dn.y, Dn.z], Bn(t, Mn, Tn, _n, Ln))) } clampPoint(e, t) { return t.copy(e).clamp(this.min, this.max) } distanceToPoint(e) { return this.clampPoint(e, En).distanceTo(e) } getBoundingSphere(e) { return this.isEmpty() ? e.makeEmpty() : (this.getCenter(e.center), e.radius = .5 * this.getSize(En).length()), e } intersect(e) { return this.min.max(e.min), this.max.min(e.max), this.isEmpty() && this.makeEmpty(), this } union(e) { return this.min.min(e.min), this.max.max(e.max), this } applyMatrix4(e) { return this.isEmpty() || (kn[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(e), kn[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(e), kn[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(e), kn[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(e), kn[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(e), kn[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(e), kn[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(e), kn[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(e), this.setFromPoints(kn)), this } translate(e) { return this.min.add(e), this.max.add(e), this } equals(e) { return e.min.equals(this.min) && e.max.equals(this.max) } } const kn = [new yn, new yn, new yn, new yn, new yn, new yn, new yn, new yn], En = new yn, Sn = new xn, Mn = new yn, Tn = new yn, _n = new yn, Cn = new yn, Pn = new yn, In = new yn, Rn = new yn, Ln = new yn, Dn = new yn, Nn = new yn; function Bn(e, t, n, i, r) { for (let a = 0, s = e.length - 3; a <= s; a += 3) { Nn.fromArray(e, a); const s = r.x * Math.abs(Nn.x) + r.y * Math.abs(Nn.y) + r.z * Math.abs(Nn.z), o = t.dot(Nn), l = n.dot(Nn), c = i.dot(Nn); if (Math.max(-Math.max(o, l, c), Math.min(o, l, c)) > s) return !1 } return !0 } const Un = new xn, zn = new yn, On = new yn; class Fn { constructor(e = new yn, t = -1) { this.isSphere = !0, this.center = e, this.radius = t } set(e, t) { return this.center.copy(e), this.radius = t, this } setFromPoints(e, t) { const n = this.center; void 0 !== t ? n.copy(t) : Un.setFromPoints(e).getCenter(n); let i = 0; for (let t = 0, r = e.length; t < r; t++) i = Math.max(i, n.distanceToSquared(e[t])); return this.radius = Math.sqrt(i), this } copy(e) { return this.center.copy(e.center), this.radius = e.radius, this } isEmpty() { return this.radius < 0 } makeEmpty() { return this.center.set(0, 0, 0), this.radius = -1, this } containsPoint(e) { return e.distanceToSquared(this.center) <= this.radius * this.radius } distanceToPoint(e) { return e.distanceTo(this.center) - this.radius } intersectsSphere(e) { const t = this.radius + e.radius; return e.center.distanceToSquared(this.center) <= t * t } intersectsBox(e) { return e.intersectsSphere(this) } intersectsPlane(e) { return Math.abs(e.distanceToPoint(this.center)) <= this.radius } clampPoint(e, t) { const n = this.center.distanceToSquared(e); return t.copy(e), n > this.radius * this.radius && (t.sub(this.center).normalize(), t.multiplyScalar(this.radius).add(this.center)), t } getBoundingBox(e) { return this.isEmpty() ? (e.makeEmpty(), e) : (e.set(this.center, this.center), e.expandByScalar(this.radius), e) } applyMatrix4(e) { return this.center.applyMatrix4(e), this.radius = this.radius * e.getMaxScaleOnAxis(), this } translate(e) { return this.center.add(e), this } expandByPoint(e) { if (this.isEmpty()) return this.center.copy(e), this.radius = 0, this; zn.subVectors(e, this.center); const t = zn.lengthSq(); if (t > this.radius * this.radius) { const e = Math.sqrt(t), n = .5 * (e - this.radius); this.center.addScaledVector(zn, n / e), this.radius += n } return this } union(e) { return e.isEmpty() ? this : this.isEmpty() ? (this.copy(e), this) : (!0 === this.center.equals(e.center) ? this.radius = Math.max(this.radius, e.radius) : (On.subVectors(e.center, this.center).setLength(e.radius), this.expandByPoint(zn.copy(e.center).add(On)), this.expandByPoint(zn.copy(e.center).sub(On))), this) } equals(e) { return e.center.equals(this.center) && e.radius === this.radius } clone() { return (new this.constructor).copy(this) } } const Wn = new yn, Vn = new yn, Hn = new yn, Gn = new yn, jn = new yn, Qn = new yn, Yn = new yn; class Kn { constructor(e = new yn, t = new yn(0, 0, -1)) { this.origin = e, this.direction = t } set(e, t) { return this.origin.copy(e), this.direction.copy(t), this } copy(e) { return this.origin.copy(e.origin), this.direction.copy(e.direction), this } at(e, t) { return t.copy(this.origin).addScaledVector(this.direction, e) } lookAt(e) { return this.direction.copy(e).sub(this.origin).normalize(), this } recast(e) { return this.origin.copy(this.at(e, Wn)), this } closestPointToPoint(e, t) { t.subVectors(e, this.origin); const n = t.dot(this.direction); return n < 0 ? t.copy(this.origin) : t.copy(this.origin).addScaledVector(this.direction, n) } distanceToPoint(e) { return Math.sqrt(this.distanceSqToPoint(e)) } distanceSqToPoint(e) { const t = Wn.subVectors(e, this.origin).dot(this.direction); return t < 0 ? this.origin.distanceToSquared(e) : (Wn.copy(this.origin).addScaledVector(this.direction, t), Wn.distanceToSquared(e)) } distanceSqToSegment(e, t, n, i) { Vn.copy(e).add(t).multiplyScalar(.5), Hn.copy(t).sub(e).normalize(), Gn.copy(this.origin).sub(Vn); const r = .5 * e.distanceTo(t), a = -this.direction.dot(Hn), s = Gn.dot(this.direction), o = -Gn.dot(Hn), l = Gn.lengthSq(), c = Math.abs(1 - a * a); let h, d, u, p; if (c > 0) if (h = a * o - s, d = a * s - o, p = r * c, h >= 0) if (d >= -p) if (d <= p) { const e = 1 / c; h *= e, d *= e, u = h * (h + a * d + 2 * s) + d * (a * h + d + 2 * o) + l } else d = r, h = Math.max(0, -(a * d + s)), u = -h * h + d * (d + 2 * o) + l; else d = -r, h = Math.max(0, -(a * d + s)), u = -h * h + d * (d + 2 * o) + l; else d <= -p ? (h = Math.max(0, -(-a * r + s)), d = h > 0 ? -r : Math.min(Math.max(-r, -o), r), u = -h * h + d * (d + 2 * o) + l) : d <= p ? (h = 0, d = Math.min(Math.max(-r, -o), r), u = d * (d + 2 * o) + l) : (h = Math.max(0, -(a * r + s)), d = h > 0 ? r : Math.min(Math.max(-r, -o), r), u = -h * h + d * (d + 2 * o) + l); else d = a > 0 ? -r : r, h = Math.max(0, -(a * d + s)), u = -h * h + d * (d + 2 * o) + l; return n && n.copy(this.origin).addScaledVector(this.direction, h), i && i.copy(Vn).addScaledVector(Hn, d), u } intersectSphere(e, t) { Wn.subVectors(e.center, this.origin); const n = Wn.dot(this.direction), i = Wn.dot(Wn) - n * n, r = e.radius * e.radius; if (i > r) return null; const a = Math.sqrt(r - i), s = n - a, o = n + a; return o < 0 ? null : s < 0 ? this.at(o, t) : this.at(s, t) } intersectsSphere(e) { return this.distanceSqToPoint(e.center) <= e.radius * e.radius } distanceToPlane(e) { const t = e.normal.dot(this.direction); if (0 === t) return 0 === e.distanceToPoint(this.origin) ? 0 : null; const n = -(this.origin.dot(e.normal) + e.constant) / t; return n >= 0 ? n : null } intersectPlane(e, t) { const n = this.distanceToPlane(e); return null === n ? null : this.at(n, t) } intersectsPlane(e) { const t = e.distanceToPoint(this.origin); if (0 === t) return !0; return e.normal.dot(this.direction) * t < 0 } intersectBox(e, t) { let n, i, r, a, s, o; const l = 1 / this.direction.x, c = 1 / this.direction.y, h = 1 / this.direction.z, d = this.origin; return l >= 0 ? (n = (e.min.x - d.x) * l, i = (e.max.x - d.x) * l) : (n = (e.max.x - d.x) * l, i = (e.min.x - d.x) * l), c >= 0 ? (r = (e.min.y - d.y) * c, a = (e.max.y - d.y) * c) : (r = (e.max.y - d.y) * c, a = (e.min.y - d.y) * c), n > a || r > i ? null : ((r > n || isNaN(n)) && (n = r), (a < i || isNaN(i)) && (i = a), h >= 0 ? (s = (e.min.z - d.z) * h, o = (e.max.z - d.z) * h) : (s = (e.max.z - d.z) * h, o = (e.min.z - d.z) * h), n > o || s > i ? null : ((s > n || n != n) && (n = s), (o < i || i != i) && (i = o), i < 0 ? null : this.at(n >= 0 ? n : i, t))) } intersectsBox(e) { return null !== this.intersectBox(e, Wn) } intersectTriangle(e, t, n, i, r) { jn.subVectors(t, e), Qn.subVectors(n, e), Yn.crossVectors(jn, Qn); let a, s = this.direction.dot(Yn); if (s > 0) { if (i) return null; a = 1 } else { if (!(s < 0)) return null; a = -1, s = -s } Gn.subVectors(this.origin, e); const o = a * this.direction.dot(Qn.crossVectors(Gn, Qn)); if (o < 0) return null; const l = a * this.direction.dot(jn.cross(Gn)); if (l < 0) return null; if (o + l > s) return null; const c = -a * Gn.dot(Yn); return c < 0 ? null : this.at(c / s, r) } applyMatrix4(e) { return this.origin.applyMatrix4(e), this.direction.transformDirection(e), this } equals(e) { return e.origin.equals(this.origin) && e.direction.equals(this.direction) } clone() { return (new this.constructor).copy(this) } } class qn { constructor(e, t, n, i, r, a, s, o, l, c, h, d, u, p, f, m) { qn.prototype.isMatrix4 = !0, this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], void 0 !== e && this.set(e, t, n, i, r, a, s, o, l, c, h, d, u, p, f, m) } set(e, t, n, i, r, a, s, o, l, c, h, d, u, p, f, m) { const g = this.elements; return g[0] = e, g[4] = t, g[8] = n, g[12] = i, g[1] = r, g[5] = a, g[9] = s, g[13] = o, g[2] = l, g[6] = c, g[10] = h, g[14] = d, g[3] = u, g[7] = p, g[11] = f, g[15] = m, this } identity() { return this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), this } clone() { return (new qn).fromArray(this.elements) } copy(e) { const t = this.elements, n = e.elements; return t[0] = n[0], t[1] = n[1], t[2] = n[2], t[3] = n[3], t[4] = n[4], t[5] = n[5], t[6] = n[6], t[7] = n[7], t[8] = n[8], t[9] = n[9], t[10] = n[10], t[11] = n[11], t[12] = n[12], t[13] = n[13], t[14] = n[14], t[15] = n[15], this } copyPosition(e) { const t = this.elements, n = e.elements; return t[12] = n[12], t[13] = n[13], t[14] = n[14], this } setFromMatrix3(e) { const t = e.elements; return this.set(t[0], t[3], t[6], 0, t[1], t[4], t[7], 0, t[2], t[5], t[8], 0, 0, 0, 0, 1), this } extractBasis(e, t, n) { return e.setFromMatrixColumn(this, 0), t.setFromMatrixColumn(this, 1), n.setFromMatrixColumn(this, 2), this } makeBasis(e, t, n) { return this.set(e.x, t.x, n.x, 0, e.y, t.y, n.y, 0, e.z, t.z, n.z, 0, 0, 0, 0, 1), this } extractRotation(e) { const t = this.elements, n = e.elements, i = 1 / Xn.setFromMatrixColumn(e, 0).length(), r = 1 / Xn.setFromMatrixColumn(e, 1).length(), a = 1 / Xn.setFromMatrixColumn(e, 2).length(); return t[0] = n[0] * i, t[1] = n[1] * i, t[2] = n[2] * i, t[3] = 0, t[4] = n[4] * r, t[5] = n[5] * r, t[6] = n[6] * r, t[7] = 0, t[8] = n[8] * a, t[9] = n[9] * a, t[10] = n[10] * a, t[11] = 0, t[12] = 0, t[13] = 0, t[14] = 0, t[15] = 1, this } makeRotationFromEuler(e) { const t = this.elements, n = e.x, i = e.y, r = e.z, a = Math.cos(n), s = Math.sin(n), o = Math.cos(i), l = Math.sin(i), c = Math.cos(r), h = Math.sin(r); if ("XYZ" === e.order) { const e = a * c, n = a * h, i = s * c, r = s * h; t[0] = o * c, t[4] = -o * h, t[8] = l, t[1] = n + i * l, t[5] = e - r * l, t[9] = -s * o, t[2] = r - e * l, t[6] = i + n * l, t[10] = a * o } else if ("YXZ" === e.order) { const e = o * c, n = o * h, i = l * c, r = l * h; t[0] = e + r * s, t[4] = i * s - n, t[8] = a * l, t[1] = a * h, t[5] = a * c, t[9] = -s, t[2] = n * s - i, t[6] = r + e * s, t[10] = a * o } else if ("ZXY" === e.order) { const e = o * c, n = o * h, i = l * c, r = l * h; t[0] = e - r * s, t[4] = -a * h, t[8] = i + n * s, t[1] = n + i * s, t[5] = a * c, t[9] = r - e * s, t[2] = -a * l, t[6] = s, t[10] = a * o } else if ("ZYX" === e.order) { const e = a * c, n = a * h, i = s * c, r = s * h; t[0] = o * c, t[4] = i * l - n, t[8] = e * l + r, t[1] = o * h, t[5] = r * l + e, t[9] = n * l - i, t[2] = -l, t[6] = s * o, t[10] = a * o } else if ("YZX" === e.order) { const e = a * o, n = a * l, i = s * o, r = s * l; t[0] = o * c, t[4] = r - e * h, t[8] = i * h + n, t[1] = h, t[5] = a * c, t[9] = -s * c, t[2] = -l * c, t[6] = n * h + i, t[10] = e - r * h } else if ("XZY" === e.order) { const e = a * o, n = a * l, i = s * o, r = s * l; t[0] = o * c, t[4] = -h, t[8] = l * c, t[1] = e * h + r, t[5] = a * c, t[9] = n * h - i, t[2] = i * h - n, t[6] = s * c, t[10] = r * h + e } return t[3] = 0, t[7] = 0, t[11] = 0, t[12] = 0, t[13] = 0, t[14] = 0, t[15] = 1, this } makeRotationFromQuaternion(e) { return this.compose(Jn, e, $n) } lookAt(e, t, n) { const i = this.elements; return ni.subVectors(e, t), 0 === ni.lengthSq() && (ni.z = 1), ni.normalize(), ei.crossVectors(n, ni), 0 === ei.lengthSq() && (1 === Math.abs(n.z) ? ni.x += 1e-4 : ni.z += 1e-4, ni.normalize(), ei.crossVectors(n, ni)), ei.normalize(), ti.crossVectors(ni, ei), i[0] = ei.x, i[4] = ti.x, i[8] = ni.x, i[1] = ei.y, i[5] = ti.y, i[9] = ni.y, i[2] = ei.z, i[6] = ti.z, i[10] = ni.z, this } multiply(e) { return this.multiplyMatrices(this, e) } premultiply(e) { return this.multiplyMatrices(e, this) } multiplyMatrices(e, t) { const n = e.elements, i = t.elements, r = this.elements, a = n[0], s = n[4], o = n[8], l = n[12], c = n[1], h = n[5], d = n[9], u = n[13], p = n[2], f = n[6], m = n[10], g = n[14], v = n[3], w = n[7], y = n[11], A = n[15], b = i[0], x = i[4], k = i[8], E = i[12], S = i[1], M = i[5], T = i[9], _ = i[13], C = i[2], P = i[6], I = i[10], R = i[14], L = i[3], D = i[7], N = i[11], B = i[15]; return r[0] = a * b + s * S + o * C + l * L, r[4] = a * x + s * M + o * P + l * D, r[8] = a * k + s * T + o * I + l * N, r[12] = a * E + s * _ + o * R + l * B, r[1] = c * b + h * S + d * C + u * L, r[5] = c * x + h * M + d * P + u * D, r[9] = c * k + h * T + d * I + u * N, r[13] = c * E + h * _ + d * R + u * B, r[2] = p * b + f * S + m * C + g * L, r[6] = p * x + f * M + m * P + g * D, r[10] = p * k + f * T + m * I + g * N, r[14] = p * E + f * _ + m * R + g * B, r[3] = v * b + w * S + y * C + A * L, r[7] = v * x + w * M + y * P + A * D, r[11] = v * k + w * T + y * I + A * N, r[15] = v * E + w * _ + y * R + A * B, this } multiplyScalar(e) { const t = this.elements; return t[0] *= e, t[4] *= e, t[8] *= e, t[12] *= e, t[1] *= e, t[5] *= e, t[9] *= e, t[13] *= e, t[2] *= e, t[6] *= e, t[10] *= e, t[14] *= e, t[3] *= e, t[7] *= e, t[11] *= e, t[15] *= e, this } determinant() { const e = this.elements, t = e[0], n = e[4], i = e[8], r = e[12], a = e[1], s = e[5], o = e[9], l = e[13], c = e[2], h = e[6], d = e[10], u = e[14]; return e[3] * (+r * o * h - i * l * h - r * s * d + n * l * d + i * s * u - n * o * u) + e[7] * (+t * o * u - t * l * d + r * a * d - i * a * u + i * l * c - r * o * c) + e[11] * (+t * l * h - t * s * u - r * a * h + n * a * u + r * s * c - n * l * c) + e[15] * (-i * s * c - t * o * h + t * s * d + i * a * h - n * a * d + n * o * c) } transpose() { const e = this.elements; let t; return t = e[1], e[1] = e[4], e[4] = t, t = e[2], e[2] = e[8], e[8] = t, t = e[6], e[6] = e[9], e[9] = t, t = e[3], e[3] = e[12], e[12] = t, t = e[7], e[7] = e[13], e[13] = t, t = e[11], e[11] = e[14], e[14] = t, this } setPosition(e, t, n) { const i = this.elements; return e.isVector3 ? (i[12] = e.x, i[13] = e.y, i[14] = e.z) : (i[12] = e, i[13] = t, i[14] = n), this } invert() { const e = this.elements, t = e[0], n = e[1], i = e[2], r = e[3], a = e[4], s = e[5], o = e[6], l = e[7], c = e[8], h = e[9], d = e[10], u = e[11], p = e[12], f = e[13], m = e[14], g = e[15], v = h * m * l - f * d * l + f * o * u - s * m * u - h * o * g + s * d * g, w = p * d * l - c * m * l - p * o * u + a * m * u + c * o * g - a * d * g, y = c * f * l - p * h * l + p * s * u - a * f * u - c * s * g + a * h * g, A = p * h * o - c * f * o - p * s * d + a * f * d + c * s * m - a * h * m, b = t * v + n * w + i * y + r * A; if (0 === b) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); const x = 1 / b; return e[0] = v * x, e[1] = (f * d * r - h * m * r - f * i * u + n * m * u + h * i * g - n * d * g) * x, e[2] = (s * m * r - f * o * r + f * i * l - n * m * l - s * i * g + n * o * g) * x, e[3] = (h * o * r - s * d * r - h * i * l + n * d * l + s * i * u - n * o * u) * x, e[4] = w * x, e[5] = (c * m * r - p * d * r + p * i * u - t * m * u - c * i * g + t * d * g) * x, e[6] = (p * o * r - a * m * r - p * i * l + t * m * l + a * i * g - t * o * g) * x, e[7] = (a * d * r - c * o * r + c * i * l - t * d * l - a * i * u + t * o * u) * x, e[8] = y * x, e[9] = (p * h * r - c * f * r - p * n * u + t * f * u + c * n * g - t * h * g) * x, e[10] = (a * f * r - p * s * r + p * n * l - t * f * l - a * n * g + t * s * g) * x, e[11] = (c * s * r - a * h * r - c * n * l + t * h * l + a * n * u - t * s * u) * x, e[12] = A * x, e[13] = (c * f * i - p * h * i + p * n * d - t * f * d - c * n * m + t * h * m) * x, e[14] = (p * s * i - a * f * i - p * n * o + t * f * o + a * n * m - t * s * m) * x, e[15] = (a * h * i - c * s * i + c * n * o - t * h * o - a * n * d + t * s * d) * x, this } scale(e) { const t = this.elements, n = e.x, i = e.y, r = e.z; return t[0] *= n, t[4] *= i, t[8] *= r, t[1] *= n, t[5] *= i, t[9] *= r, t[2] *= n, t[6] *= i, t[10] *= r, t[3] *= n, t[7] *= i, t[11] *= r, this } getMaxScaleOnAxis() { const e = this.elements, t = e[0] * e[0] + e[1] * e[1] + e[2] * e[2], n = e[4] * e[4] + e[5] * e[5] + e[6] * e[6], i = e[8] * e[8] + e[9] * e[9] + e[10] * e[10]; return Math.sqrt(Math.max(t, n, i)) } makeTranslation(e, t, n) { return e.isVector3 ? this.set(1, 0, 0, e.x, 0, 1, 0, e.y, 0, 0, 1, e.z, 0, 0, 0, 1) : this.set(1, 0, 0, e, 0, 1, 0, t, 0, 0, 1, n, 0, 0, 0, 1), this } makeRotationX(e) { const t = Math.cos(e), n = Math.sin(e); return this.set(1, 0, 0, 0, 0, t, -n, 0, 0, n, t, 0, 0, 0, 0, 1), this } makeRotationY(e) { const t = Math.cos(e), n = Math.sin(e); return this.set(t, 0, n, 0, 0, 1, 0, 0, -n, 0, t, 0, 0, 0, 0, 1), this } makeRotationZ(e) { const t = Math.cos(e), n = Math.sin(e); return this.set(t, -n, 0, 0, n, t, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), this } makeRotationAxis(e, t) { const n = Math.cos(t), i = Math.sin(t), r = 1 - n, a = e.x, s = e.y, o = e.z, l = r * a, c = r * s; return this.set(l * a + n, l * s - i * o, l * o + i * s, 0, l * s + i * o, c * s + n, c * o - i * a, 0, l * o - i * s, c * o + i * a, r * o * o + n, 0, 0, 0, 0, 1), this } makeScale(e, t, n) { return this.set(e, 0, 0, 0, 0, t, 0, 0, 0, 0, n, 0, 0, 0, 0, 1), this } makeShear(e, t, n, i, r, a) { return this.set(1, n, r, 0, e, 1, a, 0, t, i, 1, 0, 0, 0, 0, 1), this } compose(e, t, n) { const i = this.elements, r = t._x, a = t._y, s = t._z, o = t._w, l = r + r, c = a + a, h = s + s, d = r * l, u = r * c, p = r * h, f = a * c, m = a * h, g = s * h, v = o * l, w = o * c, y = o * h, A = n.x, b = n.y, x = n.z; return i[0] = (1 - (f + g)) * A, i[1] = (u + y) * A, i[2] = (p - w) * A, i[3] = 0, i[4] = (u - y) * b, i[5] = (1 - (d + g)) * b, i[6] = (m + v) * b, i[7] = 0, i[8] = (p + w) * x, i[9] = (m - v) * x, i[10] = (1 - (d + f)) * x, i[11] = 0, i[12] = e.x, i[13] = e.y, i[14] = e.z, i[15] = 1, this } decompose(e, t, n) { const i = this.elements; let r = Xn.set(i[0], i[1], i[2]).length(); const a = Xn.set(i[4], i[5], i[6]).length(), s = Xn.set(i[8], i[9], i[10]).length(); this.determinant() < 0 && (r = -r), e.x = i[12], e.y = i[13], e.z = i[14], Zn.copy(this); const o = 1 / r, l = 1 / a, c = 1 / s; return Zn.elements[0] *= o, Zn.elements[1] *= o, Zn.elements[2] *= o, Zn.elements[4] *= l, Zn.elements[5] *= l, Zn.elements[6] *= l, Zn.elements[8] *= c, Zn.elements[9] *= c, Zn.elements[10] *= c, t.setFromRotationMatrix(Zn), n.x = r, n.y = a, n.z = s, this } makePerspective(e, t, n, i, r, a, s = 2e3) { const o = this.elements, l = 2 * r / (t - e), c = 2 * r / (n - i), h = (t + e) / (t - e), d = (n + i) / (n - i); let u, p; if (s === It) u = -(a + r) / (a - r), p = -2 * a * r / (a - r); else { if (s !== Rt) throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: " + s); u = -a / (a - r), p = -a * r / (a - r) } return o[0] = l, o[4] = 0, o[8] = h, o[12] = 0, o[1] = 0, o[5] = c, o[9] = d, o[13] = 0, o[2] = 0, o[6] = 0, o[10] = u, o[14] = p, o[3] = 0, o[7] = 0, o[11] = -1, o[15] = 0, this } makeOrthographic(e, t, n, i, r, a, s = 2e3) { const o = this.elements, l = 1 / (t - e), c = 1 / (n - i), h = 1 / (a - r), d = (t + e) * l, u = (n + i) * c; let p, f; if (s === It) p = (a + r) * h, f = -2 * h; else { if (s !== Rt) throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: " + s); p = r * h, f = -1 * h } return o[0] = 2 * l, o[4] = 0, o[8] = 0, o[12] = -d, o[1] = 0, o[5] = 2 * c, o[9] = 0, o[13] = -u, o[2] = 0, o[6] = 0, o[10] = f, o[14] = -p, o[3] = 0, o[7] = 0, o[11] = 0, o[15] = 1, this } equals(e) { const t = this.elements, n = e.elements; for (let e = 0; e < 16; e++) if (t[e] !== n[e]) return !1; return !0 } fromArray(e, t = 0) { for (let n = 0; n < 16; n++) this.elements[n] = e[n + t]; return this } toArray(e = [], t = 0) { const n = this.elements; return e[t] = n[0], e[t + 1] = n[1], e[t + 2] = n[2], e[t + 3] = n[3], e[t + 4] = n[4], e[t + 5] = n[5], e[t + 6] = n[6], e[t + 7] = n[7], e[t + 8] = n[8], e[t + 9] = n[9], e[t + 10] = n[10], e[t + 11] = n[11], e[t + 12] = n[12], e[t + 13] = n[13], e[t + 14] = n[14], e[t + 15] = n[15], e } } const Xn = new yn, Zn = new qn, Jn = new yn(0, 0, 0), $n = new yn(1, 1, 1), ei = new yn, ti = new yn, ni = new yn, ii = new qn, ri = new wn; class ai { constructor(e = 0, t = 0, n = 0, i = ai.DEFAULT_ORDER) { this.isEuler = !0, this._x = e, this._y = t, this._z = n, this._order = i } get x() { return this._x } set x(e) { this._x = e, this._onChangeCallback() } get y() { return this._y } set y(e) { this._y = e, this._onChangeCallback() } get z() { return this._z } set z(e) { this._z = e, this._onChangeCallback() } get order() { return this._order } set order(e) { this._order = e, this._onChangeCallback() } set(e, t, n, i = this._order) { return this._x = e, this._y = t, this._z = n, this._order = i, this._onChangeCallback(), this } clone() { return new this.constructor(this._x, this._y, this._z, this._order) } copy(e) { return this._x = e._x, this._y = e._y, this._z = e._z, this._order = e._order, this._onChangeCallback(), this } setFromRotationMatrix(e, t = this._order, n = !0) { const i = e.elements, r = i[0], a = i[4], s = i[8], o = i[1], l = i[5], c = i[9], h = i[2], d = i[6], u = i[10]; switch (t) { case "XYZ": this._y = Math.asin(Ot(s, -1, 1)), Math.abs(s) < .9999999 ? (this._x = Math.atan2(-c, u), this._z = Math.atan2(-a, r)) : (this._x = Math.atan2(d, l), this._z = 0); break; case "YXZ": this._x = Math.asin(-Ot(c, -1, 1)), Math.abs(c) < .9999999 ? (this._y = Math.atan2(s, u), this._z = Math.atan2(o, l)) : (this._y = Math.atan2(-h, r), this._z = 0); break; case "ZXY": this._x = Math.asin(Ot(d, -1, 1)), Math.abs(d) < .9999999 ? (this._y = Math.atan2(-h, u), this._z = Math.atan2(-a, l)) : (this._y = 0, this._z = Math.atan2(o, r)); break; case "ZYX": this._y = Math.asin(-Ot(h, -1, 1)), Math.abs(h) < .9999999 ? (this._x = Math.atan2(d, u), this._z = Math.atan2(o, r)) : (this._x = 0, this._z = Math.atan2(-a, l)); break; case "YZX": this._z = Math.asin(Ot(o, -1, 1)), Math.abs(o) < .9999999 ? (this._x = Math.atan2(-c, l), this._y = Math.atan2(-h, r)) : (this._x = 0, this._y = Math.atan2(s, u)); break; case "XZY": this._z = Math.asin(-Ot(a, -1, 1)), Math.abs(a) < .9999999 ? (this._x = Math.atan2(d, l), this._y = Math.atan2(s, r)) : (this._x = Math.atan2(-c, u), this._y = 0); break; default: console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: " + t) } return this._order = t, !0 === n && this._onChangeCallback(), this } setFromQuaternion(e, t, n) { return ii.makeRotationFromQuaternion(e), this.setFromRotationMatrix(ii, t, n) } setFromVector3(e, t = this._order) { return this.set(e.x, e.y, e.z, t) } reorder(e) { return ri.setFromEuler(this), this.setFromQuaternion(ri, e) } equals(e) { return e._x === this._x && e._y === this._y && e._z === this._z && e._order === this._order } fromArray(e) { return this._x = e[0], this._y = e[1], this._z = e[2], void 0 !== e[3] && (this._order = e[3]), this._onChangeCallback(), this } toArray(e = [], t = 0) { return e[t] = this._x, e[t + 1] = this._y, e[t + 2] = this._z, e[t + 3] = this._order, e } _onChange(e) { return this._onChangeCallback = e, this } _onChangeCallback() {}*[Symbol.iterator]() { yield this._x, yield this._y, yield this._z, yield this._order } } ai.DEFAULT_ORDER = "XYZ"; class si { constructor() { this.mask = 1 } set(e) { this.mask = 1 << e >>> 0 } enable(e) { this.mask |= 1 << e } enableAll() { this.mask = -1 } toggle(e) { this.mask ^= 1 << e } disable(e) { this.mask &= ~(1 << e) } disableAll() { this.mask = 0 } test(e) { return !!(this.mask & e.mask) } isEnabled(e) { return !!(this.mask & 1 << e) } } let oi = 0; const li = new yn, ci = new wn, hi = new qn, di = new yn, ui = new yn, pi = new yn, fi = new wn, mi = new yn(1, 0, 0), gi = new yn(0, 1, 0), vi = new yn(0, 0, 1), wi = { type: "added" }, yi = { type: "removed" }, Ai = { type: "childadded", child: null }, bi = { type: "childremoved", child: null }; class xi extends Lt { constructor() { super(), this.isObject3D = !0, Object.defineProperty(this, "id", { value: oi++ }), this.uuid = zt(), this.name = "", this.type = "Object3D", this.parent = null, this.children = [], this.up = xi.DEFAULT_UP.clone(); const e = new yn, t = new ai, n = new wn, i = new yn(1, 1, 1); t._onChange((function() { n.setFromEuler(t, !1) })), n._onChange((function() { t.setFromQuaternion(n, void 0, !1) })), Object.defineProperties(this, { position: { configurable: !0, enumerable: !0, value: e }, rotation: { configurable: !0, enumerable: !0, value: t }, quaternion: { configurable: !0, enumerable: !0, value: n }, scale: { configurable: !0, enumerable: !0, value: i }, modelViewMatrix: { value: new qn }, normalMatrix: { value: new Qt } }), this.matrix = new qn, this.matrixWorld = new qn, this.matrixAutoUpdate = xi.DEFAULT_MATRIX_AUTO_UPDATE, this.matrixWorldAutoUpdate = xi.DEFAULT_MATRIX_WORLD_AUTO_UPDATE, this.matrixWorldNeedsUpdate = !1, this.layers = new si, this.visible = !0, this.castShadow = !1, this.receiveShadow = !1, this.frustumCulled = !0, this.renderOrder = 0, this.animations = [], this.userData = {} } onBeforeShadow() {} onAfterShadow() {} onBeforeRender() {} onAfterRender() {} applyMatrix4(e) { this.matrixAutoUpdate && this.updateMatrix(), this.matrix.premultiply(e), this.matrix.decompose(this.position, this.quaternion, this.scale) } applyQuaternion(e) { return this.quaternion.premultiply(e), this } setRotationFromAxisAngle(e, t) { this.quaternion.setFromAxisAngle(e, t) } setRotationFromEuler(e) { this.quaternion.setFromEuler(e, !0) } setRotationFromMatrix(e) { this.quaternion.setFromRotationMatrix(e) } setRotationFromQuaternion(e) { this.quaternion.copy(e) } rotateOnAxis(e, t) { return ci.setFromAxisAngle(e, t), this.quaternion.multiply(ci), this } rotateOnWorldAxis(e, t) { return ci.setFromAxisAngle(e, t), this.quaternion.premultiply(ci), this } rotateX(e) { return this.rotateOnAxis(mi, e) } rotateY(e) { return this.rotateOnAxis(gi, e) } rotateZ(e) { return this.rotateOnAxis(vi, e) } translateOnAxis(e, t) { return li.copy(e).applyQuaternion(this.quaternion), this.position.add(li.multiplyScalar(t)), this } translateX(e) { return this.translateOnAxis(mi, e) } translateY(e) { return this.translateOnAxis(gi, e) } translateZ(e) { return this.translateOnAxis(vi, e) } localToWorld(e) { return this.updateWorldMatrix(!0, !1), e.applyMatrix4(this.matrixWorld) } worldToLocal(e) { return this.updateWorldMatrix(!0, !1), e.applyMatrix4(hi.copy(this.matrixWorld).invert()) } lookAt(e, t, n) { e.isVector3 ? di.copy(e) : di.set(e, t, n); const i = this.parent; this.updateWorldMatrix(!0, !1), ui.setFromMatrixPosition(this.matrixWorld), this.isCamera || this.isLight ? hi.lookAt(ui, di, this.up) : hi.lookAt(di, ui, this.up), this.quaternion.setFromRotationMatrix(hi), i && (hi.extractRotation(i.matrixWorld), ci.setFromRotationMatrix(hi), this.quaternion.premultiply(ci.invert())) } add(e) { if (arguments.length > 1) { for (let e = 0; e < arguments.length; e++) this.add(arguments[e]); return this } return e === this ? (console.error("THREE.Object3D.add: object can't be added as a child of itself.", e), this) : (e && e.isObject3D ? (e.removeFromParent(), e.parent = this, this.children.push(e), e.dispatchEvent(wi), Ai.child = e, this.dispatchEvent(Ai), Ai.child = null) : console.error("THREE.Object3D.add: object not an instance of THREE.Object3D.", e), this) } remove(e) { if (arguments.length > 1) { for (let e = 0; e < arguments.length; e++) this.remove(arguments[e]); return this } const t = this.children.indexOf(e); return -1 !== t && (e.parent = null, this.children.splice(t, 1), e.dispatchEvent(yi), bi.child = e, this.dispatchEvent(bi), bi.child = null), this } removeFromParent() { const e = this.parent; return null !== e && e.remove(this), this } clear() { return this.remove(...this.children) } attach(e) { return this.updateWorldMatrix(!0, !1), hi.copy(this.matrixWorld).invert(), null !== e.parent && (e.parent.updateWorldMatrix(!0, !1), hi.multiply(e.parent.matrixWorld)), e.applyMatrix4(hi), e.removeFromParent(), e.parent = this, this.children.push(e), e.updateWorldMatrix(!1, !0), e.dispatchEvent(wi), Ai.child = e, this.dispatchEvent(Ai), Ai.child = null, this } getObjectById(e) { return this.getObjectByProperty("id", e) } getObjectByName(e) { return this.getObjectByProperty("name", e) } getObjectByProperty(e, t) { if (this[e] === t) return this; for (let n = 0, i = this.children.length; n < i; n++) { const i = this.children[n].getObjectByProperty(e, t); if (void 0 !== i) return i } } getObjectsByProperty(e, t, n = []) { this[e] === t && n.push(this); const i = this.children; for (let r = 0, a = i.length; r < a; r++) i[r].getObjectsByProperty(e, t, n); return n } getWorldPosition(e) { return this.updateWorldMatrix(!0, !1), e.setFromMatrixPosition(this.matrixWorld) } getWorldQuaternion(e) { return this.updateWorldMatrix(!0, !1), this.matrixWorld.decompose(ui, e, pi), e } getWorldScale(e) { return this.updateWorldMatrix(!0, !1), this.matrixWorld.decompose(ui, fi, e), e } getWorldDirection(e) { this.updateWorldMatrix(!0, !1); const t = this.matrixWorld.elements; return e.set(t[8], t[9], t[10]).normalize() } raycast() {} traverse(e) { e(this); const t = this.children; for (let n = 0, i = t.length; n < i; n++) t[n].traverse(e) } traverseVisible(e) { if (!1 === this.visible) return; e(this); const t = this.children; for (let n = 0, i = t.length; n < i; n++) t[n].traverseVisible(e) } traverseAncestors(e) { const t = this.parent; null !== t && (e(t), t.traverseAncestors(e)) } updateMatrix() { this.matrix.compose(this.position, this.quaternion, this.scale), this.matrixWorldNeedsUpdate = !0 } updateMatrixWorld(e) { this.matrixAutoUpdate && this.updateMatrix(), (this.matrixWorldNeedsUpdate || e) && (!0 === this.matrixWorldAutoUpdate && (null === this.parent ? this.matrixWorld.copy(this.matrix) : this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix)), this.matrixWorldNeedsUpdate = !1, e = !0); const t = this.children; for (let n = 0, i = t.length; n < i; n++) { t[n].updateMatrixWorld(e) } } updateWorldMatrix(e, t) { const n = this.parent; if (!0 === e && null !== n && n.updateWorldMatrix(!0, !1), this.matrixAutoUpdate && this.updateMatrix(), !0 === this.matrixWorldAutoUpdate && (null === this.parent ? this.matrixWorld.copy(this.matrix) : this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix)), !0 === t) { const e = this.children; for (let t = 0, n = e.length; t < n; t++) { e[t].updateWorldMatrix(!1, !0) } } } toJSON(e) { const t = void 0 === e || "string" == typeof e, n = {}; t && (e = { geometries: {}, materials: {}, textures: {}, images: {}, shapes: {}, skeletons: {}, animations: {}, nodes: {} }, n.metadata = { version: 4.6, type: "Object", generator: "Object3D.toJSON" }); const i = {}; function r(t, n) { return void 0 === t[n.uuid] && (t[n.uuid] = n.toJSON(e)), n.uuid } if (i.uuid = this.uuid, i.type = this.type, "" !== this.name && (i.name = this.name), !0 === this.castShadow && (i.castShadow = !0), !0 === this.receiveShadow && (i.receiveShadow = !0), !1 === this.visible && (i.visible = !1), !1 === this.frustumCulled && (i.frustumCulled = !1), 0 !== this.renderOrder && (i.renderOrder = this.renderOrder), Object.keys(this.userData).length > 0 && (i.userData = this.userData), i.layers = this.layers.mask, i.matrix = this.matrix.toArray(), i.up = this.up.toArray(), !1 === this.matrixAutoUpdate && (i.matrixAutoUpdate = !1), this.isInstancedMesh && (i.type = "InstancedMesh", i.count = this.count, i.instanceMatrix = this.instanceMatrix.toJSON(), null !== this.instanceColor && (i.instanceColor = this.instanceColor.toJSON())), this.isBatchedMesh && (i.type = "BatchedMesh", i.perObjectFrustumCulled = this.perObjectFrustumCulled, i.sortObjects = this.sortObjects, i.drawRanges = this._drawRanges, i.reservedRanges = this._reservedRanges, i.visibility = this._visibility, i.active = this._active, i.bounds = this._bounds.map((e => ({ boxInitialized: e.boxInitialized, boxMin: e.box.min.toArray(), boxMax: e.box.max.toArray(), sphereInitialized: e.sphereInitialized, sphereRadius: e.sphere.radius, sphereCenter: e.sphere.center.toArray() }))), i.maxInstanceCount = this._maxInstanceCount, i.maxVertexCount = this._maxVertexCount, i.maxIndexCount = this._maxIndexCount, i.geometryInitialized = this._geometryInitialized, i.geometryCount = this._geometryCount, i.matricesTexture = this._matricesTexture.toJSON(e), null !== this._colorsTexture && (i.colorsTexture = this._colorsTexture.toJSON(e)), null !== this.boundingSphere && (i.boundingSphere = { center: i.boundingSphere.center.toArray(), radius: i.boundingSphere.radius }), null !== this.boundingBox && (i.boundingBox = { min: i.boundingBox.min.toArray(), max: i.boundingBox.max.toArray() })), this.isScene) this.background && (this.background.isColor ? i.background = this.background.toJSON() : this.background.isTexture && (i.background = this.background.toJSON(e).uuid)), this.environment && this.environment.isTexture && !0 !== this.environment.isRenderTargetTexture && (i.environment = this.environment.toJSON(e).uuid); else if (this.isMesh || this.isLine || this.isPoints) { i.geometry = r(e.geometries, this.geometry); const t = this.geometry.parameters; if (void 0 !== t && void 0 !== t.shapes) { const n = t.shapes; if (Array.isArray(n)) for (let t = 0, i = n.length; t < i; t++) { const i = n[t]; r(e.shapes, i) } else r(e.shapes, n) } } if (this.isSkinnedMesh && (i.bindMode = this.bindMode, i.bindMatrix = this.bindMatrix.toArray(), void 0 !== this.skeleton && (r(e.skeletons, this.skeleton), i.skeleton = this.skeleton.uuid)), void 0 !== this.material) if (Array.isArray(this.material)) { const t = []; for (let n = 0, i = this.material.length; n < i; n++) t.push(r(e.materials, this.material[n])); i.material = t } else i.material = r(e.materials, this.material); if (this.children.length > 0) { i.children = []; for (let t = 0; t < this.children.length; t++) i.children.push(this.children[t].toJSON(e).object) } if (this.animations.length > 0) { i.animations = []; for (let t = 0; t < this.animations.length; t++) { const n = this.animations[t]; i.animations.push(r(e.animations, n)) } } if (t) { const t = a(e.geometries), i = a(e.materials), r = a(e.textures), s = a(e.images), o = a(e.shapes), l = a(e.skeletons), c = a(e.animations), h = a(e.nodes); t.length > 0 && (n.geometries = t), i.length > 0 && (n.materials = i), r.length > 0 && (n.textures = r), s.length > 0 && (n.images = s), o.length > 0 && (n.shapes = o), l.length > 0 && (n.skeletons = l), c.length > 0 && (n.animations = c), h.length > 0 && (n.nodes = h) } return n.object = i, n; function a(e) { const t = []; for (const n in e) { const i = e[n]; delete i.metadata, t.push(i) } return t } } clone(e) { return (new this.constructor).copy(this, e) } copy(e, t = !0) { if (this.name = e.name, this.up.copy(e.up), this.position.copy(e.position), this.rotation.order = e.rotation.order, this.quaternion.copy(e.quaternion), this.scale.copy(e.scale), this.matrix.copy(e.matrix), this.matrixWorld.copy(e.matrixWorld), this.matrixAutoUpdate = e.matrixAutoUpdate, this.matrixWorldAutoUpdate = e.matrixWorldAutoUpdate, this.matrixWorldNeedsUpdate = e.matrixWorldNeedsUpdate, this.layers.mask = e.layers.mask, this.visible = e.visible, this.castShadow = e.castShadow, this.receiveShadow = e.receiveShadow, this.frustumCulled = e.frustumCulled, this.renderOrder = e.renderOrder, this.animations = e.animations.slice(), this.userData = JSON.parse(JSON.stringify(e.userData)), !0 === t) for (let t = 0; t < e.children.length; t++) { const n = e.children[t]; this.add(n.clone()) } return this } } xi.DEFAULT_UP = new yn(0, 1, 0), xi.DEFAULT_MATRIX_AUTO_UPDATE = !0, xi.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = !0; const ki = new yn, Ei = new yn, Si = new yn, Mi = new yn, Ti = new yn, _i = new yn, Ci = new yn, Pi = new yn, Ii = new yn, Ri = new yn, Li = new pn, Di = new pn, Ni = new pn; class Bi { constructor(e = new yn, t = new yn, n = new yn) { this.a = e, this.b = t, this.c = n } static getNormal(e, t, n, i) { i.subVectors(n, t), ki.subVectors(e, t), i.cross(ki); const r = i.lengthSq(); return r > 0 ? i.multiplyScalar(1 / Math.sqrt(r)) : i.set(0, 0, 0) } static getBarycoord(e, t, n, i, r) { ki.subVectors(i, t), Ei.subVectors(n, t), Si.subVectors(e, t); const a = ki.dot(ki), s = ki.dot(Ei), o = ki.dot(Si), l = Ei.dot(Ei), c = Ei.dot(Si), h = a * l - s * s; if (0 === h) return r.set(0, 0, 0), null; const d = 1 / h, u = (l * o - s * c) * d, p = (a * c - s * o) * d; return r.set(1 - u - p, p, u) } static containsPoint(e, t, n, i) { return null !== this.getBarycoord(e, t, n, i, Mi) && (Mi.x >= 0 && Mi.y >= 0 && Mi.x + Mi.y <= 1) } static getInterpolation(e, t, n, i, r, a, s, o) { return null === this.getBarycoord(e, t, n, i, Mi) ? (o.x = 0, o.y = 0, "z" in o && (o.z = 0), "w" in o && (o.w = 0), null) : (o.setScalar(0), o.addScaledVector(r, Mi.x), o.addScaledVector(a, Mi.y), o.addScaledVector(s, Mi.z), o) } static getInterpolatedAttribute(e, t, n, i, r, a) { return Li.setScalar(0), Di.setScalar(0), Ni.setScalar(0), Li.fromBufferAttribute(e, t), Di.fromBufferAttribute(e, n), Ni.fromBufferAttribute(e, i), a.setScalar(0), a.addScaledVector(Li, r.x), a.addScaledVector(Di, r.y), a.addScaledVector(Ni, r.z), a } static isFrontFacing(e, t, n, i) { return ki.subVectors(n, t), Ei.subVectors(e, t), ki.cross(Ei).dot(i) < 0 } set(e, t, n) { return this.a.copy(e), this.b.copy(t), this.c.copy(n), this } setFromPointsAndIndices(e, t, n, i) { return this.a.copy(e[t]), this.b.copy(e[n]), this.c.copy(e[i]), this } setFromAttributeAndIndices(e, t, n, i) { return this.a.fromBufferAttribute(e, t), this.b.fromBufferAttribute(e, n), this.c.fromBufferAttribute(e, i), this } clone() { return (new this.constructor).copy(this) } copy(e) { return this.a.copy(e.a), this.b.copy(e.b), this.c.copy(e.c), this } getArea() { return ki.subVectors(this.c, this.b), Ei.subVectors(this.a, this.b), .5 * ki.cross(Ei).length() } getMidpoint(e) { return e.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3) } getNormal(e) { return Bi.getNormal(this.a, this.b, this.c, e) } getPlane(e) { return e.setFromCoplanarPoints(this.a, this.b, this.c) } getBarycoord(e, t) { return Bi.getBarycoord(e, this.a, this.b, this.c, t) } getInterpolation(e, t, n, i, r) { return Bi.getInterpolation(e, this.a, this.b, this.c, t, n, i, r) } containsPoint(e) { return Bi.containsPoint(e, this.a, this.b, this.c) } isFrontFacing(e) { return Bi.isFrontFacing(this.a, this.b, this.c, e) } intersectsBox(e) { return e.intersectsTriangle(this) } closestPointToPoint(e, t) { const n = this.a, i = this.b, r = this.c; let a, s; Ti.subVectors(i, n), _i.subVectors(r, n), Pi.subVectors(e, n); const o = Ti.dot(Pi), l = _i.dot(Pi); if (o <= 0 && l <= 0) return t.copy(n); Ii.subVectors(e, i); const c = Ti.dot(Ii), h = _i.dot(Ii); if (c >= 0 && h <= c) return t.copy(i); const d = o * h - c * l; if (d <= 0 && o >= 0 && c <= 0) return a = o / (o - c), t.copy(n).addScaledVector(Ti, a); Ri.subVectors(e, r); const u = Ti.dot(Ri), p = _i.dot(Ri); if (p >= 0 && u <= p) return t.copy(r); const f = u * l - o * p; if (f <= 0 && l >= 0 && p <= 0) return s = l / (l - p), t.copy(n).addScaledVector(_i, s); const m = c * p - u * h; if (m <= 0 && h - c >= 0 && u - p >= 0) return Ci.subVectors(r, i), s = (h - c) / (h - c + (u - p)), t.copy(i).addScaledVector(Ci, s); const g = 1 / (m + f + d); return a = f * g, s = d * g, t.copy(n).addScaledVector(Ti, a).addScaledVector(_i, s) } equals(e) { return e.a.equals(this.a) && e.b.equals(this.b) && e.c.equals(this.c) } } const Ui = { aliceblue: 15792383, antiquewhite: 16444375, aqua: 65535, aquamarine: 8388564, azure: 15794175, beige: 16119260, bisque: 16770244, black: 0, blanchedalmond: 16772045, blue: 255, blueviolet: 9055202, brown: 10824234, burlywood: 14596231, cadetblue: 6266528, chartreuse: 8388352, chocolate: 13789470, coral: 16744272, cornflowerblue: 6591981, cornsilk: 16775388, crimson: 14423100, cyan: 65535, darkblue: 139, darkcyan: 35723, darkgoldenrod: 12092939, darkgray: 11119017, darkgreen: 25600, darkgrey: 11119017, darkkhaki: 12433259, darkmagenta: 9109643, darkolivegreen: 5597999, darkorange: 16747520, darkorchid: 10040012, darkred: 9109504, darksalmon: 15308410, darkseagreen: 9419919, darkslateblue: 4734347, darkslategray: 3100495, darkslategrey: 3100495, darkturquoise: 52945, darkviolet: 9699539, deeppink: 16716947, deepskyblue: 49151, dimgray: 6908265, dimgrey: 6908265, dodgerblue: 2003199, firebrick: 11674146, floralwhite: 16775920, forestgreen: 2263842, fuchsia: 16711935, gainsboro: 14474460, ghostwhite: 16316671, gold: 16766720, goldenrod: 14329120, gray: 8421504, green: 32768, greenyellow: 11403055, grey: 8421504, honeydew: 15794160, hotpink: 16738740, indianred: 13458524, indigo: 4915330, ivory: 16777200, khaki: 15787660, lavender: 15132410, lavenderblush: 16773365, lawngreen: 8190976, lemonchiffon: 16775885, lightblue: 11393254, lightcoral: 15761536, lightcyan: 14745599, lightgoldenrodyellow: 16448210, lightgray: 13882323, lightgreen: 9498256, lightgrey: 13882323, lightpink: 16758465, lightsalmon: 16752762, lightseagreen: 2142890, lightskyblue: 8900346, lightslategray: 7833753, lightslategrey: 7833753, lightsteelblue: 11584734, lightyellow: 16777184, lime: 65280, limegreen: 3329330, linen: 16445670, magenta: 16711935, maroon: 8388608, mediumaquamarine: 6737322, mediumblue: 205, mediumorchid: 12211667, mediumpurple: 9662683, mediumseagreen: 3978097, mediumslateblue: 8087790, mediumspringgreen: 64154, mediumturquoise: 4772300, mediumvioletred: 13047173, midnightblue: 1644912, mintcream: 16121850, mistyrose: 16770273, moccasin: 16770229, navajowhite: 16768685, navy: 128, oldlace: 16643558, olive: 8421376, olivedrab: 7048739, orange: 16753920, orangered: 16729344, orchid: 14315734, palegoldenrod: 15657130, palegreen: 10025880, paleturquoise: 11529966, palevioletred: 14381203, papayawhip: 16773077, peachpuff: 16767673, peru: 13468991, pink: 16761035, plum: 14524637, powderblue: 11591910, purple: 8388736, rebeccapurple: 6697881, red: 16711680, rosybrown: 12357519, royalblue: 4286945, saddlebrown: 9127187, salmon: 16416882, sandybrown: 16032864, seagreen: 3050327, seashell: 16774638, sienna: 10506797, silver: 12632256, skyblue: 8900331, slateblue: 6970061, slategray: 7372944, slategrey: 7372944, snow: 16775930, springgreen: 65407, steelblue: 4620980, tan: 13808780, teal: 32896, thistle: 14204888, tomato: 16737095, turquoise: 4251856, violet: 15631086, wheat: 16113331, white: 16777215, whitesmoke: 16119285, yellow: 16776960, yellowgreen: 10145074 }, zi = { h: 0, s: 0, l: 0 }, Oi = { h: 0, s: 0, l: 0 }; function Fi(e, t, n) { return n < 0 && (n += 1), n > 1 && (n -= 1), n < 1 / 6 ? e + 6 * (t - e) * n : n < .5 ? t : n < 2 / 3 ? e + 6 * (t - e) * (2 / 3 - n) : e } class Wi { constructor(e, t, n) { return this.isColor = !0, this.r = 1, this.g = 1, this.b = 1, this.set(e, t, n) } set(e, t, n) { if (void 0 === t && void 0 === n) { const t = e; t && t.isColor ? this.copy(t) : "number" == typeof t ? this.setHex(t) : "string" == typeof t && this.setStyle(t) } else this.setRGB(e, t, n); return this } setScalar(e) { return this.r = e, this.g = e, this.b = e, this } setHex(e, t = gt) { return e = Math.floor(e), this.r = (e >> 16 & 255) / 255, this.g = (e >> 8 & 255) / 255, this.b = (255 & e) / 255, nn.toWorkingColorSpace(this, t), this } setRGB(e, t, n, i = nn.workingColorSpace) { return this.r = e, this.g = t, this.b = n, nn.toWorkingColorSpace(this, i), this } setHSL(e, t, n, i = nn.workingColorSpace) { if (e = Ft(e, 1), t = Ot(t, 0, 1), n = Ot(n, 0, 1), 0 === t) this.r = this.g = this.b = n; else { const i = n <= .5 ? n * (1 + t) : n + t - n * t, r = 2 * n - i; this.r = Fi(r, i, e + 1 / 3), this.g = Fi(r, i, e), this.b = Fi(r, i, e - 1 / 3) } return nn.toWorkingColorSpace(this, i), this } setStyle(e, t = gt) { function n(t) { void 0 !== t && parseFloat(t) < 1 && console.warn("THREE.Color: Alpha component of " + e + " will be ignored.") } let i; if (i = /^(\w+)\(([^\)]*)\)/.exec(e)) { let r; const a = i[1], s = i[2]; switch (a) { case "rgb": case "rgba": if (r = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s)) return n(r[4]), this.setRGB(Math.min(255, parseInt(r[1], 10)) / 255, Math.min(255, parseInt(r[2], 10)) / 255, Math.min(255, parseInt(r[3], 10)) / 255, t); if (r = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s)) return n(r[4]), this.setRGB(Math.min(100, parseInt(r[1], 10)) / 100, Math.min(100, parseInt(r[2], 10)) / 100, Math.min(100, parseInt(r[3], 10)) / 100, t); break; case "hsl": case "hsla": if (r = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(s)) return n(r[4]), this.setHSL(parseFloat(r[1]) / 360, parseFloat(r[2]) / 100, parseFloat(r[3]) / 100, t); break; default: console.warn("THREE.Color: Unknown color model " + e) } } else if (i = /^\#([A-Fa-f\d]+)$/.exec(e)) { const n = i[1], r = n.length; if (3 === r) return this.setRGB(parseInt(n.charAt(0), 16) / 15, parseInt(n.charAt(1), 16) / 15, parseInt(n.charAt(2), 16) / 15, t); if (6 === r) return this.setHex(parseInt(n, 16), t); console.warn("THREE.Color: Invalid hex color " + e) } else if (e && e.length > 0) return this.setColorName(e, t); return this } setColorName(e, t = gt) { const n = Ui[e.toLowerCase()]; return void 0 !== n ? this.setHex(n, t) : console.warn("THREE.Color: Unknown color " + e), this } clone() { return new this.constructor(this.r, this.g, this.b) } copy(e) { return this.r = e.r, this.g = e.g, this.b = e.b, this } copySRGBToLinear(e) { return this.r = rn(e.r), this.g = rn(e.g), this.b = rn(e.b), this } copyLinearToSRGB(e) { return this.r = an(e.r), this.g = an(e.g), this.b = an(e.b), this } convertSRGBToLinear() { return this.copySRGBToLinear(this), this } convertLinearToSRGB() { return this.copyLinearToSRGB(this), this } getHex(e = gt) { return nn.fromWorkingColorSpace(Vi.copy(this), e), 65536 * Math.round(Ot(255 * Vi.r, 0, 255)) + 256 * Math.round(Ot(255 * Vi.g, 0, 255)) + Math.round(Ot(255 * Vi.b, 0, 255)) } getHexString(e = gt) { return ("000000" + this.getHex(e).toString(16)).slice(-6) } getHSL(e, t = nn.workingColorSpace) { nn.fromWorkingColorSpace(Vi.copy(this), t); const n = Vi.r, i = Vi.g, r = Vi.b, a = Math.max(n, i, r), s = Math.min(n, i, r); let o, l; const c = (s + a) / 2; if (s === a) o = 0, l = 0; else { const e = a - s; switch (l = c <= .5 ? e / (a + s) : e / (2 - a - s), a) { case n: o = (i - r) / e + (i < r ? 6 : 0); break; case i: o = (r - n) / e + 2; break; case r: o = (n - i) / e + 4 } o /= 6 } return e.h = o, e.s = l, e.l = c, e } getRGB(e, t = nn.workingColorSpace) { return nn.fromWorkingColorSpace(Vi.copy(this), t), e.r = Vi.r, e.g = Vi.g, e.b = Vi.b, e } getStyle(e = gt) { nn.fromWorkingColorSpace(Vi.copy(this), e); const t = Vi.r, n = Vi.g, i = Vi.b; return e !== gt ? `color(${e} ${t.toFixed(3)} ${n.toFixed(3)} ${i.toFixed(3)})` : `rgb(${Math.round(255*t)},${Math.round(255*n)},${Math.round(255*i)})` } offsetHSL(e, t, n) { return this.getHSL(zi), this.setHSL(zi.h + e, zi.s + t, zi.l + n) } add(e) { return this.r += e.r, this.g += e.g, this.b += e.b, this } addColors(e, t) { return this.r = e.r + t.r, this.g = e.g + t.g, this.b = e.b + t.b, this } addScalar(e) { return this.r += e, this.g += e, this.b += e, this } sub(e) { return this.r = Math.max(0, this.r - e.r), this.g = Math.max(0, this.g - e.g), this.b = Math.max(0, this.b - e.b), this } multiply(e) { return this.r *= e.r, this.g *= e.g, this.b *= e.b, this } multiplyScalar(e) { return this.r *= e, this.g *= e, this.b *= e, this } lerp(e, t) { return this.r += (e.r - this.r) * t, this.g += (e.g - this.g) * t, this.b += (e.b - this.b) * t, this } lerpColors(e, t, n) { return this.r = e.r + (t.r - e.r) * n, this.g = e.g + (t.g - e.g) * n, this.b = e.b + (t.b - e.b) * n, this } lerpHSL(e, t) { this.getHSL(zi), e.getHSL(Oi); const n = Wt(zi.h, Oi.h, t), i = Wt(zi.s, Oi.s, t), r = Wt(zi.l, Oi.l, t); return this.setHSL(n, i, r), this } setFromVector3(e) { return this.r = e.x, this.g = e.y, this.b = e.z, this } applyMatrix3(e) { const t = this.r, n = this.g, i = this.b, r = e.elements; return this.r = r[0] * t + r[3] * n + r[6] * i, this.g = r[1] * t + r[4] * n + r[7] * i, this.b = r[2] * t + r[5] * n + r[8] * i, this } equals(e) { return e.r === this.r && e.g === this.g && e.b === this.b } fromArray(e, t = 0) { return this.r = e[t], this.g = e[t + 1], this.b = e[t + 2], this } toArray(e = [], t = 0) { return e[t] = this.r, e[t + 1] = this.g, e[t + 2] = this.b, e } fromBufferAttribute(e, t) { return this.r = e.getX(t), this.g = e.getY(t), this.b = e.getZ(t), this } toJSON() { return this.getHex() }*[Symbol.iterator]() { yield this.r, yield this.g, yield this.b } } const Vi = new Wi; Wi.NAMES = Ui; let Hi = 0; class Gi extends Lt { constructor() { super(), this.isMaterial = !0, Object.defineProperty(this, "id", { value: Hi++ }), this.uuid = zt(), this.name = "", this.type = "Material", this.blending = 1, this.side = 0, this.vertexColors = !1, this.opacity = 1, this.transparent = !1, this.alphaHash = !1, this.blendSrc = 204, this.blendDst = 205, this.blendEquation = M, this.blendSrcAlpha = null, this.blendDstAlpha = null, this.blendEquationAlpha = null, this.blendColor = new Wi(0, 0, 0), this.blendAlpha = 0, this.depthFunc = 3, this.depthTest = !0, this.depthWrite = !0, this.stencilWriteMask = 255, this.stencilFunc = 519, this.stencilRef = 0, this.stencilFuncMask = 255, this.stencilFail = At, this.stencilZFail = At, this.stencilZPass = At, this.stencilWrite = !1, this.clippingPlanes = null, this.clipIntersection = !1, this.clipShadows = !1, this.shadowSide = null, this.colorWrite = !0, this.precision = null, this.polygonOffset = !1, this.polygonOffsetFactor = 0, this.polygonOffsetUnits = 0, this.dithering = !1, this.alphaToCoverage = !1, this.premultipliedAlpha = !1, this.forceSinglePass = !1, this.visible = !0, this.toneMapped = !0, this.userData = {}, this.version = 0, this._alphaTest = 0 } get alphaTest() { return this._alphaTest } set alphaTest(e) { this._alphaTest > 0 != e > 0 && this.version++, this._alphaTest = e } onBeforeRender() {} onBeforeCompile() {} customProgramCacheKey() { return this.onBeforeCompile.toString() } setValues(e) { if (void 0 !== e) for (const t in e) { const n = e[t]; if (void 0 === n) { console.warn(`THREE.Material: parameter '${t}' has value of undefined.`); continue } const i = this[t]; void 0 !== i ? i && i.isColor ? i.set(n) : i && i.isVector3 && n && n.isVector3 ? i.copy(n) : this[t] = n : console.warn(`THREE.Material: '${t}' is not a property of THREE.${this.type}.`) } } toJSON(e) { const t = void 0 === e || "string" == typeof e; t && (e = { textures: {}, images: {} }); const n = { metadata: { version: 4.6, type: "Material", generator: "Material.toJSON" } }; function i(e) { const t = []; for (const n in e) { const i = e[n]; delete i.metadata, t.push(i) } return t } if (n.uuid = this.uuid, n.type = this.type, "" !== this.name && (n.name = this.name), this.color && this.color.isColor && (n.color = this.color.getHex()), void 0 !== this.roughness && (n.roughness = this.roughness), void 0 !== this.metalness && (n.metalness = this.metalness), void 0 !== this.sheen && (n.sheen = this.sheen), this.sheenColor && this.sheenColor.isColor && (n.sheenColor = this.sheenColor.getHex()), void 0 !== this.sheenRoughness && (n.sheenRoughness = this.sheenRoughness), this.emissive && this.emissive.isColor && (n.emissive = this.emissive.getHex()), void 0 !== this.emissiveIntensity && 1 !== this.emissiveIntensity && (n.emissiveIntensity = this.emissiveIntensity), this.specular && this.specular.isColor && (n.specular = this.specular.getHex()), void 0 !== this.specularIntensity && (n.specularIntensity = this.specularIntensity), this.specularColor && this.specularColor.isColor && (n.specularColor = this.specularColor.getHex()), void 0 !== this.shininess && (n.shininess = this.shininess), void 0 !== this.clearcoat && (n.clearcoat = this.clearcoat), void 0 !== this.clearcoatRoughness && (n.clearcoatRoughness = this.clearcoatRoughness), this.clearcoatMap && this.clearcoatMap.isTexture && (n.clearcoatMap = this.clearcoatMap.toJSON(e).uuid), this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture && (n.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(e).uuid), this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture && (n.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(e).uuid, n.clearcoatNormalScale = this.clearcoatNormalScale.toArray()), void 0 !== this.dispersion && (n.dispersion = this.dispersion), void 0 !== this.iridescence && (n.iridescence = this.iridescence), void 0 !== this.iridescenceIOR && (n.iridescenceIOR = this.iridescenceIOR), void 0 !== this.iridescenceThicknessRange && (n.iridescenceThicknessRange = this.iridescenceThicknessRange), this.iridescenceMap && this.iridescenceMap.isTexture && (n.iridescenceMap = this.iridescenceMap.toJSON(e).uuid), this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture && (n.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON(e).uuid), void 0 !== this.anisotropy && (n.anisotropy = this.anisotropy), void 0 !== this.anisotropyRotation && (n.anisotropyRotation = this.anisotropyRotation), this.anisotropyMap && this.anisotropyMap.isTexture && (n.anisotropyMap = this.anisotropyMap.toJSON(e).uuid), this.map && this.map.isTexture && (n.map = this.map.toJSON(e).uuid), this.matcap && this.matcap.isTexture && (n.matcap = this.matcap.toJSON(e).uuid), this.alphaMap && this.alphaMap.isTexture && (n.alphaMap = this.alphaMap.toJSON(e).uuid), this.lightMap && this.lightMap.isTexture && (n.lightMap = this.lightMap.toJSON(e).uuid, n.lightMapIntensity = this.lightMapIntensity), this.aoMap && this.aoMap.isTexture && (n.aoMap = this.aoMap.toJSON(e).uuid, n.aoMapIntensity = this.aoMapIntensity), this.bumpMap && this.bumpMap.isTexture && (n.bumpMap = this.bumpMap.toJSON(e).uuid, n.bumpScale = this.bumpScale), this.normalMap && this.normalMap.isTexture && (n.normalMap = this.normalMap.toJSON(e).uuid, n.normalMapType = this.normalMapType, n.normalScale = this.normalScale.toArray()), this.displacementMap && this.displacementMap.isTexture && (n.displacementMap = this.displacementMap.toJSON(e).uuid, n.displacementScale = this.displacementScale, n.displacementBias = this.displacementBias), this.roughnessMap && this.roughnessMap.isTexture && (n.roughnessMap = this.roughnessMap.toJSON(e).uuid), this.metalnessMap && this.metalnessMap.isTexture && (n.metalnessMap = this.metalnessMap.toJSON(e).uuid), this.emissiveMap && this.emissiveMap.isTexture && (n.emissiveMap = this.emissiveMap.toJSON(e).uuid), this.specularMap && this.specularMap.isTexture && (n.specularMap = this.specularMap.toJSON(e).uuid), this.specularIntensityMap && this.specularIntensityMap.isTexture && (n.specularIntensityMap = this.specularIntensityMap.toJSON(e).uuid), this.specularColorMap && this.specularColorMap.isTexture && (n.specularColorMap = this.specularColorMap.toJSON(e).uuid), this.envMap && this.envMap.isTexture && (n.envMap = this.envMap.toJSON(e).uuid, void 0 !== this.combine && (n.combine = this.combine)), void 0 !== this.envMapRotation && (n.envMapRotation = this.envMapRotation.toArray()), void 0 !== this.envMapIntensity && (n.envMapIntensity = this.envMapIntensity), void 0 !== this.reflectivity && (n.reflectivity = this.reflectivity), void 0 !== this.refractionRatio && (n.refractionRatio = this.refractionRatio), this.gradientMap && this.gradientMap.isTexture && (n.gradientMap = this.gradientMap.toJSON(e).uuid), void 0 !== this.transmission && (n.transmission = this.transmission), this.transmissionMap && this.transmissionMap.isTexture && (n.transmissionMap = this.transmissionMap.toJSON(e).uuid), void 0 !== this.thickness && (n.thickness = this.thickness), this.thicknessMap && this.thicknessMap.isTexture && (n.thicknessMap = this.thicknessMap.toJSON(e).uuid), void 0 !== this.attenuationDistance && this.attenuationDistance !== 1 / 0 && (n.attenuationDistance = this.attenuationDistance), void 0 !== this.attenuationColor && (n.attenuationColor = this.attenuationColor.getHex()), void 0 !== this.size && (n.size = this.size), null !== this.shadowSide && (n.shadowSide = this.shadowSide), void 0 !== this.sizeAttenuation && (n.sizeAttenuation = this.sizeAttenuation), 1 !== this.blending && (n.blending = this.blending), 0 !== this.side && (n.side = this.side), !0 === this.vertexColors && (n.vertexColors = !0), this.opacity < 1 && (n.opacity = this.opacity), !0 === this.transparent && (n.transparent = !0), 204 !== this.blendSrc && (n.blendSrc = this.blendSrc), 205 !== this.blendDst && (n.blendDst = this.blendDst), this.blendEquation !== M && (n.blendEquation = this.blendEquation), null !== this.blendSrcAlpha && (n.blendSrcAlpha = this.blendSrcAlpha), null !== this.blendDstAlpha && (n.blendDstAlpha = this.blendDstAlpha), null !== this.blendEquationAlpha && (n.blendEquationAlpha = this.blendEquationAlpha), this.blendColor && this.blendColor.isColor && (n.blendColor = this.blendColor.getHex()), 0 !== this.blendAlpha && (n.blendAlpha = this.blendAlpha), 3 !== this.depthFunc && (n.depthFunc = this.depthFunc), !1 === this.depthTest && (n.depthTest = this.depthTest), !1 === this.depthWrite && (n.depthWrite = this.depthWrite), !1 === this.colorWrite && (n.colorWrite = this.colorWrite), 255 !== this.stencilWriteMask && (n.stencilWriteMask = this.stencilWriteMask), 519 !== this.stencilFunc && (n.stencilFunc = this.stencilFunc), 0 !== this.stencilRef && (n.stencilRef = this.stencilRef), 255 !== this.stencilFuncMask && (n.stencilFuncMask = this.stencilFuncMask), this.stencilFail !== At && (n.stencilFail = this.stencilFail), this.stencilZFail !== At && (n.stencilZFail = this.stencilZFail), this.stencilZPass !== At && (n.stencilZPass = this.stencilZPass), !0 === this.stencilWrite && (n.stencilWrite = this.stencilWrite), void 0 !== this.rotation && 0 !== this.rotation && (n.rotation = this.rotation), !0 === this.polygonOffset && (n.polygonOffset = !0), 0 !== this.polygonOffsetFactor && (n.polygonOffsetFactor = this.polygonOffsetFactor), 0 !== this.polygonOffsetUnits && (n.polygonOffsetUnits = this.polygonOffsetUnits), void 0 !== this.linewidth && 1 !== this.linewidth && (n.linewidth = this.linewidth), void 0 !== this.dashSize && (n.dashSize = this.dashSize), void 0 !== this.gapSize && (n.gapSize = this.gapSize), void 0 !== this.scale && (n.scale = this.scale), !0 === this.dithering && (n.dithering = !0), this.alphaTest > 0 && (n.alphaTest = this.alphaTest), !0 === this.alphaHash && (n.alphaHash = !0), !0 === this.alphaToCoverage && (n.alphaToCoverage = !0), !0 === this.premultipliedAlpha && (n.premultipliedAlpha = !0), !0 === this.forceSinglePass && (n.forceSinglePass = !0), !0 === this.wireframe && (n.wireframe = !0), this.wireframeLinewidth > 1 && (n.wireframeLinewidth = this.wireframeLinewidth), "round" !== this.wireframeLinecap && (n.wireframeLinecap = this.wireframeLinecap), "round" !== this.wireframeLinejoin && (n.wireframeLinejoin = this.wireframeLinejoin), !0 === this.flatShading && (n.flatShading = !0), !1 === this.visible && (n.visible = !1), !1 === this.toneMapped && (n.toneMapped = !1), !1 === this.fog && (n.fog = !1), Object.keys(this.userData).length > 0 && (n.userData = this.userData), t) { const t = i(e.textures), r = i(e.images); t.length > 0 && (n.textures = t), r.length > 0 && (n.images = r) } return n } clone() { return (new this.constructor).copy(this) } copy(e) { this.name = e.name, this.blending = e.blending, this.side = e.side, this.vertexColors = e.vertexColors, this.opacity = e.opacity, this.transparent = e.transparent, this.blendSrc = e.blendSrc, this.blendDst = e.blendDst, this.blendEquation = e.blendEquation, this.blendSrcAlpha = e.blendSrcAlpha, this.blendDstAlpha = e.blendDstAlpha, this.blendEquationAlpha = e.blendEquationAlpha, this.blendColor.copy(e.blendColor), this.blendAlpha = e.blendAlpha, this.depthFunc = e.depthFunc, this.depthTest = e.depthTest, this.depthWrite = e.depthWrite, this.stencilWriteMask = e.stencilWriteMask, this.stencilFunc = e.stencilFunc, this.stencilRef = e.stencilRef, this.stencilFuncMask = e.stencilFuncMask, this.stencilFail = e.stencilFail, this.stencilZFail = e.stencilZFail, this.stencilZPass = e.stencilZPass, this.stencilWrite = e.stencilWrite; const t = e.clippingPlanes; let n = null; if (null !== t) { const e = t.length; n = new Array(e); for (let i = 0; i !== e; ++i) n[i] = t[i].clone() } return this.clippingPlanes = n, this.clipIntersection = e.clipIntersection, this.clipShadows = e.clipShadows, this.shadowSide = e.shadowSide, this.colorWrite = e.colorWrite, this.precision = e.precision, this.polygonOffset = e.polygonOffset, this.polygonOffsetFactor = e.polygonOffsetFactor, this.polygonOffsetUnits = e.polygonOffsetUnits, this.dithering = e.dithering, this.alphaTest = e.alphaTest, this.alphaHash = e.alphaHash, this.alphaToCoverage = e.alphaToCoverage, this.premultipliedAlpha = e.premultipliedAlpha, this.forceSinglePass = e.forceSinglePass, this.visible = e.visible, this.toneMapped = e.toneMapped, this.userData = JSON.parse(JSON.stringify(e.userData)), this } dispose() { this.dispatchEvent({ type: "dispose" }) } set needsUpdate(e) { !0 === e && this.version++ } onBuild() { console.warn("Material: onBuild() has been removed.") } } class ji extends Gi { constructor(e) { super(), this.isMeshBasicMaterial = !0, this.type = "MeshBasicMaterial", this.color = new Wi(16777215), this.map = null, this.lightMap = null, this.lightMapIntensity = 1, this.aoMap = null, this.aoMapIntensity = 1, this.specularMap = null, this.alphaMap = null, this.envMap = null, this.envMapRotation = new ai, this.combine = 0, this.reflectivity = 1, this.refractionRatio = .98, this.wireframe = !1, this.wireframeLinewidth = 1, this.wireframeLinecap = "round", this.wireframeLinejoin = "round", this.fog = !0, this.setValues(e) } copy(e) { return super.copy(e), this.color.copy(e.color), this.map = e.map, this.lightMap = e.lightMap, this.lightMapIntensity = e.lightMapIntensity, this.aoMap = e.aoMap, this.aoMapIntensity = e.aoMapIntensity, this.specularMap = e.specularMap, this.alphaMap = e.alphaMap, this.envMap = e.envMap, this.envMapRotation.copy(e.envMapRotation), this.combine = e.combine, this.reflectivity = e.reflectivity, this.refractionRatio = e.refractionRatio, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.wireframeLinecap = e.wireframeLinecap, this.wireframeLinejoin = e.wireframeLinejoin, this.fog = e.fog, this } } const Qi = new yn, Yi = new jt; let Ki = 0; class qi { constructor(e, t, n = !1) { if (Array.isArray(e)) throw new TypeError("THREE.BufferAttribute: array should be a Typed Array."); this.isBufferAttribute = !0, Object.defineProperty(this, "id", { value: Ki++ }), this.name = "", this.array = e, this.itemSize = t, this.count = void 0 !== e ? e.length / t : 0, this.normalized = n, this.usage = Ct, this.updateRanges = [], this.gpuType = ye, this.version = 0 } onUploadCallback() {} set needsUpdate(e) { !0 === e && this.version++ } setUsage(e) { return this.usage = e, this } addUpdateRange(e, t) { this.updateRanges.push({ start: e, count: t }) } clearUpdateRanges() { this.updateRanges.length = 0 } copy(e) { return this.name = e.name, this.array = new e.array.constructor(e.array), this.itemSize = e.itemSize, this.count = e.count, this.normalized = e.normalized, this.usage = e.usage, this.gpuType = e.gpuType, this } copyAt(e, t, n) { e *= this.itemSize, n *= t.itemSize; for (let i = 0, r = this.itemSize; i < r; i++) this.array[e + i] = t.array[n + i]; return this } copyArray(e) { return this.array.set(e), this } applyMatrix3(e) { if (2 === this.itemSize) for (let t = 0, n = this.count; t < n; t++) Yi.fromBufferAttribute(this, t), Yi.applyMatrix3(e), this.setXY(t, Yi.x, Yi.y); else if (3 === this.itemSize) for (let t = 0, n = this.count; t < n; t++) Qi.fromBufferAttribute(this, t), Qi.applyMatrix3(e), this.setXYZ(t, Qi.x, Qi.y, Qi.z); return this } applyMatrix4(e) { for (let t = 0, n = this.count; t < n; t++) Qi.fromBufferAttribute(this, t), Qi.applyMatrix4(e), this.setXYZ(t, Qi.x, Qi.y, Qi.z); return this } applyNormalMatrix(e) { for (let t = 0, n = this.count; t < n; t++) Qi.fromBufferAttribute(this, t), Qi.applyNormalMatrix(e), this.setXYZ(t, Qi.x, Qi.y, Qi.z); return this } transformDirection(e) { for (let t = 0, n = this.count; t < n; t++) Qi.fromBufferAttribute(this, t), Qi.transformDirection(e), this.setXYZ(t, Qi.x, Qi.y, Qi.z); return this } set(e, t = 0) { return this.array.set(e, t), this } getComponent(e, t) { let n = this.array[e * this.itemSize + t]; return this.normalized && (n = Vt(n, this.array)), n } setComponent(e, t, n) { return this.normalized && (n = Ht(n, this.array)), this.array[e * this.itemSize + t] = n, this } getX(e) { let t = this.array[e * this.itemSize]; return this.normalized && (t = Vt(t, this.array)), t } setX(e, t) { return this.normalized && (t = Ht(t, this.array)), this.array[e * this.itemSize] = t, this } getY(e) { let t = this.array[e * this.itemSize + 1]; return this.normalized && (t = Vt(t, this.array)), t } setY(e, t) { return this.normalized && (t = Ht(t, this.array)), this.array[e * this.itemSize + 1] = t, this } getZ(e) { let t = this.array[e * this.itemSize + 2]; return this.normalized && (t = Vt(t, this.array)), t } setZ(e, t) { return this.normalized && (t = Ht(t, this.array)), this.array[e * this.itemSize + 2] = t, this } getW(e) { let t = this.array[e * this.itemSize + 3]; return this.normalized && (t = Vt(t, this.array)), t } setW(e, t) { return this.normalized && (t = Ht(t, this.array)), this.array[e * this.itemSize + 3] = t, this } setXY(e, t, n) { return e *= this.itemSize, this.normalized && (t = Ht(t, this.array), n = Ht(n, this.array)), this.array[e + 0] = t, this.array[e + 1] = n, this } setXYZ(e, t, n, i) { return e *= this.itemSize, this.normalized && (t = Ht(t, this.array), n = Ht(n, this.array), i = Ht(i, this.array)), this.array[e + 0] = t, this.array[e + 1] = n, this.array[e + 2] = i, this } setXYZW(e, t, n, i, r) { return e *= this.itemSize, this.normalized && (t = Ht(t, this.array), n = Ht(n, this.array), i = Ht(i, this.array), r = Ht(r, this.array)), this.array[e + 0] = t, this.array[e + 1] = n, this.array[e + 2] = i, this.array[e + 3] = r, this } onUpload(e) { return this.onUploadCallback = e, this } clone() { return new this.constructor(this.array, this.itemSize).copy(this) } toJSON() { const e = { itemSize: this.itemSize, type: this.array.constructor.name, array: Array.from(this.array), normalized: this.normalized }; return "" !== this.name && (e.name = this.name), this.usage !== Ct && (e.usage = this.usage), e } } class Xi extends qi { constructor(e, t, n) { super(new Uint16Array(e), t, n) } } class Zi extends qi { constructor(e, t, n) { super(new Uint32Array(e), t, n) } } class Ji extends qi { constructor(e, t, n) { super(new Float32Array(e), t, n) } } let $i = 0; const er = new qn, tr = new xi, nr = new yn, ir = new xn, rr = new xn, ar = new yn; class sr extends Lt { constructor() { super(), this.isBufferGeometry = !0, Object.defineProperty(this, "id", { value: $i++ }), this.uuid = zt(), this.name = "", this.type = "BufferGeometry", this.index = null, this.indirect = null, this.attributes = {}, this.morphAttributes = {}, this.morphTargetsRelative = !1, this.groups = [], this.boundingBox = null, this.boundingSphere = null, this.drawRange = { start: 0, count: 1 / 0 }, this.userData = {} } getIndex() { return this.index } setIndex(e) { return Array.isArray(e) ? this.index = new(Kt(e) ? Zi : Xi)(e, 1) : this.index = e, this } setIndirect(e) { return this.indirect = e, this } getIndirect() { return this.indirect } getAttribute(e) { return this.attributes[e] } setAttribute(e, t) { return this.attributes[e] = t, this } deleteAttribute(e) { return delete this.attributes[e], this } hasAttribute(e) { return void 0 !== this.attributes[e] } addGroup(e, t, n = 0) { this.groups.push({ start: e, count: t, materialIndex: n }) } clearGroups() { this.groups = [] } setDrawRange(e, t) { this.drawRange.start = e, this.drawRange.count = t } applyMatrix4(e) { const t = this.attributes.position; void 0 !== t && (t.applyMatrix4(e), t.needsUpdate = !0); const n = this.attributes.normal; if (void 0 !== n) { const t = (new Qt).getNormalMatrix(e); n.applyNormalMatrix(t), n.needsUpdate = !0 } const i = this.attributes.tangent; return void 0 !== i && (i.transformDirection(e), i.needsUpdate = !0), null !== this.boundingBox && this.computeBoundingBox(), null !== this.boundingSphere && this.computeBoundingSphere(), this } applyQuaternion(e) { return er.makeRotationFromQuaternion(e), this.applyMatrix4(er), this } rotateX(e) { return er.makeRotationX(e), this.applyMatrix4(er), this } rotateY(e) { return er.makeRotationY(e), this.applyMatrix4(er), this } rotateZ(e) { return er.makeRotationZ(e), this.applyMatrix4(er), this } translate(e, t, n) { return er.makeTranslation(e, t, n), this.applyMatrix4(er), this } scale(e, t, n) { return er.makeScale(e, t, n), this.applyMatrix4(er), this } lookAt(e) { return tr.lookAt(e), tr.updateMatrix(), this.applyMatrix4(tr.matrix), this } center() { return this.computeBoundingBox(), this.boundingBox.getCenter(nr).negate(), this.translate(nr.x, nr.y, nr.z), this } setFromPoints(e) { const t = this.getAttribute("position"); if (void 0 === t) { const t = []; for (let n = 0, i = e.length; n < i; n++) { const i = e[n]; t.push(i.x, i.y, i.z || 0) } this.setAttribute("position", new Ji(t, 3)) } else { const n = Math.min(e.length, t.count); for (let i = 0; i < n; i++) { const n = e[i]; t.setXYZ(i, n.x, n.y, n.z || 0) } e.length > t.count && console.warn("THREE.BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry."), t.needsUpdate = !0 } return this } computeBoundingBox() { null === this.boundingBox && (this.boundingBox = new xn); const e = this.attributes.position, t = this.morphAttributes.position; if (e && e.isGLBufferAttribute) return console.error("THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.", this), void this.boundingBox.set(new yn(-1 / 0, -1 / 0, -1 / 0), new yn(1 / 0, 1 / 0, 1 / 0)); if (void 0 !== e) { if (this.boundingBox.setFromBufferAttribute(e), t) for (let e = 0, n = t.length; e < n; e++) { const n = t[e]; ir.setFromBufferAttribute(n), this.morphTargetsRelative ? (ar.addVectors(this.boundingBox.min, ir.min), this.boundingBox.expandByPoint(ar), ar.addVectors(this.boundingBox.max, ir.max), this.boundingBox.expandByPoint(ar)) : (this.boundingBox.expandByPoint(ir.min), this.boundingBox.expandByPoint(ir.max)) } } else this.boundingBox.makeEmpty(); (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) && console.error('THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this) } computeBoundingSphere() { null === this.boundingSphere && (this.boundingSphere = new Fn); const e = this.attributes.position, t = this.morphAttributes.position; if (e && e.isGLBufferAttribute) return console.error("THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere.", this), void this.boundingSphere.set(new yn, 1 / 0); if (e) { const n = this.boundingSphere.center; if (ir.setFromBufferAttribute(e), t) for (let e = 0, n = t.length; e < n; e++) { const n = t[e]; rr.setFromBufferAttribute(n), this.morphTargetsRelative ? (ar.addVectors(ir.min, rr.min), ir.expandByPoint(ar), ar.addVectors(ir.max, rr.max), ir.expandByPoint(ar)) : (ir.expandByPoint(rr.min), ir.expandByPoint(rr.max)) } ir.getCenter(n); let i = 0; for (let t = 0, r = e.count; t < r; t++) ar.fromBufferAttribute(e, t), i = Math.max(i, n.distanceToSquared(ar)); if (t) for (let r = 0, a = t.length; r < a; r++) { const a = t[r], s = this.morphTargetsRelative; for (let t = 0, r = a.count; t < r; t++) ar.fromBufferAttribute(a, t), s && (nr.fromBufferAttribute(e, t), ar.add(nr)), i = Math.max(i, n.distanceToSquared(ar)) } this.boundingSphere.radius = Math.sqrt(i), isNaN(this.boundingSphere.radius) && console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this) } } computeTangents() { const e = this.index, t = this.attributes; if (null === e || void 0 === t.position || void 0 === t.normal || void 0 === t.uv) return void console.error("THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)"); const n = t.position, i = t.normal, r = t.uv; !1 === this.hasAttribute("tangent") && this.setAttribute("tangent", new qi(new Float32Array(4 * n.count), 4)); const a = this.getAttribute("tangent"), s = [], o = []; for (let e = 0; e < n.count; e++) s[e] = new yn, o[e] = new yn; const l = new yn, c = new yn, h = new yn, d = new jt, u = new jt, p = new jt, f = new yn, m = new yn; function g(e, t, i) { l.fromBufferAttribute(n, e), c.fromBufferAttribute(n, t), h.fromBufferAttribute(n, i), d.fromBufferAttribute(r, e), u.fromBufferAttribute(r, t), p.fromBufferAttribute(r, i), c.sub(l), h.sub(l), u.sub(d), p.sub(d); const a = 1 / (u.x * p.y - p.x * u.y); isFinite(a) && (f.copy(c).multiplyScalar(p.y).addScaledVector(h, -u.y).multiplyScalar(a), m.copy(h).multiplyScalar(u.x).addScaledVector(c, -p.x).multiplyScalar(a), s[e].add(f), s[t].add(f), s[i].add(f), o[e].add(m), o[t].add(m), o[i].add(m)) } let v = this.groups; 0 === v.length && (v = [{ start: 0, count: e.count }]); for (let t = 0, n = v.length; t < n; ++t) { const n = v[t], i = n.start; for (let t = i, r = i + n.count; t < r; t += 3) g(e.getX(t + 0), e.getX(t + 1), e.getX(t + 2)) } const w = new yn, y = new yn, A = new yn, b = new yn; function x(e) { A.fromBufferAttribute(i, e), b.copy(A); const t = s[e]; w.copy(t), w.sub(A.multiplyScalar(A.dot(t))).normalize(), y.crossVectors(b, t); const n = y.dot(o[e]) < 0 ? -1 : 1; a.setXYZW(e, w.x, w.y, w.z, n) } for (let t = 0, n = v.length; t < n; ++t) { const n = v[t], i = n.start; for (let t = i, r = i + n.count; t < r; t += 3) x(e.getX(t + 0)), x(e.getX(t + 1)), x(e.getX(t + 2)) } } computeVertexNormals() { const e = this.index, t = this.getAttribute("position"); if (void 0 !== t) { let n = this.getAttribute("normal"); if (void 0 === n) n = new qi(new Float32Array(3 * t.count), 3), this.setAttribute("normal", n); else for (let e = 0, t = n.count; e < t; e++) n.setXYZ(e, 0, 0, 0); const i = new yn, r = new yn, a = new yn, s = new yn, o = new yn, l = new yn, c = new yn, h = new yn; if (e) for (let d = 0, u = e.count; d < u; d += 3) { const u = e.getX(d + 0), p = e.getX(d + 1), f = e.getX(d + 2); i.fromBufferAttribute(t, u), r.fromBufferAttribute(t, p), a.fromBufferAttribute(t, f), c.subVectors(a, r), h.subVectors(i, r), c.cross(h), s.fromBufferAttribute(n, u), o.fromBufferAttribute(n, p), l.fromBufferAttribute(n, f), s.add(c), o.add(c), l.add(c), n.setXYZ(u, s.x, s.y, s.z), n.setXYZ(p, o.x, o.y, o.z), n.setXYZ(f, l.x, l.y, l.z) } else for (let e = 0, s = t.count; e < s; e += 3) i.fromBufferAttribute(t, e + 0), r.fromBufferAttribute(t, e + 1), a.fromBufferAttribute(t, e + 2), c.subVectors(a, r), h.subVectors(i, r), c.cross(h), n.setXYZ(e + 0, c.x, c.y, c.z), n.setXYZ(e + 1, c.x, c.y, c.z), n.setXYZ(e + 2, c.x, c.y, c.z); this.normalizeNormals(), n.needsUpdate = !0 } } normalizeNormals() { const e = this.attributes.normal; for (let t = 0, n = e.count; t < n; t++) ar.fromBufferAttribute(e, t), ar.normalize(), e.setXYZ(t, ar.x, ar.y, ar.z) } toNonIndexed() { function e(e, t) { const n = e.array, i = e.itemSize, r = e.normalized, a = new n.constructor(t.length * i); let s = 0, o = 0; for (let r = 0, l = t.length; r < l; r++) { s = e.isInterleavedBufferAttribute ? t[r] * e.data.stride + e.offset : t[r] * i; for (let e = 0; e < i; e++) a[o++] = n[s++] } return new qi(a, i, r) } if (null === this.index) return console.warn("THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed."), this; const t = new sr, n = this.index.array, i = this.attributes; for (const r in i) { const a = e(i[r], n); t.setAttribute(r, a) } const r = this.morphAttributes; for (const i in r) { const a = [], s = r[i]; for (let t = 0, i = s.length; t < i; t++) { const i = e(s[t], n); a.push(i) } t.morphAttributes[i] = a } t.morphTargetsRelative = this.morphTargetsRelative; const a = this.groups; for (let e = 0, n = a.length; e < n; e++) { const n = a[e]; t.addGroup(n.start, n.count, n.materialIndex) } return t } toJSON() { const e = { metadata: { version: 4.6, type: "BufferGeometry", generator: "BufferGeometry.toJSON" } }; if (e.uuid = this.uuid, e.type = this.type, "" !== this.name && (e.name = this.name), Object.keys(this.userData).length > 0 && (e.userData = this.userData), void 0 !== this.parameters) { const t = this.parameters; for (const n in t) void 0 !== t[n] && (e[n] = t[n]); return e } e.data = { attributes: {} }; const t = this.index; null !== t && (e.data.index = { type: t.array.constructor.name, array: Array.prototype.slice.call(t.array) }); const n = this.attributes; for (const t in n) { const i = n[t]; e.data.attributes[t] = i.toJSON(e.data) } const i = {}; let r = !1; for (const t in this.morphAttributes) { const n = this.morphAttributes[t], a = []; for (let t = 0, i = n.length; t < i; t++) { const i = n[t]; a.push(i.toJSON(e.data)) } a.length > 0 && (i[t] = a, r = !0) } r && (e.data.morphAttributes = i, e.data.morphTargetsRelative = this.morphTargetsRelative); const a = this.groups; a.length > 0 && (e.data.groups = JSON.parse(JSON.stringify(a))); const s = this.boundingSphere; return null !== s && (e.data.boundingSphere = { center: s.center.toArray(), radius: s.radius }), e } clone() { return (new this.constructor).copy(this) } copy(e) { this.index = null, this.attributes = {}, this.morphAttributes = {}, this.groups = [], this.boundingBox = null, this.boundingSphere = null; const t = {}; this.name = e.name; const n = e.index; null !== n && this.setIndex(n.clone(t)); const i = e.attributes; for (const e in i) { const n = i[e]; this.setAttribute(e, n.clone(t)) } const r = e.morphAttributes; for (const e in r) { const n = [], i = r[e]; for (let e = 0, r = i.length; e < r; e++) n.push(i[e].clone(t)); this.morphAttributes[e] = n } this.morphTargetsRelative = e.morphTargetsRelative; const a = e.groups; for (let e = 0, t = a.length; e < t; e++) { const t = a[e]; this.addGroup(t.start, t.count, t.materialIndex) } const s = e.boundingBox; null !== s && (this.boundingBox = s.clone()); const o = e.boundingSphere; return null !== o && (this.boundingSphere = o.clone()), this.drawRange.start = e.drawRange.start, this.drawRange.count = e.drawRange.count, this.userData = e.userData, this } dispose() { this.dispatchEvent({ type: "dispose" }) } } const or = new qn, lr = new Kn, cr = new Fn, hr = new yn, dr = new yn, ur = new yn, pr = new yn, fr = new yn, mr = new yn, gr = new yn, vr = new yn; class wr extends xi { constructor(e = new sr, t = new ji) { super(), this.isMesh = !0, this.type = "Mesh", this.geometry = e, this.material = t, this.morphTargetDictionary = void 0, this.morphTargetInfluences = void 0, this.updateMorphTargets() } copy(e, t) { return super.copy(e, t), void 0 !== e.morphTargetInfluences && (this.morphTargetInfluences = e.morphTargetInfluences.slice()), void 0 !== e.morphTargetDictionary && (this.morphTargetDictionary = Object.assign({}, e.morphTargetDictionary)), this.material = Array.isArray(e.material) ? e.material.slice() : e.material, this.geometry = e.geometry, this } updateMorphTargets() { const e = this.geometry.morphAttributes, t = Object.keys(e); if (t.length > 0) { const n = e[t[0]]; if (void 0 !== n) { this.morphTargetInfluences = [], this.morphTargetDictionary = {}; for (let e = 0, t = n.length; e < t; e++) { const t = n[e].name || String(e); this.morphTargetInfluences.push(0), this.morphTargetDictionary[t] = e } } } } getVertexPosition(e, t) { const n = this.geometry, i = n.attributes.position, r = n.morphAttributes.position, a = n.morphTargetsRelative; t.fromBufferAttribute(i, e); const s = this.morphTargetInfluences; if (r && s) { mr.set(0, 0, 0); for (let n = 0, i = r.length; n < i; n++) { const i = s[n], o = r[n]; 0 !== i && (fr.fromBufferAttribute(o, e), a ? mr.addScaledVector(fr, i) : mr.addScaledVector(fr.sub(t), i)) } t.add(mr) } return t } raycast(e, t) { const n = this.geometry, i = this.material, r = this.matrixWorld; if (void 0 !== i) { if (null === n.boundingSphere && n.computeBoundingSphere(), cr.copy(n.boundingSphere), cr.applyMatrix4(r), lr.copy(e.ray).recast(e.near), !1 === cr.containsPoint(lr.origin)) { if (null === lr.intersectSphere(cr, hr)) return; if (lr.origin.distanceToSquared(hr) > (e.far - e.near) ** 2) return } or.copy(r).invert(), lr.copy(e.ray).applyMatrix4(or), null !== n.boundingBox && !1 === lr.intersectsBox(n.boundingBox) || this._computeIntersections(e, t, lr) } } _computeIntersections(e, t, n) { let i; const r = this.geometry, a = this.material, s = r.index, o = r.attributes.position, l = r.attributes.uv, c = r.attributes.uv1, h = r.attributes.normal, d = r.groups, u = r.drawRange; if (null !== s) if (Array.isArray(a)) for (let r = 0, o = d.length; r < o; r++) { const o = d[r], p = a[o.materialIndex]; for (let r = Math.max(o.start, u.start), a = Math.min(s.count, Math.min(o.start + o.count, u.start + u.count)); r < a; r += 3) { i = yr(this, p, e, n, l, c, h, s.getX(r), s.getX(r + 1), s.getX(r + 2)), i && (i.faceIndex = Math.floor(r / 3), i.face.materialIndex = o.materialIndex, t.push(i)) } } else { for (let r = Math.max(0, u.start), o = Math.min(s.count, u.start + u.count); r < o; r += 3) { i = yr(this, a, e, n, l, c, h, s.getX(r), s.getX(r + 1), s.getX(r + 2)), i && (i.faceIndex = Math.floor(r / 3), t.push(i)) } } else if (void 0 !== o) if (Array.isArray(a)) for (let r = 0, s = d.length; r < s; r++) { const s = d[r], p = a[s.materialIndex]; for (let r = Math.max(s.start, u.start), a = Math.min(o.count, Math.min(s.start + s.count, u.start + u.count)); r < a; r += 3) { i = yr(this, p, e, n, l, c, h, r, r + 1, r + 2), i && (i.faceIndex = Math.floor(r / 3), i.face.materialIndex = s.materialIndex, t.push(i)) } } else { for (let r = Math.max(0, u.start), s = Math.min(o.count, u.start + u.count); r < s; r += 3) { i = yr(this, a, e, n, l, c, h, r, r + 1, r + 2), i && (i.faceIndex = Math.floor(r / 3), t.push(i)) } } } } function yr(e, t, n, i, r, a, s, o, l, c) { e.getVertexPosition(o, dr), e.getVertexPosition(l, ur), e.getVertexPosition(c, pr); const h = function(e, t, n, i, r, a, s, o) { let l; if (l = 1 === t.side ? i.intersectTriangle(s, a, r, !0, o) : i.intersectTriangle(r, a, s, 0 === t.side, o), null === l) return null; vr.copy(o), vr.applyMatrix4(e.matrixWorld); const c = n.ray.origin.distanceTo(vr); return c < n.near || c > n.far ? null : { distance: c, point: vr.clone(), object: e } }(e, t, n, i, dr, ur, pr, gr); if (h) { const e = new yn; Bi.getBarycoord(gr, dr, ur, pr, e), r && (h.uv = Bi.getInterpolatedAttribute(r, o, l, c, e, new jt)), a && (h.uv1 = Bi.getInterpolatedAttribute(a, o, l, c, e, new jt)), s && (h.normal = Bi.getInterpolatedAttribute(s, o, l, c, e, new yn), h.normal.dot(i.direction) > 0 && h.normal.multiplyScalar(-1)); const t = { a: o, b: l, c, normal: new yn, materialIndex: 0 }; Bi.getNormal(dr, ur, pr, t.normal), h.face = t, h.barycoord = e } return h } class Ar extends sr { constructor(e = 1, t = 1, n = 1, i = 1, r = 1, a = 1) { super(), this.type = "BoxGeometry", this.parameters = { width: e, height: t, depth: n, widthSegments: i, heightSegments: r, depthSegments: a }; const s = this; i = Math.floor(i), r = Math.floor(r), a = Math.floor(a); const o = [], l = [], c = [], h = []; let d = 0, u = 0; function p(e, t, n, i, r, a, p, f, m, g, v) { const w = a / m, y = p / g, A = a / 2, b = p / 2, x = f / 2, k = m + 1, E = g + 1; let S = 0, M = 0; const T = new yn; for (let a = 0; a < E; a++) { const s = a * y - b; for (let o = 0; o < k; o++) { const d = o * w - A; T[e] = d * i, T[t] = s * r, T[n] = x, l.push(T.x, T.y, T.z), T[e] = 0, T[t] = 0, T[n] = f > 0 ? 1 : -1, c.push(T.x, T.y, T.z), h.push(o / m), h.push(1 - a / g), S += 1 } } for (let e = 0; e < g; e++) for (let t = 0; t < m; t++) { const n = d + t + k * e, i = d + t + k * (e + 1), r = d + (t + 1) + k * (e + 1), a = d + (t + 1) + k * e; o.push(n, i, a), o.push(i, r, a), M += 6 } s.addGroup(u, M, v), u += M, d += S } p("z", "y", "x", -1, -1, n, t, e, a, r, 0), p("z", "y", "x", 1, -1, n, t, -e, a, r, 1), p("x", "z", "y", 1, 1, e, n, t, i, a, 2), p("x", "z", "y", 1, -1, e, n, -t, i, a, 3), p("x", "y", "z", 1, -1, e, t, n, i, r, 4), p("x", "y", "z", -1, -1, e, t, -n, i, r, 5), this.setIndex(o), this.setAttribute("position", new Ji(l, 3)), this.setAttribute("normal", new Ji(c, 3)), this.setAttribute("uv", new Ji(h, 2)) } copy(e) { return super.copy(e), this.parameters = Object.assign({}, e.parameters), this } static fromJSON(e) { return new Ar(e.width, e.height, e.depth, e.widthSegments, e.heightSegments, e.depthSegments) } } function br(e) { const t = {}; for (const n in e) { t[n] = {}; for (const i in e[n]) { const r = e[n][i]; r && (r.isColor || r.isMatrix3 || r.isMatrix4 || r.isVector2 || r.isVector3 || r.isVector4 || r.isTexture || r.isQuaternion) ? r.isRenderTargetTexture ? (console.warn("UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms()."), t[n][i] = null) : t[n][i] = r.clone() : Array.isArray(r) ? t[n][i] = r.slice() : t[n][i] = r } } return t } function xr(e) { const t = {}; for (let n = 0; n < e.length; n++) { const i = br(e[n]); for (const e in i) t[e] = i[e] } return t } function kr(e) { const t = e.getRenderTarget(); return null === t ? e.outputColorSpace : !0 === t.isXRRenderTarget ? t.texture.colorSpace : nn.workingColorSpace } const Er = { clone: br, merge: xr }; class Sr extends Gi { constructor(e) { super(), this.isShaderMaterial = !0, this.type = "ShaderMaterial", this.defines = {}, this.uniforms = {}, this.uniformsGroups = [], this.vertexShader = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}", this.fragmentShader = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}", this.linewidth = 1, this.wireframe = !1, this.wireframeLinewidth = 1, this.fog = !1, this.lights = !1, this.clipping = !1, this.forceSinglePass = !0, this.extensions = { clipCullDistance: !1, multiDraw: !1 }, this.defaultAttributeValues = { color: [1, 1, 1], uv: [0, 0], uv1: [0, 0] }, this.index0AttributeName = void 0, this.uniformsNeedUpdate = !1, this.glslVersion = null, void 0 !== e && this.setValues(e) } copy(e) { return super.copy(e), this.fragmentShader = e.fragmentShader, this.vertexShader = e.vertexShader, this.uniforms = br(e.uniforms), this.uniformsGroups = function(e) { const t = []; for (let n = 0; n < e.length; n++) t.push(e[n].clone()); return t }(e.uniformsGroups), this.defines = Object.assign({}, e.defines), this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.fog = e.fog, this.lights = e.lights, this.clipping = e.clipping, this.extensions = Object.assign({}, e.extensions), this.glslVersion = e.glslVersion, this } toJSON(e) { const t = super.toJSON(e); t.glslVersion = this.glslVersion, t.uniforms = {}; for (const n in this.uniforms) { const i = this.uniforms[n].value; i && i.isTexture ? t.uniforms[n] = { type: "t", value: i.toJSON(e).uuid } : i && i.isColor ? t.uniforms[n] = { type: "c", value: i.getHex() } : i && i.isVector2 ? t.uniforms[n] = { type: "v2", value: i.toArray() } : i && i.isVector3 ? t.uniforms[n] = { type: "v3", value: i.toArray() } : i && i.isVector4 ? t.uniforms[n] = { type: "v4", value: i.toArray() } : i && i.isMatrix3 ? t.uniforms[n] = { type: "m3", value: i.toArray() } : i && i.isMatrix4 ? t.uniforms[n] = { type: "m4", value: i.toArray() } : t.uniforms[n] = { value: i } } Object.keys(this.defines).length > 0 && (t.defines = this.defines), t.vertexShader = this.vertexShader, t.fragmentShader = this.fragmentShader, t.lights = this.lights, t.clipping = this.clipping; const n = {}; for (const e in this.extensions) !0 === this.extensions[e] && (n[e] = !0); return Object.keys(n).length > 0 && (t.extensions = n), t } } class Mr extends xi { constructor() { super(), this.isCamera = !0, this.type = "Camera", this.matrixWorldInverse = new qn, this.projectionMatrix = new qn, this.projectionMatrixInverse = new qn, this.coordinateSystem = It } copy(e, t) { return super.copy(e, t), this.matrixWorldInverse.copy(e.matrixWorldInverse), this.projectionMatrix.copy(e.projectionMatrix), this.projectionMatrixInverse.copy(e.projectionMatrixInverse), this.coordinateSystem = e.coordinateSystem, this } getWorldDirection(e) { return super.getWorldDirection(e).negate() } updateMatrixWorld(e) { super.updateMatrixWorld(e), this.matrixWorldInverse.copy(this.matrixWorld).invert() } updateWorldMatrix(e, t) { super.updateWorldMatrix(e, t), this.matrixWorldInverse.copy(this.matrixWorld).invert() } clone() { return (new this.constructor).copy(this) } } const Tr = new yn, _r = new jt, Cr = new jt; class Pr extends Mr { constructor(e = 50, t = 1, n = .1, i = 2e3) { super(), this.isPerspectiveCamera = !0, this.type = "PerspectiveCamera", this.fov = e, this.zoom = 1, this.near = n, this.far = i, this.focus = 10, this.aspect = t, this.view = null, this.filmGauge = 35, this.filmOffset = 0, this.updateProjectionMatrix() } copy(e, t) { return super.copy(e, t), this.fov = e.fov, this.zoom = e.zoom, this.near = e.near, this.far = e.far, this.focus = e.focus, this.aspect = e.aspect, this.view = null === e.view ? null : Object.assign({}, e.view), this.filmGauge = e.filmGauge, this.filmOffset = e.filmOffset, this } setFocalLength(e) { const t = .5 * this.getFilmHeight() / e; this.fov = 2 * Ut * Math.atan(t), this.updateProjectionMatrix() } getFocalLength() { const e = Math.tan(.5 * Bt * this.fov); return .5 * this.getFilmHeight() / e } getEffectiveFOV() { return 2 * Ut * Math.atan(Math.tan(.5 * Bt * this.fov) / this.zoom) } getFilmWidth() { return this.filmGauge * Math.min(this.aspect, 1) } getFilmHeight() { return this.filmGauge / Math.max(this.aspect, 1) } getViewBounds(e, t, n) { Tr.set(-1, -1, .5).applyMatrix4(this.projectionMatrixInverse), t.set(Tr.x, Tr.y).multiplyScalar(-e / Tr.z), Tr.set(1, 1, .5).applyMatrix4(this.projectionMatrixInverse), n.set(Tr.x, Tr.y).multiplyScalar(-e / Tr.z) } getViewSize(e, t) { return this.getViewBounds(e, _r, Cr), t.subVectors(Cr, _r) } setViewOffset(e, t, n, i, r, a) { this.aspect = e / t, null === this.view && (this.view = { enabled: !0, fullWidth: 1, fullHeight: 1, offsetX: 0, offsetY: 0, width: 1, height: 1 }), this.view.enabled = !0, this.view.fullWidth = e, this.view.fullHeight = t, this.view.offsetX = n, this.view.offsetY = i, this.view.width = r, this.view.height = a, this.updateProjectionMatrix() } clearViewOffset() { null !== this.view && (this.view.enabled = !1), this.updateProjectionMatrix() } updateProjectionMatrix() { const e = this.near; let t = e * Math.tan(.5 * Bt * this.fov) / this.zoom, n = 2 * t, i = this.aspect * n, r = -.5 * i; const a = this.view; if (null !== this.view && this.view.enabled) { const e = a.fullWidth, s = a.fullHeight; r += a.offsetX * i / e, t -= a.offsetY * n / s, i *= a.width / e, n *= a.height / s } const s = this.filmOffset; 0 !== s && (r += e * s / this.getFilmWidth()), this.projectionMatrix.makePerspective(r, r + i, t, t - n, e, this.far, this.coordinateSystem), this.projectionMatrixInverse.copy(this.projectionMatrix).invert() } toJSON(e) { const t = super.toJSON(e); return t.object.fov = this.fov, t.object.zoom = this.zoom, t.object.near = this.near, t.object.far = this.far, t.object.focus = this.focus, t.object.aspect = this.aspect, null !== this.view && (t.object.view = Object.assign({}, this.view)), t.object.filmGauge = this.filmGauge, t.object.filmOffset = this.filmOffset, t } } const Ir = -90; class Rr extends xi { constructor(e, t, n) { super(), this.type = "CubeCamera", this.renderTarget = n, this.coordinateSystem = null, this.activeMipmapLevel = 0; const i = new Pr(Ir, 1, e, t); i.layers = this.layers, this.add(i); const r = new Pr(Ir, 1, e, t); r.layers = this.layers, this.add(r); const a = new Pr(Ir, 1, e, t); a.layers = this.layers, this.add(a); const s = new Pr(Ir, 1, e, t); s.layers = this.layers, this.add(s); const o = new Pr(Ir, 1, e, t); o.layers = this.layers, this.add(o); const l = new Pr(Ir, 1, e, t); l.layers = this.layers, this.add(l) } updateCoordinateSystem() { const e = this.coordinateSystem, t = this.children.concat(), [n, i, r, a, s, o] = t; for (const e of t) this.remove(e); if (e === It) n.up.set(0, 1, 0), n.lookAt(1, 0, 0), i.up.set(0, 1, 0), i.lookAt(-1, 0, 0), r.up.set(0, 0, -1), r.lookAt(0, 1, 0), a.up.set(0, 0, 1), a.lookAt(0, -1, 0), s.up.set(0, 1, 0), s.lookAt(0, 0, 1), o.up.set(0, 1, 0), o.lookAt(0, 0, -1); else { if (e !== Rt) throw new Error("THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: " + e); n.up.set(0, -1, 0), n.lookAt(-1, 0, 0), i.up.set(0, -1, 0), i.lookAt(1, 0, 0), r.up.set(0, 0, 1), r.lookAt(0, 1, 0), a.up.set(0, 0, -1), a.lookAt(0, -1, 0), s.up.set(0, -1, 0), s.lookAt(0, 0, 1), o.up.set(0, -1, 0), o.lookAt(0, 0, -1) } for (const e of t) this.add(e), e.updateMatrixWorld() } update(e, t) { null === this.parent && this.updateMatrixWorld(); const { renderTarget: n, activeMipmapLevel: i } = this; this.coordinateSystem !== e.coordinateSystem && (this.coordinateSystem = e.coordinateSystem, this.updateCoordinateSystem()); const [r, a, s, o, l, c] = this.children, h = e.getRenderTarget(), d = e.getActiveCubeFace(), u = e.getActiveMipmapLevel(), p = e.xr.enabled; e.xr.enabled = !1; const f = n.texture.generateMipmaps; n.texture.generateMipmaps = !1, e.setRenderTarget(n, 0, i), e.render(t, r), e.setRenderTarget(n, 1, i), e.render(t, a), e.setRenderTarget(n, 2, i), e.render(t, s), e.setRenderTarget(n, 3, i), e.render(t, o), e.setRenderTarget(n, 4, i), e.render(t, l), n.texture.generateMipmaps = f, e.setRenderTarget(n, 5, i), e.render(t, c), e.setRenderTarget(h, d, u), e.xr.enabled = p, n.texture.needsPMREMUpdate = !0 } } class Lr extends un { constructor(e, t, n, i, r, a, s, o, l, c) { super(e = void 0 !== e ? e : [], t = void 0 !== t ? t : $, n, i, r, a, s, o, l, c), this.isCubeTexture = !0, this.flipY = !1 } get images() { return this.image } set images(e) { this.image = e } } class Dr extends mn { constructor(e = 1, t = {}) { super(e, e, t), this.isWebGLCubeRenderTarget = !0; const n = { width: e, height: e, depth: 1 }, i = [n, n, n, n, n, n]; this.texture = new Lr(i, t.mapping, t.wrapS, t.wrapT, t.magFilter, t.minFilter, t.format, t.type, t.anisotropy, t.colorSpace), this.texture.isRenderTargetTexture = !0, this.texture.generateMipmaps = void 0 !== t.generateMipmaps && t.generateMipmaps, this.texture.minFilter = void 0 !== t.minFilter ? t.minFilter : he } fromEquirectangularTexture(e, t) { this.texture.type = t.type, this.texture.colorSpace = t.colorSpace, this.texture.generateMipmaps = t.generateMipmaps, this.texture.minFilter = t.minFilter, this.texture.magFilter = t.magFilter; const n = { uniforms: { tEquirect: { value: null } }, vertexShader: "\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\n\t\t\t\t}\n\t\t\t", fragmentShader: "\n\n\t\t\t\tuniform sampler2D tEquirect;\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\t#include \n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t\t}\n\t\t\t" }, i = new Ar(5, 5, 5), r = new Sr({ name: "CubemapFromEquirect", uniforms: br(n.uniforms), vertexShader: n.vertexShader, fragmentShader: n.fragmentShader, side: 1, blending: 0 }); r.uniforms.tEquirect.value = t; const a = new wr(i, r), s = t.minFilter; t.minFilter === ue && (t.minFilter = he); return new Rr(1, 10, this).update(e, a), t.minFilter = s, a.geometry.dispose(), a.material.dispose(), this } clear(e, t, n, i) { const r = e.getRenderTarget(); for (let r = 0; r < 6; r++) e.setRenderTarget(this, r), e.clear(t, n, i); e.setRenderTarget(r) } } class Nr extends xi { constructor() { super(), this.isGroup = !0, this.type = "Group" } } const Br = { type: "move" }; class Ur { constructor() { this._targetRay = null, this._grip = null, this._hand = null } getHandSpace() { return null === this._hand && (this._hand = new Nr, this._hand.matrixAutoUpdate = !1, this._hand.visible = !1, this._hand.joints = {}, this._hand.inputState = { pinching: !1 }), this._hand } getTargetRaySpace() { return null === this._targetRay && (this._targetRay = new Nr, this._targetRay.matrixAutoUpdate = !1, this._targetRay.visible = !1, this._targetRay.hasLinearVelocity = !1, this._targetRay.linearVelocity = new yn, this._targetRay.hasAngularVelocity = !1, this._targetRay.angularVelocity = new yn), this._targetRay } getGripSpace() { return null === this._grip && (this._grip = new Nr, this._grip.matrixAutoUpdate = !1, this._grip.visible = !1, this._grip.hasLinearVelocity = !1, this._grip.linearVelocity = new yn, this._grip.hasAngularVelocity = !1, this._grip.angularVelocity = new yn), this._grip } dispatchEvent(e) { return null !== this._targetRay && this._targetRay.dispatchEvent(e), null !== this._grip && this._grip.dispatchEvent(e), null !== this._hand && this._hand.dispatchEvent(e), this } connect(e) { if (e && e.hand) { const t = this._hand; if (t) for (const n of e.hand.values()) this._getHandJoint(t, n) } return this.dispatchEvent({ type: "connected", data: e }), this } disconnect(e) { return this.dispatchEvent({ type: "disconnected", data: e }), null !== this._targetRay && (this._targetRay.visible = !1), null !== this._grip && (this._grip.visible = !1), null !== this._hand && (this._hand.visible = !1), this } update(e, t, n) { let i = null, r = null, a = null; const s = this._targetRay, o = this._grip, l = this._hand; if (e && "visible-blurred" !== t.session.visibilityState) { if (l && e.hand) { a = !0; for (const i of e.hand.values()) { const e = t.getJointPose(i, n), r = this._getHandJoint(l, i); null !== e && (r.matrix.fromArray(e.transform.matrix), r.matrix.decompose(r.position, r.rotation, r.scale), r.matrixWorldNeedsUpdate = !0, r.jointRadius = e.radius), r.visible = null !== e } const i = l.joints["index-finger-tip"], r = l.joints["thumb-tip"], s = i.position.distanceTo(r.position), o = .02, c = .005; l.inputState.pinching && s > o + c ? (l.inputState.pinching = !1, this.dispatchEvent({ type: "pinchend", handedness: e.handedness, target: this })) : !l.inputState.pinching && s <= o - c && (l.inputState.pinching = !0, this.dispatchEvent({ type: "pinchstart", handedness: e.handedness, target: this })) } else null !== o && e.gripSpace && (r = t.getPose(e.gripSpace, n), null !== r && (o.matrix.fromArray(r.transform.matrix), o.matrix.decompose(o.position, o.rotation, o.scale), o.matrixWorldNeedsUpdate = !0, r.linearVelocity ? (o.hasLinearVelocity = !0, o.linearVelocity.copy(r.linearVelocity)) : o.hasLinearVelocity = !1, r.angularVelocity ? (o.hasAngularVelocity = !0, o.angularVelocity.copy(r.angularVelocity)) : o.hasAngularVelocity = !1)); null !== s && (i = t.getPose(e.targetRaySpace, n), null === i && null !== r && (i = r), null !== i && (s.matrix.fromArray(i.transform.matrix), s.matrix.decompose(s.position, s.rotation, s.scale), s.matrixWorldNeedsUpdate = !0, i.linearVelocity ? (s.hasLinearVelocity = !0, s.linearVelocity.copy(i.linearVelocity)) : s.hasLinearVelocity = !1, i.angularVelocity ? (s.hasAngularVelocity = !0, s.angularVelocity.copy(i.angularVelocity)) : s.hasAngularVelocity = !1, this.dispatchEvent(Br))) } return null !== s && (s.visible = null !== i), null !== o && (o.visible = null !== r), null !== l && (l.visible = null !== a), this } _getHandJoint(e, t) { if (void 0 === e.joints[t.jointName]) { const n = new Nr; n.matrixAutoUpdate = !1, n.visible = !1, e.joints[t.jointName] = n, e.add(n) } return e.joints[t.jointName] } } class zr { constructor(e, t = 1, n = 1e3) { this.isFog = !0, this.name = "", this.color = new Wi(e), this.near = t, this.far = n } clone() { return new zr(this.color, this.near, this.far) } toJSON() { return { type: "Fog", name: this.name, color: this.color.getHex(), near: this.near, far: this.far } } } class Or extends xi { constructor() { super(), this.isScene = !0, this.type = "Scene", this.background = null, this.environment = null, this.fog = null, this.backgroundBlurriness = 0, this.backgroundIntensity = 1, this.backgroundRotation = new ai, this.environmentIntensity = 1, this.environmentRotation = new ai, this.overrideMaterial = null, "undefined" != typeof __THREE_DEVTOOLS__ && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this })) } copy(e, t) { return super.copy(e, t), null !== e.background && (this.background = e.background.clone()), null !== e.environment && (this.environment = e.environment.clone()), null !== e.fog && (this.fog = e.fog.clone()), this.backgroundBlurriness = e.backgroundBlurriness, this.backgroundIntensity = e.backgroundIntensity, this.backgroundRotation.copy(e.backgroundRotation), this.environmentIntensity = e.environmentIntensity, this.environmentRotation.copy(e.environmentRotation), null !== e.overrideMaterial && (this.overrideMaterial = e.overrideMaterial.clone()), this.matrixAutoUpdate = e.matrixAutoUpdate, this } toJSON(e) { const t = super.toJSON(e); return null !== this.fog && (t.object.fog = this.fog.toJSON()), this.backgroundBlurriness > 0 && (t.object.backgroundBlurriness = this.backgroundBlurriness), 1 !== this.backgroundIntensity && (t.object.backgroundIntensity = this.backgroundIntensity), t.object.backgroundRotation = this.backgroundRotation.toArray(), 1 !== this.environmentIntensity && (t.object.environmentIntensity = this.environmentIntensity), t.object.environmentRotation = this.environmentRotation.toArray(), t } } class Fr { constructor(e, t) { this.isInterleavedBuffer = !0, this.array = e, this.stride = t, this.count = void 0 !== e ? e.length / t : 0, this.usage = Ct, this.updateRanges = [], this.version = 0, this.uuid = zt() } onUploadCallback() {} set needsUpdate(e) { !0 === e && this.version++ } setUsage(e) { return this.usage = e, this } addUpdateRange(e, t) { this.updateRanges.push({ start: e, count: t }) } clearUpdateRanges() { this.updateRanges.length = 0 } copy(e) { return this.array = new e.array.constructor(e.array), this.count = e.count, this.stride = e.stride, this.usage = e.usage, this } copyAt(e, t, n) { e *= this.stride, n *= t.stride; for (let i = 0, r = this.stride; i < r; i++) this.array[e + i] = t.array[n + i]; return this } set(e, t = 0) { return this.array.set(e, t), this } clone(e) { void 0 === e.arrayBuffers && (e.arrayBuffers = {}), void 0 === this.array.buffer._uuid && (this.array.buffer._uuid = zt()), void 0 === e.arrayBuffers[this.array.buffer._uuid] && (e.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer); const t = new this.array.constructor(e.arrayBuffers[this.array.buffer._uuid]), n = new this.constructor(t, this.stride); return n.setUsage(this.usage), n } onUpload(e) { return this.onUploadCallback = e, this } toJSON(e) { return void 0 === e.arrayBuffers && (e.arrayBuffers = {}), void 0 === this.array.buffer._uuid && (this.array.buffer._uuid = zt()), void 0 === e.arrayBuffers[this.array.buffer._uuid] && (e.arrayBuffers[this.array.buffer._uuid] = Array.from(new Uint32Array(this.array.buffer))), { uuid: this.uuid, buffer: this.array.buffer._uuid, type: this.array.constructor.name, stride: this.stride } } } const Wr = new yn; class Vr { constructor(e, t, n, i = !1) { this.isInterleavedBufferAttribute = !0, this.name = "", this.data = e, this.itemSize = t, this.offset = n, this.normalized = i } get count() { return this.data.count } get array() { return this.data.array } set needsUpdate(e) { this.data.needsUpdate = e } applyMatrix4(e) { for (let t = 0, n = this.data.count; t < n; t++) Wr.fromBufferAttribute(this, t), Wr.applyMatrix4(e), this.setXYZ(t, Wr.x, Wr.y, Wr.z); return this } applyNormalMatrix(e) { for (let t = 0, n = this.count; t < n; t++) Wr.fromBufferAttribute(this, t), Wr.applyNormalMatrix(e), this.setXYZ(t, Wr.x, Wr.y, Wr.z); return this } transformDirection(e) { for (let t = 0, n = this.count; t < n; t++) Wr.fromBufferAttribute(this, t), Wr.transformDirection(e), this.setXYZ(t, Wr.x, Wr.y, Wr.z); return this } getComponent(e, t) { let n = this.array[e * this.data.stride + this.offset + t]; return this.normalized && (n = Vt(n, this.array)), n } setComponent(e, t, n) { return this.normalized && (n = Ht(n, this.array)), this.data.array[e * this.data.stride + this.offset + t] = n, this } setX(e, t) { return this.normalized && (t = Ht(t, this.array)), this.data.array[e * this.data.stride + this.offset] = t, this } setY(e, t) { return this.normalized && (t = Ht(t, this.array)), this.data.array[e * this.data.stride + this.offset + 1] = t, this } setZ(e, t) { return this.normalized && (t = Ht(t, this.array)), this.data.array[e * this.data.stride + this.offset + 2] = t, this } setW(e, t) { return this.normalized && (t = Ht(t, this.array)), this.data.array[e * this.data.stride + this.offset + 3] = t, this } getX(e) { let t = this.data.array[e * this.data.stride + this.offset]; return this.normalized && (t = Vt(t, this.array)), t } getY(e) { let t = this.data.array[e * this.data.stride + this.offset + 1]; return this.normalized && (t = Vt(t, this.array)), t } getZ(e) { let t = this.data.array[e * this.data.stride + this.offset + 2]; return this.normalized && (t = Vt(t, this.array)), t } getW(e) { let t = this.data.array[e * this.data.stride + this.offset + 3]; return this.normalized && (t = Vt(t, this.array)), t } setXY(e, t, n) { return e = e * this.data.stride + this.offset, this.normalized && (t = Ht(t, this.array), n = Ht(n, this.array)), this.data.array[e + 0] = t, this.data.array[e + 1] = n, this } setXYZ(e, t, n, i) { return e = e * this.data.stride + this.offset, this.normalized && (t = Ht(t, this.array), n = Ht(n, this.array), i = Ht(i, this.array)), this.data.array[e + 0] = t, this.data.array[e + 1] = n, this.data.array[e + 2] = i, this } setXYZW(e, t, n, i, r) { return e = e * this.data.stride + this.offset, this.normalized && (t = Ht(t, this.array), n = Ht(n, this.array), i = Ht(i, this.array), r = Ht(r, this.array)), this.data.array[e + 0] = t, this.data.array[e + 1] = n, this.data.array[e + 2] = i, this.data.array[e + 3] = r, this } clone(e) { if (void 0 === e) { console.log("THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data."); const e = []; for (let t = 0; t < this.count; t++) { const n = t * this.data.stride + this.offset; for (let t = 0; t < this.itemSize; t++) e.push(this.data.array[n + t]) } return new qi(new this.array.constructor(e), this.itemSize, this.normalized) } return void 0 === e.interleavedBuffers && (e.interleavedBuffers = {}), void 0 === e.interleavedBuffers[this.data.uuid] && (e.interleavedBuffers[this.data.uuid] = this.data.clone(e)), new Vr(e.interleavedBuffers[this.data.uuid], this.itemSize, this.offset, this.normalized) } toJSON(e) { if (void 0 === e) { console.log("THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data."); const e = []; for (let t = 0; t < this.count; t++) { const n = t * this.data.stride + this.offset; for (let t = 0; t < this.itemSize; t++) e.push(this.data.array[n + t]) } return { itemSize: this.itemSize, type: this.array.constructor.name, array: e, normalized: this.normalized } } return void 0 === e.interleavedBuffers && (e.interleavedBuffers = {}), void 0 === e.interleavedBuffers[this.data.uuid] && (e.interleavedBuffers[this.data.uuid] = this.data.toJSON(e)), { isInterleavedBufferAttribute: !0, itemSize: this.itemSize, data: this.data.uuid, offset: this.offset, normalized: this.normalized } } } const Hr = new yn, Gr = new pn, jr = new pn, Qr = new yn, Yr = new qn, Kr = new yn, qr = new Fn, Xr = new qn, Zr = new Kn; class Jr extends wr { constructor(e, t) { super(e, t), this.isSkinnedMesh = !0, this.type = "SkinnedMesh", this.bindMode = J, this.bindMatrix = new qn, this.bindMatrixInverse = new qn, this.boundingBox = null, this.boundingSphere = null } computeBoundingBox() { const e = this.geometry; null === this.boundingBox && (this.boundingBox = new xn), this.boundingBox.makeEmpty(); const t = e.getAttribute("position"); for (let e = 0; e < t.count; e++) this.getVertexPosition(e, Kr), this.boundingBox.expandByPoint(Kr) } computeBoundingSphere() { const e = this.geometry; null === this.boundingSphere && (this.boundingSphere = new Fn), this.boundingSphere.makeEmpty(); const t = e.getAttribute("position"); for (let e = 0; e < t.count; e++) this.getVertexPosition(e, Kr), this.boundingSphere.expandByPoint(Kr) } copy(e, t) { return super.copy(e, t), this.bindMode = e.bindMode, this.bindMatrix.copy(e.bindMatrix), this.bindMatrixInverse.copy(e.bindMatrixInverse), this.skeleton = e.skeleton, null !== e.boundingBox && (this.boundingBox = e.boundingBox.clone()), null !== e.boundingSphere && (this.boundingSphere = e.boundingSphere.clone()), this } raycast(e, t) { const n = this.material, i = this.matrixWorld; void 0 !== n && (null === this.boundingSphere && this.computeBoundingSphere(), qr.copy(this.boundingSphere), qr.applyMatrix4(i), !1 !== e.ray.intersectsSphere(qr) && (Xr.copy(i).invert(), Zr.copy(e.ray).applyMatrix4(Xr), null !== this.boundingBox && !1 === Zr.intersectsBox(this.boundingBox) || this._computeIntersections(e, t, Zr))) } getVertexPosition(e, t) { return super.getVertexPosition(e, t), this.applyBoneTransform(e, t), t } bind(e, t) { this.skeleton = e, void 0 === t && (this.updateMatrixWorld(!0), this.skeleton.calculateInverses(), t = this.matrixWorld), this.bindMatrix.copy(t), this.bindMatrixInverse.copy(t).invert() } pose() { this.skeleton.pose() } normalizeSkinWeights() { const e = new pn, t = this.geometry.attributes.skinWeight; for (let n = 0, i = t.count; n < i; n++) { e.fromBufferAttribute(t, n); const i = 1 / e.manhattanLength(); i !== 1 / 0 ? e.multiplyScalar(i) : e.set(1, 0, 0, 0), t.setXYZW(n, e.x, e.y, e.z, e.w) } } updateMatrixWorld(e) { super.updateMatrixWorld(e), this.bindMode === J ? this.bindMatrixInverse.copy(this.matrixWorld).invert() : "detached" === this.bindMode ? this.bindMatrixInverse.copy(this.bindMatrix).invert() : console.warn("THREE.SkinnedMesh: Unrecognized bindMode: " + this.bindMode) } applyBoneTransform(e, t) { const n = this.skeleton, i = this.geometry; Gr.fromBufferAttribute(i.attributes.skinIndex, e), jr.fromBufferAttribute(i.attributes.skinWeight, e), Hr.copy(t).applyMatrix4(this.bindMatrix), t.set(0, 0, 0); for (let e = 0; e < 4; e++) { const i = jr.getComponent(e); if (0 !== i) { const r = Gr.getComponent(e); Yr.multiplyMatrices(n.bones[r].matrixWorld, n.boneInverses[r]), t.addScaledVector(Qr.copy(Hr).applyMatrix4(Yr), i) } } return t.applyMatrix4(this.bindMatrixInverse) } } class $r extends xi { constructor() { super(), this.isBone = !0, this.type = "Bone" } } class ea extends un { constructor(e = null, t = 1, n = 1, i, r, a, s, o, l = 1003, c = 1003, h, d) { super(null, a, s, o, l, c, i, r, h, d), this.isDataTexture = !0, this.image = { data: e, width: t, height: n }, this.generateMipmaps = !1, this.flipY = !1, this.unpackAlignment = 1 } } const ta = new qn, na = new qn; class ia { constructor(e = [], t = []) { this.uuid = zt(), this.bones = e.slice(0), this.boneInverses = t, this.boneMatrices = null, this.boneTexture = null, this.init() } init() { const e = this.bones, t = this.boneInverses; if (this.boneMatrices = new Float32Array(16 * e.length), 0 === t.length) this.calculateInverses(); else if (e.length !== t.length) { console.warn("THREE.Skeleton: Number of inverse bone matrices does not match amount of bones."), this.boneInverses = []; for (let e = 0, t = this.bones.length; e < t; e++) this.boneInverses.push(new qn) } } calculateInverses() { this.boneInverses.length = 0; for (let e = 0, t = this.bones.length; e < t; e++) { const t = new qn; this.bones[e] && t.copy(this.bones[e].matrixWorld).invert(), this.boneInverses.push(t) } } pose() { for (let e = 0, t = this.bones.length; e < t; e++) { const t = this.bones[e]; t && t.matrixWorld.copy(this.boneInverses[e]).invert() } for (let e = 0, t = this.bones.length; e < t; e++) { const t = this.bones[e]; t && (t.parent && t.parent.isBone ? (t.matrix.copy(t.parent.matrixWorld).invert(), t.matrix.multiply(t.matrixWorld)) : t.matrix.copy(t.matrixWorld), t.matrix.decompose(t.position, t.quaternion, t.scale)) } } update() { const e = this.bones, t = this.boneInverses, n = this.boneMatrices, i = this.boneTexture; for (let i = 0, r = e.length; i < r; i++) { const r = e[i] ? e[i].matrixWorld : na; ta.multiplyMatrices(r, t[i]), ta.toArray(n, 16 * i) } null !== i && (i.needsUpdate = !0) } clone() { return new ia(this.bones, this.boneInverses) } computeBoneTexture() { let e = Math.sqrt(4 * this.bones.length); e = 4 * Math.ceil(e / 4), e = Math.max(e, 4); const t = new Float32Array(e * e * 4); t.set(this.boneMatrices); const n = new ea(t, e, e, Se, ye); return n.needsUpdate = !0, this.boneMatrices = t, this.boneTexture = n, this } getBoneByName(e) { for (let t = 0, n = this.bones.length; t < n; t++) { const n = this.bones[t]; if (n.name === e) return n } } dispose() { null !== this.boneTexture && (this.boneTexture.dispose(), this.boneTexture = null) } fromJSON(e, t) { this.uuid = e.uuid; for (let n = 0, i = e.bones.length; n < i; n++) { const i = e.bones[n]; let r = t[i]; void 0 === r && (console.warn("THREE.Skeleton: No bone found with UUID:", i), r = new $r), this.bones.push(r), this.boneInverses.push((new qn).fromArray(e.boneInverses[n])) } return this.init(), this } toJSON() { const e = { metadata: { version: 4.6, type: "Skeleton", generator: "Skeleton.toJSON" }, bones: [], boneInverses: [] }; e.uuid = this.uuid; const t = this.bones, n = this.boneInverses; for (let i = 0, r = t.length; i < r; i++) { const r = t[i]; e.bones.push(r.uuid); const a = n[i]; e.boneInverses.push(a.toArray()) } return e } } class ra extends qi { constructor(e, t, n, i = 1) { super(e, t, n), this.isInstancedBufferAttribute = !0, this.meshPerAttribute = i } copy(e) { return super.copy(e), this.meshPerAttribute = e.meshPerAttribute, this } toJSON() { const e = super.toJSON(); return e.meshPerAttribute = this.meshPerAttribute, e.isInstancedBufferAttribute = !0, e } } const aa = new qn, sa = new qn, oa = [], la = new xn, ca = new qn, ha = new wr, da = new Fn; class ua extends wr { constructor(e, t, n) { super(e, t), this.isInstancedMesh = !0, this.instanceMatrix = new ra(new Float32Array(16 * n), 16), this.instanceColor = null, this.morphTexture = null, this.count = n, this.boundingBox = null, this.boundingSphere = null; for (let e = 0; e < n; e++) this.setMatrixAt(e, ca) } computeBoundingBox() { const e = this.geometry, t = this.count; null === this.boundingBox && (this.boundingBox = new xn), null === e.boundingBox && e.computeBoundingBox(), this.boundingBox.makeEmpty(); for (let n = 0; n < t; n++) this.getMatrixAt(n, aa), la.copy(e.boundingBox).applyMatrix4(aa), this.boundingBox.union(la) } computeBoundingSphere() { const e = this.geometry, t = this.count; null === this.boundingSphere && (this.boundingSphere = new Fn), null === e.boundingSphere && e.computeBoundingSphere(), this.boundingSphere.makeEmpty(); for (let n = 0; n < t; n++) this.getMatrixAt(n, aa), da.copy(e.boundingSphere).applyMatrix4(aa), this.boundingSphere.union(da) } copy(e, t) { return super.copy(e, t), this.instanceMatrix.copy(e.instanceMatrix), null !== e.morphTexture && (this.morphTexture = e.morphTexture.clone()), null !== e.instanceColor && (this.instanceColor = e.instanceColor.clone()), this.count = e.count, null !== e.boundingBox && (this.boundingBox = e.boundingBox.clone()), null !== e.boundingSphere && (this.boundingSphere = e.boundingSphere.clone()), this } getColorAt(e, t) { t.fromArray(this.instanceColor.array, 3 * e) } getMatrixAt(e, t) { t.fromArray(this.instanceMatrix.array, 16 * e) } getMorphAt(e, t) { const n = t.morphTargetInfluences, i = this.morphTexture.source.data.data, r = e * (n.length + 1) + 1; for (let e = 0; e < n.length; e++) n[e] = i[r + e] } raycast(e, t) { const n = this.matrixWorld, i = this.count; if (ha.geometry = this.geometry, ha.material = this.material, void 0 !== ha.material && (null === this.boundingSphere && this.computeBoundingSphere(), da.copy(this.boundingSphere), da.applyMatrix4(n), !1 !== e.ray.intersectsSphere(da))) for (let r = 0; r < i; r++) { this.getMatrixAt(r, aa), sa.multiplyMatrices(n, aa), ha.matrixWorld = sa, ha.raycast(e, oa); for (let e = 0, n = oa.length; e < n; e++) { const n = oa[e]; n.instanceId = r, n.object = this, t.push(n) } oa.length = 0 } } setColorAt(e, t) { null === this.instanceColor && (this.instanceColor = new ra(new Float32Array(3 * this.instanceMatrix.count).fill(1), 3)), t.toArray(this.instanceColor.array, 3 * e) } setMatrixAt(e, t) { t.toArray(this.instanceMatrix.array, 16 * e) } setMorphAt(e, t) { const n = t.morphTargetInfluences, i = n.length + 1; null === this.morphTexture && (this.morphTexture = new ea(new Float32Array(i * this.count), i, this.count, _e, ye)); const r = this.morphTexture.source.data.data; let a = 0; for (let e = 0; e < n.length; e++) a += n[e]; const s = this.geometry.morphTargetsRelative ? 1 : 1 - a, o = i * e; r[o] = s, r.set(n, o + 1) } updateMorphTargets() {} dispose() { this.dispatchEvent({ type: "dispose" }), null !== this.morphTexture && (this.morphTexture.dispose(), this.morphTexture = null) } } const pa = new yn, fa = new yn, ma = new Qt; class ga { constructor(e = new yn(1, 0, 0), t = 0) { this.isPlane = !0, this.normal = e, this.constant = t } set(e, t) { return this.normal.copy(e), this.constant = t, this } setComponents(e, t, n, i) { return this.normal.set(e, t, n), this.constant = i, this } setFromNormalAndCoplanarPoint(e, t) { return this.normal.copy(e), this.constant = -t.dot(this.normal), this } setFromCoplanarPoints(e, t, n) { const i = pa.subVectors(n, t).cross(fa.subVectors(e, t)).normalize(); return this.setFromNormalAndCoplanarPoint(i, e), this } copy(e) { return this.normal.copy(e.normal), this.constant = e.constant, this } normalize() { const e = 1 / this.normal.length(); return this.normal.multiplyScalar(e), this.constant *= e, this } negate() { return this.constant *= -1, this.normal.negate(), this } distanceToPoint(e) { return this.normal.dot(e) + this.constant } distanceToSphere(e) { return this.distanceToPoint(e.center) - e.radius } projectPoint(e, t) { return t.copy(e).addScaledVector(this.normal, -this.distanceToPoint(e)) } intersectLine(e, t) { const n = e.delta(pa), i = this.normal.dot(n); if (0 === i) return 0 === this.distanceToPoint(e.start) ? t.copy(e.start) : null; const r = -(e.start.dot(this.normal) + this.constant) / i; return r < 0 || r > 1 ? null : t.copy(e.start).addScaledVector(n, r) } intersectsLine(e) { const t = this.distanceToPoint(e.start), n = this.distanceToPoint(e.end); return t < 0 && n > 0 || n < 0 && t > 0 } intersectsBox(e) { return e.intersectsPlane(this) } intersectsSphere(e) { return e.intersectsPlane(this) } coplanarPoint(e) { return e.copy(this.normal).multiplyScalar(-this.constant) } applyMatrix4(e, t) { const n = t || ma.getNormalMatrix(e), i = this.coplanarPoint(pa).applyMatrix4(e), r = this.normal.applyMatrix3(n).normalize(); return this.constant = -i.dot(r), this } translate(e) { return this.constant -= e.dot(this.normal), this } equals(e) { return e.normal.equals(this.normal) && e.constant === this.constant } clone() { return (new this.constructor).copy(this) } } const va = new Fn, wa = new yn; class ya { constructor(e = new ga, t = new ga, n = new ga, i = new ga, r = new ga, a = new ga) { this.planes = [e, t, n, i, r, a] } set(e, t, n, i, r, a) { const s = this.planes; return s[0].copy(e), s[1].copy(t), s[2].copy(n), s[3].copy(i), s[4].copy(r), s[5].copy(a), this } copy(e) { const t = this.planes; for (let n = 0; n < 6; n++) t[n].copy(e.planes[n]); return this } setFromProjectionMatrix(e, t = 2e3) { const n = this.planes, i = e.elements, r = i[0], a = i[1], s = i[2], o = i[3], l = i[4], c = i[5], h = i[6], d = i[7], u = i[8], p = i[9], f = i[10], m = i[11], g = i[12], v = i[13], w = i[14], y = i[15]; if (n[0].setComponents(o - r, d - l, m - u, y - g).normalize(), n[1].setComponents(o + r, d + l, m + u, y + g).normalize(), n[2].setComponents(o + a, d + c, m + p, y + v).normalize(), n[3].setComponents(o - a, d - c, m - p, y - v).normalize(), n[4].setComponents(o - s, d - h, m - f, y - w).normalize(), t === It) n[5].setComponents(o + s, d + h, m + f, y + w).normalize(); else { if (t !== Rt) throw new Error("THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: " + t); n[5].setComponents(s, h, f, w).normalize() } return this } intersectsObject(e) { if (void 0 !== e.boundingSphere) null === e.boundingSphere && e.computeBoundingSphere(), va.copy(e.boundingSphere).applyMatrix4(e.matrixWorld); else { const t = e.geometry; null === t.boundingSphere && t.computeBoundingSphere(), va.copy(t.boundingSphere).applyMatrix4(e.matrixWorld) } return this.intersectsSphere(va) } intersectsSprite(e) { return va.center.set(0, 0, 0), va.radius = .7071067811865476, va.applyMatrix4(e.matrixWorld), this.intersectsSphere(va) } intersectsSphere(e) { const t = this.planes, n = e.center, i = -e.radius; for (let e = 0; e < 6; e++) { if (t[e].distanceToPoint(n) < i) return !1 } return !0 } intersectsBox(e) { const t = this.planes; for (let n = 0; n < 6; n++) { const i = t[n]; if (wa.x = i.normal.x > 0 ? e.max.x : e.min.x, wa.y = i.normal.y > 0 ? e.max.y : e.min.y, wa.z = i.normal.z > 0 ? e.max.z : e.min.z, i.distanceToPoint(wa) < 0) return !1 } return !0 } containsPoint(e) { const t = this.planes; for (let n = 0; n < 6; n++) if (t[n].distanceToPoint(e) < 0) return !1; return !0 } clone() { return (new this.constructor).copy(this) } } class Aa extends Gi { constructor(e) { super(), this.isLineBasicMaterial = !0, this.type = "LineBasicMaterial", this.color = new Wi(16777215), this.map = null, this.linewidth = 1, this.linecap = "round", this.linejoin = "round", this.fog = !0, this.setValues(e) } copy(e) { return super.copy(e), this.color.copy(e.color), this.map = e.map, this.linewidth = e.linewidth, this.linecap = e.linecap, this.linejoin = e.linejoin, this.fog = e.fog, this } } const ba = new yn, xa = new yn, ka = new qn, Ea = new Kn, Sa = new Fn, Ma = new yn, Ta = new yn; class _a extends xi { constructor(e = new sr, t = new Aa) { super(), this.isLine = !0, this.type = "Line", this.geometry = e, this.material = t, this.morphTargetDictionary = void 0, this.morphTargetInfluences = void 0, this.updateMorphTargets() } copy(e, t) { return super.copy(e, t), this.material = Array.isArray(e.material) ? e.material.slice() : e.material, this.geometry = e.geometry, this } computeLineDistances() { const e = this.geometry; if (null === e.index) { const t = e.attributes.position, n = [0]; for (let e = 1, i = t.count; e < i; e++) ba.fromBufferAttribute(t, e - 1), xa.fromBufferAttribute(t, e), n[e] = n[e - 1], n[e] += ba.distanceTo(xa); e.setAttribute("lineDistance", new Ji(n, 1)) } else console.warn("THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry."); return this } raycast(e, t) { const n = this.geometry, i = this.matrixWorld, r = e.params.Line.threshold, a = n.drawRange; if (null === n.boundingSphere && n.computeBoundingSphere(), Sa.copy(n.boundingSphere), Sa.applyMatrix4(i), Sa.radius += r, !1 === e.ray.intersectsSphere(Sa)) return; ka.copy(i).invert(), Ea.copy(e.ray).applyMatrix4(ka); const s = r / ((this.scale.x + this.scale.y + this.scale.z) / 3), o = s * s, l = this.isLineSegments ? 2 : 1, c = n.index, h = n.attributes.position; if (null !== c) { const n = Math.max(0, a.start), i = Math.min(c.count, a.start + a.count); for (let r = n, a = i - 1; r < a; r += l) { const n = c.getX(r), i = c.getX(r + 1), a = Ca(this, e, Ea, o, n, i, r); a && t.push(a) } if (this.isLineLoop) { const r = c.getX(i - 1), a = c.getX(n), s = Ca(this, e, Ea, o, r, a, i - 1); s && t.push(s) } } else { const n = Math.max(0, a.start), i = Math.min(h.count, a.start + a.count); for (let r = n, a = i - 1; r < a; r += l) { const n = Ca(this, e, Ea, o, r, r + 1, r); n && t.push(n) } if (this.isLineLoop) { const r = Ca(this, e, Ea, o, i - 1, n, i - 1); r && t.push(r) } } } updateMorphTargets() { const e = this.geometry.morphAttributes, t = Object.keys(e); if (t.length > 0) { const n = e[t[0]]; if (void 0 !== n) { this.morphTargetInfluences = [], this.morphTargetDictionary = {}; for (let e = 0, t = n.length; e < t; e++) { const t = n[e].name || String(e); this.morphTargetInfluences.push(0), this.morphTargetDictionary[t] = e } } } } } function Ca(e, t, n, i, r, a, s) { const o = e.geometry.attributes.position; ba.fromBufferAttribute(o, r), xa.fromBufferAttribute(o, a); if (n.distanceSqToSegment(ba, xa, Ma, Ta) > i) return; Ma.applyMatrix4(e.matrixWorld); const l = t.ray.origin.distanceTo(Ma); return l < t.near || l > t.far ? void 0 : { distance: l, point: Ta.clone().applyMatrix4(e.matrixWorld), index: s, face: null, faceIndex: null, barycoord: null, object: e } } const Pa = new yn, Ia = new yn; class Ra extends _a { constructor(e, t) { super(e, t), this.isLineSegments = !0, this.type = "LineSegments" } computeLineDistances() { const e = this.geometry; if (null === e.index) { const t = e.attributes.position, n = []; for (let e = 0, i = t.count; e < i; e += 2) Pa.fromBufferAttribute(t, e), Ia.fromBufferAttribute(t, e + 1), n[e] = 0 === e ? 0 : n[e - 1], n[e + 1] = n[e] + Pa.distanceTo(Ia); e.setAttribute("lineDistance", new Ji(n, 1)) } else console.warn("THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry."); return this } } class La extends _a { constructor(e, t) { super(e, t), this.isLineLoop = !0, this.type = "LineLoop" } } class Da extends Gi { constructor(e) { super(), this.isPointsMaterial = !0, this.type = "PointsMaterial", this.color = new Wi(16777215), this.map = null, this.alphaMap = null, this.size = 1, this.sizeAttenuation = !0, this.fog = !0, this.setValues(e) } copy(e) { return super.copy(e), this.color.copy(e.color), this.map = e.map, this.alphaMap = e.alphaMap, this.size = e.size, this.sizeAttenuation = e.sizeAttenuation, this.fog = e.fog, this } } const Na = new qn, Ba = new Kn, Ua = new Fn, za = new yn; class Oa extends xi { constructor(e = new sr, t = new Da) { super(), this.isPoints = !0, this.type = "Points", this.geometry = e, this.material = t, this.morphTargetDictionary = void 0, this.morphTargetInfluences = void 0, this.updateMorphTargets() } copy(e, t) { return super.copy(e, t), this.material = Array.isArray(e.material) ? e.material.slice() : e.material, this.geometry = e.geometry, this } raycast(e, t) { const n = this.geometry, i = this.matrixWorld, r = e.params.Points.threshold, a = n.drawRange; if (null === n.boundingSphere && n.computeBoundingSphere(), Ua.copy(n.boundingSphere), Ua.applyMatrix4(i), Ua.radius += r, !1 === e.ray.intersectsSphere(Ua)) return; Na.copy(i).invert(), Ba.copy(e.ray).applyMatrix4(Na); const s = r / ((this.scale.x + this.scale.y + this.scale.z) / 3), o = s * s, l = n.index, c = n.attributes.position; if (null !== l) { for (let n = Math.max(0, a.start), r = Math.min(l.count, a.start + a.count); n < r; n++) { const r = l.getX(n); za.fromBufferAttribute(c, r), Fa(za, r, o, i, e, t, this) } } else { for (let n = Math.max(0, a.start), r = Math.min(c.count, a.start + a.count); n < r; n++) za.fromBufferAttribute(c, n), Fa(za, n, o, i, e, t, this) } } updateMorphTargets() { const e = this.geometry.morphAttributes, t = Object.keys(e); if (t.length > 0) { const n = e[t[0]]; if (void 0 !== n) { this.morphTargetInfluences = [], this.morphTargetDictionary = {}; for (let e = 0, t = n.length; e < t; e++) { const t = n[e].name || String(e); this.morphTargetInfluences.push(0), this.morphTargetDictionary[t] = e } } } } } function Fa(e, t, n, i, r, a, s) { const o = Ba.distanceSqToPoint(e); if (o < n) { const n = new yn; Ba.closestPointToPoint(e, n), n.applyMatrix4(i); const l = r.ray.origin.distanceTo(n); if (l < r.near || l > r.far) return; a.push({ distance: l, distanceToRay: Math.sqrt(o), point: n, index: t, face: null, faceIndex: null, barycoord: null, object: s }) } } class Wa extends un { constructor(e, t, n, i, r, a, s, o, l, c = 1026) { if (c !== Me && c !== Te) throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat"); void 0 === n && c === Me && (n = we), void 0 === n && c === Te && (n = ke), super(null, i, r, a, s, o, c, n, l), this.isDepthTexture = !0, this.image = { width: e, height: t }, this.magFilter = void 0 !== s ? s : oe, this.minFilter = void 0 !== o ? o : oe, this.flipY = !1, this.generateMipmaps = !1, this.compareFunction = null } copy(e) { return super.copy(e), this.source = new cn(Object.assign({}, e.image)), this.compareFunction = e.compareFunction, this } toJSON(e) { const t = super.toJSON(e); return null !== this.compareFunction && (t.compareFunction = this.compareFunction), t } } class Va { constructor() { this.type = "Curve", this.arcLengthDivisions = 200, this.needsUpdate = !1, this.cacheArcLengths = null } getPoint() { console.warn("THREE.Curve: .getPoint() not implemented.") } getPointAt(e, t) { const n = this.getUtoTmapping(e); return this.getPoint(n, t) } getPoints(e = 5) { const t = []; for (let n = 0; n <= e; n++) t.push(this.getPoint(n / e)); return t } getSpacedPoints(e = 5) { const t = []; for (let n = 0; n <= e; n++) t.push(this.getPointAt(n / e)); return t } getLength() { const e = this.getLengths(); return e[e.length - 1] } getLengths(e = this.arcLengthDivisions) { if (this.cacheArcLengths && this.cacheArcLengths.length === e + 1 && !this.needsUpdate) return this.cacheArcLengths; this.needsUpdate = !1; const t = []; let n, i = this.getPoint(0), r = 0; t.push(0); for (let a = 1; a <= e; a++) n = this.getPoint(a / e), r += n.distanceTo(i), t.push(r), i = n; return this.cacheArcLengths = t, t } updateArcLengths() { this.needsUpdate = !0, this.getLengths() } getUtoTmapping(e, t = null) { const n = this.getLengths(); let i = 0; const r = n.length; let a; a = t || e * n[r - 1]; let s, o = 0, l = r - 1; for (; o <= l;) if (i = Math.floor(o + (l - o) / 2), s = n[i] - a, s < 0) o = i + 1; else { if (!(s > 0)) { l = i; break } l = i - 1 } if (i = l, n[i] === a) return i / (r - 1); const c = n[i]; return (i + (a - c) / (n[i + 1] - c)) / (r - 1) } getTangent(e, t) { const n = 1e-4; let i = e - n, r = e + n; i < 0 && (i = 0), r > 1 && (r = 1); const a = this.getPoint(i), s = this.getPoint(r), o = t || (a.isVector2 ? new jt : new yn); return o.copy(s).sub(a).normalize(), o } getTangentAt(e, t) { const n = this.getUtoTmapping(e); return this.getTangent(n, t) } computeFrenetFrames(e, t = !1) { const n = new yn, i = [], r = [], a = [], s = new yn, o = new qn; for (let t = 0; t <= e; t++) { const n = t / e; i[t] = this.getTangentAt(n, new yn) } r[0] = new yn, a[0] = new yn; let l = Number.MAX_VALUE; const c = Math.abs(i[0].x), h = Math.abs(i[0].y), d = Math.abs(i[0].z); c <= l && (l = c, n.set(1, 0, 0)), h <= l && (l = h, n.set(0, 1, 0)), d <= l && n.set(0, 0, 1), s.crossVectors(i[0], n).normalize(), r[0].crossVectors(i[0], s), a[0].crossVectors(i[0], r[0]); for (let t = 1; t <= e; t++) { if (r[t] = r[t - 1].clone(), a[t] = a[t - 1].clone(), s.crossVectors(i[t - 1], i[t]), s.length() > Number.EPSILON) { s.normalize(); const e = Math.acos(Ot(i[t - 1].dot(i[t]), -1, 1)); r[t].applyMatrix4(o.makeRotationAxis(s, e)) } a[t].crossVectors(i[t], r[t]) } if (!0 === t) { let t = Math.acos(Ot(r[0].dot(r[e]), -1, 1)); t /= e, i[0].dot(s.crossVectors(r[0], r[e])) > 0 && (t = -t); for (let n = 1; n <= e; n++) r[n].applyMatrix4(o.makeRotationAxis(i[n], t * n)), a[n].crossVectors(i[n], r[n]) } return { tangents: i, normals: r, binormals: a } } clone() { return (new this.constructor).copy(this) } copy(e) { return this.arcLengthDivisions = e.arcLengthDivisions, this } toJSON() { const e = { metadata: { version: 4.6, type: "Curve", generator: "Curve.toJSON" } }; return e.arcLengthDivisions = this.arcLengthDivisions, e.type = this.type, e } fromJSON(e) { return this.arcLengthDivisions = e.arcLengthDivisions, this } } class Ha extends Va { constructor(e = 0, t = 0, n = 1, i = 1, r = 0, a = 2 * Math.PI, s = !1, o = 0) { super(), this.isEllipseCurve = !0, this.type = "EllipseCurve", this.aX = e, this.aY = t, this.xRadius = n, this.yRadius = i, this.aStartAngle = r, this.aEndAngle = a, this.aClockwise = s, this.aRotation = o } getPoint(e, t = new jt) { const n = t, i = 2 * Math.PI; let r = this.aEndAngle - this.aStartAngle; const a = Math.abs(r) < Number.EPSILON; for (; r < 0;) r += i; for (; r > i;) r -= i; r < Number.EPSILON && (r = a ? 0 : i), !0 !== this.aClockwise || a || (r === i ? r = -i : r -= i); const s = this.aStartAngle + e * r; let o = this.aX + this.xRadius * Math.cos(s), l = this.aY + this.yRadius * Math.sin(s); if (0 !== this.aRotation) { const e = Math.cos(this.aRotation), t = Math.sin(this.aRotation), n = o - this.aX, i = l - this.aY; o = n * e - i * t + this.aX, l = n * t + i * e + this.aY } return n.set(o, l) } copy(e) { return super.copy(e), this.aX = e.aX, this.aY = e.aY, this.xRadius = e.xRadius, this.yRadius = e.yRadius, this.aStartAngle = e.aStartAngle, this.aEndAngle = e.aEndAngle, this.aClockwise = e.aClockwise, this.aRotation = e.aRotation, this } toJSON() { const e = super.toJSON(); return e.aX = this.aX, e.aY = this.aY, e.xRadius = this.xRadius, e.yRadius = this.yRadius, e.aStartAngle = this.aStartAngle, e.aEndAngle = this.aEndAngle, e.aClockwise = this.aClockwise, e.aRotation = this.aRotation, e } fromJSON(e) { return super.fromJSON(e), this.aX = e.aX, this.aY = e.aY, this.xRadius = e.xRadius, this.yRadius = e.yRadius, this.aStartAngle = e.aStartAngle, this.aEndAngle = e.aEndAngle, this.aClockwise = e.aClockwise, this.aRotation = e.aRotation, this } } function Ga() { let e = 0, t = 0, n = 0, i = 0; function r(r, a, s, o) { e = r, t = s, n = -3 * r + 3 * a - 2 * s - o, i = 2 * r - 2 * a + s + o } return { initCatmullRom: function(e, t, n, i, a) { r(t, n, a * (n - e), a * (i - t)) }, initNonuniformCatmullRom: function(e, t, n, i, a, s, o) { let l = (t - e) / a - (n - e) / (a + s) + (n - t) / s, c = (n - t) / s - (i - t) / (s + o) + (i - n) / o; l *= s, c *= s, r(t, n, l, c) }, calc: function(r) { const a = r * r; return e + t * r + n * a + i * (a * r) } } } const ja = new yn, Qa = new Ga, Ya = new Ga, Ka = new Ga; function qa(e, t, n, i, r) { const a = .5 * (i - t), s = .5 * (r - n), o = e * e; return (2 * n - 2 * i + a + s) * (e * o) + (-3 * n + 3 * i - 2 * a - s) * o + a * e + n } function Xa(e, t, n, i) { return function(e, t) { const n = 1 - e; return n * n * t }(e, t) + function(e, t) { return 2 * (1 - e) * e * t }(e, n) + function(e, t) { return e * e * t }(e, i) } function Za(e, t, n, i, r) { return function(e, t) { const n = 1 - e; return n * n * n * t }(e, t) + function(e, t) { const n = 1 - e; return 3 * n * n * e * t }(e, n) + function(e, t) { return 3 * (1 - e) * e * e * t }(e, i) + function(e, t) { return e * e * e * t }(e, r) } class Ja extends Va { constructor(e = new jt, t = new jt, n = new jt, i = new jt) { super(), this.isCubicBezierCurve = !0, this.type = "CubicBezierCurve", this.v0 = e, this.v1 = t, this.v2 = n, this.v3 = i } getPoint(e, t = new jt) { const n = t, i = this.v0, r = this.v1, a = this.v2, s = this.v3; return n.set(Za(e, i.x, r.x, a.x, s.x), Za(e, i.y, r.y, a.y, s.y)), n } copy(e) { return super.copy(e), this.v0.copy(e.v0), this.v1.copy(e.v1), this.v2.copy(e.v2), this.v3.copy(e.v3), this } toJSON() { const e = super.toJSON(); return e.v0 = this.v0.toArray(), e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e.v3 = this.v3.toArray(), e } fromJSON(e) { return super.fromJSON(e), this.v0.fromArray(e.v0), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this.v3.fromArray(e.v3), this } } class $a extends Va { constructor(e = new jt, t = new jt) { super(), this.isLineCurve = !0, this.type = "LineCurve", this.v1 = e, this.v2 = t } getPoint(e, t = new jt) { const n = t; return 1 === e ? n.copy(this.v2) : (n.copy(this.v2).sub(this.v1), n.multiplyScalar(e).add(this.v1)), n } getPointAt(e, t) { return this.getPoint(e, t) } getTangent(e, t = new jt) { return t.subVectors(this.v2, this.v1).normalize() } getTangentAt(e, t) { return this.getTangent(e, t) } copy(e) { return super.copy(e), this.v1.copy(e.v1), this.v2.copy(e.v2), this } toJSON() { const e = super.toJSON(); return e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e } fromJSON(e) { return super.fromJSON(e), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this } } class es extends Va { constructor(e = new jt, t = new jt, n = new jt) { super(), this.isQuadraticBezierCurve = !0, this.type = "QuadraticBezierCurve", this.v0 = e, this.v1 = t, this.v2 = n } getPoint(e, t = new jt) { const n = t, i = this.v0, r = this.v1, a = this.v2; return n.set(Xa(e, i.x, r.x, a.x), Xa(e, i.y, r.y, a.y)), n } copy(e) { return super.copy(e), this.v0.copy(e.v0), this.v1.copy(e.v1), this.v2.copy(e.v2), this } toJSON() { const e = super.toJSON(); return e.v0 = this.v0.toArray(), e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e } fromJSON(e) { return super.fromJSON(e), this.v0.fromArray(e.v0), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this } } class ts extends Va { constructor(e = new yn, t = new yn, n = new yn) { super(), this.isQuadraticBezierCurve3 = !0, this.type = "QuadraticBezierCurve3", this.v0 = e, this.v1 = t, this.v2 = n } getPoint(e, t = new yn) { const n = t, i = this.v0, r = this.v1, a = this.v2; return n.set(Xa(e, i.x, r.x, a.x), Xa(e, i.y, r.y, a.y), Xa(e, i.z, r.z, a.z)), n } copy(e) { return super.copy(e), this.v0.copy(e.v0), this.v1.copy(e.v1), this.v2.copy(e.v2), this } toJSON() { const e = super.toJSON(); return e.v0 = this.v0.toArray(), e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e } fromJSON(e) { return super.fromJSON(e), this.v0.fromArray(e.v0), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this } } class ns extends Va { constructor(e = []) { super(), this.isSplineCurve = !0, this.type = "SplineCurve", this.points = e } getPoint(e, t = new jt) { const n = t, i = this.points, r = (i.length - 1) * e, a = Math.floor(r), s = r - a, o = i[0 === a ? a : a - 1], l = i[a], c = i[a > i.length - 2 ? i.length - 1 : a + 1], h = i[a > i.length - 3 ? i.length - 1 : a + 2]; return n.set(qa(s, o.x, l.x, c.x, h.x), qa(s, o.y, l.y, c.y, h.y)), n } copy(e) { super.copy(e), this.points = []; for (let t = 0, n = e.points.length; t < n; t++) { const n = e.points[t]; this.points.push(n.clone()) } return this } toJSON() { const e = super.toJSON(); e.points = []; for (let t = 0, n = this.points.length; t < n; t++) { const n = this.points[t]; e.points.push(n.toArray()) } return e } fromJSON(e) { super.fromJSON(e), this.points = []; for (let t = 0, n = e.points.length; t < n; t++) { const n = e.points[t]; this.points.push((new jt).fromArray(n)) } return this } } var is = Object.freeze({ __proto__: null, ArcCurve: class extends Ha { constructor(e, t, n, i, r, a) { super(e, t, n, n, i, r, a), this.isArcCurve = !0, this.type = "ArcCurve" } }, CatmullRomCurve3: class extends Va { constructor(e = [], t = !1, n = "centripetal", i = .5) { super(), this.isCatmullRomCurve3 = !0, this.type = "CatmullRomCurve3", this.points = e, this.closed = t, this.curveType = n, this.tension = i } getPoint(e, t = new yn) { const n = t, i = this.points, r = i.length, a = (r - (this.closed ? 0 : 1)) * e; let s, o, l = Math.floor(a), c = a - l; this.closed ? l += l > 0 ? 0 : (Math.floor(Math.abs(l) / r) + 1) * r : 0 === c && l === r - 1 && (l = r - 2, c = 1), this.closed || l > 0 ? s = i[(l - 1) % r] : (ja.subVectors(i[0], i[1]).add(i[0]), s = ja); const h = i[l % r], d = i[(l + 1) % r]; if (this.closed || l + 2 < r ? o = i[(l + 2) % r] : (ja.subVectors(i[r - 1], i[r - 2]).add(i[r - 1]), o = ja), "centripetal" === this.curveType || "chordal" === this.curveType) { const e = "chordal" === this.curveType ? .5 : .25; let t = Math.pow(s.distanceToSquared(h), e), n = Math.pow(h.distanceToSquared(d), e), i = Math.pow(d.distanceToSquared(o), e); n < 1e-4 && (n = 1), t < 1e-4 && (t = n), i < 1e-4 && (i = n), Qa.initNonuniformCatmullRom(s.x, h.x, d.x, o.x, t, n, i), Ya.initNonuniformCatmullRom(s.y, h.y, d.y, o.y, t, n, i), Ka.initNonuniformCatmullRom(s.z, h.z, d.z, o.z, t, n, i) } else "catmullrom" === this.curveType && (Qa.initCatmullRom(s.x, h.x, d.x, o.x, this.tension), Ya.initCatmullRom(s.y, h.y, d.y, o.y, this.tension), Ka.initCatmullRom(s.z, h.z, d.z, o.z, this.tension)); return n.set(Qa.calc(c), Ya.calc(c), Ka.calc(c)), n } copy(e) { super.copy(e), this.points = []; for (let t = 0, n = e.points.length; t < n; t++) { const n = e.points[t]; this.points.push(n.clone()) } return this.closed = e.closed, this.curveType = e.curveType, this.tension = e.tension, this } toJSON() { const e = super.toJSON(); e.points = []; for (let t = 0, n = this.points.length; t < n; t++) { const n = this.points[t]; e.points.push(n.toArray()) } return e.closed = this.closed, e.curveType = this.curveType, e.tension = this.tension, e } fromJSON(e) { super.fromJSON(e), this.points = []; for (let t = 0, n = e.points.length; t < n; t++) { const n = e.points[t]; this.points.push((new yn).fromArray(n)) } return this.closed = e.closed, this.curveType = e.curveType, this.tension = e.tension, this } }, CubicBezierCurve: Ja, CubicBezierCurve3: class extends Va { constructor(e = new yn, t = new yn, n = new yn, i = new yn) { super(), this.isCubicBezierCurve3 = !0, this.type = "CubicBezierCurve3", this.v0 = e, this.v1 = t, this.v2 = n, this.v3 = i } getPoint(e, t = new yn) { const n = t, i = this.v0, r = this.v1, a = this.v2, s = this.v3; return n.set(Za(e, i.x, r.x, a.x, s.x), Za(e, i.y, r.y, a.y, s.y), Za(e, i.z, r.z, a.z, s.z)), n } copy(e) { return super.copy(e), this.v0.copy(e.v0), this.v1.copy(e.v1), this.v2.copy(e.v2), this.v3.copy(e.v3), this } toJSON() { const e = super.toJSON(); return e.v0 = this.v0.toArray(), e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e.v3 = this.v3.toArray(), e } fromJSON(e) { return super.fromJSON(e), this.v0.fromArray(e.v0), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this.v3.fromArray(e.v3), this } }, EllipseCurve: Ha, LineCurve: $a, LineCurve3: class extends Va { constructor(e = new yn, t = new yn) { super(), this.isLineCurve3 = !0, this.type = "LineCurve3", this.v1 = e, this.v2 = t } getPoint(e, t = new yn) { const n = t; return 1 === e ? n.copy(this.v2) : (n.copy(this.v2).sub(this.v1), n.multiplyScalar(e).add(this.v1)), n } getPointAt(e, t) { return this.getPoint(e, t) } getTangent(e, t = new yn) { return t.subVectors(this.v2, this.v1).normalize() } getTangentAt(e, t) { return this.getTangent(e, t) } copy(e) { return super.copy(e), this.v1.copy(e.v1), this.v2.copy(e.v2), this } toJSON() { const e = super.toJSON(); return e.v1 = this.v1.toArray(), e.v2 = this.v2.toArray(), e } fromJSON(e) { return super.fromJSON(e), this.v1.fromArray(e.v1), this.v2.fromArray(e.v2), this } }, QuadraticBezierCurve: es, QuadraticBezierCurve3: ts, SplineCurve: ns }); class rs extends Va { constructor() { super(), this.type = "CurvePath", this.curves = [], this.autoClose = !1 } add(e) { this.curves.push(e) } closePath() { const e = this.curves[0].getPoint(0), t = this.curves[this.curves.length - 1].getPoint(1); if (!e.equals(t)) { const n = !0 === e.isVector2 ? "LineCurve" : "LineCurve3"; this.curves.push(new is[n](t, e)) } return this } getPoint(e, t) { const n = e * this.getLength(), i = this.getCurveLengths(); let r = 0; for (; r < i.length;) { if (i[r] >= n) { const e = i[r] - n, a = this.curves[r], s = a.getLength(), o = 0 === s ? 0 : 1 - e / s; return a.getPointAt(o, t) } r++ } return null } getLength() { const e = this.getCurveLengths(); return e[e.length - 1] } updateArcLengths() { this.needsUpdate = !0, this.cacheLengths = null, this.getCurveLengths() } getCurveLengths() { if (this.cacheLengths && this.cacheLengths.length === this.curves.length) return this.cacheLengths; const e = []; let t = 0; for (let n = 0, i = this.curves.length; n < i; n++) t += this.curves[n].getLength(), e.push(t); return this.cacheLengths = e, e } getSpacedPoints(e = 40) { const t = []; for (let n = 0; n <= e; n++) t.push(this.getPoint(n / e)); return this.autoClose && t.push(t[0]), t } getPoints(e = 12) { const t = []; let n; for (let i = 0, r = this.curves; i < r.length; i++) { const a = r[i], s = a.isEllipseCurve ? 2 * e : a.isLineCurve || a.isLineCurve3 ? 1 : a.isSplineCurve ? e * a.points.length : e, o = a.getPoints(s); for (let e = 0; e < o.length; e++) { const i = o[e]; n && n.equals(i) || (t.push(i), n = i) } } return this.autoClose && t.length > 1 && !t[t.length - 1].equals(t[0]) && t.push(t[0]), t } copy(e) { super.copy(e), this.curves = []; for (let t = 0, n = e.curves.length; t < n; t++) { const n = e.curves[t]; this.curves.push(n.clone()) } return this.autoClose = e.autoClose, this } toJSON() { const e = super.toJSON(); e.autoClose = this.autoClose, e.curves = []; for (let t = 0, n = this.curves.length; t < n; t++) { const n = this.curves[t]; e.curves.push(n.toJSON()) } return e } fromJSON(e) { super.fromJSON(e), this.autoClose = e.autoClose, this.curves = []; for (let t = 0, n = e.curves.length; t < n; t++) { const n = e.curves[t]; this.curves.push((new is[n.type]).fromJSON(n)) } return this } } class as extends rs { constructor(e) { super(), this.type = "Path", this.currentPoint = new jt, e && this.setFromPoints(e) } setFromPoints(e) { this.moveTo(e[0].x, e[0].y); for (let t = 1, n = e.length; t < n; t++) this.lineTo(e[t].x, e[t].y); return this } moveTo(e, t) { return this.currentPoint.set(e, t), this } lineTo(e, t) { const n = new $a(this.currentPoint.clone(), new jt(e, t)); return this.curves.push(n), this.currentPoint.set(e, t), this } quadraticCurveTo(e, t, n, i) { const r = new es(this.currentPoint.clone(), new jt(e, t), new jt(n, i)); return this.curves.push(r), this.currentPoint.set(n, i), this } bezierCurveTo(e, t, n, i, r, a) { const s = new Ja(this.currentPoint.clone(), new jt(e, t), new jt(n, i), new jt(r, a)); return this.curves.push(s), this.currentPoint.set(r, a), this } splineThru(e) { const t = [this.currentPoint.clone()].concat(e), n = new ns(t); return this.curves.push(n), this.currentPoint.copy(e[e.length - 1]), this } arc(e, t, n, i, r, a) { const s = this.currentPoint.x, o = this.currentPoint.y; return this.absarc(e + s, t + o, n, i, r, a), this } absarc(e, t, n, i, r, a) { return this.absellipse(e, t, n, n, i, r, a), this } ellipse(e, t, n, i, r, a, s, o) { const l = this.currentPoint.x, c = this.currentPoint.y; return this.absellipse(e + l, t + c, n, i, r, a, s, o), this } absellipse(e, t, n, i, r, a, s, o) { const l = new Ha(e, t, n, i, r, a, s, o); if (this.curves.length > 0) { const e = l.getPoint(0); e.equals(this.currentPoint) || this.lineTo(e.x, e.y) } this.curves.push(l); const c = l.getPoint(1); return this.currentPoint.copy(c), this } copy(e) { return super.copy(e), this.currentPoint.copy(e.currentPoint), this } toJSON() { const e = super.toJSON(); return e.currentPoint = this.currentPoint.toArray(), e } fromJSON(e) { return super.fromJSON(e), this.currentPoint.fromArray(e.currentPoint), this } } class ss extends as { constructor(e) { super(e), this.uuid = zt(), this.type = "Shape", this.holes = [] } getPointsHoles(e) { const t = []; for (let n = 0, i = this.holes.length; n < i; n++) t[n] = this.holes[n].getPoints(e); return t } extractPoints(e) { return { shape: this.getPoints(e), holes: this.getPointsHoles(e) } } copy(e) { super.copy(e), this.holes = []; for (let t = 0, n = e.holes.length; t < n; t++) { const n = e.holes[t]; this.holes.push(n.clone()) } return this } toJSON() { const e = super.toJSON(); e.uuid = this.uuid, e.holes = []; for (let t = 0, n = this.holes.length; t < n; t++) { const n = this.holes[t]; e.holes.push(n.toJSON()) } return e } fromJSON(e) { super.fromJSON(e), this.uuid = e.uuid, this.holes = []; for (let t = 0, n = e.holes.length; t < n; t++) { const n = e.holes[t]; this.holes.push((new as).fromJSON(n)) } return this } } class os { static triangulate(e, t, n = 2) { const i = t && t.length, r = i ? t[0] * n : e.length; let a = ls(e, 0, r, n, !0); const s = []; if (!a || a.next === a.prev) return s; let o, l, c, h, d, u, p; if (i && (a = function(e, t, n, i) { const r = []; let a, s, o, l, c; for (a = 0, s = t.length; a < s; a++) o = t[a] * i, l = a < s - 1 ? t[a + 1] * i : e.length, c = ls(e, o, l, i, !1), c === c.next && (c.steiner = !0), r.push(ys(c)); for (r.sort(ms), a = 0; a < r.length; a++) n = gs(r[a], n); return n }(e, t, a, n)), e.length > 80 * n) { o = c = e[0], l = h = e[1]; for (let t = n; t < r; t += n) d = e[t], u = e[t + 1], d < o && (o = d), u < l && (l = u), d > c && (c = d), u > h && (h = u); p = Math.max(c - o, h - l), p = 0 !== p ? 32767 / p : 0 } return hs(a, s, n, o, l, p, 0), s } } function ls(e, t, n, i, r) { let a, s; if (r === function(e, t, n, i) { let r = 0; for (let a = t, s = n - i; a < n; a += i) r += (e[s] - e[a]) * (e[a + 1] + e[s + 1]), s = a; return r }(e, t, n, i) > 0) for (a = t; a < n; a += i) s = Cs(a, e[a], e[a + 1], s); else for (a = n - i; a >= t; a -= i) s = Cs(a, e[a], e[a + 1], s); return s && ks(s, s.next) && (Ps(s), s = s.next), s } function cs(e, t) { if (!e) return e; t || (t = e); let n, i = e; do { if (n = !1, i.steiner || !ks(i, i.next) && 0 !== xs(i.prev, i, i.next)) i = i.next; else { if (Ps(i), i = t = i.prev, i === i.next) break; n = !0 } } while (n || i !== t); return t } function hs(e, t, n, i, r, a, s) { if (!e) return; !s && a && function(e, t, n, i) { let r = e; do { 0 === r.z && (r.z = ws(r.x, r.y, t, n, i)), r.prevZ = r.prev, r.nextZ = r.next, r = r.next } while (r !== e); r.prevZ.nextZ = null, r.prevZ = null, function(e) { let t, n, i, r, a, s, o, l, c = 1; do { for (n = e, e = null, a = null, s = 0; n;) { for (s++, i = n, o = 0, t = 0; t < c && (o++, i = i.nextZ, i); t++); for (l = c; o > 0 || l > 0 && i;) 0 !== o && (0 === l || !i || n.z <= i.z) ? (r = n, n = n.nextZ, o--) : (r = i, i = i.nextZ, l--), a ? a.nextZ = r : e = r, r.prevZ = a, a = r; n = i } a.nextZ = null, c *= 2 } while (s > 1) }(r) }(e, i, r, a); let o, l, c = e; for (; e.prev !== e.next;) if (o = e.prev, l = e.next, a ? us(e, i, r, a) : ds(e)) t.push(o.i / n | 0), t.push(e.i / n | 0), t.push(l.i / n | 0), Ps(e), e = l.next, c = l.next; else if ((e = l) === c) { s ? 1 === s ? hs(e = ps(cs(e), t, n), t, n, i, r, a, 2) : 2 === s && fs(e, t, n, i, r, a) : hs(cs(e), t, n, i, r, a, 1); break } } function ds(e) { const t = e.prev, n = e, i = e.next; if (xs(t, n, i) >= 0) return !1; const r = t.x, a = n.x, s = i.x, o = t.y, l = n.y, c = i.y, h = r < a ? r < s ? r : s : a < s ? a : s, d = o < l ? o < c ? o : c : l < c ? l : c, u = r > a ? r > s ? r : s : a > s ? a : s, p = o > l ? o > c ? o : c : l > c ? l : c; let f = i.next; for (; f !== t;) { if (f.x >= h && f.x <= u && f.y >= d && f.y <= p && As(r, o, a, l, s, c, f.x, f.y) && xs(f.prev, f, f.next) >= 0) return !1; f = f.next } return !0 } function us(e, t, n, i) { const r = e.prev, a = e, s = e.next; if (xs(r, a, s) >= 0) return !1; const o = r.x, l = a.x, c = s.x, h = r.y, d = a.y, u = s.y, p = o < l ? o < c ? o : c : l < c ? l : c, f = h < d ? h < u ? h : u : d < u ? d : u, m = o > l ? o > c ? o : c : l > c ? l : c, g = h > d ? h > u ? h : u : d > u ? d : u, v = ws(p, f, t, n, i), w = ws(m, g, t, n, i); let y = e.prevZ, A = e.nextZ; for (; y && y.z >= v && A && A.z <= w;) { if (y.x >= p && y.x <= m && y.y >= f && y.y <= g && y !== r && y !== s && As(o, h, l, d, c, u, y.x, y.y) && xs(y.prev, y, y.next) >= 0) return !1; if (y = y.prevZ, A.x >= p && A.x <= m && A.y >= f && A.y <= g && A !== r && A !== s && As(o, h, l, d, c, u, A.x, A.y) && xs(A.prev, A, A.next) >= 0) return !1; A = A.nextZ } for (; y && y.z >= v;) { if (y.x >= p && y.x <= m && y.y >= f && y.y <= g && y !== r && y !== s && As(o, h, l, d, c, u, y.x, y.y) && xs(y.prev, y, y.next) >= 0) return !1; y = y.prevZ } for (; A && A.z <= w;) { if (A.x >= p && A.x <= m && A.y >= f && A.y <= g && A !== r && A !== s && As(o, h, l, d, c, u, A.x, A.y) && xs(A.prev, A, A.next) >= 0) return !1; A = A.nextZ } return !0 } function ps(e, t, n) { let i = e; do { const r = i.prev, a = i.next.next; !ks(r, a) && Es(r, i, i.next, a) && Ts(r, a) && Ts(a, r) && (t.push(r.i / n | 0), t.push(i.i / n | 0), t.push(a.i / n | 0), Ps(i), Ps(i.next), i = e = a), i = i.next } while (i !== e); return cs(i) } function fs(e, t, n, i, r, a) { let s = e; do { let e = s.next.next; for (; e !== s.prev;) { if (s.i !== e.i && bs(s, e)) { let o = _s(s, e); return s = cs(s, s.next), o = cs(o, o.next), hs(s, t, n, i, r, a, 0), void hs(o, t, n, i, r, a, 0) } e = e.next } s = s.next } while (s !== e) } function ms(e, t) { return e.x - t.x } function gs(e, t) { const n = function(e, t) { let n, i = t, r = -1 / 0; const a = e.x, s = e.y; do { if (s <= i.y && s >= i.next.y && i.next.y !== i.y) { const e = i.x + (s - i.y) * (i.next.x - i.x) / (i.next.y - i.y); if (e <= a && e > r && (r = e, n = i.x < i.next.x ? i : i.next, e === a)) return n } i = i.next } while (i !== t); if (!n) return null; const o = n, l = n.x, c = n.y; let h, d = 1 / 0; i = n; do { a >= i.x && i.x >= l && a !== i.x && As(s < c ? a : r, s, l, c, s < c ? r : a, s, i.x, i.y) && (h = Math.abs(s - i.y) / (a - i.x), Ts(i, e) && (h < d || h === d && (i.x > n.x || i.x === n.x && vs(n, i))) && (n = i, d = h)), i = i.next } while (i !== o); return n }(e, t); if (!n) return t; const i = _s(n, e); return cs(i, i.next), cs(n, n.next) } function vs(e, t) { return xs(e.prev, e, t.prev) < 0 && xs(t.next, e, e.next) < 0 } function ws(e, t, n, i, r) { return (e = 1431655765 & ((e = 858993459 & ((e = 252645135 & ((e = 16711935 & ((e = (e - n) * r | 0) | e << 8)) | e << 4)) | e << 2)) | e << 1)) | (t = 1431655765 & ((t = 858993459 & ((t = 252645135 & ((t = 16711935 & ((t = (t - i) * r | 0) | t << 8)) | t << 4)) | t << 2)) | t << 1)) << 1 } function ys(e) { let t = e, n = e; do { (t.x < n.x || t.x === n.x && t.y < n.y) && (n = t), t = t.next } while (t !== e); return n } function As(e, t, n, i, r, a, s, o) { return (r - s) * (t - o) >= (e - s) * (a - o) && (e - s) * (i - o) >= (n - s) * (t - o) && (n - s) * (a - o) >= (r - s) * (i - o) } function bs(e, t) { return e.next.i !== t.i && e.prev.i !== t.i && ! function(e, t) { let n = e; do { if (n.i !== e.i && n.next.i !== e.i && n.i !== t.i && n.next.i !== t.i && Es(n, n.next, e, t)) return !0; n = n.next } while (n !== e); return !1 }(e, t) && (Ts(e, t) && Ts(t, e) && function(e, t) { let n = e, i = !1; const r = (e.x + t.x) / 2, a = (e.y + t.y) / 2; do { n.y > a != n.next.y > a && n.next.y !== n.y && r < (n.next.x - n.x) * (a - n.y) / (n.next.y - n.y) + n.x && (i = !i), n = n.next } while (n !== e); return i }(e, t) && (xs(e.prev, e, t.prev) || xs(e, t.prev, t)) || ks(e, t) && xs(e.prev, e, e.next) > 0 && xs(t.prev, t, t.next) > 0) } function xs(e, t, n) { return (t.y - e.y) * (n.x - t.x) - (t.x - e.x) * (n.y - t.y) } function ks(e, t) { return e.x === t.x && e.y === t.y } function Es(e, t, n, i) { const r = Ms(xs(e, t, n)), a = Ms(xs(e, t, i)), s = Ms(xs(n, i, e)), o = Ms(xs(n, i, t)); return r !== a && s !== o || (!(0 !== r || !Ss(e, n, t)) || (!(0 !== a || !Ss(e, i, t)) || (!(0 !== s || !Ss(n, e, i)) || !(0 !== o || !Ss(n, t, i))))) } function Ss(e, t, n) { return t.x <= Math.max(e.x, n.x) && t.x >= Math.min(e.x, n.x) && t.y <= Math.max(e.y, n.y) && t.y >= Math.min(e.y, n.y) } function Ms(e) { return e > 0 ? 1 : e < 0 ? -1 : 0 } function Ts(e, t) { return xs(e.prev, e, e.next) < 0 ? xs(e, t, e.next) >= 0 && xs(e, e.prev, t) >= 0 : xs(e, t, e.prev) < 0 || xs(e, e.next, t) < 0 } function _s(e, t) { const n = new Is(e.i, e.x, e.y), i = new Is(t.i, t.x, t.y), r = e.next, a = t.prev; return e.next = t, t.prev = e, n.next = r, r.prev = n, i.next = n, n.prev = i, a.next = i, i.prev = a, i } function Cs(e, t, n, i) { const r = new Is(e, t, n); return i ? (r.next = i.next, r.prev = i, i.next.prev = r, i.next = r) : (r.prev = r, r.next = r), r } function Ps(e) { e.next.prev = e.prev, e.prev.next = e.next, e.prevZ && (e.prevZ.nextZ = e.nextZ), e.nextZ && (e.nextZ.prevZ = e.prevZ) } function Is(e, t, n) { this.i = e, this.x = t, this.y = n, this.prev = null, this.next = null, this.z = 0, this.prevZ = null, this.nextZ = null, this.steiner = !1 } class Rs { static area(e) { const t = e.length; let n = 0; for (let i = t - 1, r = 0; r < t; i = r++) n += e[i].x * e[r].y - e[r].x * e[i].y; return .5 * n } static isClockWise(e) { return Rs.area(e) < 0 } static triangulateShape(e, t) { const n = [], i = [], r = []; Ls(e), Ds(n, e); let a = e.length; t.forEach(Ls); for (let e = 0; e < t.length; e++) i.push(a), a += t[e].length, Ds(n, t[e]); const s = os.triangulate(n, i); for (let e = 0; e < s.length; e += 3) r.push(s.slice(e, e + 3)); return r } } function Ls(e) { const t = e.length; t > 2 && e[t - 1].equals(e[0]) && e.pop() } function Ds(e, t) { for (let n = 0; n < t.length; n++) e.push(t[n].x), e.push(t[n].y) } class Ns extends sr { constructor(e = 1, t = 1, n = 1, i = 1) { super(), this.type = "PlaneGeometry", this.parameters = { width: e, height: t, widthSegments: n, heightSegments: i }; const r = e / 2, a = t / 2, s = Math.floor(n), o = Math.floor(i), l = s + 1, c = o + 1, h = e / s, d = t / o, u = [], p = [], f = [], m = []; for (let e = 0; e < c; e++) { const t = e * d - a; for (let n = 0; n < l; n++) { const i = n * h - r; p.push(i, -t, 0), f.push(0, 0, 1), m.push(n / s), m.push(1 - e / o) } } for (let e = 0; e < o; e++) for (let t = 0; t < s; t++) { const n = t + l * e, i = t + l * (e + 1), r = t + 1 + l * (e + 1), a = t + 1 + l * e; u.push(n, i, a), u.push(i, r, a) } this.setIndex(u), this.setAttribute("position", new Ji(p, 3)), this.setAttribute("normal", new Ji(f, 3)), this.setAttribute("uv", new Ji(m, 2)) } copy(e) { return super.copy(e), this.parameters = Object.assign({}, e.parameters), this } static fromJSON(e) { return new Ns(e.width, e.height, e.widthSegments, e.heightSegments) } } class Bs extends sr { constructor(e = new ss([new jt(0, .5), new jt(-.5, -.5), new jt(.5, -.5)]), t = 12) { super(), this.type = "ShapeGeometry", this.parameters = { shapes: e, curveSegments: t }; const n = [], i = [], r = [], a = []; let s = 0, o = 0; if (!1 === Array.isArray(e)) l(e); else for (let t = 0; t < e.length; t++) l(e[t]), this.addGroup(s, o, t), s += o, o = 0; function l(e) { const s = i.length / 3, l = e.extractPoints(t); let c = l.shape; const h = l.holes; !1 === Rs.isClockWise(c) && (c = c.reverse()); for (let e = 0, t = h.length; e < t; e++) { const t = h[e]; !0 === Rs.isClockWise(t) && (h[e] = t.reverse()) } const d = Rs.triangulateShape(c, h); for (let e = 0, t = h.length; e < t; e++) { const t = h[e]; c = c.concat(t) } for (let e = 0, t = c.length; e < t; e++) { const t = c[e]; i.push(t.x, t.y, 0), r.push(0, 0, 1), a.push(t.x, t.y) } for (let e = 0, t = d.length; e < t; e++) { const t = d[e], i = t[0] + s, r = t[1] + s, a = t[2] + s; n.push(i, r, a), o += 3 } } this.setIndex(n), this.setAttribute("position", new Ji(i, 3)), this.setAttribute("normal", new Ji(r, 3)), this.setAttribute("uv", new Ji(a, 2)) } copy(e) { return super.copy(e), this.parameters = Object.assign({}, e.parameters), this } toJSON() { const e = super.toJSON(); return function(e, t) { if (t.shapes = [], Array.isArray(e)) for (let n = 0, i = e.length; n < i; n++) { const i = e[n]; t.shapes.push(i.uuid) } else t.shapes.push(e.uuid); return t }(this.parameters.shapes, e) } static fromJSON(e, t) { const n = []; for (let i = 0, r = e.shapes.length; i < r; i++) { const r = t[e.shapes[i]]; n.push(r) } return new Bs(n, e.curveSegments) } } class Us extends sr { constructor(e = 1, t = 32, n = 16, i = 0, r = 2 * Math.PI, a = 0, s = Math.PI) { super(), this.type = "SphereGeometry", this.parameters = { radius: e, widthSegments: t, heightSegments: n, phiStart: i, phiLength: r, thetaStart: a, thetaLength: s }, t = Math.max(3, Math.floor(t)), n = Math.max(2, Math.floor(n)); const o = Math.min(a + s, Math.PI); let l = 0; const c = [], h = new yn, d = new yn, u = [], p = [], f = [], m = []; for (let u = 0; u <= n; u++) { const g = [], v = u / n; let w = 0; 0 === u && 0 === a ? w = .5 / t : u === n && o === Math.PI && (w = -.5 / t); for (let n = 0; n <= t; n++) { const o = n / t; h.x = -e * Math.cos(i + o * r) * Math.sin(a + v * s), h.y = e * Math.cos(a + v * s), h.z = e * Math.sin(i + o * r) * Math.sin(a + v * s), p.push(h.x, h.y, h.z), d.copy(h).normalize(), f.push(d.x, d.y, d.z), m.push(o + w, 1 - v), g.push(l++) } c.push(g) } for (let e = 0; e < n; e++) for (let i = 0; i < t; i++) { const t = c[e][i + 1], r = c[e][i], s = c[e + 1][i], l = c[e + 1][i + 1]; (0 !== e || a > 0) && u.push(t, r, l), (e !== n - 1 || o < Math.PI) && u.push(r, s, l) } this.setIndex(u), this.setAttribute("position", new Ji(p, 3)), this.setAttribute("normal", new Ji(f, 3)), this.setAttribute("uv", new Ji(m, 2)) } copy(e) { return super.copy(e), this.parameters = Object.assign({}, e.parameters), this } static fromJSON(e) { return new Us(e.radius, e.widthSegments, e.heightSegments, e.phiStart, e.phiLength, e.thetaStart, e.thetaLength) } } class zs extends Gi { constructor(e) { super(), this.isMeshStandardMaterial = !0, this.type = "MeshStandardMaterial", this.defines = { STANDARD: "" }, this.color = new Wi(16777215), this.roughness = 1, this.metalness = 0, this.map = null, this.lightMap = null, this.lightMapIntensity = 1, this.aoMap = null, this.aoMapIntensity = 1, this.emissive = new Wi(0), this.emissiveIntensity = 1, this.emissiveMap = null, this.bumpMap = null, this.bumpScale = 1, this.normalMap = null, this.normalMapType = 0, this.normalScale = new jt(1, 1), this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.roughnessMap = null, this.metalnessMap = null, this.alphaMap = null, this.envMap = null, this.envMapRotation = new ai, this.envMapIntensity = 1, this.wireframe = !1, this.wireframeLinewidth = 1, this.wireframeLinecap = "round", this.wireframeLinejoin = "round", this.flatShading = !1, this.fog = !0, this.setValues(e) } copy(e) { return super.copy(e), this.defines = { STANDARD: "" }, this.color.copy(e.color), this.roughness = e.roughness, this.metalness = e.metalness, this.map = e.map, this.lightMap = e.lightMap, this.lightMapIntensity = e.lightMapIntensity, this.aoMap = e.aoMap, this.aoMapIntensity = e.aoMapIntensity, this.emissive.copy(e.emissive), this.emissiveMap = e.emissiveMap, this.emissiveIntensity = e.emissiveIntensity, this.bumpMap = e.bumpMap, this.bumpScale = e.bumpScale, this.normalMap = e.normalMap, this.normalMapType = e.normalMapType, this.normalScale.copy(e.normalScale), this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this.roughnessMap = e.roughnessMap, this.metalnessMap = e.metalnessMap, this.alphaMap = e.alphaMap, this.envMap = e.envMap, this.envMapRotation.copy(e.envMapRotation), this.envMapIntensity = e.envMapIntensity, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.wireframeLinecap = e.wireframeLinecap, this.wireframeLinejoin = e.wireframeLinejoin, this.flatShading = e.flatShading, this.fog = e.fog, this } } class Os extends zs { constructor(e) { super(), this.isMeshPhysicalMaterial = !0, this.defines = { STANDARD: "", PHYSICAL: "" }, this.type = "MeshPhysicalMaterial", this.anisotropyRotation = 0, this.anisotropyMap = null, this.clearcoatMap = null, this.clearcoatRoughness = 0, this.clearcoatRoughnessMap = null, this.clearcoatNormalScale = new jt(1, 1), this.clearcoatNormalMap = null, this.ior = 1.5, Object.defineProperty(this, "reflectivity", { get: function() { return Ot(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1) }, set: function(e) { this.ior = (1 + .4 * e) / (1 - .4 * e) } }), this.iridescenceMap = null, this.iridescenceIOR = 1.3, this.iridescenceThicknessRange = [100, 400], this.iridescenceThicknessMap = null, this.sheenColor = new Wi(0), this.sheenColorMap = null, this.sheenRoughness = 1, this.sheenRoughnessMap = null, this.transmissionMap = null, this.thickness = 0, this.thicknessMap = null, this.attenuationDistance = 1 / 0, this.attenuationColor = new Wi(1, 1, 1), this.specularIntensity = 1, this.specularIntensityMap = null, this.specularColor = new Wi(1, 1, 1), this.specularColorMap = null, this._anisotropy = 0, this._clearcoat = 0, this._dispersion = 0, this._iridescence = 0, this._sheen = 0, this._transmission = 0, this.setValues(e) } get anisotropy() { return this._anisotropy } set anisotropy(e) { this._anisotropy > 0 != e > 0 && this.version++, this._anisotropy = e } get clearcoat() { return this._clearcoat } set clearcoat(e) { this._clearcoat > 0 != e > 0 && this.version++, this._clearcoat = e } get iridescence() { return this._iridescence } set iridescence(e) { this._iridescence > 0 != e > 0 && this.version++, this._iridescence = e } get dispersion() { return this._dispersion } set dispersion(e) { this._dispersion > 0 != e > 0 && this.version++, this._dispersion = e } get sheen() { return this._sheen } set sheen(e) { this._sheen > 0 != e > 0 && this.version++, this._sheen = e } get transmission() { return this._transmission } set transmission(e) { this._transmission > 0 != e > 0 && this.version++, this._transmission = e } copy(e) { return super.copy(e), this.defines = { STANDARD: "", PHYSICAL: "" }, this.anisotropy = e.anisotropy, this.anisotropyRotation = e.anisotropyRotation, this.anisotropyMap = e.anisotropyMap, this.clearcoat = e.clearcoat, this.clearcoatMap = e.clearcoatMap, this.clearcoatRoughness = e.clearcoatRoughness, this.clearcoatRoughnessMap = e.clearcoatRoughnessMap, this.clearcoatNormalMap = e.clearcoatNormalMap, this.clearcoatNormalScale.copy(e.clearcoatNormalScale), this.dispersion = e.dispersion, this.ior = e.ior, this.iridescence = e.iridescence, this.iridescenceMap = e.iridescenceMap, this.iridescenceIOR = e.iridescenceIOR, this.iridescenceThicknessRange = [...e.iridescenceThicknessRange], this.iridescenceThicknessMap = e.iridescenceThicknessMap, this.sheen = e.sheen, this.sheenColor.copy(e.sheenColor), this.sheenColorMap = e.sheenColorMap, this.sheenRoughness = e.sheenRoughness, this.sheenRoughnessMap = e.sheenRoughnessMap, this.transmission = e.transmission, this.transmissionMap = e.transmissionMap, this.thickness = e.thickness, this.thicknessMap = e.thicknessMap, this.attenuationDistance = e.attenuationDistance, this.attenuationColor.copy(e.attenuationColor), this.specularIntensity = e.specularIntensity, this.specularIntensityMap = e.specularIntensityMap, this.specularColor.copy(e.specularColor), this.specularColorMap = e.specularColorMap, this } } class Fs extends Gi { constructor(e) { super(), this.isMeshLambertMaterial = !0, this.type = "MeshLambertMaterial", this.color = new Wi(16777215), this.map = null, this.lightMap = null, this.lightMapIntensity = 1, this.aoMap = null, this.aoMapIntensity = 1, this.emissive = new Wi(0), this.emissiveIntensity = 1, this.emissiveMap = null, this.bumpMap = null, this.bumpScale = 1, this.normalMap = null, this.normalMapType = 0, this.normalScale = new jt(1, 1), this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.specularMap = null, this.alphaMap = null, this.envMap = null, this.envMapRotation = new ai, this.combine = 0, this.reflectivity = 1, this.refractionRatio = .98, this.wireframe = !1, this.wireframeLinewidth = 1, this.wireframeLinecap = "round", this.wireframeLinejoin = "round", this.flatShading = !1, this.fog = !0, this.setValues(e) } copy(e) { return super.copy(e), this.color.copy(e.color), this.map = e.map, this.lightMap = e.lightMap, this.lightMapIntensity = e.lightMapIntensity, this.aoMap = e.aoMap, this.aoMapIntensity = e.aoMapIntensity, this.emissive.copy(e.emissive), this.emissiveMap = e.emissiveMap, this.emissiveIntensity = e.emissiveIntensity, this.bumpMap = e.bumpMap, this.bumpScale = e.bumpScale, this.normalMap = e.normalMap, this.normalMapType = e.normalMapType, this.normalScale.copy(e.normalScale), this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this.specularMap = e.specularMap, this.alphaMap = e.alphaMap, this.envMap = e.envMap, this.envMapRotation.copy(e.envMapRotation), this.combine = e.combine, this.reflectivity = e.reflectivity, this.refractionRatio = e.refractionRatio, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this.wireframeLinecap = e.wireframeLinecap, this.wireframeLinejoin = e.wireframeLinejoin, this.flatShading = e.flatShading, this.fog = e.fog, this } } class Ws extends Gi { constructor(e) { super(), this.isMeshDepthMaterial = !0, this.type = "MeshDepthMaterial", this.depthPacking = 3200, this.map = null, this.alphaMap = null, this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.wireframe = !1, this.wireframeLinewidth = 1, this.setValues(e) } copy(e) { return super.copy(e), this.depthPacking = e.depthPacking, this.map = e.map, this.alphaMap = e.alphaMap, this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this.wireframe = e.wireframe, this.wireframeLinewidth = e.wireframeLinewidth, this } } class Vs extends Gi { constructor(e) { super(), this.isMeshDistanceMaterial = !0, this.type = "MeshDistanceMaterial", this.map = null, this.alphaMap = null, this.displacementMap = null, this.displacementScale = 1, this.displacementBias = 0, this.setValues(e) } copy(e) { return super.copy(e), this.map = e.map, this.alphaMap = e.alphaMap, this.displacementMap = e.displacementMap, this.displacementScale = e.displacementScale, this.displacementBias = e.displacementBias, this } } function Hs(e, t, n) { return !e || !n && e.constructor === t ? e : "number" == typeof t.BYTES_PER_ELEMENT ? new t(e) : Array.prototype.slice.call(e) } function Gs(e) { return ArrayBuffer.isView(e) && !(e instanceof DataView) } function js(e) { const t = e.length, n = new Array(t); for (let e = 0; e !== t; ++e) n[e] = e; return n.sort((function(t, n) { return e[t] - e[n] })), n } function Qs(e, t, n) { const i = e.length, r = new e.constructor(i); for (let a = 0, s = 0; s !== i; ++a) { const i = n[a] * t; for (let n = 0; n !== t; ++n) r[s++] = e[i + n] } return r } function Ys(e, t, n, i) { let r = 1, a = e[0]; for (; void 0 !== a && void 0 === a[i];) a = e[r++]; if (void 0 === a) return; let s = a[i]; if (void 0 !== s) if (Array.isArray(s)) do { s = a[i], void 0 !== s && (t.push(a.time), n.push(...s)), a = e[r++] } while (void 0 !== a); else if (void 0 !== s.toArray) do { s = a[i], void 0 !== s && (t.push(a.time), s.toArray(n, n.length)), a = e[r++] } while (void 0 !== a); else do { s = a[i], void 0 !== s && (t.push(a.time), n.push(s)), a = e[r++] } while (void 0 !== a) } class Ks { constructor(e, t, n, i) { this.parameterPositions = e, this._cachedIndex = 0, this.resultBuffer = void 0 !== i ? i : new t.constructor(n), this.sampleValues = t, this.valueSize = n, this.settings = null, this.DefaultSettings_ = {} } evaluate(e) { const t = this.parameterPositions; let n = this._cachedIndex, i = t[n], r = t[n - 1]; e: { t: { let a;n: { i: if (!(e < i)) { for (let a = n + 2;;) { if (void 0 === i) { if (e < r) break i; return n = t.length, this._cachedIndex = n, this.copySampleValue_(n - 1) } if (n === a) break; if (r = i, i = t[++n], e < i) break t } a = t.length; break n }if (e >= r) break e; { const s = t[1]; e < s && (n = 2, r = s); for (let a = n - 2;;) { if (void 0 === r) return this._cachedIndex = 0, this.copySampleValue_(0); if (n === a) break; if (i = r, r = t[--n - 1], e >= r) break t } a = n, n = 0 } } for (; n < a;) { const i = n + a >>> 1; e < t[i] ? a = i : n = i + 1 } if (i = t[n], r = t[n - 1], void 0 === r) return this._cachedIndex = 0, this.copySampleValue_(0); if (void 0 === i) return n = t.length, this._cachedIndex = n, this.copySampleValue_(n - 1) } this._cachedIndex = n, this.intervalChanged_(n, r, i) } return this.interpolate_(n, r, e, i) } getSettings_() { return this.settings || this.DefaultSettings_ } copySampleValue_(e) { const t = this.resultBuffer, n = this.sampleValues, i = this.valueSize, r = e * i; for (let e = 0; e !== i; ++e) t[e] = n[r + e]; return t } interpolate_() { throw new Error("call to abstract method") } intervalChanged_() {} } class qs extends Ks { constructor(e, t, n, i) { super(e, t, n, i), this._weightPrev = -0, this._offsetPrev = -0, this._weightNext = -0, this._offsetNext = -0, this.DefaultSettings_ = { endingStart: ut, endingEnd: ut } } intervalChanged_(e, t, n) { const i = this.parameterPositions; let r = e - 2, a = e + 1, s = i[r], o = i[a]; if (void 0 === s) switch (this.getSettings_().endingStart) { case pt: r = e, s = 2 * t - n; break; case ft: r = i.length - 2, s = t + i[r] - i[r + 1]; break; default: r = e, s = n } if (void 0 === o) switch (this.getSettings_().endingEnd) { case pt: a = e, o = 2 * n - t; break; case ft: a = 1, o = n + i[1] - i[0]; break; default: a = e - 1, o = t } const l = .5 * (n - t), c = this.valueSize; this._weightPrev = l / (t - s), this._weightNext = l / (o - n), this._offsetPrev = r * c, this._offsetNext = a * c } interpolate_(e, t, n, i) { const r = this.resultBuffer, a = this.sampleValues, s = this.valueSize, o = e * s, l = o - s, c = this._offsetPrev, h = this._offsetNext, d = this._weightPrev, u = this._weightNext, p = (n - t) / (i - t), f = p * p, m = f * p, g = -d * m + 2 * d * f - d * p, v = (1 + d) * m + (-1.5 - 2 * d) * f + (-.5 + d) * p + 1, w = (-1 - u) * m + (1.5 + u) * f + .5 * p, y = u * m - u * f; for (let e = 0; e !== s; ++e) r[e] = g * a[c + e] + v * a[l + e] + w * a[o + e] + y * a[h + e]; return r } } class Xs extends Ks { constructor(e, t, n, i) { super(e, t, n, i) } interpolate_(e, t, n, i) { const r = this.resultBuffer, a = this.sampleValues, s = this.valueSize, o = e * s, l = o - s, c = (n - t) / (i - t), h = 1 - c; for (let e = 0; e !== s; ++e) r[e] = a[l + e] * h + a[o + e] * c; return r } } class Zs extends Ks { constructor(e, t, n, i) { super(e, t, n, i) } interpolate_(e) { return this.copySampleValue_(e - 1) } } class Js { constructor(e, t, n, i) { if (void 0 === e) throw new Error("THREE.KeyframeTrack: track name is undefined"); if (void 0 === t || 0 === t.length) throw new Error("THREE.KeyframeTrack: no keyframes in track named " + e); this.name = e, this.times = Hs(t, this.TimeBufferType), this.values = Hs(n, this.ValueBufferType), this.setInterpolation(i || this.DefaultInterpolation) } static toJSON(e) { const t = e.constructor; let n; if (t.toJSON !== this.toJSON) n = t.toJSON(e); else { n = { name: e.name, times: Hs(e.times, Array), values: Hs(e.values, Array) }; const t = e.getInterpolation(); t !== e.DefaultInterpolation && (n.interpolation = t) } return n.type = e.ValueTypeName, n } InterpolantFactoryMethodDiscrete(e) { return new Zs(this.times, this.values, this.getValueSize(), e) } InterpolantFactoryMethodLinear(e) { return new Xs(this.times, this.values, this.getValueSize(), e) } InterpolantFactoryMethodSmooth(e) { return new qs(this.times, this.values, this.getValueSize(), e) } setInterpolation(e) { let t; switch (e) { case ct: t = this.InterpolantFactoryMethodDiscrete; break; case ht: t = this.InterpolantFactoryMethodLinear; break; case dt: t = this.InterpolantFactoryMethodSmooth } if (void 0 === t) { const t = "unsupported interpolation for " + this.ValueTypeName + " keyframe track named " + this.name; if (void 0 === this.createInterpolant) { if (e === this.DefaultInterpolation) throw new Error(t); this.setInterpolation(this.DefaultInterpolation) } return console.warn("THREE.KeyframeTrack:", t), this } return this.createInterpolant = t, this } getInterpolation() { switch (this.createInterpolant) { case this.InterpolantFactoryMethodDiscrete: return ct; case this.InterpolantFactoryMethodLinear: return ht; case this.InterpolantFactoryMethodSmooth: return dt } } getValueSize() { return this.values.length / this.times.length } shift(e) { if (0 !== e) { const t = this.times; for (let n = 0, i = t.length; n !== i; ++n) t[n] += e } return this } scale(e) { if (1 !== e) { const t = this.times; for (let n = 0, i = t.length; n !== i; ++n) t[n] *= e } return this } trim(e, t) { const n = this.times, i = n.length; let r = 0, a = i - 1; for (; r !== i && n[r] < e;) ++r; for (; - 1 !== a && n[a] > t;) --a; if (++a, 0 !== r || a !== i) { r >= a && (a = Math.max(a, 1), r = a - 1); const e = this.getValueSize(); this.times = n.slice(r, a), this.values = this.values.slice(r * e, a * e) } return this } validate() { let e = !0; const t = this.getValueSize(); t - Math.floor(t) != 0 && (console.error("THREE.KeyframeTrack: Invalid value size in track.", this), e = !1); const n = this.times, i = this.values, r = n.length; 0 === r && (console.error("THREE.KeyframeTrack: Track is empty.", this), e = !1); let a = null; for (let t = 0; t !== r; t++) { const i = n[t]; if ("number" == typeof i && isNaN(i)) { console.error("THREE.KeyframeTrack: Time is not a valid number.", this, t, i), e = !1; break } if (null !== a && a > i) { console.error("THREE.KeyframeTrack: Out of order keys.", this, t, i, a), e = !1; break } a = i } if (void 0 !== i && Gs(i)) for (let t = 0, n = i.length; t !== n; ++t) { const n = i[t]; if (isNaN(n)) { console.error("THREE.KeyframeTrack: Value is not a valid number.", this, t, n), e = !1; break } } return e } optimize() { const e = this.times.slice(), t = this.values.slice(), n = this.getValueSize(), i = this.getInterpolation() === dt, r = e.length - 1; let a = 1; for (let s = 1; s < r; ++s) { let r = !1; const o = e[s]; if (o !== e[s + 1] && (1 !== s || o !== e[0])) if (i) r = !0; else { const e = s * n, i = e - n, a = e + n; for (let s = 0; s !== n; ++s) { const n = t[e + s]; if (n !== t[i + s] || n !== t[a + s]) { r = !0; break } } } if (r) { if (s !== a) { e[a] = e[s]; const i = s * n, r = a * n; for (let e = 0; e !== n; ++e) t[r + e] = t[i + e] }++a } } if (r > 0) { e[a] = e[r]; for (let e = r * n, i = a * n, s = 0; s !== n; ++s) t[i + s] = t[e + s]; ++a } return a !== e.length ? (this.times = e.slice(0, a), this.values = t.slice(0, a * n)) : (this.times = e, this.values = t), this } clone() { const e = this.times.slice(), t = this.values.slice(), n = new(0, this.constructor)(this.name, e, t); return n.createInterpolant = this.createInterpolant, n } } Js.prototype.TimeBufferType = Float32Array, Js.prototype.ValueBufferType = Float32Array, Js.prototype.DefaultInterpolation = ht; class $s extends Js { constructor(e, t, n) { super(e, t, n) } } $s.prototype.ValueTypeName = "bool", $s.prototype.ValueBufferType = Array, $s.prototype.DefaultInterpolation = ct, $s.prototype.InterpolantFactoryMethodLinear = void 0, $s.prototype.InterpolantFactoryMethodSmooth = void 0; class eo extends Js {} eo.prototype.ValueTypeName = "color"; class to extends Js {} to.prototype.ValueTypeName = "number"; class no extends Ks { constructor(e, t, n, i) { super(e, t, n, i) } interpolate_(e, t, n, i) { const r = this.resultBuffer, a = this.sampleValues, s = this.valueSize, o = (n - t) / (i - t); let l = e * s; for (let e = l + s; l !== e; l += 4) wn.slerpFlat(r, 0, a, l - s, a, l, o); return r } } class io extends Js { InterpolantFactoryMethodLinear(e) { return new no(this.times, this.values, this.getValueSize(), e) } } io.prototype.ValueTypeName = "quaternion", io.prototype.InterpolantFactoryMethodSmooth = void 0; class ro extends Js { constructor(e, t, n) { super(e, t, n) } } ro.prototype.ValueTypeName = "string", ro.prototype.ValueBufferType = Array, ro.prototype.DefaultInterpolation = ct, ro.prototype.InterpolantFactoryMethodLinear = void 0, ro.prototype.InterpolantFactoryMethodSmooth = void 0; class ao extends Js {} ao.prototype.ValueTypeName = "vector"; class so { constructor(e = "", t = -1, n = [], i = 2500) { this.name = e, this.tracks = n, this.duration = t, this.blendMode = i, this.uuid = zt(), this.duration < 0 && this.resetDuration() } static parse(e) { const t = [], n = e.tracks, i = 1 / (e.fps || 1); for (let e = 0, r = n.length; e !== r; ++e) t.push(oo(n[e]).scale(i)); const r = new this(e.name, e.duration, t, e.blendMode); return r.uuid = e.uuid, r } static toJSON(e) { const t = [], n = e.tracks, i = { name: e.name, duration: e.duration, tracks: t, uuid: e.uuid, blendMode: e.blendMode }; for (let e = 0, i = n.length; e !== i; ++e) t.push(Js.toJSON(n[e])); return i } static CreateFromMorphTargetSequence(e, t, n, i) { const r = t.length, a = []; for (let e = 0; e < r; e++) { let s = [], o = []; s.push((e + r - 1) % r, e, (e + 1) % r), o.push(0, 1, 0); const l = js(s); s = Qs(s, 1, l), o = Qs(o, 1, l), i || 0 !== s[0] || (s.push(r), o.push(o[0])), a.push(new to(".morphTargetInfluences[" + t[e].name + "]", s, o).scale(1 / n)) } return new this(e, -1, a) } static findByName(e, t) { let n = e; if (!Array.isArray(e)) { const t = e; n = t.geometry && t.geometry.animations || t.animations } for (let e = 0; e < n.length; e++) if (n[e].name === t) return n[e]; return null } static CreateClipsFromMorphTargetSequences(e, t, n) { const i = {}, r = /^([\w-]*?)([\d]+)$/; for (let t = 0, n = e.length; t < n; t++) { const n = e[t], a = n.name.match(r); if (a && a.length > 1) { const e = a[1]; let t = i[e]; t || (i[e] = t = []), t.push(n) } } const a = []; for (const e in i) a.push(this.CreateFromMorphTargetSequence(e, i[e], t, n)); return a } static parseAnimation(e, t) { if (!e) return console.error("THREE.AnimationClip: No animation in JSONLoader data."), null; const n = function(e, t, n, i, r) { if (0 !== n.length) { const a = [], s = []; Ys(n, a, s, i), 0 !== a.length && r.push(new e(t, a, s)) } }, i = [], r = e.name || "default", a = e.fps || 30, s = e.blendMode; let o = e.length || -1; const l = e.hierarchy || []; for (let e = 0; e < l.length; e++) { const r = l[e].keys; if (r && 0 !== r.length) if (r[0].morphTargets) { const e = {}; let t; for (t = 0; t < r.length; t++) if (r[t].morphTargets) for (let n = 0; n < r[t].morphTargets.length; n++) e[r[t].morphTargets[n]] = -1; for (const n in e) { const e = [], a = []; for (let i = 0; i !== r[t].morphTargets.length; ++i) { const i = r[t]; e.push(i.time), a.push(i.morphTarget === n ? 1 : 0) } i.push(new to(".morphTargetInfluence[" + n + "]", e, a)) } o = e.length * a } else { const a = ".bones[" + t[e].name + "]"; n(ao, a + ".position", r, "pos", i), n(io, a + ".quaternion", r, "rot", i), n(ao, a + ".scale", r, "scl", i) } } if (0 === i.length) return null; return new this(r, o, i, s) } resetDuration() { let e = 0; for (let t = 0, n = this.tracks.length; t !== n; ++t) { const n = this.tracks[t]; e = Math.max(e, n.times[n.times.length - 1]) } return this.duration = e, this } trim() { for (let e = 0; e < this.tracks.length; e++) this.tracks[e].trim(0, this.duration); return this } validate() { let e = !0; for (let t = 0; t < this.tracks.length; t++) e = e && this.tracks[t].validate(); return e } optimize() { for (let e = 0; e < this.tracks.length; e++) this.tracks[e].optimize(); return this } clone() { const e = []; for (let t = 0; t < this.tracks.length; t++) e.push(this.tracks[t].clone()); return new this.constructor(this.name, this.duration, e, this.blendMode) } toJSON() { return this.constructor.toJSON(this) } } function oo(e) { if (void 0 === e.type) throw new Error("THREE.KeyframeTrack: track type undefined, can not parse"); const t = function(e) { switch (e.toLowerCase()) { case "scalar": case "double": case "float": case "number": case "integer": return to; case "vector": case "vector2": case "vector3": case "vector4": return ao; case "color": return eo; case "quaternion": return io; case "bool": case "boolean": return $s; case "string": return ro } throw new Error("THREE.KeyframeTrack: Unsupported typeName: " + e) }(e.type); if (void 0 === e.times) { const t = [], n = []; Ys(e.keys, t, n, "value"), e.times = t, e.values = n } return void 0 !== t.parse ? t.parse(e) : new t(e.name, e.times, e.values, e.interpolation) } const lo = { enabled: !1, files: {}, add: function(e, t) { !1 !== this.enabled && (this.files[e] = t) }, get: function(e) { if (!1 !== this.enabled) return this.files[e] }, remove: function(e) { delete this.files[e] }, clear: function() { this.files = {} } }; class co { constructor(e, t, n) { const i = this; let r, a = !1, s = 0, o = 0; const l = []; this.onStart = void 0, this.onLoad = e, this.onProgress = t, this.onError = n, this.itemStart = function(e) { o++, !1 === a && void 0 !== i.onStart && i.onStart(e, s, o), a = !0 }, this.itemEnd = function(e) { s++, void 0 !== i.onProgress && i.onProgress(e, s, o), s === o && (a = !1, void 0 !== i.onLoad && i.onLoad()) }, this.itemError = function(e) { void 0 !== i.onError && i.onError(e) }, this.resolveURL = function(e) { return r ? r(e) : e }, this.setURLModifier = function(e) { return r = e, this }, this.addHandler = function(e, t) { return l.push(e, t), this }, this.removeHandler = function(e) { const t = l.indexOf(e); return -1 !== t && l.splice(t, 2), this }, this.getHandler = function(e) { for (let t = 0, n = l.length; t < n; t += 2) { const n = l[t], i = l[t + 1]; if (n.global && (n.lastIndex = 0), n.test(e)) return i } return null } } } const ho = new co; class uo { constructor(e) { this.manager = void 0 !== e ? e : ho, this.crossOrigin = "anonymous", this.withCredentials = !1, this.path = "", this.resourcePath = "", this.requestHeader = {} } load() {} loadAsync(e, t) { const n = this; return new Promise((function(i, r) { n.load(e, i, t, r) })) } parse() {} setCrossOrigin(e) { return this.crossOrigin = e, this } setWithCredentials(e) { return this.withCredentials = e, this } setPath(e) { return this.path = e, this } setResourcePath(e) { return this.resourcePath = e, this } setRequestHeader(e) { return this.requestHeader = e, this } } uo.DEFAULT_MATERIAL_NAME = "__DEFAULT"; const po = {}; class fo extends Error { constructor(e, t) { super(e), this.response = t } } class mo extends uo { constructor(e) { super(e) } load(e, t, n, i) { void 0 === e && (e = ""), void 0 !== this.path && (e = this.path + e), e = this.manager.resolveURL(e); const r = lo.get(e); if (void 0 !== r) return this.manager.itemStart(e), setTimeout((() => { t && t(r), this.manager.itemEnd(e) }), 0), r; if (void 0 !== po[e]) return void po[e].push({ onLoad: t, onProgress: n, onError: i }); po[e] = [], po[e].push({ onLoad: t, onProgress: n, onError: i }); const a = new Request(e, { headers: new Headers(this.requestHeader), credentials: this.withCredentials ? "include" : "same-origin" }), s = this.mimeType, o = this.responseType; fetch(a).then((t => { if (200 === t.status || 0 === t.status) { if (0 === t.status && console.warn("THREE.FileLoader: HTTP Status 0 received."), "undefined" == typeof ReadableStream || void 0 === t.body || void 0 === t.body.getReader) return t; const n = po[e], i = t.body.getReader(), r = t.headers.get("X-File-Size") || t.headers.get("Content-Length"), a = r ? parseInt(r) : 0, s = 0 !== a; let o = 0; const l = new ReadableStream({ start(e) { ! function t() { i.read().then((({ done: i, value: r }) => { if (i) e.close(); else { o += r.byteLength; const i = new ProgressEvent("progress", { lengthComputable: s, loaded: o, total: a }); for (let e = 0, t = n.length; e < t; e++) { const t = n[e]; t.onProgress && t.onProgress(i) } e.enqueue(r), t() } }), (t => { e.error(t) })) }() } }); return new Response(l) } throw new fo(`fetch for "${t.url}" responded with ${t.status}: ${t.statusText}`, t) })).then((e => { switch (o) { case "arraybuffer": return e.arrayBuffer(); case "blob": return e.blob(); case "document": return e.text().then((e => (new DOMParser).parseFromString(e, s))); case "json": return e.json(); default: if (void 0 === s) return e.text(); { const t = /charset="?([^;"\s]*)"?/i.exec(s), n = t && t[1] ? t[1].toLowerCase() : void 0, i = new TextDecoder(n); return e.arrayBuffer().then((e => i.decode(e))) } } })).then((t => { lo.add(e, t); const n = po[e]; delete po[e]; for (let e = 0, i = n.length; e < i; e++) { const i = n[e]; i.onLoad && i.onLoad(t) } })).catch((t => { const n = po[e]; if (void 0 === n) throw this.manager.itemError(e), t; delete po[e]; for (let e = 0, i = n.length; e < i; e++) { const i = n[e]; i.onError && i.onError(t) } this.manager.itemError(e) })).finally((() => { this.manager.itemEnd(e) })), this.manager.itemStart(e) } setResponseType(e) { return this.responseType = e, this } setMimeType(e) { return this.mimeType = e, this } } class go extends uo { constructor(e) { super(e) } load(e, t, n, i) { void 0 !== this.path && (e = this.path + e), e = this.manager.resolveURL(e); const r = this, a = lo.get(e); if (void 0 !== a) return r.manager.itemStart(e), setTimeout((function() { t && t(a), r.manager.itemEnd(e) }), 0), a; const s = qt("img"); function o() { c(), lo.add(e, this), t && t(this), r.manager.itemEnd(e) } function l(t) { c(), i && i(t), r.manager.itemError(e), r.manager.itemEnd(e) } function c() { s.removeEventListener("load", o, !1), s.removeEventListener("error", l, !1) } return s.addEventListener("load", o, !1), s.addEventListener("error", l, !1), "data:" !== e.slice(0, 5) && void 0 !== this.crossOrigin && (s.crossOrigin = this.crossOrigin), r.manager.itemStart(e), s.src = e, s } } class vo extends uo { constructor(e) { super(e) } load(e, t, n, i) { const r = new un, a = new go(this.manager); return a.setCrossOrigin(this.crossOrigin), a.setPath(this.path), a.load(e, (function(e) { r.image = e, r.needsUpdate = !0, void 0 !== t && t(r) }), n, i), r } } class wo extends xi { constructor(e, t = 1) { super(), this.isLight = !0, this.type = "Light", this.color = new Wi(e), this.intensity = t } dispose() {} copy(e, t) { return super.copy(e, t), this.color.copy(e.color), this.intensity = e.intensity, this } toJSON(e) { const t = super.toJSON(e); return t.object.color = this.color.getHex(), t.object.intensity = this.intensity, void 0 !== this.groundColor && (t.object.groundColor = this.groundColor.getHex()), void 0 !== this.distance && (t.object.distance = this.distance), void 0 !== this.angle && (t.object.angle = this.angle), void 0 !== this.decay && (t.object.decay = this.decay), void 0 !== this.penumbra && (t.object.penumbra = this.penumbra), void 0 !== this.shadow && (t.object.shadow = this.shadow.toJSON()), void 0 !== this.target && (t.object.target = this.target.uuid), t } } class yo extends wo { constructor(e, t, n) { super(e, n), this.isHemisphereLight = !0, this.type = "HemisphereLight", this.position.copy(xi.DEFAULT_UP), this.updateMatrix(), this.groundColor = new Wi(t) } copy(e, t) { return super.copy(e, t), this.groundColor.copy(e.groundColor), this } } const Ao = new qn, bo = new yn, xo = new yn; class ko { constructor(e) { this.camera = e, this.intensity = 1, this.bias = 0, this.normalBias = 0, this.radius = 1, this.blurSamples = 8, this.mapSize = new jt(512, 512), this.map = null, this.mapPass = null, this.matrix = new qn, this.autoUpdate = !0, this.needsUpdate = !1, this._frustum = new ya, this._frameExtents = new jt(1, 1), this._viewportCount = 1, this._viewports = [new pn(0, 0, 1, 1)] } getViewportCount() { return this._viewportCount } getFrustum() { return this._frustum } updateMatrices(e) { const t = this.camera, n = this.matrix; bo.setFromMatrixPosition(e.matrixWorld), t.position.copy(bo), xo.setFromMatrixPosition(e.target.matrixWorld), t.lookAt(xo), t.updateMatrixWorld(), Ao.multiplyMatrices(t.projectionMatrix, t.matrixWorldInverse), this._frustum.setFromProjectionMatrix(Ao), n.set(.5, 0, 0, .5, 0, .5, 0, .5, 0, 0, .5, .5, 0, 0, 0, 1), n.multiply(Ao) } getViewport(e) { return this._viewports[e] } getFrameExtents() { return this._frameExtents } dispose() { this.map && this.map.dispose(), this.mapPass && this.mapPass.dispose() } copy(e) { return this.camera = e.camera.clone(), this.intensity = e.intensity, this.bias = e.bias, this.radius = e.radius, this.mapSize.copy(e.mapSize), this } clone() { return (new this.constructor).copy(this) } toJSON() { const e = {}; return 1 !== this.intensity && (e.intensity = this.intensity), 0 !== this.bias && (e.bias = this.bias), 0 !== this.normalBias && (e.normalBias = this.normalBias), 1 !== this.radius && (e.radius = this.radius), 512 === this.mapSize.x && 512 === this.mapSize.y || (e.mapSize = this.mapSize.toArray()), e.camera = this.camera.toJSON(!1).object, delete e.camera.matrix, e } } class Eo extends ko { constructor() { super(new Pr(50, 1, .5, 500)), this.isSpotLightShadow = !0, this.focus = 1 } updateMatrices(e) { const t = this.camera, n = 2 * Ut * e.angle * this.focus, i = this.mapSize.width / this.mapSize.height, r = e.distance || t.far; n === t.fov && i === t.aspect && r === t.far || (t.fov = n, t.aspect = i, t.far = r, t.updateProjectionMatrix()), super.updateMatrices(e) } copy(e) { return super.copy(e), this.focus = e.focus, this } } class So extends wo { constructor(e, t, n = 0, i = Math.PI / 3, r = 0, a = 2) { super(e, t), this.isSpotLight = !0, this.type = "SpotLight", this.position.copy(xi.DEFAULT_UP), this.updateMatrix(), this.target = new xi, this.distance = n, this.angle = i, this.penumbra = r, this.decay = a, this.map = null, this.shadow = new Eo } get power() { return this.intensity * Math.PI } set power(e) { this.intensity = e / Math.PI } dispose() { this.shadow.dispose() } copy(e, t) { return super.copy(e, t), this.distance = e.distance, this.angle = e.angle, this.penumbra = e.penumbra, this.decay = e.decay, this.target = e.target.clone(), this.shadow = e.shadow.clone(), this } } const Mo = new qn, To = new yn, _o = new yn; class Co extends ko { constructor() { super(new Pr(90, 1, .5, 500)), this.isPointLightShadow = !0, this._frameExtents = new jt(4, 2), this._viewportCount = 6, this._viewports = [new pn(2, 1, 1, 1), new pn(0, 1, 1, 1), new pn(3, 1, 1, 1), new pn(1, 1, 1, 1), new pn(3, 0, 1, 1), new pn(1, 0, 1, 1)], this._cubeDirections = [new yn(1, 0, 0), new yn(-1, 0, 0), new yn(0, 0, 1), new yn(0, 0, -1), new yn(0, 1, 0), new yn(0, -1, 0)], this._cubeUps = [new yn(0, 1, 0), new yn(0, 1, 0), new yn(0, 1, 0), new yn(0, 1, 0), new yn(0, 0, 1), new yn(0, 0, -1)] } updateMatrices(e, t = 0) { const n = this.camera, i = this.matrix, r = e.distance || n.far; r !== n.far && (n.far = r, n.updateProjectionMatrix()), To.setFromMatrixPosition(e.matrixWorld), n.position.copy(To), _o.copy(n.position), _o.add(this._cubeDirections[t]), n.up.copy(this._cubeUps[t]), n.lookAt(_o), n.updateMatrixWorld(), i.makeTranslation(-To.x, -To.y, -To.z), Mo.multiplyMatrices(n.projectionMatrix, n.matrixWorldInverse), this._frustum.setFromProjectionMatrix(Mo) } } class Po extends wo { constructor(e, t, n = 0, i = 2) { super(e, t), this.isPointLight = !0, this.type = "PointLight", this.distance = n, this.decay = i, this.shadow = new Co } get power() { return 4 * this.intensity * Math.PI } set power(e) { this.intensity = e / (4 * Math.PI) } dispose() { this.shadow.dispose() } copy(e, t) { return super.copy(e, t), this.distance = e.distance, this.decay = e.decay, this.shadow = e.shadow.clone(), this } } class Io extends Mr { constructor(e = -1, t = 1, n = 1, i = -1, r = .1, a = 2e3) { super(), this.isOrthographicCamera = !0, this.type = "OrthographicCamera", this.zoom = 1, this.view = null, this.left = e, this.right = t, this.top = n, this.bottom = i, this.near = r, this.far = a, this.updateProjectionMatrix() } copy(e, t) { return super.copy(e, t), this.left = e.left, this.right = e.right, this.top = e.top, this.bottom = e.bottom, this.near = e.near, this.far = e.far, this.zoom = e.zoom, this.view = null === e.view ? null : Object.assign({}, e.view), this } setViewOffset(e, t, n, i, r, a) { null === this.view && (this.view = { enabled: !0, fullWidth: 1, fullHeight: 1, offsetX: 0, offsetY: 0, width: 1, height: 1 }), this.view.enabled = !0, this.view.fullWidth = e, this.view.fullHeight = t, this.view.offsetX = n, this.view.offsetY = i, this.view.width = r, this.view.height = a, this.updateProjectionMatrix() } clearViewOffset() { null !== this.view && (this.view.enabled = !1), this.updateProjectionMatrix() } updateProjectionMatrix() { const e = (this.right - this.left) / (2 * this.zoom), t = (this.top - this.bottom) / (2 * this.zoom), n = (this.right + this.left) / 2, i = (this.top + this.bottom) / 2; let r = n - e, a = n + e, s = i + t, o = i - t; if (null !== this.view && this.view.enabled) { const e = (this.right - this.left) / this.view.fullWidth / this.zoom, t = (this.top - this.bottom) / this.view.fullHeight / this.zoom; r += e * this.view.offsetX, a = r + e * this.view.width, s -= t * this.view.offsetY, o = s - t * this.view.height } this.projectionMatrix.makeOrthographic(r, a, s, o, this.near, this.far, this.coordinateSystem), this.projectionMatrixInverse.copy(this.projectionMatrix).invert() } toJSON(e) { const t = super.toJSON(e); return t.object.zoom = this.zoom, t.object.left = this.left, t.object.right = this.right, t.object.top = this.top, t.object.bottom = this.bottom, t.object.near = this.near, t.object.far = this.far, null !== this.view && (t.object.view = Object.assign({}, this.view)), t } } class Ro extends ko { constructor() { super(new Io(-5, 5, 5, -5, .5, 500)), this.isDirectionalLightShadow = !0 } } class Lo extends wo { constructor(e, t) { super(e, t), this.isDirectionalLight = !0, this.type = "DirectionalLight", this.position.copy(xi.DEFAULT_UP), this.updateMatrix(), this.target = new xi, this.shadow = new Ro } dispose() { this.shadow.dispose() } copy(e) { return super.copy(e), this.target = e.target.clone(), this.shadow = e.shadow.clone(), this } } class Do { static decodeText(e) { if (console.warn("THREE.LoaderUtils: decodeText() has been deprecated with r165 and will be removed with r175. Use TextDecoder instead."), "undefined" != typeof TextDecoder) return (new TextDecoder).decode(e); let t = ""; for (let n = 0, i = e.length; n < i; n++) t += String.fromCharCode(e[n]); try { return decodeURIComponent(escape(t)) } catch (e) { return t } } static extractUrlBase(e) { const t = e.lastIndexOf("/"); return -1 === t ? "./" : e.slice(0, t + 1) } static resolveURL(e, t) { return "string" != typeof e || "" === e ? "" : (/^https?:\/\//i.test(t) && /^\//.test(e) && (t = t.replace(/(^https?:\/\/[^\/]+).*/i, "$1")), /^(https?:)?\/\//i.test(e) || /^data:.*,.*$/i.test(e) || /^blob:.*$/i.test(e) ? e : t + e) } } class No extends uo { constructor(e) { super(e), this.isImageBitmapLoader = !0, "undefined" == typeof createImageBitmap && console.warn("THREE.ImageBitmapLoader: createImageBitmap() not supported."), "undefined" == typeof fetch && console.warn("THREE.ImageBitmapLoader: fetch() not supported."), this.options = { premultiplyAlpha: "none" } } setOptions(e) { return this.options = e, this } load(e, t, n, i) { void 0 === e && (e = ""), void 0 !== this.path && (e = this.path + e), e = this.manager.resolveURL(e); const r = this, a = lo.get(e); if (void 0 !== a) return r.manager.itemStart(e), a.then ? void a.then((n => { t && t(n), r.manager.itemEnd(e) })).catch((e => { i && i(e) })) : (setTimeout((function() { t && t(a), r.manager.itemEnd(e) }), 0), a); const s = {}; s.credentials = "anonymous" === this.crossOrigin ? "same-origin" : "include", s.headers = this.requestHeader; const o = fetch(e, s).then((function(e) { return e.blob() })).then((function(e) { return createImageBitmap(e, Object.assign(r.options, { colorSpaceConversion: "none" })) })).then((function(n) { return lo.add(e, n), t && t(n), r.manager.itemEnd(e), n })).catch((function(t) { i && i(t), lo.remove(e), r.manager.itemError(e), r.manager.itemEnd(e) })); lo.add(e, o), r.manager.itemStart(e) } } class Bo extends Pr { constructor(e = []) { super(), this.isArrayCamera = !0, this.cameras = e, this.index = 0 } } const Uo = "\\[\\]\\.:\\/", zo = new RegExp("[" + Uo + "]", "g"), Oo = "[^" + Uo + "]", Fo = "[^" + Uo.replace("\\.", "") + "]", Wo = new RegExp("^" + /((?:WC+[\/:])*)/.source.replace("WC", Oo) + /(WCOD+)?/.source.replace("WCOD", Fo) + /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC", Oo) + /\.(WC+)(?:\[(.+)\])?/.source.replace("WC", Oo) + "$"), Vo = ["material", "materials", "bones", "map"]; class Ho { constructor(e, t, n) { this.path = t, this.parsedPath = n || Ho.parseTrackName(t), this.node = Ho.findNode(e, this.parsedPath.nodeName), this.rootNode = e, this.getValue = this._getValue_unbound, this.setValue = this._setValue_unbound } static create(e, t, n) { return e && e.isAnimationObjectGroup ? new Ho.Composite(e, t, n) : new Ho(e, t, n) } static sanitizeNodeName(e) { return e.replace(/\s/g, "_").replace(zo, "") } static parseTrackName(e) { const t = Wo.exec(e); if (null === t) throw new Error("PropertyBinding: Cannot parse trackName: " + e); const n = { nodeName: t[2], objectName: t[3], objectIndex: t[4], propertyName: t[5], propertyIndex: t[6] }, i = n.nodeName && n.nodeName.lastIndexOf("."); if (void 0 !== i && -1 !== i) { const e = n.nodeName.substring(i + 1); - 1 !== Vo.indexOf(e) && (n.nodeName = n.nodeName.substring(0, i), n.objectName = e) } if (null === n.propertyName || 0 === n.propertyName.length) throw new Error("PropertyBinding: can not parse propertyName from trackName: " + e); return n } static findNode(e, t) { if (void 0 === t || "" === t || "." === t || -1 === t || t === e.name || t === e.uuid) return e; if (e.skeleton) { const n = e.skeleton.getBoneByName(t); if (void 0 !== n) return n } if (e.children) { const n = function(e) { for (let i = 0; i < e.length; i++) { const r = e[i]; if (r.name === t || r.uuid === t) return r; const a = n(r.children); if (a) return a } return null }, i = n(e.children); if (i) return i } return null } _getValue_unavailable() {} _setValue_unavailable() {} _getValue_direct(e, t) { e[t] = this.targetObject[this.propertyName] } _getValue_array(e, t) { const n = this.resolvedProperty; for (let i = 0, r = n.length; i !== r; ++i) e[t++] = n[i] } _getValue_arrayElement(e, t) { e[t] = this.resolvedProperty[this.propertyIndex] } _getValue_toArray(e, t) { this.resolvedProperty.toArray(e, t) } _setValue_direct(e, t) { this.targetObject[this.propertyName] = e[t] } _setValue_direct_setNeedsUpdate(e, t) { this.targetObject[this.propertyName] = e[t], this.targetObject.needsUpdate = !0 } _setValue_direct_setMatrixWorldNeedsUpdate(e, t) { this.targetObject[this.propertyName] = e[t], this.targetObject.matrixWorldNeedsUpdate = !0 } _setValue_array(e, t) { const n = this.resolvedProperty; for (let i = 0, r = n.length; i !== r; ++i) n[i] = e[t++] } _setValue_array_setNeedsUpdate(e, t) { const n = this.resolvedProperty; for (let i = 0, r = n.length; i !== r; ++i) n[i] = e[t++]; this.targetObject.needsUpdate = !0 } _setValue_array_setMatrixWorldNeedsUpdate(e, t) { const n = this.resolvedProperty; for (let i = 0, r = n.length; i !== r; ++i) n[i] = e[t++]; this.targetObject.matrixWorldNeedsUpdate = !0 } _setValue_arrayElement(e, t) { this.resolvedProperty[this.propertyIndex] = e[t] } _setValue_arrayElement_setNeedsUpdate(e, t) { this.resolvedProperty[this.propertyIndex] = e[t], this.targetObject.needsUpdate = !0 } _setValue_arrayElement_setMatrixWorldNeedsUpdate(e, t) { this.resolvedProperty[this.propertyIndex] = e[t], this.targetObject.matrixWorldNeedsUpdate = !0 } _setValue_fromArray(e, t) { this.resolvedProperty.fromArray(e, t) } _setValue_fromArray_setNeedsUpdate(e, t) { this.resolvedProperty.fromArray(e, t), this.targetObject.needsUpdate = !0 } _setValue_fromArray_setMatrixWorldNeedsUpdate(e, t) { this.resolvedProperty.fromArray(e, t), this.targetObject.matrixWorldNeedsUpdate = !0 } _getValue_unbound(e, t) { this.bind(), this.getValue(e, t) } _setValue_unbound(e, t) { this.bind(), this.setValue(e, t) } bind() { let e = this.node; const t = this.parsedPath, n = t.objectName, i = t.propertyName; let r = t.propertyIndex; if (e || (e = Ho.findNode(this.rootNode, t.nodeName), this.node = e), this.getValue = this._getValue_unavailable, this.setValue = this._setValue_unavailable, !e) return void console.warn("THREE.PropertyBinding: No target node found for track: " + this.path + "."); if (n) { let i = t.objectIndex; switch (n) { case "materials": if (!e.material) return void console.error("THREE.PropertyBinding: Can not bind to material as node does not have a material.", this); if (!e.material.materials) return void console.error("THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.", this); e = e.material.materials; break; case "bones": if (!e.skeleton) return void console.error("THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.", this); e = e.skeleton.bones; for (let t = 0; t < e.length; t++) if (e[t].name === i) { i = t; break } break; case "map": if ("map" in e) { e = e.map; break } if (!e.material) return void console.error("THREE.PropertyBinding: Can not bind to material as node does not have a material.", this); if (!e.material.map) return void console.error("THREE.PropertyBinding: Can not bind to material.map as node.material does not have a map.", this); e = e.material.map; break; default: if (void 0 === e[n]) return void console.error("THREE.PropertyBinding: Can not bind to objectName of node undefined.", this); e = e[n] } if (void 0 !== i) { if (void 0 === e[i]) return void console.error("THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.", this, e); e = e[i] } } const a = e[i]; if (void 0 === a) { const n = t.nodeName; return void console.error("THREE.PropertyBinding: Trying to update property for track: " + n + "." + i + " but it wasn't found.", e) } let s = this.Versioning.None; this.targetObject = e, !0 === e.isMaterial ? s = this.Versioning.NeedsUpdate : !0 === e.isObject3D && (s = this.Versioning.MatrixWorldNeedsUpdate); let o = this.BindingType.Direct; if (void 0 !== r) { if ("morphTargetInfluences" === i) { if (!e.geometry) return void console.error("THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.", this); if (!e.geometry.morphAttributes) return void console.error("THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.", this); void 0 !== e.morphTargetDictionary[r] && (r = e.morphTargetDictionary[r]) } o = this.BindingType.ArrayElement, this.resolvedProperty = a, this.propertyIndex = r } else void 0 !== a.fromArray && void 0 !== a.toArray ? (o = this.BindingType.HasFromToArray, this.resolvedProperty = a) : Array.isArray(a) ? (o = this.BindingType.EntireArray, this.resolvedProperty = a) : this.propertyName = i; this.getValue = this.GetterByBindingType[o], this.setValue = this.SetterByBindingTypeAndVersioning[o][s] } unbind() { this.node = null, this.getValue = this._getValue_unbound, this.setValue = this._setValue_unbound } } Ho.Composite = class { constructor(e, t, n) { const i = n || Ho.parseTrackName(t); this._targetGroup = e, this._bindings = e.subscribe_(t, i) } getValue(e, t) { this.bind(); const n = this._targetGroup.nCachedObjects_, i = this._bindings[n]; void 0 !== i && i.getValue(e, t) } setValue(e, t) { const n = this._bindings; for (let i = this._targetGroup.nCachedObjects_, r = n.length; i !== r; ++i) n[i].setValue(e, t) } bind() { const e = this._bindings; for (let t = this._targetGroup.nCachedObjects_, n = e.length; t !== n; ++t) e[t].bind() } unbind() { const e = this._bindings; for (let t = this._targetGroup.nCachedObjects_, n = e.length; t !== n; ++t) e[t].unbind() } }, Ho.prototype.BindingType = { Direct: 0, EntireArray: 1, ArrayElement: 2, HasFromToArray: 3 }, Ho.prototype.Versioning = { None: 0, NeedsUpdate: 1, MatrixWorldNeedsUpdate: 2 }, Ho.prototype.GetterByBindingType = [Ho.prototype._getValue_direct, Ho.prototype._getValue_array, Ho.prototype._getValue_arrayElement, Ho.prototype._getValue_toArray], Ho.prototype.SetterByBindingTypeAndVersioning = [ [Ho.prototype._setValue_direct, Ho.prototype._setValue_direct_setNeedsUpdate, Ho.prototype._setValue_direct_setMatrixWorldNeedsUpdate], [Ho.prototype._setValue_array, Ho.prototype._setValue_array_setNeedsUpdate, Ho.prototype._setValue_array_setMatrixWorldNeedsUpdate], [Ho.prototype._setValue_arrayElement, Ho.prototype._setValue_arrayElement_setNeedsUpdate, Ho.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate], [Ho.prototype._setValue_fromArray, Ho.prototype._setValue_fromArray_setNeedsUpdate, Ho.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate] ]; new Float32Array(1); const Go = new qn; class jo { constructor(e, t, n = 0, i = 1 / 0) { this.ray = new Kn(e, t), this.near = n, this.far = i, this.camera = null, this.layers = new si, this.params = { Mesh: {}, Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} } } set(e, t) { this.ray.set(e, t) } setFromCamera(e, t) { t.isPerspectiveCamera ? (this.ray.origin.setFromMatrixPosition(t.matrixWorld), this.ray.direction.set(e.x, e.y, .5).unproject(t).sub(this.ray.origin).normalize(), this.camera = t) : t.isOrthographicCamera ? (this.ray.origin.set(e.x, e.y, (t.near + t.far) / (t.near - t.far)).unproject(t), this.ray.direction.set(0, 0, -1).transformDirection(t.matrixWorld), this.camera = t) : console.error("THREE.Raycaster: Unsupported camera type: " + t.type) } setFromXRController(e) { return Go.identity().extractRotation(e.matrixWorld), this.ray.origin.setFromMatrixPosition(e.matrixWorld), this.ray.direction.set(0, 0, -1).applyMatrix4(Go), this } intersectObject(e, t = !0, n = []) { return Yo(e, this, n, t), n.sort(Qo), n } intersectObjects(e, t = !0, n = []) { for (let i = 0, r = e.length; i < r; i++) Yo(e[i], this, n, t); return n.sort(Qo), n } } function Qo(e, t) { return e.distance - t.distance } function Yo(e, t, n, i) { let r = !0; if (e.layers.test(t.layers)) { !1 === e.raycast(t, n) && (r = !1) } if (!0 === r && !0 === i) { const i = e.children; for (let e = 0, r = i.length; e < r; e++) Yo(i[e], t, n, !0) } } class Ko { constructor(e = 1, t = 0, n = 0) { this.radius = e, this.phi = t, this.theta = n } set(e, t, n) { return this.radius = e, this.phi = t, this.theta = n, this } copy(e) { return this.radius = e.radius, this.phi = e.phi, this.theta = e.theta, this } makeSafe() { const e = 1e-6; return this.phi = Ot(this.phi, e, Math.PI - e), this } setFromVector3(e) { return this.setFromCartesianCoords(e.x, e.y, e.z) } setFromCartesianCoords(e, t, n) { return this.radius = Math.sqrt(e * e + t * t + n * n), 0 === this.radius ? (this.theta = 0, this.phi = 0) : (this.theta = Math.atan2(e, n), this.phi = Math.acos(Ot(t / this.radius, -1, 1))), this } clone() { return (new this.constructor).copy(this) } } class qo { constructor() { this.type = "ShapePath", this.color = new Wi, this.subPaths = [], this.currentPath = null } moveTo(e, t) { return this.currentPath = new as, this.subPaths.push(this.currentPath), this.currentPath.moveTo(e, t), this } lineTo(e, t) { return this.currentPath.lineTo(e, t), this } quadraticCurveTo(e, t, n, i) { return this.currentPath.quadraticCurveTo(e, t, n, i), this } bezierCurveTo(e, t, n, i, r, a) { return this.currentPath.bezierCurveTo(e, t, n, i, r, a), this } splineThru(e) { return this.currentPath.splineThru(e), this } toShapes(e) { function t(e, t) { const n = t.length; let i = !1; for (let r = n - 1, a = 0; a < n; r = a++) { let n = t[r], s = t[a], o = s.x - n.x, l = s.y - n.y; if (Math.abs(l) > Number.EPSILON) { if (l < 0 && (n = t[a], o = -o, s = t[r], l = -l), e.y < n.y || e.y > s.y) continue; if (e.y === n.y) { if (e.x === n.x) return !0 } else { const t = l * (e.x - n.x) - o * (e.y - n.y); if (0 === t) return !0; if (t < 0) continue; i = !i } } else { if (e.y !== n.y) continue; if (s.x <= e.x && e.x <= n.x || n.x <= e.x && e.x <= s.x) return !0 } } return i } const n = Rs.isClockWise, i = this.subPaths; if (0 === i.length) return []; let r, a, s; const o = []; if (1 === i.length) return a = i[0], s = new ss, s.curves = a.curves, o.push(s), o; let l = !n(i[0].getPoints()); l = e ? !l : l; const c = [], h = []; let d, u, p = [], f = 0; h[f] = void 0, p[f] = []; for (let t = 0, s = i.length; t < s; t++) a = i[t], d = a.getPoints(), r = n(d), r = e ? !r : r, r ? (!l && h[f] && f++, h[f] = { s: new ss, p: d }, h[f].s.curves = a.curves, l && f++, p[f] = []) : p[f].push({ h: a, p: d[0] }); if (!h[0]) return function(e) { const t = []; for (let n = 0, i = e.length; n < i; n++) { const i = e[n], r = new ss; r.curves = i.curves, t.push(r) } return t }(i); if (h.length > 1) { let e = !1, n = 0; for (let e = 0, t = h.length; e < t; e++) c[e] = []; for (let i = 0, r = h.length; i < r; i++) { const r = p[i]; for (let a = 0; a < r.length; a++) { const s = r[a]; let o = !0; for (let r = 0; r < h.length; r++) t(s.p, h[r].p) && (i !== r && n++, o ? (o = !1, c[r].push(s)) : e = !0); o && c[i].push(s) } } n > 0 && !1 === e && (p = c) } for (let e = 0, t = h.length; e < t; e++) { s = h[e].s, o.push(s), u = p[e]; for (let e = 0, t = u.length; e < t; e++) s.holes.push(u[e].h) } return o } } class Xo extends Lt { constructor(e, t = null) { super(), this.object = e, this.domElement = t, this.enabled = !0, this.state = -1, this.keys = {}, this.mouseButtons = { LEFT: null, MIDDLE: null, RIGHT: null }, this.touches = { ONE: null, TWO: null } } connect() {} disconnect() {} dispose() {} update() {} } function Zo(e, t, n, i) { const r = function(e) { switch (e) { case pe: case fe: return { byteLength: 1, components: 1 }; case ge: case me: case Ae: return { byteLength: 2, components: 1 }; case be: case xe: return { byteLength: 2, components: 4 }; case we: case ve: case ye: return { byteLength: 4, components: 1 }; case Ee: return { byteLength: 4, components: 3 } } throw new Error(`Unknown texture type ${e}.`) }(i); switch (n) { case 1021: case 1024: return e * t; case 1025: return e * t * 2; case _e: case Ce: return e * t / r.components * r.byteLength; case 1030: case Pe: return e * t * 2 / r.components * r.byteLength; case 1022: return e * t * 3 / r.components * r.byteLength; case Se: case Ie: return e * t * 4 / r.components * r.byteLength; case Re: case Le: return Math.floor((e + 3) / 4) * Math.floor((t + 3) / 4) * 8; case De: case Ne: return Math.floor((e + 3) / 4) * Math.floor((t + 3) / 4) * 16; case Ue: case Oe: return Math.max(e, 16) * Math.max(t, 8) / 4; case Be: case ze: return Math.max(e, 8) * Math.max(t, 8) / 2; case Fe: case We: return Math.floor((e + 3) / 4) * Math.floor((t + 3) / 4) * 8; case Ve: case He: return Math.floor((e + 3) / 4) * Math.floor((t + 3) / 4) * 16; case Ge: return Math.floor((e + 4) / 5) * Math.floor((t + 3) / 4) * 16; case je: return Math.floor((e + 4) / 5) * Math.floor((t + 4) / 5) * 16; case Qe: return Math.floor((e + 5) / 6) * Math.floor((t + 4) / 5) * 16; case Ye: return Math.floor((e + 5) / 6) * Math.floor((t + 5) / 6) * 16; case Ke: return Math.floor((e + 7) / 8) * Math.floor((t + 4) / 5) * 16; case qe: return Math.floor((e + 7) / 8) * Math.floor((t + 5) / 6) * 16; case Xe: return Math.floor((e + 7) / 8) * Math.floor((t + 7) / 8) * 16; case Ze: return Math.floor((e + 9) / 10) * Math.floor((t + 4) / 5) * 16; case Je: return Math.floor((e + 9) / 10) * Math.floor((t + 5) / 6) * 16; case $e: return Math.floor((e + 9) / 10) * Math.floor((t + 7) / 8) * 16; case et: return Math.floor((e + 9) / 10) * Math.floor((t + 9) / 10) * 16; case tt: return Math.floor((e + 11) / 12) * Math.floor((t + 9) / 10) * 16; case nt: return Math.floor((e + 11) / 12) * Math.floor((t + 11) / 12) * 16; case it: case rt: case at: return Math.ceil(e / 4) * Math.ceil(t / 4) * 16; case 36283: case st: return Math.ceil(e / 4) * Math.ceil(t / 4) * 8; case ot: case lt: return Math.ceil(e / 4) * Math.ceil(t / 4) * 16 } throw new Error(`Unable to determine texture byte length for ${n} format.`) } var Jo; "undefined" != typeof __THREE_DEVTOOLS__ && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register", { detail: { revision: m } })), "undefined" != typeof window && (window.__THREE__ ? console.warn("WARNING: Multiple instances of Three.js being imported.") : window.__THREE__ = m), function(e) { e[e.ImperialUnitsEnabled = 0] = "ImperialUnitsEnabled", e[e.ResetHintEnabled = 1] = "ResetHintEnabled", e[e.GhostCarEnabled = 2] = "GhostCarEnabled", e[e.DefaultCameraMode = 3] = "DefaultCameraMode", e[e.CockpitCameraToggle = 4] = "CockpitCameraToggle", e[e.Checkpoints = 5] = "Checkpoints", e[e.Timer = 6] = "Timer", e[e.Speedometer = 7] = "Speedometer", e[e.Language = 8] = "Language", e[e.CarShadowQuality = 9] = "CarShadowQuality", e[e.TrackShadowEnabled = 10] = "TrackShadowEnabled", e[e.CloudsEnabled = 11] = "CloudsEnabled", e[e.ParticlesEnabled = 12] = "ParticlesEnabled", e[e.SkidmarksEnabled = 13] = "SkidmarksEnabled", e[e.RenderScale = 14] = "RenderScale", e[e.Antialiasing = 15] = "Antialiasing", e[e.SoundEffectVolume = 16] = "SoundEffectVolume", e[e.MusicVolume = 17] = "MusicVolume", e[e.CheckpointVolume = 18] = "CheckpointVolume" }(Jo || (Jo = {})); const $o = Jo; var el, tl, nl, il, rl, al, sl, ol, ll, cl, hl = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, dl = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; tl = new WeakMap, nl = new WeakMap, il = new WeakMap, rl = new WeakMap, al = new WeakMap, sl = new WeakMap, el = new WeakSet, ol = function e(t, n) { const i = this.context; if (null == i) n(null); else if (0 == t.length) n(null); else { const r = t[0], a = new XMLHttpRequest; a.open("GET", r, !0), a.responseType = "arraybuffer", a.onload = () => { i.decodeAudioData(a.response).then((e => { n(e) })).catch((() => { dl(this, el, "m", e).call(this, t.slice(1), n) })) }, a.send() } }, ll = function(e) { var t; let n = Math.min(Math.max(e.getSettingFloat($o.SoundEffectVolume), 0), 1); Number.isNaN(n) && (n = 0), null == dl(this, al, "f") && null != this.context && null != this.destinationMaster ? (hl(this, al, this.context.createGain(), "f"), dl(this, al, "f").gain.value = n, dl(this, al, "f").connect(this.destinationMaster)) : null === (t = dl(this, al, "f")) || void 0 === t || t.gain.setTargetAtTime(n, 0, .1) }, cl = function(e, t, n) { if (t && dl(this, tl, "f").hasLoaded()) { if (null == dl(this, il, "f")) { const e = this.getBuffer("music"); if (null != e && null != this.context && null != this.destinationMaster) { const t = this.context.createBufferSource(); t.buffer = e, t.loop = !0; const n = this.context.createGain(); n.gain.value = 0, t.connect(n), n.connect(this.destinationMaster), t.start(0), hl(this, il, { source: t, gain: n }, "f") } } else { let e = Math.min(Math.max(n.getSettingFloat($o.MusicVolume), 0), 1); Number.isNaN(e) && (e = 0), dl(this, il, "f").gain.gain.setTargetAtTime(.25 * e, 0, .5) } hl(this, rl, 0, "f") } else null != dl(this, il, "f") && (dl(this, il, "f").gain.gain.setTargetAtTime(0, 0, .5), dl(this, rl, "f") >= 5 ? (dl(this, il, "f").source.stop(), hl(this, il, null, "f")) : hl(this, rl, dl(this, rl, "f") + e, "f")) }; const ul = class { constructor(e) { el.add(this), tl.set(this, void 0), this.context = null, nl.set(this, new Map), il.set(this, null), rl.set(this, 0), al.set(this, null), sl.set(this, null), hl(this, tl, e, "f"); try { const e = new(window.AudioContext || window.webkitAudioContext); if ("running" != e.state) { const t = ["click", "contextmenu", "auxclick", "dblclick", "mousedown", "mouseup", "pointerup", "touchend", "keydown", "keyup"], n = () => { e.resume().catch((e => { console.error(e) })); for (const e of t) window.removeEventListener(e, n) }; for (const e of t) window.addEventListener(e, n) } this.context = e } catch (e) { this.context = null, console.error("Failed to create audio context: ", e) } null != this.context ? (hl(this, sl, this.context.createGain(), "f"), dl(this, sl, "f").gain.value = 1, dl(this, sl, "f").connect(this.context.destination)) : hl(this, sl, null, "f") } get destinationSfx() { return dl(this, al, "f") } get destinationMaster() { return dl(this, sl, "f") } mute() { null != dl(this, sl, "f") && dl(this, sl, "f").gain.setTargetAtTime(0, 0, .25) } unmute() { null != dl(this, sl, "f") && dl(this, sl, "f").gain.setTargetAtTime(1, 0, .25) } load(e, t) { dl(this, tl, "f").addResource(), dl(this, el, "m", ol).call(this, t, (t => { dl(this, tl, "f").loadedResource(), null == t ? (console.warn('Audio "' + e + '" failed to load'), dl(this, nl, "f").set(e, null)) : dl(this, nl, "f").set(e, t) })) } getBuffer(e) { var t; return null == this.context ? null : dl(this, nl, "f").has(e) && null !== (t = dl(this, nl, "f").get(e)) && void 0 !== t ? t : null } playUIClick() { const e = this.getBuffer("click"); if (null != e && null != this.context && null != this.destinationSfx) { const t = this.context.createBufferSource(); t.buffer = e; const n = this.context.createGain(); n.gain.value = .0075, t.connect(n), n.connect(this.destinationSfx), t.start(0) } } refreshListener(e) { if (null != this.context) { const t = new yn, n = new wn, i = new yn; e.camera.matrix.decompose(t, n, i); const r = this.context.listener; r.positionX && r.positionY && r.positionZ ? (r.positionX.value = t.x, r.positionY.value = t.y, r.positionZ.value = t.z) : r.setPosition(t.x, t.y, t.z); const a = new yn(0, 0, -1); a.applyQuaternion(n); const s = new yn(0, 1, 0); s.applyQuaternion(n), r.forwardX && r.forwardY && r.forwardZ && r.upX && r.upY && r.upZ ? (r.forwardX.value = a.x, r.forwardY.value = a.y, r.forwardZ.value = a.z, r.upX.value = s.x, r.upY.value = s.y, r.upZ.value = s.z) : r.setOrientation(a.x, a.y, a.z, s.x, s.y, s.z) } } update(e, t, n, i) { this.refreshListener(n), dl(this, el, "m", ll).call(this, i), dl(this, el, "m", cl).call(this, e, t, i) } }; function pl(e, t = !1) { const n = null !== e[0].index, i = new Set(Object.keys(e[0].attributes)), r = new Set(Object.keys(e[0].morphAttributes)), a = {}, s = {}, o = e[0].morphTargetsRelative, l = new sr; let c = 0; for (let h = 0; h < e.length; ++h) { const d = e[h]; let u = 0; if (n !== (null !== d.index)) return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + h + ". All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them."), null; for (const e in d.attributes) { if (!i.has(e)) return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + h + '. All geometries must have compatible attributes; make sure "' + e + '" attribute exists among all geometries, or in none of them.'), null; void 0 === a[e] && (a[e] = []), a[e].push(d.attributes[e]), u++ } if (u !== i.size) return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + h + ". Make sure all geometries have the same number of attributes."), null; if (o !== d.morphTargetsRelative) return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + h + ". .morphTargetsRelative must be consistent throughout all geometries."), null; for (const e in d.morphAttributes) { if (!r.has(e)) return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + h + ". .morphAttributes must be consistent throughout all geometries."), null; void 0 === s[e] && (s[e] = []), s[e].push(d.morphAttributes[e]) } if (t) { let e; if (n) e = d.index.count; else { if (void 0 === d.attributes.position) return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + h + ". The geometry must have either an index or a position attribute"), null; e = d.attributes.position.count } l.addGroup(c, e, h), c += e } } if (n) { let t = 0; const n = []; for (let i = 0; i < e.length; ++i) { const r = e[i].index; for (let e = 0; e < r.count; ++e) n.push(r.getX(e) + t); t += e[i].attributes.position.count } l.setIndex(n) } for (const e in a) { const t = fl(a[e]); if (!t) return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the " + e + " attribute."), null; l.setAttribute(e, t) } for (const e in s) { const t = s[e][0].length; if (0 === t) break; l.morphAttributes = l.morphAttributes || {}, l.morphAttributes[e] = []; for (let n = 0; n < t; ++n) { const t = []; for (let i = 0; i < s[e].length; ++i) t.push(s[e][i][n]); const i = fl(t); if (!i) return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the " + e + " morphAttribute."), null; l.morphAttributes[e].push(i) } } return l } function fl(e) { let t, n, i, r = -1, a = 0; for (let s = 0; s < e.length; ++s) { const o = e[s]; if (void 0 === t && (t = o.array.constructor), t !== o.array.constructor) return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes."), null; if (void 0 === n && (n = o.itemSize), n !== o.itemSize) return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes."), null; if (void 0 === i && (i = o.normalized), i !== o.normalized) return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes."), null; if (-1 === r && (r = o.gpuType), r !== o.gpuType) return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes."), null; a += o.count * n } const s = new t(a), o = new qi(s, n, i); let l = 0; for (let t = 0; t < e.length; ++t) { const i = e[t]; if (i.isInterleavedBufferAttribute) { const e = l / n; for (let t = 0, r = i.count; t < r; t++) for (let r = 0; r < n; r++) { const n = i.getComponent(t, r); o.setComponent(t + e, r, n) } } else s.set(i.array, l); l += i.count * n } return void 0 !== r && (o.gpuType = r), o } function ml(e, t = 1e-4) { t = Math.max(t, Number.EPSILON); const n = {}, i = e.getIndex(), r = e.getAttribute("position"), a = i ? i.count : r.count; let s = 0; const o = Object.keys(e.attributes), l = {}, c = {}, h = [], d = ["getX", "getY", "getZ", "getW"], u = ["setX", "setY", "setZ", "setW"]; for (let t = 0, n = o.length; t < n; t++) { const n = o[t], i = e.attributes[n]; l[n] = new i.constructor(new i.array.constructor(i.count * i.itemSize), i.itemSize, i.normalized); const r = e.morphAttributes[n]; r && (c[n] || (c[n] = []), r.forEach(((e, t) => { const i = new e.array.constructor(e.count * e.itemSize); c[n][t] = new e.constructor(i, e.itemSize, e.normalized) }))) } const p = .5 * t, f = Math.log10(1 / t), m = Math.pow(10, f), g = p * m; for (let t = 0; t < a; t++) { const r = i ? i.getX(t) : t; let a = ""; for (let t = 0, n = o.length; t < n; t++) { const n = o[t], i = e.getAttribute(n), s = i.itemSize; for (let e = 0; e < s; e++) a += ~~(i[d[e]](r) * m + g) + "," } if (a in n) h.push(n[a]); else { for (let t = 0, n = o.length; t < n; t++) { const n = o[t], i = e.getAttribute(n), a = e.morphAttributes[n], h = i.itemSize, p = l[n], f = c[n]; for (let e = 0; e < h; e++) { const t = d[e], n = u[e]; if (p[n](s, i[t](r)), a) for (let e = 0, i = a.length; e < i; e++) f[e][n](s, a[e][t](r)) } } n[a] = s, h.push(s), s++ } } const v = e.clone(); for (const t in e.attributes) { const e = l[t]; if (v.setAttribute(t, new e.constructor(e.array.slice(0, s * e.itemSize), e.itemSize, e.normalized)), t in c) for (let e = 0; e < c[t].length; e++) { const n = c[t][e]; v.morphAttributes[t][e] = new n.constructor(n.array.slice(0, s * n.itemSize), n.itemSize, n.normalized) } } return v.setIndex(h), v } function gl(e, t) { if (0 === t) return console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles."), e; if (2 === t || 1 === t) { let n = e.getIndex(); if (null === n) { const t = [], i = e.getAttribute("position"); if (void 0 === i) return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."), e; for (let e = 0; e < i.count; e++) t.push(e); e.setIndex(t), n = e.getIndex() } const i = n.count - 2, r = []; if (2 === t) for (let e = 1; e <= i; e++) r.push(n.getX(0)), r.push(n.getX(e)), r.push(n.getX(e + 1)); else for (let e = 0; e < i; e++) e % 2 == 0 ? (r.push(n.getX(e)), r.push(n.getX(e + 1)), r.push(n.getX(e + 2))) : (r.push(n.getX(e + 2)), r.push(n.getX(e + 1)), r.push(n.getX(e))); r.length / 3 !== i && console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles."); const a = e.clone(); return a.setIndex(r), a.clearGroups(), a } return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:", t), e } class vl extends uo { constructor(e) { super(e), this.dracoLoader = null, this.ktx2Loader = null, this.meshoptDecoder = null, this.pluginCallbacks = [], this.register((function(e) { return new kl(e) })), this.register((function(e) { return new El(e) })), this.register((function(e) { return new Ll(e) })), this.register((function(e) { return new Dl(e) })), this.register((function(e) { return new Nl(e) })), this.register((function(e) { return new Ml(e) })), this.register((function(e) { return new Tl(e) })), this.register((function(e) { return new _l(e) })), this.register((function(e) { return new Cl(e) })), this.register((function(e) { return new xl(e) })), this.register((function(e) { return new Pl(e) })), this.register((function(e) { return new Sl(e) })), this.register((function(e) { return new Rl(e) })), this.register((function(e) { return new Il(e) })), this.register((function(e) { return new Al(e) })), this.register((function(e) { return new Bl(e) })), this.register((function(e) { return new Ul(e) })) } load(e, t, n, i) { const r = this; let a; if ("" !== this.resourcePath) a = this.resourcePath; else if ("" !== this.path) { const t = Do.extractUrlBase(e); a = Do.resolveURL(t, this.path) } else a = Do.extractUrlBase(e); this.manager.itemStart(e); const s = function(t) { i ? i(t) : console.error(t), r.manager.itemError(e), r.manager.itemEnd(e) }, o = new mo(this.manager); o.setPath(this.path), o.setResponseType("arraybuffer"), o.setRequestHeader(this.requestHeader), o.setWithCredentials(this.withCredentials), o.load(e, (function(n) { try { r.parse(n, a, (function(n) { t(n), r.manager.itemEnd(e) }), s) } catch (e) { s(e) } }), n, s) } setDRACOLoader(e) { return this.dracoLoader = e, this } setKTX2Loader(e) { return this.ktx2Loader = e, this } setMeshoptDecoder(e) { return this.meshoptDecoder = e, this } register(e) { return -1 === this.pluginCallbacks.indexOf(e) && this.pluginCallbacks.push(e), this } unregister(e) { return -1 !== this.pluginCallbacks.indexOf(e) && this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(e), 1), this } parse(e, t, n, i) { let r; const a = {}, s = {}, o = new TextDecoder; if ("string" == typeof e) r = JSON.parse(e); else if (e instanceof ArrayBuffer) { if (o.decode(new Uint8Array(e, 0, 4)) === zl) { try { a[yl.KHR_BINARY_GLTF] = new Wl(e) } catch (e) { return void(i && i(e)) } r = JSON.parse(a[yl.KHR_BINARY_GLTF].content) } else r = JSON.parse(o.decode(e)) } else r = e; if (void 0 === r.asset || r.asset.version[0] < 2) return void(i && i(new Error("THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported."))); const l = new uc(r, { path: t || this.resourcePath || "", crossOrigin: this.crossOrigin, requestHeader: this.requestHeader, manager: this.manager, ktx2Loader: this.ktx2Loader, meshoptDecoder: this.meshoptDecoder }); l.fileLoader.setRequestHeader(this.requestHeader); for (let e = 0; e < this.pluginCallbacks.length; e++) { const t = this.pluginCallbacks[e](l); t.name || console.error("THREE.GLTFLoader: Invalid plugin found: missing name"), s[t.name] = t, a[t.name] = !0 } if (r.extensionsUsed) for (let e = 0; e < r.extensionsUsed.length; ++e) { const t = r.extensionsUsed[e], n = r.extensionsRequired || []; switch (t) { case yl.KHR_MATERIALS_UNLIT: a[t] = new bl; break; case yl.KHR_DRACO_MESH_COMPRESSION: a[t] = new Vl(r, this.dracoLoader); break; case yl.KHR_TEXTURE_TRANSFORM: a[t] = new Hl; break; case yl.KHR_MESH_QUANTIZATION: a[t] = new Gl; break; default: n.indexOf(t) >= 0 && void 0 === s[t] && console.warn('THREE.GLTFLoader: Unknown extension "' + t + '".') } } l.setExtensions(a), l.setPlugins(s), l.parse(n, i) } parseAsync(e, t) { const n = this; return new Promise((function(i, r) { n.parse(e, t, i, r) })) } } function wl() { let e = {}; return { get: function(t) { return e[t] }, add: function(t, n) { e[t] = n }, remove: function(t) { delete e[t] }, removeAll: function() { e = {} } } } const yl = { KHR_BINARY_GLTF: "KHR_binary_glTF", KHR_DRACO_MESH_COMPRESSION: "KHR_draco_mesh_compression", KHR_LIGHTS_PUNCTUAL: "KHR_lights_punctual", KHR_MATERIALS_CLEARCOAT: "KHR_materials_clearcoat", KHR_MATERIALS_DISPERSION: "KHR_materials_dispersion", KHR_MATERIALS_IOR: "KHR_materials_ior", KHR_MATERIALS_SHEEN: "KHR_materials_sheen", KHR_MATERIALS_SPECULAR: "KHR_materials_specular", KHR_MATERIALS_TRANSMISSION: "KHR_materials_transmission", KHR_MATERIALS_IRIDESCENCE: "KHR_materials_iridescence", KHR_MATERIALS_ANISOTROPY: "KHR_materials_anisotropy", KHR_MATERIALS_UNLIT: "KHR_materials_unlit", KHR_MATERIALS_VOLUME: "KHR_materials_volume", KHR_TEXTURE_BASISU: "KHR_texture_basisu", KHR_TEXTURE_TRANSFORM: "KHR_texture_transform", KHR_MESH_QUANTIZATION: "KHR_mesh_quantization", KHR_MATERIALS_EMISSIVE_STRENGTH: "KHR_materials_emissive_strength", EXT_MATERIALS_BUMP: "EXT_materials_bump", EXT_TEXTURE_WEBP: "EXT_texture_webp", EXT_TEXTURE_AVIF: "EXT_texture_avif", EXT_MESHOPT_COMPRESSION: "EXT_meshopt_compression", EXT_MESH_GPU_INSTANCING: "EXT_mesh_gpu_instancing" }; class Al { constructor(e) { this.parser = e, this.name = yl.KHR_LIGHTS_PUNCTUAL, this.cache = { refs: {}, uses: {} } } _markDefs() { const e = this.parser, t = this.parser.json.nodes || []; for (let n = 0, i = t.length; n < i; n++) { const i = t[n]; i.extensions && i.extensions[this.name] && void 0 !== i.extensions[this.name].light && e._addNodeRef(this.cache, i.extensions[this.name].light) } } _loadLight(e) { const t = this.parser, n = "light:" + e; let i = t.cache.get(n); if (i) return i; const r = t.json, a = ((r.extensions && r.extensions[this.name] || {}).lights || [])[e]; let s; const o = new Wi(16777215); void 0 !== a.color && o.setRGB(a.color[0], a.color[1], a.color[2], vt); const l = void 0 !== a.range ? a.range : 0; switch (a.type) { case "directional": s = new Lo(o), s.target.position.set(0, 0, -1), s.add(s.target); break; case "point": s = new Po(o), s.distance = l; break; case "spot": s = new So(o), s.distance = l, a.spot = a.spot || {}, a.spot.innerConeAngle = void 0 !== a.spot.innerConeAngle ? a.spot.innerConeAngle : 0, a.spot.outerConeAngle = void 0 !== a.spot.outerConeAngle ? a.spot.outerConeAngle : Math.PI / 4, s.angle = a.spot.outerConeAngle, s.penumbra = 1 - a.spot.innerConeAngle / a.spot.outerConeAngle, s.target.position.set(0, 0, -1), s.add(s.target); break; default: throw new Error("THREE.GLTFLoader: Unexpected light type: " + a.type) } return s.position.set(0, 0, 0), sc(s, a), void 0 !== a.intensity && (s.intensity = a.intensity), s.name = t.createUniqueName(a.name || "light_" + e), i = Promise.resolve(s), t.cache.add(n, i), i } getDependency(e, t) { if ("light" === e) return this._loadLight(t) } createNodeAttachment(e) { const t = this, n = this.parser, i = n.json.nodes[e], r = (i.extensions && i.extensions[this.name] || {}).light; return void 0 === r ? null : this._loadLight(r).then((function(e) { return n._getNodeRef(t.cache, r, e) })) } } class bl { constructor() { this.name = yl.KHR_MATERIALS_UNLIT } getMaterialType() { return ji } extendParams(e, t, n) { const i = []; e.color = new Wi(1, 1, 1), e.opacity = 1; const r = t.pbrMetallicRoughness; if (r) { if (Array.isArray(r.baseColorFactor)) { const t = r.baseColorFactor; e.color.setRGB(t[0], t[1], t[2], vt), e.opacity = t[3] } void 0 !== r.baseColorTexture && i.push(n.assignTexture(e, "map", r.baseColorTexture, gt)) } return Promise.all(i) } } class xl { constructor(e) { this.parser = e, this.name = yl.KHR_MATERIALS_EMISSIVE_STRENGTH } extendMaterialParams(e, t) { const n = this.parser.json.materials[e]; if (!n.extensions || !n.extensions[this.name]) return Promise.resolve(); const i = n.extensions[this.name].emissiveStrength; return void 0 !== i && (t.emissiveIntensity = i), Promise.resolve() } } class kl { constructor(e) { this.parser = e, this.name = yl.KHR_MATERIALS_CLEARCOAT } getMaterialType(e) { const t = this.parser.json.materials[e]; return t.extensions && t.extensions[this.name] ? Os : null } extendMaterialParams(e, t) { const n = this.parser, i = n.json.materials[e]; if (!i.extensions || !i.extensions[this.name]) return Promise.resolve(); const r = [], a = i.extensions[this.name]; if (void 0 !== a.clearcoatFactor && (t.clearcoat = a.clearcoatFactor), void 0 !== a.clearcoatTexture && r.push(n.assignTexture(t, "clearcoatMap", a.clearcoatTexture)), void 0 !== a.clearcoatRoughnessFactor && (t.clearcoatRoughness = a.clearcoatRoughnessFactor), void 0 !== a.clearcoatRoughnessTexture && r.push(n.assignTexture(t, "clearcoatRoughnessMap", a.clearcoatRoughnessTexture)), void 0 !== a.clearcoatNormalTexture && (r.push(n.assignTexture(t, "clearcoatNormalMap", a.clearcoatNormalTexture)), void 0 !== a.clearcoatNormalTexture.scale)) { const e = a.clearcoatNormalTexture.scale; t.clearcoatNormalScale = new jt(e, e) } return Promise.all(r) } } class El { constructor(e) { this.parser = e, this.name = yl.KHR_MATERIALS_DISPERSION } getMaterialType(e) { const t = this.parser.json.materials[e]; return t.extensions && t.extensions[this.name] ? Os : null } extendMaterialParams(e, t) { const n = this.parser.json.materials[e]; if (!n.extensions || !n.extensions[this.name]) return Promise.resolve(); const i = n.extensions[this.name]; return t.dispersion = void 0 !== i.dispersion ? i.dispersion : 0, Promise.resolve() } } class Sl { constructor(e) { this.parser = e, this.name = yl.KHR_MATERIALS_IRIDESCENCE } getMaterialType(e) { const t = this.parser.json.materials[e]; return t.extensions && t.extensions[this.name] ? Os : null } extendMaterialParams(e, t) { const n = this.parser, i = n.json.materials[e]; if (!i.extensions || !i.extensions[this.name]) return Promise.resolve(); const r = [], a = i.extensions[this.name]; return void 0 !== a.iridescenceFactor && (t.iridescence = a.iridescenceFactor), void 0 !== a.iridescenceTexture && r.push(n.assignTexture(t, "iridescenceMap", a.iridescenceTexture)), void 0 !== a.iridescenceIor && (t.iridescenceIOR = a.iridescenceIor), void 0 === t.iridescenceThicknessRange && (t.iridescenceThicknessRange = [100, 400]), void 0 !== a.iridescenceThicknessMinimum && (t.iridescenceThicknessRange[0] = a.iridescenceThicknessMinimum), void 0 !== a.iridescenceThicknessMaximum && (t.iridescenceThicknessRange[1] = a.iridescenceThicknessMaximum), void 0 !== a.iridescenceThicknessTexture && r.push(n.assignTexture(t, "iridescenceThicknessMap", a.iridescenceThicknessTexture)), Promise.all(r) } } class Ml { constructor(e) { this.parser = e, this.name = yl.KHR_MATERIALS_SHEEN } getMaterialType(e) { const t = this.parser.json.materials[e]; return t.extensions && t.extensions[this.name] ? Os : null } extendMaterialParams(e, t) { const n = this.parser, i = n.json.materials[e]; if (!i.extensions || !i.extensions[this.name]) return Promise.resolve(); const r = []; t.sheenColor = new Wi(0, 0, 0), t.sheenRoughness = 0, t.sheen = 1; const a = i.extensions[this.name]; if (void 0 !== a.sheenColorFactor) { const e = a.sheenColorFactor; t.sheenColor.setRGB(e[0], e[1], e[2], vt) } return void 0 !== a.sheenRoughnessFactor && (t.sheenRoughness = a.sheenRoughnessFactor), void 0 !== a.sheenColorTexture && r.push(n.assignTexture(t, "sheenColorMap", a.sheenColorTexture, gt)), void 0 !== a.sheenRoughnessTexture && r.push(n.assignTexture(t, "sheenRoughnessMap", a.sheenRoughnessTexture)), Promise.all(r) } } class Tl { constructor(e) { this.parser = e, this.name = yl.KHR_MATERIALS_TRANSMISSION } getMaterialType(e) { const t = this.parser.json.materials[e]; return t.extensions && t.extensions[this.name] ? Os : null } extendMaterialParams(e, t) { const n = this.parser, i = n.json.materials[e]; if (!i.extensions || !i.extensions[this.name]) return Promise.resolve(); const r = [], a = i.extensions[this.name]; return void 0 !== a.transmissionFactor && (t.transmission = a.transmissionFactor), void 0 !== a.transmissionTexture && r.push(n.assignTexture(t, "transmissionMap", a.transmissionTexture)), Promise.all(r) } } class _l { constructor(e) { this.parser = e, this.name = yl.KHR_MATERIALS_VOLUME } getMaterialType(e) { const t = this.parser.json.materials[e]; return t.extensions && t.extensions[this.name] ? Os : null } extendMaterialParams(e, t) { const n = this.parser, i = n.json.materials[e]; if (!i.extensions || !i.extensions[this.name]) return Promise.resolve(); const r = [], a = i.extensions[this.name]; t.thickness = void 0 !== a.thicknessFactor ? a.thicknessFactor : 0, void 0 !== a.thicknessTexture && r.push(n.assignTexture(t, "thicknessMap", a.thicknessTexture)), t.attenuationDistance = a.attenuationDistance || 1 / 0; const s = a.attenuationColor || [1, 1, 1]; return t.attenuationColor = (new Wi).setRGB(s[0], s[1], s[2], vt), Promise.all(r) } } class Cl { constructor(e) { this.parser = e, this.name = yl.KHR_MATERIALS_IOR } getMaterialType(e) { const t = this.parser.json.materials[e]; return t.extensions && t.extensions[this.name] ? Os : null } extendMaterialParams(e, t) { const n = this.parser.json.materials[e]; if (!n.extensions || !n.extensions[this.name]) return Promise.resolve(); const i = n.extensions[this.name]; return t.ior = void 0 !== i.ior ? i.ior : 1.5, Promise.resolve() } } class Pl { constructor(e) { this.parser = e, this.name = yl.KHR_MATERIALS_SPECULAR } getMaterialType(e) { const t = this.parser.json.materials[e]; return t.extensions && t.extensions[this.name] ? Os : null } extendMaterialParams(e, t) { const n = this.parser, i = n.json.materials[e]; if (!i.extensions || !i.extensions[this.name]) return Promise.resolve(); const r = [], a = i.extensions[this.name]; t.specularIntensity = void 0 !== a.specularFactor ? a.specularFactor : 1, void 0 !== a.specularTexture && r.push(n.assignTexture(t, "specularIntensityMap", a.specularTexture)); const s = a.specularColorFactor || [1, 1, 1]; return t.specularColor = (new Wi).setRGB(s[0], s[1], s[2], vt), void 0 !== a.specularColorTexture && r.push(n.assignTexture(t, "specularColorMap", a.specularColorTexture, gt)), Promise.all(r) } } class Il { constructor(e) { this.parser = e, this.name = yl.EXT_MATERIALS_BUMP } getMaterialType(e) { const t = this.parser.json.materials[e]; return t.extensions && t.extensions[this.name] ? Os : null } extendMaterialParams(e, t) { const n = this.parser, i = n.json.materials[e]; if (!i.extensions || !i.extensions[this.name]) return Promise.resolve(); const r = [], a = i.extensions[this.name]; return t.bumpScale = void 0 !== a.bumpFactor ? a.bumpFactor : 1, void 0 !== a.bumpTexture && r.push(n.assignTexture(t, "bumpMap", a.bumpTexture)), Promise.all(r) } } class Rl { constructor(e) { this.parser = e, this.name = yl.KHR_MATERIALS_ANISOTROPY } getMaterialType(e) { const t = this.parser.json.materials[e]; return t.extensions && t.extensions[this.name] ? Os : null } extendMaterialParams(e, t) { const n = this.parser, i = n.json.materials[e]; if (!i.extensions || !i.extensions[this.name]) return Promise.resolve(); const r = [], a = i.extensions[this.name]; return void 0 !== a.anisotropyStrength && (t.anisotropy = a.anisotropyStrength), void 0 !== a.anisotropyRotation && (t.anisotropyRotation = a.anisotropyRotation), void 0 !== a.anisotropyTexture && r.push(n.assignTexture(t, "anisotropyMap", a.anisotropyTexture)), Promise.all(r) } } class Ll { constructor(e) { this.parser = e, this.name = yl.KHR_TEXTURE_BASISU } loadTexture(e) { const t = this.parser, n = t.json, i = n.textures[e]; if (!i.extensions || !i.extensions[this.name]) return null; const r = i.extensions[this.name], a = t.options.ktx2Loader; if (!a) { if (n.extensionsRequired && n.extensionsRequired.indexOf(this.name) >= 0) throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures"); return null } return t.loadTextureImage(e, r.source, a) } } class Dl { constructor(e) { this.parser = e, this.name = yl.EXT_TEXTURE_WEBP, this.isSupported = null } loadTexture(e) { const t = this.name, n = this.parser, i = n.json, r = i.textures[e]; if (!r.extensions || !r.extensions[t]) return null; const a = r.extensions[t], s = i.images[a.source]; let o = n.textureLoader; if (s.uri) { const e = n.options.manager.getHandler(s.uri); null !== e && (o = e) } return this.detectSupport().then((function(r) { if (r) return n.loadTextureImage(e, a.source, o); if (i.extensionsRequired && i.extensionsRequired.indexOf(t) >= 0) throw new Error("THREE.GLTFLoader: WebP required by asset but unsupported."); return n.loadTexture(e) })) } detectSupport() { return this.isSupported || (this.isSupported = new Promise((function(e) { const t = new Image; t.src = "data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA", t.onload = t.onerror = function() { e(1 === t.height) } }))), this.isSupported } } class Nl { constructor(e) { this.parser = e, this.name = yl.EXT_TEXTURE_AVIF, this.isSupported = null } loadTexture(e) { const t = this.name, n = this.parser, i = n.json, r = i.textures[e]; if (!r.extensions || !r.extensions[t]) return null; const a = r.extensions[t], s = i.images[a.source]; let o = n.textureLoader; if (s.uri) { const e = n.options.manager.getHandler(s.uri); null !== e && (o = e) } return this.detectSupport().then((function(r) { if (r) return n.loadTextureImage(e, a.source, o); if (i.extensionsRequired && i.extensionsRequired.indexOf(t) >= 0) throw new Error("THREE.GLTFLoader: AVIF required by asset but unsupported."); return n.loadTexture(e) })) } detectSupport() { return this.isSupported || (this.isSupported = new Promise((function(e) { const t = new Image; t.src = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAABcAAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQAMAAAAABNjb2xybmNseAACAAIABoAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAAB9tZGF0EgAKCBgABogQEDQgMgkQAAAAB8dSLfI=", t.onload = t.onerror = function() { e(1 === t.height) } }))), this.isSupported } } class Bl { constructor(e) { this.name = yl.EXT_MESHOPT_COMPRESSION, this.parser = e } loadBufferView(e) { const t = this.parser.json, n = t.bufferViews[e]; if (n.extensions && n.extensions[this.name]) { const e = n.extensions[this.name], i = this.parser.getDependency("buffer", e.buffer), r = this.parser.options.meshoptDecoder; if (!r || !r.supported) { if (t.extensionsRequired && t.extensionsRequired.indexOf(this.name) >= 0) throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files"); return null } return i.then((function(t) { const n = e.byteOffset || 0, i = e.byteLength || 0, a = e.count, s = e.byteStride, o = new Uint8Array(t, n, i); return r.decodeGltfBufferAsync ? r.decodeGltfBufferAsync(a, s, o, e.mode, e.filter).then((function(e) { return e.buffer })) : r.ready.then((function() { const t = new ArrayBuffer(a * s); return r.decodeGltfBuffer(new Uint8Array(t), a, s, o, e.mode, e.filter), t })) })) } return null } } class Ul { constructor(e) { this.name = yl.EXT_MESH_GPU_INSTANCING, this.parser = e } createNodeMesh(e) { const t = this.parser.json, n = t.nodes[e]; if (!n.extensions || !n.extensions[this.name] || void 0 === n.mesh) return null; const i = t.meshes[n.mesh]; for (const e of i.primitives) if (e.mode !== Kl.TRIANGLES && e.mode !== Kl.TRIANGLE_STRIP && e.mode !== Kl.TRIANGLE_FAN && void 0 !== e.mode) return null; const r = n.extensions[this.name].attributes, a = [], s = {}; for (const e in r) a.push(this.parser.getDependency("accessor", r[e]).then((t => (s[e] = t, s[e])))); return a.length < 1 ? null : (a.push(this.parser.createNodeMesh(e)), Promise.all(a).then((e => { const t = e.pop(), n = t.isGroup ? t.children : [t], i = e[0].count, r = []; for (const e of n) { const t = new qn, n = new yn, a = new wn, o = new yn(1, 1, 1), l = new ua(e.geometry, e.material, i); for (let e = 0; e < i; e++) s.TRANSLATION && n.fromBufferAttribute(s.TRANSLATION, e), s.ROTATION && a.fromBufferAttribute(s.ROTATION, e), s.SCALE && o.fromBufferAttribute(s.SCALE, e), l.setMatrixAt(e, t.compose(n, a, o)); for (const t in s) if ("_COLOR_0" === t) { const e = s[t]; l.instanceColor = new ra(e.array, e.itemSize, e.normalized) } else "TRANSLATION" !== t && "ROTATION" !== t && "SCALE" !== t && e.geometry.setAttribute(t, s[t]); xi.prototype.copy.call(l, e), this.parser.assignFinalMaterial(l), r.push(l) } return t.isGroup ? (t.clear(), t.add(...r), t) : r[0] }))) } } const zl = "glTF", Ol = 1313821514, Fl = 5130562; class Wl { constructor(e) { this.name = yl.KHR_BINARY_GLTF, this.content = null, this.body = null; const t = new DataView(e, 0, 12), n = new TextDecoder; if (this.header = { magic: n.decode(new Uint8Array(e.slice(0, 4))), version: t.getUint32(4, !0), length: t.getUint32(8, !0) }, this.header.magic !== zl) throw new Error("THREE.GLTFLoader: Unsupported glTF-Binary header."); if (this.header.version < 2) throw new Error("THREE.GLTFLoader: Legacy binary file detected."); const i = this.header.length - 12, r = new DataView(e, 12); let a = 0; for (; a < i;) { const t = r.getUint32(a, !0); a += 4; const i = r.getUint32(a, !0); if (a += 4, i === Ol) { const i = new Uint8Array(e, 12 + a, t); this.content = n.decode(i) } else if (i === Fl) { const n = 12 + a; this.body = e.slice(n, n + t) } a += t } if (null === this.content) throw new Error("THREE.GLTFLoader: JSON content not found.") } } class Vl { constructor(e, t) { if (!t) throw new Error("THREE.GLTFLoader: No DRACOLoader instance provided."); this.name = yl.KHR_DRACO_MESH_COMPRESSION, this.json = e, this.dracoLoader = t, this.dracoLoader.preload() } decodePrimitive(e, t) { const n = this.json, i = this.dracoLoader, r = e.extensions[this.name].bufferView, a = e.extensions[this.name].attributes, s = {}, o = {}, l = {}; for (const e in a) { const t = $l[e] || e.toLowerCase(); s[t] = a[e] } for (const t in e.attributes) { const i = $l[t] || t.toLowerCase(); if (void 0 !== a[t]) { const r = n.accessors[e.attributes[t]], a = ql[r.componentType]; l[i] = a.name, o[i] = !0 === r.normalized } } return t.getDependency("bufferView", r).then((function(e) { return new Promise((function(t, n) { i.decodeDracoFile(e, (function(e) { for (const t in e.attributes) { const n = e.attributes[t], i = o[t]; void 0 !== i && (n.normalized = i) } t(e) }), s, l, vt, n) })) })) } } class Hl { constructor() { this.name = yl.KHR_TEXTURE_TRANSFORM } extendTexture(e, t) { return void 0 !== t.texCoord && t.texCoord !== e.channel || void 0 !== t.offset || void 0 !== t.rotation || void 0 !== t.scale ? (e = e.clone(), void 0 !== t.texCoord && (e.channel = t.texCoord), void 0 !== t.offset && e.offset.fromArray(t.offset), void 0 !== t.rotation && (e.rotation = t.rotation), void 0 !== t.scale && e.repeat.fromArray(t.scale), e.needsUpdate = !0, e) : e } } class Gl { constructor() { this.name = yl.KHR_MESH_QUANTIZATION } } class jl extends Ks { constructor(e, t, n, i) { super(e, t, n, i) } copySampleValue_(e) { const t = this.resultBuffer, n = this.sampleValues, i = this.valueSize, r = e * i * 3 + i; for (let e = 0; e !== i; e++) t[e] = n[r + e]; return t } interpolate_(e, t, n, i) { const r = this.resultBuffer, a = this.sampleValues, s = this.valueSize, o = 2 * s, l = 3 * s, c = i - t, h = (n - t) / c, d = h * h, u = d * h, p = e * l, f = p - l, m = -2 * u + 3 * d, g = u - d, v = 1 - m, w = g - d + h; for (let e = 0; e !== s; e++) { const t = a[f + e + s], n = a[f + e + o] * c, i = a[p + e + s], l = a[p + e] * c; r[e] = v * t + w * n + m * i + g * l } return r } } const Ql = new wn; class Yl extends jl { interpolate_(e, t, n, i) { const r = super.interpolate_(e, t, n, i); return Ql.fromArray(r).normalize().toArray(r), r } } const Kl = { FLOAT: 5126, FLOAT_MAT3: 35675, FLOAT_MAT4: 35676, FLOAT_VEC2: 35664, FLOAT_VEC3: 35665, FLOAT_VEC4: 35666, LINEAR: 9729, REPEAT: 10497, SAMPLER_2D: 35678, POINTS: 0, LINES: 1, LINE_LOOP: 2, LINE_STRIP: 3, TRIANGLES: 4, TRIANGLE_STRIP: 5, TRIANGLE_FAN: 6, UNSIGNED_BYTE: 5121, UNSIGNED_SHORT: 5123 }, ql = { 5120: Int8Array, 5121: Uint8Array, 5122: Int16Array, 5123: Uint16Array, 5125: Uint32Array, 5126: Float32Array }, Xl = { 9728: oe, 9729: he, 9984: le, 9985: de, 9986: ce, 9987: ue }, Zl = { 33071: ae, 33648: se, 10497: re }, Jl = { SCALAR: 1, VEC2: 2, VEC3: 3, VEC4: 4, MAT2: 4, MAT3: 9, MAT4: 16 }, $l = { POSITION: "position", NORMAL: "normal", TANGENT: "tangent", TEXCOORD_0: "uv", TEXCOORD_1: "uv1", TEXCOORD_2: "uv2", TEXCOORD_3: "uv3", COLOR_0: "color", WEIGHTS_0: "skinWeight", JOINTS_0: "skinIndex" }, ec = { scale: "scale", translation: "position", rotation: "quaternion", weights: "morphTargetInfluences" }, tc = { CUBICSPLINE: void 0, LINEAR: ht, STEP: ct }, nc = "OPAQUE", ic = "MASK", rc = "BLEND"; function ac(e, t, n) { for (const i in n.extensions) void 0 === e[i] && (t.userData.gltfExtensions = t.userData.gltfExtensions || {}, t.userData.gltfExtensions[i] = n.extensions[i]) } function sc(e, t) { void 0 !== t.extras && ("object" == typeof t.extras ? Object.assign(e.userData, t.extras) : console.warn("THREE.GLTFLoader: Ignoring primitive type .extras, " + t.extras)) } function oc(e, t) { if (e.updateMorphTargets(), void 0 !== t.weights) for (let n = 0, i = t.weights.length; n < i; n++) e.morphTargetInfluences[n] = t.weights[n]; if (t.extras && Array.isArray(t.extras.targetNames)) { const n = t.extras.targetNames; if (e.morphTargetInfluences.length === n.length) { e.morphTargetDictionary = {}; for (let t = 0, i = n.length; t < i; t++) e.morphTargetDictionary[n[t]] = t } else console.warn("THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.") } } function lc(e) { let t; const n = e.extensions && e.extensions[yl.KHR_DRACO_MESH_COMPRESSION]; if (t = n ? "draco:" + n.bufferView + ":" + n.indices + ":" + cc(n.attributes) : e.indices + ":" + cc(e.attributes) + ":" + e.mode, void 0 !== e.targets) for (let n = 0, i = e.targets.length; n < i; n++) t += ":" + cc(e.targets[n]); return t } function cc(e) { let t = ""; const n = Object.keys(e).sort(); for (let i = 0, r = n.length; i < r; i++) t += n[i] + ":" + e[n[i]] + ";"; return t } function hc(e) { switch (e) { case Int8Array: return 1 / 127; case Uint8Array: return 1 / 255; case Int16Array: return 1 / 32767; case Uint16Array: return 1 / 65535; default: throw new Error("THREE.GLTFLoader: Unsupported normalized accessor component type.") } } const dc = new qn; class uc { constructor(e = {}, t = {}) { this.json = e, this.extensions = {}, this.plugins = {}, this.options = t, this.cache = new wl, this.associations = new Map, this.primitiveCache = {}, this.nodeCache = {}, this.meshCache = { refs: {}, uses: {} }, this.cameraCache = { refs: {}, uses: {} }, this.lightCache = { refs: {}, uses: {} }, this.sourceCache = {}, this.textureCache = {}, this.nodeNamesUsed = {}; let n = !1, i = -1, r = !1, a = -1; if ("undefined" != typeof navigator) { const e = navigator.userAgent; n = !0 === /^((?!chrome|android).)*safari/i.test(e); const t = e.match(/Version\/(\d+)/); i = n && t ? parseInt(t[1], 10) : -1, r = e.indexOf("Firefox") > -1, a = r ? e.match(/Firefox\/([0-9]+)\./)[1] : -1 } "undefined" == typeof createImageBitmap || n && i < 17 || r && a < 98 ? this.textureLoader = new vo(this.options.manager) : this.textureLoader = new No(this.options.manager), this.textureLoader.setCrossOrigin(this.options.crossOrigin), this.textureLoader.setRequestHeader(this.options.requestHeader), this.fileLoader = new mo(this.options.manager), this.fileLoader.setResponseType("arraybuffer"), "use-credentials" === this.options.crossOrigin && this.fileLoader.setWithCredentials(!0) } setExtensions(e) { this.extensions = e } setPlugins(e) { this.plugins = e } parse(e, t) { const n = this, i = this.json, r = this.extensions; this.cache.removeAll(), this.nodeCache = {}, this._invokeAll((function(e) { return e._markDefs && e._markDefs() })), Promise.all(this._invokeAll((function(e) { return e.beforeRoot && e.beforeRoot() }))).then((function() { return Promise.all([n.getDependencies("scene"), n.getDependencies("animation"), n.getDependencies("camera")]) })).then((function(t) { const a = { scene: t[0][i.scene || 0], scenes: t[0], animations: t[1], cameras: t[2], asset: i.asset, parser: n, userData: {} }; return ac(r, a, i), sc(a, i), Promise.all(n._invokeAll((function(e) { return e.afterRoot && e.afterRoot(a) }))).then((function() { for (const e of a.scenes) e.updateMatrixWorld(); e(a) })) })).catch(t) } _markDefs() { const e = this.json.nodes || [], t = this.json.skins || [], n = this.json.meshes || []; for (let n = 0, i = t.length; n < i; n++) { const i = t[n].joints; for (let t = 0, n = i.length; t < n; t++) e[i[t]].isBone = !0 } for (let t = 0, i = e.length; t < i; t++) { const i = e[t]; void 0 !== i.mesh && (this._addNodeRef(this.meshCache, i.mesh), void 0 !== i.skin && (n[i.mesh].isSkinnedMesh = !0)), void 0 !== i.camera && this._addNodeRef(this.cameraCache, i.camera) } } _addNodeRef(e, t) { void 0 !== t && (void 0 === e.refs[t] && (e.refs[t] = e.uses[t] = 0), e.refs[t]++) } _getNodeRef(e, t, n) { if (e.refs[t] <= 1) return n; const i = n.clone(), r = (e, t) => { const n = this.associations.get(e); null != n && this.associations.set(t, n); for (const [n, i] of e.children.entries()) r(i, t.children[n]) }; return r(n, i), i.name += "_instance_" + e.uses[t]++, i } _invokeOne(e) { const t = Object.values(this.plugins); t.push(this); for (let n = 0; n < t.length; n++) { const i = e(t[n]); if (i) return i } return null } _invokeAll(e) { const t = Object.values(this.plugins); t.unshift(this); const n = []; for (let i = 0; i < t.length; i++) { const r = e(t[i]); r && n.push(r) } return n } getDependency(e, t) { const n = e + ":" + t; let i = this.cache.get(n); if (!i) { switch (e) { case "scene": i = this.loadScene(t); break; case "node": i = this._invokeOne((function(e) { return e.loadNode && e.loadNode(t) })); break; case "mesh": i = this._invokeOne((function(e) { return e.loadMesh && e.loadMesh(t) })); break; case "accessor": i = this.loadAccessor(t); break; case "bufferView": i = this._invokeOne((function(e) { return e.loadBufferView && e.loadBufferView(t) })); break; case "buffer": i = this.loadBuffer(t); break; case "material": i = this._invokeOne((function(e) { return e.loadMaterial && e.loadMaterial(t) })); break; case "texture": i = this._invokeOne((function(e) { return e.loadTexture && e.loadTexture(t) })); break; case "skin": i = this.loadSkin(t); break; case "animation": i = this._invokeOne((function(e) { return e.loadAnimation && e.loadAnimation(t) })); break; case "camera": i = this.loadCamera(t); break; default: if (i = this._invokeOne((function(n) { return n != this && n.getDependency && n.getDependency(e, t) })), !i) throw new Error("Unknown type: " + e) } this.cache.add(n, i) } return i } getDependencies(e) { let t = this.cache.get(e); if (!t) { const n = this, i = this.json[e + ("mesh" === e ? "es" : "s")] || []; t = Promise.all(i.map((function(t, i) { return n.getDependency(e, i) }))), this.cache.add(e, t) } return t } loadBuffer(e) { const t = this.json.buffers[e], n = this.fileLoader; if (t.type && "arraybuffer" !== t.type) throw new Error("THREE.GLTFLoader: " + t.type + " buffer type is not supported."); if (void 0 === t.uri && 0 === e) return Promise.resolve(this.extensions[yl.KHR_BINARY_GLTF].body); const i = this.options; return new Promise((function(e, r) { n.load(Do.resolveURL(t.uri, i.path), e, void 0, (function() { r(new Error('THREE.GLTFLoader: Failed to load buffer "' + t.uri + '".')) })) })) } loadBufferView(e) { const t = this.json.bufferViews[e]; return this.getDependency("buffer", t.buffer).then((function(e) { const n = t.byteLength || 0, i = t.byteOffset || 0; return e.slice(i, i + n) })) } loadAccessor(e) { const t = this, n = this.json, i = this.json.accessors[e]; if (void 0 === i.bufferView && void 0 === i.sparse) { const e = Jl[i.type], t = ql[i.componentType], n = !0 === i.normalized, r = new t(i.count * e); return Promise.resolve(new qi(r, e, n)) } const r = []; return void 0 !== i.bufferView ? r.push(this.getDependency("bufferView", i.bufferView)) : r.push(null), void 0 !== i.sparse && (r.push(this.getDependency("bufferView", i.sparse.indices.bufferView)), r.push(this.getDependency("bufferView", i.sparse.values.bufferView))), Promise.all(r).then((function(e) { const r = e[0], a = Jl[i.type], s = ql[i.componentType], o = s.BYTES_PER_ELEMENT, l = o * a, c = i.byteOffset || 0, h = void 0 !== i.bufferView ? n.bufferViews[i.bufferView].byteStride : void 0, d = !0 === i.normalized; let u, p; if (h && h !== l) { const e = Math.floor(c / h), n = "InterleavedBuffer:" + i.bufferView + ":" + i.componentType + ":" + e + ":" + i.count; let l = t.cache.get(n); l || (u = new s(r, e * h, i.count * h / o), l = new Fr(u, h / o), t.cache.add(n, l)), p = new Vr(l, a, c % h / o, d) } else u = null === r ? new s(i.count * a) : new s(r, c, i.count * a), p = new qi(u, a, d); if (void 0 !== i.sparse) { const t = Jl.SCALAR, n = ql[i.sparse.indices.componentType], o = i.sparse.indices.byteOffset || 0, l = i.sparse.values.byteOffset || 0, c = new n(e[1], o, i.sparse.count * t), h = new s(e[2], l, i.sparse.count * a); null !== r && (p = new qi(p.array.slice(), p.itemSize, p.normalized)), p.normalized = !1; for (let e = 0, t = c.length; e < t; e++) { const t = c[e]; if (p.setX(t, h[e * a]), a >= 2 && p.setY(t, h[e * a + 1]), a >= 3 && p.setZ(t, h[e * a + 2]), a >= 4 && p.setW(t, h[e * a + 3]), a >= 5) throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.") } p.normalized = d } return p })) } loadTexture(e) { const t = this.json, n = this.options, i = t.textures[e].source, r = t.images[i]; let a = this.textureLoader; if (r.uri) { const e = n.manager.getHandler(r.uri); null !== e && (a = e) } return this.loadTextureImage(e, i, a) } loadTextureImage(e, t, n) { const i = this, r = this.json, a = r.textures[e], s = r.images[t], o = (s.uri || s.bufferView) + ":" + a.sampler; if (this.textureCache[o]) return this.textureCache[o]; const l = this.loadImageSource(t, n).then((function(t) { t.flipY = !1, t.name = a.name || s.name || "", "" === t.name && "string" == typeof s.uri && !1 === s.uri.startsWith("data:image/") && (t.name = s.uri); const n = (r.samplers || {})[a.sampler] || {}; return t.magFilter = Xl[n.magFilter] || he, t.minFilter = Xl[n.minFilter] || ue, t.wrapS = Zl[n.wrapS] || re, t.wrapT = Zl[n.wrapT] || re, t.generateMipmaps = !t.isCompressedTexture && t.minFilter !== oe && t.minFilter !== he, i.associations.set(t, { textures: e }), t })).catch((function() { return null })); return this.textureCache[o] = l, l } loadImageSource(e, t) { const n = this, i = this.json, r = this.options; if (void 0 !== this.sourceCache[e]) return this.sourceCache[e].then((e => e.clone())); const a = i.images[e], s = self.URL || self.webkitURL; let o = a.uri || "", l = !1; if (void 0 !== a.bufferView) o = n.getDependency("bufferView", a.bufferView).then((function(e) { l = !0; const t = new Blob([e], { type: a.mimeType }); return o = s.createObjectURL(t), o })); else if (void 0 === a.uri) throw new Error("THREE.GLTFLoader: Image " + e + " is missing URI and bufferView"); const c = Promise.resolve(o).then((function(e) { return new Promise((function(n, i) { let a = n; !0 === t.isImageBitmapLoader && (a = function(e) { const t = new un(e); t.needsUpdate = !0, n(t) }), t.load(Do.resolveURL(e, r.path), a, void 0, i) })) })).then((function(e) { var t; return !0 === l && s.revokeObjectURL(o), sc(e, a), e.userData.mimeType = a.mimeType || ((t = a.uri).search(/\.jpe?g($|\?)/i) > 0 || 0 === t.search(/^data\:image\/jpeg/) ? "image/jpeg" : t.search(/\.webp($|\?)/i) > 0 || 0 === t.search(/^data\:image\/webp/) ? "image/webp" : t.search(/\.ktx2($|\?)/i) > 0 || 0 === t.search(/^data\:image\/ktx2/) ? "image/ktx2" : "image/png"), e })).catch((function(e) { throw console.error("THREE.GLTFLoader: Couldn't load texture", o), e })); return this.sourceCache[e] = c, c } assignTexture(e, t, n, i) { const r = this; return this.getDependency("texture", n.index).then((function(a) { if (!a) return null; if (void 0 !== n.texCoord && n.texCoord > 0 && ((a = a.clone()).channel = n.texCoord), r.extensions[yl.KHR_TEXTURE_TRANSFORM]) { const e = void 0 !== n.extensions ? n.extensions[yl.KHR_TEXTURE_TRANSFORM] : void 0; if (e) { const t = r.associations.get(a); a = r.extensions[yl.KHR_TEXTURE_TRANSFORM].extendTexture(a, e), r.associations.set(a, t) } } return void 0 !== i && (a.colorSpace = i), e[t] = a, a })) } assignFinalMaterial(e) { const t = e.geometry; let n = e.material; const i = void 0 === t.attributes.tangent, r = void 0 !== t.attributes.color, a = void 0 === t.attributes.normal; if (e.isPoints) { const e = "PointsMaterial:" + n.uuid; let t = this.cache.get(e); t || (t = new Da, Gi.prototype.copy.call(t, n), t.color.copy(n.color), t.map = n.map, t.sizeAttenuation = !1, this.cache.add(e, t)), n = t } else if (e.isLine) { const e = "LineBasicMaterial:" + n.uuid; let t = this.cache.get(e); t || (t = new Aa, Gi.prototype.copy.call(t, n), t.color.copy(n.color), t.map = n.map, this.cache.add(e, t)), n = t } if (i || r || a) { let e = "ClonedMaterial:" + n.uuid + ":"; i && (e += "derivative-tangents:"), r && (e += "vertex-colors:"), a && (e += "flat-shading:"); let t = this.cache.get(e); t || (t = n.clone(), r && (t.vertexColors = !0), a && (t.flatShading = !0), i && (t.normalScale && (t.normalScale.y *= -1), t.clearcoatNormalScale && (t.clearcoatNormalScale.y *= -1)), this.cache.add(e, t), this.associations.set(t, this.associations.get(n))), n = t } e.material = n } getMaterialType() { return zs } loadMaterial(e) { const t = this, n = this.json, i = this.extensions, r = n.materials[e]; let a; const s = {}, o = []; if ((r.extensions || {})[yl.KHR_MATERIALS_UNLIT]) { const e = i[yl.KHR_MATERIALS_UNLIT]; a = e.getMaterialType(), o.push(e.extendParams(s, r, t)) } else { const n = r.pbrMetallicRoughness || {}; if (s.color = new Wi(1, 1, 1), s.opacity = 1, Array.isArray(n.baseColorFactor)) { const e = n.baseColorFactor; s.color.setRGB(e[0], e[1], e[2], vt), s.opacity = e[3] } void 0 !== n.baseColorTexture && o.push(t.assignTexture(s, "map", n.baseColorTexture, gt)), s.metalness = void 0 !== n.metallicFactor ? n.metallicFactor : 1, s.roughness = void 0 !== n.roughnessFactor ? n.roughnessFactor : 1, void 0 !== n.metallicRoughnessTexture && (o.push(t.assignTexture(s, "metalnessMap", n.metallicRoughnessTexture)), o.push(t.assignTexture(s, "roughnessMap", n.metallicRoughnessTexture))), a = this._invokeOne((function(t) { return t.getMaterialType && t.getMaterialType(e) })), o.push(Promise.all(this._invokeAll((function(t) { return t.extendMaterialParams && t.extendMaterialParams(e, s) })))) }!0 === r.doubleSided && (s.side = 2); const l = r.alphaMode || nc; if (l === rc ? (s.transparent = !0, s.depthWrite = !1) : (s.transparent = !1, l === ic && (s.alphaTest = void 0 !== r.alphaCutoff ? r.alphaCutoff : .5)), void 0 !== r.normalTexture && a !== ji && (o.push(t.assignTexture(s, "normalMap", r.normalTexture)), s.normalScale = new jt(1, 1), void 0 !== r.normalTexture.scale)) { const e = r.normalTexture.scale; s.normalScale.set(e, e) } if (void 0 !== r.occlusionTexture && a !== ji && (o.push(t.assignTexture(s, "aoMap", r.occlusionTexture)), void 0 !== r.occlusionTexture.strength && (s.aoMapIntensity = r.occlusionTexture.strength)), void 0 !== r.emissiveFactor && a !== ji) { const e = r.emissiveFactor; s.emissive = (new Wi).setRGB(e[0], e[1], e[2], vt) } return void 0 !== r.emissiveTexture && a !== ji && o.push(t.assignTexture(s, "emissiveMap", r.emissiveTexture, gt)), Promise.all(o).then((function() { const n = new a(s); return r.name && (n.name = r.name), sc(n, r), t.associations.set(n, { materials: e }), r.extensions && ac(i, n, r), n })) } createUniqueName(e) { const t = Ho.sanitizeNodeName(e || ""); return t in this.nodeNamesUsed ? t + "_" + ++this.nodeNamesUsed[t] : (this.nodeNamesUsed[t] = 0, t) } loadGeometries(e) { const t = this, n = this.extensions, i = this.primitiveCache; function r(e) { return n[yl.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(e, t).then((function(n) { return pc(n, e, t) })) } const a = []; for (let n = 0, s = e.length; n < s; n++) { const s = e[n], o = lc(s), l = i[o]; if (l) a.push(l.promise); else { let e; e = s.extensions && s.extensions[yl.KHR_DRACO_MESH_COMPRESSION] ? r(s) : pc(new sr, s, t), i[o] = { primitive: s, promise: e }, a.push(e) } } return Promise.all(a) } loadMesh(e) { const t = this, n = this.json, i = this.extensions, r = n.meshes[e], a = r.primitives, s = []; for (let e = 0, t = a.length; e < t; e++) { const t = void 0 === a[e].material ? (void 0 === (o = this.cache).DefaultMaterial && (o.DefaultMaterial = new zs({ color: 16777215, emissive: 0, metalness: 1, roughness: 1, transparent: !1, depthTest: !0, side: 0 })), o.DefaultMaterial) : this.getDependency("material", a[e].material); s.push(t) } var o; return s.push(t.loadGeometries(a)), Promise.all(s).then((function(n) { const s = n.slice(0, n.length - 1), o = n[n.length - 1], l = []; for (let n = 0, c = o.length; n < c; n++) { const c = o[n], h = a[n]; let d; const u = s[n]; if (h.mode === Kl.TRIANGLES || h.mode === Kl.TRIANGLE_STRIP || h.mode === Kl.TRIANGLE_FAN || void 0 === h.mode) d = !0 === r.isSkinnedMesh ? new Jr(c, u) : new wr(c, u), !0 === d.isSkinnedMesh && d.normalizeSkinWeights(), h.mode === Kl.TRIANGLE_STRIP ? d.geometry = gl(d.geometry, 1) : h.mode === Kl.TRIANGLE_FAN && (d.geometry = gl(d.geometry, 2)); else if (h.mode === Kl.LINES) d = new Ra(c, u); else if (h.mode === Kl.LINE_STRIP) d = new _a(c, u); else if (h.mode === Kl.LINE_LOOP) d = new La(c, u); else { if (h.mode !== Kl.POINTS) throw new Error("THREE.GLTFLoader: Primitive mode unsupported: " + h.mode); d = new Oa(c, u) } Object.keys(d.geometry.morphAttributes).length > 0 && oc(d, r), d.name = t.createUniqueName(r.name || "mesh_" + e), sc(d, r), h.extensions && ac(i, d, h), t.assignFinalMaterial(d), l.push(d) } for (let n = 0, i = l.length; n < i; n++) t.associations.set(l[n], { meshes: e, primitives: n }); if (1 === l.length) return r.extensions && ac(i, l[0], r), l[0]; const c = new Nr; r.extensions && ac(i, c, r), t.associations.set(c, { meshes: e }); for (let e = 0, t = l.length; e < t; e++) c.add(l[e]); return c })) } loadCamera(e) { let t; const n = this.json.cameras[e], i = n[n.type]; if (i) return "perspective" === n.type ? t = new Pr(Gt.radToDeg(i.yfov), i.aspectRatio || 1, i.znear || 1, i.zfar || 2e6) : "orthographic" === n.type && (t = new Io(-i.xmag, i.xmag, i.ymag, -i.ymag, i.znear, i.zfar)), n.name && (t.name = this.createUniqueName(n.name)), sc(t, n), Promise.resolve(t); console.warn("THREE.GLTFLoader: Missing camera parameters.") } loadSkin(e) { const t = this.json.skins[e], n = []; for (let e = 0, i = t.joints.length; e < i; e++) n.push(this._loadNodeShallow(t.joints[e])); return void 0 !== t.inverseBindMatrices ? n.push(this.getDependency("accessor", t.inverseBindMatrices)) : n.push(null), Promise.all(n).then((function(e) { const n = e.pop(), i = e, r = [], a = []; for (let e = 0, s = i.length; e < s; e++) { const s = i[e]; if (s) { r.push(s); const t = new qn; null !== n && t.fromArray(n.array, 16 * e), a.push(t) } else console.warn('THREE.GLTFLoader: Joint "%s" could not be found.', t.joints[e]) } return new ia(r, a) })) } loadAnimation(e) { const t = this.json, n = this, i = t.animations[e], r = i.name ? i.name : "animation_" + e, a = [], s = [], o = [], l = [], c = []; for (let e = 0, t = i.channels.length; e < t; e++) { const t = i.channels[e], n = i.samplers[t.sampler], r = t.target, h = r.node, d = void 0 !== i.parameters ? i.parameters[n.input] : n.input, u = void 0 !== i.parameters ? i.parameters[n.output] : n.output; void 0 !== r.node && (a.push(this.getDependency("node", h)), s.push(this.getDependency("accessor", d)), o.push(this.getDependency("accessor", u)), l.push(n), c.push(r)) } return Promise.all([Promise.all(a), Promise.all(s), Promise.all(o), Promise.all(l), Promise.all(c)]).then((function(e) { const t = e[0], i = e[1], a = e[2], s = e[3], o = e[4], l = []; for (let e = 0, r = t.length; e < r; e++) { const r = t[e], c = i[e], h = a[e], d = s[e], u = o[e]; if (void 0 === r) continue; r.updateMatrix && r.updateMatrix(); const p = n._createAnimationTracks(r, c, h, d, u); if (p) for (let e = 0; e < p.length; e++) l.push(p[e]) } return new so(r, void 0, l) })) } createNodeMesh(e) { const t = this.json, n = this, i = t.nodes[e]; return void 0 === i.mesh ? null : n.getDependency("mesh", i.mesh).then((function(e) { const t = n._getNodeRef(n.meshCache, i.mesh, e); return void 0 !== i.weights && t.traverse((function(e) { if (e.isMesh) for (let t = 0, n = i.weights.length; t < n; t++) e.morphTargetInfluences[t] = i.weights[t] })), t })) } loadNode(e) { const t = this, n = this.json.nodes[e], i = t._loadNodeShallow(e), r = [], a = n.children || []; for (let e = 0, n = a.length; e < n; e++) r.push(t.getDependency("node", a[e])); const s = void 0 === n.skin ? Promise.resolve(null) : t.getDependency("skin", n.skin); return Promise.all([i, Promise.all(r), s]).then((function(e) { const t = e[0], n = e[1], i = e[2]; null !== i && t.traverse((function(e) { e.isSkinnedMesh && e.bind(i, dc) })); for (let e = 0, i = n.length; e < i; e++) t.add(n[e]); return t })) } _loadNodeShallow(e) { const t = this.json, n = this.extensions, i = this; if (void 0 !== this.nodeCache[e]) return this.nodeCache[e]; const r = t.nodes[e], a = r.name ? i.createUniqueName(r.name) : "", s = [], o = i._invokeOne((function(t) { return t.createNodeMesh && t.createNodeMesh(e) })); return o && s.push(o), void 0 !== r.camera && s.push(i.getDependency("camera", r.camera).then((function(e) { return i._getNodeRef(i.cameraCache, r.camera, e) }))), i._invokeAll((function(t) { return t.createNodeAttachment && t.createNodeAttachment(e) })).forEach((function(e) { s.push(e) })), this.nodeCache[e] = Promise.all(s).then((function(t) { let s; if (s = !0 === r.isBone ? new $r : t.length > 1 ? new Nr : 1 === t.length ? t[0] : new xi, s !== t[0]) for (let e = 0, n = t.length; e < n; e++) s.add(t[e]); if (r.name && (s.userData.name = r.name, s.name = a), sc(s, r), r.extensions && ac(n, s, r), void 0 !== r.matrix) { const e = new qn; e.fromArray(r.matrix), s.applyMatrix4(e) } else void 0 !== r.translation && s.position.fromArray(r.translation), void 0 !== r.rotation && s.quaternion.fromArray(r.rotation), void 0 !== r.scale && s.scale.fromArray(r.scale); return i.associations.has(s) || i.associations.set(s, {}), i.associations.get(s).nodes = e, s })), this.nodeCache[e] } loadScene(e) { const t = this.extensions, n = this.json.scenes[e], i = this, r = new Nr; n.name && (r.name = i.createUniqueName(n.name)), sc(r, n), n.extensions && ac(t, r, n); const a = n.nodes || [], s = []; for (let e = 0, t = a.length; e < t; e++) s.push(i.getDependency("node", a[e])); return Promise.all(s).then((function(e) { for (let t = 0, n = e.length; t < n; t++) r.add(e[t]); return i.associations = (e => { const t = new Map; for (const [e, n] of i.associations)(e instanceof Gi || e instanceof un) && t.set(e, n); return e.traverse((e => { const n = i.associations.get(e); null != n && t.set(e, n) })), t })(r), r })) } _createAnimationTracks(e, t, n, i, r) { const a = [], s = e.name ? e.name : e.uuid, o = []; let l; switch (ec[r.path] === ec.weights ? e.traverse((function(e) { e.morphTargetInfluences && o.push(e.name ? e.name : e.uuid) })) : o.push(s), ec[r.path]) { case ec.weights: l = to; break; case ec.rotation: l = io; break; case ec.position: case ec.scale: l = ao; break; default: if (1 === n.itemSize) l = to; else l = ao } const c = void 0 !== i.interpolation ? tc[i.interpolation] : ht, h = this._getArrayFromAccessor(n); for (let e = 0, n = o.length; e < n; e++) { const n = new l(o[e] + "." + ec[r.path], t.array, h, c); "CUBICSPLINE" === i.interpolation && this._createCubicSplineTrackInterpolant(n), a.push(n) } return a } _getArrayFromAccessor(e) { let t = e.array; if (e.normalized) { const e = hc(t.constructor), n = new Float32Array(t.length); for (let i = 0, r = t.length; i < r; i++) n[i] = t[i] * e; t = n } return t } _createCubicSplineTrackInterpolant(e) { e.createInterpolant = function(e) { return new(this instanceof io ? Yl : jl)(this.times, this.values, this.getValueSize() / 3, e) }, e.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = !0 } } function pc(e, t, n) { const i = t.attributes, r = []; function a(t, i) { return n.getDependency("accessor", t).then((function(t) { e.setAttribute(i, t) })) } for (const t in i) { const n = $l[t] || t.toLowerCase(); n in e.attributes || r.push(a(i[t], n)) } if (void 0 !== t.indices && !e.index) { const i = n.getDependency("accessor", t.indices).then((function(t) { e.setIndex(t) })); r.push(i) } return nn.workingColorSpace !== vt && "COLOR_0" in i && console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${nn.workingColorSpace}" not supported.`), sc(e, t), function(e, t, n) { const i = t.attributes, r = new xn; if (void 0 === i.POSITION) return; { const e = n.json.accessors[i.POSITION], t = e.min, a = e.max; if (void 0 === t || void 0 === a) return void console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION."); if (r.set(new yn(t[0], t[1], t[2]), new yn(a[0], a[1], a[2])), e.normalized) { const t = hc(ql[e.componentType]); r.min.multiplyScalar(t), r.max.multiplyScalar(t) } } const a = t.targets; if (void 0 !== a) { const e = new yn, t = new yn; for (let i = 0, r = a.length; i < r; i++) { const r = a[i]; if (void 0 !== r.POSITION) { const i = n.json.accessors[r.POSITION], a = i.min, s = i.max; if (void 0 !== a && void 0 !== s) { if (t.setX(Math.max(Math.abs(a[0]), Math.abs(s[0]))), t.setY(Math.max(Math.abs(a[1]), Math.abs(s[1]))), t.setZ(Math.max(Math.abs(a[2]), Math.abs(s[2]))), i.normalized) { const e = hc(ql[i.componentType]); t.multiplyScalar(e) } e.max(t) } else console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.") } } r.expandByVector(e) } e.boundingBox = r; const s = new Fn; r.getCenter(s.center), s.radius = r.min.distanceTo(r.max) / 2, e.boundingSphere = s }(e, t, n), Promise.all(r).then((function() { return void 0 !== t.targets ? function(e, t, n) { let i = !1, r = !1, a = !1; for (let e = 0, n = t.length; e < n; e++) { const n = t[e]; if (void 0 !== n.POSITION && (i = !0), void 0 !== n.NORMAL && (r = !0), void 0 !== n.COLOR_0 && (a = !0), i && r && a) break } if (!i && !r && !a) return Promise.resolve(e); const s = [], o = [], l = []; for (let c = 0, h = t.length; c < h; c++) { const h = t[c]; if (i) { const t = void 0 !== h.POSITION ? n.getDependency("accessor", h.POSITION) : e.attributes.position; s.push(t) } if (r) { const t = void 0 !== h.NORMAL ? n.getDependency("accessor", h.NORMAL) : e.attributes.normal; o.push(t) } if (a) { const t = void 0 !== h.COLOR_0 ? n.getDependency("accessor", h.COLOR_0) : e.attributes.color; l.push(t) } } return Promise.all([Promise.all(s), Promise.all(o), Promise.all(l)]).then((function(t) { const n = t[0], s = t[1], o = t[2]; return i && (e.morphAttributes.position = n), r && (e.morphAttributes.normal = s), a && (e.morphAttributes.color = o), e.morphTargetsRelative = !0, e })) }(e, t.targets, n) : e })) } /** * @license * Copyright 2010-2025 Three.js Authors * SPDX-License-Identifier: MIT */ function fc() { let e = null, t = !1, n = null, i = null; function r(t, a) { n(t, a), i = e.requestAnimationFrame(r) } return { start: function() { !0 !== t && null !== n && (i = e.requestAnimationFrame(r), t = !0) }, stop: function() { e.cancelAnimationFrame(i), t = !1 }, setAnimationLoop: function(e) { n = e }, setContext: function(t) { e = t } } } function mc(e) { const t = new WeakMap; return { get: function(e) { return e.isInterleavedBufferAttribute && (e = e.data), t.get(e) }, remove: function(n) { n.isInterleavedBufferAttribute && (n = n.data); const i = t.get(n); i && (e.deleteBuffer(i.buffer), t.delete(n)) }, update: function(n, i) { if (n.isInterleavedBufferAttribute && (n = n.data), n.isGLBufferAttribute) { const e = t.get(n); return void((!e || e.version < n.version) && t.set(n, { buffer: n.buffer, type: n.type, bytesPerElement: n.elementSize, version: n.version })) } const r = t.get(n); if (void 0 === r) t.set(n, function(t, n) { const i = t.array, r = t.usage, a = i.byteLength, s = e.createBuffer(); let o; if (e.bindBuffer(n, s), e.bufferData(n, i, r), t.onUploadCallback(), i instanceof Float32Array) o = e.FLOAT; else if (i instanceof Uint16Array) o = t.isFloat16BufferAttribute ? e.HALF_FLOAT : e.UNSIGNED_SHORT; else if (i instanceof Int16Array) o = e.SHORT; else if (i instanceof Uint32Array) o = e.UNSIGNED_INT; else if (i instanceof Int32Array) o = e.INT; else if (i instanceof Int8Array) o = e.BYTE; else if (i instanceof Uint8Array) o = e.UNSIGNED_BYTE; else { if (!(i instanceof Uint8ClampedArray)) throw new Error("THREE.WebGLAttributes: Unsupported buffer data format: " + i); o = e.UNSIGNED_BYTE } return { buffer: s, type: o, bytesPerElement: i.BYTES_PER_ELEMENT, version: t.version, size: a } }(n, i)); else if (r.version < n.version) { if (r.size !== n.array.byteLength) throw new Error("THREE.WebGLAttributes: The size of the buffer attribute's array buffer does not match the original size. Resizing buffer attributes is not supported."); ! function(t, n, i) { const r = n.array, a = n.updateRanges; if (e.bindBuffer(i, t), 0 === a.length) e.bufferSubData(i, 0, r); else { a.sort(((e, t) => e.start - t.start)); let t = 0; for (let e = 1; e < a.length; e++) { const n = a[t], i = a[e]; i.start <= n.start + n.count + 1 ? n.count = Math.max(n.count, i.start + i.count - n.start) : (++t, a[t] = i) } a.length = t + 1; for (let t = 0, n = a.length; t < n; t++) { const n = a[t]; e.bufferSubData(i, n.start * r.BYTES_PER_ELEMENT, r, n.start, n.count) } n.clearUpdateRanges() } n.onUploadCallback() }(r.buffer, n, i), r.version = n.version } } } } const gc = { alphahash_fragment: "#ifdef USE_ALPHAHASH\n\tif ( diffuseColor.a < getAlphaHashThreshold( vPosition ) ) discard;\n#endif", alphahash_pars_fragment: "#ifdef USE_ALPHAHASH\n\tconst float ALPHA_HASH_SCALE = 0.05;\n\tfloat hash2D( vec2 value ) {\n\t\treturn fract( 1.0e4 * sin( 17.0 * value.x + 0.1 * value.y ) * ( 0.1 + abs( sin( 13.0 * value.y + value.x ) ) ) );\n\t}\n\tfloat hash3D( vec3 value ) {\n\t\treturn hash2D( vec2( hash2D( value.xy ), value.z ) );\n\t}\n\tfloat getAlphaHashThreshold( vec3 position ) {\n\t\tfloat maxDeriv = max(\n\t\t\tlength( dFdx( position.xyz ) ),\n\t\t\tlength( dFdy( position.xyz ) )\n\t\t);\n\t\tfloat pixScale = 1.0 / ( ALPHA_HASH_SCALE * maxDeriv );\n\t\tvec2 pixScales = vec2(\n\t\t\texp2( floor( log2( pixScale ) ) ),\n\t\t\texp2( ceil( log2( pixScale ) ) )\n\t\t);\n\t\tvec2 alpha = vec2(\n\t\t\thash3D( floor( pixScales.x * position.xyz ) ),\n\t\t\thash3D( floor( pixScales.y * position.xyz ) )\n\t\t);\n\t\tfloat lerpFactor = fract( log2( pixScale ) );\n\t\tfloat x = ( 1.0 - lerpFactor ) * alpha.x + lerpFactor * alpha.y;\n\t\tfloat a = min( lerpFactor, 1.0 - lerpFactor );\n\t\tvec3 cases = vec3(\n\t\t\tx * x / ( 2.0 * a * ( 1.0 - a ) ),\n\t\t\t( x - 0.5 * a ) / ( 1.0 - a ),\n\t\t\t1.0 - ( ( 1.0 - x ) * ( 1.0 - x ) / ( 2.0 * a * ( 1.0 - a ) ) )\n\t\t);\n\t\tfloat threshold = ( x < ( 1.0 - a ) )\n\t\t\t? ( ( x < a ) ? cases.x : cases.y )\n\t\t\t: cases.z;\n\t\treturn clamp( threshold , 1.0e-6, 1.0 );\n\t}\n#endif", alphamap_fragment: "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vAlphaMapUv ).g;\n#endif", alphamap_pars_fragment: "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif", alphatest_fragment: "#ifdef USE_ALPHATEST\n\t#ifdef ALPHA_TO_COVERAGE\n\tdiffuseColor.a = smoothstep( alphaTest, alphaTest + fwidth( diffuseColor.a ), diffuseColor.a );\n\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\tif ( diffuseColor.a < alphaTest ) discard;\n\t#endif\n#endif", alphatest_pars_fragment: "#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif", aomap_fragment: "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vAoMapUv ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_CLEARCOAT ) \n\t\tclearcoatSpecularIndirect *= ambientOcclusion;\n\t#endif\n\t#if defined( USE_SHEEN ) \n\t\tsheenSpecularIndirect *= ambientOcclusion;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\t#endif\n#endif", aomap_pars_fragment: "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif", batching_pars_vertex: "#ifdef USE_BATCHING\n\t#if ! defined( GL_ANGLE_multi_draw )\n\t#define gl_DrawID _gl_DrawID\n\tuniform int _gl_DrawID;\n\t#endif\n\tuniform highp sampler2D batchingTexture;\n\tuniform highp usampler2D batchingIdTexture;\n\tmat4 getBatchingMatrix( const in float i ) {\n\t\tint size = textureSize( batchingTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( batchingTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( batchingTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( batchingTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( batchingTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n\tfloat getIndirectIndex( const in int i ) {\n\t\tint size = textureSize( batchingIdTexture, 0 ).x;\n\t\tint x = i % size;\n\t\tint y = i / size;\n\t\treturn float( texelFetch( batchingIdTexture, ivec2( x, y ), 0 ).r );\n\t}\n#endif\n#ifdef USE_BATCHING_COLOR\n\tuniform sampler2D batchingColorTexture;\n\tvec3 getBatchingColor( const in float i ) {\n\t\tint size = textureSize( batchingColorTexture, 0 ).x;\n\t\tint j = int( i );\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\treturn texelFetch( batchingColorTexture, ivec2( x, y ), 0 ).rgb;\n\t}\n#endif", batching_vertex: "#ifdef USE_BATCHING\n\tmat4 batchingMatrix = getBatchingMatrix( getIndirectIndex( gl_DrawID ) );\n#endif", begin_vertex: "vec3 transformed = vec3( position );\n#ifdef USE_ALPHAHASH\n\tvPosition = vec3( position );\n#endif", beginnormal_vertex: "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif", bsdfs: "float G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, 1.0, dotVH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n} // validated", iridescence_fragment: "#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 = mat3(\n\t\t 3.2404542, -0.9692660, 0.0556434,\n\t\t-1.5371385, 1.8760108, -0.2040259,\n\t\t-0.4985314, 0.0415560, 1.0572252\n\t);\n\tvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n\t\tvec3 sqrtF0 = sqrt( fresnel0 );\n\t\treturn ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n\t}\n\tvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n\t}\n\tfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n\t}\n\tvec3 evalSensitivity( float OPD, vec3 shift ) {\n\t\tfloat phase = 2.0 * PI * OPD * 1.0e-9;\n\t\tvec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n\t\tvec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n\t\tvec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n\t\tvec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var );\n\t\txyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );\n\t\txyz /= 1.0685e-7;\n\t\tvec3 rgb = XYZ_TO_REC709 * xyz;\n\t\treturn rgb;\n\t}\n\tvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n\t\tvec3 I;\n\t\tfloat iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n\t\tfloat sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n\t\tfloat cosTheta2Sq = 1.0 - sinTheta2Sq;\n\t\tif ( cosTheta2Sq < 0.0 ) {\n\t\t\treturn vec3( 1.0 );\n\t\t}\n\t\tfloat cosTheta2 = sqrt( cosTheta2Sq );\n\t\tfloat R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n\t\tfloat R12 = F_Schlick( R0, 1.0, cosTheta1 );\n\t\tfloat T121 = 1.0 - R12;\n\t\tfloat phi12 = 0.0;\n\t\tif ( iridescenceIOR < outsideIOR ) phi12 = PI;\n\t\tfloat phi21 = PI - phi12;\n\t\tvec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) );\t\tvec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n\t\tvec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n\t\tvec3 phi23 = vec3( 0.0 );\n\t\tif ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI;\n\t\tif ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI;\n\t\tif ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI;\n\t\tfloat OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n\t\tvec3 phi = vec3( phi21 ) + phi23;\n\t\tvec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n\t\tvec3 r123 = sqrt( R123 );\n\t\tvec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n\t\tvec3 C0 = R12 + Rs;\n\t\tI = C0;\n\t\tvec3 Cm = Rs - T121;\n\t\tfor ( int m = 1; m <= 2; ++ m ) {\n\t\t\tCm *= r123;\n\t\t\tvec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n\t\t\tI += Cm * Sm;\n\t\t}\n\t\treturn max( I, vec3( 0.0 ) );\n\t}\n#endif", bumpmap_pars_fragment: "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vBumpMapUv );\n\t\tvec2 dSTdy = dFdy( vBumpMapUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vBumpMapUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n\t\tvec3 vSigmaX = normalize( dFdx( surf_pos.xyz ) );\n\t\tvec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 ) * faceDirection;\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif", clipping_planes_fragment: "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#ifdef ALPHA_TO_COVERAGE\n\t\tfloat distanceToPlane, distanceGradient;\n\t\tfloat clipOpacity = 1.0;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\tclipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\tif ( clipOpacity == 0.0 ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tfloat unionClipOpacity = 1.0;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\t\tunionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tclipOpacity *= 1.0 - unionClipOpacity;\n\t\t#endif\n\t\tdiffuseColor.a *= clipOpacity;\n\t\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tbool clipped = true;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tif ( clipped ) discard;\n\t\t#endif\n\t#endif\n#endif", clipping_planes_pars_fragment: "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif", clipping_planes_pars_vertex: "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif", clipping_planes_vertex: "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif", color_fragment: "#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif", color_pars_fragment: "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif", color_pars_vertex: "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvarying vec3 vColor;\n#endif", color_vertex: "#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif\n#ifdef USE_BATCHING_COLOR\n\tvec3 batchingColor = getBatchingColor( getIndirectIndex( gl_DrawID ) );\n\tvColor.xyz *= batchingColor.xyz;\n#endif", common: "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nvec3 pow2( const in vec3 x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\n#ifdef USE_ALPHAHASH\n\tvarying vec3 vPosition;\n#endif\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}\nvec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n} // validated", cube_uv_reflection_fragment: "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\thighp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif", defaultnormal_vertex: "vec3 transformedNormal = objectNormal;\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n\tmat3 bm = mat3( batchingMatrix );\n\ttransformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n\ttransformedNormal = bm * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = bm * transformedTangent;\n\t#endif\n#endif\n#ifdef USE_INSTANCING\n\tmat3 im = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n\ttransformedNormal = im * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = im * transformedTangent;\n\t#endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\ttransformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif", displacementmap_pars_vertex: "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif", displacementmap_vertex: "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vDisplacementMapUv ).x * displacementScale + displacementBias );\n#endif", emissivemap_fragment: "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE_EMISSIVE\n\t\temissiveColor = sRGBTransferEOTF( emissiveColor );\n\t#endif\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif", emissivemap_pars_fragment: "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif", colorspace_fragment: "gl_FragColor = linearToOutputTexel( gl_FragColor );", colorspace_pars_fragment: "vec4 LinearTransferOETF( in vec4 value ) {\n\treturn value;\n}\nvec4 sRGBTransferEOTF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 sRGBTransferOETF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}", envmap_fragment: "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif", envmap_common_pars_fragment: "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform mat3 envMapRotation;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif", envmap_pars_fragment: "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif", envmap_pars_vertex: "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif", envmap_physical_pars_fragment: "#ifdef USE_ENVMAP\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\t#ifdef USE_ANISOTROPY\n\t\tvec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n\t\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\t\tvec3 bentNormal = cross( bitangent, viewDir );\n\t\t\t\tbentNormal = normalize( cross( bentNormal, bitangent ) );\n\t\t\t\tbentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n\t\t\t\treturn getIBLRadiance( viewDir, bentNormal, roughness );\n\t\t\t#else\n\t\t\t\treturn vec3( 0.0 );\n\t\t\t#endif\n\t\t}\n\t#endif\n#endif", envmap_vertex: "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif", fog_vertex: "#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif", fog_pars_vertex: "#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif", fog_fragment: "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif", fog_pars_fragment: "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif", gradientmap_pars_fragment: "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\tvec2 fw = fwidth( coord ) * 0.5;\n\t\treturn mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n\t#endif\n}", lightmap_pars_fragment: "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif", lights_lambert_fragment: "LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;", lights_lambert_pars_fragment: "varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert", lights_pars_begin: "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n\tuniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif ( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif", lights_toon_fragment: "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;", lights_toon_pars_fragment: "varying vec3 vViewPosition;\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon", lights_phong_fragment: "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;", lights_phong_pars_fragment: "varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong", lights_physical_fragment: "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n\tmaterial.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tif( material.anisotropy == 0.0 ) {\n\t\tanisotropyV = vec2( 1.0, 0.0 );\n\t} else {\n\t\tanisotropyV /= material.anisotropy;\n\t\tmaterial.anisotropy = saturate( material.anisotropy );\n\t}\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif", lights_physical_pars_fragment: "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\tfloat dispersion;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat anisotropy;\n\t\tfloat alphaT;\n\t\tvec3 anisotropyT;\n\t\tvec3 anisotropyB;\n\t#endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\n#ifdef USE_ANISOTROPY\n\tfloat V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n\t\tfloat gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n\t\tfloat gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n\t\tfloat v = 0.5 / ( gv + gl );\n\t\treturn saturate(v);\n\t}\n\tfloat D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n\t\tfloat a2 = alphaT * alphaB;\n\t\thighp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n\t\thighp float v2 = dot( v, v );\n\t\tfloat w2 = a2 / v2;\n\t\treturn RECIPROCAL_PI * a2 * pow2 ( w2 );\n\t}\n#endif\n#ifdef USE_CLEARCOAT\n\tvec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n\t\tvec3 f0 = material.clearcoatF0;\n\t\tfloat f90 = material.clearcoatF90;\n\t\tfloat roughness = material.clearcoatRoughness;\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 f0 = material.specularColor;\n\tfloat f90 = material.specularF90;\n\tfloat roughness = material.roughness;\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t#ifdef USE_IRIDESCENCE\n\t\tF = mix( F, material.iridescenceFresnel, material.iridescence );\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat dotTL = dot( material.anisotropyT, lightDir );\n\t\tfloat dotTV = dot( material.anisotropyT, viewDir );\n\t\tfloat dotTH = dot( material.anisotropyT, halfDir );\n\t\tfloat dotBL = dot( material.anisotropyB, lightDir );\n\t\tfloat dotBV = dot( material.anisotropyB, viewDir );\n\t\tfloat dotBH = dot( material.anisotropyB, halfDir );\n\t\tfloat V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n\t\tfloat D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n\t#else\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t#endif\n\treturn F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometryNormal;\n\t\tvec3 viewDir = geometryViewDir;\n\t\tvec3 position = geometryPosition;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.roughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material );\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}", lights_fragment_begin: "\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n\tgeometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if defined( USE_LIGHT_PROBES )\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif", lights_fragment_maps: "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometryNormal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\t#ifdef USE_ANISOTROPY\n\t\tradiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n\t#else\n\t\tradiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif", lights_fragment_end: "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif", logdepthbuf_fragment: "#if defined( USE_LOGDEPTHBUF )\n\tgl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif", logdepthbuf_pars_fragment: "#if defined( USE_LOGDEPTHBUF )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif", logdepthbuf_pars_vertex: "#ifdef USE_LOGDEPTHBUF\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif", logdepthbuf_vertex: "#ifdef USE_LOGDEPTHBUF\n\tvFragDepth = 1.0 + gl_Position.w;\n\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n#endif", map_fragment: "#ifdef USE_MAP\n\tvec4 sampledDiffuseColor = texture2D( map, vMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tsampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor );\n\t#endif\n\tdiffuseColor *= sampledDiffuseColor;\n#endif", map_pars_fragment: "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif", map_particle_fragment: "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t#if defined( USE_POINTS_UV )\n\t\tvec2 uv = vUv;\n\t#else\n\t\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif", map_particle_pars_fragment: "#if defined( USE_POINTS_UV )\n\tvarying vec2 vUv;\n#else\n\t#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t\tuniform mat3 uvTransform;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif", metalnessmap_fragment: "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif", metalnessmap_pars_fragment: "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif", morphinstance_vertex: "#ifdef USE_INSTANCING_MORPH\n\tfloat morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\tfloat morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tmorphTargetInfluences[i] = texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r;\n\t}\n#endif", morphcolor_vertex: "#if defined( USE_MORPHCOLORS )\n\tvColor *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t#if defined( USE_COLOR_ALPHA )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n\t\t#elif defined( USE_COLOR )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n\t\t#endif\n\t}\n#endif", morphnormal_vertex: "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif", morphtarget_pars_vertex: "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_INSTANCING_MORPH\n\t\tuniform float morphTargetBaseInfluence;\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t#endif\n\tuniform sampler2DArray morphTargetsTexture;\n\tuniform ivec2 morphTargetsTextureSize;\n\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n\t\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n\t\tint y = texelIndex / morphTargetsTextureSize.x;\n\t\tint x = texelIndex - y * morphTargetsTextureSize.x;\n\t\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\n\t\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\n\t}\n#endif", morphtarget_vertex: "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif", normal_fragment_begin: "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal *= faceDirection;\n\t#endif\n#endif\n#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn = getTangentFrame( - vViewPosition, normal,\n\t\t#if defined( USE_NORMALMAP )\n\t\t\tvNormalMapUv\n\t\t#elif defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tvClearcoatNormalMapUv\n\t\t#else\n\t\t\tvUv\n\t\t#endif\n\t\t);\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn[0] *= faceDirection;\n\t\ttbn[1] *= faceDirection;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn2[0] *= faceDirection;\n\t\ttbn2[1] *= faceDirection;\n\t#endif\n#endif\nvec3 nonPerturbedNormal = normal;", normal_fragment_maps: "#ifdef USE_NORMALMAP_OBJECTSPACE\n\tnormal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( USE_NORMALMAP_TANGENTSPACE )\n\tvec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\tnormal = normalize( tbn * mapN );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif", normal_pars_fragment: "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif", normal_pars_vertex: "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif", normal_vertex: "#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif", normalmap_pars_fragment: "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef USE_NORMALMAP_OBJECTSPACE\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) )\n\tmat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( uv.st );\n\t\tvec2 st1 = dFdy( uv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det );\n\t\treturn mat3( T * scale, B * scale, N );\n\t}\n#endif", clearcoat_normal_fragment_begin: "#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = nonPerturbedNormal;\n#endif", clearcoat_normal_fragment_maps: "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\tclearcoatNormal = normalize( tbn2 * clearcoatMapN );\n#endif", clearcoat_pars_fragment: "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif", iridescence_pars_fragment: "#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif", opaque_fragment: "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );", packing: "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;const float ShiftRight8 = 1. / 256.;\nconst float Inv255 = 1. / 255.;\nconst vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );\nconst vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g );\nconst vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b );\nconst vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a );\nvec4 packDepthToRGBA( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec4( 0., 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec4( 1., 1., 1., 1. );\n\tfloat vuf;\n\tfloat af = modf( v * PackFactors.a, vuf );\n\tfloat bf = modf( vuf * ShiftRight8, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af );\n}\nvec3 packDepthToRGB( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec3( 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec3( 1., 1., 1. );\n\tfloat vuf;\n\tfloat bf = modf( v * PackFactors.b, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec3( vuf * Inv255, gf * PackUpscale, bf );\n}\nvec2 packDepthToRG( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec2( 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec2( 1., 1. );\n\tfloat vuf;\n\tfloat gf = modf( v * 256., vuf );\n\treturn vec2( vuf * Inv255, gf );\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors4 );\n}\nfloat unpackRGBToDepth( const in vec3 v ) {\n\treturn dot( v, UnpackFactors3 );\n}\nfloat unpackRGToDepth( const in vec2 v ) {\n\treturn v.r * UnpackFactors2.r + v.g * UnpackFactors2.g;\n}\nvec4 pack2HalfToRGBA( const in vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( const in vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\treturn depth * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * depth - far );\n}", premultiplied_alpha_fragment: "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif", project_vertex: "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_BATCHING\n\tmvPosition = batchingMatrix * mvPosition;\n#endif\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;", dithering_fragment: "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif", dithering_pars_fragment: "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif", roughnessmap_fragment: "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv );\n\troughnessFactor *= texelRoughness.g;\n#endif", roughnessmap_pars_fragment: "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif", shadowmap_pars_fragment: "#if NUM_SPOT_LIGHT_COORDS > 0\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n\tuniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tfloat shadow = 1.0;\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\t\n\t\tfloat lightToPositionLength = length( lightToPosition );\n\t\tif ( lightToPositionLength - shadowCameraFar <= 0.0 && lightToPositionLength - shadowCameraNear >= 0.0 ) {\n\t\t\tfloat dp = ( lightToPositionLength - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\t\tdp += shadowBias;\n\t\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\t\tshadow = (\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t\t) * ( 1.0 / 9.0 );\n\t\t\t#else\n\t\t\t\tshadow = texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t\t#endif\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n#endif", shadowmap_pars_vertex: "#if NUM_SPOT_LIGHT_COORDS > 0\n\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif", shadowmap_vertex: "#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n#endif", shadowmask_pars_fragment: "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}", skinbase_vertex: "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif", skinning_pars_vertex: "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tint size = textureSize( boneTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif", skinning_vertex: "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif", skinnormal_vertex: "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif", specularmap_fragment: "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vSpecularMapUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif", specularmap_pars_fragment: "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif", tonemapping_fragment: "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif", tonemapping_pars_fragment: "#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 CineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n\tvec3( 1.6605, - 0.1246, - 0.0182 ),\n\tvec3( - 0.5876, 1.1329, - 0.1006 ),\n\tvec3( - 0.0728, - 0.0083, 1.1187 )\n);\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n\tvec3( 0.6274, 0.0691, 0.0164 ),\n\tvec3( 0.3293, 0.9195, 0.0880 ),\n\tvec3( 0.0433, 0.0113, 0.8956 )\n);\nvec3 agxDefaultContrastApprox( vec3 x ) {\n\tvec3 x2 = x * x;\n\tvec3 x4 = x2 * x2;\n\treturn + 15.5 * x4 * x2\n\t\t- 40.14 * x4 * x\n\t\t+ 31.96 * x4\n\t\t- 6.868 * x2 * x\n\t\t+ 0.4298 * x2\n\t\t+ 0.1191 * x\n\t\t- 0.00232;\n}\nvec3 AgXToneMapping( vec3 color ) {\n\tconst mat3 AgXInsetMatrix = mat3(\n\t\tvec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n\t\tvec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n\t\tvec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )\n\t);\n\tconst mat3 AgXOutsetMatrix = mat3(\n\t\tvec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),\n\t\tvec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),\n\t\tvec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )\n\t);\n\tconst float AgxMinEv = - 12.47393;\tconst float AgxMaxEv = 4.026069;\n\tcolor *= toneMappingExposure;\n\tcolor = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n\tcolor = AgXInsetMatrix * color;\n\tcolor = max( color, 1e-10 );\tcolor = log2( color );\n\tcolor = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );\n\tcolor = clamp( color, 0.0, 1.0 );\n\tcolor = agxDefaultContrastApprox( color );\n\tcolor = AgXOutsetMatrix * color;\n\tcolor = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );\n\tcolor = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n\tcolor = clamp( color, 0.0, 1.0 );\n\treturn color;\n}\nvec3 NeutralToneMapping( vec3 color ) {\n\tconst float StartCompression = 0.8 - 0.04;\n\tconst float Desaturation = 0.15;\n\tcolor *= toneMappingExposure;\n\tfloat x = min( color.r, min( color.g, color.b ) );\n\tfloat offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n\tcolor -= offset;\n\tfloat peak = max( color.r, max( color.g, color.b ) );\n\tif ( peak < StartCompression ) return color;\n\tfloat d = 1. - StartCompression;\n\tfloat newPeak = 1. - d * d / ( peak + d - StartCompression );\n\tcolor *= newPeak / peak;\n\tfloat g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );\n\treturn mix( color, vec3( newPeak ), g );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }", transmission_fragment: "#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmitted = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif", transmission_pars_fragment: "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tfloat w0( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 );\n\t}\n\tfloat w1( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 );\n\t}\n\tfloat w2( float a ){\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 );\n\t}\n\tfloat w3( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * a );\n\t}\n\tfloat g0( float a ) {\n\t\treturn w0( a ) + w1( a );\n\t}\n\tfloat g1( float a ) {\n\t\treturn w2( a ) + w3( a );\n\t}\n\tfloat h0( float a ) {\n\t\treturn - 1.0 + w1( a ) / ( w0( a ) + w1( a ) );\n\t}\n\tfloat h1( float a ) {\n\t\treturn 1.0 + w3( a ) / ( w2( a ) + w3( a ) );\n\t}\n\tvec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) {\n\t\tuv = uv * texelSize.zw + 0.5;\n\t\tvec2 iuv = floor( uv );\n\t\tvec2 fuv = fract( uv );\n\t\tfloat g0x = g0( fuv.x );\n\t\tfloat g1x = g1( fuv.x );\n\t\tfloat h0x = h0( fuv.x );\n\t\tfloat h1x = h1( fuv.x );\n\t\tfloat h0y = h0( fuv.y );\n\t\tfloat h1y = h1( fuv.y );\n\t\tvec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\treturn g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) +\n\t\t\tg1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) );\n\t}\n\tvec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) {\n\t\tvec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) );\n\t\tvec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) );\n\t\tvec2 fLodSizeInv = 1.0 / fLodSize;\n\t\tvec2 cLodSizeInv = 1.0 / cLodSize;\n\t\tvec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) );\n\t\tvec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) );\n\t\treturn mix( fSample, cSample, fract( lod ) );\n\t}\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\treturn textureBicubic( transmissionSamplerMap, fragCoord.xy, lod );\n\t}\n\tvec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn vec3( 1.0 );\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec4 transmittedLight;\n\t\tvec3 transmittance;\n\t\t#ifdef USE_DISPERSION\n\t\t\tfloat halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;\n\t\t\tvec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );\n\t\t\tfor ( int i = 0; i < 3; i ++ ) {\n\t\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );\n\t\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\t\trefractionCoords += 1.0;\n\t\t\t\trefractionCoords /= 2.0;\n\t\t\t\tvec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );\n\t\t\t\ttransmittedLight[ i ] = transmissionSample[ i ];\n\t\t\t\ttransmittedLight.a += transmissionSample.a;\n\t\t\t\ttransmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];\n\t\t\t}\n\t\t\ttransmittedLight.a /= 3.0;\n\t\t#else\n\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\trefractionCoords += 1.0;\n\t\t\trefractionCoords /= 2.0;\n\t\t\ttransmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\t\ttransmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\t#endif\n\t\tvec3 attenuatedColor = transmittance * transmittedLight.rgb;\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\tfloat transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0;\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor );\n\t}\n#endif", uv_pars_fragment: "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif", uv_pars_vertex: "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tuniform mat3 mapTransform;\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform mat3 alphaMapTransform;\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tuniform mat3 lightMapTransform;\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tuniform mat3 aoMapTransform;\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tuniform mat3 bumpMapTransform;\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tuniform mat3 normalMapTransform;\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tuniform mat3 displacementMapTransform;\n\tvarying vec2 vDisplacementMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tuniform mat3 emissiveMapTransform;\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tuniform mat3 metalnessMapTransform;\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tuniform mat3 roughnessMapTransform;\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tuniform mat3 anisotropyMapTransform;\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tuniform mat3 clearcoatMapTransform;\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform mat3 clearcoatNormalMapTransform;\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform mat3 clearcoatRoughnessMapTransform;\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tuniform mat3 sheenColorMapTransform;\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tuniform mat3 sheenRoughnessMapTransform;\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tuniform mat3 iridescenceMapTransform;\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform mat3 iridescenceThicknessMapTransform;\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tuniform mat3 specularMapTransform;\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tuniform mat3 specularColorMapTransform;\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tuniform mat3 specularIntensityMapTransform;\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif", uv_vertex: "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvUv = vec3( uv, 1 ).xy;\n#endif\n#ifdef USE_MAP\n\tvMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ALPHAMAP\n\tvAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_LIGHTMAP\n\tvLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_AOMAP\n\tvAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_BUMPMAP\n\tvBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_NORMALMAP\n\tvNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tvDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_METALNESSMAP\n\tvMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULARMAP\n\tvSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tvTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_THICKNESSMAP\n\tvThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy;\n#endif", worldpos_vertex: "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_BATCHING\n\t\tworldPosition = batchingMatrix * worldPosition;\n\t#endif\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif", background_vert: "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}", background_frag: "uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\ttexColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}", backgroundCube_vert: "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}", backgroundCube_frag: "#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nuniform mat3 backgroundRotation;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}", cube_vert: "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}", cube_frag: "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}", depth_vert: "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvHighPrecisionZW = gl_Position.zw;\n}", depth_frag: "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#elif DEPTH_PACKING == 3202\n\t\tgl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 );\n\t#elif DEPTH_PACKING == 3203\n\t\tgl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 );\n\t#endif\n}", distanceRGBA_vert: "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}", distanceRGBA_frag: "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}", equirect_vert: "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}", equirect_frag: "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\t#include \n\t#include \n}", linedashed_vert: "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", linedashed_frag: "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshbasic_vert: "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshbasic_frag: "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshlambert_vert: "#define LAMBERT\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}", meshlambert_frag: "#define LAMBERT\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshmatcap_vert: "#define MATCAP\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}", meshmatcap_frag: "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshnormal_vert: "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}", meshnormal_frag: "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), diffuseColor.a );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}", meshphong_vert: "#define PHONG\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}", meshphong_frag: "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshphysical_vert: "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}", meshphysical_frag: "#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define USE_SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef USE_SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULAR_COLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_DISPERSION\n\tuniform float dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\tuniform vec2 anisotropyVector;\n\t#ifdef USE_ANISOTROPYMAP\n\t\tuniform sampler2D anisotropyMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include \n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecularDirect + sheenSpecularIndirect;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshtoon_vert: "#define TOON\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}", meshtoon_frag: "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", points_vert: "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef USE_POINTS_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif\nvoid main() {\n\t#ifdef USE_POINTS_UV\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}", points_frag: "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", shadow_vert: "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", shadow_frag: "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n\t#include \n\t#include \n}", sprite_vert: "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix[ 3 ];\n\tvec2 scale = vec2( length( modelMatrix[ 0 ].xyz ), length( modelMatrix[ 1 ].xyz ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}", sprite_frag: "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n}" }, vc = { common: { diffuse: { value: new Wi(16777215) }, opacity: { value: 1 }, map: { value: null }, mapTransform: { value: new Qt }, alphaMap: { value: null }, alphaMapTransform: { value: new Qt }, alphaTest: { value: 0 } }, specularmap: { specularMap: { value: null }, specularMapTransform: { value: new Qt } }, envmap: { envMap: { value: null }, envMapRotation: { value: new Qt }, flipEnvMap: { value: -1 }, reflectivity: { value: 1 }, ior: { value: 1.5 }, refractionRatio: { value: .98 } }, aomap: { aoMap: { value: null }, aoMapIntensity: { value: 1 }, aoMapTransform: { value: new Qt } }, lightmap: { lightMap: { value: null }, lightMapIntensity: { value: 1 }, lightMapTransform: { value: new Qt } }, bumpmap: { bumpMap: { value: null }, bumpMapTransform: { value: new Qt }, bumpScale: { value: 1 } }, normalmap: { normalMap: { value: null }, normalMapTransform: { value: new Qt }, normalScale: { value: new jt(1, 1) } }, displacementmap: { displacementMap: { value: null }, displacementMapTransform: { value: new Qt }, displacementScale: { value: 1 }, displacementBias: { value: 0 } }, emissivemap: { emissiveMap: { value: null }, emissiveMapTransform: { value: new Qt } }, metalnessmap: { metalnessMap: { value: null }, metalnessMapTransform: { value: new Qt } }, roughnessmap: { roughnessMap: { value: null }, roughnessMapTransform: { value: new Qt } }, gradientmap: { gradientMap: { value: null } }, fog: { fogDensity: { value: 25e-5 }, fogNear: { value: 1 }, fogFar: { value: 2e3 }, fogColor: { value: new Wi(16777215) } }, lights: { ambientLightColor: { value: [] }, lightProbe: { value: [] }, directionalLights: { value: [], properties: { direction: {}, color: {} } }, directionalLightShadows: { value: [], properties: { shadowIntensity: 1, shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {} } }, directionalShadowMap: { value: [] }, directionalShadowMatrix: { value: [] }, spotLights: { value: [], properties: { color: {}, position: {}, direction: {}, distance: {}, coneCos: {}, penumbraCos: {}, decay: {} } }, spotLightShadows: { value: [], properties: { shadowIntensity: 1, shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {} } }, spotLightMap: { value: [] }, spotShadowMap: { value: [] }, spotLightMatrix: { value: [] }, pointLights: { value: [], properties: { color: {}, position: {}, decay: {}, distance: {} } }, pointLightShadows: { value: [], properties: { shadowIntensity: 1, shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {}, shadowCameraNear: {}, shadowCameraFar: {} } }, pointShadowMap: { value: [] }, pointShadowMatrix: { value: [] }, hemisphereLights: { value: [], properties: { direction: {}, skyColor: {}, groundColor: {} } }, rectAreaLights: { value: [], properties: { color: {}, position: {}, width: {}, height: {} } }, ltc_1: { value: null }, ltc_2: { value: null } }, points: { diffuse: { value: new Wi(16777215) }, opacity: { value: 1 }, size: { value: 1 }, scale: { value: 1 }, map: { value: null }, alphaMap: { value: null }, alphaMapTransform: { value: new Qt }, alphaTest: { value: 0 }, uvTransform: { value: new Qt } }, sprite: { diffuse: { value: new Wi(16777215) }, opacity: { value: 1 }, center: { value: new jt(.5, .5) }, rotation: { value: 0 }, map: { value: null }, mapTransform: { value: new Qt }, alphaMap: { value: null }, alphaMapTransform: { value: new Qt }, alphaTest: { value: 0 } } }, wc = { basic: { uniforms: xr([vc.common, vc.specularmap, vc.envmap, vc.aomap, vc.lightmap, vc.fog]), vertexShader: gc.meshbasic_vert, fragmentShader: gc.meshbasic_frag }, lambert: { uniforms: xr([vc.common, vc.specularmap, vc.envmap, vc.aomap, vc.lightmap, vc.emissivemap, vc.bumpmap, vc.normalmap, vc.displacementmap, vc.fog, vc.lights, { emissive: { value: new Wi(0) } }]), vertexShader: gc.meshlambert_vert, fragmentShader: gc.meshlambert_frag }, phong: { uniforms: xr([vc.common, vc.specularmap, vc.envmap, vc.aomap, vc.lightmap, vc.emissivemap, vc.bumpmap, vc.normalmap, vc.displacementmap, vc.fog, vc.lights, { emissive: { value: new Wi(0) }, specular: { value: new Wi(1118481) }, shininess: { value: 30 } }]), vertexShader: gc.meshphong_vert, fragmentShader: gc.meshphong_frag }, standard: { uniforms: xr([vc.common, vc.envmap, vc.aomap, vc.lightmap, vc.emissivemap, vc.bumpmap, vc.normalmap, vc.displacementmap, vc.roughnessmap, vc.metalnessmap, vc.fog, vc.lights, { emissive: { value: new Wi(0) }, roughness: { value: 1 }, metalness: { value: 0 }, envMapIntensity: { value: 1 } }]), vertexShader: gc.meshphysical_vert, fragmentShader: gc.meshphysical_frag }, toon: { uniforms: xr([vc.common, vc.aomap, vc.lightmap, vc.emissivemap, vc.bumpmap, vc.normalmap, vc.displacementmap, vc.gradientmap, vc.fog, vc.lights, { emissive: { value: new Wi(0) } }]), vertexShader: gc.meshtoon_vert, fragmentShader: gc.meshtoon_frag }, matcap: { uniforms: xr([vc.common, vc.bumpmap, vc.normalmap, vc.displacementmap, vc.fog, { matcap: { value: null } }]), vertexShader: gc.meshmatcap_vert, fragmentShader: gc.meshmatcap_frag }, points: { uniforms: xr([vc.points, vc.fog]), vertexShader: gc.points_vert, fragmentShader: gc.points_frag }, dashed: { uniforms: xr([vc.common, vc.fog, { scale: { value: 1 }, dashSize: { value: 1 }, totalSize: { value: 2 } }]), vertexShader: gc.linedashed_vert, fragmentShader: gc.linedashed_frag }, depth: { uniforms: xr([vc.common, vc.displacementmap]), vertexShader: gc.depth_vert, fragmentShader: gc.depth_frag }, normal: { uniforms: xr([vc.common, vc.bumpmap, vc.normalmap, vc.displacementmap, { opacity: { value: 1 } }]), vertexShader: gc.meshnormal_vert, fragmentShader: gc.meshnormal_frag }, sprite: { uniforms: xr([vc.sprite, vc.fog]), vertexShader: gc.sprite_vert, fragmentShader: gc.sprite_frag }, background: { uniforms: { uvTransform: { value: new Qt }, t2D: { value: null }, backgroundIntensity: { value: 1 } }, vertexShader: gc.background_vert, fragmentShader: gc.background_frag }, backgroundCube: { uniforms: { envMap: { value: null }, flipEnvMap: { value: -1 }, backgroundBlurriness: { value: 0 }, backgroundIntensity: { value: 1 }, backgroundRotation: { value: new Qt } }, vertexShader: gc.backgroundCube_vert, fragmentShader: gc.backgroundCube_frag }, cube: { uniforms: { tCube: { value: null }, tFlip: { value: -1 }, opacity: { value: 1 } }, vertexShader: gc.cube_vert, fragmentShader: gc.cube_frag }, equirect: { uniforms: { tEquirect: { value: null } }, vertexShader: gc.equirect_vert, fragmentShader: gc.equirect_frag }, distanceRGBA: { uniforms: xr([vc.common, vc.displacementmap, { referencePosition: { value: new yn }, nearDistance: { value: 1 }, farDistance: { value: 1e3 } }]), vertexShader: gc.distanceRGBA_vert, fragmentShader: gc.distanceRGBA_frag }, shadow: { uniforms: xr([vc.lights, vc.fog, { color: { value: new Wi(0) }, opacity: { value: 1 } }]), vertexShader: gc.shadow_vert, fragmentShader: gc.shadow_frag } }; wc.physical = { uniforms: xr([wc.standard.uniforms, { clearcoat: { value: 0 }, clearcoatMap: { value: null }, clearcoatMapTransform: { value: new Qt }, clearcoatNormalMap: { value: null }, clearcoatNormalMapTransform: { value: new Qt }, clearcoatNormalScale: { value: new jt(1, 1) }, clearcoatRoughness: { value: 0 }, clearcoatRoughnessMap: { value: null }, clearcoatRoughnessMapTransform: { value: new Qt }, dispersion: { value: 0 }, iridescence: { value: 0 }, iridescenceMap: { value: null }, iridescenceMapTransform: { value: new Qt }, iridescenceIOR: { value: 1.3 }, iridescenceThicknessMinimum: { value: 100 }, iridescenceThicknessMaximum: { value: 400 }, iridescenceThicknessMap: { value: null }, iridescenceThicknessMapTransform: { value: new Qt }, sheen: { value: 0 }, sheenColor: { value: new Wi(0) }, sheenColorMap: { value: null }, sheenColorMapTransform: { value: new Qt }, sheenRoughness: { value: 1 }, sheenRoughnessMap: { value: null }, sheenRoughnessMapTransform: { value: new Qt }, transmission: { value: 0 }, transmissionMap: { value: null }, transmissionMapTransform: { value: new Qt }, transmissionSamplerSize: { value: new jt }, transmissionSamplerMap: { value: null }, thickness: { value: 0 }, thicknessMap: { value: null }, thicknessMapTransform: { value: new Qt }, attenuationDistance: { value: 0 }, attenuationColor: { value: new Wi(0) }, specularColor: { value: new Wi(1, 1, 1) }, specularColorMap: { value: null }, specularColorMapTransform: { value: new Qt }, specularIntensity: { value: 1 }, specularIntensityMap: { value: null }, specularIntensityMapTransform: { value: new Qt }, anisotropyVector: { value: new jt }, anisotropyMap: { value: null }, anisotropyMapTransform: { value: new Qt } }]), vertexShader: gc.meshphysical_vert, fragmentShader: gc.meshphysical_frag }; const yc = { r: 0, b: 0, g: 0 }, Ac = new ai, bc = new qn; function xc(e, t, n, i, r, a, s) { const o = new Wi(0); let l, c, h = !0 === a ? 0 : 1, d = null, u = 0, p = null; function f(e) { let i = !0 === e.isScene ? e.background : null; if (i && i.isTexture) { i = (e.backgroundBlurriness > 0 ? n : t).get(i) } return i } function m(t, n) { t.getRGB(yc, kr(e)), i.buffers.color.setClear(yc.r, yc.g, yc.b, n, s) } return { getClearColor: function() { return o }, setClearColor: function(e, t = 1) { o.set(e), h = t, m(o, h) }, getClearAlpha: function() { return h }, setClearAlpha: function(e) { h = e, m(o, h) }, render: function(t) { let n = !1; const r = f(t); null === r ? m(o, h) : r && r.isColor && (m(r, 1), n = !0); const a = e.xr.getEnvironmentBlendMode(); "additive" === a ? i.buffers.color.setClear(0, 0, 0, 1, s) : "alpha-blend" === a && i.buffers.color.setClear(0, 0, 0, 0, s), (e.autoClear || n) && (i.buffers.depth.setTest(!0), i.buffers.depth.setMask(!0), i.buffers.color.setMask(!0), e.clear(e.autoClearColor, e.autoClearDepth, e.autoClearStencil)) }, addToRenderList: function(t, n) { const i = f(n); i && (i.isCubeTexture || i.mapping === ie) ? (void 0 === c && (c = new wr(new Ar(1, 1, 1), new Sr({ name: "BackgroundCubeMaterial", uniforms: br(wc.backgroundCube.uniforms), vertexShader: wc.backgroundCube.vertexShader, fragmentShader: wc.backgroundCube.fragmentShader, side: 1, depthTest: !1, depthWrite: !1, fog: !1 })), c.geometry.deleteAttribute("normal"), c.geometry.deleteAttribute("uv"), c.onBeforeRender = function(e, t, n) { this.matrixWorld.copyPosition(n.matrixWorld) }, Object.defineProperty(c.material, "envMap", { get: function() { return this.uniforms.envMap.value } }), r.update(c)), Ac.copy(n.backgroundRotation), Ac.x *= -1, Ac.y *= -1, Ac.z *= -1, i.isCubeTexture && !1 === i.isRenderTargetTexture && (Ac.y *= -1, Ac.z *= -1), c.material.uniforms.envMap.value = i, c.material.uniforms.flipEnvMap.value = i.isCubeTexture && !1 === i.isRenderTargetTexture ? -1 : 1, c.material.uniforms.backgroundBlurriness.value = n.backgroundBlurriness, c.material.uniforms.backgroundIntensity.value = n.backgroundIntensity, c.material.uniforms.backgroundRotation.value.setFromMatrix4(bc.makeRotationFromEuler(Ac)), c.material.toneMapped = nn.getTransfer(i.colorSpace) !== yt, d === i && u === i.version && p === e.toneMapping || (c.material.needsUpdate = !0, d = i, u = i.version, p = e.toneMapping), c.layers.enableAll(), t.unshift(c, c.geometry, c.material, 0, 0, null)) : i && i.isTexture && (void 0 === l && (l = new wr(new Ns(2, 2), new Sr({ name: "BackgroundMaterial", uniforms: br(wc.background.uniforms), vertexShader: wc.background.vertexShader, fragmentShader: wc.background.fragmentShader, side: 0, depthTest: !1, depthWrite: !1, fog: !1 })), l.geometry.deleteAttribute("normal"), Object.defineProperty(l.material, "map", { get: function() { return this.uniforms.t2D.value } }), r.update(l)), l.material.uniforms.t2D.value = i, l.material.uniforms.backgroundIntensity.value = n.backgroundIntensity, l.material.toneMapped = nn.getTransfer(i.colorSpace) !== yt, !0 === i.matrixAutoUpdate && i.updateMatrix(), l.material.uniforms.uvTransform.value.copy(i.matrix), d === i && u === i.version && p === e.toneMapping || (l.material.needsUpdate = !0, d = i, u = i.version, p = e.toneMapping), l.layers.enableAll(), t.unshift(l, l.geometry, l.material, 0, 0, null)) }, dispose: function() { void 0 !== c && (c.geometry.dispose(), c.material.dispose(), c = void 0), void 0 !== l && (l.geometry.dispose(), l.material.dispose(), l = void 0) } } } function kc(e, t) { const n = e.getParameter(e.MAX_VERTEX_ATTRIBS), i = {}, r = c(null); let a = r, s = !1; function o(t) { return e.bindVertexArray(t) } function l(t) { return e.deleteVertexArray(t) } function c(e) { const t = [], i = [], r = []; for (let e = 0; e < n; e++) t[e] = 0, i[e] = 0, r[e] = 0; return { geometry: null, program: null, wireframe: !1, newAttributes: t, enabledAttributes: i, attributeDivisors: r, object: e, attributes: {}, index: null } } function h() { const e = a.newAttributes; for (let t = 0, n = e.length; t < n; t++) e[t] = 0 } function d(e) { u(e, 0) } function u(t, n) { const i = a.newAttributes, r = a.enabledAttributes, s = a.attributeDivisors; i[t] = 1, 0 === r[t] && (e.enableVertexAttribArray(t), r[t] = 1), s[t] !== n && (e.vertexAttribDivisor(t, n), s[t] = n) } function p() { const t = a.newAttributes, n = a.enabledAttributes; for (let i = 0, r = n.length; i < r; i++) n[i] !== t[i] && (e.disableVertexAttribArray(i), n[i] = 0) } function f(t, n, i, r, a, s, o) { !0 === o ? e.vertexAttribIPointer(t, n, i, a, s) : e.vertexAttribPointer(t, n, i, r, a, s) } function m() { g(), s = !0, a !== r && (a = r, o(a.object)) } function g() { r.geometry = null, r.program = null, r.wireframe = !1 } return { setup: function(n, r, l, m, g) { let v = !1; const w = function(t, n, r) { const a = !0 === r.wireframe; let s = i[t.id]; void 0 === s && (s = {}, i[t.id] = s); let o = s[n.id]; void 0 === o && (o = {}, s[n.id] = o); let l = o[a]; void 0 === l && (l = c(e.createVertexArray()), o[a] = l); return l }(m, l, r); a !== w && (a = w, o(a.object)), v = function(e, t, n, i) { const r = a.attributes, s = t.attributes; let o = 0; const l = n.getAttributes(); for (const t in l) { if (l[t].location >= 0) { const n = r[t]; let i = s[t]; if (void 0 === i && ("instanceMatrix" === t && e.instanceMatrix && (i = e.instanceMatrix), "instanceColor" === t && e.instanceColor && (i = e.instanceColor)), void 0 === n) return !0; if (n.attribute !== i) return !0; if (i && n.data !== i.data) return !0; o++ } } return a.attributesNum !== o || a.index !== i }(n, m, l, g), v && function(e, t, n, i) { const r = {}, s = t.attributes; let o = 0; const l = n.getAttributes(); for (const t in l) { if (l[t].location >= 0) { let n = s[t]; void 0 === n && ("instanceMatrix" === t && e.instanceMatrix && (n = e.instanceMatrix), "instanceColor" === t && e.instanceColor && (n = e.instanceColor)); const i = {}; i.attribute = n, n && n.data && (i.data = n.data), r[t] = i, o++ } } a.attributes = r, a.attributesNum = o, a.index = i }(n, m, l, g), null !== g && t.update(g, e.ELEMENT_ARRAY_BUFFER), (v || s) && (s = !1, function(n, i, r, a) { h(); const s = a.attributes, o = r.getAttributes(), l = i.defaultAttributeValues; for (const i in o) { const r = o[i]; if (r.location >= 0) { let o = s[i]; if (void 0 === o && ("instanceMatrix" === i && n.instanceMatrix && (o = n.instanceMatrix), "instanceColor" === i && n.instanceColor && (o = n.instanceColor)), void 0 !== o) { const i = o.normalized, s = o.itemSize, l = t.get(o); if (void 0 === l) continue; const c = l.buffer, h = l.type, p = l.bytesPerElement, m = h === e.INT || h === e.UNSIGNED_INT || o.gpuType === ve; if (o.isInterleavedBufferAttribute) { const t = o.data, l = t.stride, g = o.offset; if (t.isInstancedInterleavedBuffer) { for (let e = 0; e < r.locationSize; e++) u(r.location + e, t.meshPerAttribute); !0 !== n.isInstancedMesh && void 0 === a._maxInstanceCount && (a._maxInstanceCount = t.meshPerAttribute * t.count) } else for (let e = 0; e < r.locationSize; e++) d(r.location + e); e.bindBuffer(e.ARRAY_BUFFER, c); for (let e = 0; e < r.locationSize; e++) f(r.location + e, s / r.locationSize, h, i, l * p, (g + s / r.locationSize * e) * p, m) } else { if (o.isInstancedBufferAttribute) { for (let e = 0; e < r.locationSize; e++) u(r.location + e, o.meshPerAttribute); !0 !== n.isInstancedMesh && void 0 === a._maxInstanceCount && (a._maxInstanceCount = o.meshPerAttribute * o.count) } else for (let e = 0; e < r.locationSize; e++) d(r.location + e); e.bindBuffer(e.ARRAY_BUFFER, c); for (let e = 0; e < r.locationSize; e++) f(r.location + e, s / r.locationSize, h, i, s * p, s / r.locationSize * e * p, m) } } else if (void 0 !== l) { const t = l[i]; if (void 0 !== t) switch (t.length) { case 2: e.vertexAttrib2fv(r.location, t); break; case 3: e.vertexAttrib3fv(r.location, t); break; case 4: e.vertexAttrib4fv(r.location, t); break; default: e.vertexAttrib1fv(r.location, t) } } } } p() }(n, r, l, m), null !== g && e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, t.get(g).buffer)) }, reset: m, resetDefaultState: g, dispose: function() { m(); for (const e in i) { const t = i[e]; for (const e in t) { const n = t[e]; for (const e in n) l(n[e].object), delete n[e]; delete t[e] } delete i[e] } }, releaseStatesOfGeometry: function(e) { if (void 0 === i[e.id]) return; const t = i[e.id]; for (const e in t) { const n = t[e]; for (const e in n) l(n[e].object), delete n[e]; delete t[e] } delete i[e.id] }, releaseStatesOfProgram: function(e) { for (const t in i) { const n = i[t]; if (void 0 === n[e.id]) continue; const r = n[e.id]; for (const e in r) l(r[e].object), delete r[e]; delete n[e.id] } }, initAttributes: h, enableAttribute: d, disableUnusedAttributes: p } } function Ec(e, t, n) { let i; function r(t, r, a) { 0 !== a && (e.drawArraysInstanced(i, t, r, a), n.update(r, i, a)) } this.setMode = function(e) { i = e }, this.render = function(t, r) { e.drawArrays(i, t, r), n.update(r, i, 1) }, this.renderInstances = r, this.renderMultiDraw = function(e, r, a) { if (0 === a) return; t.get("WEBGL_multi_draw").multiDrawArraysWEBGL(i, e, 0, r, 0, a); let s = 0; for (let e = 0; e < a; e++) s += r[e]; n.update(s, i, 1) }, this.renderMultiDrawInstances = function(e, a, s, o) { if (0 === s) return; const l = t.get("WEBGL_multi_draw"); if (null === l) for (let t = 0; t < e.length; t++) r(e[t], a[t], o[t]); else { l.multiDrawArraysInstancedWEBGL(i, e, 0, a, 0, o, 0, s); let t = 0; for (let e = 0; e < s; e++) t += a[e] * o[e]; n.update(t, i, 1) } } } function Sc(e, t, n, i) { let r; function a(t) { if ("highp" === t) { if (e.getShaderPrecisionFormat(e.VERTEX_SHADER, e.HIGH_FLOAT).precision > 0 && e.getShaderPrecisionFormat(e.FRAGMENT_SHADER, e.HIGH_FLOAT).precision > 0) return "highp"; t = "mediump" } return "mediump" === t && e.getShaderPrecisionFormat(e.VERTEX_SHADER, e.MEDIUM_FLOAT).precision > 0 && e.getShaderPrecisionFormat(e.FRAGMENT_SHADER, e.MEDIUM_FLOAT).precision > 0 ? "mediump" : "lowp" } let s = void 0 !== n.precision ? n.precision : "highp"; const o = a(s); o !== s && (console.warn("THREE.WebGLRenderer:", s, "not supported, using", o, "instead."), s = o); const l = !0 === n.logarithmicDepthBuffer, c = !0 === n.reverseDepthBuffer && t.has("EXT_clip_control"), h = e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS), d = e.getParameter(e.MAX_VERTEX_TEXTURE_IMAGE_UNITS); return { isWebGL2: !0, getMaxAnisotropy: function() { if (void 0 !== r) return r; if (!0 === t.has("EXT_texture_filter_anisotropic")) { const n = t.get("EXT_texture_filter_anisotropic"); r = e.getParameter(n.MAX_TEXTURE_MAX_ANISOTROPY_EXT) } else r = 0; return r }, getMaxPrecision: a, textureFormatReadable: function(t) { return t === Se || i.convert(t) === e.getParameter(e.IMPLEMENTATION_COLOR_READ_FORMAT) }, textureTypeReadable: function(n) { const r = n === Ae && (t.has("EXT_color_buffer_half_float") || t.has("EXT_color_buffer_float")); return !(n !== pe && i.convert(n) !== e.getParameter(e.IMPLEMENTATION_COLOR_READ_TYPE) && n !== ye && !r) }, precision: s, logarithmicDepthBuffer: l, reverseDepthBuffer: c, maxTextures: h, maxVertexTextures: d, maxTextureSize: e.getParameter(e.MAX_TEXTURE_SIZE), maxCubemapSize: e.getParameter(e.MAX_CUBE_MAP_TEXTURE_SIZE), maxAttributes: e.getParameter(e.MAX_VERTEX_ATTRIBS), maxVertexUniforms: e.getParameter(e.MAX_VERTEX_UNIFORM_VECTORS), maxVaryings: e.getParameter(e.MAX_VARYING_VECTORS), maxFragmentUniforms: e.getParameter(e.MAX_FRAGMENT_UNIFORM_VECTORS), vertexTextures: d > 0, maxSamples: e.getParameter(e.MAX_SAMPLES) } } function Mc(e) { const t = this; let n = null, i = 0, r = !1, a = !1; const s = new ga, o = new Qt, l = { value: null, needsUpdate: !1 }; function c(e, n, i, r) { const a = null !== e ? e.length : 0; let c = null; if (0 !== a) { if (c = l.value, !0 !== r || null === c) { const t = i + 4 * a, r = n.matrixWorldInverse; o.getNormalMatrix(r), (null === c || c.length < t) && (c = new Float32Array(t)); for (let t = 0, n = i; t !== a; ++t, n += 4) s.copy(e[t]).applyMatrix4(r, o), s.normal.toArray(c, n), c[n + 3] = s.constant } l.value = c, l.needsUpdate = !0 } return t.numPlanes = a, t.numIntersection = 0, c } this.uniform = l, this.numPlanes = 0, this.numIntersection = 0, this.init = function(e, t) { const n = 0 !== e.length || t || 0 !== i || r; return r = t, i = e.length, n }, this.beginShadows = function() { a = !0, c(null) }, this.endShadows = function() { a = !1 }, this.setGlobalState = function(e, t) { n = c(e, t, 0) }, this.setState = function(s, o, h) { const d = s.clippingPlanes, u = s.clipIntersection, p = s.clipShadows, f = e.get(s); if (!r || null === d || 0 === d.length || a && !p) a ? c(null) : function() { l.value !== n && (l.value = n, l.needsUpdate = i > 0); t.numPlanes = i, t.numIntersection = 0 }(); else { const e = a ? 0 : i, t = 4 * e; let r = f.clippingState || null; l.value = r, r = c(d, o, t, h); for (let e = 0; e !== t; ++e) r[e] = n[e]; f.clippingState = r, this.numIntersection = u ? this.numPlanes : 0, this.numPlanes += e } } } function Tc(e) { let t = new WeakMap; function n(e, t) { return t === te ? e.mapping = $ : t === ne && (e.mapping = ee), e } function i(e) { const n = e.target; n.removeEventListener("dispose", i); const r = t.get(n); void 0 !== r && (t.delete(n), r.dispose()) } return { get: function(r) { if (r && r.isTexture) { const a = r.mapping; if (a === te || a === ne) { if (t.has(r)) { return n(t.get(r).texture, r.mapping) } { const a = r.image; if (a && a.height > 0) { const s = new Dr(a.height); return s.fromEquirectangularTexture(e, r), t.set(r, s), r.addEventListener("dispose", i), n(s.texture, r.mapping) } return null } } } return r }, dispose: function() { t = new WeakMap } } } const _c = [.125, .215, .35, .446, .526, .582], Cc = 20, Pc = new Io, Ic = new Wi; let Rc = null, Lc = 0, Dc = 0, Nc = !1; const Bc = (1 + Math.sqrt(5)) / 2, Uc = 1 / Bc, zc = [new yn(-Bc, Uc, 0), new yn(Bc, Uc, 0), new yn(-Uc, 0, Bc), new yn(Uc, 0, Bc), new yn(0, Bc, -Uc), new yn(0, Bc, Uc), new yn(-1, 1, -1), new yn(1, 1, -1), new yn(-1, 1, 1), new yn(1, 1, 1)], Oc = new yn; class Fc { constructor(e) { this._renderer = e, this._pingPongRenderTarget = null, this._lodMax = 0, this._cubeSize = 0, this._lodPlanes = [], this._sizeLods = [], this._sigmas = [], this._blurMaterial = null, this._cubemapMaterial = null, this._equirectMaterial = null, this._compileMaterial(this._blurMaterial) } fromScene(e, t = 0, n = .1, i = 100, r = {}) { const { size: a = 256, position: s = Oc } = r; Rc = this._renderer.getRenderTarget(), Lc = this._renderer.getActiveCubeFace(), Dc = this._renderer.getActiveMipmapLevel(), Nc = this._renderer.xr.enabled, this._renderer.xr.enabled = !1, this._setSize(a); const o = this._allocateTargets(); return o.depthBuffer = !0, this._sceneToCubeUV(e, n, i, o, s), t > 0 && this._blur(o, 0, 0, t), this._applyPMREM(o), this._cleanup(o), o } fromEquirectangular(e, t = null) { return this._fromTexture(e, t) } fromCubemap(e, t = null) { return this._fromTexture(e, t) } compileCubemapShader() { null === this._cubemapMaterial && (this._cubemapMaterial = Gc(), this._compileMaterial(this._cubemapMaterial)) } compileEquirectangularShader() { null === this._equirectMaterial && (this._equirectMaterial = Hc(), this._compileMaterial(this._equirectMaterial)) } dispose() { this._dispose(), null !== this._cubemapMaterial && this._cubemapMaterial.dispose(), null !== this._equirectMaterial && this._equirectMaterial.dispose() } _setSize(e) { this._lodMax = Math.floor(Math.log2(e)), this._cubeSize = Math.pow(2, this._lodMax) } _dispose() { null !== this._blurMaterial && this._blurMaterial.dispose(), null !== this._pingPongRenderTarget && this._pingPongRenderTarget.dispose(); for (let e = 0; e < this._lodPlanes.length; e++) this._lodPlanes[e].dispose() } _cleanup(e) { this._renderer.setRenderTarget(Rc, Lc, Dc), this._renderer.xr.enabled = Nc, e.scissorTest = !1, Vc(e, 0, 0, e.width, e.height) } _fromTexture(e, t) { e.mapping === $ || e.mapping === ee ? this._setSize(0 === e.image.length ? 16 : e.image[0].width || e.image[0].image.width) : this._setSize(e.image.width / 4), Rc = this._renderer.getRenderTarget(), Lc = this._renderer.getActiveCubeFace(), Dc = this._renderer.getActiveMipmapLevel(), Nc = this._renderer.xr.enabled, this._renderer.xr.enabled = !1; const n = t || this._allocateTargets(); return this._textureToCubeUV(e, n), this._applyPMREM(n), this._cleanup(n), n } _allocateTargets() { const e = 3 * Math.max(this._cubeSize, 112), t = 4 * this._cubeSize, n = { magFilter: he, minFilter: he, generateMipmaps: !1, type: Ae, format: Se, colorSpace: vt, depthBuffer: !1 }, i = Wc(e, t, n); if (null === this._pingPongRenderTarget || this._pingPongRenderTarget.width !== e || this._pingPongRenderTarget.height !== t) { null !== this._pingPongRenderTarget && this._dispose(), this._pingPongRenderTarget = Wc(e, t, n); const { _lodMax: i } = this; ({ sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas } = function(e) { const t = [], n = [], i = []; let r = e; const a = e - 4 + 1 + _c.length; for (let s = 0; s < a; s++) { const a = Math.pow(2, r); n.push(a); let o = 1 / a; s > e - 4 ? o = _c[s - e + 4 - 1] : 0 === s && (o = 0), i.push(o); const l = 1 / (a - 2), c = -l, h = 1 + l, d = [c, c, h, c, h, h, c, c, h, h, c, h], u = 6, p = 6, f = 3, m = 2, g = 1, v = new Float32Array(f * p * u), w = new Float32Array(m * p * u), y = new Float32Array(g * p * u); for (let e = 0; e < u; e++) { const t = e % 3 * 2 / 3 - 1, n = e > 2 ? 0 : -1, i = [t, n, 0, t + 2 / 3, n, 0, t + 2 / 3, n + 1, 0, t, n, 0, t + 2 / 3, n + 1, 0, t, n + 1, 0]; v.set(i, f * p * e), w.set(d, m * p * e); const r = [e, e, e, e, e, e]; y.set(r, g * p * e) } const A = new sr; A.setAttribute("position", new qi(v, f)), A.setAttribute("uv", new qi(w, m)), A.setAttribute("faceIndex", new qi(y, g)), t.push(A), r > 4 && r-- } return { lodPlanes: t, sizeLods: n, sigmas: i } }(i)), this._blurMaterial = function(e, t, n) { const i = new Float32Array(Cc), r = new yn(0, 1, 0), a = new Sr({ name: "SphericalGaussianBlur", defines: { n: Cc, CUBEUV_TEXEL_WIDTH: 1 / t, CUBEUV_TEXEL_HEIGHT: 1 / n, CUBEUV_MAX_MIP: `${e}.0` }, uniforms: { envMap: { value: null }, samples: { value: 1 }, weights: { value: i }, latitudinal: { value: !1 }, dTheta: { value: 0 }, mipInt: { value: 0 }, poleAxis: { value: r } }, vertexShader: jc(), fragmentShader: "\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform int samples;\n\t\t\tuniform float weights[ n ];\n\t\t\tuniform bool latitudinal;\n\t\t\tuniform float dTheta;\n\t\t\tuniform float mipInt;\n\t\t\tuniform vec3 poleAxis;\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\t#include \n\n\t\t\tvec3 getSample( float theta, vec3 axis ) {\n\n\t\t\t\tfloat cosTheta = cos( theta );\n\t\t\t\t// Rodrigues' axis-angle rotation\n\t\t\t\tvec3 sampleDirection = vOutputDirection * cosTheta\n\t\t\t\t\t+ cross( axis, vOutputDirection ) * sin( theta )\n\t\t\t\t\t+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );\n\n\t\t\t\treturn bilinearCubeUV( envMap, sampleDirection, mipInt );\n\n\t\t\t}\n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );\n\n\t\t\t\tif ( all( equal( axis, vec3( 0.0 ) ) ) ) {\n\n\t\t\t\t\taxis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );\n\n\t\t\t\t}\n\n\t\t\t\taxis = normalize( axis );\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t\t\t\tgl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );\n\n\t\t\t\tfor ( int i = 1; i < n; i++ ) {\n\n\t\t\t\t\tif ( i >= samples ) {\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfloat theta = dTheta * float( i );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( theta, axis );\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t", blending: 0, depthTest: !1, depthWrite: !1 }); return a }(i, e, t) } return i } _compileMaterial(e) { const t = new wr(this._lodPlanes[0], e); this._renderer.compile(t, Pc) } _sceneToCubeUV(e, t, n, i, r) { const a = new Pr(90, 1, t, n), s = [1, -1, 1, 1, 1, 1], o = [1, 1, 1, -1, -1, -1], l = this._renderer, c = l.autoClear, h = l.toneMapping; l.getClearColor(Ic), l.toneMapping = 0, l.autoClear = !1; const d = new ji({ name: "PMREM.Background", side: 1, depthWrite: !1, depthTest: !1 }), u = new wr(new Ar, d); let p = !1; const f = e.background; f ? f.isColor && (d.color.copy(f), e.background = null, p = !0) : (d.color.copy(Ic), p = !0); for (let t = 0; t < 6; t++) { const n = t % 3; 0 === n ? (a.up.set(0, s[t], 0), a.position.set(r.x, r.y, r.z), a.lookAt(r.x + o[t], r.y, r.z)) : 1 === n ? (a.up.set(0, 0, s[t]), a.position.set(r.x, r.y, r.z), a.lookAt(r.x, r.y + o[t], r.z)) : (a.up.set(0, s[t], 0), a.position.set(r.x, r.y, r.z), a.lookAt(r.x, r.y, r.z + o[t])); const c = this._cubeSize; Vc(i, n * c, t > 2 ? c : 0, c, c), l.setRenderTarget(i), p && l.render(u, a), l.render(e, a) } u.geometry.dispose(), u.material.dispose(), l.toneMapping = h, l.autoClear = c, e.background = f } _textureToCubeUV(e, t) { const n = this._renderer, i = e.mapping === $ || e.mapping === ee; i ? (null === this._cubemapMaterial && (this._cubemapMaterial = Gc()), this._cubemapMaterial.uniforms.flipEnvMap.value = !1 === e.isRenderTargetTexture ? -1 : 1) : null === this._equirectMaterial && (this._equirectMaterial = Hc()); const r = i ? this._cubemapMaterial : this._equirectMaterial, a = new wr(this._lodPlanes[0], r); r.uniforms.envMap.value = e; const s = this._cubeSize; Vc(t, 0, 0, 3 * s, 2 * s), n.setRenderTarget(t), n.render(a, Pc) } _applyPMREM(e) { const t = this._renderer, n = t.autoClear; t.autoClear = !1; const i = this._lodPlanes.length; for (let t = 1; t < i; t++) { const n = Math.sqrt(this._sigmas[t] * this._sigmas[t] - this._sigmas[t - 1] * this._sigmas[t - 1]), r = zc[(i - t - 1) % zc.length]; this._blur(e, t - 1, t, n, r) } t.autoClear = n } _blur(e, t, n, i, r) { const a = this._pingPongRenderTarget; this._halfBlur(e, a, t, n, i, "latitudinal", r), this._halfBlur(a, e, n, n, i, "longitudinal", r) } _halfBlur(e, t, n, i, r, a, s) { const o = this._renderer, l = this._blurMaterial; "latitudinal" !== a && "longitudinal" !== a && console.error("blur direction must be either latitudinal or longitudinal!"); const c = new wr(this._lodPlanes[i], l), h = l.uniforms, d = this._sizeLods[n] - 1, u = isFinite(r) ? Math.PI / (2 * d) : 2 * Math.PI / 39, p = r / u, f = isFinite(r) ? 1 + Math.floor(3 * p) : Cc; f > Cc && console.warn(`sigmaRadians, ${r}, is too large and will clip, as it requested ${f} samples when the maximum is set to 20`); const m = []; let g = 0; for (let e = 0; e < Cc; ++e) { const t = e / p, n = Math.exp(-t * t / 2); m.push(n), 0 === e ? g += n : e < f && (g += 2 * n) } for (let e = 0; e < m.length; e++) m[e] = m[e] / g; h.envMap.value = e.texture, h.samples.value = f, h.weights.value = m, h.latitudinal.value = "latitudinal" === a, s && (h.poleAxis.value = s); const { _lodMax: v } = this; h.dTheta.value = u, h.mipInt.value = v - n; const w = this._sizeLods[i]; Vc(t, 3 * w * (i > v - 4 ? i - v + 4 : 0), 4 * (this._cubeSize - w), 3 * w, 2 * w), o.setRenderTarget(t), o.render(c, Pc) } } function Wc(e, t, n) { const i = new mn(e, t, n); return i.texture.mapping = ie, i.texture.name = "PMREM.cubeUv", i.scissorTest = !0, i } function Vc(e, t, n, i, r) { e.viewport.set(t, n, i, r), e.scissor.set(t, n, i, r) } function Hc() { return new Sr({ name: "EquirectangularToCubeUV", uniforms: { envMap: { value: null } }, vertexShader: jc(), fragmentShader: "\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\n\t\t\t#include \n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 outputDirection = normalize( vOutputDirection );\n\t\t\t\tvec2 uv = equirectUv( outputDirection );\n\n\t\t\t\tgl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );\n\n\t\t\t}\n\t\t", blending: 0, depthTest: !1, depthWrite: !1 }) } function Gc() { return new Sr({ name: "CubemapToCubeUV", uniforms: { envMap: { value: null }, flipEnvMap: { value: -1 } }, vertexShader: jc(), fragmentShader: "\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tuniform float flipEnvMap;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform samplerCube envMap;\n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );\n\n\t\t\t}\n\t\t", blending: 0, depthTest: !1, depthWrite: !1 }) } function jc() { return "\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\n\t\tattribute float faceIndex;\n\n\t\tvarying vec3 vOutputDirection;\n\n\t\t// RH coordinate system; PMREM face-indexing convention\n\t\tvec3 getDirection( vec2 uv, float face ) {\n\n\t\t\tuv = 2.0 * uv - 1.0;\n\n\t\t\tvec3 direction = vec3( uv, 1.0 );\n\n\t\t\tif ( face == 0.0 ) {\n\n\t\t\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\n\t\t\t} else if ( face == 1.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\n\t\t\t} else if ( face == 2.0 ) {\n\n\t\t\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\n\t\t\t} else if ( face == 3.0 ) {\n\n\t\t\t\tdirection = direction.zyx;\n\t\t\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\n\t\t\t} else if ( face == 4.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\n\t\t\t} else if ( face == 5.0 ) {\n\n\t\t\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\n\t\t\t}\n\n\t\t\treturn direction;\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvOutputDirection = getDirection( uv, faceIndex );\n\t\t\tgl_Position = vec4( position, 1.0 );\n\n\t\t}\n\t" } function Qc(e) { let t = new WeakMap, n = null; function i(e) { const n = e.target; n.removeEventListener("dispose", i); const r = t.get(n); void 0 !== r && (t.delete(n), r.dispose()) } return { get: function(r) { if (r && r.isTexture) { const a = r.mapping, s = a === te || a === ne, o = a === $ || a === ee; if (s || o) { let a = t.get(r); const l = void 0 !== a ? a.texture.pmremVersion : 0; if (r.isRenderTargetTexture && r.pmremVersion !== l) return null === n && (n = new Fc(e)), a = s ? n.fromEquirectangular(r, a) : n.fromCubemap(r, a), a.texture.pmremVersion = r.pmremVersion, t.set(r, a), a.texture; if (void 0 !== a) return a.texture; { const l = r.image; return s && l && l.height > 0 || o && l && function(e) { let t = 0; const n = 6; for (let i = 0; i < n; i++) void 0 !== e[i] && t++; return t === n }(l) ? (null === n && (n = new Fc(e)), a = s ? n.fromEquirectangular(r) : n.fromCubemap(r), a.texture.pmremVersion = r.pmremVersion, t.set(r, a), r.addEventListener("dispose", i), a.texture) : null } } } return r }, dispose: function() { t = new WeakMap, null !== n && (n.dispose(), n = null) } } } function Yc(e) { const t = {}; function n(n) { if (void 0 !== t[n]) return t[n]; let i; switch (n) { case "WEBGL_depth_texture": i = e.getExtension("WEBGL_depth_texture") || e.getExtension("MOZ_WEBGL_depth_texture") || e.getExtension("WEBKIT_WEBGL_depth_texture"); break; case "EXT_texture_filter_anisotropic": i = e.getExtension("EXT_texture_filter_anisotropic") || e.getExtension("MOZ_EXT_texture_filter_anisotropic") || e.getExtension("WEBKIT_EXT_texture_filter_anisotropic"); break; case "WEBGL_compressed_texture_s3tc": i = e.getExtension("WEBGL_compressed_texture_s3tc") || e.getExtension("MOZ_WEBGL_compressed_texture_s3tc") || e.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc"); break; case "WEBGL_compressed_texture_pvrtc": i = e.getExtension("WEBGL_compressed_texture_pvrtc") || e.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"); break; default: i = e.getExtension(n) } return t[n] = i, i } return { has: function(e) { return null !== n(e) }, init: function() { n("EXT_color_buffer_float"), n("WEBGL_clip_cull_distance"), n("OES_texture_float_linear"), n("EXT_color_buffer_half_float"), n("WEBGL_multisampled_render_to_texture"), n("WEBGL_render_shared_exponent") }, get: function(e) { const t = n(e); return null === t && Jt("THREE.WebGLRenderer: " + e + " extension not supported."), t } } } function Kc(e, t, n, i) { const r = {}, a = new WeakMap; function s(e) { const o = e.target; null !== o.index && t.remove(o.index); for (const e in o.attributes) t.remove(o.attributes[e]); o.removeEventListener("dispose", s), delete r[o.id]; const l = a.get(o); l && (t.remove(l), a.delete(o)), i.releaseStatesOfGeometry(o), !0 === o.isInstancedBufferGeometry && delete o._maxInstanceCount, n.memory.geometries-- } function o(e) { const n = [], i = e.index, r = e.attributes.position; let s = 0; if (null !== i) { const e = i.array; s = i.version; for (let t = 0, i = e.length; t < i; t += 3) { const i = e[t + 0], r = e[t + 1], a = e[t + 2]; n.push(i, r, r, a, a, i) } } else { if (void 0 === r) return; { const e = r.array; s = r.version; for (let t = 0, i = e.length / 3 - 1; t < i; t += 3) { const e = t + 0, i = t + 1, r = t + 2; n.push(e, i, i, r, r, e) } } } const o = new(Kt(n) ? Zi : Xi)(n, 1); o.version = s; const l = a.get(e); l && t.remove(l), a.set(e, o) } return { get: function(e, t) { return !0 === r[t.id] || (t.addEventListener("dispose", s), r[t.id] = !0, n.memory.geometries++), t }, update: function(n) { const i = n.attributes; for (const n in i) t.update(i[n], e.ARRAY_BUFFER) }, getWireframeAttribute: function(e) { const t = a.get(e); if (t) { const n = e.index; null !== n && t.version < n.version && o(e) } else o(e); return a.get(e) } } } function qc(e, t, n) { let i, r, a; function s(t, s, o) { 0 !== o && (e.drawElementsInstanced(i, s, r, t * a, o), n.update(s, i, o)) } this.setMode = function(e) { i = e }, this.setIndex = function(e) { r = e.type, a = e.bytesPerElement }, this.render = function(t, s) { e.drawElements(i, s, r, t * a), n.update(s, i, 1) }, this.renderInstances = s, this.renderMultiDraw = function(e, a, s) { if (0 === s) return; t.get("WEBGL_multi_draw").multiDrawElementsWEBGL(i, a, 0, r, e, 0, s); let o = 0; for (let e = 0; e < s; e++) o += a[e]; n.update(o, i, 1) }, this.renderMultiDrawInstances = function(e, o, l, c) { if (0 === l) return; const h = t.get("WEBGL_multi_draw"); if (null === h) for (let t = 0; t < e.length; t++) s(e[t] / a, o[t], c[t]); else { h.multiDrawElementsInstancedWEBGL(i, o, 0, r, e, 0, c, 0, l); let t = 0; for (let e = 0; e < l; e++) t += o[e] * c[e]; n.update(t, i, 1) } } } function Xc(e) { const t = { frame: 0, calls: 0, triangles: 0, points: 0, lines: 0 }; return { memory: { geometries: 0, textures: 0 }, render: t, programs: null, autoReset: !0, reset: function() { t.calls = 0, t.triangles = 0, t.points = 0, t.lines = 0 }, update: function(n, i, r) { switch (t.calls++, i) { case e.TRIANGLES: t.triangles += r * (n / 3); break; case e.LINES: t.lines += r * (n / 2); break; case e.LINE_STRIP: t.lines += r * (n - 1); break; case e.LINE_LOOP: t.lines += r * n; break; case e.POINTS: t.points += r * n; break; default: console.error("THREE.WebGLInfo: Unknown draw mode:", i) } } } } function Zc(e, t, n) { const i = new WeakMap, r = new pn; return { update: function(a, s, o) { const l = a.morphTargetInfluences, c = s.morphAttributes.position || s.morphAttributes.normal || s.morphAttributes.color, h = void 0 !== c ? c.length : 0; let d = i.get(s); if (void 0 === d || d.count !== h) { void 0 !== d && d.texture.dispose(); const u = void 0 !== s.morphAttributes.position, p = void 0 !== s.morphAttributes.normal, f = void 0 !== s.morphAttributes.color, m = s.morphAttributes.position || [], g = s.morphAttributes.normal || [], v = s.morphAttributes.color || []; let w = 0; !0 === u && (w = 1), !0 === p && (w = 2), !0 === f && (w = 3); let y = s.attributes.position.count * w, A = 1; y > t.maxTextureSize && (A = Math.ceil(y / t.maxTextureSize), y = t.maxTextureSize); const b = new Float32Array(y * A * 4 * h), x = new gn(b, y, A, h); x.type = ye, x.needsUpdate = !0; const k = 4 * w; for (let S = 0; S < h; S++) { const M = m[S], T = g[S], _ = v[S], C = y * A * 4 * S; for (let P = 0; P < M.count; P++) { const I = P * k; !0 === u && (r.fromBufferAttribute(M, P), b[C + I + 0] = r.x, b[C + I + 1] = r.y, b[C + I + 2] = r.z, b[C + I + 3] = 0), !0 === p && (r.fromBufferAttribute(T, P), b[C + I + 4] = r.x, b[C + I + 5] = r.y, b[C + I + 6] = r.z, b[C + I + 7] = 0), !0 === f && (r.fromBufferAttribute(_, P), b[C + I + 8] = r.x, b[C + I + 9] = r.y, b[C + I + 10] = r.z, b[C + I + 11] = 4 === _.itemSize ? r.w : 1) } } function E() { x.dispose(), i.delete(s), s.removeEventListener("dispose", E) } d = { count: h, texture: x, size: new jt(y, A) }, i.set(s, d), s.addEventListener("dispose", E) } if (!0 === a.isInstancedMesh && null !== a.morphTexture) o.getUniforms().setValue(e, "morphTexture", a.morphTexture, n); else { let R = 0; for (let D = 0; D < l.length; D++) R += l[D]; const L = s.morphTargetsRelative ? 1 : 1 - R; o.getUniforms().setValue(e, "morphTargetBaseInfluence", L), o.getUniforms().setValue(e, "morphTargetInfluences", l) } o.getUniforms().setValue(e, "morphTargetsTexture", d.texture, n), o.getUniforms().setValue(e, "morphTargetsTextureSize", d.size) } } } function Jc(e, t, n, i) { let r = new WeakMap; function a(e) { const t = e.target; t.removeEventListener("dispose", a), n.remove(t.instanceMatrix), null !== t.instanceColor && n.remove(t.instanceColor) } return { update: function(s) { const o = i.render.frame, l = s.geometry, c = t.get(s, l); if (r.get(c) !== o && (t.update(c), r.set(c, o)), s.isInstancedMesh && (!1 === s.hasEventListener("dispose", a) && s.addEventListener("dispose", a), r.get(s) !== o && (n.update(s.instanceMatrix, e.ARRAY_BUFFER), null !== s.instanceColor && n.update(s.instanceColor, e.ARRAY_BUFFER), r.set(s, o))), s.isSkinnedMesh) { const e = s.skeleton; r.get(e) !== o && (e.update(), r.set(e, o)) } return c }, dispose: function() { r = new WeakMap } } } const $c = new un, eh = new Wa(1, 1), th = new gn, nh = new vn, ih = new Lr, rh = [], ah = [], sh = new Float32Array(16), oh = new Float32Array(9), lh = new Float32Array(4); function ch(e, t, n) { const i = e[0]; if (i <= 0 || i > 0) return e; const r = t * n; let a = rh[r]; if (void 0 === a && (a = new Float32Array(r), rh[r] = a), 0 !== t) { i.toArray(a, 0); for (let i = 1, r = 0; i !== t; ++i) r += n, e[i].toArray(a, r) } return a } function hh(e, t) { if (e.length !== t.length) return !1; for (let n = 0, i = e.length; n < i; n++) if (e[n] !== t[n]) return !1; return !0 } function dh(e, t) { for (let n = 0, i = t.length; n < i; n++) e[n] = t[n] } function uh(e, t) { let n = ah[t]; void 0 === n && (n = new Int32Array(t), ah[t] = n); for (let i = 0; i !== t; ++i) n[i] = e.allocateTextureUnit(); return n } function ph(e, t) { const n = this.cache; n[0] !== t && (e.uniform1f(this.addr, t), n[0] = t) } function fh(e, t) { const n = this.cache; if (void 0 !== t.x) n[0] === t.x && n[1] === t.y || (e.uniform2f(this.addr, t.x, t.y), n[0] = t.x, n[1] = t.y); else { if (hh(n, t)) return; e.uniform2fv(this.addr, t), dh(n, t) } } function mh(e, t) { const n = this.cache; if (void 0 !== t.x) n[0] === t.x && n[1] === t.y && n[2] === t.z || (e.uniform3f(this.addr, t.x, t.y, t.z), n[0] = t.x, n[1] = t.y, n[2] = t.z); else if (void 0 !== t.r) n[0] === t.r && n[1] === t.g && n[2] === t.b || (e.uniform3f(this.addr, t.r, t.g, t.b), n[0] = t.r, n[1] = t.g, n[2] = t.b); else { if (hh(n, t)) return; e.uniform3fv(this.addr, t), dh(n, t) } } function gh(e, t) { const n = this.cache; if (void 0 !== t.x) n[0] === t.x && n[1] === t.y && n[2] === t.z && n[3] === t.w || (e.uniform4f(this.addr, t.x, t.y, t.z, t.w), n[0] = t.x, n[1] = t.y, n[2] = t.z, n[3] = t.w); else { if (hh(n, t)) return; e.uniform4fv(this.addr, t), dh(n, t) } } function vh(e, t) { const n = this.cache, i = t.elements; if (void 0 === i) { if (hh(n, t)) return; e.uniformMatrix2fv(this.addr, !1, t), dh(n, t) } else { if (hh(n, i)) return; lh.set(i), e.uniformMatrix2fv(this.addr, !1, lh), dh(n, i) } } function wh(e, t) { const n = this.cache, i = t.elements; if (void 0 === i) { if (hh(n, t)) return; e.uniformMatrix3fv(this.addr, !1, t), dh(n, t) } else { if (hh(n, i)) return; oh.set(i), e.uniformMatrix3fv(this.addr, !1, oh), dh(n, i) } } function yh(e, t) { const n = this.cache, i = t.elements; if (void 0 === i) { if (hh(n, t)) return; e.uniformMatrix4fv(this.addr, !1, t), dh(n, t) } else { if (hh(n, i)) return; sh.set(i), e.uniformMatrix4fv(this.addr, !1, sh), dh(n, i) } } function Ah(e, t) { const n = this.cache; n[0] !== t && (e.uniform1i(this.addr, t), n[0] = t) } function bh(e, t) { const n = this.cache; if (void 0 !== t.x) n[0] === t.x && n[1] === t.y || (e.uniform2i(this.addr, t.x, t.y), n[0] = t.x, n[1] = t.y); else { if (hh(n, t)) return; e.uniform2iv(this.addr, t), dh(n, t) } } function xh(e, t) { const n = this.cache; if (void 0 !== t.x) n[0] === t.x && n[1] === t.y && n[2] === t.z || (e.uniform3i(this.addr, t.x, t.y, t.z), n[0] = t.x, n[1] = t.y, n[2] = t.z); else { if (hh(n, t)) return; e.uniform3iv(this.addr, t), dh(n, t) } } function kh(e, t) { const n = this.cache; if (void 0 !== t.x) n[0] === t.x && n[1] === t.y && n[2] === t.z && n[3] === t.w || (e.uniform4i(this.addr, t.x, t.y, t.z, t.w), n[0] = t.x, n[1] = t.y, n[2] = t.z, n[3] = t.w); else { if (hh(n, t)) return; e.uniform4iv(this.addr, t), dh(n, t) } } function Eh(e, t) { const n = this.cache; n[0] !== t && (e.uniform1ui(this.addr, t), n[0] = t) } function Sh(e, t) { const n = this.cache; if (void 0 !== t.x) n[0] === t.x && n[1] === t.y || (e.uniform2ui(this.addr, t.x, t.y), n[0] = t.x, n[1] = t.y); else { if (hh(n, t)) return; e.uniform2uiv(this.addr, t), dh(n, t) } } function Mh(e, t) { const n = this.cache; if (void 0 !== t.x) n[0] === t.x && n[1] === t.y && n[2] === t.z || (e.uniform3ui(this.addr, t.x, t.y, t.z), n[0] = t.x, n[1] = t.y, n[2] = t.z); else { if (hh(n, t)) return; e.uniform3uiv(this.addr, t), dh(n, t) } } function Th(e, t) { const n = this.cache; if (void 0 !== t.x) n[0] === t.x && n[1] === t.y && n[2] === t.z && n[3] === t.w || (e.uniform4ui(this.addr, t.x, t.y, t.z, t.w), n[0] = t.x, n[1] = t.y, n[2] = t.z, n[3] = t.w); else { if (hh(n, t)) return; e.uniform4uiv(this.addr, t), dh(n, t) } } function _h(e, t, n) { const i = this.cache, r = n.allocateTextureUnit(); let a; i[0] !== r && (e.uniform1i(this.addr, r), i[0] = r), this.type === e.SAMPLER_2D_SHADOW ? (eh.compareFunction = 515, a = eh) : a = $c, n.setTexture2D(t || a, r) } function Ch(e, t, n) { const i = this.cache, r = n.allocateTextureUnit(); i[0] !== r && (e.uniform1i(this.addr, r), i[0] = r), n.setTexture3D(t || nh, r) } function Ph(e, t, n) { const i = this.cache, r = n.allocateTextureUnit(); i[0] !== r && (e.uniform1i(this.addr, r), i[0] = r), n.setTextureCube(t || ih, r) } function Ih(e, t, n) { const i = this.cache, r = n.allocateTextureUnit(); i[0] !== r && (e.uniform1i(this.addr, r), i[0] = r), n.setTexture2DArray(t || th, r) } function Rh(e, t) { e.uniform1fv(this.addr, t) } function Lh(e, t) { const n = ch(t, this.size, 2); e.uniform2fv(this.addr, n) } function Dh(e, t) { const n = ch(t, this.size, 3); e.uniform3fv(this.addr, n) } function Nh(e, t) { const n = ch(t, this.size, 4); e.uniform4fv(this.addr, n) } function Bh(e, t) { const n = ch(t, this.size, 4); e.uniformMatrix2fv(this.addr, !1, n) } function Uh(e, t) { const n = ch(t, this.size, 9); e.uniformMatrix3fv(this.addr, !1, n) } function zh(e, t) { const n = ch(t, this.size, 16); e.uniformMatrix4fv(this.addr, !1, n) } function Oh(e, t) { e.uniform1iv(this.addr, t) } function Fh(e, t) { e.uniform2iv(this.addr, t) } function Wh(e, t) { e.uniform3iv(this.addr, t) } function Vh(e, t) { e.uniform4iv(this.addr, t) } function Hh(e, t) { e.uniform1uiv(this.addr, t) } function Gh(e, t) { e.uniform2uiv(this.addr, t) } function jh(e, t) { e.uniform3uiv(this.addr, t) } function Qh(e, t) { e.uniform4uiv(this.addr, t) } function Yh(e, t, n) { const i = this.cache, r = t.length, a = uh(n, r); hh(i, a) || (e.uniform1iv(this.addr, a), dh(i, a)); for (let e = 0; e !== r; ++e) n.setTexture2D(t[e] || $c, a[e]) } function Kh(e, t, n) { const i = this.cache, r = t.length, a = uh(n, r); hh(i, a) || (e.uniform1iv(this.addr, a), dh(i, a)); for (let e = 0; e !== r; ++e) n.setTexture3D(t[e] || nh, a[e]) } function qh(e, t, n) { const i = this.cache, r = t.length, a = uh(n, r); hh(i, a) || (e.uniform1iv(this.addr, a), dh(i, a)); for (let e = 0; e !== r; ++e) n.setTextureCube(t[e] || ih, a[e]) } function Xh(e, t, n) { const i = this.cache, r = t.length, a = uh(n, r); hh(i, a) || (e.uniform1iv(this.addr, a), dh(i, a)); for (let e = 0; e !== r; ++e) n.setTexture2DArray(t[e] || th, a[e]) } class Zh { constructor(e, t, n) { this.id = e, this.addr = n, this.cache = [], this.type = t.type, this.setValue = function(e) { switch (e) { case 5126: return ph; case 35664: return fh; case 35665: return mh; case 35666: return gh; case 35674: return vh; case 35675: return wh; case 35676: return yh; case 5124: case 35670: return Ah; case 35667: case 35671: return bh; case 35668: case 35672: return xh; case 35669: case 35673: return kh; case 5125: return Eh; case 36294: return Sh; case 36295: return Mh; case 36296: return Th; case 35678: case 36198: case 36298: case 36306: case 35682: return _h; case 35679: case 36299: case 36307: return Ch; case 35680: case 36300: case 36308: case 36293: return Ph; case 36289: case 36303: case 36311: case 36292: return Ih } }(t.type) } } class Jh { constructor(e, t, n) { this.id = e, this.addr = n, this.cache = [], this.type = t.type, this.size = t.size, this.setValue = function(e) { switch (e) { case 5126: return Rh; case 35664: return Lh; case 35665: return Dh; case 35666: return Nh; case 35674: return Bh; case 35675: return Uh; case 35676: return zh; case 5124: case 35670: return Oh; case 35667: case 35671: return Fh; case 35668: case 35672: return Wh; case 35669: case 35673: return Vh; case 5125: return Hh; case 36294: return Gh; case 36295: return jh; case 36296: return Qh; case 35678: case 36198: case 36298: case 36306: case 35682: return Yh; case 35679: case 36299: case 36307: return Kh; case 35680: case 36300: case 36308: case 36293: return qh; case 36289: case 36303: case 36311: case 36292: return Xh } }(t.type) } } class $h { constructor(e) { this.id = e, this.seq = [], this.map = {} } setValue(e, t, n) { const i = this.seq; for (let r = 0, a = i.length; r !== a; ++r) { const a = i[r]; a.setValue(e, t[a.id], n) } } } const ed = /(\w+)(\])?(\[|\.)?/g; function td(e, t) { e.seq.push(t), e.map[t.id] = t } function nd(e, t, n) { const i = e.name, r = i.length; for (ed.lastIndex = 0;;) { const a = ed.exec(i), s = ed.lastIndex; let o = a[1]; const l = "]" === a[2], c = a[3]; if (l && (o |= 0), void 0 === c || "[" === c && s + 2 === r) { td(n, void 0 === c ? new Zh(o, e, t) : new Jh(o, e, t)); break } { let e = n.map[o]; void 0 === e && (e = new $h(o), td(n, e)), n = e } } } class id { constructor(e, t) { this.seq = [], this.map = {}; const n = e.getProgramParameter(t, e.ACTIVE_UNIFORMS); for (let i = 0; i < n; ++i) { const n = e.getActiveUniform(t, i); nd(n, e.getUniformLocation(t, n.name), this) } } setValue(e, t, n, i) { const r = this.map[t]; void 0 !== r && r.setValue(e, n, i) } setOptional(e, t, n) { const i = t[n]; void 0 !== i && this.setValue(e, n, i) } static upload(e, t, n, i) { for (let r = 0, a = t.length; r !== a; ++r) { const a = t[r], s = n[a.id]; !1 !== s.needsUpdate && a.setValue(e, s.value, i) } } static seqWithValue(e, t) { const n = []; for (let i = 0, r = e.length; i !== r; ++i) { const r = e[i]; r.id in t && n.push(r) } return n } } function rd(e, t, n) { const i = e.createShader(t); return e.shaderSource(i, n), e.compileShader(i), i } let ad = 0; const sd = new Qt; function od(e, t, n) { const i = e.getShaderParameter(t, e.COMPILE_STATUS), r = e.getShaderInfoLog(t).trim(); if (i && "" === r) return ""; const a = /ERROR: 0:(\d+)/.exec(r); if (a) { const i = parseInt(a[1]); return n.toUpperCase() + "\n\n" + r + "\n\n" + function(e, t) { const n = e.split("\n"), i = [], r = Math.max(t - 6, 0), a = Math.min(t + 6, n.length); for (let e = r; e < a; e++) { const r = e + 1; i.push(`${r===t?">":" "} ${r}: ${n[e]}`) } return i.join("\n") }(e.getShaderSource(t), i) } return r } function ld(e, t) { const n = function(e) { nn._getMatrix(sd, nn.workingColorSpace, e); const t = `mat3( ${sd.elements.map((e=>e.toFixed(4)))} )`; switch (nn.getTransfer(e)) { case wt: return [t, "LinearTransferOETF"]; case yt: return [t, "sRGBTransferOETF"]; default: return console.warn("THREE.WebGLProgram: Unsupported color space: ", e), [t, "LinearTransferOETF"] } }(t); return [`vec4 ${e}( vec4 value ) {`, `\treturn ${n[1]}( vec4( value.rgb * ${n[0]}, value.a ) );`, "}"].join("\n") } function cd(e, t) { let n; switch (t) { case 1: n = "Linear"; break; case 2: n = "Reinhard"; break; case 3: n = "Cineon"; break; case 4: n = "ACESFilmic"; break; case 6: n = "AgX"; break; case 7: n = "Neutral"; break; case 5: n = "Custom"; break; default: console.warn("THREE.WebGLProgram: Unsupported toneMapping:", t), n = "Linear" } return "vec3 " + e + "( vec3 color ) { return " + n + "ToneMapping( color ); }" } const hd = new yn; function dd() { nn.getLuminanceCoefficients(hd); return ["float luminance( const in vec3 rgb ) {", `\tconst vec3 weights = vec3( ${hd.x.toFixed(4)}, ${hd.y.toFixed(4)}, ${hd.z.toFixed(4)} );`, "\treturn dot( weights, rgb );", "}"].join("\n") } function ud(e) { return "" !== e } function pd(e, t) { const n = t.numSpotLightShadows + t.numSpotLightMaps - t.numSpotLightShadowsWithMaps; return e.replace(/NUM_DIR_LIGHTS/g, t.numDirLights).replace(/NUM_SPOT_LIGHTS/g, t.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g, t.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g, n).replace(/NUM_RECT_AREA_LIGHTS/g, t.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g, t.numPointLights).replace(/NUM_HEMI_LIGHTS/g, t.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g, t.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS/g, t.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g, t.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, t.numPointLightShadows) } function fd(e, t) { return e.replace(/NUM_CLIPPING_PLANES/g, t.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, t.numClippingPlanes - t.numClipIntersection) } const md = /^[ \t]*#include +<([\w\d./]+)>/gm; function gd(e) { return e.replace(md, wd) } const vd = new Map; function wd(e, t) { let n = gc[t]; if (void 0 === n) { const e = vd.get(t); if (void 0 === e) throw new Error("Can not resolve #include <" + t + ">"); n = gc[e], console.warn('THREE.WebGLRenderer: Shader chunk "%s" has been deprecated. Use "%s" instead.', t, e) } return gd(n) } const yd = /#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g; function Ad(e) { return e.replace(yd, bd) } function bd(e, t, n, i) { let r = ""; for (let e = parseInt(t); e < parseInt(n); e++) r += i.replace(/\[\s*i\s*\]/g, "[ " + e + " ]").replace(/UNROLLED_LOOP_INDEX/g, e); return r } function xd(e) { let t = `precision ${e.precision} float;\n\tprecision ${e.precision} int;\n\tprecision ${e.precision} sampler2D;\n\tprecision ${e.precision} samplerCube;\n\tprecision ${e.precision} sampler3D;\n\tprecision ${e.precision} sampler2DArray;\n\tprecision ${e.precision} sampler2DShadow;\n\tprecision ${e.precision} samplerCubeShadow;\n\tprecision ${e.precision} sampler2DArrayShadow;\n\tprecision ${e.precision} isampler2D;\n\tprecision ${e.precision} isampler3D;\n\tprecision ${e.precision} isamplerCube;\n\tprecision ${e.precision} isampler2DArray;\n\tprecision ${e.precision} usampler2D;\n\tprecision ${e.precision} usampler3D;\n\tprecision ${e.precision} usamplerCube;\n\tprecision ${e.precision} usampler2DArray;\n\t`; return "highp" === e.precision ? t += "\n#define HIGH_PRECISION" : "mediump" === e.precision ? t += "\n#define MEDIUM_PRECISION" : "lowp" === e.precision && (t += "\n#define LOW_PRECISION"), t } function kd(e, t, n, i) { const r = e.getContext(), a = n.defines; let s = n.vertexShader, o = n.fragmentShader; const l = function(e) { let t = "SHADOWMAP_TYPE_BASIC"; return 1 === e.shadowMapType ? t = "SHADOWMAP_TYPE_PCF" : 2 === e.shadowMapType ? t = "SHADOWMAP_TYPE_PCF_SOFT" : 3 === e.shadowMapType && (t = "SHADOWMAP_TYPE_VSM"), t }(n), c = function(e) { let t = "ENVMAP_TYPE_CUBE"; if (e.envMap) switch (e.envMapMode) { case $: case ee: t = "ENVMAP_TYPE_CUBE"; break; case ie: t = "ENVMAP_TYPE_CUBE_UV" } return t }(n), h = function(e) { let t = "ENVMAP_MODE_REFLECTION"; e.envMap && e.envMapMode === ee && (t = "ENVMAP_MODE_REFRACTION"); return t }(n), d = function(e) { let t = "ENVMAP_BLENDING_NONE"; if (e.envMap) switch (e.combine) { case 0: t = "ENVMAP_BLENDING_MULTIPLY"; break; case 1: t = "ENVMAP_BLENDING_MIX"; break; case 2: t = "ENVMAP_BLENDING_ADD" } return t }(n), u = function(e) { const t = e.envMapCubeUVHeight; if (null === t) return null; const n = Math.log2(t) - 2, i = 1 / t; return { texelWidth: 1 / (3 * Math.max(Math.pow(2, n), 112)), texelHeight: i, maxMip: n } }(n), p = function(e) { return [e.extensionClipCullDistance ? "#extension GL_ANGLE_clip_cull_distance : require" : "", e.extensionMultiDraw ? "#extension GL_ANGLE_multi_draw : require" : ""].filter(ud).join("\n") }(n), f = function(e) { const t = []; for (const n in e) { const i = e[n]; !1 !== i && t.push("#define " + n + " " + i) } return t.join("\n") }(a), m = r.createProgram(); let g, v, w = n.glslVersion ? "#version " + n.glslVersion + "\n" : ""; n.isRawShaderMaterial ? (g = ["#define SHADER_TYPE " + n.shaderType, "#define SHADER_NAME " + n.shaderName, f].filter(ud).join("\n"), g.length > 0 && (g += "\n"), v = ["#define SHADER_TYPE " + n.shaderType, "#define SHADER_NAME " + n.shaderName, f].filter(ud).join("\n"), v.length > 0 && (v += "\n")) : (g = [xd(n), "#define SHADER_TYPE " + n.shaderType, "#define SHADER_NAME " + n.shaderName, f, n.extensionClipCullDistance ? "#define USE_CLIP_DISTANCE" : "", n.batching ? "#define USE_BATCHING" : "", n.batchingColor ? "#define USE_BATCHING_COLOR" : "", n.instancing ? "#define USE_INSTANCING" : "", n.instancingColor ? "#define USE_INSTANCING_COLOR" : "", n.instancingMorph ? "#define USE_INSTANCING_MORPH" : "", n.useFog && n.fog ? "#define USE_FOG" : "", n.useFog && n.fogExp2 ? "#define FOG_EXP2" : "", n.map ? "#define USE_MAP" : "", n.envMap ? "#define USE_ENVMAP" : "", n.envMap ? "#define " + h : "", n.lightMap ? "#define USE_LIGHTMAP" : "", n.aoMap ? "#define USE_AOMAP" : "", n.bumpMap ? "#define USE_BUMPMAP" : "", n.normalMap ? "#define USE_NORMALMAP" : "", n.normalMapObjectSpace ? "#define USE_NORMALMAP_OBJECTSPACE" : "", n.normalMapTangentSpace ? "#define USE_NORMALMAP_TANGENTSPACE" : "", n.displacementMap ? "#define USE_DISPLACEMENTMAP" : "", n.emissiveMap ? "#define USE_EMISSIVEMAP" : "", n.anisotropy ? "#define USE_ANISOTROPY" : "", n.anisotropyMap ? "#define USE_ANISOTROPYMAP" : "", n.clearcoatMap ? "#define USE_CLEARCOATMAP" : "", n.clearcoatRoughnessMap ? "#define USE_CLEARCOAT_ROUGHNESSMAP" : "", n.clearcoatNormalMap ? "#define USE_CLEARCOAT_NORMALMAP" : "", n.iridescenceMap ? "#define USE_IRIDESCENCEMAP" : "", n.iridescenceThicknessMap ? "#define USE_IRIDESCENCE_THICKNESSMAP" : "", n.specularMap ? "#define USE_SPECULARMAP" : "", n.specularColorMap ? "#define USE_SPECULAR_COLORMAP" : "", n.specularIntensityMap ? "#define USE_SPECULAR_INTENSITYMAP" : "", n.roughnessMap ? "#define USE_ROUGHNESSMAP" : "", n.metalnessMap ? "#define USE_METALNESSMAP" : "", n.alphaMap ? "#define USE_ALPHAMAP" : "", n.alphaHash ? "#define USE_ALPHAHASH" : "", n.transmission ? "#define USE_TRANSMISSION" : "", n.transmissionMap ? "#define USE_TRANSMISSIONMAP" : "", n.thicknessMap ? "#define USE_THICKNESSMAP" : "", n.sheenColorMap ? "#define USE_SHEEN_COLORMAP" : "", n.sheenRoughnessMap ? "#define USE_SHEEN_ROUGHNESSMAP" : "", n.mapUv ? "#define MAP_UV " + n.mapUv : "", n.alphaMapUv ? "#define ALPHAMAP_UV " + n.alphaMapUv : "", n.lightMapUv ? "#define LIGHTMAP_UV " + n.lightMapUv : "", n.aoMapUv ? "#define AOMAP_UV " + n.aoMapUv : "", n.emissiveMapUv ? "#define EMISSIVEMAP_UV " + n.emissiveMapUv : "", n.bumpMapUv ? "#define BUMPMAP_UV " + n.bumpMapUv : "", n.normalMapUv ? "#define NORMALMAP_UV " + n.normalMapUv : "", n.displacementMapUv ? "#define DISPLACEMENTMAP_UV " + n.displacementMapUv : "", n.metalnessMapUv ? "#define METALNESSMAP_UV " + n.metalnessMapUv : "", n.roughnessMapUv ? "#define ROUGHNESSMAP_UV " + n.roughnessMapUv : "", n.anisotropyMapUv ? "#define ANISOTROPYMAP_UV " + n.anisotropyMapUv : "", n.clearcoatMapUv ? "#define CLEARCOATMAP_UV " + n.clearcoatMapUv : "", n.clearcoatNormalMapUv ? "#define CLEARCOAT_NORMALMAP_UV " + n.clearcoatNormalMapUv : "", n.clearcoatRoughnessMapUv ? "#define CLEARCOAT_ROUGHNESSMAP_UV " + n.clearcoatRoughnessMapUv : "", n.iridescenceMapUv ? "#define IRIDESCENCEMAP_UV " + n.iridescenceMapUv : "", n.iridescenceThicknessMapUv ? "#define IRIDESCENCE_THICKNESSMAP_UV " + n.iridescenceThicknessMapUv : "", n.sheenColorMapUv ? "#define SHEEN_COLORMAP_UV " + n.sheenColorMapUv : "", n.sheenRoughnessMapUv ? "#define SHEEN_ROUGHNESSMAP_UV " + n.sheenRoughnessMapUv : "", n.specularMapUv ? "#define SPECULARMAP_UV " + n.specularMapUv : "", n.specularColorMapUv ? "#define SPECULAR_COLORMAP_UV " + n.specularColorMapUv : "", n.specularIntensityMapUv ? "#define SPECULAR_INTENSITYMAP_UV " + n.specularIntensityMapUv : "", n.transmissionMapUv ? "#define TRANSMISSIONMAP_UV " + n.transmissionMapUv : "", n.thicknessMapUv ? "#define THICKNESSMAP_UV " + n.thicknessMapUv : "", n.vertexTangents && !1 === n.flatShading ? "#define USE_TANGENT" : "", n.vertexColors ? "#define USE_COLOR" : "", n.vertexAlphas ? "#define USE_COLOR_ALPHA" : "", n.vertexUv1s ? "#define USE_UV1" : "", n.vertexUv2s ? "#define USE_UV2" : "", n.vertexUv3s ? "#define USE_UV3" : "", n.pointsUvs ? "#define USE_POINTS_UV" : "", n.flatShading ? "#define FLAT_SHADED" : "", n.skinning ? "#define USE_SKINNING" : "", n.morphTargets ? "#define USE_MORPHTARGETS" : "", n.morphNormals && !1 === n.flatShading ? "#define USE_MORPHNORMALS" : "", n.morphColors ? "#define USE_MORPHCOLORS" : "", n.morphTargetsCount > 0 ? "#define MORPHTARGETS_TEXTURE_STRIDE " + n.morphTextureStride : "", n.morphTargetsCount > 0 ? "#define MORPHTARGETS_COUNT " + n.morphTargetsCount : "", n.doubleSided ? "#define DOUBLE_SIDED" : "", n.flipSided ? "#define FLIP_SIDED" : "", n.shadowMapEnabled ? "#define USE_SHADOWMAP" : "", n.shadowMapEnabled ? "#define " + l : "", n.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "", n.numLightProbes > 0 ? "#define USE_LIGHT_PROBES" : "", n.logarithmicDepthBuffer ? "#define USE_LOGDEPTHBUF" : "", n.reverseDepthBuffer ? "#define USE_REVERSEDEPTHBUF" : "", "uniform mat4 modelMatrix;", "uniform mat4 modelViewMatrix;", "uniform mat4 projectionMatrix;", "uniform mat4 viewMatrix;", "uniform mat3 normalMatrix;", "uniform vec3 cameraPosition;", "uniform bool isOrthographic;", "#ifdef USE_INSTANCING", "\tattribute mat4 instanceMatrix;", "#endif", "#ifdef USE_INSTANCING_COLOR", "\tattribute vec3 instanceColor;", "#endif", "#ifdef USE_INSTANCING_MORPH", "\tuniform sampler2D morphTexture;", "#endif", "attribute vec3 position;", "attribute vec3 normal;", "attribute vec2 uv;", "#ifdef USE_UV1", "\tattribute vec2 uv1;", "#endif", "#ifdef USE_UV2", "\tattribute vec2 uv2;", "#endif", "#ifdef USE_UV3", "\tattribute vec2 uv3;", "#endif", "#ifdef USE_TANGENT", "\tattribute vec4 tangent;", "#endif", "#if defined( USE_COLOR_ALPHA )", "\tattribute vec4 color;", "#elif defined( USE_COLOR )", "\tattribute vec3 color;", "#endif", "#ifdef USE_SKINNING", "\tattribute vec4 skinIndex;", "\tattribute vec4 skinWeight;", "#endif", "\n"].filter(ud).join("\n"), v = [xd(n), "#define SHADER_TYPE " + n.shaderType, "#define SHADER_NAME " + n.shaderName, f, n.useFog && n.fog ? "#define USE_FOG" : "", n.useFog && n.fogExp2 ? "#define FOG_EXP2" : "", n.alphaToCoverage ? "#define ALPHA_TO_COVERAGE" : "", n.map ? "#define USE_MAP" : "", n.matcap ? "#define USE_MATCAP" : "", n.envMap ? "#define USE_ENVMAP" : "", n.envMap ? "#define " + c : "", n.envMap ? "#define " + h : "", n.envMap ? "#define " + d : "", u ? "#define CUBEUV_TEXEL_WIDTH " + u.texelWidth : "", u ? "#define CUBEUV_TEXEL_HEIGHT " + u.texelHeight : "", u ? "#define CUBEUV_MAX_MIP " + u.maxMip + ".0" : "", n.lightMap ? "#define USE_LIGHTMAP" : "", n.aoMap ? "#define USE_AOMAP" : "", n.bumpMap ? "#define USE_BUMPMAP" : "", n.normalMap ? "#define USE_NORMALMAP" : "", n.normalMapObjectSpace ? "#define USE_NORMALMAP_OBJECTSPACE" : "", n.normalMapTangentSpace ? "#define USE_NORMALMAP_TANGENTSPACE" : "", n.emissiveMap ? "#define USE_EMISSIVEMAP" : "", n.anisotropy ? "#define USE_ANISOTROPY" : "", n.anisotropyMap ? "#define USE_ANISOTROPYMAP" : "", n.clearcoat ? "#define USE_CLEARCOAT" : "", n.clearcoatMap ? "#define USE_CLEARCOATMAP" : "", n.clearcoatRoughnessMap ? "#define USE_CLEARCOAT_ROUGHNESSMAP" : "", n.clearcoatNormalMap ? "#define USE_CLEARCOAT_NORMALMAP" : "", n.dispersion ? "#define USE_DISPERSION" : "", n.iridescence ? "#define USE_IRIDESCENCE" : "", n.iridescenceMap ? "#define USE_IRIDESCENCEMAP" : "", n.iridescenceThicknessMap ? "#define USE_IRIDESCENCE_THICKNESSMAP" : "", n.specularMap ? "#define USE_SPECULARMAP" : "", n.specularColorMap ? "#define USE_SPECULAR_COLORMAP" : "", n.specularIntensityMap ? "#define USE_SPECULAR_INTENSITYMAP" : "", n.roughnessMap ? "#define USE_ROUGHNESSMAP" : "", n.metalnessMap ? "#define USE_METALNESSMAP" : "", n.alphaMap ? "#define USE_ALPHAMAP" : "", n.alphaTest ? "#define USE_ALPHATEST" : "", n.alphaHash ? "#define USE_ALPHAHASH" : "", n.sheen ? "#define USE_SHEEN" : "", n.sheenColorMap ? "#define USE_SHEEN_COLORMAP" : "", n.sheenRoughnessMap ? "#define USE_SHEEN_ROUGHNESSMAP" : "", n.transmission ? "#define USE_TRANSMISSION" : "", n.transmissionMap ? "#define USE_TRANSMISSIONMAP" : "", n.thicknessMap ? "#define USE_THICKNESSMAP" : "", n.vertexTangents && !1 === n.flatShading ? "#define USE_TANGENT" : "", n.vertexColors || n.instancingColor || n.batchingColor ? "#define USE_COLOR" : "", n.vertexAlphas ? "#define USE_COLOR_ALPHA" : "", n.vertexUv1s ? "#define USE_UV1" : "", n.vertexUv2s ? "#define USE_UV2" : "", n.vertexUv3s ? "#define USE_UV3" : "", n.pointsUvs ? "#define USE_POINTS_UV" : "", n.gradientMap ? "#define USE_GRADIENTMAP" : "", n.flatShading ? "#define FLAT_SHADED" : "", n.doubleSided ? "#define DOUBLE_SIDED" : "", n.flipSided ? "#define FLIP_SIDED" : "", n.shadowMapEnabled ? "#define USE_SHADOWMAP" : "", n.shadowMapEnabled ? "#define " + l : "", n.premultipliedAlpha ? "#define PREMULTIPLIED_ALPHA" : "", n.numLightProbes > 0 ? "#define USE_LIGHT_PROBES" : "", n.decodeVideoTexture ? "#define DECODE_VIDEO_TEXTURE" : "", n.decodeVideoTextureEmissive ? "#define DECODE_VIDEO_TEXTURE_EMISSIVE" : "", n.logarithmicDepthBuffer ? "#define USE_LOGDEPTHBUF" : "", n.reverseDepthBuffer ? "#define USE_REVERSEDEPTHBUF" : "", "uniform mat4 viewMatrix;", "uniform vec3 cameraPosition;", "uniform bool isOrthographic;", 0 !== n.toneMapping ? "#define TONE_MAPPING" : "", 0 !== n.toneMapping ? gc.tonemapping_pars_fragment : "", 0 !== n.toneMapping ? cd("toneMapping", n.toneMapping) : "", n.dithering ? "#define DITHERING" : "", n.opaque ? "#define OPAQUE" : "", gc.colorspace_pars_fragment, ld("linearToOutputTexel", n.outputColorSpace), dd(), n.useDepthPacking ? "#define DEPTH_PACKING " + n.depthPacking : "", "\n"].filter(ud).join("\n")), s = gd(s), s = pd(s, n), s = fd(s, n), o = gd(o), o = pd(o, n), o = fd(o, n), s = Ad(s), o = Ad(o), !0 !== n.isRawShaderMaterial && (w = "#version 300 es\n", g = [p, "#define attribute in", "#define varying out", "#define texture2D texture"].join("\n") + "\n" + g, v = ["#define varying in", n.glslVersion === Pt ? "" : "layout(location = 0) out highp vec4 pc_fragColor;", n.glslVersion === Pt ? "" : "#define gl_FragColor pc_fragColor", "#define gl_FragDepthEXT gl_FragDepth", "#define texture2D texture", "#define textureCube texture", "#define texture2DProj textureProj", "#define texture2DLodEXT textureLod", "#define texture2DProjLodEXT textureProjLod", "#define textureCubeLodEXT textureLod", "#define texture2DGradEXT textureGrad", "#define texture2DProjGradEXT textureProjGrad", "#define textureCubeGradEXT textureGrad"].join("\n") + "\n" + v); const y = w + g + s, A = w + v + o, b = rd(r, r.VERTEX_SHADER, y), x = rd(r, r.FRAGMENT_SHADER, A); function k(t) { if (e.debug.checkShaderErrors) { const n = r.getProgramInfoLog(m).trim(), i = r.getShaderInfoLog(b).trim(), a = r.getShaderInfoLog(x).trim(); let s = !0, o = !0; if (!1 === r.getProgramParameter(m, r.LINK_STATUS)) if (s = !1, "function" == typeof e.debug.onShaderError) e.debug.onShaderError(r, m, b, x); else { const e = od(r, b, "vertex"), i = od(r, x, "fragment"); console.error("THREE.WebGLProgram: Shader Error " + r.getError() + " - VALIDATE_STATUS " + r.getProgramParameter(m, r.VALIDATE_STATUS) + "\n\nMaterial Name: " + t.name + "\nMaterial Type: " + t.type + "\n\nProgram Info Log: " + n + "\n" + e + "\n" + i) } else "" !== n ? console.warn("THREE.WebGLProgram: Program Info Log:", n) : "" !== i && "" !== a || (o = !1); o && (t.diagnostics = { runnable: s, programLog: n, vertexShader: { log: i, prefix: g }, fragmentShader: { log: a, prefix: v } }) } r.deleteShader(b), r.deleteShader(x), E = new id(r, m), S = function(e, t) { const n = {}, i = e.getProgramParameter(t, e.ACTIVE_ATTRIBUTES); for (let r = 0; r < i; r++) { const i = e.getActiveAttrib(t, r), a = i.name; let s = 1; i.type === e.FLOAT_MAT2 && (s = 2), i.type === e.FLOAT_MAT3 && (s = 3), i.type === e.FLOAT_MAT4 && (s = 4), n[a] = { type: i.type, location: e.getAttribLocation(t, a), locationSize: s } } return n }(r, m) } let E, S; r.attachShader(m, b), r.attachShader(m, x), void 0 !== n.index0AttributeName ? r.bindAttribLocation(m, 0, n.index0AttributeName) : !0 === n.morphTargets && r.bindAttribLocation(m, 0, "position"), r.linkProgram(m), this.getUniforms = function() { return void 0 === E && k(this), E }, this.getAttributes = function() { return void 0 === S && k(this), S }; let M = !1 === n.rendererExtensionParallelShaderCompile; return this.isReady = function() { return !1 === M && (M = r.getProgramParameter(m, 37297)), M }, this.destroy = function() { i.releaseStatesOfProgram(this), r.deleteProgram(m), this.program = void 0 }, this.type = n.shaderType, this.name = n.shaderName, this.id = ad++, this.cacheKey = t, this.usedTimes = 1, this.program = m, this.vertexShader = b, this.fragmentShader = x, this } let Ed = 0; class Sd { constructor() { this.shaderCache = new Map, this.materialCache = new Map } update(e) { const t = e.vertexShader, n = e.fragmentShader, i = this._getShaderStage(t), r = this._getShaderStage(n), a = this._getShaderCacheForMaterial(e); return !1 === a.has(i) && (a.add(i), i.usedTimes++), !1 === a.has(r) && (a.add(r), r.usedTimes++), this } remove(e) { const t = this.materialCache.get(e); for (const e of t) e.usedTimes--, 0 === e.usedTimes && this.shaderCache.delete(e.code); return this.materialCache.delete(e), this } getVertexShaderID(e) { return this._getShaderStage(e.vertexShader).id } getFragmentShaderID(e) { return this._getShaderStage(e.fragmentShader).id } dispose() { this.shaderCache.clear(), this.materialCache.clear() } _getShaderCacheForMaterial(e) { const t = this.materialCache; let n = t.get(e); return void 0 === n && (n = new Set, t.set(e, n)), n } _getShaderStage(e) { const t = this.shaderCache; let n = t.get(e); return void 0 === n && (n = new Md(e), t.set(e, n)), n } } class Md { constructor(e) { this.id = Ed++, this.code = e, this.usedTimes = 0 } } function Td(e, t, n, i, r, a, s) { const o = new si, l = new Sd, c = new Set, h = [], d = r.logarithmicDepthBuffer, u = r.vertexTextures; let p = r.precision; const f = { MeshDepthMaterial: "depth", MeshDistanceMaterial: "distanceRGBA", MeshNormalMaterial: "normal", MeshBasicMaterial: "basic", MeshLambertMaterial: "lambert", MeshPhongMaterial: "phong", MeshToonMaterial: "toon", MeshStandardMaterial: "physical", MeshPhysicalMaterial: "physical", MeshMatcapMaterial: "matcap", LineBasicMaterial: "basic", LineDashedMaterial: "dashed", PointsMaterial: "points", ShadowMaterial: "shadow", SpriteMaterial: "sprite" }; function m(e) { return c.add(e), 0 === e ? "uv" : `uv${e}` } return { getParameters: function(a, o, h, g, v) { const w = g.fog, y = v.geometry, A = a.isMeshStandardMaterial ? g.environment : null, b = (a.isMeshStandardMaterial ? n : t).get(a.envMap || A), x = b && b.mapping === ie ? b.image.height : null, k = f[a.type]; null !== a.precision && (p = r.getMaxPrecision(a.precision), p !== a.precision && console.warn("THREE.WebGLProgram.getParameters:", a.precision, "not supported, using", p, "instead.")); const E = y.morphAttributes.position || y.morphAttributes.normal || y.morphAttributes.color, S = void 0 !== E ? E.length : 0; let M, T, _, C, P = 0; if (void 0 !== y.morphAttributes.position && (P = 1), void 0 !== y.morphAttributes.normal && (P = 2), void 0 !== y.morphAttributes.color && (P = 3), k) { const e = wc[k]; M = e.vertexShader, T = e.fragmentShader } else M = a.vertexShader, T = a.fragmentShader, l.update(a), _ = l.getVertexShaderID(a), C = l.getFragmentShaderID(a); const I = e.getRenderTarget(), R = e.state.buffers.depth.getReversed(), L = !0 === v.isInstancedMesh, D = !0 === v.isBatchedMesh, N = !!a.map, B = !!a.matcap, U = !!b, z = !!a.aoMap, O = !!a.lightMap, F = !!a.bumpMap, W = !!a.normalMap, V = !!a.displacementMap, H = !!a.emissiveMap, G = !!a.metalnessMap, j = !!a.roughnessMap, Q = a.anisotropy > 0, Y = a.clearcoat > 0, K = a.dispersion > 0, q = a.iridescence > 0, X = a.sheen > 0, Z = a.transmission > 0, J = Q && !!a.anisotropyMap, $ = Y && !!a.clearcoatMap, ee = Y && !!a.clearcoatNormalMap, te = Y && !!a.clearcoatRoughnessMap, ne = q && !!a.iridescenceMap, re = q && !!a.iridescenceThicknessMap, ae = X && !!a.sheenColorMap, se = X && !!a.sheenRoughnessMap, oe = !!a.specularMap, le = !!a.specularColorMap, ce = !!a.specularIntensityMap, he = Z && !!a.transmissionMap, de = Z && !!a.thicknessMap, ue = !!a.gradientMap, pe = !!a.alphaMap, fe = a.alphaTest > 0, me = !!a.alphaHash, ge = !!a.extensions; let ve = 0; a.toneMapped && (null !== I && !0 !== I.isXRRenderTarget || (ve = e.toneMapping)); const we = { shaderID: k, shaderType: a.type, shaderName: a.name, vertexShader: M, fragmentShader: T, defines: a.defines, customVertexShaderID: _, customFragmentShaderID: C, isRawShaderMaterial: !0 === a.isRawShaderMaterial, glslVersion: a.glslVersion, precision: p, batching: D, batchingColor: D && null !== v._colorsTexture, instancing: L, instancingColor: L && null !== v.instanceColor, instancingMorph: L && null !== v.morphTexture, supportsVertexTextures: u, outputColorSpace: null === I ? e.outputColorSpace : !0 === I.isXRRenderTarget ? I.texture.colorSpace : vt, alphaToCoverage: !!a.alphaToCoverage, map: N, matcap: B, envMap: U, envMapMode: U && b.mapping, envMapCubeUVHeight: x, aoMap: z, lightMap: O, bumpMap: F, normalMap: W, displacementMap: u && V, emissiveMap: H, normalMapObjectSpace: W && 1 === a.normalMapType, normalMapTangentSpace: W && 0 === a.normalMapType, metalnessMap: G, roughnessMap: j, anisotropy: Q, anisotropyMap: J, clearcoat: Y, clearcoatMap: $, clearcoatNormalMap: ee, clearcoatRoughnessMap: te, dispersion: K, iridescence: q, iridescenceMap: ne, iridescenceThicknessMap: re, sheen: X, sheenColorMap: ae, sheenRoughnessMap: se, specularMap: oe, specularColorMap: le, specularIntensityMap: ce, transmission: Z, transmissionMap: he, thicknessMap: de, gradientMap: ue, opaque: !1 === a.transparent && 1 === a.blending && !1 === a.alphaToCoverage, alphaMap: pe, alphaTest: fe, alphaHash: me, combine: a.combine, mapUv: N && m(a.map.channel), aoMapUv: z && m(a.aoMap.channel), lightMapUv: O && m(a.lightMap.channel), bumpMapUv: F && m(a.bumpMap.channel), normalMapUv: W && m(a.normalMap.channel), displacementMapUv: V && m(a.displacementMap.channel), emissiveMapUv: H && m(a.emissiveMap.channel), metalnessMapUv: G && m(a.metalnessMap.channel), roughnessMapUv: j && m(a.roughnessMap.channel), anisotropyMapUv: J && m(a.anisotropyMap.channel), clearcoatMapUv: $ && m(a.clearcoatMap.channel), clearcoatNormalMapUv: ee && m(a.clearcoatNormalMap.channel), clearcoatRoughnessMapUv: te && m(a.clearcoatRoughnessMap.channel), iridescenceMapUv: ne && m(a.iridescenceMap.channel), iridescenceThicknessMapUv: re && m(a.iridescenceThicknessMap.channel), sheenColorMapUv: ae && m(a.sheenColorMap.channel), sheenRoughnessMapUv: se && m(a.sheenRoughnessMap.channel), specularMapUv: oe && m(a.specularMap.channel), specularColorMapUv: le && m(a.specularColorMap.channel), specularIntensityMapUv: ce && m(a.specularIntensityMap.channel), transmissionMapUv: he && m(a.transmissionMap.channel), thicknessMapUv: de && m(a.thicknessMap.channel), alphaMapUv: pe && m(a.alphaMap.channel), vertexTangents: !!y.attributes.tangent && (W || Q), vertexColors: a.vertexColors, vertexAlphas: !0 === a.vertexColors && !!y.attributes.color && 4 === y.attributes.color.itemSize, pointsUvs: !0 === v.isPoints && !!y.attributes.uv && (N || pe), fog: !!w, useFog: !0 === a.fog, fogExp2: !!w && w.isFogExp2, flatShading: !0 === a.flatShading, sizeAttenuation: !0 === a.sizeAttenuation, logarithmicDepthBuffer: d, reverseDepthBuffer: R, skinning: !0 === v.isSkinnedMesh, morphTargets: void 0 !== y.morphAttributes.position, morphNormals: void 0 !== y.morphAttributes.normal, morphColors: void 0 !== y.morphAttributes.color, morphTargetsCount: S, morphTextureStride: P, numDirLights: o.directional.length, numPointLights: o.point.length, numSpotLights: o.spot.length, numSpotLightMaps: o.spotLightMap.length, numRectAreaLights: o.rectArea.length, numHemiLights: o.hemi.length, numDirLightShadows: o.directionalShadowMap.length, numPointLightShadows: o.pointShadowMap.length, numSpotLightShadows: o.spotShadowMap.length, numSpotLightShadowsWithMaps: o.numSpotLightShadowsWithMaps, numLightProbes: o.numLightProbes, numClippingPlanes: s.numPlanes, numClipIntersection: s.numIntersection, dithering: a.dithering, shadowMapEnabled: e.shadowMap.enabled && h.length > 0, shadowMapType: e.shadowMap.type, toneMapping: ve, decodeVideoTexture: N && !0 === a.map.isVideoTexture && nn.getTransfer(a.map.colorSpace) === yt, decodeVideoTextureEmissive: H && !0 === a.emissiveMap.isVideoTexture && nn.getTransfer(a.emissiveMap.colorSpace) === yt, premultipliedAlpha: a.premultipliedAlpha, doubleSided: 2 === a.side, flipSided: 1 === a.side, useDepthPacking: a.depthPacking >= 0, depthPacking: a.depthPacking || 0, index0AttributeName: a.index0AttributeName, extensionClipCullDistance: ge && !0 === a.extensions.clipCullDistance && i.has("WEBGL_clip_cull_distance"), extensionMultiDraw: (ge && !0 === a.extensions.multiDraw || D) && i.has("WEBGL_multi_draw"), rendererExtensionParallelShaderCompile: i.has("KHR_parallel_shader_compile"), customProgramCacheKey: a.customProgramCacheKey() }; return we.vertexUv1s = c.has(1), we.vertexUv2s = c.has(2), we.vertexUv3s = c.has(3), c.clear(), we }, getProgramCacheKey: function(t) { const n = []; if (t.shaderID ? n.push(t.shaderID) : (n.push(t.customVertexShaderID), n.push(t.customFragmentShaderID)), void 0 !== t.defines) for (const e in t.defines) n.push(e), n.push(t.defines[e]); return !1 === t.isRawShaderMaterial && (! function(e, t) { e.push(t.precision), e.push(t.outputColorSpace), e.push(t.envMapMode), e.push(t.envMapCubeUVHeight), e.push(t.mapUv), e.push(t.alphaMapUv), e.push(t.lightMapUv), e.push(t.aoMapUv), e.push(t.bumpMapUv), e.push(t.normalMapUv), e.push(t.displacementMapUv), e.push(t.emissiveMapUv), e.push(t.metalnessMapUv), e.push(t.roughnessMapUv), e.push(t.anisotropyMapUv), e.push(t.clearcoatMapUv), e.push(t.clearcoatNormalMapUv), e.push(t.clearcoatRoughnessMapUv), e.push(t.iridescenceMapUv), e.push(t.iridescenceThicknessMapUv), e.push(t.sheenColorMapUv), e.push(t.sheenRoughnessMapUv), e.push(t.specularMapUv), e.push(t.specularColorMapUv), e.push(t.specularIntensityMapUv), e.push(t.transmissionMapUv), e.push(t.thicknessMapUv), e.push(t.combine), e.push(t.fogExp2), e.push(t.sizeAttenuation), e.push(t.morphTargetsCount), e.push(t.morphAttributeCount), e.push(t.numDirLights), e.push(t.numPointLights), e.push(t.numSpotLights), e.push(t.numSpotLightMaps), e.push(t.numHemiLights), e.push(t.numRectAreaLights), e.push(t.numDirLightShadows), e.push(t.numPointLightShadows), e.push(t.numSpotLightShadows), e.push(t.numSpotLightShadowsWithMaps), e.push(t.numLightProbes), e.push(t.shadowMapType), e.push(t.toneMapping), e.push(t.numClippingPlanes), e.push(t.numClipIntersection), e.push(t.depthPacking) }(n, t), function(e, t) { o.disableAll(), t.supportsVertexTextures && o.enable(0); t.instancing && o.enable(1); t.instancingColor && o.enable(2); t.instancingMorph && o.enable(3); t.matcap && o.enable(4); t.envMap && o.enable(5); t.normalMapObjectSpace && o.enable(6); t.normalMapTangentSpace && o.enable(7); t.clearcoat && o.enable(8); t.iridescence && o.enable(9); t.alphaTest && o.enable(10); t.vertexColors && o.enable(11); t.vertexAlphas && o.enable(12); t.vertexUv1s && o.enable(13); t.vertexUv2s && o.enable(14); t.vertexUv3s && o.enable(15); t.vertexTangents && o.enable(16); t.anisotropy && o.enable(17); t.alphaHash && o.enable(18); t.batching && o.enable(19); t.dispersion && o.enable(20); t.batchingColor && o.enable(21); e.push(o.mask), o.disableAll(), t.fog && o.enable(0); t.useFog && o.enable(1); t.flatShading && o.enable(2); t.logarithmicDepthBuffer && o.enable(3); t.reverseDepthBuffer && o.enable(4); t.skinning && o.enable(5); t.morphTargets && o.enable(6); t.morphNormals && o.enable(7); t.morphColors && o.enable(8); t.premultipliedAlpha && o.enable(9); t.shadowMapEnabled && o.enable(10); t.doubleSided && o.enable(11); t.flipSided && o.enable(12); t.useDepthPacking && o.enable(13); t.dithering && o.enable(14); t.transmission && o.enable(15); t.sheen && o.enable(16); t.opaque && o.enable(17); t.pointsUvs && o.enable(18); t.decodeVideoTexture && o.enable(19); t.decodeVideoTextureEmissive && o.enable(20); t.alphaToCoverage && o.enable(21); e.push(o.mask) }(n, t), n.push(e.outputColorSpace)), n.push(t.customProgramCacheKey), n.join() }, getUniforms: function(e) { const t = f[e.type]; let n; if (t) { const e = wc[t]; n = Er.clone(e.uniforms) } else n = e.uniforms; return n }, acquireProgram: function(t, n) { let i; for (let e = 0, t = h.length; e < t; e++) { const t = h[e]; if (t.cacheKey === n) { i = t, ++i.usedTimes; break } } return void 0 === i && (i = new kd(e, n, t, a), h.push(i)), i }, releaseProgram: function(e) { if (0 == --e.usedTimes) { const t = h.indexOf(e); h[t] = h[h.length - 1], h.pop(), e.destroy() } }, releaseShaderCache: function(e) { l.remove(e) }, programs: h, dispose: function() { l.dispose() } } } function _d() { let e = new WeakMap; return { has: function(t) { return e.has(t) }, get: function(t) { let n = e.get(t); return void 0 === n && (n = {}, e.set(t, n)), n }, remove: function(t) { e.delete(t) }, update: function(t, n, i) { e.get(t)[n] = i }, dispose: function() { e = new WeakMap } } } function Cd(e, t) { return e.groupOrder !== t.groupOrder ? e.groupOrder - t.groupOrder : e.renderOrder !== t.renderOrder ? e.renderOrder - t.renderOrder : e.material.id !== t.material.id ? e.material.id - t.material.id : e.z !== t.z ? e.z - t.z : e.id - t.id } function Pd(e, t) { return e.groupOrder !== t.groupOrder ? e.groupOrder - t.groupOrder : e.renderOrder !== t.renderOrder ? e.renderOrder - t.renderOrder : e.z !== t.z ? t.z - e.z : e.id - t.id } function Id() { const e = []; let t = 0; const n = [], i = [], r = []; function a(n, i, r, a, s, o) { let l = e[t]; return void 0 === l ? (l = { id: n.id, object: n, geometry: i, material: r, groupOrder: a, renderOrder: n.renderOrder, z: s, group: o }, e[t] = l) : (l.id = n.id, l.object = n, l.geometry = i, l.material = r, l.groupOrder = a, l.renderOrder = n.renderOrder, l.z = s, l.group = o), t++, l } return { opaque: n, transmissive: i, transparent: r, init: function() { t = 0, n.length = 0, i.length = 0, r.length = 0 }, push: function(e, t, s, o, l, c) { const h = a(e, t, s, o, l, c); s.transmission > 0 ? i.push(h) : !0 === s.transparent ? r.push(h) : n.push(h) }, unshift: function(e, t, s, o, l, c) { const h = a(e, t, s, o, l, c); s.transmission > 0 ? i.unshift(h) : !0 === s.transparent ? r.unshift(h) : n.unshift(h) }, finish: function() { for (let n = t, i = e.length; n < i; n++) { const t = e[n]; if (null === t.id) break; t.id = null, t.object = null, t.geometry = null, t.material = null, t.group = null } }, sort: function(e, t) { n.length > 1 && n.sort(e || Cd), i.length > 1 && i.sort(t || Pd), r.length > 1 && r.sort(t || Pd) } } } function Rd() { let e = new WeakMap; return { get: function(t, n) { const i = e.get(t); let r; return void 0 === i ? (r = new Id, e.set(t, [r])) : n >= i.length ? (r = new Id, i.push(r)) : r = i[n], r }, dispose: function() { e = new WeakMap } } } function Ld() { const e = {}; return { get: function(t) { if (void 0 !== e[t.id]) return e[t.id]; let n; switch (t.type) { case "DirectionalLight": n = { direction: new yn, color: new Wi }; break; case "SpotLight": n = { position: new yn, direction: new yn, color: new Wi, distance: 0, coneCos: 0, penumbraCos: 0, decay: 0 }; break; case "PointLight": n = { position: new yn, color: new Wi, distance: 0, decay: 0 }; break; case "HemisphereLight": n = { direction: new yn, skyColor: new Wi, groundColor: new Wi }; break; case "RectAreaLight": n = { color: new Wi, position: new yn, halfWidth: new yn, halfHeight: new yn } } return e[t.id] = n, n } } } let Dd = 0; function Nd(e, t) { return (t.castShadow ? 2 : 0) - (e.castShadow ? 2 : 0) + (t.map ? 1 : 0) - (e.map ? 1 : 0) } function Bd(e) { const t = new Ld, n = function() { const e = {}; return { get: function(t) { if (void 0 !== e[t.id]) return e[t.id]; let n; switch (t.type) { case "DirectionalLight": case "SpotLight": n = { shadowIntensity: 1, shadowBias: 0, shadowNormalBias: 0, shadowRadius: 1, shadowMapSize: new jt }; break; case "PointLight": n = { shadowIntensity: 1, shadowBias: 0, shadowNormalBias: 0, shadowRadius: 1, shadowMapSize: new jt, shadowCameraNear: 1, shadowCameraFar: 1e3 } } return e[t.id] = n, n } } }(), i = { version: 0, hash: { directionalLength: -1, pointLength: -1, spotLength: -1, rectAreaLength: -1, hemiLength: -1, numDirectionalShadows: -1, numPointShadows: -1, numSpotShadows: -1, numSpotMaps: -1, numLightProbes: -1 }, ambient: [0, 0, 0], probe: [], directional: [], directionalShadow: [], directionalShadowMap: [], directionalShadowMatrix: [], spot: [], spotLightMap: [], spotShadow: [], spotShadowMap: [], spotLightMatrix: [], rectArea: [], rectAreaLTC1: null, rectAreaLTC2: null, point: [], pointShadow: [], pointShadowMap: [], pointShadowMatrix: [], hemi: [], numSpotLightShadowsWithMaps: 0, numLightProbes: 0 }; for (let e = 0; e < 9; e++) i.probe.push(new yn); const r = new yn, a = new qn, s = new qn; return { setup: function(r) { let a = 0, s = 0, o = 0; for (let e = 0; e < 9; e++) i.probe[e].set(0, 0, 0); let l = 0, c = 0, h = 0, d = 0, u = 0, p = 0, f = 0, m = 0, g = 0, v = 0, w = 0; r.sort(Nd); for (let e = 0, y = r.length; e < y; e++) { const y = r[e], A = y.color, b = y.intensity, x = y.distance, k = y.shadow && y.shadow.map ? y.shadow.map.texture : null; if (y.isAmbientLight) a += A.r * b, s += A.g * b, o += A.b * b; else if (y.isLightProbe) { for (let e = 0; e < 9; e++) i.probe[e].addScaledVector(y.sh.coefficients[e], b); w++ } else if (y.isDirectionalLight) { const e = t.get(y); if (e.color.copy(y.color).multiplyScalar(y.intensity), y.castShadow) { const e = y.shadow, t = n.get(y); t.shadowIntensity = e.intensity, t.shadowBias = e.bias, t.shadowNormalBias = e.normalBias, t.shadowRadius = e.radius, t.shadowMapSize = e.mapSize, i.directionalShadow[l] = t, i.directionalShadowMap[l] = k, i.directionalShadowMatrix[l] = y.shadow.matrix, p++ } i.directional[l] = e, l++ } else if (y.isSpotLight) { const e = t.get(y); e.position.setFromMatrixPosition(y.matrixWorld), e.color.copy(A).multiplyScalar(b), e.distance = x, e.coneCos = Math.cos(y.angle), e.penumbraCos = Math.cos(y.angle * (1 - y.penumbra)), e.decay = y.decay, i.spot[h] = e; const r = y.shadow; if (y.map && (i.spotLightMap[g] = y.map, g++, r.updateMatrices(y), y.castShadow && v++), i.spotLightMatrix[h] = r.matrix, y.castShadow) { const e = n.get(y); e.shadowIntensity = r.intensity, e.shadowBias = r.bias, e.shadowNormalBias = r.normalBias, e.shadowRadius = r.radius, e.shadowMapSize = r.mapSize, i.spotShadow[h] = e, i.spotShadowMap[h] = k, m++ } h++ } else if (y.isRectAreaLight) { const e = t.get(y); e.color.copy(A).multiplyScalar(b), e.halfWidth.set(.5 * y.width, 0, 0), e.halfHeight.set(0, .5 * y.height, 0), i.rectArea[d] = e, d++ } else if (y.isPointLight) { const e = t.get(y); if (e.color.copy(y.color).multiplyScalar(y.intensity), e.distance = y.distance, e.decay = y.decay, y.castShadow) { const e = y.shadow, t = n.get(y); t.shadowIntensity = e.intensity, t.shadowBias = e.bias, t.shadowNormalBias = e.normalBias, t.shadowRadius = e.radius, t.shadowMapSize = e.mapSize, t.shadowCameraNear = e.camera.near, t.shadowCameraFar = e.camera.far, i.pointShadow[c] = t, i.pointShadowMap[c] = k, i.pointShadowMatrix[c] = y.shadow.matrix, f++ } i.point[c] = e, c++ } else if (y.isHemisphereLight) { const e = t.get(y); e.skyColor.copy(y.color).multiplyScalar(b), e.groundColor.copy(y.groundColor).multiplyScalar(b), i.hemi[u] = e, u++ } } d > 0 && (!0 === e.has("OES_texture_float_linear") ? (i.rectAreaLTC1 = vc.LTC_FLOAT_1, i.rectAreaLTC2 = vc.LTC_FLOAT_2) : (i.rectAreaLTC1 = vc.LTC_HALF_1, i.rectAreaLTC2 = vc.LTC_HALF_2)), i.ambient[0] = a, i.ambient[1] = s, i.ambient[2] = o; const y = i.hash; y.directionalLength === l && y.pointLength === c && y.spotLength === h && y.rectAreaLength === d && y.hemiLength === u && y.numDirectionalShadows === p && y.numPointShadows === f && y.numSpotShadows === m && y.numSpotMaps === g && y.numLightProbes === w || (i.directional.length = l, i.spot.length = h, i.rectArea.length = d, i.point.length = c, i.hemi.length = u, i.directionalShadow.length = p, i.directionalShadowMap.length = p, i.pointShadow.length = f, i.pointShadowMap.length = f, i.spotShadow.length = m, i.spotShadowMap.length = m, i.directionalShadowMatrix.length = p, i.pointShadowMatrix.length = f, i.spotLightMatrix.length = m + g - v, i.spotLightMap.length = g, i.numSpotLightShadowsWithMaps = v, i.numLightProbes = w, y.directionalLength = l, y.pointLength = c, y.spotLength = h, y.rectAreaLength = d, y.hemiLength = u, y.numDirectionalShadows = p, y.numPointShadows = f, y.numSpotShadows = m, y.numSpotMaps = g, y.numLightProbes = w, i.version = Dd++) }, setupView: function(e, t) { let n = 0, o = 0, l = 0, c = 0, h = 0; const d = t.matrixWorldInverse; for (let t = 0, u = e.length; t < u; t++) { const u = e[t]; if (u.isDirectionalLight) { const e = i.directional[n]; e.direction.setFromMatrixPosition(u.matrixWorld), r.setFromMatrixPosition(u.target.matrixWorld), e.direction.sub(r), e.direction.transformDirection(d), n++ } else if (u.isSpotLight) { const e = i.spot[l]; e.position.setFromMatrixPosition(u.matrixWorld), e.position.applyMatrix4(d), e.direction.setFromMatrixPosition(u.matrixWorld), r.setFromMatrixPosition(u.target.matrixWorld), e.direction.sub(r), e.direction.transformDirection(d), l++ } else if (u.isRectAreaLight) { const e = i.rectArea[c]; e.position.setFromMatrixPosition(u.matrixWorld), e.position.applyMatrix4(d), s.identity(), a.copy(u.matrixWorld), a.premultiply(d), s.extractRotation(a), e.halfWidth.set(.5 * u.width, 0, 0), e.halfHeight.set(0, .5 * u.height, 0), e.halfWidth.applyMatrix4(s), e.halfHeight.applyMatrix4(s), c++ } else if (u.isPointLight) { const e = i.point[o]; e.position.setFromMatrixPosition(u.matrixWorld), e.position.applyMatrix4(d), o++ } else if (u.isHemisphereLight) { const e = i.hemi[h]; e.direction.setFromMatrixPosition(u.matrixWorld), e.direction.transformDirection(d), h++ } } }, state: i } } function Ud(e) { const t = new Bd(e), n = [], i = []; const r = { lightsArray: n, shadowsArray: i, camera: null, lights: t, transmissionRenderTarget: {} }; return { init: function(e) { r.camera = e, n.length = 0, i.length = 0 }, state: r, setupLights: function() { t.setup(n) }, setupLightsView: function(e) { t.setupView(n, e) }, pushLight: function(e) { n.push(e) }, pushShadow: function(e) { i.push(e) } } } function zd(e) { let t = new WeakMap; return { get: function(n, i = 0) { const r = t.get(n); let a; return void 0 === r ? (a = new Ud(e), t.set(n, [a])) : i >= r.length ? (a = new Ud(e), r.push(a)) : a = r[i], a }, dispose: function() { t = new WeakMap } } } function Od(e, t, n) { let i = new ya; const r = new jt, a = new jt, s = new pn, o = new Ws({ depthPacking: 3201 }), l = new Vs, c = {}, h = n.maxTextureSize, d = { [k]: 1, [E]: 0, [S]: 2 }, u = new Sr({ defines: { VSM_SAMPLES: 8 }, uniforms: { shadow_pass: { value: null }, resolution: { value: new jt }, radius: { value: 4 } }, vertexShader: "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}", fragmentShader: "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include \nvoid main() {\n\tconst float samples = float( VSM_SAMPLES );\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n\tfor ( float i = 0.0; i < samples; i ++ ) {\n\t\tfloat uvOffset = uvStart + i * uvStride;\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ) );\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean / samples;\n\tsquared_mean = squared_mean / samples;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}" }), p = u.clone(); p.defines.HORIZONTAL_PASS = 1; const f = new sr; f.setAttribute("position", new qi(new Float32Array([-1, -1, .5, 3, -1, .5, -1, 3, .5]), 3)); const m = new wr(f, u), g = this; this.enabled = !1, this.autoUpdate = !0, this.needsUpdate = !1, this.type = 1; let v = this.type; function w(n, i) { const a = t.update(m); u.defines.VSM_SAMPLES !== n.blurSamples && (u.defines.VSM_SAMPLES = n.blurSamples, p.defines.VSM_SAMPLES = n.blurSamples, u.needsUpdate = !0, p.needsUpdate = !0), null === n.mapPass && (n.mapPass = new mn(r.x, r.y)), u.uniforms.shadow_pass.value = n.map.texture, u.uniforms.resolution.value = n.mapSize, u.uniforms.radius.value = n.radius, e.setRenderTarget(n.mapPass), e.clear(), e.renderBufferDirect(i, null, a, u, m, null), p.uniforms.shadow_pass.value = n.mapPass.texture, p.uniforms.resolution.value = n.mapSize, p.uniforms.radius.value = n.radius, e.setRenderTarget(n.map), e.clear(), e.renderBufferDirect(i, null, a, p, m, null) } function y(t, n, i, r) { let a = null; const s = !0 === i.isPointLight ? t.customDistanceMaterial : t.customDepthMaterial; if (void 0 !== s) a = s; else if (a = !0 === i.isPointLight ? l : o, e.localClippingEnabled && !0 === n.clipShadows && Array.isArray(n.clippingPlanes) && 0 !== n.clippingPlanes.length || n.displacementMap && 0 !== n.displacementScale || n.alphaMap && n.alphaTest > 0 || n.map && n.alphaTest > 0) { const e = a.uuid, t = n.uuid; let i = c[e]; void 0 === i && (i = {}, c[e] = i); let r = i[t]; void 0 === r && (r = a.clone(), i[t] = r, n.addEventListener("dispose", b)), a = r } if (a.visible = n.visible, a.wireframe = n.wireframe, a.side = 3 === r ? null !== n.shadowSide ? n.shadowSide : n.side : null !== n.shadowSide ? n.shadowSide : d[n.side], a.alphaMap = n.alphaMap, a.alphaTest = n.alphaTest, a.map = n.map, a.clipShadows = n.clipShadows, a.clippingPlanes = n.clippingPlanes, a.clipIntersection = n.clipIntersection, a.displacementMap = n.displacementMap, a.displacementScale = n.displacementScale, a.displacementBias = n.displacementBias, a.wireframeLinewidth = n.wireframeLinewidth, a.linewidth = n.linewidth, !0 === i.isPointLight && !0 === a.isMeshDistanceMaterial) { e.properties.get(a).light = i } return a } function A(n, r, a, s, o) { if (!1 === n.visible) return; if (n.layers.test(r.layers) && (n.isMesh || n.isLine || n.isPoints) && (n.castShadow || n.receiveShadow && 3 === o) && (!n.frustumCulled || i.intersectsObject(n))) { n.modelViewMatrix.multiplyMatrices(a.matrixWorldInverse, n.matrixWorld); const i = t.update(n), l = n.material; if (Array.isArray(l)) { const t = i.groups; for (let c = 0, h = t.length; c < h; c++) { const h = t[c], d = l[h.materialIndex]; if (d && d.visible) { const t = y(n, d, s, o); n.onBeforeShadow(e, n, r, a, i, t, h), e.renderBufferDirect(a, null, i, t, n, h), n.onAfterShadow(e, n, r, a, i, t, h) } } } else if (l.visible) { const t = y(n, l, s, o); n.onBeforeShadow(e, n, r, a, i, t, null), e.renderBufferDirect(a, null, i, t, n, null), n.onAfterShadow(e, n, r, a, i, t, null) } } const l = n.children; for (let e = 0, t = l.length; e < t; e++) A(l[e], r, a, s, o) } function b(e) { e.target.removeEventListener("dispose", b); for (const t in c) { const n = c[t], i = e.target.uuid; if (i in n) { n[i].dispose(), delete n[i] } } } this.render = function(t, n, o) { if (!1 === g.enabled) return; if (!1 === g.autoUpdate && !1 === g.needsUpdate) return; if (0 === t.length) return; const l = e.getRenderTarget(), c = e.getActiveCubeFace(), d = e.getActiveMipmapLevel(), u = e.state; u.setBlending(0), u.buffers.color.setClear(1, 1, 1, 1), u.buffers.depth.setTest(!0), u.setScissorTest(!1); const p = 3 !== v && 3 === this.type, f = 3 === v && 3 !== this.type; for (let l = 0, c = t.length; l < c; l++) { const c = t[l], d = c.shadow; if (void 0 === d) { console.warn("THREE.WebGLShadowMap:", c, "has no shadow."); continue } if (!1 === d.autoUpdate && !1 === d.needsUpdate) continue; r.copy(d.mapSize); const m = d.getFrameExtents(); if (r.multiply(m), a.copy(d.mapSize), (r.x > h || r.y > h) && (r.x > h && (a.x = Math.floor(h / m.x), r.x = a.x * m.x, d.mapSize.x = a.x), r.y > h && (a.y = Math.floor(h / m.y), r.y = a.y * m.y, d.mapSize.y = a.y)), null === d.map || !0 === p || !0 === f) { const e = 3 !== this.type ? { minFilter: oe, magFilter: oe } : {}; null !== d.map && d.map.dispose(), d.map = new mn(r.x, r.y, e), d.map.texture.name = c.name + ".shadowMap", d.camera.updateProjectionMatrix() } e.setRenderTarget(d.map), e.clear(); const g = d.getViewportCount(); for (let e = 0; e < g; e++) { const t = d.getViewport(e); s.set(a.x * t.x, a.y * t.y, a.x * t.z, a.y * t.w), u.viewport(s), d.updateMatrices(c, e), i = d.getFrustum(), A(n, o, d.camera, c, this.type) }!0 !== d.isPointLightShadow && 3 === this.type && w(d, o), d.needsUpdate = !1 } v = this.type, g.needsUpdate = !1, e.setRenderTarget(l, c, d) } } const Fd = { [G]: 1, [Q]: 6, [K]: 7, [Y]: 5, [j]: 0, [X]: 2, [Z]: 4, [q]: 3 }; function Wd(e, t) { const n = new function() { let t = !1; const n = new pn; let i = null; const r = new pn(0, 0, 0, 0); return { setMask: function(n) { i === n || t || (e.colorMask(n, n, n, n), i = n) }, setLocked: function(e) { t = e }, setClear: function(t, i, a, s, o) { !0 === o && (t *= s, i *= s, a *= s), n.set(t, i, a, s), !1 === r.equals(n) && (e.clearColor(t, i, a, s), r.copy(n)) }, reset: function() { t = !1, i = null, r.set(-1, 0, 0, 0) } } }, i = new function() { let n = !1, i = !1, r = null, a = null, s = null; return { setReversed: function(e) { if (i !== e) { const e = t.get("EXT_clip_control"); i ? e.clipControlEXT(e.LOWER_LEFT_EXT, e.ZERO_TO_ONE_EXT) : e.clipControlEXT(e.LOWER_LEFT_EXT, e.NEGATIVE_ONE_TO_ONE_EXT); const n = s; s = null, this.setClear(n) } i = e }, getReversed: function() { return i }, setTest: function(t) { t ? re(e.DEPTH_TEST) : ae(e.DEPTH_TEST) }, setMask: function(t) { r === t || n || (e.depthMask(t), r = t) }, setFunc: function(t) { if (i && (t = Fd[t]), a !== t) { switch (t) { case 0: e.depthFunc(e.NEVER); break; case 1: e.depthFunc(e.ALWAYS); break; case 2: e.depthFunc(e.LESS); break; case 3: default: e.depthFunc(e.LEQUAL); break; case 4: e.depthFunc(e.EQUAL); break; case 5: e.depthFunc(e.GEQUAL); break; case 6: e.depthFunc(e.GREATER); break; case 7: e.depthFunc(e.NOTEQUAL) } a = t } }, setLocked: function(e) { n = e }, setClear: function(t) { s !== t && (i && (t = 1 - t), e.clearDepth(t), s = t) }, reset: function() { n = !1, r = null, a = null, s = null, i = !1 } } }, r = new function() { let t = !1, n = null, i = null, r = null, a = null, s = null, o = null, l = null, c = null; return { setTest: function(n) { t || (n ? re(e.STENCIL_TEST) : ae(e.STENCIL_TEST)) }, setMask: function(i) { n === i || t || (e.stencilMask(i), n = i) }, setFunc: function(t, n, s) { i === t && r === n && a === s || (e.stencilFunc(t, n, s), i = t, r = n, a = s) }, setOp: function(t, n, i) { s === t && o === n && l === i || (e.stencilOp(t, n, i), s = t, o = n, l = i) }, setLocked: function(e) { t = e }, setClear: function(t) { c !== t && (e.clearStencil(t), c = t) }, reset: function() { t = !1, n = null, i = null, r = null, a = null, s = null, o = null, l = null, c = null } } }, a = new WeakMap, s = new WeakMap; let o = {}, l = {}, c = new WeakMap, h = [], d = null, u = !1, p = null, f = null, m = null, g = null, v = null, w = null, y = null, A = new Wi(0, 0, 0), b = 0, x = !1, k = null, E = null, S = null, G = null, j = null; const Q = e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS); let Y = !1, K = 0; const q = e.getParameter(e.VERSION); - 1 !== q.indexOf("WebGL") ? (K = parseFloat(/^WebGL (\d)/.exec(q)[1]), Y = K >= 1) : -1 !== q.indexOf("OpenGL ES") && (K = parseFloat(/^OpenGL ES (\d)/.exec(q)[1]), Y = K >= 2); let X = null, Z = {}; const J = e.getParameter(e.SCISSOR_BOX), $ = e.getParameter(e.VIEWPORT), ee = (new pn).fromArray(J), te = (new pn).fromArray($); function ne(t, n, i, r) { const a = new Uint8Array(4), s = e.createTexture(); e.bindTexture(t, s), e.texParameteri(t, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(t, e.TEXTURE_MAG_FILTER, e.NEAREST); for (let s = 0; s < i; s++) t === e.TEXTURE_3D || t === e.TEXTURE_2D_ARRAY ? e.texImage3D(n, 0, e.RGBA, 1, 1, r, 0, e.RGBA, e.UNSIGNED_BYTE, a) : e.texImage2D(n + s, 0, e.RGBA, 1, 1, 0, e.RGBA, e.UNSIGNED_BYTE, a); return s } const ie = {}; function re(t) { !0 !== o[t] && (e.enable(t), o[t] = !0) } function ae(t) { !1 !== o[t] && (e.disable(t), o[t] = !1) } ie[e.TEXTURE_2D] = ne(e.TEXTURE_2D, e.TEXTURE_2D, 1), ie[e.TEXTURE_CUBE_MAP] = ne(e.TEXTURE_CUBE_MAP, e.TEXTURE_CUBE_MAP_POSITIVE_X, 6), ie[e.TEXTURE_2D_ARRAY] = ne(e.TEXTURE_2D_ARRAY, e.TEXTURE_2D_ARRAY, 1, 1), ie[e.TEXTURE_3D] = ne(e.TEXTURE_3D, e.TEXTURE_3D, 1, 1), n.setClear(0, 0, 0, 1), i.setClear(1), r.setClear(0), re(e.DEPTH_TEST), i.setFunc(3), ce(!1), he(1), re(e.CULL_FACE), le(0); const se = { [M]: e.FUNC_ADD, [T]: e.FUNC_SUBTRACT, [_]: e.FUNC_REVERSE_SUBTRACT }; se[103] = e.MIN, se[104] = e.MAX; const oe = { [C]: e.ZERO, [P]: e.ONE, [I]: e.SRC_COLOR, [L]: e.SRC_ALPHA, [O]: e.SRC_ALPHA_SATURATE, [U]: e.DST_COLOR, [N]: e.DST_ALPHA, [R]: e.ONE_MINUS_SRC_COLOR, [D]: e.ONE_MINUS_SRC_ALPHA, [z]: e.ONE_MINUS_DST_COLOR, [B]: e.ONE_MINUS_DST_ALPHA, [F]: e.CONSTANT_COLOR, [W]: e.ONE_MINUS_CONSTANT_COLOR, [V]: e.CONSTANT_ALPHA, [H]: e.ONE_MINUS_CONSTANT_ALPHA }; function le(t, n, i, r, a, s, o, l, c, h) { if (0 !== t) { if (!1 === u && (re(e.BLEND), u = !0), 5 === t) a = a || n, s = s || i, o = o || r, n === f && a === v || (e.blendEquationSeparate(se[n], se[a]), f = n, v = a), i === m && r === g && s === w && o === y || (e.blendFuncSeparate(oe[i], oe[r], oe[s], oe[o]), m = i, g = r, w = s, y = o), !1 !== l.equals(A) && c === b || (e.blendColor(l.r, l.g, l.b, c), A.copy(l), b = c), p = t, x = !1; else if (t !== p || h !== x) { if (f === M && v === M || (e.blendEquation(e.FUNC_ADD), f = M, v = M), h) switch (t) { case 1: e.blendFuncSeparate(e.ONE, e.ONE_MINUS_SRC_ALPHA, e.ONE, e.ONE_MINUS_SRC_ALPHA); break; case 2: e.blendFunc(e.ONE, e.ONE); break; case 3: e.blendFuncSeparate(e.ZERO, e.ONE_MINUS_SRC_COLOR, e.ZERO, e.ONE); break; case 4: e.blendFuncSeparate(e.ZERO, e.SRC_COLOR, e.ZERO, e.SRC_ALPHA); break; default: console.error("THREE.WebGLState: Invalid blending: ", t) } else switch (t) { case 1: e.blendFuncSeparate(e.SRC_ALPHA, e.ONE_MINUS_SRC_ALPHA, e.ONE, e.ONE_MINUS_SRC_ALPHA); break; case 2: e.blendFunc(e.SRC_ALPHA, e.ONE); break; case 3: e.blendFuncSeparate(e.ZERO, e.ONE_MINUS_SRC_COLOR, e.ZERO, e.ONE); break; case 4: e.blendFunc(e.ZERO, e.SRC_COLOR); break; default: console.error("THREE.WebGLState: Invalid blending: ", t) } m = null, g = null, w = null, y = null, A.set(0, 0, 0), b = 0, p = t, x = h } } else !0 === u && (ae(e.BLEND), u = !1) } function ce(t) { k !== t && (t ? e.frontFace(e.CW) : e.frontFace(e.CCW), k = t) } function he(t) { 0 !== t ? (re(e.CULL_FACE), t !== E && (1 === t ? e.cullFace(e.BACK) : 2 === t ? e.cullFace(e.FRONT) : e.cullFace(e.FRONT_AND_BACK))) : ae(e.CULL_FACE), E = t } function de(t, n, i) { t ? (re(e.POLYGON_OFFSET_FILL), G === n && j === i || (e.polygonOffset(n, i), G = n, j = i)) : ae(e.POLYGON_OFFSET_FILL) } return { buffers: { color: n, depth: i, stencil: r }, enable: re, disable: ae, bindFramebuffer: function(t, n) { return l[t] !== n && (e.bindFramebuffer(t, n), l[t] = n, t === e.DRAW_FRAMEBUFFER && (l[e.FRAMEBUFFER] = n), t === e.FRAMEBUFFER && (l[e.DRAW_FRAMEBUFFER] = n), !0) }, drawBuffers: function(t, n) { let i = h, r = !1; if (t) { i = c.get(n), void 0 === i && (i = [], c.set(n, i)); const a = t.textures; if (i.length !== a.length || i[0] !== e.COLOR_ATTACHMENT0) { for (let t = 0, n = a.length; t < n; t++) i[t] = e.COLOR_ATTACHMENT0 + t; i.length = a.length, r = !0 } } else i[0] !== e.BACK && (i[0] = e.BACK, r = !0); r && e.drawBuffers(i) }, useProgram: function(t) { return d !== t && (e.useProgram(t), d = t, !0) }, setBlending: le, setMaterial: function(t, a) { 2 === t.side ? ae(e.CULL_FACE) : re(e.CULL_FACE); let s = 1 === t.side; a && (s = !s), ce(s), 1 === t.blending && !1 === t.transparent ? le(0) : le(t.blending, t.blendEquation, t.blendSrc, t.blendDst, t.blendEquationAlpha, t.blendSrcAlpha, t.blendDstAlpha, t.blendColor, t.blendAlpha, t.premultipliedAlpha), i.setFunc(t.depthFunc), i.setTest(t.depthTest), i.setMask(t.depthWrite), n.setMask(t.colorWrite); const o = t.stencilWrite; r.setTest(o), o && (r.setMask(t.stencilWriteMask), r.setFunc(t.stencilFunc, t.stencilRef, t.stencilFuncMask), r.setOp(t.stencilFail, t.stencilZFail, t.stencilZPass)), de(t.polygonOffset, t.polygonOffsetFactor, t.polygonOffsetUnits), !0 === t.alphaToCoverage ? re(e.SAMPLE_ALPHA_TO_COVERAGE) : ae(e.SAMPLE_ALPHA_TO_COVERAGE) }, setFlipSided: ce, setCullFace: he, setLineWidth: function(t) { t !== S && (Y && e.lineWidth(t), S = t) }, setPolygonOffset: de, setScissorTest: function(t) { t ? re(e.SCISSOR_TEST) : ae(e.SCISSOR_TEST) }, activeTexture: function(t) { void 0 === t && (t = e.TEXTURE0 + Q - 1), X !== t && (e.activeTexture(t), X = t) }, bindTexture: function(t, n, i) { void 0 === i && (i = null === X ? e.TEXTURE0 + Q - 1 : X); let r = Z[i]; void 0 === r && (r = { type: void 0, texture: void 0 }, Z[i] = r), r.type === t && r.texture === n || (X !== i && (e.activeTexture(i), X = i), e.bindTexture(t, n || ie[t]), r.type = t, r.texture = n) }, unbindTexture: function() { const t = Z[X]; void 0 !== t && void 0 !== t.type && (e.bindTexture(t.type, null), t.type = void 0, t.texture = void 0) }, compressedTexImage2D: function() { try { e.compressedTexImage2D(...arguments) } catch (e) { console.error("THREE.WebGLState:", e) } }, compressedTexImage3D: function() { try { e.compressedTexImage3D(...arguments) } catch (e) { console.error("THREE.WebGLState:", e) } }, texImage2D: function() { try { e.texImage2D(...arguments) } catch (e) { console.error("THREE.WebGLState:", e) } }, texImage3D: function() { try { e.texImage3D(...arguments) } catch (e) { console.error("THREE.WebGLState:", e) } }, updateUBOMapping: function(t, n) { let i = s.get(n); void 0 === i && (i = new WeakMap, s.set(n, i)); let r = i.get(t); void 0 === r && (r = e.getUniformBlockIndex(n, t.name), i.set(t, r)) }, uniformBlockBinding: function(t, n) { const i = s.get(n).get(t); a.get(n) !== i && (e.uniformBlockBinding(n, i, t.__bindingPointIndex), a.set(n, i)) }, texStorage2D: function() { try { e.texStorage2D(...arguments) } catch (e) { console.error("THREE.WebGLState:", e) } }, texStorage3D: function() { try { e.texStorage3D(...arguments) } catch (e) { console.error("THREE.WebGLState:", e) } }, texSubImage2D: function() { try { e.texSubImage2D(...arguments) } catch (e) { console.error("THREE.WebGLState:", e) } }, texSubImage3D: function() { try { e.texSubImage3D(...arguments) } catch (e) { console.error("THREE.WebGLState:", e) } }, compressedTexSubImage2D: function() { try { e.compressedTexSubImage2D(...arguments) } catch (e) { console.error("THREE.WebGLState:", e) } }, compressedTexSubImage3D: function() { try { e.compressedTexSubImage3D(...arguments) } catch (e) { console.error("THREE.WebGLState:", e) } }, scissor: function(t) { !1 === ee.equals(t) && (e.scissor(t.x, t.y, t.z, t.w), ee.copy(t)) }, viewport: function(t) { !1 === te.equals(t) && (e.viewport(t.x, t.y, t.z, t.w), te.copy(t)) }, reset: function() { e.disable(e.BLEND), e.disable(e.CULL_FACE), e.disable(e.DEPTH_TEST), e.disable(e.POLYGON_OFFSET_FILL), e.disable(e.SCISSOR_TEST), e.disable(e.STENCIL_TEST), e.disable(e.SAMPLE_ALPHA_TO_COVERAGE), e.blendEquation(e.FUNC_ADD), e.blendFunc(e.ONE, e.ZERO), e.blendFuncSeparate(e.ONE, e.ZERO, e.ONE, e.ZERO), e.blendColor(0, 0, 0, 0), e.colorMask(!0, !0, !0, !0), e.clearColor(0, 0, 0, 0), e.depthMask(!0), e.depthFunc(e.LESS), i.setReversed(!1), e.clearDepth(1), e.stencilMask(4294967295), e.stencilFunc(e.ALWAYS, 0, 4294967295), e.stencilOp(e.KEEP, e.KEEP, e.KEEP), e.clearStencil(0), e.cullFace(e.BACK), e.frontFace(e.CCW), e.polygonOffset(0, 0), e.activeTexture(e.TEXTURE0), e.bindFramebuffer(e.FRAMEBUFFER, null), e.bindFramebuffer(e.DRAW_FRAMEBUFFER, null), e.bindFramebuffer(e.READ_FRAMEBUFFER, null), e.useProgram(null), e.lineWidth(1), e.scissor(0, 0, e.canvas.width, e.canvas.height), e.viewport(0, 0, e.canvas.width, e.canvas.height), o = {}, X = null, Z = {}, l = {}, c = new WeakMap, h = [], d = null, u = !1, p = null, f = null, m = null, g = null, v = null, w = null, y = null, A = new Wi(0, 0, 0), b = 0, x = !1, k = null, E = null, S = null, G = null, j = null, ee.set(0, 0, e.canvas.width, e.canvas.height), te.set(0, 0, e.canvas.width, e.canvas.height), n.reset(), i.reset(), r.reset() } } } function Vd(e, t, n, i, r, a, s) { const o = t.has("WEBGL_multisampled_render_to_texture") ? t.get("WEBGL_multisampled_render_to_texture") : null, l = "undefined" != typeof navigator && /OculusBrowser/g.test(navigator.userAgent), c = new jt, h = new WeakMap; let d; const u = new WeakMap; let p = !1; try { p = "undefined" != typeof OffscreenCanvas && null !== new OffscreenCanvas(1, 1).getContext("2d") } catch (e) {} function f(e, t) { return p ? new OffscreenCanvas(e, t) : qt("canvas") } function m(e, t, n) { let i = 1; const r = W(e); if ((r.width > n || r.height > n) && (i = n / Math.max(r.width, r.height)), i < 1) { if ("undefined" != typeof HTMLImageElement && e instanceof HTMLImageElement || "undefined" != typeof HTMLCanvasElement && e instanceof HTMLCanvasElement || "undefined" != typeof ImageBitmap && e instanceof ImageBitmap || "undefined" != typeof VideoFrame && e instanceof VideoFrame) { const n = Math.floor(i * r.width), a = Math.floor(i * r.height); void 0 === d && (d = f(n, a)); const s = t ? f(n, a) : d; s.width = n, s.height = a; return s.getContext("2d").drawImage(e, 0, 0, n, a), console.warn("THREE.WebGLRenderer: Texture has been resized from (" + r.width + "x" + r.height + ") to (" + n + "x" + a + ")."), s } return "data" in e && console.warn("THREE.WebGLRenderer: Image in DataTexture is too big (" + r.width + "x" + r.height + ")."), e } return e } function g(e) { return e.generateMipmaps } function v(t) { e.generateMipmap(t) } function w(t) { return t.isWebGLCubeRenderTarget ? e.TEXTURE_CUBE_MAP : t.isWebGL3DRenderTarget ? e.TEXTURE_3D : t.isWebGLArrayRenderTarget || t.isCompressedArrayTexture ? e.TEXTURE_2D_ARRAY : e.TEXTURE_2D } function y(n, i, r, a, s = !1) { if (null !== n) { if (void 0 !== e[n]) return e[n]; console.warn("THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format '" + n + "'") } let o = i; if (i === e.RED && (r === e.FLOAT && (o = e.R32F), r === e.HALF_FLOAT && (o = e.R16F), r === e.UNSIGNED_BYTE && (o = e.R8)), i === e.RED_INTEGER && (r === e.UNSIGNED_BYTE && (o = e.R8UI), r === e.UNSIGNED_SHORT && (o = e.R16UI), r === e.UNSIGNED_INT && (o = e.R32UI), r === e.BYTE && (o = e.R8I), r === e.SHORT && (o = e.R16I), r === e.INT && (o = e.R32I)), i === e.RG && (r === e.FLOAT && (o = e.RG32F), r === e.HALF_FLOAT && (o = e.RG16F), r === e.UNSIGNED_BYTE && (o = e.RG8)), i === e.RG_INTEGER && (r === e.UNSIGNED_BYTE && (o = e.RG8UI), r === e.UNSIGNED_SHORT && (o = e.RG16UI), r === e.UNSIGNED_INT && (o = e.RG32UI), r === e.BYTE && (o = e.RG8I), r === e.SHORT && (o = e.RG16I), r === e.INT && (o = e.RG32I)), i === e.RGB_INTEGER && (r === e.UNSIGNED_BYTE && (o = e.RGB8UI), r === e.UNSIGNED_SHORT && (o = e.RGB16UI), r === e.UNSIGNED_INT && (o = e.RGB32UI), r === e.BYTE && (o = e.RGB8I), r === e.SHORT && (o = e.RGB16I), r === e.INT && (o = e.RGB32I)), i === e.RGBA_INTEGER && (r === e.UNSIGNED_BYTE && (o = e.RGBA8UI), r === e.UNSIGNED_SHORT && (o = e.RGBA16UI), r === e.UNSIGNED_INT && (o = e.RGBA32UI), r === e.BYTE && (o = e.RGBA8I), r === e.SHORT && (o = e.RGBA16I), r === e.INT && (o = e.RGBA32I)), i === e.RGB && r === e.UNSIGNED_INT_5_9_9_9_REV && (o = e.RGB9_E5), i === e.RGBA) { const t = s ? wt : nn.getTransfer(a); r === e.FLOAT && (o = e.RGBA32F), r === e.HALF_FLOAT && (o = e.RGBA16F), r === e.UNSIGNED_BYTE && (o = t === yt ? e.SRGB8_ALPHA8 : e.RGBA8), r === e.UNSIGNED_SHORT_4_4_4_4 && (o = e.RGBA4), r === e.UNSIGNED_SHORT_5_5_5_1 && (o = e.RGB5_A1) } return o !== e.R16F && o !== e.R32F && o !== e.RG16F && o !== e.RG32F && o !== e.RGBA16F && o !== e.RGBA32F || t.get("EXT_color_buffer_float"), o } function A(t, n) { let i; return t ? null === n || n === we || n === ke ? i = e.DEPTH24_STENCIL8 : n === ye ? i = e.DEPTH32F_STENCIL8 : n === ge && (i = e.DEPTH24_STENCIL8, console.warn("DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment.")) : null === n || n === we || n === ke ? i = e.DEPTH_COMPONENT24 : n === ye ? i = e.DEPTH_COMPONENT32F : n === ge && (i = e.DEPTH_COMPONENT16), i } function b(e, t) { return !0 === g(e) || e.isFramebufferTexture && e.minFilter !== oe && e.minFilter !== he ? Math.log2(Math.max(t.width, t.height)) + 1 : void 0 !== e.mipmaps && e.mipmaps.length > 0 ? e.mipmaps.length : e.isCompressedTexture && Array.isArray(e.image) ? t.mipmaps.length : 1 } function x(e) { const t = e.target; t.removeEventListener("dispose", x), function(e) { const t = i.get(e); if (void 0 === t.__webglInit) return; const n = e.source, r = u.get(n); if (r) { const i = r[t.__cacheKey]; i.usedTimes--, 0 === i.usedTimes && E(e), 0 === Object.keys(r).length && u.delete(n) } i.remove(e) }(t), t.isVideoTexture && h.delete(t) } function k(t) { const n = t.target; n.removeEventListener("dispose", k), function(t) { const n = i.get(t); t.depthTexture && (t.depthTexture.dispose(), i.remove(t.depthTexture)); if (t.isWebGLCubeRenderTarget) for (let t = 0; t < 6; t++) { if (Array.isArray(n.__webglFramebuffer[t])) for (let i = 0; i < n.__webglFramebuffer[t].length; i++) e.deleteFramebuffer(n.__webglFramebuffer[t][i]); else e.deleteFramebuffer(n.__webglFramebuffer[t]); n.__webglDepthbuffer && e.deleteRenderbuffer(n.__webglDepthbuffer[t]) } else { if (Array.isArray(n.__webglFramebuffer)) for (let t = 0; t < n.__webglFramebuffer.length; t++) e.deleteFramebuffer(n.__webglFramebuffer[t]); else e.deleteFramebuffer(n.__webglFramebuffer); if (n.__webglDepthbuffer && e.deleteRenderbuffer(n.__webglDepthbuffer), n.__webglMultisampledFramebuffer && e.deleteFramebuffer(n.__webglMultisampledFramebuffer), n.__webglColorRenderbuffer) for (let t = 0; t < n.__webglColorRenderbuffer.length; t++) n.__webglColorRenderbuffer[t] && e.deleteRenderbuffer(n.__webglColorRenderbuffer[t]); n.__webglDepthRenderbuffer && e.deleteRenderbuffer(n.__webglDepthRenderbuffer) } const r = t.textures; for (let t = 0, n = r.length; t < n; t++) { const n = i.get(r[t]); n.__webglTexture && (e.deleteTexture(n.__webglTexture), s.memory.textures--), i.remove(r[t]) } i.remove(t) }(n) } function E(t) { const n = i.get(t); e.deleteTexture(n.__webglTexture); const r = t.source; delete u.get(r)[n.__cacheKey], s.memory.textures-- } let S = 0; function M(t, r) { const a = i.get(t); if (t.isVideoTexture && function(e) { const t = s.render.frame; h.get(e) !== t && (h.set(e, t), e.update()) }(t), !1 === t.isRenderTargetTexture && t.version > 0 && a.__version !== t.version) { const e = t.image; if (null === e) console.warn("THREE.WebGLRenderer: Texture marked for update but no image data found."); else { if (!1 !== e.complete) return void R(a, t, r); console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete") } } n.bindTexture(e.TEXTURE_2D, a.__webglTexture, e.TEXTURE0 + r) } const T = { [re]: e.REPEAT, [ae]: e.CLAMP_TO_EDGE, [se]: e.MIRRORED_REPEAT }, _ = { [oe]: e.NEAREST, [le]: e.NEAREST_MIPMAP_NEAREST, [ce]: e.NEAREST_MIPMAP_LINEAR, [he]: e.LINEAR, [de]: e.LINEAR_MIPMAP_NEAREST, [ue]: e.LINEAR_MIPMAP_LINEAR }, C = { [bt]: e.NEVER, [_t]: e.ALWAYS, [xt]: e.LESS, [Et]: e.LEQUAL, [kt]: e.EQUAL, [Tt]: e.GEQUAL, [St]: e.GREATER, [Mt]: e.NOTEQUAL }; function P(n, a) { if (a.type !== ye || !1 !== t.has("OES_texture_float_linear") || a.magFilter !== he && a.magFilter !== de && a.magFilter !== ce && a.magFilter !== ue && a.minFilter !== he && a.minFilter !== de && a.minFilter !== ce && a.minFilter !== ue || console.warn("THREE.WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device."), e.texParameteri(n, e.TEXTURE_WRAP_S, T[a.wrapS]), e.texParameteri(n, e.TEXTURE_WRAP_T, T[a.wrapT]), n !== e.TEXTURE_3D && n !== e.TEXTURE_2D_ARRAY || e.texParameteri(n, e.TEXTURE_WRAP_R, T[a.wrapR]), e.texParameteri(n, e.TEXTURE_MAG_FILTER, _[a.magFilter]), e.texParameteri(n, e.TEXTURE_MIN_FILTER, _[a.minFilter]), a.compareFunction && (e.texParameteri(n, e.TEXTURE_COMPARE_MODE, e.COMPARE_REF_TO_TEXTURE), e.texParameteri(n, e.TEXTURE_COMPARE_FUNC, C[a.compareFunction])), !0 === t.has("EXT_texture_filter_anisotropic")) { if (a.magFilter === oe) return; if (a.minFilter !== ce && a.minFilter !== ue) return; if (a.type === ye && !1 === t.has("OES_texture_float_linear")) return; if (a.anisotropy > 1 || i.get(a).__currentAnisotropy) { const s = t.get("EXT_texture_filter_anisotropic"); e.texParameterf(n, s.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(a.anisotropy, r.getMaxAnisotropy())), i.get(a).__currentAnisotropy = a.anisotropy } } } function I(t, n) { let i = !1; void 0 === t.__webglInit && (t.__webglInit = !0, n.addEventListener("dispose", x)); const r = n.source; let a = u.get(r); void 0 === a && (a = {}, u.set(r, a)); const o = function(e) { const t = []; return t.push(e.wrapS), t.push(e.wrapT), t.push(e.wrapR || 0), t.push(e.magFilter), t.push(e.minFilter), t.push(e.anisotropy), t.push(e.internalFormat), t.push(e.format), t.push(e.type), t.push(e.generateMipmaps), t.push(e.premultiplyAlpha), t.push(e.flipY), t.push(e.unpackAlignment), t.push(e.colorSpace), t.join() }(n); if (o !== t.__cacheKey) { void 0 === a[o] && (a[o] = { texture: e.createTexture(), usedTimes: 0 }, s.memory.textures++, i = !0), a[o].usedTimes++; const r = a[t.__cacheKey]; void 0 !== r && (a[t.__cacheKey].usedTimes--, 0 === r.usedTimes && E(n)), t.__cacheKey = o, t.__webglTexture = a[o].texture } return i } function R(t, s, o) { let l = e.TEXTURE_2D; (s.isDataArrayTexture || s.isCompressedArrayTexture) && (l = e.TEXTURE_2D_ARRAY), s.isData3DTexture && (l = e.TEXTURE_3D); const c = I(t, s), h = s.source; n.bindTexture(l, t.__webglTexture, e.TEXTURE0 + o); const d = i.get(h); if (h.version !== d.__version || !0 === c) { n.activeTexture(e.TEXTURE0 + o); const t = nn.getPrimaries(nn.workingColorSpace), i = s.colorSpace === mt ? null : nn.getPrimaries(s.colorSpace), u = s.colorSpace === mt || t === i ? e.NONE : e.BROWSER_DEFAULT_WEBGL; e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL, s.flipY), e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL, s.premultiplyAlpha), e.pixelStorei(e.UNPACK_ALIGNMENT, s.unpackAlignment), e.pixelStorei(e.UNPACK_COLORSPACE_CONVERSION_WEBGL, u); let p = m(s.image, !1, r.maxTextureSize); p = F(s, p); const f = a.convert(s.format, s.colorSpace), w = a.convert(s.type); let x, k = y(s.internalFormat, f, w, s.colorSpace, s.isVideoTexture); P(l, s); const E = s.mipmaps, S = !0 !== s.isVideoTexture, M = void 0 === d.__version || !0 === c, T = h.dataReady, _ = b(s, p); if (s.isDepthTexture) k = A(s.format === Te, s.type), M && (S ? n.texStorage2D(e.TEXTURE_2D, 1, k, p.width, p.height) : n.texImage2D(e.TEXTURE_2D, 0, k, p.width, p.height, 0, f, w, null)); else if (s.isDataTexture) if (E.length > 0) { S && M && n.texStorage2D(e.TEXTURE_2D, _, k, E[0].width, E[0].height); for (let t = 0, i = E.length; t < i; t++) x = E[t], S ? T && n.texSubImage2D(e.TEXTURE_2D, t, 0, 0, x.width, x.height, f, w, x.data) : n.texImage2D(e.TEXTURE_2D, t, k, x.width, x.height, 0, f, w, x.data); s.generateMipmaps = !1 } else S ? (M && n.texStorage2D(e.TEXTURE_2D, _, k, p.width, p.height), T && n.texSubImage2D(e.TEXTURE_2D, 0, 0, 0, p.width, p.height, f, w, p.data)) : n.texImage2D(e.TEXTURE_2D, 0, k, p.width, p.height, 0, f, w, p.data); else if (s.isCompressedTexture) if (s.isCompressedArrayTexture) { S && M && n.texStorage3D(e.TEXTURE_2D_ARRAY, _, k, E[0].width, E[0].height, p.depth); for (let t = 0, i = E.length; t < i; t++) if (x = E[t], s.format !== Se) if (null !== f) if (S) { if (T) if (s.layerUpdates.size > 0) { const i = Zo(x.width, x.height, s.format, s.type); for (const r of s.layerUpdates) { const a = x.data.subarray(r * i / x.data.BYTES_PER_ELEMENT, (r + 1) * i / x.data.BYTES_PER_ELEMENT); n.compressedTexSubImage3D(e.TEXTURE_2D_ARRAY, t, 0, 0, r, x.width, x.height, 1, f, a) } s.clearLayerUpdates() } else n.compressedTexSubImage3D(e.TEXTURE_2D_ARRAY, t, 0, 0, 0, x.width, x.height, p.depth, f, x.data) } else n.compressedTexImage3D(e.TEXTURE_2D_ARRAY, t, k, x.width, x.height, p.depth, 0, x.data, 0, 0); else console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"); else S ? T && n.texSubImage3D(e.TEXTURE_2D_ARRAY, t, 0, 0, 0, x.width, x.height, p.depth, f, w, x.data) : n.texImage3D(e.TEXTURE_2D_ARRAY, t, k, x.width, x.height, p.depth, 0, f, w, x.data) } else { S && M && n.texStorage2D(e.TEXTURE_2D, _, k, E[0].width, E[0].height); for (let t = 0, i = E.length; t < i; t++) x = E[t], s.format !== Se ? null !== f ? S ? T && n.compressedTexSubImage2D(e.TEXTURE_2D, t, 0, 0, x.width, x.height, f, x.data) : n.compressedTexImage2D(e.TEXTURE_2D, t, k, x.width, x.height, 0, x.data) : console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()") : S ? T && n.texSubImage2D(e.TEXTURE_2D, t, 0, 0, x.width, x.height, f, w, x.data) : n.texImage2D(e.TEXTURE_2D, t, k, x.width, x.height, 0, f, w, x.data) } else if (s.isDataArrayTexture) if (S) { if (M && n.texStorage3D(e.TEXTURE_2D_ARRAY, _, k, p.width, p.height, p.depth), T) if (s.layerUpdates.size > 0) { const t = Zo(p.width, p.height, s.format, s.type); for (const i of s.layerUpdates) { const r = p.data.subarray(i * t / p.data.BYTES_PER_ELEMENT, (i + 1) * t / p.data.BYTES_PER_ELEMENT); n.texSubImage3D(e.TEXTURE_2D_ARRAY, 0, 0, 0, i, p.width, p.height, 1, f, w, r) } s.clearLayerUpdates() } else n.texSubImage3D(e.TEXTURE_2D_ARRAY, 0, 0, 0, 0, p.width, p.height, p.depth, f, w, p.data) } else n.texImage3D(e.TEXTURE_2D_ARRAY, 0, k, p.width, p.height, p.depth, 0, f, w, p.data); else if (s.isData3DTexture) S ? (M && n.texStorage3D(e.TEXTURE_3D, _, k, p.width, p.height, p.depth), T && n.texSubImage3D(e.TEXTURE_3D, 0, 0, 0, 0, p.width, p.height, p.depth, f, w, p.data)) : n.texImage3D(e.TEXTURE_3D, 0, k, p.width, p.height, p.depth, 0, f, w, p.data); else if (s.isFramebufferTexture) { if (M) if (S) n.texStorage2D(e.TEXTURE_2D, _, k, p.width, p.height); else { let t = p.width, i = p.height; for (let r = 0; r < _; r++) n.texImage2D(e.TEXTURE_2D, r, k, t, i, 0, f, w, null), t >>= 1, i >>= 1 } } else if (E.length > 0) { if (S && M) { const t = W(E[0]); n.texStorage2D(e.TEXTURE_2D, _, k, t.width, t.height) } for (let t = 0, i = E.length; t < i; t++) x = E[t], S ? T && n.texSubImage2D(e.TEXTURE_2D, t, 0, 0, f, w, x) : n.texImage2D(e.TEXTURE_2D, t, k, f, w, x); s.generateMipmaps = !1 } else if (S) { if (M) { const t = W(p); n.texStorage2D(e.TEXTURE_2D, _, k, t.width, t.height) } T && n.texSubImage2D(e.TEXTURE_2D, 0, 0, 0, f, w, p) } else n.texImage2D(e.TEXTURE_2D, 0, k, f, w, p); g(s) && v(l), d.__version = h.version, s.onUpdate && s.onUpdate(s) } t.__version = s.version } function L(t, r, s, l, c, h) { const d = a.convert(s.format, s.colorSpace), u = a.convert(s.type), p = y(s.internalFormat, d, u, s.colorSpace), f = i.get(r), m = i.get(s); if (m.__renderTarget = r, !f.__hasExternalTextures) { const t = Math.max(1, r.width >> h), i = Math.max(1, r.height >> h); c === e.TEXTURE_3D || c === e.TEXTURE_2D_ARRAY ? n.texImage3D(c, h, p, t, i, r.depth, 0, d, u, null) : n.texImage2D(c, h, p, t, i, 0, d, u, null) } n.bindFramebuffer(e.FRAMEBUFFER, t), O(r) ? o.framebufferTexture2DMultisampleEXT(e.FRAMEBUFFER, l, c, m.__webglTexture, 0, z(r)) : (c === e.TEXTURE_2D || c >= e.TEXTURE_CUBE_MAP_POSITIVE_X && c <= e.TEXTURE_CUBE_MAP_NEGATIVE_Z) && e.framebufferTexture2D(e.FRAMEBUFFER, l, c, m.__webglTexture, h), n.bindFramebuffer(e.FRAMEBUFFER, null) } function D(t, n, i) { if (e.bindRenderbuffer(e.RENDERBUFFER, t), n.depthBuffer) { const r = n.depthTexture, a = r && r.isDepthTexture ? r.type : null, s = A(n.stencilBuffer, a), l = n.stencilBuffer ? e.DEPTH_STENCIL_ATTACHMENT : e.DEPTH_ATTACHMENT, c = z(n); O(n) ? o.renderbufferStorageMultisampleEXT(e.RENDERBUFFER, c, s, n.width, n.height) : i ? e.renderbufferStorageMultisample(e.RENDERBUFFER, c, s, n.width, n.height) : e.renderbufferStorage(e.RENDERBUFFER, s, n.width, n.height), e.framebufferRenderbuffer(e.FRAMEBUFFER, l, e.RENDERBUFFER, t) } else { const t = n.textures; for (let r = 0; r < t.length; r++) { const s = t[r], l = a.convert(s.format, s.colorSpace), c = a.convert(s.type), h = y(s.internalFormat, l, c, s.colorSpace), d = z(n); i && !1 === O(n) ? e.renderbufferStorageMultisample(e.RENDERBUFFER, d, h, n.width, n.height) : O(n) ? o.renderbufferStorageMultisampleEXT(e.RENDERBUFFER, d, h, n.width, n.height) : e.renderbufferStorage(e.RENDERBUFFER, h, n.width, n.height) } } e.bindRenderbuffer(e.RENDERBUFFER, null) } function N(t) { const r = i.get(t), a = !0 === t.isWebGLCubeRenderTarget; if (r.__boundDepthTexture !== t.depthTexture) { const e = t.depthTexture; if (r.__depthDisposeCallback && r.__depthDisposeCallback(), e) { const t = () => { delete r.__boundDepthTexture, delete r.__depthDisposeCallback, e.removeEventListener("dispose", t) }; e.addEventListener("dispose", t), r.__depthDisposeCallback = t } r.__boundDepthTexture = e } if (t.depthTexture && !r.__autoAllocateDepthBuffer) { if (a) throw new Error("target.depthTexture not supported in Cube render targets"); ! function(t, r) { if (r && r.isWebGLCubeRenderTarget) throw new Error("Depth Texture with cube render targets is not supported"); if (n.bindFramebuffer(e.FRAMEBUFFER, t), !r.depthTexture || !r.depthTexture.isDepthTexture) throw new Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture"); const a = i.get(r.depthTexture); a.__renderTarget = r, a.__webglTexture && r.depthTexture.image.width === r.width && r.depthTexture.image.height === r.height || (r.depthTexture.image.width = r.width, r.depthTexture.image.height = r.height, r.depthTexture.needsUpdate = !0), M(r.depthTexture, 0); const s = a.__webglTexture, l = z(r); if (r.depthTexture.format === Me) O(r) ? o.framebufferTexture2DMultisampleEXT(e.FRAMEBUFFER, e.DEPTH_ATTACHMENT, e.TEXTURE_2D, s, 0, l) : e.framebufferTexture2D(e.FRAMEBUFFER, e.DEPTH_ATTACHMENT, e.TEXTURE_2D, s, 0); else { if (r.depthTexture.format !== Te) throw new Error("Unknown depthTexture format"); O(r) ? o.framebufferTexture2DMultisampleEXT(e.FRAMEBUFFER, e.DEPTH_STENCIL_ATTACHMENT, e.TEXTURE_2D, s, 0, l) : e.framebufferTexture2D(e.FRAMEBUFFER, e.DEPTH_STENCIL_ATTACHMENT, e.TEXTURE_2D, s, 0) } }(r.__webglFramebuffer, t) } else if (a) { r.__webglDepthbuffer = []; for (let i = 0; i < 6; i++) if (n.bindFramebuffer(e.FRAMEBUFFER, r.__webglFramebuffer[i]), void 0 === r.__webglDepthbuffer[i]) r.__webglDepthbuffer[i] = e.createRenderbuffer(), D(r.__webglDepthbuffer[i], t, !1); else { const n = t.stencilBuffer ? e.DEPTH_STENCIL_ATTACHMENT : e.DEPTH_ATTACHMENT, a = r.__webglDepthbuffer[i]; e.bindRenderbuffer(e.RENDERBUFFER, a), e.framebufferRenderbuffer(e.FRAMEBUFFER, n, e.RENDERBUFFER, a) } } else if (n.bindFramebuffer(e.FRAMEBUFFER, r.__webglFramebuffer), void 0 === r.__webglDepthbuffer) r.__webglDepthbuffer = e.createRenderbuffer(), D(r.__webglDepthbuffer, t, !1); else { const n = t.stencilBuffer ? e.DEPTH_STENCIL_ATTACHMENT : e.DEPTH_ATTACHMENT, i = r.__webglDepthbuffer; e.bindRenderbuffer(e.RENDERBUFFER, i), e.framebufferRenderbuffer(e.FRAMEBUFFER, n, e.RENDERBUFFER, i) } n.bindFramebuffer(e.FRAMEBUFFER, null) } const B = [], U = []; function z(e) { return Math.min(r.maxSamples, e.samples) } function O(e) { const n = i.get(e); return e.samples > 0 && !0 === t.has("WEBGL_multisampled_render_to_texture") && !1 !== n.__useRenderToTexture } function F(e, t) { const n = e.colorSpace, i = e.format, r = e.type; return !0 === e.isCompressedTexture || !0 === e.isVideoTexture || n !== vt && n !== mt && (nn.getTransfer(n) === yt ? i === Se && r === pe || console.warn("THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType.") : console.error("THREE.WebGLTextures: Unsupported texture color space:", n)), t } function W(e) { return "undefined" != typeof HTMLImageElement && e instanceof HTMLImageElement ? (c.width = e.naturalWidth || e.width, c.height = e.naturalHeight || e.height) : "undefined" != typeof VideoFrame && e instanceof VideoFrame ? (c.width = e.displayWidth, c.height = e.displayHeight) : (c.width = e.width, c.height = e.height), c } this.allocateTextureUnit = function() { const e = S; return e >= r.maxTextures && console.warn("THREE.WebGLTextures: Trying to use " + e + " texture units while this GPU supports only " + r.maxTextures), S += 1, e }, this.resetTextureUnits = function() { S = 0 }, this.setTexture2D = M, this.setTexture2DArray = function(t, r) { const a = i.get(t); t.version > 0 && a.__version !== t.version ? R(a, t, r) : n.bindTexture(e.TEXTURE_2D_ARRAY, a.__webglTexture, e.TEXTURE0 + r) }, this.setTexture3D = function(t, r) { const a = i.get(t); t.version > 0 && a.__version !== t.version ? R(a, t, r) : n.bindTexture(e.TEXTURE_3D, a.__webglTexture, e.TEXTURE0 + r) }, this.setTextureCube = function(t, s) { const o = i.get(t); t.version > 0 && o.__version !== t.version ? function(t, s, o) { if (6 !== s.image.length) return; const l = I(t, s), c = s.source; n.bindTexture(e.TEXTURE_CUBE_MAP, t.__webglTexture, e.TEXTURE0 + o); const h = i.get(c); if (c.version !== h.__version || !0 === l) { n.activeTexture(e.TEXTURE0 + o); const t = nn.getPrimaries(nn.workingColorSpace), i = s.colorSpace === mt ? null : nn.getPrimaries(s.colorSpace), d = s.colorSpace === mt || t === i ? e.NONE : e.BROWSER_DEFAULT_WEBGL; e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL, s.flipY), e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL, s.premultiplyAlpha), e.pixelStorei(e.UNPACK_ALIGNMENT, s.unpackAlignment), e.pixelStorei(e.UNPACK_COLORSPACE_CONVERSION_WEBGL, d); const u = s.isCompressedTexture || s.image[0].isCompressedTexture, p = s.image[0] && s.image[0].isDataTexture, f = []; for (let e = 0; e < 6; e++) f[e] = u || p ? p ? s.image[e].image : s.image[e] : m(s.image[e], !0, r.maxCubemapSize), f[e] = F(s, f[e]); const w = f[0], A = a.convert(s.format, s.colorSpace), x = a.convert(s.type), k = y(s.internalFormat, A, x, s.colorSpace), E = !0 !== s.isVideoTexture, S = void 0 === h.__version || !0 === l, M = c.dataReady; let T, _ = b(s, w); if (P(e.TEXTURE_CUBE_MAP, s), u) { E && S && n.texStorage2D(e.TEXTURE_CUBE_MAP, _, k, w.width, w.height); for (let t = 0; t < 6; t++) { T = f[t].mipmaps; for (let i = 0; i < T.length; i++) { const r = T[i]; s.format !== Se ? null !== A ? E ? M && n.compressedTexSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, i, 0, 0, r.width, r.height, A, r.data) : n.compressedTexImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, i, k, r.width, r.height, 0, r.data) : console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()") : E ? M && n.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, i, 0, 0, r.width, r.height, A, x, r.data) : n.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, i, k, r.width, r.height, 0, A, x, r.data) } } } else { if (T = s.mipmaps, E && S) { T.length > 0 && _++; const t = W(f[0]); n.texStorage2D(e.TEXTURE_CUBE_MAP, _, k, t.width, t.height) } for (let t = 0; t < 6; t++) if (p) { E ? M && n.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, 0, 0, 0, f[t].width, f[t].height, A, x, f[t].data) : n.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, 0, k, f[t].width, f[t].height, 0, A, x, f[t].data); for (let i = 0; i < T.length; i++) { const r = T[i].image[t].image; E ? M && n.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, i + 1, 0, 0, r.width, r.height, A, x, r.data) : n.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, i + 1, k, r.width, r.height, 0, A, x, r.data) } } else { E ? M && n.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, 0, 0, 0, A, x, f[t]) : n.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, 0, k, A, x, f[t]); for (let i = 0; i < T.length; i++) { const r = T[i]; E ? M && n.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, i + 1, 0, 0, A, x, r.image[t]) : n.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X + t, i + 1, k, A, x, r.image[t]) } } } g(s) && v(e.TEXTURE_CUBE_MAP), h.__version = c.version, s.onUpdate && s.onUpdate(s) } t.__version = s.version }(o, t, s) : n.bindTexture(e.TEXTURE_CUBE_MAP, o.__webglTexture, e.TEXTURE0 + s) }, this.rebindTextures = function(t, n, r) { const a = i.get(t); void 0 !== n && L(a.__webglFramebuffer, t, t.texture, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, 0), void 0 !== r && N(t) }, this.setupRenderTarget = function(t) { const r = t.texture, o = i.get(t), l = i.get(r); t.addEventListener("dispose", k); const c = t.textures, h = !0 === t.isWebGLCubeRenderTarget, d = c.length > 1; if (d || (void 0 === l.__webglTexture && (l.__webglTexture = e.createTexture()), l.__version = r.version, s.memory.textures++), h) { o.__webglFramebuffer = []; for (let t = 0; t < 6; t++) if (r.mipmaps && r.mipmaps.length > 0) { o.__webglFramebuffer[t] = []; for (let n = 0; n < r.mipmaps.length; n++) o.__webglFramebuffer[t][n] = e.createFramebuffer() } else o.__webglFramebuffer[t] = e.createFramebuffer() } else { if (r.mipmaps && r.mipmaps.length > 0) { o.__webglFramebuffer = []; for (let t = 0; t < r.mipmaps.length; t++) o.__webglFramebuffer[t] = e.createFramebuffer() } else o.__webglFramebuffer = e.createFramebuffer(); if (d) for (let t = 0, n = c.length; t < n; t++) { const n = i.get(c[t]); void 0 === n.__webglTexture && (n.__webglTexture = e.createTexture(), s.memory.textures++) } if (t.samples > 0 && !1 === O(t)) { o.__webglMultisampledFramebuffer = e.createFramebuffer(), o.__webglColorRenderbuffer = [], n.bindFramebuffer(e.FRAMEBUFFER, o.__webglMultisampledFramebuffer); for (let n = 0; n < c.length; n++) { const i = c[n]; o.__webglColorRenderbuffer[n] = e.createRenderbuffer(), e.bindRenderbuffer(e.RENDERBUFFER, o.__webglColorRenderbuffer[n]); const r = a.convert(i.format, i.colorSpace), s = a.convert(i.type), l = y(i.internalFormat, r, s, i.colorSpace, !0 === t.isXRRenderTarget), h = z(t); e.renderbufferStorageMultisample(e.RENDERBUFFER, h, l, t.width, t.height), e.framebufferRenderbuffer(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0 + n, e.RENDERBUFFER, o.__webglColorRenderbuffer[n]) } e.bindRenderbuffer(e.RENDERBUFFER, null), t.depthBuffer && (o.__webglDepthRenderbuffer = e.createRenderbuffer(), D(o.__webglDepthRenderbuffer, t, !0)), n.bindFramebuffer(e.FRAMEBUFFER, null) } } if (h) { n.bindTexture(e.TEXTURE_CUBE_MAP, l.__webglTexture), P(e.TEXTURE_CUBE_MAP, r); for (let n = 0; n < 6; n++) if (r.mipmaps && r.mipmaps.length > 0) for (let i = 0; i < r.mipmaps.length; i++) L(o.__webglFramebuffer[n][i], t, r, e.COLOR_ATTACHMENT0, e.TEXTURE_CUBE_MAP_POSITIVE_X + n, i); else L(o.__webglFramebuffer[n], t, r, e.COLOR_ATTACHMENT0, e.TEXTURE_CUBE_MAP_POSITIVE_X + n, 0); g(r) && v(e.TEXTURE_CUBE_MAP), n.unbindTexture() } else if (d) { for (let r = 0, a = c.length; r < a; r++) { const a = c[r], s = i.get(a); n.bindTexture(e.TEXTURE_2D, s.__webglTexture), P(e.TEXTURE_2D, a), L(o.__webglFramebuffer, t, a, e.COLOR_ATTACHMENT0 + r, e.TEXTURE_2D, 0), g(a) && v(e.TEXTURE_2D) } n.unbindTexture() } else { let i = e.TEXTURE_2D; if ((t.isWebGL3DRenderTarget || t.isWebGLArrayRenderTarget) && (i = t.isWebGL3DRenderTarget ? e.TEXTURE_3D : e.TEXTURE_2D_ARRAY), n.bindTexture(i, l.__webglTexture), P(i, r), r.mipmaps && r.mipmaps.length > 0) for (let n = 0; n < r.mipmaps.length; n++) L(o.__webglFramebuffer[n], t, r, e.COLOR_ATTACHMENT0, i, n); else L(o.__webglFramebuffer, t, r, e.COLOR_ATTACHMENT0, i, 0); g(r) && v(i), n.unbindTexture() } t.depthBuffer && N(t) }, this.updateRenderTargetMipmap = function(e) { const t = e.textures; for (let r = 0, a = t.length; r < a; r++) { const a = t[r]; if (g(a)) { const t = w(e), r = i.get(a).__webglTexture; n.bindTexture(t, r), v(t), n.unbindTexture() } } }, this.updateMultisampleRenderTarget = function(t) { if (t.samples > 0) if (!1 === O(t)) { const r = t.textures, a = t.width, s = t.height; let o = e.COLOR_BUFFER_BIT; const c = t.stencilBuffer ? e.DEPTH_STENCIL_ATTACHMENT : e.DEPTH_ATTACHMENT, h = i.get(t), d = r.length > 1; if (d) for (let t = 0; t < r.length; t++) n.bindFramebuffer(e.FRAMEBUFFER, h.__webglMultisampledFramebuffer), e.framebufferRenderbuffer(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0 + t, e.RENDERBUFFER, null), n.bindFramebuffer(e.FRAMEBUFFER, h.__webglFramebuffer), e.framebufferTexture2D(e.DRAW_FRAMEBUFFER, e.COLOR_ATTACHMENT0 + t, e.TEXTURE_2D, null, 0); n.bindFramebuffer(e.READ_FRAMEBUFFER, h.__webglMultisampledFramebuffer), n.bindFramebuffer(e.DRAW_FRAMEBUFFER, h.__webglFramebuffer); for (let n = 0; n < r.length; n++) { if (t.resolveDepthBuffer && (t.depthBuffer && (o |= e.DEPTH_BUFFER_BIT), t.stencilBuffer && t.resolveStencilBuffer && (o |= e.STENCIL_BUFFER_BIT)), d) { e.framebufferRenderbuffer(e.READ_FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.RENDERBUFFER, h.__webglColorRenderbuffer[n]); const t = i.get(r[n]).__webglTexture; e.framebufferTexture2D(e.DRAW_FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, t, 0) } e.blitFramebuffer(0, 0, a, s, 0, 0, a, s, o, e.NEAREST), !0 === l && (B.length = 0, U.length = 0, B.push(e.COLOR_ATTACHMENT0 + n), t.depthBuffer && !1 === t.resolveDepthBuffer && (B.push(c), U.push(c), e.invalidateFramebuffer(e.DRAW_FRAMEBUFFER, U)), e.invalidateFramebuffer(e.READ_FRAMEBUFFER, B)) } if (n.bindFramebuffer(e.READ_FRAMEBUFFER, null), n.bindFramebuffer(e.DRAW_FRAMEBUFFER, null), d) for (let t = 0; t < r.length; t++) { n.bindFramebuffer(e.FRAMEBUFFER, h.__webglMultisampledFramebuffer), e.framebufferRenderbuffer(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0 + t, e.RENDERBUFFER, h.__webglColorRenderbuffer[t]); const a = i.get(r[t]).__webglTexture; n.bindFramebuffer(e.FRAMEBUFFER, h.__webglFramebuffer), e.framebufferTexture2D(e.DRAW_FRAMEBUFFER, e.COLOR_ATTACHMENT0 + t, e.TEXTURE_2D, a, 0) } n.bindFramebuffer(e.DRAW_FRAMEBUFFER, h.__webglMultisampledFramebuffer) } else if (t.depthBuffer && !1 === t.resolveDepthBuffer && l) { const n = t.stencilBuffer ? e.DEPTH_STENCIL_ATTACHMENT : e.DEPTH_ATTACHMENT; e.invalidateFramebuffer(e.DRAW_FRAMEBUFFER, [n]) } }, this.setupDepthRenderbuffer = N, this.setupFrameBufferTexture = L, this.useMultisampledRTT = O } function Hd(e, t) { return { convert: function(n, i = "") { let r; const a = nn.getTransfer(i); if (n === pe) return e.UNSIGNED_BYTE; if (n === be) return e.UNSIGNED_SHORT_4_4_4_4; if (n === xe) return e.UNSIGNED_SHORT_5_5_5_1; if (n === Ee) return e.UNSIGNED_INT_5_9_9_9_REV; if (n === fe) return e.BYTE; if (n === me) return e.SHORT; if (n === ge) return e.UNSIGNED_SHORT; if (n === ve) return e.INT; if (n === we) return e.UNSIGNED_INT; if (n === ye) return e.FLOAT; if (n === Ae) return e.HALF_FLOAT; if (1021 === n) return e.ALPHA; if (1022 === n) return e.RGB; if (n === Se) return e.RGBA; if (1024 === n) return e.LUMINANCE; if (1025 === n) return e.LUMINANCE_ALPHA; if (n === Me) return e.DEPTH_COMPONENT; if (n === Te) return e.DEPTH_STENCIL; if (n === _e) return e.RED; if (n === Ce) return e.RED_INTEGER; if (1030 === n) return e.RG; if (n === Pe) return e.RG_INTEGER; if (n === Ie) return e.RGBA_INTEGER; if (n === Re || n === Le || n === De || n === Ne) if (a === yt) { if (r = t.get("WEBGL_compressed_texture_s3tc_srgb"), null === r) return null; if (n === Re) return r.COMPRESSED_SRGB_S3TC_DXT1_EXT; if (n === Le) return r.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; if (n === De) return r.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; if (n === Ne) return r.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT } else { if (r = t.get("WEBGL_compressed_texture_s3tc"), null === r) return null; if (n === Re) return r.COMPRESSED_RGB_S3TC_DXT1_EXT; if (n === Le) return r.COMPRESSED_RGBA_S3TC_DXT1_EXT; if (n === De) return r.COMPRESSED_RGBA_S3TC_DXT3_EXT; if (n === Ne) return r.COMPRESSED_RGBA_S3TC_DXT5_EXT } if (n === Be || n === Ue || n === ze || n === Oe) { if (r = t.get("WEBGL_compressed_texture_pvrtc"), null === r) return null; if (n === Be) return r.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; if (n === Ue) return r.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; if (n === ze) return r.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; if (n === Oe) return r.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG } if (n === Fe || n === We || n === Ve) { if (r = t.get("WEBGL_compressed_texture_etc"), null === r) return null; if (n === Fe || n === We) return a === yt ? r.COMPRESSED_SRGB8_ETC2 : r.COMPRESSED_RGB8_ETC2; if (n === Ve) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : r.COMPRESSED_RGBA8_ETC2_EAC } if (n === He || n === Ge || n === je || n === Qe || n === Ye || n === Ke || n === qe || n === Xe || n === Ze || n === Je || n === $e || n === et || n === tt || n === nt) { if (r = t.get("WEBGL_compressed_texture_astc"), null === r) return null; if (n === He) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : r.COMPRESSED_RGBA_ASTC_4x4_KHR; if (n === Ge) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : r.COMPRESSED_RGBA_ASTC_5x4_KHR; if (n === je) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : r.COMPRESSED_RGBA_ASTC_5x5_KHR; if (n === Qe) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : r.COMPRESSED_RGBA_ASTC_6x5_KHR; if (n === Ye) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : r.COMPRESSED_RGBA_ASTC_6x6_KHR; if (n === Ke) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : r.COMPRESSED_RGBA_ASTC_8x5_KHR; if (n === qe) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : r.COMPRESSED_RGBA_ASTC_8x6_KHR; if (n === Xe) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : r.COMPRESSED_RGBA_ASTC_8x8_KHR; if (n === Ze) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : r.COMPRESSED_RGBA_ASTC_10x5_KHR; if (n === Je) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : r.COMPRESSED_RGBA_ASTC_10x6_KHR; if (n === $e) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : r.COMPRESSED_RGBA_ASTC_10x8_KHR; if (n === et) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : r.COMPRESSED_RGBA_ASTC_10x10_KHR; if (n === tt) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : r.COMPRESSED_RGBA_ASTC_12x10_KHR; if (n === nt) return a === yt ? r.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : r.COMPRESSED_RGBA_ASTC_12x12_KHR } if (n === it || n === rt || n === at) { if (r = t.get("EXT_texture_compression_bptc"), null === r) return null; if (n === it) return a === yt ? r.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : r.COMPRESSED_RGBA_BPTC_UNORM_EXT; if (n === rt) return r.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT; if (n === at) return r.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT } if (36283 === n || n === st || n === ot || n === lt) { if (r = t.get("EXT_texture_compression_rgtc"), null === r) return null; if (n === it) return r.COMPRESSED_RED_RGTC1_EXT; if (n === st) return r.COMPRESSED_SIGNED_RED_RGTC1_EXT; if (n === ot) return r.COMPRESSED_RED_GREEN_RGTC2_EXT; if (n === lt) return r.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT } return n === ke ? e.UNSIGNED_INT_24_8 : void 0 !== e[n] ? e[n] : null } } } class Gd { constructor() { this.texture = null, this.mesh = null, this.depthNear = 0, this.depthFar = 0 } init(e, t, n) { if (null === this.texture) { const i = new un; e.properties.get(i).__webglTexture = t.texture, t.depthNear === n.depthNear && t.depthFar === n.depthFar || (this.depthNear = t.depthNear, this.depthFar = t.depthFar), this.texture = i } } getMesh(e) { if (null !== this.texture && null === this.mesh) { const t = e.cameras[0].viewport, n = new Sr({ vertexShader: "\nvoid main() {\n\n\tgl_Position = vec4( position, 1.0 );\n\n}", fragmentShader: "\nuniform sampler2DArray depthColor;\nuniform float depthWidth;\nuniform float depthHeight;\n\nvoid main() {\n\n\tvec2 coord = vec2( gl_FragCoord.x / depthWidth, gl_FragCoord.y / depthHeight );\n\n\tif ( coord.x >= 1.0 ) {\n\n\t\tgl_FragDepth = texture( depthColor, vec3( coord.x - 1.0, coord.y, 1 ) ).r;\n\n\t} else {\n\n\t\tgl_FragDepth = texture( depthColor, vec3( coord.x, coord.y, 0 ) ).r;\n\n\t}\n\n}", uniforms: { depthColor: { value: this.texture }, depthWidth: { value: t.z }, depthHeight: { value: t.w } } }); this.mesh = new wr(new Ns(20, 20), n) } return this.mesh } reset() { this.texture = null, this.mesh = null } getDepthTexture() { return this.texture } } class jd extends Lt { constructor(e, t) { super(); const n = this; let i = null, r = 1, a = null, s = "local-floor", o = 1, l = null, c = null, h = null, d = null, u = null, p = null; const f = new Gd, m = t.getContextAttributes(); let g = null, v = null; const w = [], y = [], A = new jt; let b = null; const x = new Pr; x.viewport = new pn; const k = new Pr; k.viewport = new pn; const E = [x, k], S = new Bo; let M = null, T = null; function _(e) { const t = y.indexOf(e.inputSource); if (-1 === t) return; const n = w[t]; void 0 !== n && (n.update(e.inputSource, e.frame, l || a), n.dispatchEvent({ type: e.type, data: e.inputSource })) } function C() { i.removeEventListener("select", _), i.removeEventListener("selectstart", _), i.removeEventListener("selectend", _), i.removeEventListener("squeeze", _), i.removeEventListener("squeezestart", _), i.removeEventListener("squeezeend", _), i.removeEventListener("end", C), i.removeEventListener("inputsourceschange", P); for (let e = 0; e < w.length; e++) { const t = y[e]; null !== t && (y[e] = null, w[e].disconnect(t)) } M = null, T = null, f.reset(), e.setRenderTarget(g), u = null, d = null, h = null, i = null, v = null, N.stop(), n.isPresenting = !1, e.setPixelRatio(b), e.setSize(A.width, A.height, !1), n.dispatchEvent({ type: "sessionend" }) } function P(e) { for (let t = 0; t < e.removed.length; t++) { const n = e.removed[t], i = y.indexOf(n); i >= 0 && (y[i] = null, w[i].disconnect(n)) } for (let t = 0; t < e.added.length; t++) { const n = e.added[t]; let i = y.indexOf(n); if (-1 === i) { for (let e = 0; e < w.length; e++) { if (e >= y.length) { y.push(n), i = e; break } if (null === y[e]) { y[e] = n, i = e; break } } if (-1 === i) break } const r = w[i]; r && r.connect(n) } } this.cameraAutoUpdate = !0, this.enabled = !1, this.isPresenting = !1, this.getController = function(e) { let t = w[e]; return void 0 === t && (t = new Ur, w[e] = t), t.getTargetRaySpace() }, this.getControllerGrip = function(e) { let t = w[e]; return void 0 === t && (t = new Ur, w[e] = t), t.getGripSpace() }, this.getHand = function(e) { let t = w[e]; return void 0 === t && (t = new Ur, w[e] = t), t.getHandSpace() }, this.setFramebufferScaleFactor = function(e) { r = e, !0 === n.isPresenting && console.warn("THREE.WebXRManager: Cannot change framebuffer scale while presenting.") }, this.setReferenceSpaceType = function(e) { s = e, !0 === n.isPresenting && console.warn("THREE.WebXRManager: Cannot change reference space type while presenting.") }, this.getReferenceSpace = function() { return l || a }, this.setReferenceSpace = function(e) { l = e }, this.getBaseLayer = function() { return null !== d ? d : u }, this.getBinding = function() { return h }, this.getFrame = function() { return p }, this.getSession = function() { return i }, this.setSession = async function(c) { if (i = c, null !== i) { g = e.getRenderTarget(), i.addEventListener("select", _), i.addEventListener("selectstart", _), i.addEventListener("selectend", _), i.addEventListener("squeeze", _), i.addEventListener("squeezestart", _), i.addEventListener("squeezeend", _), i.addEventListener("end", C), i.addEventListener("inputsourceschange", P), !0 !== m.xrCompatible && await t.makeXRCompatible(), b = e.getPixelRatio(), e.getSize(A); if ("undefined" != typeof XRWebGLBinding && "createProjectionLayer" in XRWebGLBinding.prototype) { let n = null, a = null, s = null; m.depth && (s = m.stencil ? t.DEPTH24_STENCIL8 : t.DEPTH_COMPONENT24, n = m.stencil ? Te : Me, a = m.stencil ? ke : we); const o = { colorFormat: t.RGBA8, depthFormat: s, scaleFactor: r }; h = new XRWebGLBinding(i, t), d = h.createProjectionLayer(o), i.updateRenderState({ layers: [d] }), e.setPixelRatio(1), e.setSize(d.textureWidth, d.textureHeight, !1), v = new mn(d.textureWidth, d.textureHeight, { format: Se, type: pe, depthTexture: new Wa(d.textureWidth, d.textureHeight, a, void 0, void 0, void 0, void 0, void 0, void 0, n), stencilBuffer: m.stencil, colorSpace: e.outputColorSpace, samples: m.antialias ? 4 : 0, resolveDepthBuffer: !1 === d.ignoreDepthValues, resolveStencilBuffer: !1 === d.ignoreDepthValues }) } else { const n = { antialias: m.antialias, alpha: !0, depth: m.depth, stencil: m.stencil, framebufferScaleFactor: r }; u = new XRWebGLLayer(i, t, n), i.updateRenderState({ baseLayer: u }), e.setPixelRatio(1), e.setSize(u.framebufferWidth, u.framebufferHeight, !1), v = new mn(u.framebufferWidth, u.framebufferHeight, { format: Se, type: pe, colorSpace: e.outputColorSpace, stencilBuffer: m.stencil, resolveDepthBuffer: !1 === u.ignoreDepthValues, resolveStencilBuffer: !1 === u.ignoreDepthValues }) } v.isXRRenderTarget = !0, this.setFoveation(o), l = null, a = await i.requestReferenceSpace(s), N.setContext(i), N.start(), n.isPresenting = !0, n.dispatchEvent({ type: "sessionstart" }) } }, this.getEnvironmentBlendMode = function() { if (null !== i) return i.environmentBlendMode }, this.getDepthTexture = function() { return f.getDepthTexture() }; const I = new yn, R = new yn; function L(e, t) { null === t ? e.matrixWorld.copy(e.matrix) : e.matrixWorld.multiplyMatrices(t.matrixWorld, e.matrix), e.matrixWorldInverse.copy(e.matrixWorld).invert() } this.updateCamera = function(e) { if (null === i) return; let t = e.near, n = e.far; null !== f.texture && (f.depthNear > 0 && (t = f.depthNear), f.depthFar > 0 && (n = f.depthFar)), S.near = k.near = x.near = t, S.far = k.far = x.far = n, M === S.near && T === S.far || (i.updateRenderState({ depthNear: S.near, depthFar: S.far }), M = S.near, T = S.far), x.layers.mask = 2 | e.layers.mask, k.layers.mask = 4 | e.layers.mask, S.layers.mask = x.layers.mask | k.layers.mask; const r = e.parent, a = S.cameras; L(S, r); for (let e = 0; e < a.length; e++) L(a[e], r); 2 === a.length ? function(e, t, n) { I.setFromMatrixPosition(t.matrixWorld), R.setFromMatrixPosition(n.matrixWorld); const i = I.distanceTo(R), r = t.projectionMatrix.elements, a = n.projectionMatrix.elements, s = r[14] / (r[10] - 1), o = r[14] / (r[10] + 1), l = (r[9] + 1) / r[5], c = (r[9] - 1) / r[5], h = (r[8] - 1) / r[0], d = (a[8] + 1) / a[0], u = s * h, p = s * d, f = i / (-h + d), m = f * -h; if (t.matrixWorld.decompose(e.position, e.quaternion, e.scale), e.translateX(m), e.translateZ(f), e.matrixWorld.compose(e.position, e.quaternion, e.scale), e.matrixWorldInverse.copy(e.matrixWorld).invert(), -1 === r[10]) e.projectionMatrix.copy(t.projectionMatrix), e.projectionMatrixInverse.copy(t.projectionMatrixInverse); else { const t = s + f, n = o + f, r = u - m, a = p + (i - m), h = l * o / n * t, d = c * o / n * t; e.projectionMatrix.makePerspective(r, a, h, d, t, n), e.projectionMatrixInverse.copy(e.projectionMatrix).invert() } }(S, x, k) : S.projectionMatrix.copy(x.projectionMatrix), function(e, t, n) { null === n ? e.matrix.copy(t.matrixWorld) : (e.matrix.copy(n.matrixWorld), e.matrix.invert(), e.matrix.multiply(t.matrixWorld)); e.matrix.decompose(e.position, e.quaternion, e.scale), e.updateMatrixWorld(!0), e.projectionMatrix.copy(t.projectionMatrix), e.projectionMatrixInverse.copy(t.projectionMatrixInverse), e.isPerspectiveCamera && (e.fov = 2 * Ut * Math.atan(1 / e.projectionMatrix.elements[5]), e.zoom = 1) }(e, S, r) }, this.getCamera = function() { return S }, this.getFoveation = function() { if (null !== d || null !== u) return o }, this.setFoveation = function(e) { o = e, null !== d && (d.fixedFoveation = e), null !== u && void 0 !== u.fixedFoveation && (u.fixedFoveation = e) }, this.hasDepthSensing = function() { return null !== f.texture }, this.getDepthSensingMesh = function() { return f.getMesh(S) }; let D = null; const N = new fc; N.setAnimationLoop((function(t, r) { if (c = r.getViewerPose(l || a), p = r, null !== c) { const t = c.views; null !== u && (e.setRenderTargetFramebuffer(v, u.framebuffer), e.setRenderTarget(v)); let n = !1; t.length !== S.cameras.length && (S.cameras.length = 0, n = !0); for (let i = 0; i < t.length; i++) { const r = t[i]; let a = null; if (null !== u) a = u.getViewport(r); else { const t = h.getViewSubImage(d, r); a = t.viewport, 0 === i && (e.setRenderTargetTextures(v, t.colorTexture, d.ignoreDepthValues ? void 0 : t.depthStencilTexture), e.setRenderTarget(v)) } let s = E[i]; void 0 === s && (s = new Pr, s.layers.enable(i), s.viewport = new pn, E[i] = s), s.matrix.fromArray(r.transform.matrix), s.matrix.decompose(s.position, s.quaternion, s.scale), s.projectionMatrix.fromArray(r.projectionMatrix), s.projectionMatrixInverse.copy(s.projectionMatrix).invert(), s.viewport.set(a.x, a.y, a.width, a.height), 0 === i && (S.matrix.copy(s.matrix), S.matrix.decompose(S.position, S.quaternion, S.scale)), !0 === n && S.cameras.push(s) } const r = i.enabledFeatures; if (r && r.includes("depth-sensing") && "gpu-optimized" == i.depthUsage && h) { const n = h.getDepthInformation(t[0]); n && n.isValid && n.texture && f.init(e, n, i.renderState) } } for (let e = 0; e < w.length; e++) { const t = y[e], n = w[e]; null !== t && void 0 !== n && n.update(t, r, l || a) } D && D(t, r), r.detectedPlanes && n.dispatchEvent({ type: "planesdetected", data: r }), p = null })), this.setAnimationLoop = function(e) { D = e }, this.dispose = function() {} } } const Qd = new ai, Yd = new qn; function Kd(e, t) { function n(e, t) { !0 === e.matrixAutoUpdate && e.updateMatrix(), t.value.copy(e.matrix) } function i(e, i) { e.opacity.value = i.opacity, i.color && e.diffuse.value.copy(i.color), i.emissive && e.emissive.value.copy(i.emissive).multiplyScalar(i.emissiveIntensity), i.map && (e.map.value = i.map, n(i.map, e.mapTransform)), i.alphaMap && (e.alphaMap.value = i.alphaMap, n(i.alphaMap, e.alphaMapTransform)), i.bumpMap && (e.bumpMap.value = i.bumpMap, n(i.bumpMap, e.bumpMapTransform), e.bumpScale.value = i.bumpScale, 1 === i.side && (e.bumpScale.value *= -1)), i.normalMap && (e.normalMap.value = i.normalMap, n(i.normalMap, e.normalMapTransform), e.normalScale.value.copy(i.normalScale), 1 === i.side && e.normalScale.value.negate()), i.displacementMap && (e.displacementMap.value = i.displacementMap, n(i.displacementMap, e.displacementMapTransform), e.displacementScale.value = i.displacementScale, e.displacementBias.value = i.displacementBias), i.emissiveMap && (e.emissiveMap.value = i.emissiveMap, n(i.emissiveMap, e.emissiveMapTransform)), i.specularMap && (e.specularMap.value = i.specularMap, n(i.specularMap, e.specularMapTransform)), i.alphaTest > 0 && (e.alphaTest.value = i.alphaTest); const r = t.get(i), a = r.envMap, s = r.envMapRotation; a && (e.envMap.value = a, Qd.copy(s), Qd.x *= -1, Qd.y *= -1, Qd.z *= -1, a.isCubeTexture && !1 === a.isRenderTargetTexture && (Qd.y *= -1, Qd.z *= -1), e.envMapRotation.value.setFromMatrix4(Yd.makeRotationFromEuler(Qd)), e.flipEnvMap.value = a.isCubeTexture && !1 === a.isRenderTargetTexture ? -1 : 1, e.reflectivity.value = i.reflectivity, e.ior.value = i.ior, e.refractionRatio.value = i.refractionRatio), i.lightMap && (e.lightMap.value = i.lightMap, e.lightMapIntensity.value = i.lightMapIntensity, n(i.lightMap, e.lightMapTransform)), i.aoMap && (e.aoMap.value = i.aoMap, e.aoMapIntensity.value = i.aoMapIntensity, n(i.aoMap, e.aoMapTransform)) } return { refreshFogUniforms: function(t, n) { n.color.getRGB(t.fogColor.value, kr(e)), n.isFog ? (t.fogNear.value = n.near, t.fogFar.value = n.far) : n.isFogExp2 && (t.fogDensity.value = n.density) }, refreshMaterialUniforms: function(e, r, a, s, o) { r.isMeshBasicMaterial || r.isMeshLambertMaterial ? i(e, r) : r.isMeshToonMaterial ? (i(e, r), function(e, t) { t.gradientMap && (e.gradientMap.value = t.gradientMap) }(e, r)) : r.isMeshPhongMaterial ? (i(e, r), function(e, t) { e.specular.value.copy(t.specular), e.shininess.value = Math.max(t.shininess, 1e-4) }(e, r)) : r.isMeshStandardMaterial ? (i(e, r), function(e, t) { e.metalness.value = t.metalness, t.metalnessMap && (e.metalnessMap.value = t.metalnessMap, n(t.metalnessMap, e.metalnessMapTransform)); e.roughness.value = t.roughness, t.roughnessMap && (e.roughnessMap.value = t.roughnessMap, n(t.roughnessMap, e.roughnessMapTransform)); t.envMap && (e.envMapIntensity.value = t.envMapIntensity) }(e, r), r.isMeshPhysicalMaterial && function(e, t, i) { e.ior.value = t.ior, t.sheen > 0 && (e.sheenColor.value.copy(t.sheenColor).multiplyScalar(t.sheen), e.sheenRoughness.value = t.sheenRoughness, t.sheenColorMap && (e.sheenColorMap.value = t.sheenColorMap, n(t.sheenColorMap, e.sheenColorMapTransform)), t.sheenRoughnessMap && (e.sheenRoughnessMap.value = t.sheenRoughnessMap, n(t.sheenRoughnessMap, e.sheenRoughnessMapTransform))); t.clearcoat > 0 && (e.clearcoat.value = t.clearcoat, e.clearcoatRoughness.value = t.clearcoatRoughness, t.clearcoatMap && (e.clearcoatMap.value = t.clearcoatMap, n(t.clearcoatMap, e.clearcoatMapTransform)), t.clearcoatRoughnessMap && (e.clearcoatRoughnessMap.value = t.clearcoatRoughnessMap, n(t.clearcoatRoughnessMap, e.clearcoatRoughnessMapTransform)), t.clearcoatNormalMap && (e.clearcoatNormalMap.value = t.clearcoatNormalMap, n(t.clearcoatNormalMap, e.clearcoatNormalMapTransform), e.clearcoatNormalScale.value.copy(t.clearcoatNormalScale), 1 === t.side && e.clearcoatNormalScale.value.negate())); t.dispersion > 0 && (e.dispersion.value = t.dispersion); t.iridescence > 0 && (e.iridescence.value = t.iridescence, e.iridescenceIOR.value = t.iridescenceIOR, e.iridescenceThicknessMinimum.value = t.iridescenceThicknessRange[0], e.iridescenceThicknessMaximum.value = t.iridescenceThicknessRange[1], t.iridescenceMap && (e.iridescenceMap.value = t.iridescenceMap, n(t.iridescenceMap, e.iridescenceMapTransform)), t.iridescenceThicknessMap && (e.iridescenceThicknessMap.value = t.iridescenceThicknessMap, n(t.iridescenceThicknessMap, e.iridescenceThicknessMapTransform))); t.transmission > 0 && (e.transmission.value = t.transmission, e.transmissionSamplerMap.value = i.texture, e.transmissionSamplerSize.value.set(i.width, i.height), t.transmissionMap && (e.transmissionMap.value = t.transmissionMap, n(t.transmissionMap, e.transmissionMapTransform)), e.thickness.value = t.thickness, t.thicknessMap && (e.thicknessMap.value = t.thicknessMap, n(t.thicknessMap, e.thicknessMapTransform)), e.attenuationDistance.value = t.attenuationDistance, e.attenuationColor.value.copy(t.attenuationColor)); t.anisotropy > 0 && (e.anisotropyVector.value.set(t.anisotropy * Math.cos(t.anisotropyRotation), t.anisotropy * Math.sin(t.anisotropyRotation)), t.anisotropyMap && (e.anisotropyMap.value = t.anisotropyMap, n(t.anisotropyMap, e.anisotropyMapTransform))); e.specularIntensity.value = t.specularIntensity, e.specularColor.value.copy(t.specularColor), t.specularColorMap && (e.specularColorMap.value = t.specularColorMap, n(t.specularColorMap, e.specularColorMapTransform)); t.specularIntensityMap && (e.specularIntensityMap.value = t.specularIntensityMap, n(t.specularIntensityMap, e.specularIntensityMapTransform)) }(e, r, o)) : r.isMeshMatcapMaterial ? (i(e, r), function(e, t) { t.matcap && (e.matcap.value = t.matcap) }(e, r)) : r.isMeshDepthMaterial ? i(e, r) : r.isMeshDistanceMaterial ? (i(e, r), function(e, n) { const i = t.get(n).light; e.referencePosition.value.setFromMatrixPosition(i.matrixWorld), e.nearDistance.value = i.shadow.camera.near, e.farDistance.value = i.shadow.camera.far }(e, r)) : r.isMeshNormalMaterial ? i(e, r) : r.isLineBasicMaterial ? (function(e, t) { e.diffuse.value.copy(t.color), e.opacity.value = t.opacity, t.map && (e.map.value = t.map, n(t.map, e.mapTransform)) }(e, r), r.isLineDashedMaterial && function(e, t) { e.dashSize.value = t.dashSize, e.totalSize.value = t.dashSize + t.gapSize, e.scale.value = t.scale }(e, r)) : r.isPointsMaterial ? function(e, t, i, r) { e.diffuse.value.copy(t.color), e.opacity.value = t.opacity, e.size.value = t.size * i, e.scale.value = .5 * r, t.map && (e.map.value = t.map, n(t.map, e.uvTransform)); t.alphaMap && (e.alphaMap.value = t.alphaMap, n(t.alphaMap, e.alphaMapTransform)); t.alphaTest > 0 && (e.alphaTest.value = t.alphaTest) }(e, r, a, s) : r.isSpriteMaterial ? function(e, t) { e.diffuse.value.copy(t.color), e.opacity.value = t.opacity, e.rotation.value = t.rotation, t.map && (e.map.value = t.map, n(t.map, e.mapTransform)); t.alphaMap && (e.alphaMap.value = t.alphaMap, n(t.alphaMap, e.alphaMapTransform)); t.alphaTest > 0 && (e.alphaTest.value = t.alphaTest) }(e, r) : r.isShadowMaterial ? (e.color.value.copy(r.color), e.opacity.value = r.opacity) : r.isShaderMaterial && (r.uniformsNeedUpdate = !1) } } } function qd(e, t, n, i) { let r = {}, a = {}, s = []; const o = e.getParameter(e.MAX_UNIFORM_BUFFER_BINDINGS); function l(e, t, n, i) { const r = e.value, a = t + "_" + n; if (void 0 === i[a]) return i[a] = "number" == typeof r || "boolean" == typeof r ? r : r.clone(), !0; { const e = i[a]; if ("number" == typeof r || "boolean" == typeof r) { if (e !== r) return i[a] = r, !0 } else if (!1 === e.equals(r)) return e.copy(r), !0 } return !1 } function c(e) { const t = { boundary: 0, storage: 0 }; return "number" == typeof e || "boolean" == typeof e ? (t.boundary = 4, t.storage = 4) : e.isVector2 ? (t.boundary = 8, t.storage = 8) : e.isVector3 || e.isColor ? (t.boundary = 16, t.storage = 12) : e.isVector4 ? (t.boundary = 16, t.storage = 16) : e.isMatrix3 ? (t.boundary = 48, t.storage = 48) : e.isMatrix4 ? (t.boundary = 64, t.storage = 64) : e.isTexture ? console.warn("THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group.") : console.warn("THREE.WebGLRenderer: Unsupported uniform value type.", e), t } function h(t) { const n = t.target; n.removeEventListener("dispose", h); const i = s.indexOf(n.__bindingPointIndex); s.splice(i, 1), e.deleteBuffer(r[n.id]), delete r[n.id], delete a[n.id] } return { bind: function(e, t) { const n = t.program; i.uniformBlockBinding(e, n) }, update: function(n, d) { let u = r[n.id]; void 0 === u && (! function(e) { const t = e.uniforms; let n = 0; const i = 16; for (let e = 0, r = t.length; e < r; e++) { const r = Array.isArray(t[e]) ? t[e] : [t[e]]; for (let e = 0, t = r.length; e < t; e++) { const t = r[e], a = Array.isArray(t.value) ? t.value : [t.value]; for (let e = 0, r = a.length; e < r; e++) { const r = c(a[e]), s = n % i, o = s % r.boundary, l = s + o; n += o, 0 !== l && i - l < r.storage && (n += i - l), t.__data = new Float32Array(r.storage / Float32Array.BYTES_PER_ELEMENT), t.__offset = n, n += r.storage } } } const r = n % i; r > 0 && (n += i - r); e.__size = n, e.__cache = {} }(n), u = function(t) { const n = function() { for (let e = 0; e < o; e++) if (-1 === s.indexOf(e)) return s.push(e), e; return console.error("THREE.WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached."), 0 }(); t.__bindingPointIndex = n; const i = e.createBuffer(), r = t.__size, a = t.usage; return e.bindBuffer(e.UNIFORM_BUFFER, i), e.bufferData(e.UNIFORM_BUFFER, r, a), e.bindBuffer(e.UNIFORM_BUFFER, null), e.bindBufferBase(e.UNIFORM_BUFFER, n, i), i }(n), r[n.id] = u, n.addEventListener("dispose", h)); const p = d.program; i.updateUBOMapping(n, p); const f = t.render.frame; a[n.id] !== f && (! function(t) { const n = r[t.id], i = t.uniforms, a = t.__cache; e.bindBuffer(e.UNIFORM_BUFFER, n); for (let t = 0, n = i.length; t < n; t++) { const n = Array.isArray(i[t]) ? i[t] : [i[t]]; for (let i = 0, r = n.length; i < r; i++) { const r = n[i]; if (!0 === l(r, t, i, a)) { const t = r.__offset, n = Array.isArray(r.value) ? r.value : [r.value]; let i = 0; for (let a = 0; a < n.length; a++) { const s = n[a], o = c(s); "number" == typeof s || "boolean" == typeof s ? (r.__data[0] = s, e.bufferSubData(e.UNIFORM_BUFFER, t + i, r.__data)) : s.isMatrix3 ? (r.__data[0] = s.elements[0], r.__data[1] = s.elements[1], r.__data[2] = s.elements[2], r.__data[3] = 0, r.__data[4] = s.elements[3], r.__data[5] = s.elements[4], r.__data[6] = s.elements[5], r.__data[7] = 0, r.__data[8] = s.elements[6], r.__data[9] = s.elements[7], r.__data[10] = s.elements[8], r.__data[11] = 0) : (s.toArray(r.__data, i), i += o.storage / Float32Array.BYTES_PER_ELEMENT) } e.bufferSubData(e.UNIFORM_BUFFER, t, r.__data) } } } e.bindBuffer(e.UNIFORM_BUFFER, null) }(n), a[n.id] = f) }, dispose: function() { for (const t in r) e.deleteBuffer(r[t]); s = [], r = {}, a = {} } } } class Xd { constructor(e = {}) { const { canvas: t = Xt(), context: n = null, depth: i = !0, stencil: r = !1, alpha: a = !1, antialias: s = !1, premultipliedAlpha: o = !0, preserveDrawingBuffer: l = !1, powerPreference: c = "default", failIfMajorPerformanceCaveat: h = !1, reverseDepthBuffer: d = !1 } = e; let u; if (this.isWebGLRenderer = !0, null !== n) { if ("undefined" != typeof WebGLRenderingContext && n instanceof WebGLRenderingContext) throw new Error("THREE.WebGLRenderer: WebGL 1 is not supported since r163."); u = n.getContextAttributes().alpha } else u = a; const p = new Uint32Array(4), f = new Int32Array(4); let g = null, v = null; const w = [], y = []; this.domElement = t, this.debug = { checkShaderErrors: !0, onShaderError: null }, this.autoClear = !0, this.autoClearColor = !0, this.autoClearDepth = !0, this.autoClearStencil = !0, this.sortObjects = !0, this.clippingPlanes = [], this.localClippingEnabled = !1, this._outputColorSpace = gt, this.toneMapping = 0, this.toneMappingExposure = 1; const A = this; let b = !1, x = 0, k = 0, E = null, S = -1, M = null; const T = new pn, _ = new pn; let C = null; const P = new Wi(0); let I = 0, R = t.width, L = t.height, D = 1, N = null, B = null; const U = new pn(0, 0, R, L), z = new pn(0, 0, R, L); let O = !1; const F = new ya; let W = !1, V = !1; this.transmissionResolutionScale = 1; const H = new qn, G = new qn, j = new yn, Q = new pn, Y = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: !0 }; let K = !1; function q() { return null === E ? D : 1 } let X, Z, J, $, ee, te, ne, ie, re, ae, se, oe, le, ce, he, de, fe, me, ve, ye, Ee, Se, Me, Te, _e = n; function Re(e, n) { return t.getContext(e, n) } try { const e = { alpha: !0, depth: i, stencil: r, antialias: s, premultipliedAlpha: o, preserveDrawingBuffer: l, powerPreference: c, failIfMajorPerformanceCaveat: h }; if ("setAttribute" in t && t.setAttribute("data-engine", `three.js r${m}`), t.addEventListener("webglcontextlost", Ne, !1), t.addEventListener("webglcontextrestored", Be, !1), t.addEventListener("webglcontextcreationerror", Ue, !1), null === _e) { const t = "webgl2"; if (_e = Re(t, e), null === _e) throw Re(t) ? new Error("Error creating WebGL context with your selected attributes.") : new Error("Error creating WebGL context.") } } catch (e) { throw console.error("THREE.WebGLRenderer: " + e.message), e } function Le() { X = new Yc(_e), X.init(), Se = new Hd(_e, X), Z = new Sc(_e, X, e, Se), J = new Wd(_e, X), Z.reverseDepthBuffer && d && J.buffers.depth.setReversed(!0), $ = new Xc(_e), ee = new _d, te = new Vd(_e, X, J, ee, Z, Se, $), ne = new Tc(A), ie = new Qc(A), re = new mc(_e), Me = new kc(_e, re), ae = new Kc(_e, re, $, Me), se = new Jc(_e, ae, re, $), ve = new Zc(_e, Z, te), de = new Mc(ee), oe = new Td(A, ne, ie, X, Z, Me, de), le = new Kd(A, ee), ce = new Rd, he = new zd(X), me = new xc(A, ne, ie, J, se, u, o), fe = new Od(A, se, Z), Te = new qd(_e, $, Z, J), ye = new Ec(_e, X, $), Ee = new qc(_e, X, $), $.programs = oe.programs, A.capabilities = Z, A.extensions = X, A.properties = ee, A.renderLists = ce, A.shadowMap = fe, A.state = J, A.info = $ } Le(); const De = new jd(A, _e); function Ne(e) { e.preventDefault(), console.log("THREE.WebGLRenderer: Context Lost."), b = !0 } function Be() { console.log("THREE.WebGLRenderer: Context Restored."), b = !1; const e = $.autoReset, t = fe.enabled, n = fe.autoUpdate, i = fe.needsUpdate, r = fe.type; Le(), $.autoReset = e, fe.enabled = t, fe.autoUpdate = n, fe.needsUpdate = i, fe.type = r } function Ue(e) { console.error("THREE.WebGLRenderer: A WebGL context could not be created. Reason: ", e.statusMessage) } function ze(e) { const t = e.target; t.removeEventListener("dispose", ze), function(e) { (function(e) { const t = ee.get(e).programs; void 0 !== t && (t.forEach((function(e) { oe.releaseProgram(e) })), e.isShaderMaterial && oe.releaseShaderCache(e)) })(e), ee.remove(e) }(t) } function Oe(e, t, n) { !0 === e.transparent && 2 === e.side && !1 === e.forceSinglePass ? (e.side = 1, e.needsUpdate = !0, qe(e, t, n), e.side = 0, e.needsUpdate = !0, qe(e, t, n), e.side = 2) : qe(e, t, n) } this.xr = De, this.getContext = function() { return _e }, this.getContextAttributes = function() { return _e.getContextAttributes() }, this.forceContextLoss = function() { const e = X.get("WEBGL_lose_context"); e && e.loseContext() }, this.forceContextRestore = function() { const e = X.get("WEBGL_lose_context"); e && e.restoreContext() }, this.getPixelRatio = function() { return D }, this.setPixelRatio = function(e) { void 0 !== e && (D = e, this.setSize(R, L, !1)) }, this.getSize = function(e) { return e.set(R, L) }, this.setSize = function(e, n, i = !0) { De.isPresenting ? console.warn("THREE.WebGLRenderer: Can't change size while VR device is presenting.") : (R = e, L = n, t.width = Math.floor(e * D), t.height = Math.floor(n * D), !0 === i && (t.style.width = e + "px", t.style.height = n + "px"), this.setViewport(0, 0, e, n)) }, this.getDrawingBufferSize = function(e) { return e.set(R * D, L * D).floor() }, this.setDrawingBufferSize = function(e, n, i) { R = e, L = n, D = i, t.width = Math.floor(e * i), t.height = Math.floor(n * i), this.setViewport(0, 0, e, n) }, this.getCurrentViewport = function(e) { return e.copy(T) }, this.getViewport = function(e) { return e.copy(U) }, this.setViewport = function(e, t, n, i) { e.isVector4 ? U.set(e.x, e.y, e.z, e.w) : U.set(e, t, n, i), J.viewport(T.copy(U).multiplyScalar(D).round()) }, this.getScissor = function(e) { return e.copy(z) }, this.setScissor = function(e, t, n, i) { e.isVector4 ? z.set(e.x, e.y, e.z, e.w) : z.set(e, t, n, i), J.scissor(_.copy(z).multiplyScalar(D).round()) }, this.getScissorTest = function() { return O }, this.setScissorTest = function(e) { J.setScissorTest(O = e) }, this.setOpaqueSort = function(e) { N = e }, this.setTransparentSort = function(e) { B = e }, this.getClearColor = function(e) { return e.copy(me.getClearColor()) }, this.setClearColor = function() { me.setClearColor(...arguments) }, this.getClearAlpha = function() { return me.getClearAlpha() }, this.setClearAlpha = function() { me.setClearAlpha(...arguments) }, this.clear = function(e = !0, t = !0, n = !0) { let i = 0; if (e) { let e = !1; if (null !== E) { const t = E.texture.format; e = t === Ie || t === Pe || t === Ce } if (e) { const e = E.texture.type, t = e === pe || e === we || e === ge || e === ke || e === be || e === xe, n = me.getClearColor(), i = me.getClearAlpha(), r = n.r, a = n.g, s = n.b; t ? (p[0] = r, p[1] = a, p[2] = s, p[3] = i, _e.clearBufferuiv(_e.COLOR, 0, p)) : (f[0] = r, f[1] = a, f[2] = s, f[3] = i, _e.clearBufferiv(_e.COLOR, 0, f)) } else i |= _e.COLOR_BUFFER_BIT } t && (i |= _e.DEPTH_BUFFER_BIT), n && (i |= _e.STENCIL_BUFFER_BIT, this.state.buffers.stencil.setMask(4294967295)), _e.clear(i) }, this.clearColor = function() { this.clear(!0, !1, !1) }, this.clearDepth = function() { this.clear(!1, !0, !1) }, this.clearStencil = function() { this.clear(!1, !1, !0) }, this.dispose = function() { t.removeEventListener("webglcontextlost", Ne, !1), t.removeEventListener("webglcontextrestored", Be, !1), t.removeEventListener("webglcontextcreationerror", Ue, !1), me.dispose(), ce.dispose(), he.dispose(), ee.dispose(), ne.dispose(), ie.dispose(), se.dispose(), Me.dispose(), Te.dispose(), oe.dispose(), De.dispose(), De.removeEventListener("sessionstart", We), De.removeEventListener("sessionend", Ve), He.stop() }, this.renderBufferDirect = function(e, t, n, i, r, a) { null === t && (t = Y); const s = r.isMesh && r.matrixWorld.determinant() < 0, o = function(e, t, n, i, r) { !0 !== t.isScene && (t = Y); te.resetTextureUnits(); const a = t.fog, s = i.isMeshStandardMaterial ? t.environment : null, o = null === E ? A.outputColorSpace : !0 === E.isXRRenderTarget ? E.texture.colorSpace : vt, l = (i.isMeshStandardMaterial ? ie : ne).get(i.envMap || s), c = !0 === i.vertexColors && !!n.attributes.color && 4 === n.attributes.color.itemSize, h = !!n.attributes.tangent && (!!i.normalMap || i.anisotropy > 0), d = !!n.morphAttributes.position, u = !!n.morphAttributes.normal, p = !!n.morphAttributes.color; let f = 0; i.toneMapped && (null !== E && !0 !== E.isXRRenderTarget || (f = A.toneMapping)); const m = n.morphAttributes.position || n.morphAttributes.normal || n.morphAttributes.color, g = void 0 !== m ? m.length : 0, w = ee.get(i), y = v.state.lights; if (!0 === W && (!0 === V || e !== M)) { const t = e === M && i.id === S; de.setState(i, e, t) } let b = !1; i.version === w.__version ? w.needsLights && w.lightsStateVersion !== y.state.version || w.outputColorSpace !== o || r.isBatchedMesh && !1 === w.batching ? b = !0 : r.isBatchedMesh || !0 !== w.batching ? r.isBatchedMesh && !0 === w.batchingColor && null === r.colorTexture || r.isBatchedMesh && !1 === w.batchingColor && null !== r.colorTexture || r.isInstancedMesh && !1 === w.instancing ? b = !0 : r.isInstancedMesh || !0 !== w.instancing ? r.isSkinnedMesh && !1 === w.skinning ? b = !0 : r.isSkinnedMesh || !0 !== w.skinning ? r.isInstancedMesh && !0 === w.instancingColor && null === r.instanceColor || r.isInstancedMesh && !1 === w.instancingColor && null !== r.instanceColor || r.isInstancedMesh && !0 === w.instancingMorph && null === r.morphTexture || r.isInstancedMesh && !1 === w.instancingMorph && null !== r.morphTexture || w.envMap !== l || !0 === i.fog && w.fog !== a ? b = !0 : void 0 === w.numClippingPlanes || w.numClippingPlanes === de.numPlanes && w.numIntersection === de.numIntersection ? (w.vertexAlphas !== c || w.vertexTangents !== h || w.morphTargets !== d || w.morphNormals !== u || w.morphColors !== p || w.toneMapping !== f || w.morphTargetsCount !== g) && (b = !0) : b = !0 : b = !0 : b = !0 : b = !0 : (b = !0, w.__version = i.version); let x = w.currentProgram; !0 === b && (x = qe(i, t, r)); let k = !1, T = !1, _ = !1; const C = x.getUniforms(), P = w.uniforms; J.useProgram(x.program) && (k = !0, T = !0, _ = !0); i.id !== S && (S = i.id, T = !0); if (k || M !== e) { J.buffers.depth.getReversed() ? (H.copy(e.projectionMatrix), function(e) { const t = e.elements; t[2] = .5 * t[2] + .5 * t[3], t[6] = .5 * t[6] + .5 * t[7], t[10] = .5 * t[10] + .5 * t[11], t[14] = .5 * t[14] + .5 * t[15] }(H), function(e) { const t = e.elements; - 1 === t[11] ? (t[10] = -t[10] - 1, t[14] = -t[14]) : (t[10] = -t[10], t[14] = 1 - t[14]) }(H), C.setValue(_e, "projectionMatrix", H)) : C.setValue(_e, "projectionMatrix", e.projectionMatrix), C.setValue(_e, "viewMatrix", e.matrixWorldInverse); const t = C.map.cameraPosition; void 0 !== t && t.setValue(_e, j.setFromMatrixPosition(e.matrixWorld)), Z.logarithmicDepthBuffer && C.setValue(_e, "logDepthBufFC", 2 / (Math.log(e.far + 1) / Math.LN2)), (i.isMeshPhongMaterial || i.isMeshToonMaterial || i.isMeshLambertMaterial || i.isMeshBasicMaterial || i.isMeshStandardMaterial || i.isShaderMaterial) && C.setValue(_e, "isOrthographic", !0 === e.isOrthographicCamera), M !== e && (M = e, T = !0, _ = !0) } if (r.isSkinnedMesh) { C.setOptional(_e, r, "bindMatrix"), C.setOptional(_e, r, "bindMatrixInverse"); const e = r.skeleton; e && (null === e.boneTexture && e.computeBoneTexture(), C.setValue(_e, "boneTexture", e.boneTexture, te)) } r.isBatchedMesh && (C.setOptional(_e, r, "batchingTexture"), C.setValue(_e, "batchingTexture", r._matricesTexture, te), C.setOptional(_e, r, "batchingIdTexture"), C.setValue(_e, "batchingIdTexture", r._indirectTexture, te), C.setOptional(_e, r, "batchingColorTexture"), null !== r._colorsTexture && C.setValue(_e, "batchingColorTexture", r._colorsTexture, te)); const I = n.morphAttributes; void 0 === I.position && void 0 === I.normal && void 0 === I.color || ve.update(r, n, x); (T || w.receiveShadow !== r.receiveShadow) && (w.receiveShadow = r.receiveShadow, C.setValue(_e, "receiveShadow", r.receiveShadow)); i.isMeshGouraudMaterial && null !== i.envMap && (P.envMap.value = l, P.flipEnvMap.value = l.isCubeTexture && !1 === l.isRenderTargetTexture ? -1 : 1); i.isMeshStandardMaterial && null === i.envMap && null !== t.environment && (P.envMapIntensity.value = t.environmentIntensity); T && (C.setValue(_e, "toneMappingExposure", A.toneMappingExposure), w.needsLights && (N = _, (R = P).ambientLightColor.needsUpdate = N, R.lightProbe.needsUpdate = N, R.directionalLights.needsUpdate = N, R.directionalLightShadows.needsUpdate = N, R.pointLights.needsUpdate = N, R.pointLightShadows.needsUpdate = N, R.spotLights.needsUpdate = N, R.spotLightShadows.needsUpdate = N, R.rectAreaLights.needsUpdate = N, R.hemisphereLights.needsUpdate = N), a && !0 === i.fog && le.refreshFogUniforms(P, a), le.refreshMaterialUniforms(P, i, D, L, v.state.transmissionRenderTarget[e.id]), id.upload(_e, Xe(w), P, te)); var R, N; i.isShaderMaterial && !0 === i.uniformsNeedUpdate && (id.upload(_e, Xe(w), P, te), i.uniformsNeedUpdate = !1); i.isSpriteMaterial && C.setValue(_e, "center", r.center); if (C.setValue(_e, "modelViewMatrix", r.modelViewMatrix), C.setValue(_e, "normalMatrix", r.normalMatrix), C.setValue(_e, "modelMatrix", r.matrixWorld), i.isShaderMaterial || i.isRawShaderMaterial) { const e = i.uniformsGroups; for (let t = 0, n = e.length; t < n; t++) { const n = e[t]; Te.update(n, x), Te.bind(n, x) } } return x }(e, t, n, i, r); J.setMaterial(i, s); let l = n.index, c = 1; if (!0 === i.wireframe) { if (l = ae.getWireframeAttribute(n), void 0 === l) return; c = 2 } const h = n.drawRange, d = n.attributes.position; let u = h.start * c, p = (h.start + h.count) * c; null !== a && (u = Math.max(u, a.start * c), p = Math.min(p, (a.start + a.count) * c)), null !== l ? (u = Math.max(u, 0), p = Math.min(p, l.count)) : null != d && (u = Math.max(u, 0), p = Math.min(p, d.count)); const f = p - u; if (f < 0 || f === 1 / 0) return; let m; Me.setup(r, i, o, n, l); let g = ye; if (null !== l && (m = re.get(l), g = Ee, g.setIndex(m)), r.isMesh) !0 === i.wireframe ? (J.setLineWidth(i.wireframeLinewidth * q()), g.setMode(_e.LINES)) : g.setMode(_e.TRIANGLES); else if (r.isLine) { let e = i.linewidth; void 0 === e && (e = 1), J.setLineWidth(e * q()), r.isLineSegments ? g.setMode(_e.LINES) : r.isLineLoop ? g.setMode(_e.LINE_LOOP) : g.setMode(_e.LINE_STRIP) } else r.isPoints ? g.setMode(_e.POINTS) : r.isSprite && g.setMode(_e.TRIANGLES); if (r.isBatchedMesh) if (null !== r._multiDrawInstances) Jt("THREE.WebGLRenderer: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection."), g.renderMultiDrawInstances(r._multiDrawStarts, r._multiDrawCounts, r._multiDrawCount, r._multiDrawInstances); else if (X.get("WEBGL_multi_draw")) g.renderMultiDraw(r._multiDrawStarts, r._multiDrawCounts, r._multiDrawCount); else { const e = r._multiDrawStarts, t = r._multiDrawCounts, n = r._multiDrawCount, a = l ? re.get(l).bytesPerElement : 1, s = ee.get(i).currentProgram.getUniforms(); for (let i = 0; i < n; i++) s.setValue(_e, "_gl_DrawID", i), g.render(e[i] / a, t[i]) } else if (r.isInstancedMesh) g.renderInstances(u, f, r.count); else if (n.isInstancedBufferGeometry) { const e = void 0 !== n._maxInstanceCount ? n._maxInstanceCount : 1 / 0, t = Math.min(n.instanceCount, e); g.renderInstances(u, f, t) } else g.render(u, f) }, this.compile = function(e, t, n = null) { null === n && (n = e), v = he.get(n), v.init(t), y.push(v), n.traverseVisible((function(e) { e.isLight && e.layers.test(t.layers) && (v.pushLight(e), e.castShadow && v.pushShadow(e)) })), e !== n && e.traverseVisible((function(e) { e.isLight && e.layers.test(t.layers) && (v.pushLight(e), e.castShadow && v.pushShadow(e)) })), v.setupLights(); const i = new Set; return e.traverse((function(e) { if (!(e.isMesh || e.isPoints || e.isLine || e.isSprite)) return; const t = e.material; if (t) if (Array.isArray(t)) for (let r = 0; r < t.length; r++) { const a = t[r]; Oe(a, n, e), i.add(a) } else Oe(t, n, e), i.add(t) })), v = y.pop(), i }, this.compileAsync = function(e, t, n = null) { const i = this.compile(e, t, n); return new Promise((t => { function n() { i.forEach((function(e) { ee.get(e).currentProgram.isReady() && i.delete(e) })), 0 !== i.size ? setTimeout(n, 10) : t(e) } null !== X.get("KHR_parallel_shader_compile") ? n() : setTimeout(n, 10) })) }; let Fe = null; function We() { He.stop() } function Ve() { He.start() } const He = new fc; function Ge(e, t, n, i) { if (!1 === e.visible) return; if (e.layers.test(t.layers)) if (e.isGroup) n = e.renderOrder; else if (e.isLOD) !0 === e.autoUpdate && e.update(t); else if (e.isLight) v.pushLight(e), e.castShadow && v.pushShadow(e); else if (e.isSprite) { if (!e.frustumCulled || F.intersectsSprite(e)) { i && Q.setFromMatrixPosition(e.matrixWorld).applyMatrix4(G); const t = se.update(e), r = e.material; r.visible && g.push(e, t, r, n, Q.z, null) } } else if ((e.isMesh || e.isLine || e.isPoints) && (!e.frustumCulled || F.intersectsObject(e))) { const t = se.update(e), r = e.material; if (i && (void 0 !== e.boundingSphere ? (null === e.boundingSphere && e.computeBoundingSphere(), Q.copy(e.boundingSphere.center)) : (null === t.boundingSphere && t.computeBoundingSphere(), Q.copy(t.boundingSphere.center)), Q.applyMatrix4(e.matrixWorld).applyMatrix4(G)), Array.isArray(r)) { const i = t.groups; for (let a = 0, s = i.length; a < s; a++) { const s = i[a], o = r[s.materialIndex]; o && o.visible && g.push(e, t, o, n, Q.z, s) } } else r.visible && g.push(e, t, r, n, Q.z, null) } const r = e.children; for (let e = 0, a = r.length; e < a; e++) Ge(r[e], t, n, i) } function je(e, t, n, i) { const r = e.opaque, a = e.transmissive, s = e.transparent; v.setupLightsView(n), !0 === W && de.setGlobalState(A.clippingPlanes, n), i && J.viewport(T.copy(i)), r.length > 0 && Ye(r, t, n), a.length > 0 && Ye(a, t, n), s.length > 0 && Ye(s, t, n), J.buffers.depth.setTest(!0), J.buffers.depth.setMask(!0), J.buffers.color.setMask(!0), J.setPolygonOffset(!1) } function Qe(e, t, n, i) { if (null !== (!0 === n.isScene ? n.overrideMaterial : null)) return; void 0 === v.state.transmissionRenderTarget[i.id] && (v.state.transmissionRenderTarget[i.id] = new mn(1, 1, { generateMipmaps: !0, type: X.has("EXT_color_buffer_half_float") || X.has("EXT_color_buffer_float") ? Ae : pe, minFilter: ue, samples: 4, stencilBuffer: r, resolveDepthBuffer: !1, resolveStencilBuffer: !1, colorSpace: nn.workingColorSpace })); const a = v.state.transmissionRenderTarget[i.id], s = i.viewport || T; a.setSize(s.z * A.transmissionResolutionScale, s.w * A.transmissionResolutionScale); const o = A.getRenderTarget(); A.setRenderTarget(a), A.getClearColor(P), I = A.getClearAlpha(), I < 1 && A.setClearColor(16777215, .5), A.clear(), K && me.render(n); const l = A.toneMapping; A.toneMapping = 0; const c = i.viewport; if (void 0 !== i.viewport && (i.viewport = void 0), v.setupLightsView(i), !0 === W && de.setGlobalState(A.clippingPlanes, i), Ye(e, n, i), te.updateMultisampleRenderTarget(a), te.updateRenderTargetMipmap(a), !1 === X.has("WEBGL_multisampled_render_to_texture")) { let e = !1; for (let r = 0, a = t.length; r < a; r++) { const a = t[r], s = a.object, o = a.geometry, l = a.material, c = a.group; if (2 === l.side && s.layers.test(i.layers)) { const t = l.side; l.side = 1, l.needsUpdate = !0, Ke(s, n, i, o, l, c), l.side = t, l.needsUpdate = !0, e = !0 } }!0 === e && (te.updateMultisampleRenderTarget(a), te.updateRenderTargetMipmap(a)) } A.setRenderTarget(o), A.setClearColor(P, I), void 0 !== c && (i.viewport = c), A.toneMapping = l } function Ye(e, t, n) { const i = !0 === t.isScene ? t.overrideMaterial : null; for (let r = 0, a = e.length; r < a; r++) { const a = e[r], s = a.object, o = a.geometry, l = null === i ? a.material : i, c = a.group; s.layers.test(n.layers) && Ke(s, t, n, o, l, c) } } function Ke(e, t, n, i, r, a) { e.onBeforeRender(A, t, n, i, r, a), e.modelViewMatrix.multiplyMatrices(n.matrixWorldInverse, e.matrixWorld), e.normalMatrix.getNormalMatrix(e.modelViewMatrix), r.onBeforeRender(A, t, n, i, e, a), !0 === r.transparent && 2 === r.side && !1 === r.forceSinglePass ? (r.side = 1, r.needsUpdate = !0, A.renderBufferDirect(n, t, i, r, e, a), r.side = 0, r.needsUpdate = !0, A.renderBufferDirect(n, t, i, r, e, a), r.side = 2) : A.renderBufferDirect(n, t, i, r, e, a), e.onAfterRender(A, t, n, i, r, a) } function qe(e, t, n) { !0 !== t.isScene && (t = Y); const i = ee.get(e), r = v.state.lights, a = v.state.shadowsArray, s = r.state.version, o = oe.getParameters(e, r.state, a, t, n), l = oe.getProgramCacheKey(o); let c = i.programs; i.environment = e.isMeshStandardMaterial ? t.environment : null, i.fog = t.fog, i.envMap = (e.isMeshStandardMaterial ? ie : ne).get(e.envMap || i.environment), i.envMapRotation = null !== i.environment && null === e.envMap ? t.environmentRotation : e.envMapRotation, void 0 === c && (e.addEventListener("dispose", ze), c = new Map, i.programs = c); let h = c.get(l); if (void 0 !== h) { if (i.currentProgram === h && i.lightsStateVersion === s) return Ze(e, o), h } else o.uniforms = oe.getUniforms(e), e.onBeforeCompile(o, A), h = oe.acquireProgram(o, l), c.set(l, h), i.uniforms = o.uniforms; const d = i.uniforms; return (e.isShaderMaterial || e.isRawShaderMaterial) && !0 !== e.clipping || (d.clippingPlanes = de.uniform), Ze(e, o), i.needsLights = function(e) { return e.isMeshLambertMaterial || e.isMeshToonMaterial || e.isMeshPhongMaterial || e.isMeshStandardMaterial || e.isShadowMaterial || e.isShaderMaterial && !0 === e.lights }(e), i.lightsStateVersion = s, i.needsLights && (d.ambientLightColor.value = r.state.ambient, d.lightProbe.value = r.state.probe, d.directionalLights.value = r.state.directional, d.directionalLightShadows.value = r.state.directionalShadow, d.spotLights.value = r.state.spot, d.spotLightShadows.value = r.state.spotShadow, d.rectAreaLights.value = r.state.rectArea, d.ltc_1.value = r.state.rectAreaLTC1, d.ltc_2.value = r.state.rectAreaLTC2, d.pointLights.value = r.state.point, d.pointLightShadows.value = r.state.pointShadow, d.hemisphereLights.value = r.state.hemi, d.directionalShadowMap.value = r.state.directionalShadowMap, d.directionalShadowMatrix.value = r.state.directionalShadowMatrix, d.spotShadowMap.value = r.state.spotShadowMap, d.spotLightMatrix.value = r.state.spotLightMatrix, d.spotLightMap.value = r.state.spotLightMap, d.pointShadowMap.value = r.state.pointShadowMap, d.pointShadowMatrix.value = r.state.pointShadowMatrix), i.currentProgram = h, i.uniformsList = null, h } function Xe(e) { if (null === e.uniformsList) { const t = e.currentProgram.getUniforms(); e.uniformsList = id.seqWithValue(t.seq, e.uniforms) } return e.uniformsList } function Ze(e, t) { const n = ee.get(e); n.outputColorSpace = t.outputColorSpace, n.batching = t.batching, n.batchingColor = t.batchingColor, n.instancing = t.instancing, n.instancingColor = t.instancingColor, n.instancingMorph = t.instancingMorph, n.skinning = t.skinning, n.morphTargets = t.morphTargets, n.morphNormals = t.morphNormals, n.morphColors = t.morphColors, n.morphTargetsCount = t.morphTargetsCount, n.numClippingPlanes = t.numClippingPlanes, n.numIntersection = t.numClipIntersection, n.vertexAlphas = t.vertexAlphas, n.vertexTangents = t.vertexTangents, n.toneMapping = t.toneMapping } He.setAnimationLoop((function(e) { Fe && Fe(e) })), "undefined" != typeof self && He.setContext(self), this.setAnimationLoop = function(e) { Fe = e, De.setAnimationLoop(e), null === e ? He.stop() : He.start() }, De.addEventListener("sessionstart", We), De.addEventListener("sessionend", Ve), this.render = function(e, t) { if (void 0 !== t && !0 !== t.isCamera) return void console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera."); if (!0 === b) return; if (!0 === e.matrixWorldAutoUpdate && e.updateMatrixWorld(), null === t.parent && !0 === t.matrixWorldAutoUpdate && t.updateMatrixWorld(), !0 === De.enabled && !0 === De.isPresenting && (!0 === De.cameraAutoUpdate && De.updateCamera(t), t = De.getCamera()), !0 === e.isScene && e.onBeforeRender(A, e, t, E), v = he.get(e, y.length), v.init(t), y.push(v), G.multiplyMatrices(t.projectionMatrix, t.matrixWorldInverse), F.setFromProjectionMatrix(G), V = this.localClippingEnabled, W = de.init(this.clippingPlanes, V), g = ce.get(e, w.length), g.init(), w.push(g), !0 === De.enabled && !0 === De.isPresenting) { const e = A.xr.getDepthSensingMesh(); null !== e && Ge(e, t, -1 / 0, A.sortObjects) } Ge(e, t, 0, A.sortObjects), g.finish(), !0 === A.sortObjects && g.sort(N, B), K = !1 === De.enabled || !1 === De.isPresenting || !1 === De.hasDepthSensing(), K && me.addToRenderList(g, e), this.info.render.frame++, !0 === W && de.beginShadows(); const n = v.state.shadowsArray; fe.render(n, e, t), !0 === W && de.endShadows(), !0 === this.info.autoReset && this.info.reset(); const i = g.opaque, r = g.transmissive; if (v.setupLights(), t.isArrayCamera) { const n = t.cameras; if (r.length > 0) for (let t = 0, a = n.length; t < a; t++) { Qe(i, r, e, n[t]) } K && me.render(e); for (let t = 0, i = n.length; t < i; t++) { const i = n[t]; je(g, e, i, i.viewport) } } else r.length > 0 && Qe(i, r, e, t), K && me.render(e), je(g, e, t); null !== E && 0 === k && (te.updateMultisampleRenderTarget(E), te.updateRenderTargetMipmap(E)), !0 === e.isScene && e.onAfterRender(A, e, t), Me.resetDefaultState(), S = -1, M = null, y.pop(), y.length > 0 ? (v = y[y.length - 1], !0 === W && de.setGlobalState(A.clippingPlanes, v.state.camera)) : v = null, w.pop(), g = w.length > 0 ? w[w.length - 1] : null }, this.getActiveCubeFace = function() { return x }, this.getActiveMipmapLevel = function() { return k }, this.getRenderTarget = function() { return E }, this.setRenderTargetTextures = function(e, t, n) { ee.get(e.texture).__webglTexture = t, ee.get(e.depthTexture).__webglTexture = n; const i = ee.get(e); i.__hasExternalTextures = !0, i.__autoAllocateDepthBuffer = void 0 === n, i.__autoAllocateDepthBuffer || !0 === X.has("WEBGL_multisampled_render_to_texture") && (console.warn("THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided"), i.__useRenderToTexture = !1) }, this.setRenderTargetFramebuffer = function(e, t) { const n = ee.get(e); n.__webglFramebuffer = t, n.__useDefaultFramebuffer = void 0 === t }; const Je = _e.createFramebuffer(); this.setRenderTarget = function(e, t = 0, n = 0) { E = e, x = t, k = n; let i = !0, r = null, a = !1, s = !1; if (e) { const o = ee.get(e); if (void 0 !== o.__useDefaultFramebuffer) J.bindFramebuffer(_e.FRAMEBUFFER, null), i = !1; else if (void 0 === o.__webglFramebuffer) te.setupRenderTarget(e); else if (o.__hasExternalTextures) te.rebindTextures(e, ee.get(e.texture).__webglTexture, ee.get(e.depthTexture).__webglTexture); else if (e.depthBuffer) { const t = e.depthTexture; if (o.__boundDepthTexture !== t) { if (null !== t && ee.has(t) && (e.width !== t.image.width || e.height !== t.image.height)) throw new Error("WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size."); te.setupDepthRenderbuffer(e) } } const l = e.texture; (l.isData3DTexture || l.isDataArrayTexture || l.isCompressedArrayTexture) && (s = !0); const c = ee.get(e).__webglFramebuffer; e.isWebGLCubeRenderTarget ? (r = Array.isArray(c[t]) ? c[t][n] : c[t], a = !0) : r = e.samples > 0 && !1 === te.useMultisampledRTT(e) ? ee.get(e).__webglMultisampledFramebuffer : Array.isArray(c) ? c[n] : c, T.copy(e.viewport), _.copy(e.scissor), C = e.scissorTest } else T.copy(U).multiplyScalar(D).floor(), _.copy(z).multiplyScalar(D).floor(), C = O; 0 !== n && (r = Je); if (J.bindFramebuffer(_e.FRAMEBUFFER, r) && i && J.drawBuffers(e, r), J.viewport(T), J.scissor(_), J.setScissorTest(C), a) { const i = ee.get(e.texture); _e.framebufferTexture2D(_e.FRAMEBUFFER, _e.COLOR_ATTACHMENT0, _e.TEXTURE_CUBE_MAP_POSITIVE_X + t, i.__webglTexture, n) } else if (s) { const i = ee.get(e.texture), r = t; _e.framebufferTextureLayer(_e.FRAMEBUFFER, _e.COLOR_ATTACHMENT0, i.__webglTexture, n, r) } else if (null !== e && 0 !== n) { const t = ee.get(e.texture); _e.framebufferTexture2D(_e.FRAMEBUFFER, _e.COLOR_ATTACHMENT0, _e.TEXTURE_2D, t.__webglTexture, n) } S = -1 }, this.readRenderTargetPixels = function(e, t, n, i, r, a, s) { if (!e || !e.isWebGLRenderTarget) return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); let o = ee.get(e).__webglFramebuffer; if (e.isWebGLCubeRenderTarget && void 0 !== s && (o = o[s]), o) { J.bindFramebuffer(_e.FRAMEBUFFER, o); try { const s = e.texture, o = s.format, l = s.type; if (!Z.textureFormatReadable(o)) return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."); if (!Z.textureTypeReadable(l)) return void console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type."); t >= 0 && t <= e.width - i && n >= 0 && n <= e.height - r && _e.readPixels(t, n, i, r, Se.convert(o), Se.convert(l), a) } finally { const e = null !== E ? ee.get(E).__webglFramebuffer : null; J.bindFramebuffer(_e.FRAMEBUFFER, e) } } }, this.readRenderTargetPixelsAsync = async function(e, t, n, i, r, a, s) { if (!e || !e.isWebGLRenderTarget) throw new Error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); let o = ee.get(e).__webglFramebuffer; if (e.isWebGLCubeRenderTarget && void 0 !== s && (o = o[s]), o) { const s = e.texture, l = s.format, c = s.type; if (!Z.textureFormatReadable(l)) throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format."); if (!Z.textureTypeReadable(c)) throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type."); if (t >= 0 && t <= e.width - i && n >= 0 && n <= e.height - r) { J.bindFramebuffer(_e.FRAMEBUFFER, o); const e = _e.createBuffer(); _e.bindBuffer(_e.PIXEL_PACK_BUFFER, e), _e.bufferData(_e.PIXEL_PACK_BUFFER, a.byteLength, _e.STREAM_READ), _e.readPixels(t, n, i, r, Se.convert(l), Se.convert(c), 0); const s = null !== E ? ee.get(E).__webglFramebuffer : null; J.bindFramebuffer(_e.FRAMEBUFFER, s); const h = _e.fenceSync(_e.SYNC_GPU_COMMANDS_COMPLETE, 0); return _e.flush(), await function(e, t, n) { return new Promise((function(i, r) { setTimeout((function a() { switch (e.clientWaitSync(t, e.SYNC_FLUSH_COMMANDS_BIT, 0)) { case e.WAIT_FAILED: r(); break; case e.TIMEOUT_EXPIRED: setTimeout(a, n); break; default: i() } }), n) })) }(_e, h, 4), _e.bindBuffer(_e.PIXEL_PACK_BUFFER, e), _e.getBufferSubData(_e.PIXEL_PACK_BUFFER, 0, a), _e.deleteBuffer(e), _e.deleteSync(h), a } throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range.") } }, this.copyFramebufferToTexture = function(e, t = null, n = 0) { !0 !== e.isTexture && (Jt("WebGLRenderer: copyFramebufferToTexture function signature has changed."), t = arguments[0] || null, e = arguments[1]); const i = Math.pow(2, -n), r = Math.floor(e.image.width * i), a = Math.floor(e.image.height * i), s = null !== t ? t.x : 0, o = null !== t ? t.y : 0; te.setTexture2D(e, 0), _e.copyTexSubImage2D(_e.TEXTURE_2D, n, 0, 0, s, o, r, a), J.unbindTexture() }; const $e = _e.createFramebuffer(), et = _e.createFramebuffer(); this.copyTextureToTexture = function(e, t, n = null, i = null, r = 0, a = null) { let s, o, l, c, h, d, u, p, f; !0 !== e.isTexture && (Jt("WebGLRenderer: copyTextureToTexture function signature has changed."), i = arguments[0] || null, e = arguments[1], t = arguments[2], a = arguments[3] || 0, n = null), null === a && (0 !== r ? (Jt("WebGLRenderer: copyTextureToTexture function signature has changed to support src and dst mipmap levels."), a = r, r = 0) : a = 0); const m = e.isCompressedTexture ? e.mipmaps[a] : e.image; if (null !== n) s = n.max.x - n.min.x, o = n.max.y - n.min.y, l = n.isBox3 ? n.max.z - n.min.z : 1, c = n.min.x, h = n.min.y, d = n.isBox3 ? n.min.z : 0; else { const t = Math.pow(2, -r); s = Math.floor(m.width * t), o = Math.floor(m.height * t), l = e.isDataArrayTexture ? m.depth : e.isData3DTexture ? Math.floor(m.depth * t) : 1, c = 0, h = 0, d = 0 } null !== i ? (u = i.x, p = i.y, f = i.z) : (u = 0, p = 0, f = 0); const g = Se.convert(t.format), v = Se.convert(t.type); let w; t.isData3DTexture ? (te.setTexture3D(t, 0), w = _e.TEXTURE_3D) : t.isDataArrayTexture || t.isCompressedArrayTexture ? (te.setTexture2DArray(t, 0), w = _e.TEXTURE_2D_ARRAY) : (te.setTexture2D(t, 0), w = _e.TEXTURE_2D), _e.pixelStorei(_e.UNPACK_FLIP_Y_WEBGL, t.flipY), _e.pixelStorei(_e.UNPACK_PREMULTIPLY_ALPHA_WEBGL, t.premultiplyAlpha), _e.pixelStorei(_e.UNPACK_ALIGNMENT, t.unpackAlignment); const y = _e.getParameter(_e.UNPACK_ROW_LENGTH), A = _e.getParameter(_e.UNPACK_IMAGE_HEIGHT), b = _e.getParameter(_e.UNPACK_SKIP_PIXELS), x = _e.getParameter(_e.UNPACK_SKIP_ROWS), k = _e.getParameter(_e.UNPACK_SKIP_IMAGES); _e.pixelStorei(_e.UNPACK_ROW_LENGTH, m.width), _e.pixelStorei(_e.UNPACK_IMAGE_HEIGHT, m.height), _e.pixelStorei(_e.UNPACK_SKIP_PIXELS, c), _e.pixelStorei(_e.UNPACK_SKIP_ROWS, h), _e.pixelStorei(_e.UNPACK_SKIP_IMAGES, d); const E = e.isDataArrayTexture || e.isData3DTexture, S = t.isDataArrayTexture || t.isData3DTexture; if (e.isDepthTexture) { const n = ee.get(e), i = ee.get(t), m = ee.get(n.__renderTarget), g = ee.get(i.__renderTarget); J.bindFramebuffer(_e.READ_FRAMEBUFFER, m.__webglFramebuffer), J.bindFramebuffer(_e.DRAW_FRAMEBUFFER, g.__webglFramebuffer); for (let n = 0; n < l; n++) E && (_e.framebufferTextureLayer(_e.READ_FRAMEBUFFER, _e.COLOR_ATTACHMENT0, ee.get(e).__webglTexture, r, d + n), _e.framebufferTextureLayer(_e.DRAW_FRAMEBUFFER, _e.COLOR_ATTACHMENT0, ee.get(t).__webglTexture, a, f + n)), _e.blitFramebuffer(c, h, s, o, u, p, s, o, _e.DEPTH_BUFFER_BIT, _e.NEAREST); J.bindFramebuffer(_e.READ_FRAMEBUFFER, null), J.bindFramebuffer(_e.DRAW_FRAMEBUFFER, null) } else if (0 !== r || e.isRenderTargetTexture || ee.has(e)) { const n = ee.get(e), i = ee.get(t); J.bindFramebuffer(_e.READ_FRAMEBUFFER, $e), J.bindFramebuffer(_e.DRAW_FRAMEBUFFER, et); for (let e = 0; e < l; e++) E ? _e.framebufferTextureLayer(_e.READ_FRAMEBUFFER, _e.COLOR_ATTACHMENT0, n.__webglTexture, r, d + e) : _e.framebufferTexture2D(_e.READ_FRAMEBUFFER, _e.COLOR_ATTACHMENT0, _e.TEXTURE_2D, n.__webglTexture, r), S ? _e.framebufferTextureLayer(_e.DRAW_FRAMEBUFFER, _e.COLOR_ATTACHMENT0, i.__webglTexture, a, f + e) : _e.framebufferTexture2D(_e.DRAW_FRAMEBUFFER, _e.COLOR_ATTACHMENT0, _e.TEXTURE_2D, i.__webglTexture, a), 0 !== r ? _e.blitFramebuffer(c, h, s, o, u, p, s, o, _e.COLOR_BUFFER_BIT, _e.NEAREST) : S ? _e.copyTexSubImage3D(w, a, u, p, f + e, c, h, s, o) : _e.copyTexSubImage2D(w, a, u, p, c, h, s, o); J.bindFramebuffer(_e.READ_FRAMEBUFFER, null), J.bindFramebuffer(_e.DRAW_FRAMEBUFFER, null) } else S ? e.isDataTexture || e.isData3DTexture ? _e.texSubImage3D(w, a, u, p, f, s, o, l, g, v, m.data) : t.isCompressedArrayTexture ? _e.compressedTexSubImage3D(w, a, u, p, f, s, o, l, g, m.data) : _e.texSubImage3D(w, a, u, p, f, s, o, l, g, v, m) : e.isDataTexture ? _e.texSubImage2D(_e.TEXTURE_2D, a, u, p, s, o, g, v, m.data) : e.isCompressedTexture ? _e.compressedTexSubImage2D(_e.TEXTURE_2D, a, u, p, m.width, m.height, g, m.data) : _e.texSubImage2D(_e.TEXTURE_2D, a, u, p, s, o, g, v, m); _e.pixelStorei(_e.UNPACK_ROW_LENGTH, y), _e.pixelStorei(_e.UNPACK_IMAGE_HEIGHT, A), _e.pixelStorei(_e.UNPACK_SKIP_PIXELS, b), _e.pixelStorei(_e.UNPACK_SKIP_ROWS, x), _e.pixelStorei(_e.UNPACK_SKIP_IMAGES, k), 0 === a && t.generateMipmaps && _e.generateMipmap(w), J.unbindTexture() }, this.copyTextureToTexture3D = function(e, t, n = null, i = null, r = 0) { return !0 !== e.isTexture && (Jt("WebGLRenderer: copyTextureToTexture3D function signature has changed."), n = arguments[0] || null, i = arguments[1] || null, e = arguments[2], t = arguments[3], r = arguments[4] || 0), Jt('WebGLRenderer: copyTextureToTexture3D function has been deprecated. Use "copyTextureToTexture" instead.'), this.copyTextureToTexture(e, t, n, i, r) }, this.initRenderTarget = function(e) { void 0 === ee.get(e).__webglFramebuffer && te.setupRenderTarget(e) }, this.initTexture = function(e) { e.isCubeTexture ? te.setTextureCube(e, 0) : e.isData3DTexture ? te.setTexture3D(e, 0) : e.isDataArrayTexture || e.isCompressedArrayTexture ? te.setTexture2DArray(e, 0) : te.setTexture2D(e, 0), J.unbindTexture() }, this.resetState = function() { x = 0, k = 0, E = null, J.reset(), Me.reset() }, "undefined" != typeof __THREE_DEVTOOLS__ && __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this })) } get coordinateSystem() { return It } get outputColorSpace() { return this._outputColorSpace } set outputColorSpace(e) { this._outputColorSpace = e; const t = this.getContext(); t.drawingBufferColorspace = nn._getDrawingBufferColorSpace(e), t.unpackColorSpace = nn._getUnpackColorSpace() } } const Zd = JSON.parse('{"rE":"0.5.0","l$":{"r":5,"M":4}}'); const Jd = "itch", $d = !1, eu = "https://vps.kodub.com:43273/", tu = Zd.l$.r; if (!Number.isSafeInteger(tu) || tu < 1) throw new Error("package.json beta version property must be a positive integer"); let nu = ""; const iu = Zd.rE + nu, ru = Zd.l$.M; if (!Number.isSafeInteger(ru) || ru < 1) throw new Error("package.json beta physicsVersion property must be a positive integer"); var au, su, ou, lu, cu, hu, du, uu, pu, fu, mu, gu = function(e, t, n, i) { return new(n || (n = Promise))((function(r, a) { function s(e) { try { l(i.next(e)) } catch (e) { a(e) } } function o(e) { try { l(i.throw(e)) } catch (e) { a(e) } } function l(e) { var t; e.done ? r(e.value) : (t = e.value, t instanceof n ? t : new n((function(e) { e(t) }))).then(s, o) } l((i = i.apply(e, t || [])).next()) })) }, vu = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, wu = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class yu { constructor(e, t, n = !0, i = !1) { var r; au.add(this), su.set(this, void 0), ou.set(this, void 0), lu.set(this, void 0), cu.set(this, void 0), hu.set(this, new Pr), du.set(this, void 0), uu.set(this, new yn(8, 10, 10)), pu.set(this, []), vu(this, su, e, "f"), vu(this, ou, t, "f"), vu(this, lu, new Xd({ antialias: null === (r = null == t ? void 0 : t.getSettingBoolean($o.Antialiasing)) || void 0 === r || r, powerPreference: "high-performance", canvas: e, alpha: i }), "f"), wu(this, lu, "f").outputColorSpace = vt, wu(this, lu, "f").shadowMap.enabled = !0, wu(this, lu, "f").debug.checkShaderErrors = $d, vu(this, cu, new Or, "f"), n && (wu(this, cu, "f").fog = new zr(10211839, 0, yu.maxViewDistance)), wu(this, cu, "f").add(new yo(3891597, 11714755, 4.7)), vu(this, du, new Lo(16777215, 4.7), "f"), wu(this, du, "f").position.copy(wu(this, uu, "f")), wu(this, du, "f").castShadow = !0, wu(this, du, "f").shadow.camera.top = 10, wu(this, du, "f").shadow.camera.right = 10, wu(this, du, "f").shadow.camera.bottom = -10, wu(this, du, "f").shadow.camera.left = -10, wu(this, du, "f").shadow.camera.near = 1, wu(this, du, "f").shadow.camera.far = 50, wu(this, du, "f").shadow.mapSize.width = 2048, wu(this, du, "f").shadow.mapSize.height = 2048, wu(this, cu, "f").add(wu(this, du, "f")), wu(this, cu, "f").add(wu(this, du, "f").target), document.addEventListener("fullscreenchange", (() => { wu(this, au, "m", mu).call(this) })), null != window.electron && window.electron.addFullscreenChangeListener((() => { wu(this, au, "m", mu).call(this) })) } clear() { wu(this, lu, "f").clear() } update(e, t) { var n, i, r; const a = null !== (i = null === (n = wu(this, ou, "f")) || void 0 === n ? void 0 : n.getSettingInteger($o.CarShadowQuality)) && void 0 !== i ? i : 0; if (!Number.isFinite(a) || a <= 0) wu(this, du, "f").castShadow = !1; else { wu(this, du, "f").castShadow = !0; const e = Math.min(a, wu(this, lu, "f").capabilities.maxTextureSize); wu(this, du, "f").shadow.mapSize.width == e && wu(this, du, "f").shadow.mapSize.height == e || (wu(this, du, "f").shadow.mapSize.setScalar(e), null === (r = wu(this, du, "f").shadow.map) || void 0 === r || r.dispose(), wu(this, du, "f").shadow.map = null) } wu(this, uu, "f").copy(t.getSunPosition()), wu(this, du, "f").position.addVectors(e, wu(this, uu, "f").multiplyScalar(12.5)), wu(this, du, "f").target.position.copy(e), wu(this, au, "m", fu).call(this), wu(this, lu, "f").render(wu(this, cu, "f"), wu(this, hu, "f")) } getShadowDirection() { return (new yn).subVectors(wu(this, du, "f").position, wu(this, du, "f").target.position).normalize() } getLightTarget() { return wu(this, du, "f").target.position } getMaxAnisotropy() { return wu(this, lu, "f").capabilities.getMaxAnisotropy() } get isFullscreen() { return null != window.electron ? window.electron.isFullscreen() : null != document.fullscreenElement } toggleFullscreen() { return gu(this, void 0, void 0, (function*() { this.isFullscreen ? null != window.electron ? window.electron.setFullscreen(!1) : yield document.exitFullscreen(): null != window.electron ? window.electron.setFullscreen(!0) : yield document.body.requestFullscreen() })) } addFullscreenChangeListener(e) { wu(this, pu, "f").push(e) } removeFullscreenChangeListener(e) { const t = wu(this, pu, "f").indexOf(e); t >= 0 && wu(this, pu, "f").splice(t, 1) } setCamera(e) { vu(this, hu, e, "f") } get camera() { return wu(this, hu, "f") } get canvas() { return wu(this, su, "f") } setAnimationLoop(e) { wu(this, lu, "f").setAnimationLoop(e) } get scene() { return wu(this, cu, "f") } } su = new WeakMap, ou = new WeakMap, lu = new WeakMap, cu = new WeakMap, hu = new WeakMap, du = new WeakMap, uu = new WeakMap, pu = new WeakMap, au = new WeakSet, fu = function() { var e, t; let n = null !== (t = null === (e = wu(this, ou, "f")) || void 0 === e ? void 0 : e.getSettingFloat($o.RenderScale)) && void 0 !== t ? t : 1; n = Number.isFinite(n) ? Math.min(Math.max(n, .25), 2) : 1; const i = window.devicePixelRatio * n; if (wu(this, lu, "f").getPixelRatio() != i && wu(this, lu, "f").setPixelRatio(i), wu(this, hu, "f") instanceof Pr) { const e = window.innerWidth / window.innerHeight, t = new jt; wu(this, lu, "f").getSize(t), t.width == window.innerWidth && t.height == window.innerHeight && wu(this, hu, "f").aspect == e || (wu(this, lu, "f").setSize(window.innerWidth, window.innerHeight), wu(this, hu, "f").aspect = e, wu(this, hu, "f").updateProjectionMatrix()) } }, mu = function() { for (const e of wu(this, pu, "f")) e() }, yu.maxViewDistance = 1e4; const Au = yu; var bu, xu, ku, Eu, Su, Mu = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class Tu { constructor() { bu.add(this), Eu.set(this, new Pr(Mu(xu, xu, "f", ku), 1, .5, Au.maxViewDistance)) } reset(e, t, n) { this.update(e, t, 0), Mu(this, Eu, "f").fov = Mu(this, bu, "m", Su).call(this, null != n ? n : 0), Mu(this, Eu, "f").updateProjectionMatrix() } update(e, t, n) { Mu(this, Eu, "f").fov = Mu(this, bu, "m", Su).call(this, n), Mu(this, Eu, "f").updateProjectionMatrix(); const i = new yn(0, 1.1, .4); Mu(this, Eu, "f").position.addVectors(e, i.applyQuaternion(t)), Mu(this, Eu, "f").quaternion.copy(t), Mu(this, Eu, "f").quaternion.multiply((new wn).setFromEuler(new ai(0, Math.PI, 0))), Mu(this, Eu, "f").updateMatrix() } get camera() { return Mu(this, Eu, "f") } } xu = Tu, Eu = new WeakMap, bu = new WeakSet, Su = function(e) { const t = Math.min(1, Math.abs(e) / 400); return Mu(xu, xu, "f", ku) + (80 - Mu(xu, xu, "f", ku)) * Math.pow(t, 1) / (Math.pow(t, 1) + Math.pow(1 - t, 1)) }, ku = { value: 70 }; const _u = Tu; class Cu { constructor(e, t, n, i) { this.primary = e, this.secondary = t, this.frame = n, this.rims = i } static random() { const e = 360 * Math.random(), t = 100 * (1 - Math.pow(Math.random(), 2)), n = 100 * (.05 + .25 * (1 - Math.pow(Math.random(), 2))); return new Cu(new Wi("hsl(" + e.toString() + "," + t.toString() + "%," + n.toString() + "%)"), new Wi("#ffffff"), new Wi("#131313"), new Wi("#666666")) } serialize() { return this.primary.getHexString() + this.secondary.getHexString() + this.frame.getHexString() + this.rims.getHexString() } static deserialize(e) { const t = []; for (let n = 0; n < 4; n++) { const i = e.substring(6 * n, 6 * (n + 1)); /^[0-9a-f]{6}$/i.test(i) ? t.push(new Wi("#" + i)) : t.push(new Wi("#555")) } return new Cu(t[0], t[1], t[2], t[3]) } } const Pu = Cu; var Iu, Ru, Lu, Du, Nu, Bu, Uu, zu = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, Ou = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class Fu { constructor() { Iu.add(this), Du.set(this, new Pr(Ou(Ru, Ru, "f", Lu), 1, .5, 1e4)), Nu.set(this, new yn), Bu.set(this, new yn(0, 1, 0)) } reset(e, t, n) { zu(this, Nu, new yn(1e-5, 0, -1), "f"), Ou(this, Nu, "f").applyQuaternion(t), Ou(this, Nu, "f").add(e), zu(this, Bu, new yn(0, 1, 0), "f"), Ou(this, Bu, "f").applyQuaternion(t), this.update(0, e, t, 0), Ou(this, Du, "f").fov = Ou(this, Iu, "m", Uu).call(this, null != n ? n : 0), Ou(this, Du, "f").updateProjectionMatrix() } update(e, t, n, i) { Ou(this, Du, "f").fov = Ou(this, Iu, "m", Uu).call(this, i), Ou(this, Du, "f").updateProjectionMatrix(); const r = new yn(0, 1, 0); r.applyQuaternion(n); const a = Math.min(1, 5 * e); Ou(this, Bu, "f").set(a * r.x + (1 - a) * Ou(this, Bu, "f").x, a * r.y + (1 - a) * Ou(this, Bu, "f").y, a * r.z + (1 - a) * Ou(this, Bu, "f").z); const s = (new yn).subVectors(t, Ou(this, Nu, "f")); s.normalize(); const o = 5.5; Ou(this, Du, "f").position.x = t.x - s.x * o + 2 * Ou(this, Bu, "f").x, Ou(this, Du, "f").position.y = Math.max(.25, t.y - s.y * o + 2 * Ou(this, Bu, "f").y), Ou(this, Du, "f").position.z = t.z - s.z * o + 2 * Ou(this, Bu, "f").z, Ou(this, Du, "f").lookAt(t.x + 2 * Ou(this, Bu, "f").x * .9, t.y + 2 * Ou(this, Bu, "f").y * .9, t.z + 2 * Ou(this, Bu, "f").z * .9), Ou(this, Du, "f").updateMatrix(), Ou(this, Nu, "f").set(t.x - s.x * o, t.y - s.y * o, t.z - s.z * o) } get camera() { return Ou(this, Du, "f") } } Ru = Fu, Du = new WeakMap, Nu = new WeakMap, Bu = new WeakMap, Iu = new WeakSet, Uu = function(e) { const t = Math.abs(e) / 400; return Ou(Ru, Ru, "f", Lu) + (100 - Ou(Ru, Ru, "f", Lu)) * Math.pow(t, 1) / (Math.pow(t, 1) + Math.pow(1 - t, 1)) }, Lu = { value: 70 }; const Wu = Fu; var Vu, Hu, Gu, ju, Qu, Yu, Ku, qu, Xu = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, Zu = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class Ju { constructor(e) { Hu.set(this, void 0), Gu.set(this, void 0), ju.set(this, []), Qu.set(this, 256), Yu.set(this, new yn(0, 1, 0)), Xu(this, Hu, e, "f"), Xu(this, Gu, new ua(Zu(Vu, Vu, "f", Ku), Zu(Vu, Vu, "f", qu), Zu(this, Qu, "f")), "f"), Zu(this, Gu, "f").frustumCulled = !1, e.scene.add(Zu(this, Gu, "f")), this.clear() } dispose() { Zu(this, Gu, "f").dispose(), Zu(this, Hu, "f").scene.remove(Zu(this, Gu, "f")) } clear() { Zu(this, ju, "f").length = 0, Zu(this, Gu, "f").count = 0, Zu(this, Gu, "f").instanceMatrix.needsUpdate = !0 } spawn(e, t, n) { Zu(this, ju, "f").push({ x: e + .25 * (Math.random() - .5), y: t + .25 * (Math.random() - .5), z: n + .25 * (Math.random() - .5), vx: .5 * (Math.random() - .5), vy: .5 * (Math.random() - .5), vz: .5 * (Math.random() - .5), rotation: Math.random() * Math.PI * 2, lifetime: .5 }) } update(e) { for (let t = Zu(this, ju, "f").length - 1; t >= 0; --t) { const n = Zu(this, ju, "f")[t]; n.vy += 15 * e, n.x += n.vx * e, n.y += n.vy * e, n.z += n.vz * e, n.lifetime -= e, n.lifetime <= 0 && Zu(this, ju, "f").splice(t, 1) } let t = !1; Zu(this, Gu, "f").count != Zu(this, ju, "f").length && (Zu(this, Gu, "f").count = Math.min(Zu(this, ju, "f").length, Zu(this, Qu, "f")), t = !0); for (let e = 0; e < Zu(this, Gu, "f").count; ++e) { const t = Zu(this, ju, "f")[Zu(this, ju, "f").length - 1 - e], n = new qn; n.lookAt(new yn(t.x, t.y, t.z), Zu(this, Hu, "f").camera.position, Zu(this, Yu, "f")), n.setPosition(t.x, t.y, t.z), n.multiply((new qn).makeRotationZ(t.rotation)); const i = .5 + 2 * (.5 - t.lifetime); n.scale(new yn(i, i, i)), Zu(this, Gu, "f").setMatrixAt(e, n) }(t || Zu(this, ju, "f").length > 0) && (Zu(this, Gu, "f").instanceMatrix.needsUpdate = !0) } static initResources(e) { e.addResource(); const t = (new vo).load("images/smoke.png", (() => { e.loadedResource() })); Zu(this, Vu, "f", qu).map = t } } Vu = Ju, Hu = new WeakMap, Gu = new WeakMap, ju = new WeakMap, Qu = new WeakMap, Yu = new WeakMap, Ku = { value: (() => { const e = new Ns; return e.rotateX(Math.PI), e })() }, qu = { value: new ji({ opacity: .3, depthWrite: !1, transparent: !0 }) }; const $u = Ju; var ep, tp, np, ip, rp, ap, sp, op, lp, cp, hp, dp, up, pp, fp = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, mp = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class gp { constructor(e, t, n) { ep.add(this), np.set(this, void 0), ip.set(this, void 0), rp.set(this, void 0), ap.set(this, void 0), sp.set(this, void 0), op.set(this, void 0), lp.set(this, 1e3), cp.set(this, 0), hp.set(this, null), dp.set(this, null), fp(this, np, e, "f"), fp(this, ip, t, "f"), fp(this, rp, n, "f"); const i = new sr; fp(this, sp, new Float32Array(6 * mp(this, lp, "f") * 3), "f"), fp(this, op, new qi(mp(this, sp, "f"), 3), "f"), i.setAttribute("position", mp(this, op, "f")), fp(this, ap, new wr(i, mp(tp, tp, "f", up)), "f"), mp(this, ap, "f").frustumCulled = !1, mp(this, np, "f").scene.add(mp(this, ap, "f")) } dispose() { mp(this, ap, "f").geometry.dispose(), mp(this, np, "f").scene.remove(mp(this, ap, "f")) } clear() { for (let e = 0; e < mp(this, sp, "f").length; ++e) mp(this, sp, "f")[e] = 0; mp(this, op, "f").needsUpdate = !0, fp(this, cp, 0, "f"), this.break() } break () { fp(this, hp, null, "f"), fp(this, dp, null, "f") } spawn(e, t, n, i) { var r, a; const s = mp(this, hp, "f"), o = mp(this, dp, "f"); let l = new yn(e, t, n).add(new yn(.172, -.3, 0).applyQuaternion(i)), c = new yn(e, t, n).add(new yn(-.172, -.3, 0).applyQuaternion(i)); const h = new yn(0, -1, 0).applyQuaternion(i), d = mp(this, ep, "m", pp).call(this, l, h, 0, .05), u = mp(this, ep, "m", pp).call(this, c, h, 0, .05); if (null != d && null != u) { if (l = d.point, c = u.point, null != s && null != o) { const e = (fp(this, cp, (a = mp(this, cp, "f"), r = a++, a), "f"), r); mp(this, sp, "f")[6 * e * 3 + 0] = l.x, mp(this, sp, "f")[6 * e * 3 + 1] = l.y, mp(this, sp, "f")[6 * e * 3 + 2] = l.z, mp(this, sp, "f")[6 * e * 3 + 3] = s.x, mp(this, sp, "f")[6 * e * 3 + 4] = s.y, mp(this, sp, "f")[6 * e * 3 + 5] = s.z, mp(this, sp, "f")[6 * e * 3 + 6] = c.x, mp(this, sp, "f")[6 * e * 3 + 7] = c.y, mp(this, sp, "f")[6 * e * 3 + 8] = c.z, mp(this, sp, "f")[6 * e * 3 + 9] = c.x, mp(this, sp, "f")[6 * e * 3 + 10] = c.y, mp(this, sp, "f")[6 * e * 3 + 11] = c.z, mp(this, sp, "f")[6 * e * 3 + 12] = s.x, mp(this, sp, "f")[6 * e * 3 + 13] = s.y, mp(this, sp, "f")[6 * e * 3 + 14] = s.z, mp(this, sp, "f")[6 * e * 3 + 15] = o.x, mp(this, sp, "f")[6 * e * 3 + 16] = o.y, mp(this, sp, "f")[6 * e * 3 + 17] = o.z, mp(this, op, "f").needsUpdate = !0, mp(this, cp, "f") >= mp(this, lp, "f") - 1 && fp(this, cp, 0, "f") } fp(this, hp, l, "f"), fp(this, dp, c, "f") } else this.break() } } tp = gp, np = new WeakMap, ip = new WeakMap, rp = new WeakMap, ap = new WeakMap, sp = new WeakMap, op = new WeakMap, lp = new WeakMap, cp = new WeakMap, hp = new WeakMap, dp = new WeakMap, ep = new WeakSet, pp = function(e, t, n, i) { const r = new jo(e, t, n, i), a = mp(this, rp, "f").shortRaycast(r); if (null != a) return a; const s = mp(this, ip, "f").raycast(r); return null != s ? s : null }, up = { value: new ji({ color: 1118481, side: 2, polygonOffset: !0, polygonOffsetFactor: -1, polygonOffsetUnits: 0 }) }; const vp = gp; var wp, yp = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, Ap = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class bp { constructor(e) { if (wp.set(this, 0), null != e) { if (!Number.isSafeInteger(e)) throw new Error("Frames is not a safe integer"); yp(this, wp, e, "f") } } get numberOfFrames() { return Ap(this, wp, "f") } get time() { return Ap(this, wp, "f") / 1e3 } increment() { var e; yp(this, wp, (e = Ap(this, wp, "f"), ++e), "f") } difference(e) { return new bp(Ap(this, wp, "f") - Ap(e, wp, "f")) } lessThan(e) { return Ap(this, wp, "f") < Ap(e, wp, "f") } greaterThan(e) { return Ap(this, wp, "f") > Ap(e, wp, "f") } lessOrEqual(e) { return Ap(this, wp, "f") <= Ap(e, wp, "f") } greaterOrEqual(e) { return Ap(this, wp, "f") >= Ap(e, wp, "f") } equals(e) { return Ap(this, wp, "f") == Ap(e, wp, "f") } isNegative() { return Ap(this, wp, "f") < 0 } clone() { const e = new bp; return yp(e, wp, Ap(this, wp, "f"), "f"), e } } wp = new WeakMap; const xp = bp; function kp(e) { let t = e.length; for (; --t >= 0;) e[t] = 0 } const Ep = 256, Sp = 286, Mp = 30, Tp = 15, _p = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0]), Cp = new Uint8Array([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]), Pp = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7]), Ip = new Uint8Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]), Rp = new Array(576); kp(Rp); const Lp = new Array(60); kp(Lp); const Dp = new Array(512); kp(Dp); const Np = new Array(256); kp(Np); const Bp = new Array(29); kp(Bp); const Up = new Array(Mp); function zp(e, t, n, i, r) { this.static_tree = e, this.extra_bits = t, this.extra_base = n, this.elems = i, this.max_length = r, this.has_stree = e && e.length } let Op, Fp, Wp; function Vp(e, t) { this.dyn_tree = e, this.max_code = 0, this.stat_desc = t } kp(Up); const Hp = e => e < 256 ? Dp[e] : Dp[256 + (e >>> 7)], Gp = (e, t) => { e.pending_buf[e.pending++] = 255 & t, e.pending_buf[e.pending++] = t >>> 8 & 255 }, jp = (e, t, n) => { e.bi_valid > 16 - n ? (e.bi_buf |= t << e.bi_valid & 65535, Gp(e, e.bi_buf), e.bi_buf = t >> 16 - e.bi_valid, e.bi_valid += n - 16) : (e.bi_buf |= t << e.bi_valid & 65535, e.bi_valid += n) }, Qp = (e, t, n) => { jp(e, n[2 * t], n[2 * t + 1]) }, Yp = (e, t) => { let n = 0; do { n |= 1 & e, e >>>= 1, n <<= 1 } while (--t > 0); return n >>> 1 }, Kp = (e, t, n) => { const i = new Array(16); let r, a, s = 0; for (r = 1; r <= Tp; r++) s = s + n[r - 1] << 1, i[r] = s; for (a = 0; a <= t; a++) { let t = e[2 * a + 1]; 0 !== t && (e[2 * a] = Yp(i[t]++, t)) } }, qp = e => { let t; for (t = 0; t < Sp; t++) e.dyn_ltree[2 * t] = 0; for (t = 0; t < Mp; t++) e.dyn_dtree[2 * t] = 0; for (t = 0; t < 19; t++) e.bl_tree[2 * t] = 0; e.dyn_ltree[512] = 1, e.opt_len = e.static_len = 0, e.sym_next = e.matches = 0 }, Xp = e => { e.bi_valid > 8 ? Gp(e, e.bi_buf) : e.bi_valid > 0 && (e.pending_buf[e.pending++] = e.bi_buf), e.bi_buf = 0, e.bi_valid = 0 }, Zp = (e, t, n, i) => { const r = 2 * t, a = 2 * n; return e[r] < e[a] || e[r] === e[a] && i[t] <= i[n] }, Jp = (e, t, n) => { const i = e.heap[n]; let r = n << 1; for (; r <= e.heap_len && (r < e.heap_len && Zp(t, e.heap[r + 1], e.heap[r], e.depth) && r++, !Zp(t, i, e.heap[r], e.depth));) e.heap[n] = e.heap[r], n = r, r <<= 1; e.heap[n] = i }, $p = (e, t, n) => { let i, r, a, s, o = 0; if (0 !== e.sym_next) do { i = 255 & e.pending_buf[e.sym_buf + o++], i += (255 & e.pending_buf[e.sym_buf + o++]) << 8, r = e.pending_buf[e.sym_buf + o++], 0 === i ? Qp(e, r, t) : (a = Np[r], Qp(e, a + Ep + 1, t), s = _p[a], 0 !== s && (r -= Bp[a], jp(e, r, s)), i--, a = Hp(i), Qp(e, a, n), s = Cp[a], 0 !== s && (i -= Up[a], jp(e, i, s))) } while (o < e.sym_next); Qp(e, 256, t) }, ef = (e, t) => { const n = t.dyn_tree, i = t.stat_desc.static_tree, r = t.stat_desc.has_stree, a = t.stat_desc.elems; let s, o, l, c = -1; for (e.heap_len = 0, e.heap_max = 573, s = 0; s < a; s++) 0 !== n[2 * s] ? (e.heap[++e.heap_len] = c = s, e.depth[s] = 0) : n[2 * s + 1] = 0; for (; e.heap_len < 2;) l = e.heap[++e.heap_len] = c < 2 ? ++c : 0, n[2 * l] = 1, e.depth[l] = 0, e.opt_len--, r && (e.static_len -= i[2 * l + 1]); for (t.max_code = c, s = e.heap_len >> 1; s >= 1; s--) Jp(e, n, s); l = a; do { s = e.heap[1], e.heap[1] = e.heap[e.heap_len--], Jp(e, n, 1), o = e.heap[1], e.heap[--e.heap_max] = s, e.heap[--e.heap_max] = o, n[2 * l] = n[2 * s] + n[2 * o], e.depth[l] = (e.depth[s] >= e.depth[o] ? e.depth[s] : e.depth[o]) + 1, n[2 * s + 1] = n[2 * o + 1] = l, e.heap[1] = l++, Jp(e, n, 1) } while (e.heap_len >= 2); e.heap[--e.heap_max] = e.heap[1], ((e, t) => { const n = t.dyn_tree, i = t.max_code, r = t.stat_desc.static_tree, a = t.stat_desc.has_stree, s = t.stat_desc.extra_bits, o = t.stat_desc.extra_base, l = t.stat_desc.max_length; let c, h, d, u, p, f, m = 0; for (u = 0; u <= Tp; u++) e.bl_count[u] = 0; for (n[2 * e.heap[e.heap_max] + 1] = 0, c = e.heap_max + 1; c < 573; c++) h = e.heap[c], u = n[2 * n[2 * h + 1] + 1] + 1, u > l && (u = l, m++), n[2 * h + 1] = u, h > i || (e.bl_count[u]++, p = 0, h >= o && (p = s[h - o]), f = n[2 * h], e.opt_len += f * (u + p), a && (e.static_len += f * (r[2 * h + 1] + p))); if (0 !== m) { do { for (u = l - 1; 0 === e.bl_count[u];) u--; e.bl_count[u]--, e.bl_count[u + 1] += 2, e.bl_count[l]--, m -= 2 } while (m > 0); for (u = l; 0 !== u; u--) for (h = e.bl_count[u]; 0 !== h;) d = e.heap[--c], d > i || (n[2 * d + 1] !== u && (e.opt_len += (u - n[2 * d + 1]) * n[2 * d], n[2 * d + 1] = u), h--) } })(e, t), Kp(n, c, e.bl_count) }, tf = (e, t, n) => { let i, r, a = -1, s = t[1], o = 0, l = 7, c = 4; for (0 === s && (l = 138, c = 3), t[2 * (n + 1) + 1] = 65535, i = 0; i <= n; i++) r = s, s = t[2 * (i + 1) + 1], ++o < l && r === s || (o < c ? e.bl_tree[2 * r] += o : 0 !== r ? (r !== a && e.bl_tree[2 * r]++, e.bl_tree[32]++) : o <= 10 ? e.bl_tree[34]++ : e.bl_tree[36]++, o = 0, a = r, 0 === s ? (l = 138, c = 3) : r === s ? (l = 6, c = 3) : (l = 7, c = 4)) }, nf = (e, t, n) => { let i, r, a = -1, s = t[1], o = 0, l = 7, c = 4; for (0 === s && (l = 138, c = 3), i = 0; i <= n; i++) if (r = s, s = t[2 * (i + 1) + 1], !(++o < l && r === s)) { if (o < c) do { Qp(e, r, e.bl_tree) } while (0 != --o); else 0 !== r ? (r !== a && (Qp(e, r, e.bl_tree), o--), Qp(e, 16, e.bl_tree), jp(e, o - 3, 2)) : o <= 10 ? (Qp(e, 17, e.bl_tree), jp(e, o - 3, 3)) : (Qp(e, 18, e.bl_tree), jp(e, o - 11, 7)); o = 0, a = r, 0 === s ? (l = 138, c = 3) : r === s ? (l = 6, c = 3) : (l = 7, c = 4) } }; let rf = !1; const af = (e, t, n, i) => { jp(e, 0 + (i ? 1 : 0), 3), Xp(e), Gp(e, n), Gp(e, ~n), n && e.pending_buf.set(e.window.subarray(t, t + n), e.pending), e.pending += n }; var sf = (e, t, n, i) => { let r, a, s = 0; e.level > 0 ? (2 === e.strm.data_type && (e.strm.data_type = (e => { let t, n = 4093624447; for (t = 0; t <= 31; t++, n >>>= 1) if (1 & n && 0 !== e.dyn_ltree[2 * t]) return 0; if (0 !== e.dyn_ltree[18] || 0 !== e.dyn_ltree[20] || 0 !== e.dyn_ltree[26]) return 1; for (t = 32; t < Ep; t++) if (0 !== e.dyn_ltree[2 * t]) return 1; return 0 })(e)), ef(e, e.l_desc), ef(e, e.d_desc), s = (e => { let t; for (tf(e, e.dyn_ltree, e.l_desc.max_code), tf(e, e.dyn_dtree, e.d_desc.max_code), ef(e, e.bl_desc), t = 18; t >= 3 && 0 === e.bl_tree[2 * Ip[t] + 1]; t--); return e.opt_len += 3 * (t + 1) + 5 + 5 + 4, t })(e), r = e.opt_len + 3 + 7 >>> 3, a = e.static_len + 3 + 7 >>> 3, a <= r && (r = a)) : r = a = n + 5, n + 4 <= r && -1 !== t ? af(e, t, n, i) : 4 === e.strategy || a === r ? (jp(e, 2 + (i ? 1 : 0), 3), $p(e, Rp, Lp)) : (jp(e, 4 + (i ? 1 : 0), 3), ((e, t, n, i) => { let r; for (jp(e, t - 257, 5), jp(e, n - 1, 5), jp(e, i - 4, 4), r = 0; r < i; r++) jp(e, e.bl_tree[2 * Ip[r] + 1], 3); nf(e, e.dyn_ltree, t - 1), nf(e, e.dyn_dtree, n - 1) })(e, e.l_desc.max_code + 1, e.d_desc.max_code + 1, s + 1), $p(e, e.dyn_ltree, e.dyn_dtree)), qp(e), i && Xp(e) }, of = { _tr_init: e => { rf || ((() => { let e, t, n, i, r; const a = new Array(16); for (n = 0, i = 0; i < 28; i++) for (Bp[i] = n, e = 0; e < 1 << _p[i]; e++) Np[n++] = i; for (Np[n - 1] = i, r = 0, i = 0; i < 16; i++) for (Up[i] = r, e = 0; e < 1 << Cp[i]; e++) Dp[r++] = i; for (r >>= 7; i < Mp; i++) for (Up[i] = r << 7, e = 0; e < 1 << Cp[i] - 7; e++) Dp[256 + r++] = i; for (t = 0; t <= Tp; t++) a[t] = 0; for (e = 0; e <= 143;) Rp[2 * e + 1] = 8, e++, a[8]++; for (; e <= 255;) Rp[2 * e + 1] = 9, e++, a[9]++; for (; e <= 279;) Rp[2 * e + 1] = 7, e++, a[7]++; for (; e <= 287;) Rp[2 * e + 1] = 8, e++, a[8]++; for (Kp(Rp, 287, a), e = 0; e < Mp; e++) Lp[2 * e + 1] = 5, Lp[2 * e] = Yp(e, 5); Op = new zp(Rp, _p, 257, Sp, Tp), Fp = new zp(Lp, Cp, 0, Mp, Tp), Wp = new zp(new Array(0), Pp, 0, 19, 7) })(), rf = !0), e.l_desc = new Vp(e.dyn_ltree, Op), e.d_desc = new Vp(e.dyn_dtree, Fp), e.bl_desc = new Vp(e.bl_tree, Wp), e.bi_buf = 0, e.bi_valid = 0, qp(e) }, _tr_stored_block: af, _tr_flush_block: sf, _tr_tally: (e, t, n) => (e.pending_buf[e.sym_buf + e.sym_next++] = t, e.pending_buf[e.sym_buf + e.sym_next++] = t >> 8, e.pending_buf[e.sym_buf + e.sym_next++] = n, 0 === t ? e.dyn_ltree[2 * n]++ : (e.matches++, t--, e.dyn_ltree[2 * (Np[n] + Ep + 1)]++, e.dyn_dtree[2 * Hp(t)]++), e.sym_next === e.sym_end), _tr_align: e => { jp(e, 2, 3), Qp(e, 256, Rp), (e => { 16 === e.bi_valid ? (Gp(e, e.bi_buf), e.bi_buf = 0, e.bi_valid = 0) : e.bi_valid >= 8 && (e.pending_buf[e.pending++] = 255 & e.bi_buf, e.bi_buf >>= 8, e.bi_valid -= 8) })(e) } }; var lf = (e, t, n, i) => { let r = 65535 & e, a = e >>> 16 & 65535, s = 0; for (; 0 !== n;) { s = n > 2e3 ? 2e3 : n, n -= s; do { r = r + t[i++] | 0, a = a + r | 0 } while (--s); r %= 65521, a %= 65521 } return r | a << 16 }; const cf = new Uint32Array((() => { let e, t = []; for (var n = 0; n < 256; n++) { e = n; for (var i = 0; i < 8; i++) e = 1 & e ? 3988292384 ^ e >>> 1 : e >>> 1; t[n] = e } return t })()); var hf = (e, t, n, i) => { const r = cf, a = i + n; e ^= -1; for (let n = i; n < a; n++) e = e >>> 8 ^ r[255 & (e ^ t[n])]; return ~e }, df = { 2: "need dictionary", 1: "stream end", 0: "", "-1": "file error", "-2": "stream error", "-3": "data error", "-4": "insufficient memory", "-5": "buffer error", "-6": "incompatible version" }, uf = { Z_NO_FLUSH: 0, Z_PARTIAL_FLUSH: 1, Z_SYNC_FLUSH: 2, Z_FULL_FLUSH: 3, Z_FINISH: 4, Z_BLOCK: 5, Z_TREES: 6, Z_OK: 0, Z_STREAM_END: 1, Z_NEED_DICT: 2, Z_ERRNO: -1, Z_STREAM_ERROR: -2, Z_DATA_ERROR: -3, Z_MEM_ERROR: -4, Z_BUF_ERROR: -5, Z_NO_COMPRESSION: 0, Z_BEST_SPEED: 1, Z_BEST_COMPRESSION: 9, Z_DEFAULT_COMPRESSION: -1, Z_FILTERED: 1, Z_HUFFMAN_ONLY: 2, Z_RLE: 3, Z_FIXED: 4, Z_DEFAULT_STRATEGY: 0, Z_BINARY: 0, Z_TEXT: 1, Z_UNKNOWN: 2, Z_DEFLATED: 8 }; const { _tr_init: pf, _tr_stored_block: ff, _tr_flush_block: mf, _tr_tally: gf, _tr_align: vf } = of, { Z_NO_FLUSH: wf, Z_PARTIAL_FLUSH: yf, Z_FULL_FLUSH: Af, Z_FINISH: bf, Z_BLOCK: xf, Z_OK: kf, Z_STREAM_END: Ef, Z_STREAM_ERROR: Sf, Z_DATA_ERROR: Mf, Z_BUF_ERROR: Tf, Z_DEFAULT_COMPRESSION: _f, Z_FILTERED: Cf, Z_HUFFMAN_ONLY: Pf, Z_RLE: If, Z_FIXED: Rf, Z_DEFAULT_STRATEGY: Lf, Z_UNKNOWN: Df, Z_DEFLATED: Nf } = uf, Bf = 258, Uf = 262, zf = 42, Of = 113, Ff = 666, Wf = (e, t) => (e.msg = df[t], t), Vf = e => 2 * e - (e > 4 ? 9 : 0), Hf = e => { let t = e.length; for (; --t >= 0;) e[t] = 0 }, Gf = e => { let t, n, i, r = e.w_size; t = e.hash_size, i = t; do { n = e.head[--i], e.head[i] = n >= r ? n - r : 0 } while (--t); t = r, i = t; do { n = e.prev[--i], e.prev[i] = n >= r ? n - r : 0 } while (--t) }; let jf = (e, t, n) => (t << e.hash_shift ^ n) & e.hash_mask; const Qf = e => { const t = e.state; let n = t.pending; n > e.avail_out && (n = e.avail_out), 0 !== n && (e.output.set(t.pending_buf.subarray(t.pending_out, t.pending_out + n), e.next_out), e.next_out += n, t.pending_out += n, e.total_out += n, e.avail_out -= n, t.pending -= n, 0 === t.pending && (t.pending_out = 0)) }, Yf = (e, t) => { mf(e, e.block_start >= 0 ? e.block_start : -1, e.strstart - e.block_start, t), e.block_start = e.strstart, Qf(e.strm) }, Kf = (e, t) => { e.pending_buf[e.pending++] = t }, qf = (e, t) => { e.pending_buf[e.pending++] = t >>> 8 & 255, e.pending_buf[e.pending++] = 255 & t }, Xf = (e, t, n, i) => { let r = e.avail_in; return r > i && (r = i), 0 === r ? 0 : (e.avail_in -= r, t.set(e.input.subarray(e.next_in, e.next_in + r), n), 1 === e.state.wrap ? e.adler = lf(e.adler, t, r, n) : 2 === e.state.wrap && (e.adler = hf(e.adler, t, r, n)), e.next_in += r, e.total_in += r, r) }, Zf = (e, t) => { let n, i, r = e.max_chain_length, a = e.strstart, s = e.prev_length, o = e.nice_match; const l = e.strstart > e.w_size - Uf ? e.strstart - (e.w_size - Uf) : 0, c = e.window, h = e.w_mask, d = e.prev, u = e.strstart + Bf; let p = c[a + s - 1], f = c[a + s]; e.prev_length >= e.good_match && (r >>= 2), o > e.lookahead && (o = e.lookahead); do { if (n = t, c[n + s] === f && c[n + s - 1] === p && c[n] === c[a] && c[++n] === c[a + 1]) { a += 2, n++; do {} while (c[++a] === c[++n] && c[++a] === c[++n] && c[++a] === c[++n] && c[++a] === c[++n] && c[++a] === c[++n] && c[++a] === c[++n] && c[++a] === c[++n] && c[++a] === c[++n] && a < u); if (i = Bf - (u - a), a = u - Bf, i > s) { if (e.match_start = t, s = i, i >= o) break; p = c[a + s - 1], f = c[a + s] } } } while ((t = d[t & h]) > l && 0 != --r); return s <= e.lookahead ? s : e.lookahead }, Jf = e => { const t = e.w_size; let n, i, r; do { if (i = e.window_size - e.lookahead - e.strstart, e.strstart >= t + (t - Uf) && (e.window.set(e.window.subarray(t, t + t - i), 0), e.match_start -= t, e.strstart -= t, e.block_start -= t, e.insert > e.strstart && (e.insert = e.strstart), Gf(e), i += t), 0 === e.strm.avail_in) break; if (n = Xf(e.strm, e.window, e.strstart + e.lookahead, i), e.lookahead += n, e.lookahead + e.insert >= 3) for (r = e.strstart - e.insert, e.ins_h = e.window[r], e.ins_h = jf(e, e.ins_h, e.window[r + 1]); e.insert && (e.ins_h = jf(e, e.ins_h, e.window[r + 3 - 1]), e.prev[r & e.w_mask] = e.head[e.ins_h], e.head[e.ins_h] = r, r++, e.insert--, !(e.lookahead + e.insert < 3));); } while (e.lookahead < Uf && 0 !== e.strm.avail_in) }, $f = (e, t) => { let n, i, r, a = e.pending_buf_size - 5 > e.w_size ? e.w_size : e.pending_buf_size - 5, s = 0, o = e.strm.avail_in; do { if (n = 65535, r = e.bi_valid + 42 >> 3, e.strm.avail_out < r) break; if (r = e.strm.avail_out - r, i = e.strstart - e.block_start, n > i + e.strm.avail_in && (n = i + e.strm.avail_in), n > r && (n = r), n < a && (0 === n && t !== bf || t === wf || n !== i + e.strm.avail_in)) break; s = t === bf && n === i + e.strm.avail_in ? 1 : 0, ff(e, 0, 0, s), e.pending_buf[e.pending - 4] = n, e.pending_buf[e.pending - 3] = n >> 8, e.pending_buf[e.pending - 2] = ~n, e.pending_buf[e.pending - 1] = ~n >> 8, Qf(e.strm), i && (i > n && (i = n), e.strm.output.set(e.window.subarray(e.block_start, e.block_start + i), e.strm.next_out), e.strm.next_out += i, e.strm.avail_out -= i, e.strm.total_out += i, e.block_start += i, n -= i), n && (Xf(e.strm, e.strm.output, e.strm.next_out, n), e.strm.next_out += n, e.strm.avail_out -= n, e.strm.total_out += n) } while (0 === s); return o -= e.strm.avail_in, o && (o >= e.w_size ? (e.matches = 2, e.window.set(e.strm.input.subarray(e.strm.next_in - e.w_size, e.strm.next_in), 0), e.strstart = e.w_size, e.insert = e.strstart) : (e.window_size - e.strstart <= o && (e.strstart -= e.w_size, e.window.set(e.window.subarray(e.w_size, e.w_size + e.strstart), 0), e.matches < 2 && e.matches++, e.insert > e.strstart && (e.insert = e.strstart)), e.window.set(e.strm.input.subarray(e.strm.next_in - o, e.strm.next_in), e.strstart), e.strstart += o, e.insert += o > e.w_size - e.insert ? e.w_size - e.insert : o), e.block_start = e.strstart), e.high_water < e.strstart && (e.high_water = e.strstart), s ? 4 : t !== wf && t !== bf && 0 === e.strm.avail_in && e.strstart === e.block_start ? 2 : (r = e.window_size - e.strstart, e.strm.avail_in > r && e.block_start >= e.w_size && (e.block_start -= e.w_size, e.strstart -= e.w_size, e.window.set(e.window.subarray(e.w_size, e.w_size + e.strstart), 0), e.matches < 2 && e.matches++, r += e.w_size, e.insert > e.strstart && (e.insert = e.strstart)), r > e.strm.avail_in && (r = e.strm.avail_in), r && (Xf(e.strm, e.window, e.strstart, r), e.strstart += r, e.insert += r > e.w_size - e.insert ? e.w_size - e.insert : r), e.high_water < e.strstart && (e.high_water = e.strstart), r = e.bi_valid + 42 >> 3, r = e.pending_buf_size - r > 65535 ? 65535 : e.pending_buf_size - r, a = r > e.w_size ? e.w_size : r, i = e.strstart - e.block_start, (i >= a || (i || t === bf) && t !== wf && 0 === e.strm.avail_in && i <= r) && (n = i > r ? r : i, s = t === bf && 0 === e.strm.avail_in && n === i ? 1 : 0, ff(e, e.block_start, n, s), e.block_start += n, Qf(e.strm)), s ? 3 : 1) }, em = (e, t) => { let n, i; for (;;) { if (e.lookahead < Uf) { if (Jf(e), e.lookahead < Uf && t === wf) return 1; if (0 === e.lookahead) break } if (n = 0, e.lookahead >= 3 && (e.ins_h = jf(e, e.ins_h, e.window[e.strstart + 3 - 1]), n = e.prev[e.strstart & e.w_mask] = e.head[e.ins_h], e.head[e.ins_h] = e.strstart), 0 !== n && e.strstart - n <= e.w_size - Uf && (e.match_length = Zf(e, n)), e.match_length >= 3) if (i = gf(e, e.strstart - e.match_start, e.match_length - 3), e.lookahead -= e.match_length, e.match_length <= e.max_lazy_match && e.lookahead >= 3) { e.match_length--; do { e.strstart++, e.ins_h = jf(e, e.ins_h, e.window[e.strstart + 3 - 1]), n = e.prev[e.strstart & e.w_mask] = e.head[e.ins_h], e.head[e.ins_h] = e.strstart } while (0 != --e.match_length); e.strstart++ } else e.strstart += e.match_length, e.match_length = 0, e.ins_h = e.window[e.strstart], e.ins_h = jf(e, e.ins_h, e.window[e.strstart + 1]); else i = gf(e, 0, e.window[e.strstart]), e.lookahead--, e.strstart++; if (i && (Yf(e, !1), 0 === e.strm.avail_out)) return 1 } return e.insert = e.strstart < 2 ? e.strstart : 2, t === bf ? (Yf(e, !0), 0 === e.strm.avail_out ? 3 : 4) : e.sym_next && (Yf(e, !1), 0 === e.strm.avail_out) ? 1 : 2 }, tm = (e, t) => { let n, i, r; for (;;) { if (e.lookahead < Uf) { if (Jf(e), e.lookahead < Uf && t === wf) return 1; if (0 === e.lookahead) break } if (n = 0, e.lookahead >= 3 && (e.ins_h = jf(e, e.ins_h, e.window[e.strstart + 3 - 1]), n = e.prev[e.strstart & e.w_mask] = e.head[e.ins_h], e.head[e.ins_h] = e.strstart), e.prev_length = e.match_length, e.prev_match = e.match_start, e.match_length = 2, 0 !== n && e.prev_length < e.max_lazy_match && e.strstart - n <= e.w_size - Uf && (e.match_length = Zf(e, n), e.match_length <= 5 && (e.strategy === Cf || 3 === e.match_length && e.strstart - e.match_start > 4096) && (e.match_length = 2)), e.prev_length >= 3 && e.match_length <= e.prev_length) { r = e.strstart + e.lookahead - 3, i = gf(e, e.strstart - 1 - e.prev_match, e.prev_length - 3), e.lookahead -= e.prev_length - 1, e.prev_length -= 2; do { ++e.strstart <= r && (e.ins_h = jf(e, e.ins_h, e.window[e.strstart + 3 - 1]), n = e.prev[e.strstart & e.w_mask] = e.head[e.ins_h], e.head[e.ins_h] = e.strstart) } while (0 != --e.prev_length); if (e.match_available = 0, e.match_length = 2, e.strstart++, i && (Yf(e, !1), 0 === e.strm.avail_out)) return 1 } else if (e.match_available) { if (i = gf(e, 0, e.window[e.strstart - 1]), i && Yf(e, !1), e.strstart++, e.lookahead--, 0 === e.strm.avail_out) return 1 } else e.match_available = 1, e.strstart++, e.lookahead-- } return e.match_available && (i = gf(e, 0, e.window[e.strstart - 1]), e.match_available = 0), e.insert = e.strstart < 2 ? e.strstart : 2, t === bf ? (Yf(e, !0), 0 === e.strm.avail_out ? 3 : 4) : e.sym_next && (Yf(e, !1), 0 === e.strm.avail_out) ? 1 : 2 }; function nm(e, t, n, i, r) { this.good_length = e, this.max_lazy = t, this.nice_length = n, this.max_chain = i, this.func = r } const im = [new nm(0, 0, 0, 0, $f), new nm(4, 4, 8, 4, em), new nm(4, 5, 16, 8, em), new nm(4, 6, 32, 32, em), new nm(4, 4, 16, 16, tm), new nm(8, 16, 32, 32, tm), new nm(8, 16, 128, 128, tm), new nm(8, 32, 128, 256, tm), new nm(32, 128, 258, 1024, tm), new nm(32, 258, 258, 4096, tm)]; function rm() { this.strm = null, this.status = 0, this.pending_buf = null, this.pending_buf_size = 0, this.pending_out = 0, this.pending = 0, this.wrap = 0, this.gzhead = null, this.gzindex = 0, this.method = Nf, this.last_flush = -1, this.w_size = 0, this.w_bits = 0, this.w_mask = 0, this.window = null, this.window_size = 0, this.prev = null, this.head = null, this.ins_h = 0, this.hash_size = 0, this.hash_bits = 0, this.hash_mask = 0, this.hash_shift = 0, this.block_start = 0, this.match_length = 0, this.prev_match = 0, this.match_available = 0, this.strstart = 0, this.match_start = 0, this.lookahead = 0, this.prev_length = 0, this.max_chain_length = 0, this.max_lazy_match = 0, this.level = 0, this.strategy = 0, this.good_match = 0, this.nice_match = 0, this.dyn_ltree = new Uint16Array(1146), this.dyn_dtree = new Uint16Array(122), this.bl_tree = new Uint16Array(78), Hf(this.dyn_ltree), Hf(this.dyn_dtree), Hf(this.bl_tree), this.l_desc = null, this.d_desc = null, this.bl_desc = null, this.bl_count = new Uint16Array(16), this.heap = new Uint16Array(573), Hf(this.heap), this.heap_len = 0, this.heap_max = 0, this.depth = new Uint16Array(573), Hf(this.depth), this.sym_buf = 0, this.lit_bufsize = 0, this.sym_next = 0, this.sym_end = 0, this.opt_len = 0, this.static_len = 0, this.matches = 0, this.insert = 0, this.bi_buf = 0, this.bi_valid = 0 } const am = e => { if (!e) return 1; const t = e.state; return !t || t.strm !== e || t.status !== zf && 57 !== t.status && 69 !== t.status && 73 !== t.status && 91 !== t.status && 103 !== t.status && t.status !== Of && t.status !== Ff ? 1 : 0 }, sm = e => { if (am(e)) return Wf(e, Sf); e.total_in = e.total_out = 0, e.data_type = Df; const t = e.state; return t.pending = 0, t.pending_out = 0, t.wrap < 0 && (t.wrap = -t.wrap), t.status = 2 === t.wrap ? 57 : t.wrap ? zf : Of, e.adler = 2 === t.wrap ? 0 : 1, t.last_flush = -2, pf(t), kf }, om = e => { const t = sm(e); var n; return t === kf && ((n = e.state).window_size = 2 * n.w_size, Hf(n.head), n.max_lazy_match = im[n.level].max_lazy, n.good_match = im[n.level].good_length, n.nice_match = im[n.level].nice_length, n.max_chain_length = im[n.level].max_chain, n.strstart = 0, n.block_start = 0, n.lookahead = 0, n.insert = 0, n.match_length = n.prev_length = 2, n.match_available = 0, n.ins_h = 0), t }, lm = (e, t, n, i, r, a) => { if (!e) return Sf; let s = 1; if (t === _f && (t = 6), i < 0 ? (s = 0, i = -i) : i > 15 && (s = 2, i -= 16), r < 1 || r > 9 || n !== Nf || i < 8 || i > 15 || t < 0 || t > 9 || a < 0 || a > Rf || 8 === i && 1 !== s) return Wf(e, Sf); 8 === i && (i = 9); const o = new rm; return e.state = o, o.strm = e, o.status = zf, o.wrap = s, o.gzhead = null, o.w_bits = i, o.w_size = 1 << o.w_bits, o.w_mask = o.w_size - 1, o.hash_bits = r + 7, o.hash_size = 1 << o.hash_bits, o.hash_mask = o.hash_size - 1, o.hash_shift = ~~((o.hash_bits + 3 - 1) / 3), o.window = new Uint8Array(2 * o.w_size), o.head = new Uint16Array(o.hash_size), o.prev = new Uint16Array(o.w_size), o.lit_bufsize = 1 << r + 6, o.pending_buf_size = 4 * o.lit_bufsize, o.pending_buf = new Uint8Array(o.pending_buf_size), o.sym_buf = o.lit_bufsize, o.sym_end = 3 * (o.lit_bufsize - 1), o.level = t, o.strategy = a, o.method = n, om(e) }; var cm = { deflateInit: (e, t) => lm(e, t, Nf, 15, 8, Lf), deflateInit2: lm, deflateReset: om, deflateResetKeep: sm, deflateSetHeader: (e, t) => am(e) || 2 !== e.state.wrap ? Sf : (e.state.gzhead = t, kf), deflate: (e, t) => { if (am(e) || t > xf || t < 0) return e ? Wf(e, Sf) : Sf; const n = e.state; if (!e.output || 0 !== e.avail_in && !e.input || n.status === Ff && t !== bf) return Wf(e, 0 === e.avail_out ? Tf : Sf); const i = n.last_flush; if (n.last_flush = t, 0 !== n.pending) { if (Qf(e), 0 === e.avail_out) return n.last_flush = -1, kf } else if (0 === e.avail_in && Vf(t) <= Vf(i) && t !== bf) return Wf(e, Tf); if (n.status === Ff && 0 !== e.avail_in) return Wf(e, Tf); if (n.status === zf && 0 === n.wrap && (n.status = Of), n.status === zf) { let t = Nf + (n.w_bits - 8 << 4) << 8, i = -1; if (i = n.strategy >= Pf || n.level < 2 ? 0 : n.level < 6 ? 1 : 6 === n.level ? 2 : 3, t |= i << 6, 0 !== n.strstart && (t |= 32), t += 31 - t % 31, qf(n, t), 0 !== n.strstart && (qf(n, e.adler >>> 16), qf(n, 65535 & e.adler)), e.adler = 1, n.status = Of, Qf(e), 0 !== n.pending) return n.last_flush = -1, kf } if (57 === n.status) if (e.adler = 0, Kf(n, 31), Kf(n, 139), Kf(n, 8), n.gzhead) Kf(n, (n.gzhead.text ? 1 : 0) + (n.gzhead.hcrc ? 2 : 0) + (n.gzhead.extra ? 4 : 0) + (n.gzhead.name ? 8 : 0) + (n.gzhead.comment ? 16 : 0)), Kf(n, 255 & n.gzhead.time), Kf(n, n.gzhead.time >> 8 & 255), Kf(n, n.gzhead.time >> 16 & 255), Kf(n, n.gzhead.time >> 24 & 255), Kf(n, 9 === n.level ? 2 : n.strategy >= Pf || n.level < 2 ? 4 : 0), Kf(n, 255 & n.gzhead.os), n.gzhead.extra && n.gzhead.extra.length && (Kf(n, 255 & n.gzhead.extra.length), Kf(n, n.gzhead.extra.length >> 8 & 255)), n.gzhead.hcrc && (e.adler = hf(e.adler, n.pending_buf, n.pending, 0)), n.gzindex = 0, n.status = 69; else if (Kf(n, 0), Kf(n, 0), Kf(n, 0), Kf(n, 0), Kf(n, 0), Kf(n, 9 === n.level ? 2 : n.strategy >= Pf || n.level < 2 ? 4 : 0), Kf(n, 3), n.status = Of, Qf(e), 0 !== n.pending) return n.last_flush = -1, kf; if (69 === n.status) { if (n.gzhead.extra) { let t = n.pending, i = (65535 & n.gzhead.extra.length) - n.gzindex; for (; n.pending + i > n.pending_buf_size;) { let r = n.pending_buf_size - n.pending; if (n.pending_buf.set(n.gzhead.extra.subarray(n.gzindex, n.gzindex + r), n.pending), n.pending = n.pending_buf_size, n.gzhead.hcrc && n.pending > t && (e.adler = hf(e.adler, n.pending_buf, n.pending - t, t)), n.gzindex += r, Qf(e), 0 !== n.pending) return n.last_flush = -1, kf; t = 0, i -= r } let r = new Uint8Array(n.gzhead.extra); n.pending_buf.set(r.subarray(n.gzindex, n.gzindex + i), n.pending), n.pending += i, n.gzhead.hcrc && n.pending > t && (e.adler = hf(e.adler, n.pending_buf, n.pending - t, t)), n.gzindex = 0 } n.status = 73 } if (73 === n.status) { if (n.gzhead.name) { let t, i = n.pending; do { if (n.pending === n.pending_buf_size) { if (n.gzhead.hcrc && n.pending > i && (e.adler = hf(e.adler, n.pending_buf, n.pending - i, i)), Qf(e), 0 !== n.pending) return n.last_flush = -1, kf; i = 0 } t = n.gzindex < n.gzhead.name.length ? 255 & n.gzhead.name.charCodeAt(n.gzindex++) : 0, Kf(n, t) } while (0 !== t); n.gzhead.hcrc && n.pending > i && (e.adler = hf(e.adler, n.pending_buf, n.pending - i, i)), n.gzindex = 0 } n.status = 91 } if (91 === n.status) { if (n.gzhead.comment) { let t, i = n.pending; do { if (n.pending === n.pending_buf_size) { if (n.gzhead.hcrc && n.pending > i && (e.adler = hf(e.adler, n.pending_buf, n.pending - i, i)), Qf(e), 0 !== n.pending) return n.last_flush = -1, kf; i = 0 } t = n.gzindex < n.gzhead.comment.length ? 255 & n.gzhead.comment.charCodeAt(n.gzindex++) : 0, Kf(n, t) } while (0 !== t); n.gzhead.hcrc && n.pending > i && (e.adler = hf(e.adler, n.pending_buf, n.pending - i, i)) } n.status = 103 } if (103 === n.status) { if (n.gzhead.hcrc) { if (n.pending + 2 > n.pending_buf_size && (Qf(e), 0 !== n.pending)) return n.last_flush = -1, kf; Kf(n, 255 & e.adler), Kf(n, e.adler >> 8 & 255), e.adler = 0 } if (n.status = Of, Qf(e), 0 !== n.pending) return n.last_flush = -1, kf } if (0 !== e.avail_in || 0 !== n.lookahead || t !== wf && n.status !== Ff) { let i = 0 === n.level ? $f(n, t) : n.strategy === Pf ? ((e, t) => { let n; for (;;) { if (0 === e.lookahead && (Jf(e), 0 === e.lookahead)) { if (t === wf) return 1; break } if (e.match_length = 0, n = gf(e, 0, e.window[e.strstart]), e.lookahead--, e.strstart++, n && (Yf(e, !1), 0 === e.strm.avail_out)) return 1 } return e.insert = 0, t === bf ? (Yf(e, !0), 0 === e.strm.avail_out ? 3 : 4) : e.sym_next && (Yf(e, !1), 0 === e.strm.avail_out) ? 1 : 2 })(n, t) : n.strategy === If ? ((e, t) => { let n, i, r, a; const s = e.window; for (;;) { if (e.lookahead <= Bf) { if (Jf(e), e.lookahead <= Bf && t === wf) return 1; if (0 === e.lookahead) break } if (e.match_length = 0, e.lookahead >= 3 && e.strstart > 0 && (r = e.strstart - 1, i = s[r], i === s[++r] && i === s[++r] && i === s[++r])) { a = e.strstart + Bf; do {} while (i === s[++r] && i === s[++r] && i === s[++r] && i === s[++r] && i === s[++r] && i === s[++r] && i === s[++r] && i === s[++r] && r < a); e.match_length = Bf - (a - r), e.match_length > e.lookahead && (e.match_length = e.lookahead) } if (e.match_length >= 3 ? (n = gf(e, 1, e.match_length - 3), e.lookahead -= e.match_length, e.strstart += e.match_length, e.match_length = 0) : (n = gf(e, 0, e.window[e.strstart]), e.lookahead--, e.strstart++), n && (Yf(e, !1), 0 === e.strm.avail_out)) return 1 } return e.insert = 0, t === bf ? (Yf(e, !0), 0 === e.strm.avail_out ? 3 : 4) : e.sym_next && (Yf(e, !1), 0 === e.strm.avail_out) ? 1 : 2 })(n, t) : im[n.level].func(n, t); if (3 !== i && 4 !== i || (n.status = Ff), 1 === i || 3 === i) return 0 === e.avail_out && (n.last_flush = -1), kf; if (2 === i && (t === yf ? vf(n) : t !== xf && (ff(n, 0, 0, !1), t === Af && (Hf(n.head), 0 === n.lookahead && (n.strstart = 0, n.block_start = 0, n.insert = 0))), Qf(e), 0 === e.avail_out)) return n.last_flush = -1, kf } return t !== bf ? kf : n.wrap <= 0 ? Ef : (2 === n.wrap ? (Kf(n, 255 & e.adler), Kf(n, e.adler >> 8 & 255), Kf(n, e.adler >> 16 & 255), Kf(n, e.adler >> 24 & 255), Kf(n, 255 & e.total_in), Kf(n, e.total_in >> 8 & 255), Kf(n, e.total_in >> 16 & 255), Kf(n, e.total_in >> 24 & 255)) : (qf(n, e.adler >>> 16), qf(n, 65535 & e.adler)), Qf(e), n.wrap > 0 && (n.wrap = -n.wrap), 0 !== n.pending ? kf : Ef) }, deflateEnd: e => { if (am(e)) return Sf; const t = e.state.status; return e.state = null, t === Of ? Wf(e, Mf) : kf }, deflateSetDictionary: (e, t) => { let n = t.length; if (am(e)) return Sf; const i = e.state, r = i.wrap; if (2 === r || 1 === r && i.status !== zf || i.lookahead) return Sf; if (1 === r && (e.adler = lf(e.adler, t, n, 0)), i.wrap = 0, n >= i.w_size) { 0 === r && (Hf(i.head), i.strstart = 0, i.block_start = 0, i.insert = 0); let e = new Uint8Array(i.w_size); e.set(t.subarray(n - i.w_size, n), 0), t = e, n = i.w_size } const a = e.avail_in, s = e.next_in, o = e.input; for (e.avail_in = n, e.next_in = 0, e.input = t, Jf(i); i.lookahead >= 3;) { let e = i.strstart, t = i.lookahead - 2; do { i.ins_h = jf(i, i.ins_h, i.window[e + 3 - 1]), i.prev[e & i.w_mask] = i.head[i.ins_h], i.head[i.ins_h] = e, e++ } while (--t); i.strstart = e, i.lookahead = 2, Jf(i) } return i.strstart += i.lookahead, i.block_start = i.strstart, i.insert = i.lookahead, i.lookahead = 0, i.match_length = i.prev_length = 2, i.match_available = 0, e.next_in = s, e.input = o, e.avail_in = a, i.wrap = r, kf }, deflateInfo: "pako deflate (from Nodeca project)" }; const hm = (e, t) => Object.prototype.hasOwnProperty.call(e, t); var dm = function(e) { const t = Array.prototype.slice.call(arguments, 1); for (; t.length;) { const n = t.shift(); if (n) { if ("object" != typeof n) throw new TypeError(n + "must be non-object"); for (const t in n) hm(n, t) && (e[t] = n[t]) } } return e }, um = e => { let t = 0; for (let n = 0, i = e.length; n < i; n++) t += e[n].length; const n = new Uint8Array(t); for (let t = 0, i = 0, r = e.length; t < r; t++) { let r = e[t]; n.set(r, i), i += r.length } return n }; let pm = !0; try { String.fromCharCode.apply(null, new Uint8Array(1)) } catch (e) { pm = !1 } const fm = new Uint8Array(256); for (let e = 0; e < 256; e++) fm[e] = e >= 252 ? 6 : e >= 248 ? 5 : e >= 240 ? 4 : e >= 224 ? 3 : e >= 192 ? 2 : 1; fm[254] = fm[254] = 1; var mm = e => { if ("function" == typeof TextEncoder && TextEncoder.prototype.encode) return (new TextEncoder).encode(e); let t, n, i, r, a, s = e.length, o = 0; for (r = 0; r < s; r++) n = e.charCodeAt(r), 55296 == (64512 & n) && r + 1 < s && (i = e.charCodeAt(r + 1), 56320 == (64512 & i) && (n = 65536 + (n - 55296 << 10) + (i - 56320), r++)), o += n < 128 ? 1 : n < 2048 ? 2 : n < 65536 ? 3 : 4; for (t = new Uint8Array(o), a = 0, r = 0; a < o; r++) n = e.charCodeAt(r), 55296 == (64512 & n) && r + 1 < s && (i = e.charCodeAt(r + 1), 56320 == (64512 & i) && (n = 65536 + (n - 55296 << 10) + (i - 56320), r++)), n < 128 ? t[a++] = n : n < 2048 ? (t[a++] = 192 | n >>> 6, t[a++] = 128 | 63 & n) : n < 65536 ? (t[a++] = 224 | n >>> 12, t[a++] = 128 | n >>> 6 & 63, t[a++] = 128 | 63 & n) : (t[a++] = 240 | n >>> 18, t[a++] = 128 | n >>> 12 & 63, t[a++] = 128 | n >>> 6 & 63, t[a++] = 128 | 63 & n); return t }, gm = (e, t) => { const n = t || e.length; if ("function" == typeof TextDecoder && TextDecoder.prototype.decode) return (new TextDecoder).decode(e.subarray(0, t)); let i, r; const a = new Array(2 * n); for (r = 0, i = 0; i < n;) { let t = e[i++]; if (t < 128) { a[r++] = t; continue } let s = fm[t]; if (s > 4) a[r++] = 65533, i += s - 1; else { for (t &= 2 === s ? 31 : 3 === s ? 15 : 7; s > 1 && i < n;) t = t << 6 | 63 & e[i++], s--; s > 1 ? a[r++] = 65533 : t < 65536 ? a[r++] = t : (t -= 65536, a[r++] = 55296 | t >> 10 & 1023, a[r++] = 56320 | 1023 & t) } } return ((e, t) => { if (t < 65534 && e.subarray && pm) return String.fromCharCode.apply(null, e.length === t ? e : e.subarray(0, t)); let n = ""; for (let i = 0; i < t; i++) n += String.fromCharCode(e[i]); return n })(a, r) }, vm = (e, t) => { (t = t || e.length) > e.length && (t = e.length); let n = t - 1; for (; n >= 0 && 128 == (192 & e[n]);) n--; return n < 0 || 0 === n ? t : n + fm[e[n]] > t ? n : t }; var wm = function() { this.input = null, this.next_in = 0, this.avail_in = 0, this.total_in = 0, this.output = null, this.next_out = 0, this.avail_out = 0, this.total_out = 0, this.msg = "", this.state = null, this.data_type = 2, this.adler = 0 }; const ym = Object.prototype.toString, { Z_NO_FLUSH: Am, Z_SYNC_FLUSH: bm, Z_FULL_FLUSH: xm, Z_FINISH: km, Z_OK: Em, Z_STREAM_END: Sm, Z_DEFAULT_COMPRESSION: Mm, Z_DEFAULT_STRATEGY: Tm, Z_DEFLATED: _m } = uf; function Cm(e) { this.options = dm({ level: Mm, method: _m, chunkSize: 16384, windowBits: 15, memLevel: 8, strategy: Tm }, e || {}); let t = this.options; t.raw && t.windowBits > 0 ? t.windowBits = -t.windowBits : t.gzip && t.windowBits > 0 && t.windowBits < 16 && (t.windowBits += 16), this.err = 0, this.msg = "", this.ended = !1, this.chunks = [], this.strm = new wm, this.strm.avail_out = 0; let n = cm.deflateInit2(this.strm, t.level, t.method, t.windowBits, t.memLevel, t.strategy); if (n !== Em) throw new Error(df[n]); if (t.header && cm.deflateSetHeader(this.strm, t.header), t.dictionary) { let e; if (e = "string" == typeof t.dictionary ? mm(t.dictionary) : "[object ArrayBuffer]" === ym.call(t.dictionary) ? new Uint8Array(t.dictionary) : t.dictionary, n = cm.deflateSetDictionary(this.strm, e), n !== Em) throw new Error(df[n]); this._dict_set = !0 } } function Pm(e, t) { const n = new Cm(t); if (n.push(e, !0), n.err) throw n.msg || df[n.err]; return n.result } Cm.prototype.push = function(e, t) { const n = this.strm, i = this.options.chunkSize; let r, a; if (this.ended) return !1; for (a = t === ~~t ? t : !0 === t ? km : Am, "string" == typeof e ? n.input = mm(e) : "[object ArrayBuffer]" === ym.call(e) ? n.input = new Uint8Array(e) : n.input = e, n.next_in = 0, n.avail_in = n.input.length;;) if (0 === n.avail_out && (n.output = new Uint8Array(i), n.next_out = 0, n.avail_out = i), (a === bm || a === xm) && n.avail_out <= 6) this.onData(n.output.subarray(0, n.next_out)), n.avail_out = 0; else { if (r = cm.deflate(n, a), r === Sm) return n.next_out > 0 && this.onData(n.output.subarray(0, n.next_out)), r = cm.deflateEnd(this.strm), this.onEnd(r), this.ended = !0, r === Em; if (0 !== n.avail_out) { if (a > 0 && n.next_out > 0) this.onData(n.output.subarray(0, n.next_out)), n.avail_out = 0; else if (0 === n.avail_in) break } else this.onData(n.output) } return !0 }, Cm.prototype.onData = function(e) { this.chunks.push(e) }, Cm.prototype.onEnd = function(e) { e === Em && (this.result = um(this.chunks)), this.chunks = [], this.err = e, this.msg = this.strm.msg }; var Im = function(e, t) { return (t = t || {}).raw = !0, Pm(e, t) }, Rm = function(e, t) { return (t = t || {}).gzip = !0, Pm(e, t) }, Lm = { Deflate: Cm, deflate: Pm, deflateRaw: Im, gzip: Rm, constants: uf }; const Dm = 16209; var Nm = function(e, t) { let n, i, r, a, s, o, l, c, h, d, u, p, f, m, g, v, w, y, A, b, x, k, E, S; const M = e.state; n = e.next_in, E = e.input, i = n + (e.avail_in - 5), r = e.next_out, S = e.output, a = r - (t - e.avail_out), s = r + (e.avail_out - 257), o = M.dmax, l = M.wsize, c = M.whave, h = M.wnext, d = M.window, u = M.hold, p = M.bits, f = M.lencode, m = M.distcode, g = (1 << M.lenbits) - 1, v = (1 << M.distbits) - 1; e: do { p < 15 && (u += E[n++] << p, p += 8, u += E[n++] << p, p += 8), w = f[u & g]; t: for (;;) { if (y = w >>> 24, u >>>= y, p -= y, y = w >>> 16 & 255, 0 === y) S[r++] = 65535 & w; else { if (!(16 & y)) { if (64 & y) { if (32 & y) { M.mode = 16191; break e } e.msg = "invalid literal/length code", M.mode = Dm; break e } w = f[(65535 & w) + (u & (1 << y) - 1)]; continue t } for (A = 65535 & w, y &= 15, y && (p < y && (u += E[n++] << p, p += 8), A += u & (1 << y) - 1, u >>>= y, p -= y), p < 15 && (u += E[n++] << p, p += 8, u += E[n++] << p, p += 8), w = m[u & v];;) { if (y = w >>> 24, u >>>= y, p -= y, y = w >>> 16 & 255, 16 & y) { if (b = 65535 & w, y &= 15, p < y && (u += E[n++] << p, p += 8, p < y && (u += E[n++] << p, p += 8)), b += u & (1 << y) - 1, b > o) { e.msg = "invalid distance too far back", M.mode = Dm; break e } if (u >>>= y, p -= y, y = r - a, b > y) { if (y = b - y, y > c && M.sane) { e.msg = "invalid distance too far back", M.mode = Dm; break e } if (x = 0, k = d, 0 === h) { if (x += l - y, y < A) { A -= y; do { S[r++] = d[x++] } while (--y); x = r - b, k = S } } else if (h < y) { if (x += l + h - y, y -= h, y < A) { A -= y; do { S[r++] = d[x++] } while (--y); if (x = 0, h < A) { y = h, A -= y; do { S[r++] = d[x++] } while (--y); x = r - b, k = S } } } else if (x += h - y, y < A) { A -= y; do { S[r++] = d[x++] } while (--y); x = r - b, k = S } for (; A > 2;) S[r++] = k[x++], S[r++] = k[x++], S[r++] = k[x++], A -= 3; A && (S[r++] = k[x++], A > 1 && (S[r++] = k[x++])) } else { x = r - b; do { S[r++] = S[x++], S[r++] = S[x++], S[r++] = S[x++], A -= 3 } while (A > 2); A && (S[r++] = S[x++], A > 1 && (S[r++] = S[x++])) } break } if (64 & y) { e.msg = "invalid distance code", M.mode = Dm; break e } w = m[(65535 & w) + (u & (1 << y) - 1)] } } break } } while (n < i && r < s); A = p >> 3, n -= A, p -= A << 3, u &= (1 << p) - 1, e.next_in = n, e.next_out = r, e.avail_in = n < i ? i - n + 5 : 5 - (n - i), e.avail_out = r < s ? s - r + 257 : 257 - (r - s), M.hold = u, M.bits = p }; const Bm = 15, Um = new Uint16Array([3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0]), zm = new Uint8Array([16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78]), Om = new Uint16Array([1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0]), Fm = new Uint8Array([16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64]); var Wm = (e, t, n, i, r, a, s, o) => { const l = o.bits; let c, h, d, u, p, f, m = 0, g = 0, v = 0, w = 0, y = 0, A = 0, b = 0, x = 0, k = 0, E = 0, S = null; const M = new Uint16Array(16), T = new Uint16Array(16); let _, C, P, I = null; for (m = 0; m <= Bm; m++) M[m] = 0; for (g = 0; g < i; g++) M[t[n + g]]++; for (y = l, w = Bm; w >= 1 && 0 === M[w]; w--); if (y > w && (y = w), 0 === w) return r[a++] = 20971520, r[a++] = 20971520, o.bits = 1, 0; for (v = 1; v < w && 0 === M[v]; v++); for (y < v && (y = v), x = 1, m = 1; m <= Bm; m++) if (x <<= 1, x -= M[m], x < 0) return -1; if (x > 0 && (0 === e || 1 !== w)) return -1; for (T[1] = 0, m = 1; m < Bm; m++) T[m + 1] = T[m] + M[m]; for (g = 0; g < i; g++) 0 !== t[n + g] && (s[T[t[n + g]]++] = g); if (0 === e ? (S = I = s, f = 20) : 1 === e ? (S = Um, I = zm, f = 257) : (S = Om, I = Fm, f = 0), E = 0, g = 0, m = v, p = a, A = y, b = 0, d = -1, k = 1 << y, u = k - 1, 1 === e && k > 852 || 2 === e && k > 592) return 1; for (;;) { _ = m - b, s[g] + 1 < f ? (C = 0, P = s[g]) : s[g] >= f ? (C = I[s[g] - f], P = S[s[g] - f]) : (C = 96, P = 0), c = 1 << m - b, h = 1 << A, v = h; do { h -= c, r[p + (E >> b) + h] = _ << 24 | C << 16 | P } while (0 !== h); for (c = 1 << m - 1; E & c;) c >>= 1; if (0 !== c ? (E &= c - 1, E += c) : E = 0, g++, 0 == --M[m]) { if (m === w) break; m = t[n + s[g]] } if (m > y && (E & u) !== d) { for (0 === b && (b = y), p += v, A = m - b, x = 1 << A; A + b < w && (x -= M[A + b], !(x <= 0));) A++, x <<= 1; if (k += 1 << A, 1 === e && k > 852 || 2 === e && k > 592) return 1; d = E & u, r[d] = y << 24 | A << 16 | p - a } } return 0 !== E && (r[p + E] = m - b << 24 | 64 << 16), o.bits = y, 0 }; const { Z_FINISH: Vm, Z_BLOCK: Hm, Z_TREES: Gm, Z_OK: jm, Z_STREAM_END: Qm, Z_NEED_DICT: Ym, Z_STREAM_ERROR: Km, Z_DATA_ERROR: qm, Z_MEM_ERROR: Xm, Z_BUF_ERROR: Zm, Z_DEFLATED: Jm } = uf, $m = 16180, eg = 16190, tg = 16191, ng = 16192, ig = 16194, rg = 16199, ag = 16200, sg = 16206, og = 16209, lg = e => (e >>> 24 & 255) + (e >>> 8 & 65280) + ((65280 & e) << 8) + ((255 & e) << 24); function cg() { this.strm = null, this.mode = 0, this.last = !1, this.wrap = 0, this.havedict = !1, this.flags = 0, this.dmax = 0, this.check = 0, this.total = 0, this.head = null, this.wbits = 0, this.wsize = 0, this.whave = 0, this.wnext = 0, this.window = null, this.hold = 0, this.bits = 0, this.length = 0, this.offset = 0, this.extra = 0, this.lencode = null, this.distcode = null, this.lenbits = 0, this.distbits = 0, this.ncode = 0, this.nlen = 0, this.ndist = 0, this.have = 0, this.next = null, this.lens = new Uint16Array(320), this.work = new Uint16Array(288), this.lendyn = null, this.distdyn = null, this.sane = 0, this.back = 0, this.was = 0 } const hg = e => { if (!e) return 1; const t = e.state; return !t || t.strm !== e || t.mode < $m || t.mode > 16211 ? 1 : 0 }, dg = e => { if (hg(e)) return Km; const t = e.state; return e.total_in = e.total_out = t.total = 0, e.msg = "", t.wrap && (e.adler = 1 & t.wrap), t.mode = $m, t.last = 0, t.havedict = 0, t.flags = -1, t.dmax = 32768, t.head = null, t.hold = 0, t.bits = 0, t.lencode = t.lendyn = new Int32Array(852), t.distcode = t.distdyn = new Int32Array(592), t.sane = 1, t.back = -1, jm }, ug = e => { if (hg(e)) return Km; const t = e.state; return t.wsize = 0, t.whave = 0, t.wnext = 0, dg(e) }, pg = (e, t) => { let n; if (hg(e)) return Km; const i = e.state; return t < 0 ? (n = 0, t = -t) : (n = 5 + (t >> 4), t < 48 && (t &= 15)), t && (t < 8 || t > 15) ? Km : (null !== i.window && i.wbits !== t && (i.window = null), i.wrap = n, i.wbits = t, ug(e)) }, fg = (e, t) => { if (!e) return Km; const n = new cg; e.state = n, n.strm = e, n.window = null, n.mode = $m; const i = pg(e, t); return i !== jm && (e.state = null), i }; let mg, gg, vg = !0; const wg = e => { if (vg) { mg = new Int32Array(512), gg = new Int32Array(32); let t = 0; for (; t < 144;) e.lens[t++] = 8; for (; t < 256;) e.lens[t++] = 9; for (; t < 280;) e.lens[t++] = 7; for (; t < 288;) e.lens[t++] = 8; for (Wm(1, e.lens, 0, 288, mg, 0, e.work, { bits: 9 }), t = 0; t < 32;) e.lens[t++] = 5; Wm(2, e.lens, 0, 32, gg, 0, e.work, { bits: 5 }), vg = !1 } e.lencode = mg, e.lenbits = 9, e.distcode = gg, e.distbits = 5 }, yg = (e, t, n, i) => { let r; const a = e.state; return null === a.window && (a.wsize = 1 << a.wbits, a.wnext = 0, a.whave = 0, a.window = new Uint8Array(a.wsize)), i >= a.wsize ? (a.window.set(t.subarray(n - a.wsize, n), 0), a.wnext = 0, a.whave = a.wsize) : (r = a.wsize - a.wnext, r > i && (r = i), a.window.set(t.subarray(n - i, n - i + r), a.wnext), (i -= r) ? (a.window.set(t.subarray(n - i, n), 0), a.wnext = i, a.whave = a.wsize) : (a.wnext += r, a.wnext === a.wsize && (a.wnext = 0), a.whave < a.wsize && (a.whave += r))), 0 }; var Ag = (e, t) => { let n, i, r, a, s, o, l, c, h, d, u, p, f, m, g, v, w, y, A, b, x, k, E = 0; const S = new Uint8Array(4); let M, T; const _ = new Uint8Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); if (hg(e) || !e.output || !e.input && 0 !== e.avail_in) return Km; n = e.state, n.mode === tg && (n.mode = ng), s = e.next_out, r = e.output, l = e.avail_out, a = e.next_in, i = e.input, o = e.avail_in, c = n.hold, h = n.bits, d = o, u = l, k = jm; e: for (;;) switch (n.mode) { case $m: if (0 === n.wrap) { n.mode = ng; break } for (; h < 16;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } if (2 & n.wrap && 35615 === c) { 0 === n.wbits && (n.wbits = 15), n.check = 0, S[0] = 255 & c, S[1] = c >>> 8 & 255, n.check = hf(n.check, S, 2, 0), c = 0, h = 0, n.mode = 16181; break } if (n.head && (n.head.done = !1), !(1 & n.wrap) || (((255 & c) << 8) + (c >> 8)) % 31) { e.msg = "incorrect header check", n.mode = og; break } if ((15 & c) !== Jm) { e.msg = "unknown compression method", n.mode = og; break } if (c >>>= 4, h -= 4, x = 8 + (15 & c), 0 === n.wbits && (n.wbits = x), x > 15 || x > n.wbits) { e.msg = "invalid window size", n.mode = og; break } n.dmax = 1 << n.wbits, n.flags = 0, e.adler = n.check = 1, n.mode = 512 & c ? 16189 : tg, c = 0, h = 0; break; case 16181: for (; h < 16;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } if (n.flags = c, (255 & n.flags) !== Jm) { e.msg = "unknown compression method", n.mode = og; break } if (57344 & n.flags) { e.msg = "unknown header flags set", n.mode = og; break } n.head && (n.head.text = c >> 8 & 1), 512 & n.flags && 4 & n.wrap && (S[0] = 255 & c, S[1] = c >>> 8 & 255, n.check = hf(n.check, S, 2, 0)), c = 0, h = 0, n.mode = 16182; case 16182: for (; h < 32;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } n.head && (n.head.time = c), 512 & n.flags && 4 & n.wrap && (S[0] = 255 & c, S[1] = c >>> 8 & 255, S[2] = c >>> 16 & 255, S[3] = c >>> 24 & 255, n.check = hf(n.check, S, 4, 0)), c = 0, h = 0, n.mode = 16183; case 16183: for (; h < 16;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } n.head && (n.head.xflags = 255 & c, n.head.os = c >> 8), 512 & n.flags && 4 & n.wrap && (S[0] = 255 & c, S[1] = c >>> 8 & 255, n.check = hf(n.check, S, 2, 0)), c = 0, h = 0, n.mode = 16184; case 16184: if (1024 & n.flags) { for (; h < 16;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } n.length = c, n.head && (n.head.extra_len = c), 512 & n.flags && 4 & n.wrap && (S[0] = 255 & c, S[1] = c >>> 8 & 255, n.check = hf(n.check, S, 2, 0)), c = 0, h = 0 } else n.head && (n.head.extra = null); n.mode = 16185; case 16185: if (1024 & n.flags && (p = n.length, p > o && (p = o), p && (n.head && (x = n.head.extra_len - n.length, n.head.extra || (n.head.extra = new Uint8Array(n.head.extra_len)), n.head.extra.set(i.subarray(a, a + p), x)), 512 & n.flags && 4 & n.wrap && (n.check = hf(n.check, i, p, a)), o -= p, a += p, n.length -= p), n.length)) break e; n.length = 0, n.mode = 16186; case 16186: if (2048 & n.flags) { if (0 === o) break e; p = 0; do { x = i[a + p++], n.head && x && n.length < 65536 && (n.head.name += String.fromCharCode(x)) } while (x && p < o); if (512 & n.flags && 4 & n.wrap && (n.check = hf(n.check, i, p, a)), o -= p, a += p, x) break e } else n.head && (n.head.name = null); n.length = 0, n.mode = 16187; case 16187: if (4096 & n.flags) { if (0 === o) break e; p = 0; do { x = i[a + p++], n.head && x && n.length < 65536 && (n.head.comment += String.fromCharCode(x)) } while (x && p < o); if (512 & n.flags && 4 & n.wrap && (n.check = hf(n.check, i, p, a)), o -= p, a += p, x) break e } else n.head && (n.head.comment = null); n.mode = 16188; case 16188: if (512 & n.flags) { for (; h < 16;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } if (4 & n.wrap && c !== (65535 & n.check)) { e.msg = "header crc mismatch", n.mode = og; break } c = 0, h = 0 } n.head && (n.head.hcrc = n.flags >> 9 & 1, n.head.done = !0), e.adler = n.check = 0, n.mode = tg; break; case 16189: for (; h < 32;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } e.adler = n.check = lg(c), c = 0, h = 0, n.mode = eg; case eg: if (0 === n.havedict) return e.next_out = s, e.avail_out = l, e.next_in = a, e.avail_in = o, n.hold = c, n.bits = h, Ym; e.adler = n.check = 1, n.mode = tg; case tg: if (t === Hm || t === Gm) break e; case ng: if (n.last) { c >>>= 7 & h, h -= 7 & h, n.mode = sg; break } for (; h < 3;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } switch (n.last = 1 & c, c >>>= 1, h -= 1, 3 & c) { case 0: n.mode = 16193; break; case 1: if (wg(n), n.mode = rg, t === Gm) { c >>>= 2, h -= 2; break e } break; case 2: n.mode = 16196; break; case 3: e.msg = "invalid block type", n.mode = og } c >>>= 2, h -= 2; break; case 16193: for (c >>>= 7 & h, h -= 7 & h; h < 32;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } if ((65535 & c) != (c >>> 16 ^ 65535)) { e.msg = "invalid stored block lengths", n.mode = og; break } if (n.length = 65535 & c, c = 0, h = 0, n.mode = ig, t === Gm) break e; case ig: n.mode = 16195; case 16195: if (p = n.length, p) { if (p > o && (p = o), p > l && (p = l), 0 === p) break e; r.set(i.subarray(a, a + p), s), o -= p, a += p, l -= p, s += p, n.length -= p; break } n.mode = tg; break; case 16196: for (; h < 14;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } if (n.nlen = 257 + (31 & c), c >>>= 5, h -= 5, n.ndist = 1 + (31 & c), c >>>= 5, h -= 5, n.ncode = 4 + (15 & c), c >>>= 4, h -= 4, n.nlen > 286 || n.ndist > 30) { e.msg = "too many length or distance symbols", n.mode = og; break } n.have = 0, n.mode = 16197; case 16197: for (; n.have < n.ncode;) { for (; h < 3;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } n.lens[_[n.have++]] = 7 & c, c >>>= 3, h -= 3 } for (; n.have < 19;) n.lens[_[n.have++]] = 0; if (n.lencode = n.lendyn, n.lenbits = 7, M = { bits: n.lenbits }, k = Wm(0, n.lens, 0, 19, n.lencode, 0, n.work, M), n.lenbits = M.bits, k) { e.msg = "invalid code lengths set", n.mode = og; break } n.have = 0, n.mode = 16198; case 16198: for (; n.have < n.nlen + n.ndist;) { for (; E = n.lencode[c & (1 << n.lenbits) - 1], g = E >>> 24, v = E >>> 16 & 255, w = 65535 & E, !(g <= h);) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } if (w < 16) c >>>= g, h -= g, n.lens[n.have++] = w; else { if (16 === w) { for (T = g + 2; h < T;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } if (c >>>= g, h -= g, 0 === n.have) { e.msg = "invalid bit length repeat", n.mode = og; break } x = n.lens[n.have - 1], p = 3 + (3 & c), c >>>= 2, h -= 2 } else if (17 === w) { for (T = g + 3; h < T;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } c >>>= g, h -= g, x = 0, p = 3 + (7 & c), c >>>= 3, h -= 3 } else { for (T = g + 7; h < T;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } c >>>= g, h -= g, x = 0, p = 11 + (127 & c), c >>>= 7, h -= 7 } if (n.have + p > n.nlen + n.ndist) { e.msg = "invalid bit length repeat", n.mode = og; break } for (; p--;) n.lens[n.have++] = x } } if (n.mode === og) break; if (0 === n.lens[256]) { e.msg = "invalid code -- missing end-of-block", n.mode = og; break } if (n.lenbits = 9, M = { bits: n.lenbits }, k = Wm(1, n.lens, 0, n.nlen, n.lencode, 0, n.work, M), n.lenbits = M.bits, k) { e.msg = "invalid literal/lengths set", n.mode = og; break } if (n.distbits = 6, n.distcode = n.distdyn, M = { bits: n.distbits }, k = Wm(2, n.lens, n.nlen, n.ndist, n.distcode, 0, n.work, M), n.distbits = M.bits, k) { e.msg = "invalid distances set", n.mode = og; break } if (n.mode = rg, t === Gm) break e; case rg: n.mode = ag; case ag: if (o >= 6 && l >= 258) { e.next_out = s, e.avail_out = l, e.next_in = a, e.avail_in = o, n.hold = c, n.bits = h, Nm(e, u), s = e.next_out, r = e.output, l = e.avail_out, a = e.next_in, i = e.input, o = e.avail_in, c = n.hold, h = n.bits, n.mode === tg && (n.back = -1); break } for (n.back = 0; E = n.lencode[c & (1 << n.lenbits) - 1], g = E >>> 24, v = E >>> 16 & 255, w = 65535 & E, !(g <= h);) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } if (v && !(240 & v)) { for (y = g, A = v, b = w; E = n.lencode[b + ((c & (1 << y + A) - 1) >> y)], g = E >>> 24, v = E >>> 16 & 255, w = 65535 & E, !(y + g <= h);) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } c >>>= y, h -= y, n.back += y } if (c >>>= g, h -= g, n.back += g, n.length = w, 0 === v) { n.mode = 16205; break } if (32 & v) { n.back = -1, n.mode = tg; break } if (64 & v) { e.msg = "invalid literal/length code", n.mode = og; break } n.extra = 15 & v, n.mode = 16201; case 16201: if (n.extra) { for (T = n.extra; h < T;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } n.length += c & (1 << n.extra) - 1, c >>>= n.extra, h -= n.extra, n.back += n.extra } n.was = n.length, n.mode = 16202; case 16202: for (; E = n.distcode[c & (1 << n.distbits) - 1], g = E >>> 24, v = E >>> 16 & 255, w = 65535 & E, !(g <= h);) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } if (!(240 & v)) { for (y = g, A = v, b = w; E = n.distcode[b + ((c & (1 << y + A) - 1) >> y)], g = E >>> 24, v = E >>> 16 & 255, w = 65535 & E, !(y + g <= h);) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } c >>>= y, h -= y, n.back += y } if (c >>>= g, h -= g, n.back += g, 64 & v) { e.msg = "invalid distance code", n.mode = og; break } n.offset = w, n.extra = 15 & v, n.mode = 16203; case 16203: if (n.extra) { for (T = n.extra; h < T;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } n.offset += c & (1 << n.extra) - 1, c >>>= n.extra, h -= n.extra, n.back += n.extra } if (n.offset > n.dmax) { e.msg = "invalid distance too far back", n.mode = og; break } n.mode = 16204; case 16204: if (0 === l) break e; if (p = u - l, n.offset > p) { if (p = n.offset - p, p > n.whave && n.sane) { e.msg = "invalid distance too far back", n.mode = og; break } p > n.wnext ? (p -= n.wnext, f = n.wsize - p) : f = n.wnext - p, p > n.length && (p = n.length), m = n.window } else m = r, f = s - n.offset, p = n.length; p > l && (p = l), l -= p, n.length -= p; do { r[s++] = m[f++] } while (--p); 0 === n.length && (n.mode = ag); break; case 16205: if (0 === l) break e; r[s++] = n.length, l--, n.mode = ag; break; case sg: if (n.wrap) { for (; h < 32;) { if (0 === o) break e; o--, c |= i[a++] << h, h += 8 } if (u -= l, e.total_out += u, n.total += u, 4 & n.wrap && u && (e.adler = n.check = n.flags ? hf(n.check, r, u, s - u) : lf(n.check, r, u, s - u)), u = l, 4 & n.wrap && (n.flags ? c : lg(c)) !== n.check) { e.msg = "incorrect data check", n.mode = og; break } c = 0, h = 0 } n.mode = 16207; case 16207: if (n.wrap && n.flags) { for (; h < 32;) { if (0 === o) break e; o--, c += i[a++] << h, h += 8 } if (4 & n.wrap && c !== (4294967295 & n.total)) { e.msg = "incorrect length check", n.mode = og; break } c = 0, h = 0 } n.mode = 16208; case 16208: k = Qm; break e; case og: k = qm; break e; case 16210: return Xm; default: return Km } return e.next_out = s, e.avail_out = l, e.next_in = a, e.avail_in = o, n.hold = c, n.bits = h, (n.wsize || u !== e.avail_out && n.mode < og && (n.mode < sg || t !== Vm)) && yg(e, e.output, e.next_out, u - e.avail_out), d -= e.avail_in, u -= e.avail_out, e.total_in += d, e.total_out += u, n.total += u, 4 & n.wrap && u && (e.adler = n.check = n.flags ? hf(n.check, r, u, e.next_out - u) : lf(n.check, r, u, e.next_out - u)), e.data_type = n.bits + (n.last ? 64 : 0) + (n.mode === tg ? 128 : 0) + (n.mode === rg || n.mode === ig ? 256 : 0), (0 === d && 0 === u || t === Vm) && k === jm && (k = Zm), k }, bg = e => { if (hg(e)) return Km; let t = e.state; return t.window && (t.window = null), e.state = null, jm }, xg = (e, t) => { if (hg(e)) return Km; const n = e.state; return 2 & n.wrap ? (n.head = t, t.done = !1, jm) : Km }, kg = (e, t) => { const n = t.length; let i, r, a; return hg(e) ? Km : (i = e.state, 0 !== i.wrap && i.mode !== eg ? Km : i.mode === eg && (r = 1, r = lf(r, t, n, 0), r !== i.check) ? qm : (a = yg(e, t, n, n), a ? (i.mode = 16210, Xm) : (i.havedict = 1, jm))) }, Eg = { inflateReset: ug, inflateReset2: pg, inflateResetKeep: dg, inflateInit: e => fg(e, 15), inflateInit2: fg, inflate: Ag, inflateEnd: bg, inflateGetHeader: xg, inflateSetDictionary: kg, inflateInfo: "pako inflate (from Nodeca project)" }; var Sg = function() { this.text = 0, this.time = 0, this.xflags = 0, this.os = 0, this.extra = null, this.extra_len = 0, this.name = "", this.comment = "", this.hcrc = 0, this.done = !1 }; const Mg = Object.prototype.toString, { Z_NO_FLUSH: Tg, Z_FINISH: _g, Z_OK: Cg, Z_STREAM_END: Pg, Z_NEED_DICT: Ig, Z_STREAM_ERROR: Rg, Z_DATA_ERROR: Lg, Z_MEM_ERROR: Dg } = uf; function Ng(e) { this.options = dm({ chunkSize: 65536, windowBits: 15, to: "" }, e || {}); const t = this.options; t.raw && t.windowBits >= 0 && t.windowBits < 16 && (t.windowBits = -t.windowBits, 0 === t.windowBits && (t.windowBits = -15)), !(t.windowBits >= 0 && t.windowBits < 16) || e && e.windowBits || (t.windowBits += 32), t.windowBits > 15 && t.windowBits < 48 && (15 & t.windowBits || (t.windowBits |= 15)), this.err = 0, this.msg = "", this.ended = !1, this.chunks = [], this.strm = new wm, this.strm.avail_out = 0; let n = Eg.inflateInit2(this.strm, t.windowBits); if (n !== Cg) throw new Error(df[n]); if (this.header = new Sg, Eg.inflateGetHeader(this.strm, this.header), t.dictionary && ("string" == typeof t.dictionary ? t.dictionary = mm(t.dictionary) : "[object ArrayBuffer]" === Mg.call(t.dictionary) && (t.dictionary = new Uint8Array(t.dictionary)), t.raw && (n = Eg.inflateSetDictionary(this.strm, t.dictionary), n !== Cg))) throw new Error(df[n]) } function Bg(e, t) { const n = new Ng(t); if (n.push(e), n.err) throw n.msg || df[n.err]; return n.result } Ng.prototype.push = function(e, t) { const n = this.strm, i = this.options.chunkSize, r = this.options.dictionary; let a, s, o; if (this.ended) return !1; for (s = t === ~~t ? t : !0 === t ? _g : Tg, "[object ArrayBuffer]" === Mg.call(e) ? n.input = new Uint8Array(e) : n.input = e, n.next_in = 0, n.avail_in = n.input.length;;) { for (0 === n.avail_out && (n.output = new Uint8Array(i), n.next_out = 0, n.avail_out = i), a = Eg.inflate(n, s), a === Ig && r && (a = Eg.inflateSetDictionary(n, r), a === Cg ? a = Eg.inflate(n, s) : a === Lg && (a = Ig)); n.avail_in > 0 && a === Pg && n.state.wrap > 0 && 0 !== e[n.next_in];) Eg.inflateReset(n), a = Eg.inflate(n, s); switch (a) { case Rg: case Lg: case Ig: case Dg: return this.onEnd(a), this.ended = !0, !1 } if (o = n.avail_out, n.next_out && (0 === n.avail_out || a === Pg)) if ("string" === this.options.to) { let e = vm(n.output, n.next_out), t = n.next_out - e, r = gm(n.output, e); n.next_out = t, n.avail_out = i - t, t && n.output.set(n.output.subarray(e, e + t), 0), this.onData(r) } else this.onData(n.output.length === n.next_out ? n.output : n.output.subarray(0, n.next_out)); if (a !== Cg || 0 !== o) { if (a === Pg) return a = Eg.inflateEnd(this.strm), this.onEnd(a), this.ended = !0, !0; if (0 === n.avail_in) break } } return !0 }, Ng.prototype.onData = function(e) { this.chunks.push(e) }, Ng.prototype.onEnd = function(e) { e === Cg && ("string" === this.options.to ? this.result = this.chunks.join("") : this.result = um(this.chunks)), this.chunks = [], this.err = e, this.msg = this.strm.msg }; var Ug = function(e, t) { return (t = t || {}).raw = !0, Bg(e, t) }, zg = { Inflate: Ng, inflate: Bg, inflateRaw: Ug, ungzip: Bg, constants: uf }; const { Deflate: Og, deflate: Fg, deflateRaw: Wg, gzip: Vg } = Lm, { Inflate: Hg, inflate: Gg, inflateRaw: jg, ungzip: Qg } = zg; var Yg = { Deflate: Og, deflate: Fg, deflateRaw: Wg, gzip: Vg, Inflate: Hg, inflate: Gg, inflateRaw: jg, ungzip: Qg, constants: uf }; function Kg(e) { let t; e = (e = e.replace(/-/g, "+")).replace(/_/g, "/"); try { t = atob(e) } catch (e) { return null } const n = new Uint8Array(t.length); for (let e = 0; e < t.length; ++e) { const i = t.charCodeAt(e); if (i > 255) return null; n[e] = i } return n } var qg, Xg, Zg, Jg, $g, ev, tv, nv, iv, rv, av, sv = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, ov = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class lv { constructor(e) { qg.add(this), Zg.set(this, []), Jg.set(this, []), $g.set(this, []), ev.set(this, []), tv.set(this, []), nv.set(this, null), null != e && (sv(this, Zg, e.up, "f"), sv(this, Jg, e.right, "f"), sv(this, $g, e.down, "f"), sv(this, ev, e.left, "f"), sv(this, tv, e.reset, "f")) } recordFrame(e, t) { if (e > Xg.maxFrames) throw new Error("Frame number exceeds maximum frame count."); if (null != ov(this, nv, "f") && e <= ov(this, nv, "f")) throw new Error("Frame number must be greater than the previous recorded frame."); sv(this, nv, e, "f"); const n = ov(this, Zg, "f").length % 2 != 0, i = ov(this, Jg, "f").length % 2 != 0, r = ov(this, $g, "f").length % 2 != 0, a = ov(this, ev, "f").length % 2 != 0, s = ov(this, tv, "f").length % 2 != 0; t.up != n && ov(this, Zg, "f").push(e), t.right != i && ov(this, Jg, "f").push(e), t.down != r && ov(this, $g, "f").push(e), t.left != a && ov(this, ev, "f").push(e), t.reset != s && ov(this, tv, "f").push(e) } getFrame(e) { return { up: (ov(this, qg, "m", iv).call(this, e, ov(this, Zg, "f")) + 1) % 2 != 0, right: (ov(this, qg, "m", iv).call(this, e, ov(this, Jg, "f")) + 1) % 2 != 0, down: (ov(this, qg, "m", iv).call(this, e, ov(this, $g, "f")) + 1) % 2 != 0, left: (ov(this, qg, "m", iv).call(this, e, ov(this, ev, "f")) + 1) % 2 != 0, reset: (ov(this, qg, "m", iv).call(this, e, ov(this, tv, "f")) + 1) % 2 != 0 } } serialize() { const e = new Uint8Array(3 + 3 * ov(this, Zg, "f").length + 3 + 3 * ov(this, Jg, "f").length + 3 + 3 * ov(this, $g, "f").length + 3 + 3 * ov(this, ev, "f").length + 3 + 3 * ov(this, tv, "f").length); ov(this, qg, "m", rv).call(this, ov(this, Zg, "f"), e.subarray(0, 3 + 3 * ov(this, Zg, "f").length)), ov(this, qg, "m", rv).call(this, ov(this, Jg, "f"), e.subarray(3 + 3 * ov(this, Zg, "f").length, 3 + 3 * ov(this, Zg, "f").length + 3 + 3 * ov(this, Jg, "f").length)), ov(this, qg, "m", rv).call(this, ov(this, $g, "f"), e.subarray(3 + 3 * ov(this, Zg, "f").length + 3 + 3 * ov(this, Jg, "f").length, 3 + 3 * ov(this, Zg, "f").length + 3 + 3 * ov(this, Jg, "f").length + 3 + 3 * ov(this, $g, "f").length)), ov(this, qg, "m", rv).call(this, ov(this, ev, "f"), e.subarray(3 + 3 * ov(this, Zg, "f").length + 3 + 3 * ov(this, Jg, "f").length + 3 + 3 * ov(this, $g, "f").length, 3 + 3 * ov(this, Zg, "f").length + 3 + 3 * ov(this, Jg, "f").length + 3 + 3 * ov(this, $g, "f").length + 3 + 3 * ov(this, ev, "f").length)), ov(this, qg, "m", rv).call(this, ov(this, tv, "f"), e.subarray(3 + 3 * ov(this, Zg, "f").length + 3 + 3 * ov(this, Jg, "f").length + 3 + 3 * ov(this, $g, "f").length + 3 + 3 * ov(this, ev, "f").length, 3 + 3 * ov(this, Zg, "f").length + 3 + 3 * ov(this, Jg, "f").length + 3 + 3 * ov(this, $g, "f").length + 3 + 3 * ov(this, ev, "f").length + 3 + 3 * ov(this, tv, "f").length)); const t = new Yg.Deflate({ level: 9 }); return t.push(new Uint8Array(e), !0), function(e) { let t = ""; for (const n of e) t += String.fromCharCode(n); let n = btoa(t); return n = n.replace(/\+/g, "-"), n = n.replace(/\//g, "_"), n = n.replace(/=/g, ""), n }(t.result) } static deserialize(e) { const t = Kg(e); if (null == t) return null; const n = new Yg.Inflate; if (n.push(t, !0), n.err) return null; const i = n.result; if (!(i instanceof Uint8Array)) return null; const r = ov(Xg, Xg, "m", av).call(Xg, i); if (null == r) return null; const a = ov(Xg, Xg, "m", av).call(Xg, i.subarray(3 + 3 * r.length)); if (null == a) return null; const s = ov(Xg, Xg, "m", av).call(Xg, i.subarray(3 + 3 * r.length + 3 + 3 * a.length)); if (null == s) return null; const o = ov(Xg, Xg, "m", av).call(Xg, i.subarray(3 + 3 * r.length + 3 + 3 * a.length + 3 + 3 * s.length)); if (null == o) return null; const l = ov(Xg, Xg, "m", av).call(Xg, i.subarray(3 + 3 * r.length + 3 + 3 * a.length + 3 + 3 * s.length + 3 + 3 * o.length)); return null == l ? null : new Xg({ up: r, right: a, down: s, left: o, reset: l }) } } Xg = lv, Zg = new WeakMap, Jg = new WeakMap, $g = new WeakMap, ev = new WeakMap, tv = new WeakMap, nv = new WeakMap, qg = new WeakSet, iv = function(e, t) { let n = -1; for (let i = 0; i < t.length; ++i) { const r = t[i]; if (r == e) { n = i; break } if (r > e) break; n = i } return n }, rv = function(e, t) { t[0] = 255 & e.length, t[1] = e.length >>> 8 & 255, t[2] = e.length >>> 16 & 255; for (let n = 0; n < e.length; ++n) { let i; i = 0 == n ? e[n] : e[n] - e[n - 1], t[3 + 3 * n] = 255 & i, t[3 + 3 * n + 1] = i >>> 8 & 255, t[3 + 3 * n + 2] = i >>> 16 & 255 } }, av = function(e) { if (e.length < 3) return null; const t = e[0] | e[1] << 8 | e[2] << 16; if (e.length < 3 + 3 * t) return null; const n = []; for (let i = 0; i < t; ++i) { const t = e[3 + 3 * i] | e[3 + 3 * i + 1] << 8 | e[3 + 3 * i + 2] << 16; 0 == i ? n.push(t) : n.push(n[i - 1] + t) } return n }, lv.maxFrames = 5999999; const cv = lv; var hv, dv, uv, pv, fv, mv, gv, vv, wv, yv, Av, bv, xv, kv, Ev, Sv, Mv, Tv, _v, Cv, Pv, Iv, Rv, Lv, Dv, Nv, Bv, Uv, zv, Ov, Fv, Wv, Vv, Hv, Gv, jv, Qv, Yv, Kv, qv, Xv, Zv, Jv, $v, ew, tw, nw, iw, rw, aw, sw, ow, lw, cw, hw, dw, uw, pw, fw, mw, gw = function(e, t, n, i) { return new(n || (n = Promise))((function(r, a) { function s(e) { try { l(i.next(e)) } catch (e) { a(e) } } function o(e) { try { l(i.throw(e)) } catch (e) { a(e) } } function l(e) { var t; e.done ? r(e.value) : (t = e.value, t instanceof n ? t : new n((function(e) { e(t) }))).then(s, o) } l((i = i.apply(e, t || [])).next()) })) }, vw = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, ww = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class yw { constructor(e, t, n, i, r, a, s, o, l) { var c; if (hv.add(this), uv.set(this, void 0), pv.set(this, null), fv.set(this, 1), mv.set(this, null), gv.set(this, []), vv.set(this, null), wv.set(this, null), yv.set(this, null), Av.set(this, []), this.notificationAudioEnabled = !1, bv.set(this, void 0), xv.set(this, void 0), kv.set(this, void 0), Ev.set(this, !1), Sv.set(this, void 0), Mv.set(this, void 0), Tv.set(this, void 0), _v.set(this, void 0), Cv.set(this, []), Pv.set(this, []), Iv.set(this, []), Rv.set(this, [0, 0, 0, 0]), Lv.set(this, [0, 0, 0, 0]), Dv.set(this, [0, 0, 0, 0]), Nv.set(this, void 0), Bv.set(this, void 0), Uv.set(this, null), zv.set(this, null), Ov.set(this, []), Fv.set(this, null), Wv.set(this, void 0), Vv.set(this, void 0), Hv.set(this, void 0), Gv.set(this, void 0), jv.set(this, void 0), Qv.set(this, void 0), Yv.set(this, void 0), Kv.set(this, []), qv.set(this, null), Xv.set(this, [.075, .075, .075, .075]), Zv.set(this, void 0), Jv.set(this, null), $v.set(this, !1), vw(this, uv, a, "f"), vw(this, Nv, r, "f"), vw(this, jv, s, "f"), vw(this, Qv, o, "f"), vw(this, Yv, l, "f"), vw(this, kv, e, "f"), (null == l ? void 0 : l.getSettingBoolean($o.ParticlesEnabled)) ? vw(this, Zv, new $u(r), "f") : vw(this, Zv, null, "f"), null != ww(this, jv, "f") && null != ww(this, Qv, "f") && vw(this, Kv, [new vp(ww(this, Nv, "f"), ww(this, jv, "f"), ww(this, Qv, "f")), new vp(ww(this, Nv, "f"), ww(this, jv, "f"), ww(this, Qv, "f")), new vp(ww(this, Nv, "f"), ww(this, jv, "f"), ww(this, Qv, "f")), new vp(ww(this, Nv, "f"), ww(this, jv, "f"), ww(this, Qv, "f"))], "f"), vw(this, bv, new Wu, "f"), ww(this, bv, "f").reset(t.position, t.quaternion), r.scene.add(ww(this, bv, "f").camera), vw(this, xv, new _u, "f"), ww(this, xv, "f").reset(t.position, t.quaternion), r.scene.add(ww(this, xv, "f").camera), null == dv.models) throw new Error("Car model isn't loaded yet"); if (null != ww(this, kv, "f") && null != ww(this, jv, "f") && null != ww(this, Qv, "f")) vw(this, Sv, ww(this, kv, "f").createCar(t, ww(this, jv, "f").getMountainVertices(), ww(this, jv, "f").getMountainOffset(), ww(this, Qv, "f").getTrackData(), n, (e => { this.setCarState(e) })), "f"); else { const e = [new yn(.627909, .27 - dv.suspensionResetLengthFront, 1.3478).applyQuaternion(t.quaternion).add(t.position), new yn(-.627909, .27 - dv.suspensionResetLengthFront, 1.3478).applyQuaternion(t.quaternion).add(t.position), new yn(.720832, .27 - dv.suspensionResetLengthRear, -1.52686).applyQuaternion(t.quaternion).add(t.position), new yn(-.720832, .27 - dv.suspensionResetLengthRear, -1.52686).applyQuaternion(t.quaternion).add(t.position)], n = [(new wn).setFromEuler((new ai).set(0, Math.PI, 0)).multiply(t.quaternion), (new wn).setFromEuler((new ai).set(0, Math.PI, 0)).multiply(t.quaternion), (new wn).setFromEuler((new ai).set(0, Math.PI, 0)).multiply(t.quaternion), (new wn).setFromEuler((new ai).set(0, Math.PI, 0)).multiply(t.quaternion)]; vw(this, Sv, { id: 0, frames: 0, speedKmh: 0, hasStarted: !1, finishFrames: null, nextCheckpointIndex: 0, hasCheckpointToRespawnAt: !1, position: { x: t.position.x, y: t.position.y, z: t.position.z }, quaternion: { x: t.quaternion.x, y: t.quaternion.y, z: t.quaternion.z, w: t.quaternion.w }, collisionImpulses: [], wheelInContact: [!1, !1, !1, !1], wheelSuspensionLength: [dv.suspensionResetLengthFront, dv.suspensionResetLengthFront, dv.suspensionResetLengthRear, dv.suspensionResetLengthRear], wheelSuspensionVelocity: [0, 0, 0, 0], wheelRotation: [0, 0, 0, 0], wheelDeltaRotation: [0, 0, 0, 0], wheelSkidInfo: [0, 0, 0, 0], wheelPosition: e, wheelQuaternion: n, brakeLightEnabled: !1, controls: { up: !1, right: !1, down: !1, left: !1, reset: !1 } }, "f") } if (vw(this, Mv, i, "f"), null == n) vw(this, Tv, null != ww(this, Mv, "f"), "f"), vw(this, _v, new cv, "f"); else { if (null != ww(this, Mv, "f")) throw new Error("Can't control car when recording is set"); vw(this, Tv, !1, "f"), vw(this, _v, n, "f") } vw(this, Bv, new Nr, "f"), ww(this, Bv, "f").add(dv.models.chassis.clone()), ww(this, Bv, "f").add(dv.models.suspension.clone()), ww(this, Bv, "f").add(dv.models.wheelFL.clone()), ww(this, Bv, "f").add(dv.models.wheelFR.clone()), ww(this, Bv, "f").add(dv.models.wheelBL.clone()), ww(this, Bv, "f").add(dv.models.wheelBR.clone()); for (const e of ww(this, Bv, "f").children) { const t = e; Array.isArray(t.material) ? t.material = t.material.map((e => e.clone())) : t.material = t.material.clone(), t.castShadow = !0, t.receiveShadow = !0, t.frustumCulled = !1 } ww(this, Nv, "f").scene.add(ww(this, Bv, "f")), vw(this, Uv, ww(this, Bv, "f").getObjectByName("Body"), "f"), vw(this, zv, ww(this, Bv, "f").getObjectByName("Suspension"), "f"); { const e = document.createElement("canvas"); e.width = 2048, e.height = 2048; const t = e.getContext("2d"); if (null == t) throw new Error("Failed to get context for car texture"); const n = new un(e); let i; n.flipY = !1, n.anisotropy = ww(this, Nv, "f").getMaxAnisotropy(), n.needsUpdate = !0, vw(this, Wv, t, "f"), vw(this, Vv, n, "f"), vw(this, Gv, Pu.random(), "f"), ww(this, hv, "m", tw).call(this), vw(this, Hv, { value: new yn(0, 0, 0) }, "f"), i = Array.isArray(ww(this, Uv, "f").material) ? ww(this, Uv, "f").material : [ww(this, Uv, "f").material]; for (const e of i) "Main" == e.name ? e.onBeforeCompile = e => { e.fragmentShader = "uniform sampler2D carColorPattern;\nuniform vec3 carColorSecondary;\n" + e.fragmentShader, e.fragmentShader = e.fragmentShader.replace("vec4 diffuseColor = vec4( diffuse, opacity );", "float colorSource = texture(carColorPattern, vUv).a;\nvec4 diffuseColor = vec4( carColorSecondary * colorSource + diffuse * (1.0 - colorSource), opacity );"), e.uniforms.carColorPattern = { value: n }, e.uniforms.carColorSecondary = ww(this, Hv, "f"), null == e.defines && (e.defines = {}), e.defines.USE_UV = !0 } : "Metal" == e.name ? e.needsUpdate = !0 : "BrakeLight" == e.name && vw(this, Fv, e, "f") } ww(this, zv, "f").geometry.morphAttributes.position = []; const h = ww(this, zv, "f"), d = dv.models.suspensionFL, u = dv.models.suspensionFR, p = dv.models.suspensionBL, f = dv.models.suspensionBR; for (const e of ww(this, Bv, "f").children) if (e != ww(this, Uv, "f") && e != ww(this, zv, "f")) { const t = e; if (!(d.geometry.attributes.position instanceof qi && u.geometry.attributes.position instanceof qi && p.geometry.attributes.position instanceof qi && f.geometry.attributes.position instanceof qi)) throw new Error("Vertices must use BufferAttribute"); const n = d.geometry.attributes.position.array, i = u.geometry.attributes.position.array, r = p.geometry.attributes.position.array, a = f.geometry.attributes.position.array, s = h.geometry.morphAttributes.position; if ("WheelFL" == t.name) s.push(new qi(n, 3)); else if ("WheelFR" == t.name) s.push(new qi(i, 3)); else if ("WheelBL" == t.name) s.push(new qi(r, 3)); else { if ("WheelBR" != t.name) throw new Error("Unidentified wheel"); s.push(new qi(a, 3)) } ww(this, Ov, "f").push(t) } ww(this, zv, "f").updateMorphTargets(), null != ww(this, Mv, "f") && (null === (c = ww(this, kv, "f")) || void 0 === c || c.controlCar(ww(this, Sv, "f").id, ww(this, Mv, "f").up, ww(this, Mv, "f").right, ww(this, Mv, "f").down, ww(this, Mv, "f").left, ww(this, Mv, "f").reset), ww(this, Mv, "f").addChangeCallback(vw(this, Jv, (e => { var t; null === (t = ww(this, kv, "f")) || void 0 === t || t.controlCar(ww(this, Sv, "f").id, e.up, e.right, e.down, e.left, e.reset) }), "f"))) } dispose() { var e, t, n; vw(this, $v, !0, "f"), ww(this, hv, "m", ew).call(this), ww(this, Nv, "f").scene.remove(ww(this, bv, "f").camera), ww(this, Nv, "f").scene.remove(ww(this, xv, "f").camera), null === (e = ww(this, Zv, "f")) || void 0 === e || e.dispose(); for (const e of ww(this, Kv, "f")) e.dispose(); ww(this, Kv, "f").length = 0, ww(this, Nv, "f").scene.remove(ww(this, Bv, "f")), ww(this, Vv, "f").dispose(), null === (t = ww(this, kv, "f")) || void 0 === t || t.deleteCar(ww(this, Sv, "f").id), null != ww(this, Jv, "f") && (null === (n = ww(this, Mv, "f")) || void 0 === n || n.removeChangeCallback(ww(this, Jv, "f"))) } addResetCallback(e) { ww(this, Cv, "f").push(e) } addCheckpointCallback(e) { ww(this, Pv, "f").push(e) } addFinishCallback(e) { ww(this, Iv, "f").push(e) } getChassisMatrix() { return null != ww(this, Uv, "f") ? ww(this, Uv, "f").matrix : null } getSpeedKmh() { return ww(this, Sv, "f").speedKmh } start() { var e; null === (e = ww(this, kv, "f")) || void 0 === e || e.startCar(ww(this, Sv, "f").id, null) } hasStarted() { return ww(this, Sv, "f").hasStarted } hasFinished() { return null != ww(this, Sv, "f").finishFrames } getFinishTime() { return null == ww(this, Sv, "f").finishFrames ? null : new xp(ww(this, Sv, "f").finishFrames) } getRecording() { return ww(this, _v, "f") } getTime() { return new xp(ww(this, Sv, "f").frames) } getNextCheckpointIndex() { return ww(this, Sv, "f").nextCheckpointIndex } hasCheckpointToRespawnAt() { return ww(this, Sv, "f").hasCheckpointToRespawnAt } getPosition() { return new yn(ww(this, Sv, "f").position.x, ww(this, Sv, "f").position.y, ww(this, Sv, "f").position.z) } getQuaternion() { return new wn(ww(this, Sv, "f").quaternion.x, ww(this, Sv, "f").quaternion.y, ww(this, Sv, "f").quaternion.z, ww(this, Sv, "f").quaternion.w) } getMatrix4() { const e = this.getPosition(), t = this.getQuaternion(), n = (new qn).makeRotationFromQuaternion(t); return n.setPosition(e), n } get isPaused() { return ww(this, Ev, "f") } set isPaused(e) { var t; ww(this, Ev, "f") != e && (null === (t = ww(this, kv, "f")) || void 0 === t || t.pauseCar(ww(this, Sv, "f").id, e), vw(this, Ev, e, "f")) } getControls() { return null != ww(this, Mv, "f") ? ww(this, Mv, "f").getControls() : ww(this, Sv, "f").controls } getColors() { return ww(this, Gv, "f") } setColors(e) { if (ww(this, Hv, "f").value = (new yn).setFromColor(e.secondary), null != ww(this, Uv, "f") && Array.isArray(ww(this, Uv, "f").material)) for (const t of ww(this, Uv, "f").material) "Main" == t.name ? t.color.set(e.primary) : "Metal" == t.name && t.color.set(e.frame); if (null != ww(this, zv, "f") && !Array.isArray(ww(this, zv, "f").material)) { const t = ww(this, zv, "f").material; "Metal" == t.name && t.color.set(e.frame) } for (const t of ww(this, Ov, "f")) if (Array.isArray(t.material)) for (const n of t.material) "Metal" == n.name ? n.color.set(e.frame) : "Rim" == n.name && n.color.set(e.rims); vw(this, Gv, e, "f") } setOpacity(e) { for (const t of ww(this, Bv, "f").children) { const n = t; let i; i = Array.isArray(n.material) ? n.material : [n.material]; for (const t of i) { t.opacity = e; const n = e < 1; t.needsUpdate = n != t.transparent, t.transparent = n } } } setVisible(e) { ww(this, Bv, "f").visible = e } setCarState(e) { var t; if (ww(this, $v, "f")) return; const n = ww(this, Sv, "f"); vw(this, Sv, e, "f"); const i = ww(this, Sv, "f").frames != n.frames && ww(this, Sv, "f").frames != n.frames + 1; if (ww(this, Sv, "f").nextCheckpointIndex > n.nextCheckpointIndex) { this.notificationAudioEnabled && ww(this, hv, "m", iw).call(this); for (const e of ww(this, Pv, "f")) e(n.nextCheckpointIndex) } if (null != ww(this, Sv, "f").finishFrames && null == n.finishFrames) { this.notificationAudioEnabled && ww(this, hv, "m", rw).call(this); for (const e of ww(this, Iv, "f")) e(this) } const r = .001; if (i) { null === (t = ww(this, Zv, "f")) || void 0 === t || t.clear(); for (const e of ww(this, Kv, "f")) e.clear() } if (this.getTime().numberOfFrames % 10 == 0 && ww(this, hv, "m", aw).call(this, .01), i || !n.controls.reset && ww(this, Sv, "f").controls.reset) { ww(this, bv, "f").reset(this.getPosition(), this.getQuaternion(), this.getSpeedKmh()), ww(this, xv, "f").reset(this.getPosition(), this.getQuaternion(), this.getSpeedKmh()); for (const e of ww(this, Cv, "f")) e() } ww(this, hv, "m", lw).call(this, r), ww(this, hv, "m", hw).call(this, r), ww(this, Tv, "f") && ww(this, Sv, "f").hasStarted && null == n.finishFrames && ww(this, _v, "f").recordFrame(n.frames, ww(this, Sv, "f").controls) } update(e) { var t, n; if (null != ww(this, Uv, "f") && null != ww(this, zv, "f")) { ww(this, hv, "m", sw).call(this), null === (t = ww(this, Zv, "f")) || void 0 === t || t.update(e); const i = this.getMatrix4(), r = this.getQuaternion(); ww(this, Uv, "f").matrixAutoUpdate = !1, ww(this, Uv, "f").matrix.copy(i), ww(this, Uv, "f").matrix.multiply((new qn).makeTranslation(0, dv.massOffset, 0)), ww(this, zv, "f").matrixAutoUpdate = !1, ww(this, zv, "f").matrix.copy(ww(this, Uv, "f").matrix); const a = 4; for (let t = 0; t < a; t++) { const i = ww(this, Sv, "f").wheelInContact[t], a = ww(this, Sv, "f").wheelDeltaRotation[t]; if (this.hasStarted()) { if (i) ww(this, Rv, "f")[t] = 1e3 * a, ww(this, Lv, "f")[t] = 1e3 * a; else { const { up: n, down: i } = this.getControls(), r = 2 == t || 3 == t; i ? ww(this, Sv, "f").brakeLightEnabled ? ww(this, Lv, "f")[t] > 0 ? ww(this, Lv, "f")[t] = Math.max(0, ww(this, Lv, "f")[t] - 50 * e) : ww(this, Lv, "f")[t] < 0 && (ww(this, Lv, "f")[t] = Math.min(0, ww(this, Lv, "f")[t] + 50 * e)) : r && (ww(this, Rv, "f")[t] -= 25 * e, ww(this, Lv, "f")[t] -= 25 * e) : n && r && (ww(this, Rv, "f")[t] += 25 * e, ww(this, Lv, "f")[t] += 50 * e), ww(this, Rv, "f")[t] *= Math.max(0, 1 - e), ww(this, Lv, "f")[t] *= Math.max(0, 1 - e) } ww(this, Dv, "f")[t] += ww(this, Lv, "f")[t] * e } const s = ww(this, Sv, "f").wheelPosition[t], o = new wn(ww(this, Sv, "f").wheelQuaternion[t].x, ww(this, Sv, "f").wheelQuaternion[t].y, ww(this, Sv, "f").wheelQuaternion[t].z, ww(this, Sv, "f").wheelQuaternion[t].w), l = ww(this, Sv, "f").wheelRotation[t]; o.multiply((new wn).setFromAxisAngle(new yn(-1, 0, 0), ww(this, Dv, "f")[t] - l)), ww(this, Ov, "f")[t].position.set(s.x, s.y, s.z), ww(this, Ov, "f")[t].quaternion.set(o.x, o.y, o.z, o.w); const c = ww(this, Sv, "f").wheelSuspensionLength[t], h = ww(this, Sv, "f").wheelSkidInfo[t]; ww(this, zv, "f").morphTargetInfluences || (ww(this, zv, "f").morphTargetInfluences = []), ww(this, zv, "f").morphTargetInfluences[t] = 2 * c + .06, e > 0 && (null === (n = ww(this, Yv, "f")) || void 0 === n ? void 0 : n.getSettingBoolean($o.SkidmarksEnabled)) && t < ww(this, Kv, "f").length && i && a > .06 && h < .5 && 0 == ww(this, Xv, "f")[t] && ww(this, Kv, "f")[t].spawn(s.x, s.y, s.z, r) } ww(this, hv, "m", pw).call(this, ww(this, Sv, "f").brakeLightEnabled) } } updateCameras(e) { if (null == ww(this, Sv, "f").finishFrames) { const t = this.getPosition(), n = this.getQuaternion(), i = this.getSpeedKmh(); ww(this, bv, "f").update(e, t, n, i), ww(this, xv, "f").update(t, n, i) } } get cameraOrbit() { return ww(this, bv, "f").camera } get cameraCockpit() { return ww(this, xv, "f").camera } set audioVolume(e) { vw(this, fv, e, "f"), null != ww(this, pv, "f") && ww(this, pv, "f").gain.setTargetAtTime(ww(this, fv, "f"), 0, .01) } static initResources() { return gw(this, void 0, void 0, (function*() { const e = yield new Promise(((e, t) => { (new vl).load("models/car.glb", (n => { function i(e) { const t = n.scene.getObjectByName(e); if (null == t) throw new Error('Mesh "' + e + '" does not exist'); if (0 == t.children.length) { const e = t; return e.updateMatrixWorld(!0), e.geometry.applyMatrix4(e.matrix.clone()), e.matrix.identity(), e } const i = pl(t.children.map((e => e.geometry)), !0); t.updateMatrixWorld(!0), i.applyMatrix4(t.matrix.clone()); const r = t.children.map((e => e.material)), a = new wr(i, r); return a.name = e, a } function r(e) { let t; t = Array.isArray(e.material) ? e.material : [e.material]; for (const e of t) e.side = 0; return e } dv.models = { chassis: r(i("Body")), suspension: r(i("Suspension")), suspensionFL: r(i("SuspensionFL")), suspensionFR: r(i("SuspensionFR")), suspensionBL: r(i("SuspensionBL")), suspensionBR: r(i("SuspensionBR")), wheelFL: r(i("WheelFL")), wheelFR: r(i("WheelFR")), wheelBL: r(i("WheelBL")), wheelBR: r(i("WheelBR")), collisionShapeVertices: ww(dv, dv, "m", fw).call(dv, i("Collision")) }, dv.models.wheelFL.geometry.translate(-.627909, .218824, -1.3478), dv.models.wheelFR.geometry.translate(.627909, .218824, -1.3478), dv.models.wheelBL.geometry.translate(-.720832, .218824, 1.52686), dv.models.wheelBR.geometry.translate(.720832, .218824, 1.52686), dv.models.wheelFL.geometry.rotateZ(Math.PI), dv.models.wheelFR.geometry.rotateZ(Math.PI), dv.models.wheelBL.geometry.rotateZ(Math.PI), dv.models.wheelBR.geometry.rotateZ(Math.PI), ww(dv, dv, "m", mw).call(dv).then((t => { e(t) })).catch(t) }), void 0, t) })); return yield new Promise(((e, t) => { const n = new Image; n.addEventListener("load", (() => { e() })), n.addEventListener("error", (() => { t(new Error("Failed to load image")) })), n.src = "images/car_stripe.svg", dv.images = { stripe: n } })), e })) } } dv = yw, uv = new WeakMap, pv = new WeakMap, fv = new WeakMap, mv = new WeakMap, gv = new WeakMap, vv = new WeakMap, wv = new WeakMap, yv = new WeakMap, Av = new WeakMap, bv = new WeakMap, xv = new WeakMap, kv = new WeakMap, Ev = new WeakMap, Sv = new WeakMap, Mv = new WeakMap, Tv = new WeakMap, _v = new WeakMap, Cv = new WeakMap, Pv = new WeakMap, Iv = new WeakMap, Rv = new WeakMap, Lv = new WeakMap, Dv = new WeakMap, Nv = new WeakMap, Bv = new WeakMap, Uv = new WeakMap, zv = new WeakMap, Ov = new WeakMap, Fv = new WeakMap, Wv = new WeakMap, Vv = new WeakMap, Hv = new WeakMap, Gv = new WeakMap, jv = new WeakMap, Qv = new WeakMap, Yv = new WeakMap, Kv = new WeakMap, qv = new WeakMap, Xv = new WeakMap, Zv = new WeakMap, Jv = new WeakMap, $v = new WeakMap, hv = new WeakSet, ew = function() { ww(this, hv, "m", nw).call(this), setTimeout((() => { if (null != ww(this, mv, "f") && (ww(this, mv, "f").source.stop(), vw(this, mv, null, "f")), null != ww(this, vv, "f")) { for (const { source: e } of ww(this, vv, "f")) e.stop(); vw(this, vv, null, "f") } }), 200) }, tw = function() { if (null == dv.images) throw new Error("Car images are not loaded yet"); ww(this, Wv, "f").clearRect(0, 0, ww(this, Wv, "f").canvas.width, ww(this, Wv, "f").canvas.height), ww(this, Wv, "f").drawImage(dv.images.stripe, 0, 0, ww(this, Wv, "f").canvas.width, ww(this, Wv, "f").canvas.height), ww(this, Vv, "f").needsUpdate = !0 }, nw = function() { if (null != ww(this, mv, "f") && (ww(this, mv, "f").source.playbackRate.setTargetAtTime(.7, 0, .15), ww(this, mv, "f").gain.gain.setTargetAtTime(0, 0, .15)), null != ww(this, vv, "f")) for (const e of ww(this, vv, "f")) e.source.playbackRate.setTargetAtTime(.3, 0, .15), e.gain.gain.setTargetAtTime(0, 0, .15); if (null != ww(this, qv, "f")) { for (const { source: e } of ww(this, qv, "f")) e.stop(); vw(this, qv, null, "f") } }, iw = function() { var e, t; const n = null !== (t = null === (e = ww(this, Yv, "f")) || void 0 === e ? void 0 : e.getSettingFloat($o.CheckpointVolume)) && void 0 !== t ? t : 0; let i = Math.min(Math.max(ww(this, fv, "f") * n, 0), 1); if (Number.isNaN(i) && (i = 0), i > 0 && null != ww(this, uv, "f")) { const e = ww(this, uv, "f").getBuffer("checkpoint"); if (null != e && null != ww(this, uv, "f").context && null != ww(this, uv, "f").destinationMaster) { const t = ww(this, uv, "f").context.createBufferSource(); t.buffer = e, t.playbackRate.value = 1.25; const n = ww(this, uv, "f").context.createGain(); n.gain.value = .03 * i, t.connect(n), n.connect(ww(this, uv, "f").destinationMaster), t.start(0) } } }, rw = function() { var e, t; const n = null !== (t = null === (e = ww(this, Yv, "f")) || void 0 === e ? void 0 : e.getSettingFloat($o.CheckpointVolume)) && void 0 !== t ? t : 0; let i = Math.min(Math.max(ww(this, fv, "f") * n, 0), 1); if (Number.isNaN(i) && (i = 0), i > 0 && null != ww(this, uv, "f")) { const e = ww(this, uv, "f").getBuffer("finish"); if (null != e && null != ww(this, uv, "f").context && null != ww(this, uv, "f").destinationMaster) { const t = ww(this, uv, "f").context.createBufferSource(); t.buffer = e, t.playbackRate.value = 1.25; const n = ww(this, uv, "f").context.createGain(); n.gain.value = .03, t.connect(n), n.connect(ww(this, uv, "f").destinationMaster), t.start(0) } } }, aw = function(e) { var t; for (let n = 0; n < 4; n++) { const i = ww(this, Sv, "f").wheelPosition[n], r = ww(this, Sv, "f").wheelInContact[n], a = ww(this, Sv, "f").wheelDeltaRotation[n], s = ww(this, Sv, "f").wheelSkidInfo[n]; r && a > .06 && s < .5 ? (n < ww(this, Kv, "f").length && (ww(this, Xv, "f")[n] = Math.max(0, ww(this, Xv, "f")[n] - e)), 0 == ww(this, Xv, "f")[n] && null != ww(this, Zv, "f") && ww(this, Zv, "f").spawn(i.x, i.y, i.z)) : (n < ww(this, Kv, "f").length && (null === (t = ww(this, Yv, "f")) || void 0 === t ? void 0 : t.getSettingBoolean($o.SkidmarksEnabled)) && ww(this, Kv, "f")[n].break(), ww(this, Xv, "f")[n] = .075) } }, sw = function() { if (null != ww(this, uv, "f") && null != ww(this, uv, "f").context && null != ww(this, uv, "f").destinationSfx) { null == ww(this, pv, "f") && (vw(this, pv, ww(this, uv, "f").context.createGain(), "f"), ww(this, pv, "f").gain.value = ww(this, fv, "f"), ww(this, pv, "f").connect(ww(this, uv, "f").destinationSfx)), null == ww(this, yv, "f") && (vw(this, yv, ww(this, uv, "f").context.createPanner(), "f"), ww(this, yv, "f").refDistance = 5, ww(this, yv, "f").connect(ww(this, pv, "f"))); const e = this.getPosition(); ww(this, yv, "f").positionX.value = e.x, ww(this, yv, "f").positionY.value = e.y, ww(this, yv, "f").positionZ.value = e.z; const t = 4; if (ww(this, Av, "f").length < t) { ww(this, Av, "f").length = 0; for (let e = 0; e < t; ++e) { const e = ww(this, uv, "f").context.createPanner(); e.refDistance = 5, e.connect(ww(this, pv, "f")), ww(this, Av, "f").push(e) } } for (let e = 0; e < t; ++e) { const t = ww(this, Av, "f")[e], n = ww(this, Sv, "f").wheelPosition[e]; t.positionX.value = n.x, t.positionY.value = n.y, t.positionZ.value = n.z } ww(this, Nv, "f").camera != ww(this, bv, "f").camera && ww(this, Nv, "f").camera != ww(this, xv, "f").camera || ww(this, uv, "f").refreshListener(ww(this, Nv, "f")), ww(this, hv, "m", ow).call(this), ww(this, hv, "m", cw).call(this), ww(this, hv, "m", uw).call(this) } }, ow = function() { if (null == ww(this, mv, "f") && null != ww(this, yv, "f") && null != ww(this, uv, "f")) { const e = ww(this, uv, "f").getBuffer("engine"); if (null != e && null != ww(this, uv, "f").context) { const t = ww(this, uv, "f").context.createBufferSource(); t.buffer = e, t.loop = !0, t.playbackRate.value = .7; const n = ww(this, uv, "f").context.createGain(); n.gain.value = 0, t.connect(n), n.connect(ww(this, yv, "f")), t.start(0, 2 * Math.random()), vw(this, mv, { source: t, gain: n }, "f") } } if (null != ww(this, mv, "f")) { const e = (ww(this, Rv, "f")[0] + ww(this, Rv, "f")[1] + ww(this, Rv, "f")[2] + ww(this, Rv, "f")[3]) / 4, t = .7 + Math.pow(Math.abs(e), 1 / 3) / 3, n = ww(this, Sv, "f").wheelInContact[0] || ww(this, Sv, "f").wheelInContact[1] || ww(this, Sv, "f").wheelInContact[2] || ww(this, Sv, "f").wheelInContact[3], { up: i, down: r } = this.getControls(), a = this.hasStarted() && !this.hasFinished() && (i && !(r && ww(this, Sv, "f").brakeLightEnabled) || r && !ww(this, Sv, "f").brakeLightEnabled); let s; s = n ? a ? t : Math.max(.7, t / 2) : a ? Math.max(.7, 1.15 * t) : Math.max(.7, t / 2), ww(this, mv, "f").source.playbackRate.setTargetAtTime(s, 0, .05), ww(this, mv, "f").gain.gain.setTargetAtTime(Math.min(.285, s / 14), 0, .05) } }, lw = function(e) { if (ww(this, gv, "f").length < 4) { ww(this, gv, "f").length = 0; for (let e = 0; e < 4; ++e) ww(this, gv, "f").push(0) } for (let t = 0; t < 4 && t < ww(this, Av, "f").length; t++) if (ww(this, gv, "f")[t] -= e, ww(this, gv, "f")[t] <= 0) { const e = Math.abs(ww(this, Sv, "f").wheelSuspensionVelocity[t]); if (e > 4 && null != ww(this, uv, "f")) { const n = ww(this, uv, "f").getBuffer("suspension"); if (null != n && null != ww(this, uv, "f").context) { const i = ww(this, uv, "f").context.createBufferSource(); i.buffer = n, i.playbackRate.value = .7 + .1 * Math.random(); const r = ww(this, uv, "f").context.createGain(); r.gain.value = Math.min(.285, e / 140), i.connect(r), r.connect(ww(this, Av, "f")[t]), i.start(ww(this, uv, "f").context.currentTime + .02 * Math.random()), ww(this, gv, "f")[t] = .1 } } } }, cw = function() { if (null == ww(this, vv, "f") && null != ww(this, uv, "f")) { const e = ww(this, uv, "f").getBuffer("tires"); if (null != e && null != ww(this, uv, "f").context) { vw(this, vv, [], "f"); const t = 4; for (let n = 0; n < t; n++) { const i = ww(this, uv, "f").context.createBufferSource(); i.buffer = e, i.loop = !0, i.playbackRate.value = .3; const r = ww(this, uv, "f").context.createGain(); r.gain.value = 0, i.connect(r), r.connect(ww(this, Av, "f")[n]), i.start(0, n / t * 3.5 + .25 * Math.random()), ww(this, vv, "f").push({ source: i, gain: r }) } } } if (null != ww(this, vv, "f")) for (let e = 0; e < ww(this, vv, "f").length; ++e) { const t = ww(this, vv, "f")[e]; if (ww(this, Sv, "f").wheelInContact[e]) { const e = Math.min(3, Math.abs(this.getSpeedKmh()) / 110); t.gain.gain.setTargetAtTime(e / 10.5, 0, .15) } else t.gain.gain.setTargetAtTime(0, 0, .15); const n = .3 + Math.min(.4, Math.abs(this.getSpeedKmh()) / 800); t.source.playbackRate.setTargetAtTime(n, 0, .15) } }, hw = function(e) { null != ww(this, wv, "f") && (ww(this, wv, "f").timeout -= e, ww(this, wv, "f").timeout <= 0 && vw(this, wv, null, "f")); const t = ww(this, Sv, "f").collisionImpulses; for (const e of t) ww(this, hv, "m", dw).call(this, e) }, dw = function(e) { if (e > 25 && null != ww(this, yv, "f") && null != ww(this, uv, "f") && (null == ww(this, wv, "f") || ww(this, wv, "f").impulse + 100 < e)) { vw(this, wv, { timeout: .2, impulse: e }, "f"); const t = ww(this, uv, "f").getBuffer("collision"); if (null != t && null != ww(this, uv, "f").context) { const n = ww(this, uv, "f").context.createBufferSource(); n.buffer = t, n.playbackRate.value = .1 + .15 * Math.min(e / 4e3, 1); const i = ww(this, uv, "f").context.createGain(); i.gain.value = Math.max(.3, Math.min(e / 4e3, 1)) / 2.5, n.connect(i), i.connect(ww(this, yv, "f")), n.start(0) } } }, uw = function() { if (null == ww(this, qv, "f") && null != ww(this, uv, "f")) { const e = ww(this, uv, "f").getBuffer("skidding"); if (null != e && null != ww(this, uv, "f").context) { vw(this, qv, [], "f"); const t = 4; for (let n = 0; n < t; ++n) { const i = ww(this, uv, "f").context.createBufferSource(); i.buffer = e, i.loop = !0, i.playbackRate.value = .5; const r = ww(this, uv, "f").context.createGain(); r.gain.value = 0, i.connect(r), r.connect(ww(this, Av, "f")[n]), i.start(0, n / t * 3.5 + .25 * Math.random()), ww(this, qv, "f").push({ source: i, gain: r }) } } } if (null != ww(this, qv, "f")) for (let e = 0; e < ww(this, qv, "f").length; ++e) { const t = ww(this, qv, "f")[e]; 0 == ww(this, Xv, "f")[e] ? t.gain.gain.setTargetAtTime(.75 / 3.5, 0, .1) : t.gain.gain.setTargetAtTime(0, 0, .1) } }, pw = function(e) { null != ww(this, Fv, "f") && (e ? ww(this, Fv, "f").emissive.setRGB(1, .4, .3) : ww(this, Fv, "f").emissive.setRGB(0, 0, 0)) }, fw = function(e) { const t = e.geometry.toNonIndexed(); if (!(t.attributes.position instanceof qi)) throw new Error("Vertices must use BufferAttribute"); return Array.from(t.attributes.position.array) }, mw = function() { return gw(this, void 0, void 0, (function*() { if (null == dv.models) throw new Error("Car models are not loaded yet"); const e = new Float32Array(dv.models.collisionShapeVertices), t = yield window.crypto.subtle.digest("SHA-256", e.buffer), n = Array.from(new Uint8Array(t)).map((e => e.toString(16).padStart(2, "0"))).join(""), i = "dd663fb6330ed93725bf865d5eac2cd29ba19f74dbb3f67ae7f695ea1f68aed0"; return n == i || console.error("Car collision model checksum mismatch: " + n + " != " + i), n == i })) }, yw.massOffset = .6, yw.detectorBoxCenter = new yn(0, .48, -.15), yw.detectorBoxSize = new yn(.89, .22, 1.8), yw.suspensionResetLengthFront = .07809501004219055, yw.suspensionResetLengthRear = .0781289680480957, yw.models = null, yw.images = null; const Aw = yw; var bw = n(5959), xw = {}; xw.styleTagTransform = u(), xw.setAttributes = l(), xw.insert = s().bind(null, "head"), xw.domAPI = r(), xw.insertStyleElement = h(); t()(bw.A, xw); bw.A && bw.A.locals && bw.A.locals; const kw = { type: "change" }, Ew = { type: "start" }, Sw = { type: "end" }, Mw = new Kn, Tw = new ga, _w = Math.cos(70 * Gt.DEG2RAD), Cw = new yn, Pw = 2 * Math.PI, Iw = -1, Rw = 0, Lw = 1, Dw = 2, Nw = 3, Bw = 4, Uw = 5, zw = 6, Ow = 1e-6; class Fw extends Xo { constructor(e, t = null) { super(e, t), this.state = Iw, this.enabled = !0, this.target = new yn, this.cursor = new yn, this.minDistance = 0, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.minTargetRadius = 0, this.maxTargetRadius = 1 / 0, this.minPolarAngle = 0, this.maxPolarAngle = Math.PI, this.minAzimuthAngle = -1 / 0, this.maxAzimuthAngle = 1 / 0, this.enableDamping = !1, this.dampingFactor = .05, this.enableZoom = !0, this.zoomSpeed = 1, this.enableRotate = !0, this.rotateSpeed = 1, this.keyRotateSpeed = 1, this.enablePan = !0, this.panSpeed = 1, this.screenSpacePanning = !0, this.keyPanSpeed = 7, this.zoomToCursor = !1, this.autoRotate = !1, this.autoRotateSpeed = 2, this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" }, this.mouseButtons = { LEFT: g, MIDDLE: v, RIGHT: w }, this.touches = { ONE: y, TWO: b }, this.target0 = this.target.clone(), this.position0 = this.object.position.clone(), this.zoom0 = this.object.zoom, this._domElementKeyEvents = null, this._lastPosition = new yn, this._lastQuaternion = new wn, this._lastTargetPosition = new yn, this._quat = (new wn).setFromUnitVectors(e.up, new yn(0, 1, 0)), this._quatInverse = this._quat.clone().invert(), this._spherical = new Ko, this._sphericalDelta = new Ko, this._scale = 1, this._panOffset = new yn, this._rotateStart = new jt, this._rotateEnd = new jt, this._rotateDelta = new jt, this._panStart = new jt, this._panEnd = new jt, this._panDelta = new jt, this._dollyStart = new jt, this._dollyEnd = new jt, this._dollyDelta = new jt, this._dollyDirection = new yn, this._mouse = new jt, this._performCursorZoom = !1, this._pointers = [], this._pointerPositions = {}, this._controlActive = !1, this._onPointerMove = Vw.bind(this), this._onPointerDown = Ww.bind(this), this._onPointerUp = Hw.bind(this), this._onContextMenu = Xw.bind(this), this._onMouseWheel = Qw.bind(this), this._onKeyDown = Yw.bind(this), this._onTouchStart = Kw.bind(this), this._onTouchMove = qw.bind(this), this._onMouseDown = Gw.bind(this), this._onMouseMove = jw.bind(this), this._interceptControlDown = Zw.bind(this), this._interceptControlUp = Jw.bind(this), null !== this.domElement && this.connect(), this.update() } connect() { this.domElement.addEventListener("pointerdown", this._onPointerDown), this.domElement.addEventListener("pointercancel", this._onPointerUp), this.domElement.addEventListener("contextmenu", this._onContextMenu), this.domElement.addEventListener("wheel", this._onMouseWheel, { passive: !1 }); this.domElement.getRootNode().addEventListener("keydown", this._interceptControlDown, { passive: !0, capture: !0 }), this.domElement.style.touchAction = "none" } disconnect() { this.domElement.removeEventListener("pointerdown", this._onPointerDown), this.domElement.removeEventListener("pointermove", this._onPointerMove), this.domElement.removeEventListener("pointerup", this._onPointerUp), this.domElement.removeEventListener("pointercancel", this._onPointerUp), this.domElement.removeEventListener("wheel", this._onMouseWheel), this.domElement.removeEventListener("contextmenu", this._onContextMenu), this.stopListenToKeyEvents(); this.domElement.getRootNode().removeEventListener("keydown", this._interceptControlDown, { capture: !0 }), this.domElement.style.touchAction = "auto" } dispose() { this.disconnect() } getPolarAngle() { return this._spherical.phi } getAzimuthalAngle() { return this._spherical.theta } getDistance() { return this.object.position.distanceTo(this.target) } listenToKeyEvents(e) { e.addEventListener("keydown", this._onKeyDown), this._domElementKeyEvents = e } stopListenToKeyEvents() { null !== this._domElementKeyEvents && (this._domElementKeyEvents.removeEventListener("keydown", this._onKeyDown), this._domElementKeyEvents = null) } saveState() { this.target0.copy(this.target), this.position0.copy(this.object.position), this.zoom0 = this.object.zoom } reset() { this.target.copy(this.target0), this.object.position.copy(this.position0), this.object.zoom = this.zoom0, this.object.updateProjectionMatrix(), this.dispatchEvent(kw), this.update(), this.state = Iw } update(e = null) { const t = this.object.position; Cw.copy(t).sub(this.target), Cw.applyQuaternion(this._quat), this._spherical.setFromVector3(Cw), this.autoRotate && this.state === Iw && this._rotateLeft(this._getAutoRotationAngle(e)), this.enableDamping ? (this._spherical.theta += this._sphericalDelta.theta * this.dampingFactor, this._spherical.phi += this._sphericalDelta.phi * this.dampingFactor) : (this._spherical.theta += this._sphericalDelta.theta, this._spherical.phi += this._sphericalDelta.phi); let n = this.minAzimuthAngle, i = this.maxAzimuthAngle; isFinite(n) && isFinite(i) && (n < -Math.PI ? n += Pw : n > Math.PI && (n -= Pw), i < -Math.PI ? i += Pw : i > Math.PI && (i -= Pw), this._spherical.theta = n <= i ? Math.max(n, Math.min(i, this._spherical.theta)) : this._spherical.theta > (n + i) / 2 ? Math.max(n, this._spherical.theta) : Math.min(i, this._spherical.theta)), this._spherical.phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this._spherical.phi)), this._spherical.makeSafe(), !0 === this.enableDamping ? this.target.addScaledVector(this._panOffset, this.dampingFactor) : this.target.add(this._panOffset), this.target.sub(this.cursor), this.target.clampLength(this.minTargetRadius, this.maxTargetRadius), this.target.add(this.cursor); let r = !1; if (this.zoomToCursor && this._performCursorZoom || this.object.isOrthographicCamera) this._spherical.radius = this._clampDistance(this._spherical.radius); else { const e = this._spherical.radius; this._spherical.radius = this._clampDistance(this._spherical.radius * this._scale), r = e != this._spherical.radius } if (Cw.setFromSpherical(this._spherical), Cw.applyQuaternion(this._quatInverse), t.copy(this.target).add(Cw), this.object.lookAt(this.target), !0 === this.enableDamping ? (this._sphericalDelta.theta *= 1 - this.dampingFactor, this._sphericalDelta.phi *= 1 - this.dampingFactor, this._panOffset.multiplyScalar(1 - this.dampingFactor)) : (this._sphericalDelta.set(0, 0, 0), this._panOffset.set(0, 0, 0)), this.zoomToCursor && this._performCursorZoom) { let e = null; if (this.object.isPerspectiveCamera) { const t = Cw.length(); e = this._clampDistance(t * this._scale); const n = t - e; this.object.position.addScaledVector(this._dollyDirection, n), this.object.updateMatrixWorld(), r = !!n } else if (this.object.isOrthographicCamera) { const t = new yn(this._mouse.x, this._mouse.y, 0); t.unproject(this.object); const n = this.object.zoom; this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / this._scale)), this.object.updateProjectionMatrix(), r = n !== this.object.zoom; const i = new yn(this._mouse.x, this._mouse.y, 0); i.unproject(this.object), this.object.position.sub(i).add(t), this.object.updateMatrixWorld(), e = Cw.length() } else console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."), this.zoomToCursor = !1; null !== e && (this.screenSpacePanning ? this.target.set(0, 0, -1).transformDirection(this.object.matrix).multiplyScalar(e).add(this.object.position) : (Mw.origin.copy(this.object.position), Mw.direction.set(0, 0, -1).transformDirection(this.object.matrix), Math.abs(this.object.up.dot(Mw.direction)) < _w ? this.object.lookAt(this.target) : (Tw.setFromNormalAndCoplanarPoint(this.object.up, this.target), Mw.intersectPlane(Tw, this.target)))) } else if (this.object.isOrthographicCamera) { const e = this.object.zoom; this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / this._scale)), e !== this.object.zoom && (this.object.updateProjectionMatrix(), r = !0) } return this._scale = 1, this._performCursorZoom = !1, !!(r || this._lastPosition.distanceToSquared(this.object.position) > Ow || 8 * (1 - this._lastQuaternion.dot(this.object.quaternion)) > Ow || this._lastTargetPosition.distanceToSquared(this.target) > Ow) && (this.dispatchEvent(kw), this._lastPosition.copy(this.object.position), this._lastQuaternion.copy(this.object.quaternion), this._lastTargetPosition.copy(this.target), !0) } _getAutoRotationAngle(e) { return null !== e ? Pw / 60 * this.autoRotateSpeed * e : Pw / 60 / 60 * this.autoRotateSpeed } _getZoomScale(e) { const t = Math.abs(.01 * e); return Math.pow(.95, this.zoomSpeed * t) } _rotateLeft(e) { this._sphericalDelta.theta -= e } _rotateUp(e) { this._sphericalDelta.phi -= e } _panLeft(e, t) { Cw.setFromMatrixColumn(t, 0), Cw.multiplyScalar(-e), this._panOffset.add(Cw) } _panUp(e, t) { !0 === this.screenSpacePanning ? Cw.setFromMatrixColumn(t, 1) : (Cw.setFromMatrixColumn(t, 0), Cw.crossVectors(this.object.up, Cw)), Cw.multiplyScalar(e), this._panOffset.add(Cw) } _pan(e, t) { const n = this.domElement; if (this.object.isPerspectiveCamera) { const i = this.object.position; Cw.copy(i).sub(this.target); let r = Cw.length(); r *= Math.tan(this.object.fov / 2 * Math.PI / 180), this._panLeft(2 * e * r / n.clientHeight, this.object.matrix), this._panUp(2 * t * r / n.clientHeight, this.object.matrix) } else this.object.isOrthographicCamera ? (this._panLeft(e * (this.object.right - this.object.left) / this.object.zoom / n.clientWidth, this.object.matrix), this._panUp(t * (this.object.top - this.object.bottom) / this.object.zoom / n.clientHeight, this.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), this.enablePan = !1) } _dollyOut(e) { this.object.isPerspectiveCamera || this.object.isOrthographicCamera ? this._scale /= e : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), this.enableZoom = !1) } _dollyIn(e) { this.object.isPerspectiveCamera || this.object.isOrthographicCamera ? this._scale *= e : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), this.enableZoom = !1) } _updateZoomParameters(e, t) { if (!this.zoomToCursor) return; this._performCursorZoom = !0; const n = this.domElement.getBoundingClientRect(), i = e - n.left, r = t - n.top, a = n.width, s = n.height; this._mouse.x = i / a * 2 - 1, this._mouse.y = -r / s * 2 + 1, this._dollyDirection.set(this._mouse.x, this._mouse.y, 1).unproject(this.object).sub(this.object.position).normalize() } _clampDistance(e) { return Math.max(this.minDistance, Math.min(this.maxDistance, e)) } _handleMouseDownRotate(e) { this._rotateStart.set(e.clientX, e.clientY) } _handleMouseDownDolly(e) { this._updateZoomParameters(e.clientX, e.clientX), this._dollyStart.set(e.clientX, e.clientY) } _handleMouseDownPan(e) { this._panStart.set(e.clientX, e.clientY) } _handleMouseMoveRotate(e) { this._rotateEnd.set(e.clientX, e.clientY), this._rotateDelta.subVectors(this._rotateEnd, this._rotateStart).multiplyScalar(this.rotateSpeed); const t = this.domElement; this._rotateLeft(Pw * this._rotateDelta.x / t.clientHeight), this._rotateUp(Pw * this._rotateDelta.y / t.clientHeight), this._rotateStart.copy(this._rotateEnd), this.update() } _handleMouseMoveDolly(e) { this._dollyEnd.set(e.clientX, e.clientY), this._dollyDelta.subVectors(this._dollyEnd, this._dollyStart), this._dollyDelta.y > 0 ? this._dollyOut(this._getZoomScale(this._dollyDelta.y)) : this._dollyDelta.y < 0 && this._dollyIn(this._getZoomScale(this._dollyDelta.y)), this._dollyStart.copy(this._dollyEnd), this.update() } _handleMouseMovePan(e) { this._panEnd.set(e.clientX, e.clientY), this._panDelta.subVectors(this._panEnd, this._panStart).multiplyScalar(this.panSpeed), this._pan(this._panDelta.x, this._panDelta.y), this._panStart.copy(this._panEnd), this.update() } _handleMouseWheel(e) { this._updateZoomParameters(e.clientX, e.clientY), e.deltaY < 0 ? this._dollyIn(this._getZoomScale(e.deltaY)) : e.deltaY > 0 && this._dollyOut(this._getZoomScale(e.deltaY)), this.update() } _handleKeyDown(e) { let t = !1; switch (e.code) { case this.keys.UP: e.ctrlKey || e.metaKey || e.shiftKey ? this.enableRotate && this._rotateUp(Pw * this.keyRotateSpeed / this.domElement.clientHeight) : this.enablePan && this._pan(0, this.keyPanSpeed), t = !0; break; case this.keys.BOTTOM: e.ctrlKey || e.metaKey || e.shiftKey ? this.enableRotate && this._rotateUp(-Pw * this.keyRotateSpeed / this.domElement.clientHeight) : this.enablePan && this._pan(0, -this.keyPanSpeed), t = !0; break; case this.keys.LEFT: e.ctrlKey || e.metaKey || e.shiftKey ? this.enableRotate && this._rotateLeft(Pw * this.keyRotateSpeed / this.domElement.clientHeight) : this.enablePan && this._pan(this.keyPanSpeed, 0), t = !0; break; case this.keys.RIGHT: e.ctrlKey || e.metaKey || e.shiftKey ? this.enableRotate && this._rotateLeft(-Pw * this.keyRotateSpeed / this.domElement.clientHeight) : this.enablePan && this._pan(-this.keyPanSpeed, 0), t = !0 } t && (e.preventDefault(), this.update()) } _handleTouchStartRotate(e) { if (1 === this._pointers.length) this._rotateStart.set(e.pageX, e.pageY); else { const t = this._getSecondPointerPosition(e), n = .5 * (e.pageX + t.x), i = .5 * (e.pageY + t.y); this._rotateStart.set(n, i) } } _handleTouchStartPan(e) { if (1 === this._pointers.length) this._panStart.set(e.pageX, e.pageY); else { const t = this._getSecondPointerPosition(e), n = .5 * (e.pageX + t.x), i = .5 * (e.pageY + t.y); this._panStart.set(n, i) } } _handleTouchStartDolly(e) { const t = this._getSecondPointerPosition(e), n = e.pageX - t.x, i = e.pageY - t.y, r = Math.sqrt(n * n + i * i); this._dollyStart.set(0, r) } _handleTouchStartDollyPan(e) { this.enableZoom && this._handleTouchStartDolly(e), this.enablePan && this._handleTouchStartPan(e) } _handleTouchStartDollyRotate(e) { this.enableZoom && this._handleTouchStartDolly(e), this.enableRotate && this._handleTouchStartRotate(e) } _handleTouchMoveRotate(e) { if (1 == this._pointers.length) this._rotateEnd.set(e.pageX, e.pageY); else { const t = this._getSecondPointerPosition(e), n = .5 * (e.pageX + t.x), i = .5 * (e.pageY + t.y); this._rotateEnd.set(n, i) } this._rotateDelta.subVectors(this._rotateEnd, this._rotateStart).multiplyScalar(this.rotateSpeed); const t = this.domElement; this._rotateLeft(Pw * this._rotateDelta.x / t.clientHeight), this._rotateUp(Pw * this._rotateDelta.y / t.clientHeight), this._rotateStart.copy(this._rotateEnd) } _handleTouchMovePan(e) { if (1 === this._pointers.length) this._panEnd.set(e.pageX, e.pageY); else { const t = this._getSecondPointerPosition(e), n = .5 * (e.pageX + t.x), i = .5 * (e.pageY + t.y); this._panEnd.set(n, i) } this._panDelta.subVectors(this._panEnd, this._panStart).multiplyScalar(this.panSpeed), this._pan(this._panDelta.x, this._panDelta.y), this._panStart.copy(this._panEnd) } _handleTouchMoveDolly(e) { const t = this._getSecondPointerPosition(e), n = e.pageX - t.x, i = e.pageY - t.y, r = Math.sqrt(n * n + i * i); this._dollyEnd.set(0, r), this._dollyDelta.set(0, Math.pow(this._dollyEnd.y / this._dollyStart.y, this.zoomSpeed)), this._dollyOut(this._dollyDelta.y), this._dollyStart.copy(this._dollyEnd); const a = .5 * (e.pageX + t.x), s = .5 * (e.pageY + t.y); this._updateZoomParameters(a, s) } _handleTouchMoveDollyPan(e) { this.enableZoom && this._handleTouchMoveDolly(e), this.enablePan && this._handleTouchMovePan(e) } _handleTouchMoveDollyRotate(e) { this.enableZoom && this._handleTouchMoveDolly(e), this.enableRotate && this._handleTouchMoveRotate(e) } _addPointer(e) { this._pointers.push(e.pointerId) } _removePointer(e) { delete this._pointerPositions[e.pointerId]; for (let t = 0; t < this._pointers.length; t++) if (this._pointers[t] == e.pointerId) return void this._pointers.splice(t, 1) } _isTrackingPointer(e) { for (let t = 0; t < this._pointers.length; t++) if (this._pointers[t] == e.pointerId) return !0; return !1 } _trackPointer(e) { let t = this._pointerPositions[e.pointerId]; void 0 === t && (t = new jt, this._pointerPositions[e.pointerId] = t), t.set(e.pageX, e.pageY) } _getSecondPointerPosition(e) { const t = e.pointerId === this._pointers[0] ? this._pointers[1] : this._pointers[0]; return this._pointerPositions[t] } _customWheelEvent(e) { const t = e.deltaMode, n = { clientX: e.clientX, clientY: e.clientY, deltaY: e.deltaY }; switch (t) { case 1: n.deltaY *= 16; break; case 2: n.deltaY *= 100 } return e.ctrlKey && !this._controlActive && (n.deltaY *= 10), n } } function Ww(e) { !1 !== this.enabled && (0 === this._pointers.length && (this.domElement.setPointerCapture(e.pointerId), this.domElement.addEventListener("pointermove", this._onPointerMove), this.domElement.addEventListener("pointerup", this._onPointerUp)), this._isTrackingPointer(e) || (this._addPointer(e), "touch" === e.pointerType ? this._onTouchStart(e) : this._onMouseDown(e))) } function Vw(e) { !1 !== this.enabled && ("touch" === e.pointerType ? this._onTouchMove(e) : this._onMouseMove(e)) } function Hw(e) { switch (this._removePointer(e), this._pointers.length) { case 0: this.domElement.releasePointerCapture(e.pointerId), this.domElement.removeEventListener("pointermove", this._onPointerMove), this.domElement.removeEventListener("pointerup", this._onPointerUp), this.dispatchEvent(Sw), this.state = Iw; break; case 1: const t = this._pointers[0], n = this._pointerPositions[t]; this._onTouchStart({ pointerId: t, pageX: n.x, pageY: n.y }) } } function Gw(e) { let t; switch (e.button) { case 0: t = this.mouseButtons.LEFT; break; case 1: t = this.mouseButtons.MIDDLE; break; case 2: t = this.mouseButtons.RIGHT; break; default: t = -1 } switch (t) { case v: if (!1 === this.enableZoom) return; this._handleMouseDownDolly(e), this.state = Lw; break; case g: if (e.ctrlKey || e.metaKey || e.shiftKey) { if (!1 === this.enablePan) return; this._handleMouseDownPan(e), this.state = Dw } else { if (!1 === this.enableRotate) return; this._handleMouseDownRotate(e), this.state = Rw } break; case w: if (e.ctrlKey || e.metaKey || e.shiftKey) { if (!1 === this.enableRotate) return; this._handleMouseDownRotate(e), this.state = Rw } else { if (!1 === this.enablePan) return; this._handleMouseDownPan(e), this.state = Dw } break; default: this.state = Iw } this.state !== Iw && this.dispatchEvent(Ew) } function jw(e) { switch (this.state) { case Rw: if (!1 === this.enableRotate) return; this._handleMouseMoveRotate(e); break; case Lw: if (!1 === this.enableZoom) return; this._handleMouseMoveDolly(e); break; case Dw: if (!1 === this.enablePan) return; this._handleMouseMovePan(e) } } function Qw(e) { !1 !== this.enabled && !1 !== this.enableZoom && this.state === Iw && (e.preventDefault(), this.dispatchEvent(Ew), this._handleMouseWheel(this._customWheelEvent(e)), this.dispatchEvent(Sw)) } function Yw(e) { !1 !== this.enabled && this._handleKeyDown(e) } function Kw(e) { switch (this._trackPointer(e), this._pointers.length) { case 1: switch (this.touches.ONE) { case y: if (!1 === this.enableRotate) return; this._handleTouchStartRotate(e), this.state = Nw; break; case A: if (!1 === this.enablePan) return; this._handleTouchStartPan(e), this.state = Bw; break; default: this.state = Iw } break; case 2: switch (this.touches.TWO) { case b: if (!1 === this.enableZoom && !1 === this.enablePan) return; this._handleTouchStartDollyPan(e), this.state = Uw; break; case x: if (!1 === this.enableZoom && !1 === this.enableRotate) return; this._handleTouchStartDollyRotate(e), this.state = zw; break; default: this.state = Iw } break; default: this.state = Iw } this.state !== Iw && this.dispatchEvent(Ew) } function qw(e) { switch (this._trackPointer(e), this.state) { case Nw: if (!1 === this.enableRotate) return; this._handleTouchMoveRotate(e), this.update(); break; case Bw: if (!1 === this.enablePan) return; this._handleTouchMovePan(e), this.update(); break; case Uw: if (!1 === this.enableZoom && !1 === this.enablePan) return; this._handleTouchMoveDollyPan(e), this.update(); break; case zw: if (!1 === this.enableZoom && !1 === this.enableRotate) return; this._handleTouchMoveDollyRotate(e), this.update(); break; default: this.state = Iw } } function Xw(e) { !1 !== this.enabled && e.preventDefault() } function Zw(e) { if ("Control" === e.key) { this._controlActive = !0; this.domElement.getRootNode().addEventListener("keyup", this._interceptControlUp, { passive: !0, capture: !0 }) } } function Jw(e) { if ("Control" === e.key) { this._controlActive = !1; this.domElement.getRootNode().removeEventListener("keyup", this._interceptControlUp, { passive: !0, capture: !0 }) } } var $w = n(5848), ey = {}; ey.styleTagTransform = u(), ey.setAttributes = l(), ey.insert = s().bind(null, "head"), ey.domAPI = r(), ey.insertStyleElement = h(); t()($w.A, ey); $w.A && $w.A.locals && $w.A.locals; var ty, ny, iy, ry, ay, sy, oy, ly, cy, hy, dy, uy, py, fy, my, gy, vy, wy, yy, Ay = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, by = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; ny = new WeakMap, iy = new WeakMap, ry = new WeakMap, ay = new WeakMap, sy = new WeakMap, oy = new WeakMap, ly = new WeakMap, cy = new WeakMap, hy = new WeakMap, dy = new WeakMap, uy = new WeakMap, py = new WeakMap, fy = new WeakMap, my = new WeakMap, gy = new WeakMap, vy = new WeakMap, ty = new WeakSet, wy = function() { by(this, cy, "f").style.left = "calc(" + (100 * by(this, py, "f") / 360).toString() + "% - 1px)", by(this, ay, "f").style.backgroundImage = "linear-gradient(transparent, #000), linear-gradient(to right, transparent, hsla(" + by(this, py, "f").toString() + ", 100%, 50%, 1))" }, yy = function() { by(this, sy, "f").style.left = "calc(" + by(this, uy, "f").toString() + "% - 6px)", by(this, sy, "f").style.top = "calc(" + (100 - by(this, dy, "f")).toString() + "% - 6px)" }; const xy = class { constructor(e, t) { ty.add(this), ny.set(this, void 0), iy.set(this, void 0), ry.set(this, void 0), ay.set(this, void 0), sy.set(this, void 0), oy.set(this, !1), ly.set(this, void 0), cy.set(this, void 0), hy.set(this, !1), dy.set(this, 0), uy.set(this, 0), py.set(this, 0), fy.set(this, void 0), my.set(this, void 0), gy.set(this, void 0), vy.set(this, void 0), Ay(this, ny, e, "f"), Ay(this, iy, t, "f"), Ay(this, ry, document.createElement("div"), "f"), by(this, ry, "f").className = "color-picker", Ay(this, ay, document.createElement("div"), "f"), by(this, ay, "f").className = "value-saturation-picker", by(this, ry, "f").appendChild(by(this, ay, "f")), Ay(this, sy, document.createElement("div"), "f"), by(this, sy, "f").className = "marker", by(this, ay, "f").appendChild(by(this, sy, "f")), Ay(this, ly, document.createElement("div"), "f"), by(this, ly, "f").className = "hue-picker", by(this, ry, "f").appendChild(by(this, ly, "f")), Ay(this, cy, document.createElement("div"), "f"), by(this, cy, "f").className = "marker", by(this, ly, "f").appendChild(by(this, cy, "f")), by(this, ny, "f").appendChild(by(this, ry, "f")); Ay(this, fy, (e => { let n = null; if (e instanceof MouseEvent ? by(this, oy, "f") && (n = e) : e instanceof TouchEvent && e.targetTouches.length > 0 && (n = e.targetTouches[e.targetTouches.length - 1]), null != n) { const e = by(this, ay, "f").getBoundingClientRect(), i = Math.max(0, Math.min(1, (n.clientX - e.left) / e.width)), r = Math.max(0, Math.min(1, (n.clientY - e.top) / e.height)); Ay(this, uy, 100 * i, "f"), Ay(this, dy, 100 * (1 - r), "f"), by(this, ty, "m", yy).call(this), t(this.color) } }), "f"), Ay(this, my, (e => { 0 == e.button && Ay(this, oy, !1, "f") }), "f"), by(this, ay, "f").addEventListener("mousedown", (e => { 0 == e.button && Ay(this, oy, !0, "f"), by(this, fy, "f").call(this, e) })), window.addEventListener("mouseup", by(this, my, "f")), window.addEventListener("mousemove", by(this, fy, "f")), by(this, ay, "f").addEventListener("touchstart", by(this, fy, "f")), by(this, ay, "f").addEventListener("touchmove", by(this, fy, "f")), Ay(this, gy, (e => { let n = null; if (e instanceof MouseEvent ? by(this, hy, "f") && (n = e) : e instanceof TouchEvent && e.targetTouches.length > 0 && (n = e.targetTouches[e.targetTouches.length - 1]), null != n) { const e = by(this, ly, "f").getBoundingClientRect(), i = Math.max(0, Math.min(1, (n.clientX - e.left) / e.width)); Ay(this, py, 360 * i, "f"), by(this, ty, "m", wy).call(this), t(this.color) } }), "f"), Ay(this, vy, (e => { 0 == e.button && Ay(this, hy, !1, "f") }), "f"), by(this, ly, "f").addEventListener("mousedown", (e => { 0 == e.button && Ay(this, hy, !0, "f"), by(this, gy, "f").call(this, e) })), window.addEventListener("mouseup", by(this, vy, "f")), window.addEventListener("mousemove", by(this, gy, "f")), by(this, ly, "f").addEventListener("touchstart", by(this, gy, "f")), by(this, ly, "f").addEventListener("touchmove", by(this, gy, "f")), by(this, ty, "m", wy).call(this), by(this, ty, "m", yy).call(this) } dispose() { window.removeEventListener("mouseup", by(this, my, "f")), window.removeEventListener("mousemove", by(this, fy, "f")), window.removeEventListener("mouseup", by(this, vy, "f")), window.removeEventListener("mousemove", by(this, gy, "f")) } get color() { const e = by(this, uy, "f") / 100, t = by(this, dy, "f") / 100, n = t - t * e / 2, i = Math.min(n, 1 - n), r = 0 != i ? (t - n) / i : 0; return new Wi("hsl(" + by(this, py, "f").toString() + "," + (100 * r).toString() + "%," + (100 * n).toString() + "%)") } set color(e) { const { h: t, s: n, l: i } = e.getHSL({ h: 0, s: 0, l: 0 }, gt), r = i + n * Math.min(i, 1 - i), a = 0 == r ? 0 : 2 * (1 - i / r); Ay(this, py, 360 * t, "f"), Ay(this, uy, 100 * a, "f"), Ay(this, dy, 100 * r, "f"), by(this, ty, "m", wy).call(this), by(this, ty, "m", yy).call(this), by(this, iy, "f").call(this, this.color) } }; var ky, Ey, Sy, My, Ty, _y, Cy, Py, Iy, Ry, Ly, Dy, Ny, By, Uy, zy, Oy, Fy, Wy, Vy, Hy, Gy, jy, Qy, Yy, Ky = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, qy = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; Ey = new WeakMap, Sy = new WeakMap, My = new WeakMap, Ty = new WeakMap, _y = new WeakMap, Cy = new WeakMap, Py = new WeakMap, Iy = new WeakMap, Ry = new WeakMap, Ly = new WeakMap, Dy = new WeakMap, Ny = new WeakMap, By = new WeakMap, Uy = new WeakMap, zy = new WeakMap, Oy = new WeakMap, Fy = new WeakMap, ky = new WeakSet, Wy = function(e) { const t = document.createElement("div"); t.className = "color", qy(this, Uy, "f").appendChild(t); const n = document.createElement("h2"); n.textContent = e, t.appendChild(n); const i = document.createElement("input"); i.type = "text", i.addEventListener("input", (() => { let e = i.value; /^[0-9A-F]{6}$/i.test(e) && (e = "#" + e), r.color = new Wi(e), qy(this, Ey, "f").setColors(qy(this, ky, "m", Hy).call(this)), Ky(this, Oy, !0, "f") })), i.addEventListener("blur", (() => { i.value = "#" + r.color.getHexString() })), t.appendChild(i); const r = new xy(t, (e => { document.activeElement != i && (i.value = "#" + e.getHexString()), qy(this, Ey, "f").setColors(qy(this, ky, "m", Hy).call(this)), Ky(this, Oy, !0, "f") })); i.value = "#" + r.color.getHexString(), qy(this, zy, "f").push(r) }, Vy = function() { const e = Pu.random(); qy(this, zy, "f")[0].color = e.primary.clone(), qy(this, zy, "f")[1].color = e.secondary.clone(), qy(this, zy, "f")[2].color = e.frame.clone(), qy(this, zy, "f")[3].color = e.rims.clone() }, Hy = function() { return new Pu(qy(this, zy, "f")[0].color.clone(), qy(this, zy, "f")[1].color.clone(), qy(this, zy, "f")[2].color.clone(), qy(this, zy, "f")[3].color.clone()) }, Gy = function(e) { qy(this, zy, "f")[0].color = e.primary.clone(), qy(this, zy, "f")[1].color = e.secondary.clone(), qy(this, zy, "f")[2].color = e.frame.clone(), qy(this, zy, "f")[3].color = e.rims.clone() }, jy = function(e) { qy(this, Oy, "f") ? qy(this, Cy, "f").showConfirm(qy(this, Sy, "f").get("Are you sure you want to exit without saving?") + "\n\n" + qy(this, Sy, "f").get("All changes will be lost!"), qy(this, Sy, "f").get("Cancel"), qy(this, Sy, "f").get("Confirm"), null, (() => { e() })) : e() }, Qy = function() { if (qy(this, Oy, "f")) { const e = qy(this, ky, "m", Hy).call(this); qy(this, _y, "f").setCarColors(e), Ky(this, Oy, !1, "f"), Ky(this, Fy, !0, "f") } qy(this, ky, "m", Yy).call(this) }, Yy = function() { null != qy(this, By, "f") && (clearTimeout(qy(this, By, "f")), Ky(this, By, null, "f")), qy(this, Ny, "f").classList.remove("show"), qy(this, Ny, "f").classList.remove("hide"), Ky(this, By, window.setTimeout((() => { qy(this, Ny, "f").textContent = qy(this, Sy, "f").get("Car saved!"), qy(this, Ny, "f").classList.add("show"), Ky(this, By, window.setTimeout((() => { qy(this, Ny, "f").classList.remove("show"), qy(this, Ny, "f").classList.add("hide") }), 3e3), "f") }), 0), "f") }; const Xy = class { constructor(e, t, n, i, r, a, s, o) { ky.add(this), Ey.set(this, void 0), Sy.set(this, void 0), My.set(this, void 0), Ty.set(this, void 0), _y.set(this, void 0), Cy.set(this, void 0), Py.set(this, void 0), Iy.set(this, void 0), Ry.set(this, void 0), Ly.set(this, void 0), Dy.set(this, void 0), Ny.set(this, void 0), By.set(this, null), Uy.set(this, void 0), zy.set(this, []), Oy.set(this, !1), Fy.set(this, !1), Ky(this, Ey, e, "f"), Ky(this, My, n, "f"), Ky(this, Ty, r, "f"), Ky(this, _y, a, "f"), Ky(this, Cy, s, "f"), Ky(this, Sy, t, "f"), Ky(this, Ry, new Pr(70, 1, .1, Au.maxViewDistance), "f"), qy(this, Ry, "f").position.set(4, 3, 4), n.scene.add(qy(this, Ry, "f")), Ky(this, Ly, new Fw(qy(this, Ry, "f"), n.canvas), "f"), qy(this, Ly, "f").target.set(0, .7, 1.2), qy(this, Ly, "f").update(), qy(this, Ly, "f").mouseButtons = { LEFT: g, MIDDLE: g, RIGHT: g }, qy(this, Ly, "f").enablePan = !1, qy(this, Ly, "f").minDistance = 2.5, qy(this, Ly, "f").maxDistance = 5.8, qy(this, Ly, "f").maxPolarAngle = Math.PI / 2 + .06; const l = document.getElementById("ui"); if (null == l) throw new Error("UI element not found"); Ky(this, Py, l, "f"), Ky(this, Dy, document.createElement("div"), "f"), qy(this, Dy, "f").className = "customization"; const c = document.createElement("div"); c.className = "top", qy(this, Dy, "f").appendChild(c); const h = document.createElement("button"); h.className = "button", h.innerHTML = ' ', h.append(document.createTextNode(t.get("Exit"))), h.addEventListener("click", (() => { i.playUIClick(), qy(this, ky, "m", jy).call(this, o) })), c.appendChild(h), window.addEventListener("keydown", Ky(this, Iy, (e => { "Escape" == e.code && (qy(this, ky, "m", jy).call(this, o), e.preventDefault()) }), "f")); const d = document.createElement("button"); d.className = "button", d.innerHTML = ' ', d.append(document.createTextNode(t.get("Save"))), d.addEventListener("click", (() => { i.playUIClick(), qy(this, ky, "m", Qy).call(this) })), c.appendChild(d); const u = document.createElement("button"); u.className = "button", u.innerHTML = ' ', u.append(document.createTextNode(t.get("Random"))), u.addEventListener("click", (() => { i.playUIClick(), qy(this, ky, "m", Vy).call(this) })), c.appendChild(u), Ky(this, Ny, document.createElement("div"), "f"), qy(this, Ny, "f").className = "save-message", qy(this, Dy, "f").appendChild(qy(this, Ny, "f")), Ky(this, Uy, document.createElement("div"), "f"), qy(this, Uy, "f").className = "colors", qy(this, Dy, "f").appendChild(qy(this, Uy, "f")), qy(this, ky, "m", Wy).call(this, t.get("Primary")), qy(this, ky, "m", Wy).call(this, t.get("Secondary")), qy(this, ky, "m", Wy).call(this, t.get("Frame")), qy(this, ky, "m", Wy).call(this, t.get("Rims")), qy(this, Py, "f").appendChild(qy(this, Dy, "f")); const p = qy(this, _y, "f").getCurrentUserProfile().carColors; qy(this, ky, "m", Gy).call(this, p), qy(this, Ey, "f").setColors(p), Ky(this, Oy, !1, "f") } dispose() { for (const e of qy(this, zy, "f")) e.dispose(); if (qy(this, Fy, "f")) { const { token: e, nickname: t, carColors: n } = qy(this, _y, "f").getCurrentUserProfile(); qy(this, Ty, "f").submitUserProfile(e, t, n).catch((e => { console.warn(e) })) } qy(this, My, "f").scene.remove(qy(this, Ry, "f")), window.removeEventListener("keydown", qy(this, Iy, "f")), qy(this, Py, "f").removeChild(qy(this, Dy, "f")), qy(this, Ly, "f").dispose(), qy(this, My, "f").canvas.style.touchAction = "" } get camera() { return qy(this, Ry, "f") } }; var Zy; ! function(e) { e[e.Default = 0] = "Default", e[e.Summer = 1] = "Summer", e[e.Winter = 2] = "Winter", e[e.Desert = 3] = "Desert", e[e.Custom0 = 32] = "Custom0", e[e.Custom1 = 33] = "Custom1", e[e.Custom2 = 34] = "Custom2", e[e.Custom3 = 35] = "Custom3", e[e.Custom4 = 36] = "Custom4", e[e.Custom5 = 37] = "Custom5", e[e.Custom6 = 38] = "Custom6", e[e.Custom7 = 39] = "Custom7", e[e.Custom8 = 40] = "Custom8" }(Zy || (Zy = {})); const Jy = Zy; var $y; ! function(e) { e[e.Straight = 0] = "Straight", e[e.TurnSharp = 1] = "TurnSharp", e[e.SlopeUp = 2] = "SlopeUp", e[e.SlopeDown = 3] = "SlopeDown", e[e.Slope = 4] = "Slope", e[e.Start = 5] = "Start", e[e.Finish = 6] = "Finish", e[e.ToWideMiddle = 7] = "ToWideMiddle", e[e.ToWideLeft = 8] = "ToWideLeft", e[e.ToWideRight = 9] = "ToWideRight", e[e.StraightWide = 10] = "StraightWide", e[e.InnerCornerWide = 11] = "InnerCornerWide", e[e.OuterCornerWide = 12] = "OuterCornerWide", e[e.SlopeUpLeftWide = 13] = "SlopeUpLeftWide", e[e.SlopeUpRightWide = 14] = "SlopeUpRightWide", e[e.SlopeDownLeftWide = 15] = "SlopeDownLeftWide", e[e.SlopeDownRightWide = 16] = "SlopeDownRightWide", e[e.SlopeLeftWide = 17] = "SlopeLeftWide", e[e.SlopeRightWide = 18] = "SlopeRightWide", e[e.PillarTop = 19] = "PillarTop", e[e.PillarMiddle = 20] = "PillarMiddle", e[e.PillarBottom = 21] = "PillarBottom", e[e.PillarShort = 22] = "PillarShort", e[e.PlanePillarBottom = 23] = "PlanePillarBottom", e[e.PlanePillarShort = 24] = "PlanePillarShort", e[e.Plane = 25] = "Plane", e[e.PlaneWall = 26] = "PlaneWall", e[e.PlaneWallCorner = 27] = "PlaneWallCorner", e[e.PlaneWallInnerCorner = 28] = "PlaneWallInnerCorner", e[e.Block = 29] = "Block", e[e.WallTrackTop = 30] = "WallTrackTop", e[e.WallTrackMiddle = 31] = "WallTrackMiddle", e[e.WallTrackBottom = 32] = "WallTrackBottom", e[e.PlaneSlopeUp = 33] = "PlaneSlopeUp", e[e.PlaneSlopeDown = 34] = "PlaneSlopeDown", e[e.PlaneSlope = 35] = "PlaneSlope", e[e.TurnShort = 36] = "TurnShort", e[e.TurnLong = 37] = "TurnLong", e[e.SlopeUpLong = 38] = "SlopeUpLong", e[e.SlopeDownLong = 39] = "SlopeDownLong", e[e.SlopePillar = 40] = "SlopePillar", e[e.TurnSLeft = 41] = "TurnSLeft", e[e.TurnSRight = 42] = "TurnSRight", e[e.IntersectionT = 43] = "IntersectionT", e[e.IntersectionCross = 44] = "IntersectionCross", e[e.PillarBranch1 = 45] = "PillarBranch1", e[e.PillarBranch2 = 46] = "PillarBranch2", e[e.PillarBranch3 = 47] = "PillarBranch3", e[e.PillarBranch4 = 48] = "PillarBranch4", e[e.WallTrackBottomCorner = 49] = "WallTrackBottomCorner", e[e.WallTrackMiddleCorner = 50] = "WallTrackMiddleCorner", e[e.WallTrackTopCorner = 51] = "WallTrackTopCorner", e[e.Checkpoint = 52] = "Checkpoint", e[e.HalfBlock = 53] = "HalfBlock", e[e.QuarterBlock = 54] = "QuarterBlock", e[e.HalfPlane = 55] = "HalfPlane", e[e.QuarterPlane = 56] = "QuarterPlane", e[e.PlaneBridge = 57] = "PlaneBridge", e[e.SignArrowLeft = 58] = "SignArrowLeft", e[e.SignArrowRight = 59] = "SignArrowRight", e[e.SignArrowUp = 61] = "SignArrowUp", e[e.SignArrowDown = 62] = "SignArrowDown", e[e.SignWarning = 63] = "SignWarning", e[e.SignWrongWay = 64] = "SignWrongWay", e[e.CheckpointWide = 65] = "CheckpointWide", e[e.WallTrackCeiling = 66] = "WallTrackCeiling", e[e.WallTrackFloor = 67] = "WallTrackFloor", e[e.BlockSlopedDown = 68] = "BlockSlopedDown", e[e.BlockSlopedDownInnerCorner = 69] = "BlockSlopedDownInnerCorner", e[e.BlockSlopedDownOuterCorner = 70] = "BlockSlopedDownOuterCorner", e[e.BlockSlopedUp = 71] = "BlockSlopedUp", e[e.BlockSlopedUpInnerCorner = 72] = "BlockSlopedUpInnerCorner", e[e.BlockSlopedUpOuterCorner = 73] = "BlockSlopedUpOuterCorner", e[e.FinishWide = 74] = "FinishWide", e[e.PlaneCheckpoint = 75] = "PlaneCheckpoint", e[e.PlaneFinish = 76] = "PlaneFinish", e[e.PlaneCheckpointWide = 77] = "PlaneCheckpointWide", e[e.PlaneFinishWide = 78] = "PlaneFinishWide", e[e.WallTrackBottomInnerCorner = 79] = "WallTrackBottomInnerCorner", e[e.WallTrackInnerCorner = 80] = "WallTrackInnerCorner", e[e.WallTrackTopInnerCorner = 81] = "WallTrackTopInnerCorner", e[e.TurnLong2 = 82] = "TurnLong2", e[e.TurnLong3 = 83] = "TurnLong3", e[e.SlopePillarShort = 84] = "SlopePillarShort", e[e.BlockSlopeUp = 85] = "BlockSlopeUp", e[e.BlockSlopeDown = 86] = "BlockSlopeDown", e[e.BlockSlopeVerticalTop = 87] = "BlockSlopeVerticalTop", e[e.BlockSlopeVerticalBottom = 88] = "BlockSlopeVerticalBottom", e[e.PlaneSlopeVerticalBottom = 90] = "PlaneSlopeVerticalBottom", e[e.StartWide = 91] = "StartWide", e[e.PlaneStart = 92] = "PlaneStart", e[e.PlaneStartWide = 93] = "PlaneStartWide", e[e.TurnShortLeftWide = 94] = "TurnShortLeftWide", e[e.TurnShortRightWide = 95] = "TurnShortRightWide", e[e.TurnLongLeftWide = 96] = "TurnLongLeftWide", e[e.TurnLongRightWide = 97] = "TurnLongRightWide", e[e.SlopeUpVertical = 98] = "SlopeUpVertical", e[e.PlaneSlopePillar = 99] = "PlaneSlopePillar", e[e.PlaneSlopePillarShort = 100] = "PlaneSlopePillarShort", e[e.PillarBranch1Top = 101] = "PillarBranch1Top", e[e.PillarBranch1Bottom = 102] = "PillarBranch1Bottom", e[e.PillarBranch1Middle = 103] = "PillarBranch1Middle", e[e.PillarBranch2Top = 104] = "PillarBranch2Top", e[e.PillarBranch2Middle = 105] = "PillarBranch2Middle", e[e.PillarBranch2Bottom = 106] = "PillarBranch2Bottom", e[e.PillarBranch3Top = 107] = "PillarBranch3Top", e[e.PillarBranch3Middle = 108] = "PillarBranch3Middle", e[e.PillarBranch3Bottom = 109] = "PillarBranch3Bottom", e[e.PillarBranch4Top = 110] = "PillarBranch4Top", e[e.PillarBranch4Middle = 111] = "PillarBranch4Middle", e[e.PillarBranch4Bottom = 112] = "PillarBranch4Bottom", e[e.PillarBranch5 = 113] = "PillarBranch5", e[e.PillarBranch5Top = 114] = "PillarBranch5Top", e[e.PillarBranch5Middle = 115] = "PillarBranch5Middle", e[e.PillarBranch5Bottom = 116] = "PillarBranch5Bottom", e[e.ToWideDouble = 117] = "ToWideDouble", e[e.ToWideDiagonal = 118] = "ToWideDiagonal", e[e.StraightPillarBottom = 119] = "StraightPillarBottom", e[e.StraightPillarShort = 120] = "StraightPillarShort", e[e.TurnSharpPillarBottom = 121] = "TurnSharpPillarBottom", e[e.TurnSharpPillarShort = 122] = "TurnSharpPillarShort", e[e.IntersectionTPillarBottom = 123] = "IntersectionTPillarBottom", e[e.IntersectionTPillarShort = 124] = "IntersectionTPillarShort", e[e.IntersectionCrossPillarBottom = 125] = "IntersectionCrossPillarBottom", e[e.IntersectionCrossPillarShort = 126] = "IntersectionCrossPillarShort", e[e.PlaneBridgeCorner = 127] = "PlaneBridgeCorner", e[e.PlaneBridgeIntersectionT = 128] = "PlaneBridgeIntersectionT", e[e.PlaneBridgeIntersectionCross = 129] = "PlaneBridgeIntersectionCross", e[e.BlockBridge = 130] = "BlockBridge", e[e.BlockBridgeCorner = 131] = "BlockBridgeCorner", e[e.BlockBridgeIntersectionT = 132] = "BlockBridgeIntersectionT", e[e.BlockBridgeIntersectionCross = 133] = "BlockBridgeIntersectionCross", e[e.WallTrackCeilingCorner = 134] = "WallTrackCeilingCorner", e[e.WallTrackCeilingPlaneCorner = 135] = "WallTrackCeilingPlaneCorner", e[e.WallTrackFloorCorner = 136] = "WallTrackFloorCorner", e[e.WallTrackFloorPlaneCorner = 137] = "WallTrackFloorPlaneCorner", e[e.SlopeUpVerticalLeftWide = 138] = "SlopeUpVerticalLeftWide", e[e.SlopeUpVerticalRightWide = 139] = "SlopeUpVerticalRightWide", e[e.BlockSlopeVerticalCornerTop = 140] = "BlockSlopeVerticalCornerTop", e[e.BlockSlopeVerticalCornerBottom = 141] = "BlockSlopeVerticalCornerBottom", e[e.WallTrackSlopeToVertical = 142] = "WallTrackSlopeToVertical", e[e.PlaneSlopeToVertical = 143] = "PlaneSlopeToVertical", e[e.BlockSlopeToVertical = 144] = "BlockSlopeToVertical", e[e.PlaneSlopeUpLong = 145] = "PlaneSlopeUpLong", e[e.PlaneSlopeDownLong = 146] = "PlaneSlopeDownLong", e[e.SlopeUpLongLeftWide = 147] = "SlopeUpLongLeftWide", e[e.SlopeUpLongRightWide = 148] = "SlopeUpLongRightWide", e[e.SlopeDownLongLeftWide = 149] = "SlopeDownLongLeftWide", e[e.SlopeDownLongRightWide = 150] = "SlopeDownLongRightWide", e[e.BlockSlopeUpLong = 151] = "BlockSlopeUpLong", e[e.BlockSlopeDownLong = 152] = "BlockSlopeDownLong", e[e.BlockSlopeVerticalInnerCornerBottom = 153] = "BlockSlopeVerticalInnerCornerBottom", e[e.BlockSlopeVerticalInnerCornerTop = 154] = "BlockSlopeVerticalInnerCornerTop", e[e.BlockInnerCorner = 155] = "BlockInnerCorner" }($y || ($y = {})); const eA = $y; var tA; ! function(e) { e[e.YPositive = 0] = "YPositive", e[e.YNegative = 1] = "YNegative", e[e.XPositive = 2] = "XPositive", e[e.XNegative = 3] = "XNegative", e[e.ZPositive = 4] = "ZPositive", e[e.ZNegative = 5] = "ZNegative" }(tA || (tA = {})); const nA = tA; var iA, rA, aA, sA, oA, lA, cA, hA, dA = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, uA = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; iA = new WeakMap, rA = new WeakMap, aA = new WeakMap, sA = new WeakMap, oA = new WeakMap, lA = new WeakMap, cA = new WeakMap, hA = new WeakMap; const pA = class { constructor(e, t, n, i, r, a, s, o, l, c, h) { iA.set(this, void 0), rA.set(this, void 0), aA.set(this, void 0), sA.set(this, void 0), oA.set(this, void 0), lA.set(this, void 0), cA.set(this, void 0), hA.set(this, void 0), dA(this, iA, a, "f"), dA(this, rA, t, "f"), dA(this, aA, n, "f"), dA(this, sA, i, "f"), dA(this, oA, r, "f"), dA(this, lA, o, "f"); for (let e = -100; e < 100; ++e) 0 == e ? t.setPart(0, 0, 4 * e, eA.Start, 2, nA.YPositive, Jy.Default, null, 0) : t.setPart(0, 0, 4 * e, eA.Straight, 0, nA.YPositive, Jy.Default, null, null); t.generateMeshes(), n.generateMountains(t.getBounds()); const d = t.getStartTransform(); if (null == d) throw new Error("Start transform is null"); dA(this, hA, new Aw(null, d, null, null, r, a, n, t, o), "f"), uA(this, hA, "f").audioVolume = 0, uA(this, hA, "f").update(0), dA(this, cA, new Xy(uA(this, hA, "f"), e, r, a, l, s, c, h), "f"), r.setCamera(uA(this, cA, "f").camera) } dispose() { uA(this, rA, "f").clear(), uA(this, aA, "f").clearMountains(), uA(this, cA, "f").dispose(), uA(this, hA, "f").dispose() } update(e) { uA(this, aA, "f").update(uA(this, rA, "f")), uA(this, sA, "f").update(e, uA(this, oA, "f").camera, uA(this, rA, "f").sunDirection), uA(this, iA, "f").update(e, !0, uA(this, oA, "f"), uA(this, lA, "f")), uA(this, oA, "f").update(uA(this, hA, "f").getPosition(), uA(this, rA, "f").sunDirection) } }; var fA = n(4344), mA = {}; mA.styleTagTransform = u(), mA.setAttributes = l(), mA.insert = s().bind(null, "head"), mA.domAPI = r(), mA.insertStyleElement = h(); t()(fA.A, mA); fA.A && fA.A.locals && fA.A.locals; var gA, vA, wA, yA, AA, bA, xA, kA = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, EA = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; vA = new WeakMap, wA = new WeakMap, yA = new WeakMap, AA = new WeakMap, bA = new WeakMap, gA = new WeakSet, xA = function() { if (null != EA(this, wA, "f")) { const e = "FPS: " + EA(this, bA, "f").toString(); EA(this, wA, "f").textContent != e && (EA(this, wA, "f").textContent = e) } }; const SA = class { constructor() { gA.add(this), vA.set(this, void 0), wA.set(this, null), yA.set(this, 0), AA.set(this, 0), bA.set(this, 0); const e = document.getElementById("ui"); if (null == e) throw new Error("UI element not found"); kA(this, vA, e, "f") } show() { kA(this, wA, document.createElement("div"), "f"), EA(this, wA, "f").className = "debug", EA(this, vA, "f").appendChild(EA(this, wA, "f")), EA(this, gA, "m", xA).call(this) } hide() { null != EA(this, wA, "f") && (EA(this, vA, "f").removeChild(EA(this, wA, "f")), kA(this, wA, null, "f")) } toggle() { null != EA(this, wA, "f") ? this.hide() : this.show() } update(e) { kA(this, yA, EA(this, yA, "f") + e, "f"), kA(this, AA, EA(this, AA, "f") + 1, "f"), EA(this, yA, "f") >= 1 && (kA(this, bA, EA(this, AA, "f"), "f"), kA(this, yA, EA(this, yA, "f") - Math.trunc(EA(this, yA, "f")), "f"), kA(this, AA, 0, "f"), EA(this, gA, "m", xA).call(this)) } }; var MA = n(6057), TA = {}; TA.styleTagTransform = u(), TA.setAttributes = l(), TA.insert = s().bind(null, "head"), TA.domAPI = r(), TA.insertStyleElement = h(); t()(MA.A, TA); MA.A && MA.A.locals && MA.A.locals; class _A extends Fw { constructor(e, t) { super(e, t), this.screenSpacePanning = !1, this.mouseButtons = { LEFT: w, MIDDLE: v, RIGHT: g }, this.touches = { ONE: A, TWO: x } } } class CA extends uo { constructor(e) { super(e) } load(e, t, n, i) { const r = this, a = new mo(this.manager); a.setPath(this.path), a.setRequestHeader(this.requestHeader), a.setWithCredentials(this.withCredentials), a.load(e, (function(e) { const n = r.parse(JSON.parse(e)); t && t(n) }), n, i) } parse(e) { return new PA(e) } } class PA { constructor(e) { this.isFont = !0, this.type = "Font", this.data = e } generateShapes(e, t = 100) { const n = [], i = function(e, t, n) { const i = Array.from(e), r = t / n.resolution, a = (n.boundingBox.yMax - n.boundingBox.yMin + n.underlineThickness) * r, s = []; let o = 0, l = 0; for (let e = 0; e < i.length; e++) { const t = i[e]; if ("\n" === t) o = 0, l -= a; else { const e = IA(t, r, o, l, n); o += e.offsetX, s.push(e.path) } } return s }(e, t, this.data); for (let e = 0, t = i.length; e < t; e++) n.push(...i[e].toShapes()); return n } } function IA(e, t, n, i, r) { const a = r.glyphs[e] || r.glyphs["?"]; if (!a) return void console.error('THREE.Font: character "' + e + '" does not exists in font family ' + r.familyName + "."); const s = new qo; let o, l, c, h, d, u, p, f; if (a.o) { const e = a._cachedOutline || (a._cachedOutline = a.o.split(" ")); for (let r = 0, a = e.length; r < a;) { switch (e[r++]) { case "m": o = e[r++] * t + n, l = e[r++] * t + i, s.moveTo(o, l); break; case "l": o = e[r++] * t + n, l = e[r++] * t + i, s.lineTo(o, l); break; case "q": c = e[r++] * t + n, h = e[r++] * t + i, d = e[r++] * t + n, u = e[r++] * t + i, s.quadraticCurveTo(d, u, c, h); break; case "b": c = e[r++] * t + n, h = e[r++] * t + i, d = e[r++] * t + n, u = e[r++] * t + i, p = e[r++] * t + n, f = e[r++] * t + i, s.bezierCurveTo(d, u, p, f, c, h) } } } return { offsetX: a.ha * t, path: s } } class RA extends ua { constructor(e, t) { const n = new ji({ color: t, depthWrite: !1 }); super(e.geometry, n, e.count); for (let t = 0; t < e.count; ++t) { const n = new qn; e.getMatrixAt(t, n), this.setMatrixAt(t, n) } this.meshMatrix = e.matrixWorld, this.frustumCulled = !1, this.matrixAutoUpdate = !1, this.renderOrder = -1 } update(e, t) { var n = new qn, i = e.normal.x * t.x + e.normal.y * t.y + e.normal.z * t.z + -e.constant * t.w, r = n.elements; r[0] = i - t.x * e.normal.x, r[4] = -t.x * e.normal.y, r[8] = -t.x * e.normal.z, r[12] = -t.x * -e.constant, r[1] = -t.y * e.normal.x, r[5] = i - t.y * e.normal.y, r[9] = -t.y * e.normal.z, r[13] = -t.y * -e.constant, r[2] = -t.z * e.normal.x, r[6] = -t.z * e.normal.y, r[10] = i - t.z * e.normal.z, r[14] = -t.z * -e.constant, r[3] = -t.w * e.normal.x, r[7] = -t.w * e.normal.y, r[11] = -t.w * e.normal.z, r[15] = i - t.w * -e.constant, this.matrix.multiplyMatrices(n, this.meshMatrix) } } var LA = n(1312); const DA = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], NA = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]; function BA(e) { let t = 0, n = ""; for (; t < 8 * e.length;) { const i = zA(e, t); let r; 30 & ~i ? (r = i, t += 6) : (r = 31 & i, t += 5), n += DA[r] } return n } function UA(e) { let t = 0; const n = [], i = e.length; for (let r = 0; r < i; r++) { const a = e.charCodeAt(r); if (a >= NA.length) return null; const s = NA[a]; if (-1 == s) return null; 30 & ~s ? (OA(n, t, 6, s, r == i - 1), t += 6) : (OA(n, t, 5, s, r == i - 1), t += 5) } return new Uint8Array(n) } function zA(e, t) { if (t >= 8 * e.length) throw new Error("Out of range"); const n = Math.floor(t / 8), i = e[n], r = t - 8 * n; if (r <= 2 || n >= e.length - 1) return (i & 63 << r) >>> r; return (i & 63 << r) >>> r | (e[n + 1] & 63 >>> 8 - r) << 8 - r } function OA(e, t, n, i, r) { const a = Math.floor(t / 8); for (; a >= e.length;) e.push(0); const s = t - 8 * a; if (e[a] |= i << s & 255, s > 8 - n && !r) { const t = a + 1; t >= e.length && e.push(0), e[t] |= i >> 8 - s } } var FA, WA = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, VA = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class HA { constructor(e = 28) { if (FA.set(this, void 0), !(Number.isSafeInteger(e) && e >= 0 && e < 180)) throw new Error("Representation is not a safe integer or is out of range"); WA(this, FA, e, "f") } clone() { return new HA(VA(this, FA, "f")) } toDegrees() { return 2 * VA(this, FA, "f") } static fromDegrees(e) { const t = Math.round(e / 2 % 180); return new HA(t) } getSunPosition() { const e = 2 * VA(this, FA, "f") * (Math.PI / 180), t = Math.cos(e), n = Math.sin(e); return new yn(t, .78, n).normalize() } get representation() { return VA(this, FA, "f") } } FA = new WeakMap; const GA = HA; var jA; ! function(e) { e[e.Summer = 0] = "Summer", e[e.Winter = 1] = "Winter", e[e.Desert = 2] = "Desert" }(jA || (jA = {})); const QA = jA; var YA; ! function(e) { e[e.Special = 0] = "Special", e[e.Road = 1] = "Road", e[e.RoadTurns = 2] = "RoadTurns", e[e.RoadWide = 3] = "RoadWide", e[e.Plane = 4] = "Plane", e[e.Block = 5] = "Block", e[e.WallTrack = 6] = "WallTrack", e[e.Pillar = 7] = "Pillar", e[e.Sign = 8] = "Sign" }(YA || (YA = {})); const KA = YA; var qA; ! function(e) { e[e.Checkpoint = 0] = "Checkpoint", e[e.Finish = 1] = "Finish" }(qA || (qA = {})); const XA = qA; var ZA, JA = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, $A = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class eb { constructor(e) { ZA.set(this, void 0); const t = []; for (const [n, i, r] of e) t.push([n, i, r]); JA(this, ZA, t, "f") } rotated(e, t) { const n = t == nA.YNegative || t == nA.XNegative || t == nA.ZNegative; return new eb($A(this, ZA, "f").map((([i, r, a]) => { if (n) switch (e) { case 0: break; case 1: [i, a] = [-a - 1, i]; break; case 2: [i, a] = [-i - 1, -a - 1]; break; case 3: [i, a] = [a, -i - 1]; break; default: throw new Error("Invalid rotation") } else switch (e) { case 0: break; case 1: [i, a] = [a, -i - 1]; break; case 2: [i, a] = [-i - 1, -a - 1]; break; case 3: [i, a] = [-a - 1, i]; break; default: throw new Error("Invalid rotation") } return t == nA.YPositive || (t == nA.YNegative ? [i, r] = [-i - 1, -r - 1] : t == nA.XPositive ? [i, r] = [r, -i - 1] : t == nA.XNegative ? [i, r] = [-r - 1, i] : t == nA.ZPositive ? [r, a] = [-a - 1, r] : [r, a] = [a, -r - 1]), [i, r, a] }))) } forEach(e) { for (let t = 0; t < $A(this, ZA, "f").length; t++) { const [n, i, r] = $A(this, ZA, "f")[t]; e(n, i, r, t) } } get length() { return $A(this, ZA, "f").length } } ZA = new WeakMap; const tb = eb, nb = [{ id: Jy.Summer, colors: {} }, { id: Jy.Winter, colors: { Road: "#5077b2", RoadBarrier: "#898989", RoadEdgeWhite: "#ffffff", RoadEdgeRed: "#1f3d6b", BlockSurface: "#878787", Pillar: "#2b4d7f", PillarEdge: "#071428", WallTrack: "#5077b2", WallTrackBottom: "#878787", WallTrackSides: "#ffffff", PlaneWall: "#1f3d6b", PlaneWallDetail: "#878787", SignYellow: "#1b2a89", SignRed: "#841901", SignBlack: "#5077b2" } }, { id: Jy.Desert, colors: { Road: "#997240", RoadBarrier: "#211001", RoadEdgeRed: "#5b2424", RoadEdgeWhite: "#510808", BlockSurface: "#b78f5b", Pillar: "#99713d", PillarEdge: "#1c1105", WallTrack: "#260b0b", WallTrackBottom: "#160606", WallTrackSides: "#75562e", PlaneWall: "#633030", PlaneWallDetail: "#aa8a53", SignYellow: "#997240", SignRed: "#d80202", SignBlack: "#601d1d" } }], ib = nb.concat([{ id: Jy.Custom0, colors: { BlockSurface: "#131313" } }, { id: Jy.Custom1, colors: { BlockSurface: "#501b1b" } }, { id: Jy.Custom2, colors: { BlockSurface: "#7f4d2b" } }, { id: Jy.Custom3, colors: { BlockSurface: "#93862d" } }, { id: Jy.Custom4, colors: { BlockSurface: "#2a5e30" } }, { id: Jy.Custom5, colors: { BlockSurface: "#236363" } }, { id: Jy.Custom6, colors: { BlockSurface: "#20244b" } }, { id: Jy.Custom7, colors: { BlockSurface: "#592759" } }, { id: Jy.Custom8, colors: { BlockSurface: "#302318" } }]); class rb { constructor(e, t, n, i, r, a, s = null, o = null) { const l = []; for (const [e, t] of a) for (let n = e[0]; n <= t[0]; n++) for (let i = e[1]; i <= t[1]; i++) for (let r = e[2]; r <= t[2]; r++) { if (null != l.find((([e, t, a]) => e == n && t == i && a == r))) throw new Error("Duplicate tile in track part"); l.push([n, i, r]) } this.checksum = e, this.category = t, this.id = n, this.models = i, this.colors = r, this.tiles = new tb(l), this.detector = s, this.startOffset = o, Object.freeze(this) } } const ab = [new rb("6d94d798abd14dc3bce4e99c180309d993ad43adb5f2c90eef8e350eedafe7cf", KA.Special, eA.Start, [ ["Road", "Start"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ], null, new yn(0, .35, 1.35)), new rb("f29e34b2e05e0a4751109ae564b03fe8878a79cc6b26288f1117ed296d09c5bb", KA.Special, eA.StartWide, [ ["RoadWide", "StartWide"] ], nb, [ [ [-2, 0, -2], [5, 0, 1] ] ], null, new yn(-10, .35, 1.35)), new rb("3c304054f415fbede4f73a43517db04302f38b16fa2cd4e587082b37b75e20e5", KA.Special, eA.PlaneStart, [ ["Planes", "PlaneStart"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ], null, new yn(0, .35, 1.35)), new rb("f08710416bdaa3d91d0d43f014e45d421fdb4587a334993bad0056f3dbbcb6bb", KA.Special, eA.PlaneStartWide, [ ["Planes", "PlaneStartWide"] ], nb, [ [ [-2, 0, -2], [5, 0, 1] ] ], null, new yn(-10, .35, 1.35)), new rb("223fc87c72bb64b58677062ffa08ab7eafd78071bced7c53233606763cd5316b", KA.Special, eA.Checkpoint, [ ["Road", "Checkpoint"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ], { type: XA.Checkpoint, center: [0, 2.2, 0], size: [10.5, 3.8, 1] }), new rb("82d9a9879cee92c04c8d4ba2e16fc31bb1917a31f5802a3bb5177ca9a5cfee01", KA.Special, eA.CheckpointWide, [ ["RoadWide", "CheckpointWide"] ], nb, [ [ [-2, 0, -2], [5, 0, 1] ] ], { type: XA.Checkpoint, center: [10, 2.2, 0], size: [30.6, 3.8, 1] }), new rb("fe8946d7f09724b5e11f493eb5c2a5b5e3d502b15beaad003f8134ac63558948", KA.Special, eA.PlaneCheckpoint, [ ["Planes", "PlaneCheckpoint"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ], { type: XA.Checkpoint, center: [0, 2.2, 0], size: [18.25, 3.8, 1] }), new rb("d486d9b851db35dd44c15f9e0bb3bf582118daf7be514598a19307f61cf46678", KA.Special, eA.PlaneCheckpointWide, [ ["Planes", "PlaneCheckpointWide"] ], nb, [ [ [-2, 0, -2], [5, 0, 1] ] ], { type: XA.Checkpoint, center: [10, 2.2, 0], size: [38.25, 3.8, 1] }), new rb("c01200d573a3594a6a4cb73ebb600964d653e4a89267d3297f3969220742aa79", KA.Special, eA.Finish, [ ["Road", "Finish"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ], { type: XA.Finish, center: [0, 2.2, 0], size: [10.5, 3.8, 2] }), new rb("a9cefdff816e94a643210c58582c2809de0e3e0e0478b8d5baabd7fe81f13e73", KA.Special, eA.FinishWide, [ ["RoadWide", "FinishWide"] ], nb, [ [ [-2, 0, -2], [5, 0, 1] ] ], { type: XA.Finish, center: [10, 2.2, 0], size: [30.6, 3.8, 2] }), new rb("75e5f09fe8a18ecafaf1fb80929173ef0a7dc0b785596bbe0ccd85a934d79578", KA.Special, eA.PlaneFinish, [ ["Planes", "PlaneFinish"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ], { type: XA.Finish, center: [0, 2.2, 0], size: [18.25, 3.8, 2] }), new rb("5801b3268c75809728c63450d06000c5f6fcfd5d72691902f99d7d19d25e1d78", KA.Special, eA.PlaneFinishWide, [ ["Planes", "PlaneFinishWide"] ], nb, [ [ [-2, 0, -2], [5, 0, 1] ] ], { type: XA.Finish, center: [10, 2.2, 0], size: [38.25, 3.8, 2] }), new rb("3421096c1986d008da88b5fac64cd4c475603138c9bf8a98ab6d581dda6befa7", KA.Road, eA.Straight, [ ["Road", "Straight"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("bdc3bcdafec9bc26835dc76159f7223da7da5babb3a5770129fa11046c748b69", KA.Road, eA.StraightPillarBottom, [ ["Road", "Straight"], ["Pillar", "SurfacePillarBottom"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("2758e984d87b3170f6618c9c689554ef169fd5f80ea7f0df292ffd69792d414e", KA.Road, eA.StraightPillarShort, [ ["Road", "Straight"], ["Pillar", "SurfacePillarShort"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("fb5a81784022cfc2d3d0007a032976c8dfd066e72a3bc92f671c98c5cca36aaa", KA.Road, eA.TurnSharp, [ ["Road", "TurnSharp"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("3da2e9a93da06b1376c33486f30a5f02d8c2f125f5b7d8b41166049ecd95f269", KA.Road, eA.TurnSharpPillarBottom, [ ["Road", "TurnSharp"], ["Pillar", "SurfacePillarBottom"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("c642122276547382e37dcb857b130088f4dc0d208dc7fdb6055b2a93080a3ffe", KA.Road, eA.TurnSharpPillarShort, [ ["Road", "TurnSharp"], ["Pillar", "SurfacePillarShort"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("110efb0facc096e1c875e545b075b0effaa1b78d50b97f906aec44796501544b", KA.RoadTurns, eA.TurnShort, [ ["Road", "TurnShort"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 0, -1], [2, 0, -1] ], [ [-1, 0, -2], [3, 0, -2] ], [ [-1, 0, -3], [5, 0, -3] ], [ [0, 0, -4], [5, 0, -4] ], [ [1, 0, -5], [5, 0, -5] ], [ [3, 0, -6], [5, 0, -6] ] ]), new rb("20a164840b0e83f3eac96ba9e3650a30e3b3dec4bb635946e3e9e9a1b74820d2", KA.RoadTurns, eA.TurnLong, [ ["Road", "TurnLong"] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-1, 0, -2], [2, 0, -2] ], [ [-1, 0, -3], [2, 0, -3] ], [ [-1, 0, -4], [3, 0, -4] ], [ [0, 0, -5], [4, 0, -5] ], [ [1, 0, -6], [6, 0, -6] ], [ [2, 0, -7], [9, 0, -7] ], [ [3, 0, -8], [9, 0, -8] ], [ [4, 0, -9], [9, 0, -9] ], [ [7, 0, -10], [9, 0, -10] ] ]), new rb("c36dddde35a740c6f01227522bf35e1a450cddbfdd8bde1617873bef0d47c95c", KA.RoadTurns, eA.TurnLong2, [ ["Road", "TurnLong2"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-1, 0, -4], [2, 0, -3] ], [ [-1, 0, -5], [3, 0, -5] ], [ [0, 0, -6], [4, 0, -6] ], [ [0, 0, -7], [5, 0, -7] ], [ [1, 0, -8], [6, 0, -8] ], [ [2, 0, -9], [7, 0, -9] ], [ [3, 0, -10], [9, 0, -10] ], [ [4, 0, -11], [13, 0, -11] ], [ [5, 0, -12], [13, 0, -12] ], [ [7, 0, -13], [13, 0, -13] ], [ [10, 0, -14], [13, 0, -14] ] ]), new rb("0ed20c04a941708c23fe6ced4af3f357c0e435f09278e06f3de2806786d44059", KA.RoadTurns, eA.TurnLong3, [ ["Road", "TurnLong3"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-1, 0, -4], [2, 0, -3] ], [ [-1, 0, -5], [2, 0, -5] ], [ [0, 0, -6], [3, 0, -6] ], [ [0, 0, -7], [3, 0, -7] ], [ [0, 0, -8], [4, 0, -8] ], [ [1, 0, -9], [5, 0, -9] ], [ [2, 0, -10], [6, 0, -10] ], [ [2, 0, -11], [7, 0, -11] ], [ [3, 0, -12], [8, 0, -12] ], [ [4, 0, -13], [10, 0, -13] ], [ [5, 0, -14], [13, 0, -14] ], [ [7, 0, -15], [17, 0, -15] ], [ [8, 0, -16], [17, 0, -16] ], [ [11, 0, -17], [17, 0, -17] ], [ [14, 0, -18], [17, 0, -18] ] ]), new rb("034ef287319877f2fcc32fbd6f32415539a4c287dfcd620360386a781adad22a", KA.RoadTurns, eA.TurnSLeft, [ ["Road", "TurnS", { flipX: !0 }] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-3, 0, -3], [0, 0, -2] ], [ [-4, 0, -4], [0, 0, -4] ], [ [-5, 0, -5], [-1, 0, -5] ], [ [-5, 0, -7], [-2, 0, -6] ], [ [-6, 0, -10], [-3, 0, -8] ] ]), new rb("0d49e9feb603d0899927c7e5184f4f4fdd4363d2e1fd296f0b7b3cf4dbbf0e8d", KA.RoadTurns, eA.TurnSRight, [ ["Road", "TurnS"] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-1, 0, -3], [2, 0, -2] ], [ [-1, 0, -4], [3, 0, -4] ], [ [0, 0, -5], [4, 0, -5] ], [ [1, 0, -7], [4, 0, -6] ], [ [2, 0, -10], [5, 0, -8] ] ]), new rb("26bca19e63867bc0b755ff6fcca65de296c9d1f109f87540103565eb88a0e03d", KA.RoadTurns, eA.TurnShortLeftWide, [ ["RoadWide", "TurnShortLeftWide"] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-1, 0, -2], [1, 0, -2] ], [ [-1, 0, -4], [5, 0, -3] ], [ [0, 0, -5], [5, 0, -5] ], [ [1, 0, -6], [5, 0, -6] ], [ [2, 0, -7], [9, 0, -7] ], [ [3, 0, -8], [9, 0, -8] ], [ [4, 0, -9], [9, 0, -9] ], [ [7, 0, -10], [9, 0, -10] ] ]), new rb("e3845854f85dafd8cec193bcbecdac6cb79f625066de29524d5c10c5580611c5", KA.RoadTurns, eA.TurnShortRightWide, [ ["RoadWide", "TurnShortRightWide"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 0, -1], [2, 0, -1] ], [ [-2, 0, -2], [3, 0, -2] ], [ [2, 0, -6], [5, 0, -3] ] ]), new rb("dc6088960a65a55c74353a1e7c8a1ca8ec99e683f6273bf666d6909b288bb84b", KA.RoadTurns, eA.TurnLongLeftWide, [ ["RoadWide", "TurnLongLeftWide"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-1, 0, -5], [1, 0, -3] ], [ [0, 0, -6], [1, 0, -6] ], [ [0, 0, -7], [5, 0, -7] ], [ [1, 0, -8], [5, 0, -8] ], [ [2, 0, -9], [5, 0, -9] ], [ [3, 0, -10], [5, 0, -10] ], [ [4, 0, -11], [13, 0, -11] ], [ [5, 0, -12], [13, 0, -12] ], [ [7, 0, -13], [13, 0, -13] ], [ [10, 0, -14], [13, 0, -14] ] ]), new rb("0bbb8d6c1e4a325e10643cf45546da725c1ea18e92a3a95f753339629a06ef6c", KA.RoadTurns, eA.TurnLongRightWide, [ ["RoadWide", "TurnLongRightWide"] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-2, 0, -3], [2, 0, -2] ], [ [-2, 0, -4], [3, 0, -4] ], [ [-2, 0, -5], [4, 0, -5] ], [ [-2, 0, -6], [6, 0, -6] ], [ [2, 0, -10], [9, 0, -7] ] ]), new rb("7d8d1eed719515ba7e48b5ef4a53b6b4bb2bef42496b6b40d2551230435ecb66", KA.Road, eA.SlopeUp, [ ["Road", "SlopeUp"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, -2] ] ]), new rb("d6d54dbf283f7209032541fc6b924dc879d914f253e391cf8b34dde8354661be", KA.Road, eA.SlopeUpLong, [ ["Road", "SlopeUpLong"] ], nb, [ [ [-2, 0, -4], [1, 0, 1] ], [ [-2, 1, -5], [1, 1, -4] ], [ [-2, 1, -6], [1, 2, -6] ] ]), new rb("435e8cf33d28e52f75890cba1cb6529991148afd701f9b40e9ab876c11b2c448", KA.Road, eA.SlopeDown, [ ["Road", "SlopeDown"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, 0], [1, 1, 1] ] ]), new rb("01990158f65e5d499030d8c6d0ce80d34c136189ae1a9430d4260ea7a85e91a9", KA.Road, eA.SlopeDownLong, [ ["Road", "SlopeDownLong"] ], nb, [ [ [-2, 0, -2], [1, 0, 0] ], [ [-2, 1, -1], [1, 1, 5] ], [ [-2, 2, 3], [1, 2, 5] ] ]), new rb("4afecc8b9bd7a3b074112008831fef6b11f9a55ab8c1e570e3e73c1e92b43c6d", KA.Road, eA.Slope, [ ["Road", "Slope"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, 0] ], [ [-2, 2, -2], [1, 2, -2] ] ]), new rb("27f9b25126b1006514941bd148c8f19dc2d82022b0c1aa2358f36cb711d4b59c", KA.Road, eA.SlopePillar, [ ["Road", "Slope"], ["Pillar", "PillarTopSlope"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, 0] ], [ [-2, 2, -2], [1, 2, -2] ], [ [-1, 0, -1], [0, 0, -1] ] ]), new rb("eb236f0ac4bd895c170db53cb518c8df5167a9db5af4bb4f33f73c02deec5265", KA.Road, eA.SlopePillarShort, [ ["Road", "Slope"], ["Pillar", "PillarShortSlope"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, 0] ], [ [-2, 2, -2], [1, 2, -2] ], [ [-1, 0, -1], [0, 0, -1] ] ]), new rb("99cb9068cb3f97e7cbfdbb3f1edc1085ea37514f3d5dd8936bc32089cc066a5c", KA.Road, eA.SlopeUpVertical, [ ["Road", "SlopeUpVertical"] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-2, 1, -1], [1, 1, -1] ], [ [-2, 1, -2], [1, 3, -2] ] ]), new rb("63628b23e104a3eb3c2ba8189cd408a10fbb6ebcd6fa4359d981e3c3804c13d8", KA.Road, eA.IntersectionT, [ ["Road", "IntersectionT"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("400dc4643653001d283bb13f740593fc2300c547bb4d2a962054ba6aabf3721c", KA.Road, eA.IntersectionTPillarBottom, [ ["Road", "IntersectionT"], ["Pillar", "SurfacePillarBottom"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("60355388650d35fcbddaaac29e0d03bc2ae46db1a05cd23ddd3f2722ec2d409e", KA.Road, eA.IntersectionTPillarShort, [ ["Road", "IntersectionT"], ["Pillar", "SurfacePillarShort"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("74197b3731c2befd03498bf5172859f0b3652f1972c19e43a99bb938769573df", KA.Road, eA.IntersectionCross, [ ["Road", "IntersectionCross"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("464e69b5c4f2667c246ade9ed33fd3e50b49438ed0ab787a086dfe74c217ff6c", KA.Road, eA.IntersectionCrossPillarBottom, [ ["Road", "IntersectionCross"], ["Pillar", "SurfacePillarBottom"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("90004caf354627289265314966f11b5656e6879ca7de10507e6c50cd95254b75", KA.Road, eA.IntersectionCrossPillarShort, [ ["Road", "IntersectionCross"], ["Pillar", "SurfacePillarShort"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("2af8aa6050028dd6ee69b7150e83a6d8819e1848a7b1c782848d3f6448c5091a", KA.RoadWide, eA.ToWideMiddle, [ ["RoadWide", "ToWideMiddle"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("26341cfe6bec34f46b10ffcd9a7706a8156b9ac41ed2cdfd166f9f8d3e9bc8f3", KA.RoadWide, eA.ToWideLeft, [ ["RoadWide", "ToWideSide", { flipX: !0 }] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("3f82ebd6c72110b532a20673f8b54c7b25ae5988a51d3793bf383fea8ffcffc3", KA.RoadWide, eA.ToWideRight, [ ["RoadWide", "ToWideSide"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("f5cecce9870f41f8cba7a9fbe631c315370a7a82824d04977ec857dbb1dfed29", KA.RoadWide, eA.ToWideDouble, [ ["RoadWide", "ToWideDouble"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("99dc726611397f81b47459d32c7bfb8232322d1ca976ba9a3e71cc15451d8cfb", KA.RoadWide, eA.ToWideDiagonal, [ ["RoadWide", "ToWideDiagonal"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("47d7e3fb334681911e122babef127881a36a763fb22176854114495802d5ce84", KA.RoadWide, eA.StraightWide, [ ["RoadWide", "StraightWide"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("521adc95ed5a4809eeff7eec872c3d6449e4d6a7e4941d672f1e06a50a6615de", KA.RoadWide, eA.InnerCornerWide, [ ["RoadWide", "InnerCornerWide"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("d82274b362794e3c1772510002d5015dde345f1e72dd675c8bac41cf2331398b", KA.RoadWide, eA.OuterCornerWide, [ ["RoadWide", "OuterCornerWide"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("9b1df4dd4687404adb5789f3b90af39ea6fa65ef741a07b116dc436dc14a2aa1", KA.RoadWide, eA.SlopeUpLeftWide, [ ["RoadWide", "SlopeUpWide", { flipX: !0 }] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, -2] ] ]), new rb("651d4e988913b84359ad10e0c4745965b6a388eaa8c9bfbba4b6a50ae6d4f592", KA.RoadWide, eA.SlopeUpRightWide, [ ["RoadWide", "SlopeUpWide"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, -2] ] ]), new rb("848d9930c58e66152090d7853af87c8bb7971e1771d3c337ac1a50aaa4975a78", KA.RoadWide, eA.SlopeUpLongLeftWide, [ ["RoadWide", "SlopeUpLongWide", { flipX: !0 }] ], nb, [ [ [-2, 0, -4], [1, 0, 1] ], [ [-2, 1, -5], [1, 1, -4] ], [ [-2, 1, -6], [1, 2, -6] ] ]), new rb("e4d54c6c3b6011a1acfb6766b6b3e7ea0de6f9c6569a5ec88c47968ad4105b2a", KA.RoadWide, eA.SlopeUpLongRightWide, [ ["RoadWide", "SlopeUpLongWide"] ], nb, [ [ [-2, 0, -4], [1, 0, 1] ], [ [-2, 1, -5], [1, 1, -4] ], [ [-2, 1, -6], [1, 2, -6] ] ]), new rb("106ad1d4c5aded30cc3ef4cd1bdc40babab84464ce7dbce3b81cc20d55fd615f", KA.RoadWide, eA.SlopeDownLeftWide, [ ["RoadWide", "SlopeDownWide", { flipX: !0 }] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, 0], [1, 1, 1] ] ]), new rb("23a693633b8453c7a531de9723e6ca14d0676b1d7a4df7f78278914467b90a27", KA.RoadWide, eA.SlopeDownRightWide, [ ["RoadWide", "SlopeDownWide"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, 0], [1, 1, 1] ] ]), new rb("0f2e33a8b68667e30e80ceaefdb890a77643799d63c7f20672ca3185bbc04270", KA.RoadWide, eA.SlopeDownLongLeftWide, [ ["RoadWide", "SlopeDownLongWide", { flipX: !0 }] ], nb, [ [ [-2, 0, -2], [1, 0, 0] ], [ [-2, 1, -1], [1, 1, 5] ], [ [-2, 2, 3], [1, 2, 5] ] ]), new rb("164903518c7efa4890a792017ea2b8125a2c3dae76bba4c6f1f56fb0f7e40ebc", KA.RoadWide, eA.SlopeDownLongRightWide, [ ["RoadWide", "SlopeDownLongWide"] ], nb, [ [ [-2, 0, -2], [1, 0, 0] ], [ [-2, 1, -1], [1, 1, 5] ], [ [-2, 2, 3], [1, 2, 5] ] ]), new rb("c20560fd35288c5cc74af61834b9a56efaeacdde55eb793d400b7c5b97904993", KA.RoadWide, eA.SlopeLeftWide, [ ["RoadWide", "SlopeWide", { flipX: !0 }] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, 0] ], [ [-2, 2, -2], [1, 2, -2] ] ]), new rb("b6a26eb3cefee53d4deef24544e5b5c1ecd25e8e8bd7c3070c7947ada55c57c2", KA.RoadWide, eA.SlopeRightWide, [ ["RoadWide", "SlopeWide"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, 0] ], [ [-2, 2, -2], [1, 2, -2] ] ]), new rb("b598ff14bda99600434b24a619132fec4bffcc535483b9b57b0c8c09c1be1f1b", KA.RoadWide, eA.SlopeUpVerticalLeftWide, [ ["RoadWide", "SlopeUpVerticalWide"] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-2, 1, -1], [1, 1, -1] ], [ [-2, 1, -2], [1, 3, -2] ] ]), new rb("4e0275d3a01eaca6ec5118b8b816ed292cb7172710cf9b7801068424ab684b22", KA.RoadWide, eA.SlopeUpVerticalRightWide, [ ["RoadWide", "SlopeUpVerticalWide", { flipX: !0 }] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-2, 1, -1], [1, 1, -1] ], [ [-2, 1, -2], [1, 3, -2] ] ]), new rb("896b47675cc2ff58494979168f6fd36c27c43da29aed6a52fdf80f054630166a", KA.Plane, eA.Plane, [ ["Planes", "Plane"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("dc9afb98a8bb998d3b76c3563385e58c1749e56ff43fbc7577b1f57ba8360702", KA.Plane, eA.PlanePillarBottom, [ ["Planes", "Plane"], ["Pillar", "SurfacePillarBottom"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("f59ad95edd26814236ab30b73f6f4f68003885ef150201a4ace14b832abcf438", KA.Plane, eA.PlanePillarShort, [ ["Planes", "Plane"], ["Pillar", "SurfacePillarShort"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("48247a66b232461083fa2aa36644e7e8779f5b426d474efd375ee7d21d009c9a", KA.Plane, eA.HalfPlane, [ ["Planes", "HalfPlane"] ], nb, [ [ [-2, 0, 1], [1, 0, 1] ], [ [-2, 0, 0], [0, 0, 0] ], [ [-2, 0, -1], [-1, 0, -1] ], [ [-2, 0, -2], [-2, 0, -2] ] ]), new rb("eac8530d1a025291674bf34b206f75700dc8626012d8d33ed398f7aed746dac8", KA.Plane, eA.QuarterPlane, [ ["Planes", "QuarterPlane"] ], nb, [ [ [-2, 0, 1], [-2, 0, 1] ], [ [-2, 0, -1], [-1, 0, 0] ], [ [-2, 0, -2], [-2, 0, -2] ] ]), new rb("1da4dcad366aa90a5977e1b20c5d79297106ed3b4f664be04b6b3f6370c105b4", KA.Plane, eA.PlaneSlopeUp, [ ["Planes", "PlaneSlopeUp"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, -2] ] ]), new rb("3e203219ec0ea114da510b37a4c392b90417af796e2b089da6d996e628c0a323", KA.Plane, eA.PlaneSlopeUpLong, [ ["Planes", "PlaneSlopeUpLong"] ], nb, [ [ [-2, 0, -4], [1, 0, 1] ], [ [-2, 1, -5], [1, 1, -4] ], [ [-2, 1, -6], [1, 2, -6] ] ]), new rb("053dbf6c03eea5102b67168ccb479d8364233b36c4210aff093928bbb83d859d", KA.Plane, eA.PlaneSlopeDown, [ ["Planes", "PlaneSlopeDown"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, 0], [1, 1, 1] ] ]), new rb("d68121a3cb0ee19cab45adb136e0df6145f43ca9ecbde8a417c02a6d4a75a757", KA.Plane, eA.PlaneSlopeDownLong, [ ["Planes", "PlaneSlopeDownLong"] ], nb, [ [ [-2, 0, -2], [1, 0, 0] ], [ [-2, 1, -1], [1, 1, 5] ], [ [-2, 2, 3], [1, 2, 5] ] ]), new rb("67ec222e8fe770a8d728bb76ff571377c261d2f232134d4cb328c9ab772cf3ca", KA.Plane, eA.PlaneSlope, [ ["Planes", "PlaneSlope"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, 0] ], [ [-2, 2, -2], [1, 2, -2] ] ]), new rb("a52c09d87d37088b68420db07626f274c74f792cb223764624d887a5ed145a2e", KA.Plane, eA.PlaneSlopePillar, [ ["Planes", "PlaneSlope"], ["Pillar", "PillarTopSlope"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, 0] ], [ [-2, 2, -2], [1, 2, -2] ], [ [-1, 0, -1], [0, 0, -1] ] ]), new rb("57df805433e706ec946d767d7ff0881f163c2e36bb1db00b0e3259954a787dec", KA.Plane, eA.PlaneSlopePillarShort, [ ["Planes", "PlaneSlope"], ["Pillar", "PillarShortSlope"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, 0] ], [ [-2, 2, -2], [1, 2, -2] ], [ [-1, 0, -1], [0, 0, -1] ] ]), new rb("ba0d6ec33647740bf4c60e542d1758095afa3ef451bdaec76c783dd32116e4cb", KA.Plane, eA.PlaneSlopeVerticalBottom, [ ["Planes", "PlaneSlopeVertical"] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-2, 1, -1], [1, 1, -1] ], [ [-2, 1, -2], [1, 3, -2] ] ]), new rb("78a372de15f3151f901cf7fa7a3983ee6513cf19fa8568f10946e195c5a62515", KA.Plane, eA.PlaneSlopeToVertical, [ ["Planes", "PlaneSlopeToVertical"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, 0] ], [ [-2, 2, -2], [1, 3, -2] ] ]), new rb("5f6d1ece085d450643f1399af53673dcc6bbbf413094d8dd5ee6816d80e1c8ae", KA.Plane, eA.PlaneBridge, [ ["Planes", "PlaneBridge"] ], nb, [ [ [-1, 0, -2], [0, 0, 1] ] ]), new rb("32b91fc4cdf95f5b7a490d81058522bae14741601dd44c73cc110121aa1dd6e6", KA.Plane, eA.PlaneBridgeCorner, [ ["Planes", "PlaneBridgeCorner"] ], nb, [ [ [-1, 0, -1], [0, 0, 1] ], [ [1, 0, -1], [1, 0, 0] ] ]), new rb("2db870b1821fb655437bd0527569d5a6843718fa0775682701437432265a1a88", KA.Plane, eA.PlaneBridgeIntersectionT, [ ["Planes", "PlaneBridgeIntersectionT"] ], nb, [ [ [-1, 0, -1], [0, 0, 1] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ] ]), new rb("33aa0e7524b74dcdae4aed89856c09d25248c4cab8f70dcc31b347f0a00fcb52", KA.Plane, eA.PlaneBridgeIntersectionCross, [ ["Planes", "PlaneBridgeIntersectionCross"] ], nb, [ [ [-1, 0, -1], [0, 0, 1] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ], [ [-1, 0, -2], [0, 0, -2] ] ]), new rb("bd7cc4ab180fc0a6936fef828ae3a91566b3dd621b888fbcc57c9ac11dcb713b", KA.Plane, eA.PlaneWall, [ ["Planes", "PlaneWall"] ], nb, [ [ [-2, 0, 1], [1, 0, 1] ] ]), new rb("d92568164028bb2e65799abd9dc6ba66cfe8a28515c09fbe5ac175f5966af66a", KA.Plane, eA.PlaneWallCorner, [ ["Planes", "PlaneWallCorner"] ], nb, [ [ [-2, 0, 1], [1, 0, 1] ], [ [1, 0, -2], [1, 0, 0] ] ]), new rb("792ab5a6f0e2bf8e556575ef12731ec30755855d4394f98eb4ca7ec8b713933c", KA.Plane, eA.PlaneWallInnerCorner, [ ["Planes", "PlaneWallInnerCorner"] ], nb, [ [ [1, 0, 1], [1, 0, 1] ] ]), new rb("de0d588c4b2fe6b32d72a7e0e2984285955f805ccb86d3c269f7155401cd6b20", KA.Block, eA.Block, [ ["Blocks", "Block"] ], ib, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("1ce6b585c0e99d71877fefe015ff16336ae62eb0caebeca62dd09d836092d7b6", KA.Block, eA.HalfBlock, [ ["Blocks", "HalfBlock"] ], ib, [ [ [-2, 0, 1], [1, 0, 1] ], [ [-2, 0, 0], [0, 0, 0] ], [ [-2, 0, -1], [-1, 0, -1] ], [ [-2, 0, -2], [-2, 0, -2] ] ]), new rb("0d5f0609c3c98f687d55d3a73313225c1642f6285ddaca3ed536db742c85958d", KA.Block, eA.QuarterBlock, [ ["Blocks", "QuarterBlock"] ], ib, [ [ [-2, 0, 1], [-2, 0, 1] ], [ [-2, 0, -1], [-1, 0, 0] ], [ [-2, 0, -2], [-2, 0, -2] ] ]), new rb("18fc1c569c6fc04f95f10174143d19e7a9ea4e387302363f4ae60883c1acd3f0", KA.Block, eA.BlockSlopedDown, [ ["Blocks", "BlockSlopedDown"] ], ib, [ [ [-2, 0, -2], [1, 0, -1] ], [ [-2, 1, -2], [1, 1, 1] ] ]), new rb("22dd5b2804c88994a4d283cb822f47de3c72f82376e4c9332d39feae85206c0f", KA.Block, eA.BlockSlopedDownInnerCorner, [ ["Blocks", "BlockSlopedDownInnerCorner"] ], ib, [ [ [-2, 0, -2], [-1, 0, 1] ], [ [0, 0, -2], [1, 0, -1] ], [ [-2, 1, -2], [1, 1, 1] ] ]), new rb("81a71b4cc6ef8520f20fd738457abc31b04258c97f9862f70190fd2a0ba91382", KA.Block, eA.BlockSlopedDownOuterCorner, [ ["Blocks", "BlockSlopedDownOuterCorner"] ], ib, [ [ [-2, 0, -2], [-1, 0, -1] ], [ [-2, 1, -2], [1, 1, 1] ] ]), new rb("f4e19d3bc49994a85fecd187b76c21d258e7f30f0506d90bc6f173336e11627d", KA.Block, eA.BlockSlopedUp, [ ["Blocks", "BlockSlopedUp"] ], ib, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, -1] ] ]), new rb("fd9309468e97131bbbd1404fac34a7137cb176327789b955c1aea30267e1cded", KA.Block, eA.BlockSlopedUpInnerCorner, [ ["Blocks", "BlockSlopedUpInnerCorner"] ], ib, [ [ [-2, 1, -2], [-1, 1, 1] ], [ [0, 1, -2], [1, 1, -1] ], [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("1321fb07ece1b80b99dc4671b52673ac028fbf43322e9e652ad633ff6afac21b", KA.Block, eA.BlockSlopedUpOuterCorner, [ ["Blocks", "BlockSlopedUpOuterCorner"] ], ib, [ [ [-2, 1, -2], [-1, 1, -1] ], [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("b97c17388fc38139f2f5a98a36d94831095f79db709dd97748ad2904bc54d689", KA.Block, eA.BlockSlopeDown, [ ["Blocks", "BlockSlopeDown"] ], ib, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("50276826bbfb9fcb11a8519b8dae8a2b1cf82817d5431418d9a376664261be82", KA.Block, eA.BlockSlopeUp, [ ["Blocks", "BlockSlopeUp"] ], ib, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("63fd3032796397f8e25669c1c1d3fc97b8ec0e5fc88bfcb5c00a2a2c2b517888", KA.Block, eA.BlockSlopeDownLong, [ ["Blocks", "BlockSlopeDownLong"] ], ib, [ [ [-2, 0, -2], [1, 0, 5] ], [ [-2, 1, 0], [1, 1, 5] ] ]), new rb("2d29131222a8d891b4350e6a2f335b114e001cf22e4e2f170dc9b86c4b2fd325", KA.Block, eA.BlockSlopeUpLong, [ ["Blocks", "BlockSlopeUpLong"] ], ib, [ [ [-2, 0, -6], [1, 0, 1] ], [ [-2, 1, -6], [1, 1, -4] ] ]), new rb("0bbcd96c91b69e6e8005bfae5b64455b0d6510cb1595f3fca7f77c86ddda4560", KA.Block, eA.BlockSlopeVerticalTop, [ ["Blocks", "BlockSlopeVertical", { flipY: !0 }] ], ib, [ [ [-2, 3, -2], [1, 3, 1] ], [ [-2, 2, -2], [1, 2, -1] ], [ [-2, 0, -2], [1, 1, -2] ] ]), new rb("e81a123c0be3f8f168fb584d53e8aa038785569bbf2cd1c1cead2272889591e0", KA.Block, eA.BlockSlopeVerticalBottom, [ ["Blocks", "BlockSlopeVertical"] ], ib, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, -1] ], [ [-2, 2, -2], [1, 3, -2] ] ]), new rb("94e14468f31af7f39b9d7ba188a364089ae81da2bd6a9db2b8f5b1b8cedce741", KA.Block, eA.BlockSlopeToVertical, [ ["Blocks", "BlockSlopeToVertical"] ], ib, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, -1] ], [ [-2, 2, -2], [1, 3, -2] ] ]), new rb("3a2f05b1c2c2fd976997fa473f1adb3ba14495701dc5a998f8697798384c6946", KA.Block, eA.BlockSlopeVerticalCornerTop, [ ["Blocks", "BlockSlopeVerticalCornerBottom", { flipY: !0 }] ], ib, [ [ [-2, 3, -2], [1, 3, 1] ], [ [-2, 2, -2], [0, 2, 0] ], [ [1, 2, -2], [1, 2, -1] ], [ [-2, 2, 1], [-1, 2, 1] ], [ [-2, 1, -2], [-1, 1, -1] ], [ [-2, 1, 0], [-1, 1, 0] ], [ [0, 1, -2], [0, 1, -1] ], [ [1, 1, -2], [1, 1, -2] ], [ [-2, 1, 1], [-2, 1, 1] ], [ [-2, 0, -2], [-1, 0, -1] ], [ [-2, 0, 0], [-2, 0, 1] ], [ [0, 0, -2], [1, 0, -2] ] ]), new rb("3e4fa43e69aa1dbee584e16451a95a16229bba8d638df2bf6f6c9ffb3a9629c9", KA.Block, eA.BlockInnerCorner, [ ["Blocks", "BlockInnerCorner"] ], ib, [ [ [-2, 0, 0], [-2, 0, 1] ], [ [-2, 0, -2], [-1, 0, -1] ], [ [0, 0, -2], [1, 0, -2] ] ]), new rb("cc9c95eef56def4cf013e4ac85b8013a2b4f4b4346f1f5dd41fa017de763ef17", KA.Block, eA.BlockSlopeVerticalCornerBottom, [ ["Blocks", "BlockSlopeVerticalCornerBottom"] ], ib, [ [ [-2, 0, -2], [1, 0, 1] ], [ [-2, 1, -2], [0, 1, 0] ], [ [1, 1, -2], [1, 1, -1] ], [ [-2, 1, 1], [-1, 1, 1] ], [ [-2, 2, -2], [-1, 2, -1] ], [ [-2, 2, 0], [-1, 2, 0] ], [ [0, 2, -2], [0, 2, -1] ], [ [1, 2, -2], [1, 2, -2] ], [ [-2, 2, 1], [-2, 2, 1] ], [ [-2, 3, -2], [-1, 3, -1] ], [ [-2, 3, 0], [-2, 3, 1] ], [ [0, 3, -2], [1, 3, -2] ] ]), new rb("e4c82c8e512d52269cb6588fa34b06c179340ea40e71f74cbadadc7e8353f5a2", KA.Block, eA.BlockSlopeVerticalInnerCornerTop, [ ["Blocks", "BlockSlopeVerticalInnerCorner", { flipY: !0 }] ], ib, [ [ [-2, 3, -2], [0, 3, 1] ], [ [1, 3, -2], [1, 3, 0] ], [ [-2, 2, -2], [-2, 2, -1] ], [ [-1, 2, -2], [-1, 2, -2] ], [ [-2, 0, -2], [-2, 1, -2] ] ]), new rb("926fdc6e82ecd709cc535faea6bb8778c6e2e91edb39eb6ae6308076dca2ed18", KA.Block, eA.BlockSlopeVerticalInnerCornerBottom, [ ["Blocks", "BlockSlopeVerticalInnerCorner"] ], ib, [ [ [-2, 0, -2], [0, 0, 1] ], [ [1, 0, -2], [1, 0, 0] ], [ [-2, 1, -2], [-2, 1, -1] ], [ [-1, 1, -2], [-1, 1, -2] ], [ [-2, 2, -2], [-2, 3, -2] ] ]), new rb("1086515ba3c1d8e5ec76b378f0bdbc77fc5a57fc8eba8972f0d5e611be945235", KA.Block, eA.BlockBridge, [ ["Blocks", "BlockBridge"] ], ib, [ [ [-1, 0, -2], [0, 0, 1] ] ]), new rb("5426ad4ff64af3f1a0f0794ad30cfc20434dfffdf44d93010f5f98671c246ff3", KA.Block, eA.BlockBridgeCorner, [ ["Blocks", "BlockBridgeCorner"] ], ib, [ [ [-1, 0, -1], [0, 0, 1] ], [ [1, 0, -1], [1, 0, 0] ] ]), new rb("784b9b4459e838e5b8f74f6250769ffa52ec5cc3608abc24c380a2e792c3d338", KA.Block, eA.BlockBridgeIntersectionT, [ ["Blocks", "BlockBridgeIntersectionT"] ], ib, [ [ [-1, 0, -1], [0, 0, 1] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ] ]), new rb("dfbcbc107a3c12217bfa3b224a5757d08e995705d1c122bb2c2665bbb8447b1c", KA.Block, eA.BlockBridgeIntersectionCross, [ ["Blocks", "BlockBridgeIntersectionCross"] ], ib, [ [ [-1, 0, -1], [0, 0, 1] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ], [ [-1, 0, -2], [0, 0, -2] ] ]), new rb("5fe53442e559418b7cc9483315b0ac45b8797f9630d5ecc4c7604dab4be25584", KA.WallTrack, eA.WallTrackTop, [ ["WallTrack", "WallTrackBottom", { flipY: !0 }] ], nb, [ [ [-2, 3, -1], [1, 3, 1] ], [ [-2, 2, -1], [1, 2, -1] ], [ [-2, 0, -2], [1, 2, -2] ] ]), new rb("010d187fbfbd399bfe880bbea1b548678c239eba0be2913e5cb8a69fbd17adf7", KA.WallTrack, eA.WallTrackMiddle, [ ["WallTrack", "WallTrackMiddle"] ], nb, [ [ [-2, 0, -2], [1, 0, -2] ] ]), new rb("33216a4dcb734511a80c5bf70ca6f66de555800426686eae5a2519d4c837090e", KA.WallTrack, eA.WallTrackBottom, [ ["WallTrack", "WallTrackBottom"] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-2, 1, -1], [1, 1, -1] ], [ [-2, 1, -2], [1, 3, -2] ] ]), new rb("1e306d2a6347b68d6e275bf4ccc9c8942e0a633bf625a3bba95fa9f98ecd50ff", KA.WallTrack, eA.WallTrackSlopeToVertical, [ ["WallTrack", "WallTrackSlopeToVertical"] ], nb, [ [ [-2, 0, 0], [1, 0, 1] ], [ [-2, 1, -2], [1, 1, 0] ], [ [-2, 2, -2], [1, 3, -2] ] ]), new rb("3ed21ddbc756a6644e05f5e1ca78ff8df6d51affc472c2d86e7f23d85911e273", KA.WallTrack, eA.WallTrackTopCorner, [ ["WallTrack", "WallTrackBottomCorner", { flipY: !0 }] ], nb, [ [ [-2, 0, -1], [-2, 0, 1] ], [ [-1, 0, -1], [-1, 0, -1] ], [ [-1, 0, -2], [1, 0, -2] ], [ [-2, 1, -1], [-2, 1, 1] ], [ [-1, 1, -1], [-1, 1, 0] ], [ [0, 1, -1], [0, 1, -1] ], [ [-1, 1, -2], [1, 1, -2] ], [ [-2, 2, 0], [-2, 2, 1] ], [ [-1, 2, 1], [-1, 2, 1] ], [ [-1, 2, -1], [0, 2, 0] ], [ [1, 2, -1], [1, 2, -1] ], [ [0, 2, -2], [1, 2, -2] ], [ [0, 3, -1], [1, 3, 1] ], [ [-1, 3, 0], [-1, 3, 1] ] ]), new rb("4027a2439cc3e42ceda50ff3d427a31e127b25a6457b55edc2d498b474a296a7", KA.WallTrack, eA.WallTrackMiddleCorner, [ ["WallTrack", "WallTrackMiddleCorner"] ], nb, [ [ [-2, 0, -1], [-2, 0, 1] ], [ [-1, 0, -1], [-1, 0, -1] ], [ [-1, 0, -2], [1, 0, -2] ] ]), new rb("498286e062056a537a482ed3385fe0ac0343b399f29d470641df8f74c0532672", KA.WallTrack, eA.WallTrackBottomCorner, [ ["WallTrack", "WallTrackBottomCorner"] ], nb, [ [ [-2, 3, -1], [-2, 3, 1] ], [ [-1, 3, -1], [-1, 3, -1] ], [ [-1, 3, -2], [1, 3, -2] ], [ [-2, 2, -1], [-2, 2, 1] ], [ [-1, 2, -1], [-1, 2, 0] ], [ [0, 2, -1], [0, 2, -1] ], [ [-1, 2, -2], [1, 2, -2] ], [ [-2, 1, 0], [-2, 1, 1] ], [ [-1, 1, 1], [-1, 1, 1] ], [ [-1, 1, -1], [0, 1, 0] ], [ [1, 1, -1], [1, 1, -1] ], [ [0, 1, -2], [1, 1, -2] ], [ [0, 0, -1], [1, 0, 1] ], [ [-1, 0, 0], [-1, 0, 1] ] ]), new rb("ac09cd62c83af376f23d37dd88273614a2a11cc04a04bff6075fd749bb1ff421", KA.WallTrack, eA.WallTrackTopInnerCorner, [ ["WallTrack", "WallTrackBottomInnerCorner", { flipY: !0 }] ], nb, [ [ [-2, 3, -1], [1, 3, 1] ], [ [-1, 3, -2], [1, 3, -2] ], [ [-2, 2, -2], [-1, 2, -1] ], [ [-2, 0, -2], [-2, 1, -2] ] ]), new rb("16c9c8ece47c097f60cfc7f8a2daa2f0e7ad0befb0ebfd185402013fd1ec8e0f", KA.WallTrack, eA.WallTrackInnerCorner, [ ["WallTrack", "WallTrackInnerCorner"] ], nb, [ [ [-2, 0, -2], [-2, 0, -2] ] ]), new rb("404e7506c2f7e9302acac39c31a659e7e09e7852786e5f0244f9827727a0bf1e", KA.WallTrack, eA.WallTrackBottomInnerCorner, [ ["WallTrack", "WallTrackBottomInnerCorner"] ], nb, [ [ [-2, 0, -1], [1, 0, 1] ], [ [-1, 0, -2], [1, 0, -2] ], [ [-2, 1, -2], [-1, 1, -1] ], [ [-2, 2, -2], [-2, 3, -2] ] ]), new rb("8b7023471502607ef19109760bee3b954ea3b3883c32f3960f75c6651c912ffd", KA.WallTrack, eA.WallTrackFloor, [ ["WallTrack", "WallTrackFloor"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("59e7f31827236c71db8b16f3f1f259c4c82c87a37e4d57a5a097c0d527d128f3", KA.WallTrack, eA.WallTrackFloorCorner, [ ["WallTrack", "WallTrackFloorCorner"] ], nb, [ [ [-2, 0, 1], [1, 0, 1] ], [ [0, 0, 0], [1, 0, 0] ], [ [1, 0, -2], [1, 0, -1] ] ]), new rb("d58e3805b550b70940c845a807086865b21a4c36da74ffddedcfe5ce2d08e093", KA.WallTrack, eA.WallTrackFloorPlaneCorner, [ ["WallTrack", "WallTrackFloorPlaneCorner"] ], nb, [ [ [-2, 0, 1], [1, 0, 1] ], [ [0, 0, 0], [1, 0, 0] ], [ [1, 0, -2], [1, 0, -1] ] ]), new rb("a56b0c1cf964b213a38167cbbac6f33acd403978ad75746eb51bcfd8c6a36148", KA.WallTrack, eA.WallTrackCeiling, [ ["WallTrack", "WallTrackCeiling"] ], nb, [ [ [-2, 0, -2], [1, 0, 1] ] ]), new rb("f87b592d02120312e8e93d8a27c02dcda1095ac2f09879c6efafb2ca2b49d127", KA.WallTrack, eA.WallTrackCeilingCorner, [ ["WallTrack", "WallTrackCeilingCorner"] ], nb, [ [ [-2, 0, 1], [1, 0, 1] ], [ [0, 0, 0], [1, 0, 0] ], [ [1, 0, -2], [1, 0, -1] ] ]), new rb("cfce1fe50f8cd26393eadd475783830e02f0b39bad4c0e00f7aa69614b22decc", KA.WallTrack, eA.WallTrackCeilingPlaneCorner, [ ["WallTrack", "WallTrackCeilingPlaneCorner"] ], nb, [ [ [-2, 0, 1], [1, 0, 1] ], [ [0, 0, 0], [1, 0, 0] ], [ [1, 0, -2], [1, 0, -1] ] ]), new rb("19656d02145f1a4ba07dbf2f236f865d34c86f823741b247b5d444a36d61c316", KA.Pillar, eA.PillarTop, [ ["Pillar", "PillarTop"] ], nb, [ [ [-1, 0, -1], [0, 0, 0] ] ]), new rb("dde596d55ffc00f0f00d361667239d9f71c414f03304fecb6a7d11f6f5e702f1", KA.Pillar, eA.PillarMiddle, [ ["Pillar", "PillarMiddle"] ], nb, [ [ [-1, 0, -1], [0, 0, 0] ] ]), new rb("dced5202d9373f9dd81a39530a87a1a7036c93ae71604a4e26c3a191abf3c197", KA.Pillar, eA.PillarBottom, [ ["Pillar", "PillarBottom"] ], nb, [ [ [-1, 0, -1], [0, 0, 0] ] ]), new rb("af83eebf50c302880377e4f8c1fb3b2ef96ae193e8d03c17e1fd77c73a847e63", KA.Pillar, eA.PillarShort, [ ["Pillar", "PillarShort"] ], nb, [ [ [-1, 0, -1], [0, 0, 0] ] ]), new rb("25b41116fb04b1f3cdd3119f57e0000a6ea8cb12d435718ffd6bb765866c272f", KA.Pillar, eA.PillarBranch1, [ ["Pillar", "PillarBranch1"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ] ]), new rb("05ae39aea4f1ddd818fa57860e688c9cb875544f9b82eafe58a2eb9c19d8d91d", KA.Pillar, eA.PillarBranch1Top, [ ["Pillar", "PillarBranch1Top"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ] ]), new rb("06c29d92e42e0c32050af98d69eecc94ce15adf8ac81dbe53dfb577a83265f4e", KA.Pillar, eA.PillarBranch1Middle, [ ["Pillar", "PillarBranch1Middle"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ] ]), new rb("4a989027e0bd6db264f092bac729d9d450e012a710ea28d199f7ff52efd70fbd", KA.Pillar, eA.PillarBranch1Bottom, [ ["Pillar", "PillarBranch1Bottom"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ] ]), new rb("78b2ff83ad71e7f3d692abc35923fa20c2ae14c01e37d44ec430746ca1bac992", KA.Pillar, eA.PillarBranch2, [ ["Pillar", "PillarBranch2"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ] ]), new rb("b22c93bc73ec2da9dbff218da1676d7436527ed284e264f37294e48ef1307301", KA.Pillar, eA.PillarBranch2Top, [ ["Pillar", "PillarBranch2Top"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ] ]), new rb("79a456a8fa3da24bec6c033f6c736fa1c728745f9624ae78ca20b6a4a76afae8", KA.Pillar, eA.PillarBranch2Middle, [ ["Pillar", "PillarBranch2Middle"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ] ]), new rb("3b81b3f965cbc9fda4fe09e830ba25f1b96ce512d87b0146a1192a6cd0d07335", KA.Pillar, eA.PillarBranch2Bottom, [ ["Pillar", "PillarBranch2Bottom"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ] ]), new rb("27727678bbcac9d3b0172b165ca5c92b10f4b4584a3a18fef4c542f3e791f26f", KA.Pillar, eA.PillarBranch3, [ ["Pillar", "PillarBranch3"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ] ]), new rb("50c7ac511d30ab9e065c928b776652f038be7683d948082bbefc419ee049e505", KA.Pillar, eA.PillarBranch3Top, [ ["Pillar", "PillarBranch3Top"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ] ]), new rb("98b3bfe99e7132825f5aa93122e4e5fdec46eb2877c8eb91fa2648f709527b60", KA.Pillar, eA.PillarBranch3Middle, [ ["Pillar", "PillarBranch3Middle"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ] ]), new rb("7326bbb558f8bcc28d5875c43b1b8e3646caadb873a14fde3ab517f779aea345", KA.Pillar, eA.PillarBranch3Bottom, [ ["Pillar", "PillarBranch3Bottom"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ] ]), new rb("0e23c2615cfdb350bb3a700b6169589265a1d1079f61294fb497b8f80191d523", KA.Pillar, eA.PillarBranch4, [ ["Pillar", "PillarBranch4"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ], [ [-1, 0, 1], [0, 0, 1] ] ]), new rb("e62b55e111dbcb3faefed0a203eac5b55051a2b11911946660310e3df3588da3", KA.Pillar, eA.PillarBranch4Top, [ ["Pillar", "PillarBranch4Top"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ], [ [-1, 0, 1], [0, 0, 1] ] ]), new rb("4e2cfb89c1c591803a1440532a74c3ace37ec7fe78a526c1b57f6679c620df2e", KA.Pillar, eA.PillarBranch4Middle, [ ["Pillar", "PillarBranch4Middle"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ], [ [-1, 0, 1], [0, 0, 1] ] ]), new rb("e7807350788e4570c8bb74d4a635639ef731d83e52922fac5bc10f415f73f794", KA.Pillar, eA.PillarBranch4Bottom, [ ["Pillar", "PillarBranch4Bottom"] ], nb, [ [ [-1, 0, -2], [0, 0, 0] ], [ [1, 0, -1], [1, 0, 0] ], [ [-2, 0, -1], [-2, 0, 0] ], [ [-1, 0, 1], [0, 0, 1] ] ]), new rb("836bfd12791bfebd99aba70531da4c9bd6e332d16c1e120a8888ea54f59456f9", KA.Pillar, eA.PillarBranch5, [ ["Pillar", "PillarBranch5"] ], nb, [ [ [-2, 0, -1], [1, 0, 0] ] ]), new rb("ab85228116faf9ae7b1e6cb4a03530cbec808df3d3c1d7883eb41eb7cfe231d7", KA.Pillar, eA.PillarBranch5Top, [ ["Pillar", "PillarBranch5Top"] ], nb, [ [ [-2, 0, -1], [1, 0, 0] ] ]), new rb("db93d5cea4e523fd67a56f8d928084ab6355331a8e5d1899115c1841866006bb", KA.Pillar, eA.PillarBranch5Middle, [ ["Pillar", "PillarBranch5Middle"] ], nb, [ [ [-2, 0, -1], [1, 0, 0] ] ]), new rb("dd793efa234159e3a0ff28b064ecb715e6c8bb76e06acfe4bd0d9a2f2b9bba88", KA.Pillar, eA.PillarBranch5Bottom, [ ["Pillar", "PillarBranch5Bottom"] ], nb, [ [ [-2, 0, -1], [1, 0, 0] ] ]), new rb("350f7d3591ffd0b2cfb8204d1c6cd0022fd3bda81ea7e950fce3abea7ec89e1a", KA.Sign, eA.SignArrowLeft, [ ["Signs", "SignArrowRight", { flipX: !0 }] ], nb, [ [ [-2, 0, -2], [1, 0, -2] ] ]), new rb("22e104e58bba0a609d379578e391ce50ca523c9eee1c3fddebb6d1bb2246a0b9", KA.Sign, eA.SignArrowRight, [ ["Signs", "SignArrowRight"] ], nb, [ [ [-2, 0, -2], [1, 0, -2] ] ]), new rb("acba0cfe380e625285b973e09344e61740e77d6f8cac8691ef3e0a0b0878040e", KA.Sign, eA.SignArrowUp, [ ["Signs", "SignArrowUp"] ], nb, [ [ [-2, 0, -2], [1, 0, -2] ] ]), new rb("8d0dbea0a26bdf3addd372f5d9a2fdecfd776a48f31218acdeb036129b248ca5", KA.Sign, eA.SignArrowDown, [ ["Signs", "SignArrowUp", { flipY: !0 }] ], nb, [ [ [-2, 0, -2], [1, 0, -2] ] ]), new rb("e5e1b1ca69d7b230331171be07876c4b1bdebba557c19b18ab17d91eee2771d5", KA.Sign, eA.SignWarning, [ ["Signs", "SignWarning"] ], nb, [ [ [-2, 0, -2], [1, 0, -2] ] ]), new rb("64ed1fba4990a25bc774575ff8835117638d2c3e7c8f41bf0032d219e1083e4c", KA.Sign, eA.SignWrongWay, [ ["Signs", "SignWrongWay"] ], nb, [ [ [-2, 0, -2], [1, 0, -2] ] ])], sb = new Map; for (const e of ab) { if (sb.has(e.id)) throw new Error("Duplicate track part id " + e.id.toString()); sb.set(e.id, e) } function ob(e) { const t = sb.get(e); if (null == t) throw new Error("Unknown track part id " + e.toString()); return t } const lb = ab.filter((e => { var t; return (null === (t = e.detector) || void 0 === t ? void 0 : t.type) == XA.Checkpoint })).map((e => e.id)), cb = ab.filter((e => null != e.startOffset)).map((e => e.id)); function hb(e) { const t = e.parts; if ("object" != typeof t && null !== t && !Array.isArray(t)) return null; const n = new Sb(QA.Summer, new GA), i = Object.keys(t); for (const e of i) { const i = parseInt(e, 10); if (!(i in eA)) return null; { const e = t[i]; if (!Array.isArray(e)) return null; if (e.length % 4 != 0) return null; for (let t = 0; t < e.length; t += 4) { const r = parseInt(e[t + 0], 10), a = parseInt(e[t + 1], 10), s = parseInt(e[t + 2], 10), o = parseInt(e[t + 3], 10); if (isNaN(r) || isNaN(a) || isNaN(s) || isNaN(o)) return null; if (!(o >= 0 && o <= 3 && Math.abs(r) <= 1e9 && a >= 0 && a <= 1e9 && Math.abs(s) <= 1e9)) return null; { if (lb.includes(i)) return null; let e = null; cb.includes(i) && (e = 0), n.addPart(4 * r, a, 4 * s, i, o, nA.YPositive, Jy.Default, null, e) } } } } return n } function db(e) { let t, n; try { t = JSON.parse(e) } catch (e) { return console.error(e), null } if ("string" != typeof t.name) return null; if ("string" != typeof t.track) return null; try { n = JSON.parse(t.track) } catch (e) { return console.error(e), null } const i = hb(n); return null == i ? null : { trackMetadata: { name: t.name, author: null }, trackData: i } } function ub(e) { const t = Kg(e); if (null == t) return null; const n = new Sb(QA.Summer, new GA); let i = 0; for (; i < t.length;) { if (t.length - i < 2) return null; const e = t[i + 0] | t[i + 1] << 8; if (i += 2, !(e in eA)) return null; if (t.length - i < 4) return null; const r = t[i + 0] | t[i + 1] << 8 | t[i + 2] << 16 | t[i + 3] << 24; i += 4; for (let a = 0; a < r; ++a) { if (t.length - i < 3) return null; const r = (t[i + 0] | t[i + 1] << 8 | t[i + 2] << 16) - Math.pow(2, 23); if (i += 3, t.length - i < 3) return null; const a = t[i + 0] | t[i + 1] << 8 | t[i + 2] << 16; if (i += 3, t.length - i < 3) return null; const s = (t[i + 0] | t[i + 1] << 8 | t[i + 2] << 16) - Math.pow(2, 23); if (i += 3, t.length - i < 1) return null; const o = 3 & t[i + 0]; if (i += 1, o < 0 || o > 3) return null; if (lb.includes(e)) return null; let l = null; cb.includes(e) && (l = 0), n.addPart(4 * r, a, 4 * s, e, o, nA.YPositive, Jy.Default, null, l) } } return n } function pb(e) { const t = UA(e); if (null == t) return null; const n = new Yg.Inflate; if (n.push(t, !0), n.err) return null; const i = n.result; if (!(i instanceof Uint8Array)) return null; const r = new Sb(QA.Summer, new GA); let a = 0; for (; a < i.length;) { if (i.length - a < 2) return null; const e = i[a + 0] | i[a + 1] << 8; if (a += 2, !(e in eA)) return null; if (i.length - a < 4) return null; const t = i[a + 0] | i[a + 1] << 8 | i[a + 2] << 16 | i[a + 3] << 24; a += 4; for (let n = 0; n < t; ++n) { if (i.length - a < 3) return null; const t = (i[a + 0] | i[a + 1] << 8 | i[a + 2] << 16) - Math.pow(2, 23); if (a += 3, i.length - a < 3) return null; const n = i[a + 0] | i[a + 1] << 8 | i[a + 2] << 16; if (a += 3, i.length - a < 3) return null; const s = (i[a + 0] | i[a + 1] << 8 | i[a + 2] << 16) - Math.pow(2, 23); if (a += 3, i.length - a < 1) return null; const o = i[a + 0]; if (a += 1, o < 0 || o > 3) return null; let l = null; if (lb.includes(e)) { if (i.length - a < 2) return null; l = i[a + 0] | i[a + 1] << 8, a += 2 } let c = null; cb.includes(e) && (c = 0), r.addPart(4 * t, n, 4 * s, e, o, nA.YPositive, Jy.Default, l, c) } } return r } function fb(e) { const t = UA(e); if (null == t) return null; const n = new Yg.Inflate; if (n.push(t, !0), n.err) return null; const i = n.result; if (!(i instanceof Uint8Array)) return null; const r = new Sb(QA.Summer, new GA); let a = 0; for (; a < i.length;) { if (i.length - a < 2) return null; let e = i[a + 0] | i[a + 1] << 8; a += 2; let t = Jy.Default; if (e >= 134 && e <= 178) switch (e) { case 134: e = eA.Block, t = Jy.Custom1; break; case 135: e = eA.HalfBlock, t = Jy.Custom1; break; case 136: e = eA.QuarterBlock, t = Jy.Custom1; break; case 137: e = eA.BlockSlopedDown, t = Jy.Custom1; break; case 138: e = eA.BlockSlopedDownInnerCorner, t = Jy.Custom1; break; case 139: e = eA.BlockSlopedDownOuterCorner, t = Jy.Custom1; break; case 140: e = eA.BlockSlopedUp, t = Jy.Custom1; break; case 141: e = eA.BlockSlopedUpInnerCorner, t = Jy.Custom1; break; case 142: e = eA.BlockSlopedUpOuterCorner, t = Jy.Custom1; break; case 143: e = eA.BlockSlopeDown, t = Jy.Custom1; break; case 144: e = eA.BlockSlopeUp, t = Jy.Custom1; break; case 145: e = eA.BlockBridge, t = Jy.Custom1; break; case 146: e = eA.BlockBridgeCorner, t = Jy.Custom1; break; case 147: e = eA.BlockBridgeIntersectionT, t = Jy.Custom1; break; case 148: e = eA.BlockBridgeIntersectionCross, t = Jy.Custom1; break; case 149: e = eA.Block, t = Jy.Custom6; break; case 150: e = eA.HalfBlock, t = Jy.Custom6; break; case 151: e = eA.QuarterBlock, t = Jy.Custom6; break; case 152: e = eA.BlockSlopedDown, t = Jy.Custom6; break; case 153: e = eA.BlockSlopedDownInnerCorner, t = Jy.Custom6; break; case 154: e = eA.BlockSlopedDownOuterCorner, t = Jy.Custom6; break; case 155: e = eA.BlockSlopedUp, t = Jy.Custom6; break; case 156: e = eA.BlockSlopedUpInnerCorner, t = Jy.Custom6; break; case 157: e = eA.BlockSlopedUpOuterCorner, t = Jy.Custom6; break; case 158: e = eA.BlockSlopeDown, t = Jy.Custom6; break; case 159: e = eA.BlockSlopeUp, t = Jy.Custom6; break; case 160: e = eA.BlockBridge, t = Jy.Custom6; break; case 161: e = eA.BlockBridgeCorner, t = Jy.Custom6; break; case 162: e = eA.BlockBridgeIntersectionT, t = Jy.Custom6; break; case 163: e = eA.BlockBridgeIntersectionCross, t = Jy.Custom6; break; case 164: e = eA.Block, t = Jy.Custom0; break; case 165: e = eA.HalfBlock, t = Jy.Custom0; break; case 166: e = eA.QuarterBlock, t = Jy.Custom0; break; case 167: e = eA.BlockSlopedDown, t = Jy.Custom0; break; case 168: e = eA.BlockSlopedDownInnerCorner, t = Jy.Custom0; break; case 169: e = eA.BlockSlopedDownOuterCorner, t = Jy.Custom0; break; case 170: e = eA.BlockSlopedUp, t = Jy.Custom0; break; case 171: e = eA.BlockSlopedUpInnerCorner, t = Jy.Custom0; break; case 172: e = eA.BlockSlopedUpOuterCorner, t = Jy.Custom0; break; case 173: e = eA.BlockSlopeDown, t = Jy.Custom0; break; case 174: e = eA.BlockSlopeUp, t = Jy.Custom0; break; case 175: e = eA.BlockBridge, t = Jy.Custom0; break; case 176: e = eA.BlockBridgeCorner, t = Jy.Custom0; break; case 177: e = eA.BlockBridgeIntersectionT, t = Jy.Custom0; break; case 178: e = eA.BlockBridgeIntersectionCross, t = Jy.Custom0 } let n = null, s = { x: 0, y: 0, z: 0 }; if (79 == e) n = eA.WallTrackFloorPlaneCorner; else if (81 == e) n = eA.WallTrackCeilingPlaneCorner, s = { x: 0, y: 3, z: 0 }; else if (e >= 87 && e <= 98) switch (e) { case 87: e = eA.Slope, n = eA.BlockSlopedUp; break; case 88: e = eA.SlopeUp, n = eA.BlockSlopeUp; break; case 89: e = eA.SlopeDown, n = eA.BlockSlopeDown; break; case 90: e = eA.SlopeUpLeftWide, n = eA.BlockSlopeUp; break; case 91: e = eA.SlopeUpRightWide, n = eA.BlockSlopeUp; break; case 92: e = eA.SlopeDownLeftWide, n = eA.BlockSlopeDown; break; case 93: e = eA.SlopeDownRightWide, n = eA.BlockSlopeDown; break; case 94: e = eA.SlopeLeftWide, n = eA.BlockSlopedUp; break; case 95: e = eA.SlopeRightWide, n = eA.BlockSlopedUp; break; case 96: e = eA.PlaneSlopeUp, n = eA.BlockSlopeUp; break; case 97: e = eA.PlaneSlopeDown, n = eA.BlockSlopeDown; break; case 98: e = eA.PlaneSlope, n = eA.BlockSlopedUp; break; default: throw new Error("Invalid track part id") } if (!(e in eA)) return null; if (i.length - a < 4) return null; const o = i[a + 0] | i[a + 1] << 8 | i[a + 2] << 16 | i[a + 3] << 24; a += 4; for (let l = 0; l < o; ++l) { if (i.length - a < 3) return null; const o = (i[a + 0] | i[a + 1] << 8 | i[a + 2] << 16) - Math.pow(2, 23); if (a += 3, i.length - a < 3) return null; const l = i[a + 0] | i[a + 1] << 8 | i[a + 2] << 16; if (a += 3, i.length - a < 3) return null; const c = (i[a + 0] | i[a + 1] << 8 | i[a + 2] << 16) - Math.pow(2, 23); if (a += 3, i.length - a < 1) return null; const h = i[a + 0]; if (a += 1, h < 0 || h > 3) return null; let d = null; if (lb.includes(e)) { if (i.length - a < 2) return null; d = i[a + 0] | i[a + 1] << 8, a += 2 } let u = null; cb.includes(e) && (u = 0), null != n && r.addPart(4 * o + s.x, l + s.y, 4 * c + s.z, n, h, nA.YPositive, Jy.Default, null, u), r.addPart(4 * o, l, 4 * c, e, h, nA.YPositive, t, d, u) } } return r } function mb(e, t) { let n = e; if (t.length - n < 1) return null; const i = t[n]; if (n += 1, !(i in QA)) return null; if (t.length - n < 1) return null; const r = t[n]; if (n += 1, !Number.isSafeInteger(r) || r < 0 || r >= 180) return null; const a = new Sb(i, new GA(r)); if (t.length - n < 9) return null; const s = t[n] | t[n + 1] << 8 | t[n + 2] << 16 | t[n + 3] << 24; n += 4; const o = t[n] | t[n + 1] << 8 | t[n + 2] << 16 | t[n + 3] << 24; n += 4; const l = t[n] | t[n + 1] << 8 | t[n + 2] << 16 | t[n + 3] << 24; n += 4; const c = 3 & t[n], h = t[n] >> 2 & 3, d = t[n] >> 4 & 3; if (n += 1, c < 1 || c > 4 || h < 1 || h > 4 || d < 1 || d > 4) return null; for (; n < t.length;) { if (t.length - n < 1) return null; const e = t[n + 0]; if (n += 1, !(e in eA)) return null; if (t.length - n < 4) return null; const i = t[n + 0] | t[n + 1] << 8 | t[n + 2] << 16 | t[n + 3] << 24; n += 4; for (let r = 0; r < i; ++r) { if (t.length - n < c) return null; let i = 0; for (let e = 0; e < c; ++e) i |= t[n + e] << 8 * e; if (i += s, n += c, t.length - n < h) return null; let r = 0; for (let e = 0; e < h; ++e) r |= t[n + e] << 8 * e; if (r += o, n += h, t.length - n < d) return null; let u = 0; for (let e = 0; e < d; ++e) u |= t[n + e] << 8 * e; if (u += l, n += d, t.length - n < 1) return null; const p = t[n + 0]; if (n += 1, p < 0 || p > 3) return null; if (t.length - n < 1) return null; const f = t[n + 0]; if (n += 1, !(f in nA)) return null; if (t.length - n < 1) return null; const m = t[n + 0]; if (n += 1, !(m in Jy)) return null; let g = null; if (lb.includes(e)) { if (t.length - n < 2) return null; g = t[n + 0] | t[n + 1] << 8, n += 2 } let v = null; if (cb.includes(e)) { if (t.length - n < 4) return null; v = t[n + 0] | t[n + 1] << 8 | t[n + 2] << 16 | t[n + 3] << 24, n += 4 } a.addPart(i, r, u, e, p, f, m, g, v) } } return a } const gb = [ [new wn(0, 0, 0, 1), new wn(0, .7071067811865475, 0, .7071067811865476), new wn(0, 1, 0, 0), new wn(0, .7071067811865476, 0, -.7071067811865475)], [new wn(0, 0, 1, 0), new wn(.7071067811865475, 0, .7071067811865476, 0), new wn(1, 0, 0, 0), new wn(.7071067811865476, 0, -.7071067811865475, 0)], [new wn(0, 0, -.7071067811865477, .7071067811865475), new wn(.5, .5, -.5, .5), new wn(.7071067811865475, .7071067811865477, 0, 0), new wn(.5, .5, .5, -.5)], [new wn(0, 0, .7071067811865475, .7071067811865476), new wn(.5, -.5, .5, .5), new wn(.7071067811865476, -.7071067811865475, 0, 0), new wn(.5, -.5, -.5, -.5)], [new wn(.7071067811865475, 0, 0, .7071067811865476), new wn(.5, .5, .5, .5), new wn(0, .7071067811865476, .7071067811865475, 0), new wn(-.5, .5, .5, -.5)], [new wn(-.7071067811865477, 0, 0, .7071067811865475), new wn(-.5, -.5, .5, .5), new wn(0, -.7071067811865475, .7071067811865477, 0), new wn(.5, -.5, .5, -.5)] ]; function vb(e, t) { return gb[t][e].clone() } var wb, yb, Ab, bb, xb, kb = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, Eb = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; yb = new WeakMap, Ab = new WeakMap, wb = new WeakSet, bb = function() { let e = -1 / 0, t = null; for (const [n, i] of Eb(this, Ab, "f")) { const r = ob(n).startOffset; if (i.length > 0 && null != r) for (const n of i) { if (null == n.startOrder) throw new Error("Start part has no start order"); n.startOrder >= e && (e = n.startOrder, t = { part: n, startOffset: r }) } } return null != t ? { x: t.part.x, y: t.part.y, z: t.part.z, rotation: t.part.rotation, rotationAxis: t.part.rotationAxis, startOffset: t.startOffset.clone() } : null }, xb = function() { const e = []; e.push(this.environment), e.push(Eb(this, yb, "f").representation); let t = 1 / 0, n = 1 / 0, i = 1 / 0, r = -1 / 0, a = -1 / 0, s = -1 / 0; for (const [, e] of Eb(this, Ab, "f")) for (const o of e) t = Math.min(o.x, t), n = Math.min(o.y, n), i = Math.min(o.z, i), r = Math.max(o.x, r), a = Math.max(o.y, a), s = Math.max(o.z, s); Number.isFinite(t) && Number.isFinite(n) && Number.isFinite(i) && Number.isFinite(r) && Number.isFinite(a) && Number.isFinite(s) || (t = 0, n = 0, i = 0, r = 0, a = 0, s = 0); const o = r - t + 1, l = a - n + 1, c = s - i + 1, h = Math.max(1, Math.min(4, Math.ceil(Math.log2(o + 1) / 8))), d = Math.max(1, Math.min(4, Math.ceil(Math.log2(l + 1) / 8))), u = Math.max(1, Math.min(4, Math.ceil(Math.log2(c + 1) / 8))); e.push(255 & t, t >>> 8 & 255, t >>> 16 & 255, t >>> 24 & 255, 255 & n, n >>> 8 & 255, n >>> 16 & 255, n >>> 24 & 255, 255 & i, i >>> 8 & 255, i >>> 16 & 255, i >>> 24 & 255, 255 & (h | d << 2 | u << 4)); for (const [r, a] of Eb(this, Ab, "f")) { if (r < 0 || r > 255) throw new Error("Type id is out of range"); const s = a.length; e.push(255 & r, 255 & s, s >>> 8 & 255, s >>> 16 & 255, s >>> 24 & 255); for (const s of a) { const a = s.x - t, o = s.y - n, l = s.z - i; if (1 == h ? e.push(255 & a) : 2 == h ? e.push(255 & a, a >>> 8 & 255) : 3 == h ? e.push(255 & a, a >>> 8 & 255, a >>> 16 & 255) : 4 == h && e.push(255 & a, a >>> 8 & 255, a >>> 16 & 255, a >>> 24 & 255), 1 == d ? e.push(255 & o) : 2 == d ? e.push(255 & o, o >>> 8 & 255) : 3 == d ? e.push(255 & o, o >>> 8 & 255, o >>> 16 & 255) : 4 == d && e.push(255 & o, o >>> 8 & 255, o >>> 16 & 255, o >>> 24 & 255), 1 == u ? e.push(255 & l) : 2 == u ? e.push(255 & l, l >>> 8 & 255) : 3 == u ? e.push(255 & l, l >>> 8 & 255, l >>> 16 & 255) : 4 == u && e.push(255 & l, l >>> 8 & 255, l >>> 16 & 255, l >>> 24 & 255), e.push(3 & s.rotation, 7 & s.rotationAxis, 255 & s.color), lb.includes(r)) { if (null == s.checkpointOrder) throw new Error("Checkpoint has no checkpoint order"); e.push(255 & s.checkpointOrder, s.checkpointOrder >>> 8 & 255) } if (cb.includes(r)) { if (null == s.startOrder) throw new Error("Start has no start order"); e.push(255 & s.startOrder, s.startOrder >>> 8 & 255, s.startOrder >>> 16 & 255, s.startOrder >>> 24 & 255) } } } return new Uint8Array(e) }; const Sb = class { constructor(e, t) { wb.add(this), yb.set(this, void 0), Ab.set(this, new Map), this.environment = e, kb(this, yb, t.clone(), "f") } get sunDirection() { return Eb(this, yb, "f").clone() } set sunDirection(e) { kb(this, yb, e.clone(), "f") } addPart(e, t, n, i, r, a, s, o, l) { const c = { x: e, y: t, z: n, rotation: r, rotationAxis: a, color: s, checkpointOrder: o, startOrder: l }, h = Eb(this, Ab, "f").get(i); null != h ? h.push(c) : Eb(this, Ab, "f").set(i, [c]) } forEachPart(e) { for (const [t, n] of Eb(this, Ab, "f")) for (const i of n) e(i.x, i.y, i.z, t, i.rotation, i.rotationAxis, i.color, i.checkpointOrder, i.startOrder) } getId() { return (0, LA.sha256)(Eb(this, wb, "m", xb).call(this)) } getBounds() { let e = 1 / 0, t = 1 / 0, n = -1 / 0, i = -1 / 0; return this.forEachPart(((r, a, s) => { e = Math.min(r, e), t = Math.min(s, t), n = Math.max(r, n), i = Math.max(s, i) })), Number.isFinite(e) && Number.isFinite(t) && Number.isFinite(n) && Number.isFinite(i) ? { min: new jt(e, t), max: new jt(n, i) } : { min: new jt, max: new jt } } hasStartingPoint() { return null != Eb(this, wb, "m", bb).call(this) } getStartTransform() { const e = Eb(this, wb, "m", bb).call(this); if (null != e) { const t = vb(e.rotation, e.rotationAxis).multiply((new wn).setFromEuler(new ai(0, Math.PI, 0))), n = e.startOffset; return n.applyQuaternion(t), { position: new yn(e.x * jb.partSize + n.x, e.y * jb.partSize + n.y, e.z * jb.partSize + n.z), quaternion: t } } return null } toSaveString() { const e = Eb(this, wb, "m", xb).call(this), t = new Yg.Deflate({ level: 9, windowBits: 9, memLevel: 9 }); t.push(e, !0); const n = BA(t.result), i = new Yg.Deflate({ level: 9, windowBits: 15, memLevel: 9 }); return i.push(n, !0), BA(i.result) } toExportString(e) { const t = (new TextEncoder).encode(e.name); let n, i; null != e.author ? (i = (new TextEncoder).encode(e.author), n = i.length) : (i = null, n = 0); const r = new Uint8Array(1 + t.length + 1 + n); r[0] = t.length, r.set(t, 1), r[1 + t.length] = n, null != i && r.set(i, 1 + t.length + 1); const a = Eb(this, wb, "m", xb).call(this), s = new Yg.Deflate({ level: 9, windowBits: 9, memLevel: 9 }); s.push(r, !1), s.push(a, !0); const o = BA(s.result), l = new Yg.Deflate({ level: 9, windowBits: 15, memLevel: 9 }); return l.push(o, !0), "PolyTrack1" + BA(l.result) } static fromSaveString(e) { const t = function(e) { const t = UA(e); if (null == t) return null; const n = new Yg.Inflate({ to: "string" }); if (n.push(t, !0), n.err) return null; const i = n.result; if ("string" != typeof i) return null; const r = UA(i); if (null == r) return null; const a = new Yg.Inflate; if (a.push(r, !0), a.err) return null; const s = a.result; return s instanceof Uint8Array ? mb(0, s) : null }(e); if (null != t) return t; const n = fb(e); if (null != n) return n; const i = pb(e); if (null != i) return i; const r = ub(e); if (null != r) return r; const a = hb(e); return null != a ? a : null } static fromExportString(e) { const t = e.replace(/\s+/g, ""), n = function(e) { const t = "PolyTrack1"; if (!e.startsWith(t)) return null; const n = UA(e.substring(10)); if (null == n) return null; const i = new Yg.Inflate({ to: "string" }); if (i.push(n, !0), i.err) return null; const r = i.result; if ("string" != typeof r) return null; const a = UA(r); if (null == a) return null; const s = new Yg.Inflate; if (s.push(a, !0), s.err) return null; const o = s.result; if (!(o instanceof Uint8Array)) return null; const l = o[0]; if (o.length < 1 + l) return null; const c = new TextDecoder("utf-8").decode(o.subarray(1, 1 + l)), h = o[1 + l]; if (o.length < 1 + l + 1 + h) return null; let d; d = h > 0 ? new TextDecoder("utf-8").decode(o.subarray(1 + l + 1, 1 + l + 1 + h)) : null; const u = mb(1 + l + 1 + h, o); return null == u ? null : { trackMetadata: { name: c, author: d }, trackData: u } }(t); if (null != n) return n; const i = function(e) { if (!e.startsWith("v3")) return null; const t = UA(e.substring(2, 4)); if (null == t) return null; if (1 != t.length) return null; const n = t[0], i = UA(e.substring(4, 4 + n)); if (null == i) return null; let r; try { r = new TextDecoder("utf-8").decode(i) } catch (e) { return null } const a = fb(e.substring(4 + n)); return null == a ? null : { trackMetadata: { name: r, author: null }, trackData: a } }(t); if (null != i) return i; const r = function(e) { if (!e.startsWith("v2")) return null; const t = UA(e.substring(2, 4)); if (null == t) return null; if (1 != t.length) return null; const n = t[0], i = Math.ceil(n / 3 * 4), r = UA(e.substring(4, 4 + i)); if (null == r) return null; let a; try { a = new TextDecoder("utf-8").decode(r) } catch (e) { return null } const s = pb(e.substring(4 + i)); return null == s ? null : { trackMetadata: { name: a, author: null }, trackData: s } }(t); if (null != r) return r; const a = function(e) { if (!e.startsWith("v1n")) return null; const t = Kg(e.substring(3, 5)); if (null == t) return null; if (1 != t.length) return null; const n = t[0], i = e.substring(5, 5 + n); let r; try { r = decodeURIComponent(i) } catch (e) { return console.error(e), null } const a = ub(e.substring(5 + n)); return null == a ? null : { trackMetadata: { name: r, author: null }, trackData: a } }(t); if (null != a) return a; const s = db(e); return null != s ? s : null } createThumbnail() { let e = 1 / 0, t = 1 / 0, n = -1 / 0, i = -1 / 0; this.forEachPart(((r, a, s, o, l, c) => { ob(o).tiles.rotated(l, c).forEach(((a, o, l) => { e = Math.min(e, Math.floor((r + a - 2) / 4)), t = Math.min(t, Math.floor((s + l - 2) / 4)), n = Math.max(n, Math.floor((r + a - 2) / 4)), i = Math.max(i, Math.floor((s + l - 2) / 4)) })) })), Number.isFinite(e) && Number.isFinite(t) && Number.isFinite(n) && Number.isFinite(i) || (e = 0, t = 0, n = 0, i = 0); const r = 10, a = n - e + 1; a <= r && (n += Math.ceil((r - a) / 2), e -= Math.ceil((r - a) / 2)); const s = i - t + 1; s <= r && (i += Math.ceil((r - s) / 2), t -= Math.ceil((r - s) / 2)); const o = document.createElement("canvas"); o.width = Math.min(1024, n - e + 1), o.height = Math.min(1024, i - t + 1); const l = o.getContext("2d"); if (null == l) throw new Error("Failed to get canvas context"); const c = l.createImageData(o.width, o.height), h = [], d = [], u = []; let p, f, m; switch (this.environment) { case QA.Summer: p = 255, f = 255, m = 255; break; case QA.Winter: p = 190, f = 216, m = 247; break; case QA.Desert: p = 237, f = 226, m = 175 } this.forEachPart(((n, i, r, a, s, l) => { const g = ob(a); g.tiles.rotated(s, l).forEach(((i, a, s) => { const l = Math.floor((n + i - 2) / 4) - e, v = Math.floor((r + s - 2) / 4) - t, w = 4 * (l + v * o.width); c.data[w + 0] = p, c.data[w + 1] = f, c.data[w + 2] = m, c.data[w + 3] = 255, null != g.startOffset ? d.push([l, v]) : null != g.detector && g.detector.type == XA.Checkpoint ? h.push([l, v]) : null != g.detector && g.detector.type == XA.Finish && u.push([l, v]) })) })); for (const [e, t] of h) c.data[4 * (e + t * o.width) + 0] = 226, c.data[4 * (e + t * o.width) + 1] = 192, c.data[4 * (e + t * o.width) + 2] = 38, c.data[4 * (e + t * o.width) + 3] = 255; for (const [e, t] of d) c.data[4 * (e + t * o.width) + 0] = 51, c.data[4 * (e + t * o.width) + 1] = 140, c.data[4 * (e + t * o.width) + 2] = 224, c.data[4 * (e + t * o.width) + 3] = 255; for (const [e, t] of u) c.data[4 * (e + t * o.width) + 0] = 209, c.data[4 * (e + t * o.width) + 1] = 41, c.data[4 * (e + t * o.width) + 2] = 41, c.data[4 * (e + t * o.width) + 3] = 255; return l.putImageData(c, 0, 0), o } }; var Mb, Tb, _b, Cb, Pb, Ib, Rb, Lb, Db, Nb, Bb, Ub, zb, Ob, Fb, Wb = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, Vb = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class Hb { constructor(e, t, n, i, r, a, s, o, l, c) { if (this.checkpointOrder = null, this.startOrder = null, this.x = e, this.y = t, this.z = n, this.rotation = i, this.rotationAxis = r, this.color = a, this.type = s, this.matrix = o, this.checkpointOrder = l, this.startOrder = c, null != s.configuration.detector && s.configuration.detector.type == XA.Checkpoint) { if (null == l) throw new Error("Checkpoint has no checkpoint order") } else if (null != l) throw new Error("Non-checkpoint has checkpoint order"); if (null != s.configuration.startOffset && null == c) throw new Error("Start part has no start order"); if (null == s.configuration.startOffset && null != c) throw new Error("Non-start part has start order") } } class Gb { constructor(e, t, n) { Mb.add(this), Tb.set(this, void 0), _b.set(this, void 0), Cb.set(this, void 0), this.environment = QA.Summer, Pb.set(this, new GA), Ib.set(this, []), Rb.set(this, new Map), Lb.set(this, new Map), Db.set(this, { min: new jt(0, 0), max: new jt(0, 0) }), Nb.set(this, null), Bb.set(this, []), Wb(this, Tb, e, "f"), Wb(this, _b, t, "f"), Wb(this, Cb, n, "f") } get sunDirection() { return Vb(this, Pb, "f") } set sunDirection(e) { Wb(this, Pb, e.clone(), "f") } getID() { return Vb(this, Nb, "f") } clear() { Wb(this, Nb, null, "f"), Vb(this, Ib, "f").length = 0, Vb(this, Rb, "f").clear(), Vb(this, Lb, "f").clear(), Vb(this, Mb, "m", Ub).call(this) } getPartsAt(e, t, n) { const i = Vb(this, Rb, "f").get(e.toString() + "|" + t.toString() + "|" + n.toString()); return null == i ? [] : i.map((e => ({ id: e.type.configuration.id, x: e.x, y: e.y, z: e.z, rotation: e.rotation, rotationAxis: e.rotationAxis, color: e.color }))) } setPart(e, t, n, i, r, a, s, o, l) { const c = Vb(this, Cb, "f").getPart(i); if (s != Jy.Default && !c.colors.has(s)) throw new Error("Track part color does not exist"); const h = vb(r, a), d = new yn(e * Gb.partSize, t * Gb.partSize, n * Gb.partSize), u = (new qn).compose(d, h, new yn(1, 1, 1)), p = new Hb(e, t, n, r, a, s, c, u, o, l); Vb(this, Ib, "f").push(p); c.configuration.tiles.rotated(r, a).forEach(((i, r, a) => { const s = (e + i).toString() + "|" + (t + r).toString() + "|" + (n + a).toString(); if (t + r < 0) throw new Error("Track part below ground"); { const e = Vb(this, Rb, "f").get(s); null == e ? Vb(this, Rb, "f").set(s, [p]) : e.push(p) } })); const f = Vb(this, Lb, "f").get(i); null == f ? Vb(this, Lb, "f").set(i, [p]) : f.push(p) } deletePartsAt(e, t, n) { const i = Vb(this, Rb, "f").get(e.toString() + "|" + t.toString() + "|" + n.toString()); if (null == i) return !1; for (const e of i) Vb(this, Mb, "m", Ob).call(this, e); return !0 } deleteSpecificPart(e, t, n, i, r, a) { for (const s of Vb(this, Ib, "f")) if (s.type.configuration.id == e && s.x == t && s.y == n && s.z == i && s.rotation == r && s.rotationAxis == a) return Vb(this, Mb, "m", Ob).call(this, s), !0; return !1 } getBounds() { return Vb(this, Db, "f") } shortRaycast(e) { const t = new yn(Math.floor(e.ray.origin.x / Gb.partSize), Math.floor(e.ray.origin.y / Gb.partSize), Math.floor(e.ray.origin.z / Gb.partSize)), n = new Set; for (let e = -1; e <= 0; e++) for (let i = -1; i <= 0; i++) for (let r = -1; r <= 0; r++) { const a = Vb(this, Mb, "m", zb).call(this, t.x + e, t.y + i, t.z + r); for (const e of a) n.add(e) } let i = null; for (const t of n) { let n = t.color; n == Jy.Default && (n = Jy.Summer); const r = t.type.colors.get(n); if (null == r) throw new Error("Track part is not loaded yet"); if (null == i) { r.matrixWorld.copy(t.matrix); const n = e.intersectObject(r, !0); n.length > 0 && (i = n[0]) } } return i } generateMeshes() { Vb(this, Mb, "m", Ub).call(this); const e = Vb(this, Pb, "f").getSunPosition(), t = new pn(e.x, e.y, e.z, 0); let n, i = null; if (Vb(this, _b, "f").getSettingBoolean($o.TrackShadowEnabled)) switch (this.environment) { case QA.Summer: i = new Wi(1192238); break; case QA.Winter: i = new Wi(3825803); break; case QA.Desert: i = new Wi(3883831) } switch (this.environment) { case QA.Summer: n = Jy.Summer; break; case QA.Winter: n = Jy.Winter; break; case QA.Desert: n = Jy.Desert } for (const e of Vb(this, Cb, "f").getAllParts()) for (const [r, a] of e.colors) { const s = []; for (const t of Vb(this, Ib, "f")) { let i = t.color; i == Jy.Default && (i = n), t.type == e && i == r && s.push(t) } if (s.length > 0) { if (null == a) throw new Error("Mesh is not loaded"); const e = new ua(a.geometry, a.material, s.length); e.frustumCulled = !1, e.receiveShadow = !0; for (let t = 0; t < s.length; ++t) e.setMatrixAt(t, s[t].matrix); if (Vb(this, Tb, "f").scene.add(e), Vb(this, Bb, "f").push(e), null != i) { const n = new RA(e, i); n.update(new ga(new yn(0, 1, 0), 0), t), Vb(this, Tb, "f").scene.add(n), Vb(this, Bb, "f").push(n) } } } Vb(this, Mb, "m", Fb).call(this) } getCheckpoints() { let e = []; const t = Vb(this, Cb, "f").getPartTypesWithDetector(XA.Checkpoint); for (const n of t) { const t = Vb(this, Lb, "f").get(n); null != t && (e = e.concat(t)) } return e.map((e => { if (null == e.checkpointOrder) throw new Error("Checkpoint has no checkpoint order"); if (null == e.type.configuration.detector) throw new Error("Checkpoint has no detector"); return { x: e.x, y: e.y, z: e.z, rotation: e.rotation, rotationAxis: e.rotationAxis, type: e.type.configuration.id, checkpointOrder: e.checkpointOrder, detector: e.type.configuration.detector } })) } getCheckpointOrders() { let e = []; const t = Vb(this, Cb, "f").getPartTypesWithDetector(XA.Checkpoint); for (const n of t) { const t = Vb(this, Lb, "f").get(n); null != t && (e = e.concat(t)) } return e.map((e => { if (null == e.checkpointOrder) throw new Error("Checkpoint has no checkpoint order"); if (null == e.type.configuration.detector) throw new Error("Checkpoint has no detector"); return e.checkpointOrder })) } getTotalNumberOfCheckpointIndices() { let e = []; const t = Vb(this, Cb, "f").getPartTypesWithDetector(XA.Checkpoint); for (const n of t) { const t = Vb(this, Lb, "f").get(n); null != t && (e = e.concat(t)) } return e.map((e => e.checkpointOrder)).filter(((e, t, n) => n.indexOf(e) == t)).length } getStart() { let e = -1 / 0, t = null; for (const [n, i] of Vb(this, Lb, "f")) { const r = Vb(this, Cb, "f").getPartStartOffset(n); if (i.length > 0 && null != r) for (const n of i) { if (null == n.startOrder) throw new Error("Start part has no start order"); n.startOrder >= e && (e = n.startOrder, t = { part: n, startOffset: r }) } } return null != t ? { x: t.part.x, y: t.part.y, z: t.part.z, rotation: t.part.rotation, rotationAxis: t.part.rotationAxis, startOffset: t.startOffset } : null } getStartTransform() { const e = this.getStart(); if (null != e) { const t = vb(e.rotation, e.rotationAxis).multiply((new wn).setFromEuler(new ai(0, Math.PI, 0))), n = e.startOffset; return n.applyQuaternion(t), { position: new yn(e.x * Gb.partSize + n.x, e.y * Gb.partSize + n.y, e.z * Gb.partSize + n.z), quaternion: t } } return null } getNextStartOrder() { let e = 0; for (const [t, n] of Vb(this, Lb, "f")) { const i = Vb(this, Cb, "f").getPartStartOffset(t); if (n.length > 0 && null != i) for (const t of n) { if (null == t.startOrder) throw new Error("Start part has no start order"); e = Math.max(e, t.startOrder + 1) } } return e } getTrackData() { const e = new Sb(this.environment, Vb(this, Pb, "f")); for (const t of Vb(this, Ib, "f")) e.addPart(t.x, t.y, t.z, t.type.configuration.id, t.rotation, t.rotationAxis, t.color, t.checkpointOrder, t.startOrder); return e } loadTrackData(e, t = !0) { return this.clear(), Wb(this, Nb, t ? e.getId() : null, "f"), this.environment = e.environment, this.sunDirection = e.sunDirection.clone(), e.forEachPart(((e, t, n, i, r, a, s, o, l) => { this.setPart(e, t, n, i, r, a, s, o, l) })), !0 } } Tb = new WeakMap, _b = new WeakMap, Cb = new WeakMap, Pb = new WeakMap, Ib = new WeakMap, Rb = new WeakMap, Lb = new WeakMap, Db = new WeakMap, Nb = new WeakMap, Bb = new WeakMap, Mb = new WeakSet, Ub = function() { for (const e of Vb(this, Bb, "f")) Vb(this, Tb, "f").scene.remove(e); Vb(this, Bb, "f").length = 0 }, zb = function(e, t, n) { var i; return null !== (i = Vb(this, Rb, "f").get(e.toString() + "|" + t.toString() + "|" + n.toString())) && void 0 !== i ? i : [] }, Ob = function(e) { const t = Vb(this, Ib, "f").indexOf(e); if (!(t >= 0)) throw new Error("Track part missing from parts list"); Vb(this, Ib, "f").splice(t, 1); e.type.configuration.tiles.rotated(e.rotation, e.rotationAxis).forEach(((t, n, i) => { const r = (e.x + t).toString() + "|" + (e.y + n).toString() + "|" + (e.z + i).toString(), a = Vb(this, Rb, "f").get(r); if (null == a) throw new Error("Track part section missing"); { const t = a.indexOf(e); if (!(t >= 0)) throw new Error("Track part missing from parts by position map"); a.splice(t, 1), 0 == a.length && Vb(this, Rb, "f").delete(r) } })); const n = Vb(this, Lb, "f").get(e.type.configuration.id); if (null == n) throw new Error("Track part type is missing from parts by type map"); for (let t = 0; t < n.length; ++t) { if (n[t] == e) { n.splice(t, 1); break } if (t == n.length - 1) throw new Error("Track part is missing from parts by type map") } }, Fb = function() { let e = 1 / 0, t = 1 / 0, n = -1 / 0, i = -1 / 0; for (const r of Vb(this, Ib, "f")) e = Math.min(r.x, e), t = Math.min(r.z, t), n = Math.max(r.x, n), i = Math.max(r.z, i); Number.isFinite(e) && Number.isFinite(t) && Number.isFinite(n) && Number.isFinite(i) ? Wb(this, Db, { min: new jt(e, t), max: new jt(n, i) }, "f") : Wb(this, Db, { min: new jt, max: new jt }, "f") }, Gb.partSize = 5; const jb = Gb; var Qb, Yb, Kb, qb, Xb, Zb = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, Jb = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class $b { constructor(e) { Yb.set(this, void 0), Kb.set(this, []), qb.set(this, []), Zb(this, Yb, e, "f") } dispose() { for (const e of Jb(this, Kb, "f")) { if (Array.isArray(e.material)) for (const t of e.material) t.dispose(); else e.material.dispose(); e.geometry.dispose(), Jb(this, Yb, "f").scene.remove(e) } Jb(this, Kb, "f").length = 0 } refresh(e) { const t = e.getCheckpoints(); let n = !1; if (t.length == Jb(this, qb, "f").length) for (let e = 0; e < t.length; e++) { const i = t[e], r = Jb(this, qb, "f")[e]; if (i.x != r.x || i.y != r.y || i.z != r.z || i.rotation != r.rotation || i.rotationAxis != r.rotationAxis || i.type != r.type || i.checkpointOrder != r.checkpointOrder) { n = !0; break } } else n = !0; if (n) { this.dispose(), Zb(this, qb, t, "f"); const e = new ji({ color: 16777215 }); for (const n of t) { if (null == Jb(Qb, Qb, "f", Xb)) throw new Error("Font is not loaded yet"); const t = vb(n.rotation, n.rotationAxis), i = new yn(...n.detector.center).add(new yn(0, -1.3, 0)).applyQuaternion(t); i.add(new yn(n.x * jb.partSize, n.y * jb.partSize, n.z * jb.partSize)); const r = Jb(Qb, Qb, "f", Xb).generateShapes((n.checkpointOrder + 1).toString(), 4), a = new Bs(r); a.computeBoundingBox(); const s = a.boundingBox; if (null == s) throw new Error("Bounding box is null"); const o = -.5 * (s.max.x - s.min.x); a.translate(o, 0, 0); const l = new wr(a, e); l.position.copy(i), l.quaternion.copy(t), Jb(this, Yb, "f").scene.add(l), Jb(this, Kb, "f").push(l); const c = new wr(a, e); c.position.copy(i), c.quaternion.copy(t).multiply((new wn).setFromEuler(new ai(0, Math.PI, 0))), Jb(this, Yb, "f").scene.add(c), Jb(this, Kb, "f").push(c) } } } static initResources(e) { e.addResource(); (new CA).load("forced_square.json", (t => { Zb(this, Qb, t, "f", Xb), e.loadedResource() })) } } Qb = $b, Yb = new WeakMap, Kb = new WeakMap, qb = new WeakMap, Xb = { value: null }; const ex = $b; var tx = n(8909), nx = {}; nx.styleTagTransform = u(), nx.setAttributes = l(), nx.insert = s().bind(null, "head"), nx.domAPI = r(), nx.insertStyleElement = h(); t()(tx.A, nx); tx.A && tx.A.locals && tx.A.locals; var ix, rx, ax, sx, ox, lx, cx, hx, dx, ux, px = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, fx = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; rx = new WeakMap, ax = new WeakMap, sx = new WeakMap, ox = new WeakMap, lx = new WeakMap, cx = new WeakMap, hx = new WeakMap, ix = new WeakSet, dx = function() { fx(this, lx, "f").textContent = fx(this, ax, "f").get("Checkpoint order") + ": " + (this.checkpointOrder + 1).toString() }, ux = function(e) { const t = e.getCheckpointOrders(), n = new Set; for (const e of t) n.add(e); for (let e = 0; e < 65535; e++) if (!n.has(e)) return e; return 65535 }; const mx = class { constructor(e, t, n, i) { ix.add(this), rx.set(this, void 0), ax.set(this, void 0), sx.set(this, void 0), ox.set(this, void 0), lx.set(this, void 0), cx.set(this, 0), hx.set(this, void 0), px(this, rx, e, "f"), px(this, ax, t, "f"), px(this, sx, i, "f"), px(this, ox, document.createElement("div"), "f"), fx(this, ox, "f").className = "hidden", e.appendChild(fx(this, ox, "f")), fx(this, sx, "f").addChangeListener(px(this, hx, (e => { e ? fx(this, ox, "f").classList.add("touch") : fx(this, ox, "f").classList.remove("touch") }), "f")); const r = document.createElement("div"); r.className = "buttons", fx(this, ox, "f").appendChild(r); const a = document.createElement("button"); a.addEventListener("click", (() => { n.playUIClick(), this.checkpointOrder++ })), r.appendChild(a); const s = document.createElement("img"); s.src = "images/arrow_up.svg", a.appendChild(s); const o = document.createElement("button"); o.addEventListener("click", (() => { n.playUIClick(), this.checkpointOrder-- })), r.appendChild(o); const l = document.createElement("img"); l.src = "images/arrow_down.svg", o.appendChild(l), px(this, lx, document.createElement("p"), "f"), fx(this, ox, "f").appendChild(fx(this, lx, "f")), fx(this, ix, "m", dx).call(this) } dispose() { fx(this, rx, "f").removeChild(fx(this, ox, "f")), fx(this, sx, "f").removeChangeListener(fx(this, hx, "f")) } hide() { fx(this, ox, "f").classList.add("hidden"), fx(this, ox, "f").classList.remove("editor-checkpoint-order") } show() { fx(this, ox, "f").classList.remove("hidden"), fx(this, ox, "f").classList.add("editor-checkpoint-order") } reset() { this.checkpointOrder = 0 } get checkpointOrder() { return fx(this, cx, "f") } set checkpointOrder(e) { px(this, cx, Math.max(0, Math.min(65535, e)), "f"), fx(this, ix, "m", dx).call(this) } setFromExistingCheckpoints(e) { this.checkpointOrder = fx(this, ix, "m", ux).call(this, e) } }; var gx = n(5007), vx = {}; vx.styleTagTransform = u(), vx.setAttributes = l(), vx.insert = s().bind(null, "head"), vx.domAPI = r(), vx.insertStyleElement = h(); t()(gx.A, vx); gx.A && gx.A.locals && gx.A.locals; var wx, yx, Ax, bx, xx, kx, Ex, Sx, Mx, Tx = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, _x = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; wx = new WeakMap, yx = new WeakMap, Ax = new WeakMap, bx = new WeakMap, xx = new WeakMap, kx = new WeakMap, Ex = new WeakMap, Sx = new WeakMap, Mx = new WeakMap; const Cx = class { constructor(e, t, n, i, r) { wx.set(this, void 0), yx.set(this, void 0), Ax.set(this, void 0), bx.set(this, void 0), xx.set(this, void 0), kx.set(this, void 0), Ex.set(this, !1), Sx.set(this, !1), Mx.set(this, void 0), Tx(this, wx, e, "f"), Tx(this, yx, t, "f"), Tx(this, Ax, n, "f"), Tx(this, bx, document.createElement("div"), "f"), _x(this, bx, "f").className = "editor-height-selector", e.appendChild(_x(this, bx, "f")), _x(this, Ax, "f").addChangeListener(Tx(this, kx, (e => { e ? _x(this, bx, "f").classList.add("touch") : _x(this, bx, "f").classList.remove("touch") }), "f")), Tx(this, xx, document.createElement("p"), "f"), _x(this, bx, "f").appendChild(_x(this, xx, "f")); const a = document.createElement("div"); a.className = "buttons", _x(this, bx, "f").appendChild(a); const s = document.createElement("button"); s.addEventListener("pointerdown", (() => { if (i(), !_x(this, Ex, "f")) { Tx(this, Ex, !0, "f"); const e = () => { _x(this, Ex, "f") && (i(), setTimeout(e, 50)) }; setTimeout(e, 500) } })), a.appendChild(s); const o = document.createElement("img"); o.src = "images/arrow_up.svg", s.appendChild(o); const l = document.createElement("button"); l.addEventListener("pointerdown", (() => { if (r(), !_x(this, Sx, "f")) { Tx(this, Sx, !0, "f"); const e = () => { _x(this, Sx, "f") && (r(), setTimeout(e, 50)) }; setTimeout(e, 500) } })), a.appendChild(l); const c = document.createElement("img"); c.src = "images/arrow_down.svg", l.appendChild(c), Tx(this, Mx, (() => { Tx(this, Ex, !1, "f"), Tx(this, Sx, !1, "f") }), "f"), window.addEventListener("pointerup", _x(this, Mx, "f")) } refresh(e) { _x(this, xx, "f").textContent = _x(this, yx, "f").get("Height") + ": " + e.toString() } dispose() { _x(this, wx, "f").removeChild(_x(this, bx, "f")), _x(this, Ax, "f").removeChangeListener(_x(this, kx, "f")), window.removeEventListener("pointerup", _x(this, Mx, "f")) } }; var Px; ! function(e) { e[e.VehicleAccelerate = 0] = "VehicleAccelerate", e[e.VehicleTurnRight = 1] = "VehicleTurnRight", e[e.VehicleBrake = 2] = "VehicleBrake", e[e.VehicleTurnLeft = 3] = "VehicleTurnLeft", e[e.VehicleCheckpointReset = 4] = "VehicleCheckpointReset", e[e.VehicleStartReset = 5] = "VehicleStartReset", e[e.VehicleCockpitCamera = 6] = "VehicleCockpitCamera", e[e.ToggleUI = 7] = "ToggleUI", e[e.Pause = 8] = "Pause", e[e.EditorRotatePart = 9] = "EditorRotatePart", e[e.EditorHeightModifier = 10] = "EditorHeightModifier", e[e.EditorDelete = 11] = "EditorDelete", e[e.EditorMoveForwards = 12] = "EditorMoveForwards", e[e.EditorMoveRight = 13] = "EditorMoveRight", e[e.EditorMoveBackwards = 14] = "EditorMoveBackwards", e[e.EditorMoveLeft = 15] = "EditorMoveLeft", e[e.EditorRotateViewUp = 16] = "EditorRotateViewUp", e[e.EditorRotateViewDown = 17] = "EditorRotateViewDown", e[e.EditorRotateViewLeft = 18] = "EditorRotateViewLeft", e[e.EditorRotateViewRight = 19] = "EditorRotateViewRight", e[e.EditorMoveDown = 20] = "EditorMoveDown", e[e.EditorMoveUp = 21] = "EditorMoveUp", e[e.EditorTest = 22] = "EditorTest", e[e.EditorPick = 23] = "EditorPick", e[e.ToggleFpsCounter = 24] = "ToggleFpsCounter", e[e.ToggleSpectatorCamera = 25] = "ToggleSpectatorCamera", e[e.SpectatorMoveForwards = 26] = "SpectatorMoveForwards", e[e.SpectatorMoveRight = 27] = "SpectatorMoveRight", e[e.SpectatorMoveBackwards = 28] = "SpectatorMoveBackwards", e[e.SpectatorMoveLeft = 29] = "SpectatorMoveLeft", e[e.SpectatorSpeedModifier = 30] = "SpectatorSpeedModifier" }(Px || (Px = {})); const Ix = Px; var Rx = n(7687), Lx = {}; Lx.styleTagTransform = u(), Lx.setAttributes = l(), Lx.insert = s().bind(null, "head"), Lx.domAPI = r(), Lx.insertStyleElement = h(); t()(Rx.A, Lx); Rx.A && Rx.A.locals && Rx.A.locals; var Dx, Nx, Bx, Ux, zx, Ox, Fx, Wx = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, Vx = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; Dx = new WeakMap, Nx = new WeakMap, Bx = new WeakMap, Ux = new WeakMap, zx = new WeakMap, Ox = new WeakMap, Fx = new WeakMap; const Hx = class { constructor(e, t, n, i, r, a, s, o) { Dx.set(this, void 0), Nx.set(this, void 0), Bx.set(this, void 0), Ux.set(this, void 0), zx.set(this, void 0), Ox.set(this, void 0), Fx.set(this, void 0), Wx(this, Dx, r, "f"); const l = document.getElementById("ui"); if (null == l) throw new Error("UI element not found"); Wx(this, Nx, l, "f"), Wx(this, Bx, document.createElement("div"), "f"), Vx(this, Bx, "f").className = "track-export", Vx(this, Nx, "f").appendChild(Vx(this, Bx, "f")); const c = document.createElement("div"); c.className = "background", Vx(this, Bx, "f").appendChild(c); const h = document.createElement("div"); h.className = "box", Vx(this, Bx, "f").appendChild(h); const d = document.createElement("div"); d.className = "bar", h.appendChild(d); const u = document.createElement("button"); u.className = "button", u.innerHTML = ' ', u.append(document.createTextNode(r.get("Back"))), u.addEventListener("click", (() => { a.playUIClick(), t() })), d.appendChild(u), Wx(this, zx, document.createElement("button"), "f"), Vx(this, zx, "f").className = "hidden", Vx(this, zx, "f").innerHTML = ' ', Vx(this, zx, "f").append(document.createTextNode(r.get("Copy"))), Vx(this, zx, "f").addEventListener("click", (() => { a.playUIClick(); try { navigator.clipboard.writeText(Vx(this, Ux, "f").value).catch((e => { console.error(e) })) } catch (e) { console.error(e) } })), d.appendChild(Vx(this, zx, "f")), Wx(this, Ox, document.createElement("button"), "f"), Vx(this, Ox, "f").className = "hidden", Vx(this, Ox, "f").innerHTML = ' ', Vx(this, Ox, "f").append(document.createTextNode(r.get("Import"))), Vx(this, Ox, "f").addEventListener("click", (() => { a.playUIClick(); const e = () => { const e = Vx(this, Bx, "f").className; Vx(this, Bx, "f").className = "hidden", o.show(r.get("Failed to import track"), r.get("Ok"), (() => { Vx(this, Bx, "f").className = e })) }, i = Vx(this, Ux, "f").value, l = Sb.fromExportString(i); if (null == l) e(); else { const { trackMetadata: i, trackData: a } = l, c = a.getId(), h = a.createThumbnail(); if (s.checkCustomTrackNameExists(i.name)) { const l = Vx(this, Bx, "f").className; Vx(this, Bx, "f").className = "hidden", o.showConfirm(r.get('The track "{0}" already exists. Do you wish to overwrite it?', [i.name]), r.get("Cancel"), r.get("Overwrite"), (() => { Vx(this, Bx, "f").className = l }), (() => { Vx(this, Bx, "f").className = l, s.saveCustomTrack(i, a) ? null != n ? n(i, a, c, h) : t() : e() })) } else s.saveCustomTrack(i, a) ? null != n ? n(i, a, c, h) : t() : e() } })), d.appendChild(Vx(this, Ox, "f")), Wx(this, Ux, document.createElement("textarea"), "f"), Vx(this, Ux, "f").spellcheck = !1, h.appendChild(Vx(this, Ux, "f")), i && (Vx(this, Ux, "f").placeholder = Vx(this, Dx, "f").get("Paste track data here...")), Vx(this, Ux, "f").value = e, Vx(this, Ux, "f").readOnly = !i, i ? (Vx(this, zx, "f").className = "hidden", Vx(this, Ox, "f").className = "button right") : (Vx(this, zx, "f").className = "button right", Vx(this, Ox, "f").className = "hidden"), window.addEventListener("keydown", Wx(this, Fx, (e => { "Escape" == e.code && (t(), e.preventDefault()) }), "f")) } dispose() { Vx(this, Nx, "f").removeChild(Vx(this, Bx, "f")), window.removeEventListener("keydown", Vx(this, Fx, "f")) } }; var Gx = n(8353), jx = {}; jx.styleTagTransform = u(), jx.setAttributes = l(), jx.insert = s().bind(null, "head"), jx.domAPI = r(), jx.insertStyleElement = h(); t()(Gx.A, jx); Gx.A && Gx.A.locals && Gx.A.locals; var Qx = n(7479), Yx = {}; Yx.styleTagTransform = u(), Yx.setAttributes = l(), Yx.insert = s().bind(null, "head"), Yx.domAPI = r(), Yx.insertStyleElement = h(); t()(Qx.A, Yx); Qx.A && Qx.A.locals && Qx.A.locals; var Kx, qx, Xx, Zx, Jx, $x, ek, tk, nk, ik, rk, ak, sk, ok, lk, ck, hk, dk = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, uk = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class pk { constructor(e, t, n = !1) { Kx.set(this, void 0), qx.set(this, void 0), Xx.set(this, void 0), Zx.set(this, void 0), Jx.set(this, null), $x.set(this, void 0), ek.set(this, null), tk.set(this, null), nk.set(this, void 0), ik.set(this, null), rk.set(this, []), ak.set(this, void 0), sk.set(this, void 0), ok.set(this, void 0), lk.set(this, null), ck.set(this, null), hk.set(this, null), this.record = null, dk(this, Kx, e, "f"), dk(this, qx, t, "f"); const i = document.getElementById("ui"); if (null == i) throw new Error("UI element not found"); if (dk(this, Xx, i, "f"), dk(this, Zx, document.createElement("div"), "f"), "off" == t.getSetting($o.Timer) ? uk(this, Zx, "f").className = "timer hidden" : "top" == t.getSetting($o.Timer) ? uk(this, Zx, "f").className = "timer up" : uk(this, Zx, "f").className = "timer", n) dk(this, ak, null, "f"); else { const t = document.createElement("div"); t.className = "left", uk(this, Zx, "f").appendChild(t); const n = document.createElement("div"); n.className = "title-container", t.appendChild(n), dk(this, Jx, document.createElement("h2"), "f"), uk(this, Jx, "f").className = "title", uk(this, Jx, "f").textContent = e.get("Record"), n.appendChild(uk(this, Jx, "f")), dk(this, tk, document.createElement("h2"), "f"), uk(this, tk, "f").className = "checkpoint-time", n.appendChild(uk(this, tk, "f")); const i = document.createElement("div"); i.className = "time", t.appendChild(i), dk(this, ak, document.createElement("p"), "f"), uk(this, ak, "f").className = "small", uk(this, ak, "f").textContent = "- - -", i.appendChild(uk(this, ak, "f")) } const r = document.createElement("div"); r.className = "center", uk(this, Zx, "f").appendChild(r); const a = document.createElement("div"); a.className = "title-container", r.appendChild(a), dk(this, $x, document.createElement("h2"), "f"), uk(this, $x, "f").className = "title", uk(this, $x, "f").textContent = e.get("Current"), a.appendChild(uk(this, $x, "f")), dk(this, nk, document.createElement("h2"), "f"), uk(this, nk, "f").className = "checkpoint-time", a.appendChild(uk(this, nk, "f")); const s = document.createElement("div"); if (s.className = "time", r.appendChild(s), dk(this, sk, document.createElement("p"), "f"), uk(this, sk, "f").textContent = "- - -", s.appendChild(uk(this, sk, "f")), n) dk(this, ok, null, "f"); else { const t = document.createElement("div"); t.className = "right", uk(this, Zx, "f").appendChild(t); const n = document.createElement("div"); n.className = "title-container", t.appendChild(n), dk(this, ek, document.createElement("h2"), "f"), uk(this, ek, "f").className = "title", uk(this, ek, "f").textContent = e.get("Difference"), n.appendChild(uk(this, ek, "f")), dk(this, ik, document.createElement("h2"), "f"), uk(this, ik, "f").className = "checkpoint-time", n.appendChild(uk(this, ik, "f")); const i = document.createElement("div"); i.className = "time", t.appendChild(i), dk(this, ok, document.createElement("p"), "f"), uk(this, ok, "f").className = "small", uk(this, ok, "f").textContent = "- - -", i.appendChild(uk(this, ok, "f")) } uk(this, Xx, "f").appendChild(uk(this, Zx, "f")) } dispose() { uk(this, Xx, "f").removeChild(uk(this, Zx, "f")) } setOverridePosition(e) { const t = uk(this, qx, "f").getSetting($o.Timer); uk(this, Zx, "f").className = "off" == t ? "timer hidden" : (null != e ? e : "top" == t) ? "timer up" : "timer" } hideCheckpointTime() { for (const e of uk(this, rk, "f")) e.cancel(); uk(this, rk, "f").length = 0 } showCheckpointTime(e, t) { if (this.hideCheckpointTime(), null != uk(this, tk, "f") && null != t && (uk(this, tk, "f").textContent = pk.formatTimeString(t, !1), uk(this, rk, "f").push(uk(this, tk, "f").animate([{ opacity: 0, transform: "translateX(20px)", offset: 0, easing: "ease-in-out" }, { opacity: 1, transform: "translateX(0)", offset: 1 / 28, easing: "ease-in-out" }, { opacity: 1, transform: "translateX(0)", offset: 27 / 28, easing: "ease-in-out" }, { opacity: 0, transform: "translateX(-10px)", offset: 1, easing: "ease-in-out" }], { duration: 3500 }))), uk(this, nk, "f").textContent = pk.formatTimeString(e, !1), uk(this, rk, "f").push(uk(this, nk, "f").animate([{ opacity: 0, transform: "translateX(20px)", offset: 0, easing: "ease-in-out" }, { opacity: 1, transform: "translateX(0)", offset: 1 / 28, easing: "ease-in-out" }, { opacity: 1, transform: "translateX(0)", offset: 27 / 28, easing: "ease-in-out" }, { opacity: 0, transform: "translateX(-10px)", offset: 1, easing: "ease-in-out" }], { duration: 3500 })), null != uk(this, ik, "f") && null != t) { const n = e.difference(t); uk(this, ik, "f").textContent = pk.formatTimeString(n, !0), n.isNegative() ? (uk(this, ik, "f").classList.remove("red"), uk(this, ik, "f").classList.add("green")) : (uk(this, ik, "f").classList.add("red"), uk(this, ik, "f").classList.remove("green")), uk(this, rk, "f").push(uk(this, ik, "f").animate([{ opacity: 0, transform: "translateX(20px)", offset: 0, easing: "ease-in-out" }, { opacity: 1, transform: "translateX(0)", offset: 1 / 28, easing: "ease-in-out" }, { opacity: 1, transform: "translateX(0)", offset: 27 / 28, easing: "ease-in-out" }, { opacity: 0, transform: "translateX(-10px)", offset: 1, easing: "ease-in-out" }], { duration: 3500 })) } null != uk(this, Jx, "f") && null != t && uk(this, rk, "f").push(uk(this, Jx, "f").animate([{ opacity: 1, offset: 0, easing: "ease-in-out" }, { opacity: 0, offset: 1 / 28, easing: "ease-in-out" }, { opacity: 0, offset: 27 / 28, easing: "ease-in-out" }, { opacity: 1, offset: 1, easing: "ease-in-out" }], { duration: 3500 })), uk(this, rk, "f").push(uk(this, $x, "f").animate([{ opacity: 1, offset: 0, easing: "ease-in-out" }, { opacity: 0, offset: 1 / 28, easing: "ease-in-out" }, { opacity: 0, offset: 27 / 28, easing: "ease-in-out" }, { opacity: 1, offset: 1, easing: "ease-in-out" }], { duration: 3500 })), null != uk(this, ek, "f") && null != t && uk(this, rk, "f").push(uk(this, ek, "f").animate([{ opacity: 1, offset: 0, easing: "ease-in-out" }, { opacity: 0, offset: 1 / 28, easing: "ease-in-out" }, { opacity: 0, offset: 27 / 28, easing: "ease-in-out" }, { opacity: 1, offset: 1, easing: "ease-in-out" }], { duration: 3500 })) } static formatTimeString(e, t = !1) { if (null == e) return "---"; { const n = Math.abs(e.numberOfFrames), i = Math.floor(n / 6e4), r = Math.floor((n - 6e4 * i) / 1e3), a = n - 6e4 * i - 1e3 * r; let s; return s = t ? e.isNegative() ? "-" : "+" : "", s + i.toString().padStart(2, "0") + ":" + r.toString().padStart(2, "0") + "." + a.toString().padStart(3, "0") } } update(e) { var t; const n = null !== (t = e.getFinishTime()) && void 0 !== t ? t : e.getTime(); let i; if (i = null != this.record ? n.difference(this.record) : null, null != uk(this, ak, "f")) { const e = pk.formatTimeString(this.record, !1); if (e != uk(this, lk, "f")) { uk(this, ak, "f").innerHTML = ""; for (const t of e) { const e = document.createElement("span"); e.textContent = t, uk(this, ak, "f").appendChild(e) } dk(this, lk, e, "f") } null == this.record ? "small center" != uk(this, ak, "f").className && (uk(this, ak, "f").className = "small center") : "small" != uk(this, ak, "f").className && (uk(this, ak, "f").className = "small") } const r = pk.formatTimeString(n, !1); if (r != uk(this, ck, "f")) { uk(this, sk, "f").innerHTML = ""; for (const e of r) { const t = document.createElement("span"); t.textContent = e, uk(this, sk, "f").appendChild(t) } dk(this, ck, r, "f") } if (null != uk(this, ok, "f")) { const e = pk.formatTimeString(i, !0); if (e != uk(this, hk, "f")) { uk(this, ok, "f").innerHTML = ""; for (let t = 0; t < e.length; ++t) { const n = document.createElement("span"); 0 == t && Number.isFinite(i) && (n.className = "sign"), n.textContent = e[t], uk(this, ok, "f").appendChild(n) } dk(this, hk, e, "f") } null == i ? "small center" != uk(this, ok, "f").className && (uk(this, ok, "f").className = "small center") : i.isNegative() ? "small green" != uk(this, ok, "f").className && (uk(this, ok, "f").className = "small green") : "small red" != uk(this, ok, "f").className && (uk(this, ok, "f").className = "small red") } } set nickname(e) { null != uk(this, Jx, "f") ? uk(this, Jx, "f").textContent = null != e ? '"' + e + '"' : uk(this, Kx, "f").get("Record") : uk(this, $x, "f").textContent = null != e ? '"' + e + '"' : uk(this, Kx, "f").get("Current") } } Kx = new WeakMap, qx = new WeakMap, Xx = new WeakMap, Zx = new WeakMap, Jx = new WeakMap, $x = new WeakMap, ek = new WeakMap, tk = new WeakMap, nk = new WeakMap, ik = new WeakMap, rk = new WeakMap, ak = new WeakMap, sk = new WeakMap, ok = new WeakMap, lk = new WeakMap, ck = new WeakMap, hk = new WeakMap; const fk = pk; var mk, gk, vk, wk, yk, Ak, bk, xk, kk, Ek, Sk, Mk, Tk, _k, Ck, Pk, Ik, Rk, Lk, Dk, Nk, Bk, Uk, zk, Ok, Fk, Wk, Vk, Hk, Gk, jk, Qk, Yk = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, Kk = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; let qk = null, Xk = 0, Zk = 0, Jk = 0; gk = new WeakMap, vk = new WeakMap, wk = new WeakMap, yk = new WeakMap, Ak = new WeakMap, bk = new WeakMap, xk = new WeakMap, kk = new WeakMap, Ek = new WeakMap, Sk = new WeakMap, Mk = new WeakMap, Tk = new WeakMap, _k = new WeakMap, Ck = new WeakMap, Pk = new WeakMap, Ik = new WeakMap, Rk = new WeakMap, Lk = new WeakMap, Dk = new WeakMap, Nk = new WeakMap, Bk = new WeakMap, Uk = new WeakMap, zk = new WeakMap, Ok = new WeakMap, Fk = new WeakMap, Wk = new WeakMap, Vk = new WeakMap, Hk = new WeakMap, mk = new WeakSet, Gk = function(e, t, n, i, r, a = null) { const s = document.createElement("div"); let o; switch (s.className = "track", e) { case "official": o = Kk(this, Lk, "f"); break; case "community": o = Kk(this, Dk, "f"); break; case "custom": o = Kk(this, Nk, "f") } let l = o.get(n.environment); if (null == l) { let t, i, r, a; switch (e) { case "official": t = Kk(this, Pk, "f"); break; case "community": t = Kk(this, Ik, "f"); break; case "custom": t = Kk(this, Rk, "f") } switch (l = document.createElement("div"), o.set(n.environment, l), n.environment) { case QA.Summer: t.prepend(l); break; case QA.Winter: { const e = o.get(QA.Desert); null != e ? t.insertBefore(l, e) : t.appendChild(l); break } case QA.Desert: t.appendChild(l) } switch (n.environment) { case QA.Summer: i = "summer", r = Kk(this, vk, "f").get("Summer"), a = "images/summer.svg"; break; case QA.Winter: i = "winter", r = Kk(this, vk, "f").get("Winter"), a = "images/winter_colored.svg"; break; case QA.Desert: i = "desert", r = Kk(this, vk, "f").get("Desert"), a = "images/desert_colored.svg" } const s = document.createElement("div"); s.className = "environment-title " + i, s.textContent = r, l.appendChild(s); const c = document.createElement("img"); c.src = a, s.prepend(c) } l.appendChild(s); const c = document.createElement("button"); c.className = "button", c.addEventListener("click", (() => { Kk(this, wk, "f").playUIClick(), Kk(this, Sk, "f").call(this, t, n, e, i, r) })), s.appendChild(c); const h = document.createElement("div"); h.className = "track-title", c.appendChild(h); const d = document.createElement("p"); let u; switch (d.textContent = t.name, h.appendChild(d), c.appendChild(r), n.environment) { case QA.Summer: u = "images/summer.svg"; break; case QA.Winter: u = "images/winter.svg"; break; case QA.Desert: u = "images/desert.svg" } const p = document.createElement("img"); p.className = "environment", p.src = u, c.appendChild(p); const f = Kk(this, yk, "f").getRecordTime(Kk(this, bk, "f").profileSlot, i), m = document.createElement("div"); if (m.className = "record", m.textContent = null != f ? fk.formatTimeString(f) : Kk(this, vk, "f").get("No record"), c.appendChild(m), null != a) { const e = document.createElement("button"); e.className = "delete-button", e.innerHTML = '', e.addEventListener("click", (() => { Kk(this, wk, "f").playUIClick(), a() })), s.appendChild(e) } Kk(this, Bk, "f").push({ category: e, trackData: n, trackMetadata: t, buttonContainer: s }) }, jk = function(e) { qk = e, Kk(this, kk, "f").saveTrackSelectionTab(qk), "official" == e ? (Kk(this, Tk, "f").classList.add("selected"), Kk(this, _k, "f").classList.remove("selected"), Kk(this, Ck, "f").classList.remove("selected"), Kk(this, Pk, "f").classList.add("open"), Kk(this, Ik, "f").classList.remove("open"), Kk(this, Rk, "f").classList.remove("open")) : "community" == e ? (Kk(this, Tk, "f").classList.remove("selected"), Kk(this, _k, "f").classList.add("selected"), Kk(this, Ck, "f").classList.remove("selected"), Kk(this, Pk, "f").classList.remove("open"), Kk(this, Ik, "f").classList.add("open"), Kk(this, Rk, "f").classList.remove("open")) : (Kk(this, Tk, "f").classList.remove("selected"), Kk(this, _k, "f").classList.remove("selected"), Kk(this, Ck, "f").classList.add("selected"), Kk(this, Pk, "f").classList.remove("open"), Kk(this, Ik, "f").classList.remove("open"), Kk(this, Rk, "f").classList.add("open")) }, Qk = function() { const e = Kk(this, Uk, "f").value.trim().toLowerCase(); for (const t of Kk(this, Bk, "f")) t.trackMetadata.name.toLowerCase().includes(e) ? t.buttonContainer.style.display = "" : t.buttonContainer.style.display = "none"; for (const e of ["official", "community", "custom"]) { let t; switch (e) { case "official": t = Kk(this, Lk, "f"); break; case "community": t = Kk(this, Dk, "f"); break; case "custom": t = Kk(this, Nk, "f") } for (const [n, i] of t.entries()) Kk(this, Bk, "f").some((t => t.category == e && t.trackData.environment == n && "none" != t.buttonContainer.style.display)) ? i.style.display = "" : i.style.display = "none" } if (null == qk && (qk = Kk(this, kk, "f").loadTrackSelectionTab()), Kk(this, Bk, "f").filter((e => e.category == qk)).every((e => "none" == e.buttonContainer.style.display))) for (const e of ["official", "community", "custom"]) if (Kk(this, Bk, "f").some((t => t.category == e && "none" != t.buttonContainer.style.display))) { Kk(this, mk, "m", jk).call(this, e); break } }; const $k = class { constructor(e, t, n, i, r, a, s, o, l, c, h) { mk.add(this), gk.set(this, void 0), vk.set(this, void 0), wk.set(this, void 0), yk.set(this, void 0), Ak.set(this, void 0), bk.set(this, void 0), xk.set(this, void 0), kk.set(this, void 0), Ek.set(this, void 0), Sk.set(this, void 0), Mk.set(this, void 0), Tk.set(this, void 0), _k.set(this, void 0), Ck.set(this, void 0), Pk.set(this, void 0), Ik.set(this, void 0), Rk.set(this, void 0), Lk.set(this, new Map), Dk.set(this, new Map), Nk.set(this, new Map), Bk.set(this, []), Uk.set(this, void 0), zk.set(this, null), Ok.set(this, !1), Fk.set(this, !1), Wk.set(this, void 0), Vk.set(this, void 0), Hk.set(this, void 0), Yk(this, gk, e, "f"), Yk(this, vk, t, "f"), Yk(this, wk, n, "f"), Yk(this, yk, i, "f"), Yk(this, Ak, r, "f"), Yk(this, bk, a, "f"), Yk(this, xk, s, "f"), Yk(this, kk, o, "f"), Yk(this, Ek, l, "f"), Yk(this, Sk, h, "f"), Yk(this, Mk, document.createElement("div"), "f"), Kk(this, Mk, "f").className = "hidden", e.appendChild(Kk(this, Mk, "f")); const d = document.createElement("div"); d.className = "bar", Kk(this, Mk, "f").appendChild(d); const u = document.createElement("div"); u.className = "category-container", Kk(this, Mk, "f").appendChild(u), Yk(this, Tk, document.createElement("button"), "f"), Kk(this, Tk, "f").className = "button official selected", Kk(this, Tk, "f").append(document.createTextNode(Kk(this, vk, "f").get("Official tracks"))), Kk(this, Tk, "f").addEventListener("click", (() => { Kk(this, wk, "f").playUIClick(), Kk(this, mk, "m", jk).call(this, "official") })), u.appendChild(Kk(this, Tk, "f")); const p = document.createElement("div"); p.className = "cover", Kk(this, Tk, "f").prepend(p), Yk(this, _k, document.createElement("button"), "f"), Kk(this, _k, "f").className = "button community", Kk(this, _k, "f").append(document.createTextNode(Kk(this, vk, "f").get("Community tracks"))), Kk(this, _k, "f").addEventListener("click", (() => { Kk(this, wk, "f").playUIClick(), Kk(this, mk, "m", jk).call(this, "community") })), u.appendChild(Kk(this, _k, "f")); const f = document.createElement("div"); f.className = "cover", Kk(this, _k, "f").prepend(f), Yk(this, Ck, document.createElement("button"), "f"), Kk(this, Ck, "f").className = "button custom", Kk(this, Ck, "f").append(document.createTextNode(Kk(this, vk, "f").get("Custom tracks"))), Kk(this, Ck, "f").addEventListener("click", (() => { Kk(this, wk, "f").playUIClick(), Kk(this, mk, "m", jk).call(this, "custom") })), u.appendChild(Kk(this, Ck, "f")); const m = document.createElement("div"); m.className = "cover", Kk(this, Ck, "f").prepend(m), Yk(this, Pk, document.createElement("div"), "f"), Kk(this, Pk, "f").className = "tracks-container open", Kk(this, Mk, "f").appendChild(Kk(this, Pk, "f")), Yk(this, Ik, document.createElement("div"), "f"), Kk(this, Ik, "f").className = "tracks-container", Kk(this, Mk, "f").appendChild(Kk(this, Ik, "f")), Yk(this, Rk, document.createElement("div"), "f"), Kk(this, Rk, "f").className = "tracks-container", Kk(this, Mk, "f").appendChild(Kk(this, Rk, "f")); const g = document.createElement("button"); g.className = "button", l ? (g.innerHTML = ' ', g.append(document.createTextNode(Kk(this, vk, "f").get("Cancel")))) : (g.innerHTML = ' ', g.append(document.createTextNode(Kk(this, vk, "f").get("Back")))), g.addEventListener("click", (() => { Kk(this, wk, "f").playUIClick(), c() })), d.appendChild(g); const v = document.createElement("div"); v.className = "search-bar-container", d.appendChild(v), Yk(this, Uk, document.createElement("input"), "f"), Kk(this, Uk, "f").type = "text", Kk(this, Uk, "f").spellcheck = !1, Kk(this, Uk, "f").autocomplete = "off", Kk(this, Uk, "f").autocapitalize = "off", Kk(this, Uk, "f").enterKeyHint = "search", Kk(this, Uk, "f").placeholder = Kk(this, vk, "f").get("Search tracks..."), Kk(this, Uk, "f").addEventListener("input", (() => { Kk(this, mk, "m", Qk).call(this) })), v.appendChild(Kk(this, Uk, "f")); const w = document.createElement("img"); w.src = "images/search.svg", v.appendChild(w); const y = document.createElement("button"); y.className = "button", y.innerHTML = ' ', y.append(document.createTextNode(Kk(this, vk, "f").get("Import"))), y.addEventListener("click", (() => { Kk(this, wk, "f").playUIClick(), this.hide(), Yk(this, zk, new Hx("", (() => { var e; this.show(), null === (e = Kk(this, zk, "f")) || void 0 === e || e.dispose(), Yk(this, zk, null, "f") }), ((e, t, n, i) => { var r; null === (r = Kk(this, zk, "f")) || void 0 === r || r.dispose(), Yk(this, zk, null, "f"), Kk(this, mk, "m", jk).call(this, "custom"), Kk(this, Sk, "f").call(this, e, t, "custom", n, i) }), !0, t, n, r, s), "f") })), d.appendChild(y), window.addEventListener("keydown", Yk(this, Wk, (e => { Kk(this, Ok, "f") && "Escape" == e.code && (c(), e.preventDefault()) }), "f")), Kk(this, Ak, "f").addCustomTracksChangedListener(Yk(this, Vk, (() => { Kk(this, Fk, "f") && this.refresh() }), "f")), Kk(this, Pk, "f").addEventListener("scroll", (() => { Xk = Kk(this, Pk, "f").scrollTop }), { passive: !0 }), Kk(this, Ik, "f").addEventListener("scroll", (() => { Zk = Kk(this, Ik, "f").scrollTop }), { passive: !0 }), Kk(this, Rk, "f").addEventListener("scroll", (() => { Jk = Kk(this, Rk, "f").scrollTop }), { passive: !0 }), Kk(this, yk, "f").addRecordChangedCallback(Yk(this, Hk, (() => { this.refresh() }), "f")) } dispose() { var e; Kk(this, gk, "f").removeChild(Kk(this, Mk, "f")), window.removeEventListener("keydown", Kk(this, Wk, "f")), null === (e = Kk(this, zk, "f")) || void 0 === e || e.dispose(), Yk(this, zk, null, "f"), Kk(this, Ak, "f").removeCustomTracksChangedListener(Kk(this, Vk, "f")), Kk(this, yk, "f").removeRecordChangedCallback(Kk(this, Hk, "f")) } hide() { Kk(this, Mk, "f").className = "hidden", Yk(this, Ok, !1, "f") } show() { Kk(this, Ek, "f") ? Kk(this, Mk, "f").className = "track-selection editor-track-selection" : Kk(this, Mk, "f").className = "track-selection", Yk(this, Ok, !0, "f"), Kk(this, Fk, "f") || this.refresh(), null == qk && (qk = Kk(this, kk, "f").loadTrackSelectionTab()), "official" == qk ? (Kk(this, Tk, "f").classList.add("selected"), Kk(this, _k, "f").classList.remove("selected"), Kk(this, Ck, "f").classList.remove("selected"), Kk(this, Pk, "f").classList.add("open"), Kk(this, Ik, "f").classList.remove("open"), Kk(this, Rk, "f").classList.remove("open"), Kk(this, Pk, "f").scrollTop = Xk) : "community" == qk ? (Kk(this, Tk, "f").classList.remove("selected"), Kk(this, _k, "f").classList.add("selected"), Kk(this, Ck, "f").classList.remove("selected"), Kk(this, Pk, "f").classList.remove("open"), Kk(this, Ik, "f").classList.add("open"), Kk(this, Rk, "f").classList.remove("open"), Kk(this, Ik, "f").scrollTop = Zk) : (Kk(this, Tk, "f").classList.remove("selected"), Kk(this, _k, "f").classList.remove("selected"), Kk(this, Ck, "f").classList.add("selected"), Kk(this, Pk, "f").classList.remove("open"), Kk(this, Ik, "f").classList.remove("open"), Kk(this, Rk, "f").classList.add("open"), Kk(this, Rk, "f").scrollTop = Jk) } get isOpen() { return Kk(this, Ok, "f") || null != Kk(this, zk, "f") } refresh() { if (Yk(this, Bk, [], "f"), Kk(this, Pk, "f").innerHTML = "", Kk(this, Ik, "f").innerHTML = "", Kk(this, Rk, "f").innerHTML = "", Kk(this, Lk, "f").clear(), Kk(this, Dk, "f").clear(), Kk(this, Nk, "f").clear(), Kk(this, Ak, "f").forEachOfficialTrack(((e, t, n, i) => { Kk(this, mk, "m", Gk).call(this, "official", t, n, e, i) })), Kk(this, Ak, "f").isCommunityTracksEmpty()) { const e = document.createElement("div"); e.className = "empty"; const t = document.createElement("div"); t.className = "title", t.textContent = Kk(this, vk, "f").get("No community tracks"), e.appendChild(t); const n = document.createElement("div"); n.className = "description", n.textContent = Kk(this, vk, "f").get("Community tracks are coming soon"), e.appendChild(n), Kk(this, Ik, "f").appendChild(e) } else Kk(this, Ak, "f").forEachCommunityTrack(((e, t, n, i) => { Kk(this, mk, "m", Gk).call(this, "community", t, n, e, i) })); if (Kk(this, Ak, "f").isCustomTracksEmpty()) { const e = document.createElement("div"); e.className = "empty"; const t = document.createElement("div"); t.className = "title", t.textContent = Kk(this, vk, "f").get("No custom tracks"), e.appendChild(t); const n = document.createElement("div"); n.className = "description", n.textContent = Kk(this, vk, "f").get("Create a track using the editor or import a track code"), e.appendChild(n), Kk(this, Rk, "f").appendChild(e) } else Kk(this, Ak, "f").forEachCustomTrack(((e, t, n, i) => { Kk(this, mk, "m", Gk).call(this, "custom", t, n, e, i, (() => { this.hide(), Kk(this, xk, "f").showConfirm(Kk(this, vk, "f").get('Are you sure you want to delete "{0}"?', [t.name]), Kk(this, vk, "f").get("Cancel"), Kk(this, vk, "f").get("Delete"), (() => { this.show() }), (() => { Kk(this, Ak, "f").deleteCustomTrack(t.name), this.show() })) })) })); Kk(this, mk, "m", Qk).call(this), Yk(this, Fk, !0, "f") } }; var eE = n(2346), tE = {}; tE.styleTagTransform = u(), tE.setAttributes = l(), tE.insert = s().bind(null, "head"), tE.domAPI = r(), tE.insertStyleElement = h(); t()(eE.A, tE); eE.A && eE.A.locals && eE.A.locals; var nE, iE, rE, aE, sE, oE, lE, cE, hE = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, dE = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; nE = new WeakMap, iE = new WeakMap, rE = new WeakMap, aE = new WeakMap, sE = new WeakMap, oE = new WeakMap, lE = new WeakMap, cE = new WeakMap; const uE = class { constructor(e, t, n, i, r, a, s) { nE.set(this, void 0), iE.set(this, void 0), rE.set(this, void 0), aE.set(this, void 0), sE.set(this, void 0), oE.set(this, void 0), lE.set(this, []), cE.set(this, void 0), hE(this, nE, e, "f"), hE(this, iE, n, "f"), hE(this, rE, document.createElement("div"), "f"), dE(this, rE, "f").className = "editor-side-toolbar", dE(this, nE, "f").appendChild(dE(this, rE, "f")); let o = !1; const l = document.createElement("button"), c = document.createElement("img"); c.src = "images/overlapping_disabled.svg", l.appendChild(c), l.addEventListener("click", (() => { t.playUIClick(), o = !o, c.src = o ? "images/overlapping_enabled.svg" : "images/overlapping_disabled.svg", i(o) })), dE(this, rE, "f").appendChild(l); let h = !0; const d = document.createElement("button"), u = document.createElement("img"); u.src = "images/grid_large.svg", d.appendChild(u), d.addEventListener("click", (() => { t.playUIClick(), h = !h, u.src = h ? "images/grid_large.svg" : "images/grid_small.svg", r(h) })), dE(this, rE, "f").appendChild(d); const p = document.createElement("div"); p.className = "accordion", dE(this, rE, "f").appendChild(p), hE(this, oE, document.createElement("button"), "f"), dE(this, oE, "f").innerHTML = '', dE(this, oE, "f").addEventListener("click", (() => { t.playUIClick(), p.classList.toggle("open"); for (const e of p.children) e != dE(this, oE, "f") && e instanceof HTMLButtonElement && (p.classList.contains("open") ? (e.inert = !1, e.tabIndex = 0) : (e.inert = !0, e.tabIndex = -1)) })), p.appendChild(dE(this, oE, "f")); for (const e of [nA.YPositive, nA.YNegative, nA.XPositive, nA.XNegative, nA.ZPositive, nA.ZNegative]) { const n = document.createElement("button"); switch (n.inert = !0, n.tabIndex = -1, e) { case nA.YPositive: n.innerHTML = ''; break; case nA.YNegative: n.innerHTML = ''; break; case nA.XPositive: n.innerHTML = ''; break; case nA.XNegative: n.innerHTML = ''; break; case nA.ZPositive: n.innerHTML = ''; break; case nA.ZNegative: n.innerHTML = '' } n.addEventListener("click", (() => { t.playUIClick(), a(e) })), e == nA.YPositive && n.classList.add("selected"), p.appendChild(n), dE(this, lE, "f").push([e, n]) } const f = document.createElement("button"); f.className = "rotate", f.addEventListener("click", (() => { t.playUIClick(), s() })), dE(this, rE, "f").appendChild(f), hE(this, aE, document.createElement("div"), "f"), dE(this, aE, "f").innerHTML = '', f.appendChild(dE(this, aE, "f")), hE(this, sE, document.createElement("span"), "f"), dE(this, sE, "f").textContent = "0°", f.appendChild(dE(this, sE, "f")), n.addChangeListener(hE(this, cE, (e => { e ? dE(this, rE, "f").classList.add("touch") : dE(this, rE, "f").classList.remove("touch") }), "f")) } dispose() { dE(this, nE, "f").removeChild(dE(this, rE, "f")), dE(this, iE, "f").removeChangeListener(dE(this, cE, "f")) } set rotation(e) { dE(this, aE, "f").style.transform = `rotate(${(90*-e).toString()}deg)`, dE(this, sE, "f").textContent = (90 * e).toString() + "°" } set rotationAxis(e) { let t; switch (e) { case nA.YPositive: t = "images/rotation_axis_y_positive.svg"; break; case nA.YNegative: t = "images/rotation_axis_y_negative.svg"; break; case nA.XPositive: t = "images/rotation_axis_x_positive.svg"; break; case nA.XNegative: t = "images/rotation_axis_x_negative.svg"; break; case nA.ZPositive: t = "images/rotation_axis_z_positive.svg"; break; case nA.ZNegative: t = "images/rotation_axis_z_negative.svg" } dE(this, oE, "f").innerHTML = ""; const n = document.createElement("img"); n.src = t, dE(this, oE, "f").appendChild(n); for (const [t, n] of dE(this, lE, "f")) t == e ? n.classList.add("selected") : n.classList.remove("selected") } hide() { dE(this, rE, "f").classList.add("hidden") } show() { dE(this, rE, "f").classList.remove("hidden") } }; var pE = n(9242), fE = {}; fE.styleTagTransform = u(), fE.setAttributes = l(), fE.insert = s().bind(null, "head"), fE.domAPI = r(), fE.insertStyleElement = h(); t()(pE.A, fE); pE.A && pE.A.locals && pE.A.locals; var mE, gE, vE, wE = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, yE = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; mE = new WeakMap, gE = new WeakMap, vE = new WeakMap; const AE = class { constructor(e, t, n, i, r, a, s, o) { mE.set(this, void 0), gE.set(this, void 0), vE.set(this, void 0); const l = document.getElementById("ui"); if (null == l) throw new Error("UI element not found"); wE(this, mE, l, "f"), wE(this, gE, document.createElement("div"), "f"), yE(this, gE, "f").className = "editor-help", yE(this, mE, "f").appendChild(yE(this, gE, "f")); const c = document.createElement("div"); c.className = "background", yE(this, gE, "f").appendChild(c); const h = document.createElement("section"); h.className = "container", yE(this, gE, "f").appendChild(h); const d = document.createElement("h1"); d.textContent = t.get("How to use the editor"), h.appendChild(d); const u = document.createElement("section"); u.className = "content", h.appendChild(u); const p = document.createElement("h2"); function f(e) { const i = n.getKeyBindings(e).filter((e => null != e)); return 0 == i.length ? t.get("Not set") : i.map((e => "[" + e + "]")).join(" " + t.get("or") + " ") } p.textContent = t.get("Camera controls"), u.appendChild(p); let m = ""; i.touchEnabled ? (m += t.get("The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.") + "\n\n", m += t.get("The edited height can be changed by using the height selection in the bottom left corner.")) : (m += t.get("The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.") + "\n\n", m += t.get("Alternatively, the camera can also be controlled using the following keyboard keys:") + "\n\n", m += "\t" + t.get("Move forwards:") + " " + f(Ix.EditorMoveForwards) + "\n", m += "\t" + t.get("Move backwards:") + " " + f(Ix.EditorMoveBackwards) + "\n", m += "\t" + t.get("Move left:") + " " + f(Ix.EditorMoveLeft) + "\n", m += "\t" + t.get("Move right:") + " " + f(Ix.EditorMoveRight) + "\n", m += "\t" + t.get("Rotate left:") + " " + f(Ix.EditorRotateViewLeft) + "\n", m += "\t" + t.get("Rotate right:") + " " + f(Ix.EditorRotateViewRight) + "\n\n", m += t.get("The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:") + "\n\n", m += "\t" + t.get("Move up:") + " " + f(Ix.EditorMoveUp) + "\n", m += "\t" + t.get("Move down:") + " " + f(Ix.EditorMoveDown)); const g = document.createElement("p"); g.textContent = m, u.appendChild(g); const v = document.createElement("h2"); v.textContent = t.get("Editing"), u.appendChild(v); let w = ""; i.touchEnabled ? (w += t.get("Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.") + "\n\n", w += t.get("The selected part can then be rotated by tapping the rotate button in the bottom left corner.") + "\n\n", w += t.get("Track parts can be deleted by using the delete tool in the right side menu.")) : (w += t.get("Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.") + "\n\n", w += t.get("Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:") + " " + f(Ix.EditorPick) + "\n\n", w += t.get("The selected part can then be rotated using the following keyboard shortcut:") + " " + f(Ix.EditorRotatePart) + "\n\n", w += t.get("Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:") + " " + f(Ix.EditorDelete)); const y = document.createElement("p"); y.textContent = w, u.appendChild(y); const A = document.createElement("h2"); A.textContent = t.get("Starting points, checkpoints and the finish line"), u.appendChild(A); let b = t.get("Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.") + "\n\n"; b += t.get("Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.") + "\n\n", b += t.get("Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.") + "\n\n", b += t.get("The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines."); const x = document.createElement("p"); x.textContent = b, u.appendChild(x); const k = document.createElement("div"); k.className = "part-images", u.appendChild(k); const E = document.createElement("div"); k.appendChild(E); const S = document.createElement("img"); S.className = "loading", r.then((e => { S.className = "", S.src = e })).catch((e => { console.error(e) })), E.appendChild(S); const M = document.createElement("span"); M.textContent = t.get("Starting point"), E.appendChild(M); const T = document.createElement("div"); k.appendChild(T); const _ = document.createElement("img"); _.className = "loading", a.then((e => { _.className = "", _.src = e })).catch((e => { console.error(e) })), T.appendChild(_); const C = document.createElement("span"); C.textContent = t.get("Checkpoint"), T.appendChild(C); const P = document.createElement("div"); k.appendChild(P); const I = document.createElement("img"); I.className = "loading", s.then((e => { I.className = "", I.src = e })).catch((e => { console.error(e) })), P.appendChild(I); const R = document.createElement("span"); R.textContent = t.get("Finish line"), P.appendChild(R); const L = document.createElement("h2"); L.textContent = t.get("Exporting the track"), u.appendChild(L); const D = t.get("When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.") + "\n\n", N = document.createElement("p"); N.textContent = D, u.appendChild(N); const B = document.createElement("div"); B.className = "button-wrapper", h.appendChild(B); const U = document.createElement("button"); U.className = "button", U.innerHTML = ' ', U.append(document.createTextNode(t.get("Close"))), U.addEventListener("click", (() => { e.playUIClick(), o() })), B.appendChild(U), window.addEventListener("keydown", wE(this, vE, (e => { "Escape" == e.code && (o(), e.preventDefault()) }), "f")) } dispose() { yE(this, mE, "f").removeChild(yE(this, gE, "f")), window.removeEventListener("keydown", yE(this, vE, "f")) } }; var bE = n(1997), xE = {}; xE.styleTagTransform = u(), xE.setAttributes = l(), xE.insert = s().bind(null, "head"), xE.domAPI = r(), xE.insertStyleElement = h(); t()(bE.A, xE); bE.A && bE.A.locals && bE.A.locals; var kE, EE, SE, ME, TE = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, _E = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; kE = new WeakMap, EE = new WeakMap, SE = new WeakMap, ME = new WeakMap; const CE = class { constructor(e, t, n, i, r, a, s, o, l) { kE.set(this, void 0), EE.set(this, void 0), SE.set(this, null), ME.set(this, void 0); const c = document.getElementById("ui"); if (null == c) throw new Error("UI element not found"); TE(this, kE, c, "f"), TE(this, EE, document.createElement("div"), "f"), _E(this, EE, "f").className = "editor-track-settings", _E(this, kE, "f").appendChild(_E(this, EE, "f")); const h = document.createElement("div"); h.className = "background", _E(this, EE, "f").appendChild(h); const d = document.createElement("section"); d.className = "container", _E(this, EE, "f").appendChild(d); const u = document.createElement("h1"); u.textContent = t.get("Track settings"), d.appendChild(u); const p = document.createElement("section"); p.className = "content", d.appendChild(p); const f = document.createElement("div"); f.className = "setting", p.appendChild(f); const m = document.createElement("label"); m.className = "title", m.append(document.createTextNode(t.get("Track name"))), f.appendChild(m); const g = document.createElement("input"); g.type = "text", g.maxLength = 64, g.spellcheck = !1, g.value = null != n ? n : "", g.addEventListener("input", (() => { 0 == g.value.trim().length ? (null != _E(this, SE, "f") && (_E(this, SE, "f").disabled = !0), f.classList.add("error")) : (null != _E(this, SE, "f") && (_E(this, SE, "f").disabled = !1), f.classList.remove("error")) })), f.appendChild(g), null != n && 0 != n.length || (f.classList.add("error"), g.focus()); const v = document.createElement("div"); v.className = "setting", p.appendChild(v); const w = document.createElement("label"); w.className = "title", w.append(document.createTextNode(t.get("Author"))), v.appendChild(w); const y = document.createElement("input"); y.type = "text", y.maxLength = 64, y.spellcheck = !1, y.value = null != i ? i : "", y.placeholder = t.get("Unknown"), y.addEventListener("input", (() => { const e = y.value.trim(); 0 == e.length ? r.trackAuthor = null : r.trackAuthor = e })), v.appendChild(y); const A = document.createElement("div"); A.className = "setting", p.appendChild(A); const b = document.createElement("div"); b.className = "title", b.append(document.createTextNode(t.get("Environment"))), A.appendChild(b); const x = document.createElement("button"); x.className = "button environment-button", a.environment == QA.Summer && (x.classList.add("selected"), x.disabled = !0), x.innerHTML = ' ', x.append(document.createTextNode(t.get("Summer"))), x.addEventListener("click", (() => { e.playUIClick(), s(QA.Summer), x.classList.add("selected"), k.classList.remove("selected"), E.classList.remove("selected"), x.disabled = !0, k.disabled = !1, E.disabled = !1 })), A.appendChild(x); const k = document.createElement("button"); k.className = "button environment-button", a.environment == QA.Winter && (k.classList.add("selected"), k.disabled = !0), k.innerHTML = ' ', k.append(document.createTextNode(t.get("Winter"))), k.addEventListener("click", (() => { e.playUIClick(), s(QA.Winter), x.classList.remove("selected"), k.classList.add("selected"), E.classList.remove("selected"), x.disabled = !1, k.disabled = !0, E.disabled = !1 })), A.appendChild(k); const E = document.createElement("button"); E.className = "button environment-button", a.environment == QA.Desert && (E.classList.add("selected"), E.disabled = !0), E.innerHTML = ' ', E.append(document.createTextNode(t.get("Desert"))), E.addEventListener("click", (() => { e.playUIClick(), s(QA.Desert), x.classList.remove("selected"), k.classList.remove("selected"), E.classList.add("selected"), x.disabled = !1, k.disabled = !1, E.disabled = !0 })), A.appendChild(E); const S = document.createElement("div"); S.className = "setting", p.appendChild(S); const M = document.createElement("label"); M.className = "title", M.append(document.createTextNode(t.get("Sun direction") + " (")), S.appendChild(M); const T = document.createTextNode(a.sunDirection.toDegrees().toString()); M.appendChild(T), M.append(document.createTextNode("°)")); let _ = null; const C = document.createElement("input"); C.type = "range", C.min = "0", C.max = "360", C.step = "2", C.value = a.sunDirection.toDegrees().toString(), C.addEventListener("input", (() => { a.sunDirection = GA.fromDegrees(parseInt(C.value, 10)), T.textContent = C.value, null == _ && (_ = setTimeout((() => { a.generateMeshes(), _ = null }), 100)) })), S.appendChild(C); const P = document.createElement("div"); P.className = "button-wrapper", d.appendChild(P); const I = document.createElement("button"); I.className = "button", I.innerHTML = ' ', I.append(document.createTextNode(t.get("Close"))), I.addEventListener("click", (() => { e.playUIClick(); const t = g.value.trim(); 0 == t.length ? o(null) : o(t) })), P.appendChild(I), null != l && (TE(this, SE, document.createElement("button"), "f"), _E(this, SE, "f").disabled = null == n || 0 == n.length, _E(this, SE, "f").className = "button", _E(this, SE, "f").innerHTML = ' ', _E(this, SE, "f").append(document.createTextNode(t.get("Save"))), _E(this, SE, "f").addEventListener("click", (() => { e.playUIClick(); const t = g.value.trim(); 0 == t.length || l(t) })), P.appendChild(_E(this, SE, "f"))), window.addEventListener("keydown", TE(this, ME, (e => { if ("Escape" == e.code) { const t = g.value.trim(); 0 == t.length ? o(null) : o(t), e.preventDefault() } }), "f")) } dispose() { _E(this, kE, "f").removeChild(_E(this, EE, "f")), window.removeEventListener("keydown", _E(this, ME, "f")) } }; var PE = function(e, t, n, i) { return new(n || (n = Promise))((function(r, a) { function s(e) { try { l(i.next(e)) } catch (e) { a(e) } } function o(e) { try { l(i.throw(e)) } catch (e) { a(e) } } function l(e) { var t; e.done ? r(e.value) : (t = e.value, t instanceof n ? t : new n((function(e) { e(t) }))).then(s, o) } l((i = i.apply(e, t || [])).next()) })) }; let IE = null, RE = null, LE = null, DE = null; function NE(e) { return PE(this, void 0, void 0, (function*() { for (; null != DE;) yield DE; const t = function(e) { return new Promise((t => { setTimeout((() => { var n; if (null == IE || null == RE || null == LE) { const e = document.createElement("canvas"); e.width = 128, e.height = 128, IE = new Xd({ canvas: e, alpha: !0, preserveDrawingBuffer: !0, antialias: !0 }), IE.outputColorSpace = vt, LE = new Or, RE = new Io(-1, 1, 1, -1, .5, Au.maxViewDistance), RE.position.set(1e3, 1e3, 1e3), RE.lookAt(0, 0, 0), LE.add(RE); const t = new Lo(16777215, 4.7); t.position.set(8, 10, 10), LE.add(t) } e.geometry.computeBoundingSphere(); const i = null === (n = e.geometry.boundingSphere) || void 0 === n ? void 0 : n.clone(); if (null == i) throw new Error("Bounding sphere is null"); RE.zoom = 1 / i.radius * .9, RE.position.copy(i.center), RE.position.addScalar(1e3), RE.updateProjectionMatrix(), IE.clear(), LE.add(e), IE.render(LE, RE), LE.remove(e), t(IE.domElement.toDataURL()) }), 25) })) }(e); let n; DE = t; try { n = yield t } finally { DE = null } return n })) } var BE, UE, zE, OE, FE, WE, VE, HE, GE, jE, QE, YE, KE, qE, XE, ZE, JE, $E, eS, tS, nS, iS, rS, aS, sS, oS, lS, cS, hS, dS, uS, pS, fS, mS, gS, vS, wS, yS, AS, bS, xS, kS, ES, SS, MS, TS, _S, CS, PS, IS, RS, LS, DS, NS, BS, US, zS, OS, FS, WS, VS, HS, GS, jS, QS, YS, KS, qS, XS, ZS, JS, $S, eM, tM, nM, iM, rM, aM, sM, oM, lM, cM, hM, dM, uM, pM, fM, mM, gM, vM, wM, yM, AM, bM, xM, kM, EM, SM, MM, TM, _M = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, CM = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; UE = new WeakMap, zE = new WeakMap, OE = new WeakMap, FE = new WeakMap, WE = new WeakMap, VE = new WeakMap, HE = new WeakMap, GE = new WeakMap, jE = new WeakMap, QE = new WeakMap, YE = new WeakMap, KE = new WeakMap, qE = new WeakMap, XE = new WeakMap, ZE = new WeakMap, JE = new WeakMap, $E = new WeakMap, eS = new WeakMap, tS = new WeakMap, nS = new WeakMap, iS = new WeakMap, rS = new WeakMap, aS = new WeakMap, sS = new WeakMap, oS = new WeakMap, lS = new WeakMap, cS = new WeakMap, hS = new WeakMap, dS = new WeakMap, uS = new WeakMap, pS = new WeakMap, fS = new WeakMap, mS = new WeakMap, gS = new WeakMap, vS = new WeakMap, wS = new WeakMap, yS = new WeakMap, AS = new WeakMap, bS = new WeakMap, xS = new WeakMap, kS = new WeakMap, ES = new WeakMap, SS = new WeakMap, MS = new WeakMap, TS = new WeakMap, _S = new WeakMap, CS = new WeakMap, PS = new WeakMap, IS = new WeakMap, RS = new WeakMap, LS = new WeakMap, DS = new WeakMap, NS = new WeakMap, BS = new WeakMap, US = new WeakMap, zS = new WeakMap, OS = new WeakMap, FS = new WeakMap, WS = new WeakMap, VS = new WeakMap, HS = new WeakMap, GS = new WeakMap, jS = new WeakMap, QS = new WeakMap, YS = new WeakMap, KS = new WeakMap, qS = new WeakMap, XS = new WeakMap, ZS = new WeakMap, JS = new WeakMap, $S = new WeakMap, eM = new WeakMap, tM = new WeakMap, nM = new WeakMap, iM = new WeakMap, rM = new WeakMap, aM = new WeakMap, sM = new WeakMap, oM = new WeakMap, BE = new WeakSet, lM = function(e) { var t; _M(this, eM, e, "f"), CM(this, uS, "f").innerHTML = ' ', CM(this, uS, "f").append(document.createTextNode(null !== (t = CM(this, eM, "f")) && void 0 !== t ? t : CM(this, OE, "f").get("Unnamed Track"))) }, cM = function(e) { const t = () => { CM(this, WE, "f").trigger((() => { _M(this, DS, !0, "f"), CM(this, BE, "m", lM).call(this, null), e(), CM(this, $E, "f").inert = !1 })) }; CM(this, DS, "f") ? t() : (CM(this, $E, "f").inert = !0, CM(this, KE, "f").showConfirm(CM(this, OE, "f").get("Are you sure you want to exit the editor?") + "\n\n" + CM(this, OE, "f").get("All unsaved data will be lost!"), CM(this, OE, "f").get("Cancel"), CM(this, OE, "f").get("Confirm"), (() => { CM(this, $E, "f").inert = !1 }), (() => { t() }))) }, hM = function() { if (null != CM(this, VE, "f").getStartTransform()) { if (null == CM(this, ZE, "f")) throw new Error("Test callback is null"); CM(this, ZE, "f").call(this) } else CM(this, BE, "m", uM).call(this, CM(this, OE, "f").get("Starting point is missing!"), !1) }, dM = function() { if (null != CM(this, YS, "f") && null != CM(this, rM, "f")) { const e = CM(this, iM, "f")[CM(this, rM, "f")], t = CM(this, BE, "m", EM).call(this, CM(this, YS, "f"), e.tiles); if (t.length > 0) { let e; e = CM(this, ZS, "f") ? new yn(CM(this, YS, "f").x + 2, CM(this, YS, "f").y, CM(this, YS, "f").z + 2) : new yn(CM(this, YS, "f").x, CM(this, YS, "f").y, Math.floor(CM(this, YS, "f").z)); let n = t[0], i = e.distanceToSquared(new yn(n.x, n.y, n.z)); for (let r = 1; r < t.length; r++) { const a = t[r], s = e.distanceToSquared(new yn(a.x, a.y, a.z)); s < i && (n = a, i = s) } const r = n.parts[n.parts.length - 1], a = CM(this, iM, "f").findIndex((e => e.id == r.id)); if (a >= 0) { const e = CM(this, iM, "f")[a]; _M(this, qS, r.rotation, "f"), CM(this, cS, "f").rotation = CM(this, qS, "f"), _M(this, XS, r.rotationAxis, "f"), CM(this, cS, "f").rotationAxis = CM(this, XS, "f"), _M(this, aM, r.color, "f"), CM(this, BE, "m", vM).call(this, e.category), CM(this, BE, "m", wM).call(this, a) } } } }, uM = function(e, t) { null != CM(this, nS, "f") && (clearTimeout(CM(this, nS, "f")), _M(this, nS, null, "f")), t ? CM(this, tS, "f").classList.add("green") : CM(this, tS, "f").classList.remove("green"), CM(this, tS, "f").classList.remove("show"), CM(this, tS, "f").classList.remove("hide"), _M(this, nS, window.setTimeout((() => { CM(this, tS, "f").textContent = e, CM(this, tS, "f").classList.add("show"), _M(this, nS, window.setTimeout((() => { CM(this, tS, "f").classList.remove("show"), CM(this, tS, "f").classList.add("hide") }), 3e3), "f") }), 0), "f") }, pM = function() { var e; const t = CM(this, HE, "f").getAllParts(); for (let n = 0; n < t.length; n++) { const i = t[n], r = i.colors.get(Jy.Summer); if (null == r) throw new Error("Mesh is not loaded"); const a = r.clone(); a.material = CM(this, zS, "f"), CM(this, US, "f").add(a); let s = null === (e = CM(this, sM, "f").find((e => e.category == i.configuration.category))) || void 0 === e ? void 0 : e.partPanel; if (null == s) { s = document.createElement("div"), s.className = "part-panel hidden", CM(this, iS, "f").prepend(s); const e = CM(this, HE, "f").getCategoryMesh(i.configuration.category, CM(this, VE, "f").environment), t = document.createElement("button"); t.addEventListener("click", (() => { CM(this, BE, "m", vM).call(this, i.configuration.category), CM(this, UE, "f").playUIClick() })), CM(this, rS, "f").appendChild(t); const n = document.createElement("img"); n.className = "loading", NE(e).then((e => { n.src = e, n.className = "" })).catch((e => { console.error(e) })), t.appendChild(n), CM(this, sM, "f").push({ category: i.configuration.category, button: t, image: n, partPanel: s, selectedIndex: null }) } const o = document.createElement("button"); o.addEventListener("click", (() => { CM(this, UE, "f").playUIClick(), CM(this, BE, "m", wM).call(this, 1 + n) })), s.appendChild(o); const l = document.createElement("img"); l.className = "loading", o.appendChild(l); const c = []; let h; if (i.colors.size <= 1) h = null; else { h = document.createElement("div"), h.className = "color-panel hidden", CM(this, iS, "f").prepend(h); const e = [Jy.Default].concat(Array.from(i.colors.keys())); for (const t of e) { const e = document.createElement("button"); e.addEventListener("click", (() => { CM(this, UE, "f").playUIClick(), _M(this, aM, t, "f"), e.classList.add("selected"); const n = e.parentElement; if (null == n) throw new Error("Color panel not found"); for (const t of n.children) t != e && t.classList.remove("selected") })), t == Jy.Default && e.classList.add("selected"), h.appendChild(e); const n = document.createElement("img"); n.className = "loading", e.appendChild(n), c.push([t, e, n]) } } const d = { id: i.configuration.id, selectionMesh: a, button: o, image: l, colorPanel: h, colorButtons: c, tiles: i.configuration.tiles, isCheckpoint: null != i.configuration.detector && i.configuration.detector.type == XA.Checkpoint, isStart: null != i.configuration.startOffset, category: i.configuration.category }; CM(this, iM, "f").push(d) } }, fM = function() { if (null == CM(this, rM, "f")) return Jy.Default; return CM(this, iM, "f")[CM(this, rM, "f")].colorButtons.some((([e]) => e == CM(this, aM, "f"))) ? CM(this, aM, "f") : Jy.Default }, mM = function(e) { CM(this, VE, "f").environment = e, CM(this, BE, "m", gM).call(this), CM(this, VE, "f").generateMeshes() }, gM = function() { for (const e of CM(this, sM, "f")) { const t = CM(this, HE, "f").getCategoryMesh(e.category, CM(this, VE, "f").environment); e.image.removeAttribute("src"), e.image.className = "loading", NE(t).then((t => { e.image.src = t, e.image.className = "" })).catch((e => { console.error(e) })) } let e; switch (CM(this, VE, "f").environment) { case QA.Summer: e = Jy.Summer; break; case QA.Winter: e = Jy.Winter; break; case QA.Desert: e = Jy.Desert } for (const t of CM(this, iM, "f")) if (null != t.id) if (t.category == CM(this, oM, "f")) { const n = CM(this, HE, "f").getPart(t.id).colors.get(e); if (null == n) throw new Error("Mesh is not loaded"); t.image.removeAttribute("src"), t.image.className = "loading", NE(n).then((e => { t.image.src = e, t.image.className = "" })).catch((e => { console.error(e) })) } else t.image.removeAttribute("src"), t.image.className = "loading" }, vM = function(e) { var t; if (CM(this, oM, "f") != e || null == e) { _M(this, oM, e, "f"); for (const t of CM(this, sM, "f")) t.category == e ? (t.button.classList.add("selected"), t.partPanel.classList.remove("hidden")) : (t.button.classList.remove("selected"), t.partPanel.classList.add("hidden")); if (null == e) CM(this, BE, "m", wM).call(this, 0); else { let n; switch (CM(this, VE, "f").environment) { case QA.Summer: n = Jy.Summer; break; case QA.Winter: n = Jy.Winter; break; case QA.Desert: n = Jy.Desert } for (const t of CM(this, iM, "f")) if (t.category == e && null != t.id && !t.image.hasAttribute("src")) { const e = CM(this, HE, "f").getPart(t.id).colors.get(n); if (null == e) throw new Error("Mesh is not loaded"); t.image.className = "loading", NE(e).then((e => { t.image.src = e, t.image.className = "" })).catch((e => { console.error(e) })) } let i = null === (t = CM(this, sM, "f").find((t => t.category == e))) || void 0 === t ? void 0 : t.selectedIndex; if (null == i && (i = CM(this, iM, "f").findIndex((t => t.category == e)), i < 0)) throw new Error("Empty category"); CM(this, BE, "m", wM).call(this, i) } } }, wM = function(e) { for (let t = 0; t < CM(this, iM, "f").length; t++) { const { selectionMesh: n, button: i, colorPanel: r } = CM(this, iM, "f")[t]; t == e ? (n.visible = !0, i.className = "selected", null == r || r.classList.remove("hidden")) : (n.visible = !1, i.className = "", null == r || r.classList.add("hidden")) } _M(this, rM, e, "f"); const t = CM(this, sM, "f").find((e => e.category == CM(this, oM, "f"))); if (null != t && (t.selectedIndex = e), null != CM(this, WS, "f")) { if (CM(this, US, "f").remove(CM(this, WS, "f")), CM(this, WS, "f").geometry.dispose(), Array.isArray(CM(this, WS, "f").material)) for (const e of CM(this, WS, "f").material) e.dispose(); else CM(this, WS, "f").material.dispose(); CM(this, WS, "f").dispose(), _M(this, WS, null, "f") } if (null != e && e >= 0 && e < CM(this, iM, "f").length) { const t = CM(this, iM, "f")[e]; t.isCheckpoint ? CM(this, sS, "f").show() : CM(this, sS, "f").hide(); const n = new ua(CM(this, FS, "f"), CM(this, OS, "f"), t.tiles.length); t.tiles.forEach(((e, t, i, r) => { const a = (new qn).makeTranslation(e * jb.partSize, t * jb.partSize, i * jb.partSize); n.setMatrixAt(r, a) })), CM(this, US, "f").add(n), _M(this, WS, n, "f"); const i = CM(this, BE, "m", fM).call(this); if (null != t.id) for (const [e, n, r] of t.colorButtons) if (e == i ? n.classList.add("selected") : n.classList.remove("selected"), !r.hasAttribute("src")) if (e == Jy.Default) r.src = "images/empty.svg", r.className = ""; else { const n = CM(this, HE, "f").getPart(t.id).colors.get(e); if (null == n) throw new Error("Mesh is not loaded"); r.className = "loading", NE(n).then((e => { r.src = e, r.className = "" })).catch((e => { console.error(e) })) } } else CM(this, sS, "f").hide(); CM(this, BE, "m", bM).call(this) }, yM = function() { return Math.floor(CM(this, BS, "f").position.y / 5) }, AM = function(e) { const t = CM(this, BE, "a", yM); CM(this, BS, "f").position.y = 5 * e, CM(this, kS, "f").position.y += 5 * (e - t), CM(this, ES, "f").target.y = 5 * e, CM(this, aS, "f").refresh(e), CM(this, BS, "f").updateWorldMatrix(!0, !0), CM(this, ES, "f").update() }, bM = function() { if (null != CM(this, rM, "f") && CM(this, rM, "f") >= 0 && CM(this, rM, "f") < CM(this, iM, "f").length) { const e = CM(this, iM, "f")[CM(this, rM, "f")]; _M(this, KS, 0, "f"), e.tiles.rotated(CM(this, qS, "f"), CM(this, XS, "f")).forEach(((e, t) => { _M(this, KS, Math.max(CM(this, KS, "f"), -t), "f") })) } else _M(this, KS, 0, "f") }, xM = function() { const e = performance.now(); if (e - CM(this, zE, "f") > 35) { const t = CM(this, UE, "f").getBuffer("editor_edit"); if (null != t && null != CM(this, UE, "f").context && null != CM(this, UE, "f").destinationSfx) { const e = CM(this, UE, "f").context.createBufferSource(); e.buffer = t, e.playbackRate.value = .7; const n = CM(this, UE, "f").context.createGain(); n.gain.value = .05, e.connect(n), n.connect(CM(this, UE, "f").destinationSfx), e.start(0) } _M(this, zE, e, "f") } }, kM = function() { let e; if (CM(this, qE, "f").touchEnabled) e = new yn(CM(this, ES, "f").target.x / jb.partSize, CM(this, ES, "f").target.y / jb.partSize, CM(this, ES, "f").target.z / jb.partSize); else { let t; if (null != CM(this, GS, "f") ? (CM(this, NS, "f").setFromCamera(CM(this, GS, "f"), CM(this, FE, "f").camera), t = CM(this, NS, "f").intersectObjects([CM(this, BS, "f")])) : t = [], t.length > 0) { const n = t[0]; e = n.point.distanceToSquared(CM(this, ES, "f").target) <= CM(this, tM, "f") * CM(this, tM, "f") ? new yn(Math.round(n.point.x / jb.partSize), Math.floor(CM(this, BS, "f").position.y / jb.partSize), Math.round(n.point.z / jb.partSize)) : null } else e = null } if (null != e) { let t, n; t = CM(this, ZS, "f") ? 4 : 1, n = CM(this, XS, "f") == nA.XPositive || CM(this, XS, "f") == nA.XNegative ? Math.round(e.x) : Math.round(e.x / t) * t; const i = Math.round(e.y) + CM(this, KS, "f"); let r; return r = CM(this, XS, "f") == nA.ZPositive || CM(this, XS, "f") == nA.ZNegative ? Math.round(e.z) : Math.round(e.z / t) * t, new yn(n, i, r) } return null }, EM = function(e, t) { const n = []; return t.rotated(CM(this, qS, "f"), CM(this, XS, "f")).forEach(((t, i, r) => { const a = e.x + t, s = e.y + i, o = e.z + r, l = CM(this, VE, "f").getPartsAt(a, s, o); l.length > 0 && n.push({ x: a, y: s, z: o, parts: l }) })), n }, SM = function(e) { var t; let n = !1; for (const { x: t, y: i, z: r } of e) CM(this, VE, "f").deletePartsAt(t, i, r) && (n = !0); n && (CM(this, BE, "m", xM).call(this), CM(this, VE, "f").generateMeshes(), null === (t = CM(this, nM, "f")) || void 0 === t || t.refresh(CM(this, VE, "f")), CM(this, sS, "f").setFromExistingCheckpoints(CM(this, VE, "f")), _M(this, DS, !1, "f")) }, MM = function(e) { const t = 4 * CM(this, ES, "f").getDistance(); if (CM(this, JE, "f") && CM(this, BE, "m", TM).call(this)) { const n = new yn; if (CM(this, MS, "f") && (n.z = -1), CM(this, TS, "f") && (n.x = 1), CM(this, _S, "f") && (n.z = 1), CM(this, CS, "f") && (n.x = -1), 0 != n.x || 0 != n.z) { const i = n.applyQuaternion(CM(this, kS, "f").quaternion), r = new jt(i.x, i.z).normalize(), a = new yn(r.x, 0, r.y).multiplyScalar(t * e); CM(this, kS, "f").position.add(a), CM(this, ES, "f").target.add(a) } let i = 0; CM(this, PS, "f") && (i += 1.5 * Math.PI * e), CM(this, IS, "f") && (i -= 1.5 * Math.PI * e); let r = 0; if (CM(this, RS, "f") && (r += 1.5 * Math.PI * e), CM(this, LS, "f") && (r -= 1.5 * Math.PI * e), 0 != i || 0 != r) { const e = new jt(CM(this, kS, "f").position.x, CM(this, kS, "f").position.z).distanceTo(new jt(CM(this, ES, "f").target.x, CM(this, ES, "f").target.z)), t = CM(this, kS, "f").position.y - CM(this, ES, "f").target.y, n = Math.sqrt(e * e + t * t), a = Math.atan2(CM(this, kS, "f").position.z - CM(this, ES, "f").target.z, CM(this, kS, "f").position.x - CM(this, ES, "f").target.x) + r; let s = Math.asin(t / n) + i; s = Math.max(-Math.PI / 2 + .001, Math.min(Math.PI / 2 - .001, s)), CM(this, kS, "f").position.x = CM(this, ES, "f").target.x + Math.cos(s) * Math.cos(a) * n, CM(this, kS, "f").position.y = CM(this, ES, "f").target.y + Math.sin(s) * n, CM(this, kS, "f").position.z = CM(this, ES, "f").target.z + Math.cos(s) * Math.sin(a) * n, CM(this, ES, "f").update() } } }, TM = function() { return !!CM(this, JE, "f") && (!CM(this, KE, "f").isOpen && null == CM(this, lS, "f") && !CM(this, oS, "f").isOpen && null == CM(this, hS, "f") && null == CM(this, dS, "f")) }; const PM = class { constructor(e, t, n, i, r, a, s, o, l, c, h, d, u, p) { var f; BE.add(this), UE.set(this, void 0), zE.set(this, performance.now()), OE.set(this, void 0), FE.set(this, void 0), WE.set(this, void 0), VE.set(this, void 0), HE.set(this, void 0), GE.set(this, void 0), jE.set(this, void 0), QE.set(this, void 0), YE.set(this, void 0), KE.set(this, void 0), qE.set(this, void 0), XE.set(this, void 0), ZE.set(this, null), JE.set(this, !1), $E.set(this, void 0), eS.set(this, void 0), tS.set(this, void 0), nS.set(this, null), iS.set(this, void 0), rS.set(this, void 0), aS.set(this, void 0), sS.set(this, void 0), oS.set(this, void 0), lS.set(this, null), cS.set(this, void 0), hS.set(this, null), dS.set(this, null), uS.set(this, void 0), pS.set(this, void 0), fS.set(this, void 0), mS.set(this, void 0), gS.set(this, void 0), vS.set(this, void 0), wS.set(this, void 0), yS.set(this, void 0), AS.set(this, void 0), bS.set(this, void 0), xS.set(this, void 0), kS.set(this, void 0), ES.set(this, void 0), SS.set(this, !1), MS.set(this, !1), TS.set(this, !1), _S.set(this, !1), CS.set(this, !1), PS.set(this, !1), IS.set(this, !1), RS.set(this, !1), LS.set(this, !1), DS.set(this, !0), NS.set(this, void 0), BS.set(this, void 0), US.set(this, void 0), zS.set(this, void 0), OS.set(this, void 0), FS.set(this, void 0), WS.set(this, null), VS.set(this, !1), HS.set(this, !1), GS.set(this, null), jS.set(this, null), QS.set(this, !1), YS.set(this, null), KS.set(this, 0), qS.set(this, 0), XS.set(this, nA.YPositive), ZS.set(this, !0), JS.set(this, !1), $S.set(this, null), eM.set(this, null), tM.set(this, 1e3), nM.set(this, null), iM.set(this, []), rM.set(this, null), aM.set(this, Jy.Default), sM.set(this, []), oM.set(this, null), _M(this, OE, e, "f"), _M(this, UE, t, "f"), _M(this, FE, n, "f"), _M(this, WE, i, "f"), _M(this, VE, r, "f"), _M(this, HE, a, "f"), _M(this, QE, s, "f"), _M(this, YE, o, "f"), _M(this, GE, l, "f"), _M(this, jE, c, "f"), _M(this, KE, h, "f"), _M(this, qE, d, "f"), _M(this, XE, u, "f"), _M(this, kS, new Pr(70, 1, .5, Au.maxViewDistance), "f"), CM(this, kS, "f").position.set(40, 40, -40), n.scene.add(CM(this, kS, "f")), _M(this, ES, new _A(CM(this, kS, "f"), n.canvas), "f"), CM(this, ES, "f").mouseButtons = { MIDDLE: g, RIGHT: w }, CM(this, ES, "f").minDistance = 4, CM(this, ES, "f").maxDistance = 600, _M(this, NS, new jo, "f"), this.trackAuthor = o.getCurrentUserProfile().nickname, _M(this, zS, new Fs({ transparent: !0, opacity: .3, polygonOffset: !0, polygonOffsetFactor: -.3, depthWrite: !1 }), "f"), _M(this, US, new Nr, "f"), CM(this, US, "f").visible = !1, n.scene.add(CM(this, US, "f")), _M(this, FS, (new sr).setFromPoints([new yn(0, 0, 0), new yn(0, 0, 0), new yn(0, 0, 1), new yn(0, 0, 1), new yn(0, 0, 1), new yn(1, 0, 1), new yn(1, 0, 1), new yn(1, 0, 1), new yn(1, 0, 0), new yn(1, 0, 0), new yn(1, 0, 0), new yn(0, 0, 0), new yn(0, 1, 0), new yn(0, 1, 0), new yn(0, 1, 1), new yn(0, 1, 1), new yn(0, 1, 1), new yn(1, 1, 1), new yn(1, 1, 1), new yn(1, 1, 1), new yn(1, 1, 0), new yn(1, 1, 0), new yn(1, 1, 0), new yn(0, 1, 0), new yn(0, 0, 0), new yn(0, 0, 0), new yn(0, 1, 0), new yn(0, 0, 1), new yn(0, 0, 1), new yn(0, 1, 1), new yn(1, 0, 1), new yn(1, 0, 1), new yn(1, 1, 1), new yn(1, 0, 0), new yn(1, 0, 0), new yn(1, 1, 0)]).scale(jb.partSize, jb.partSize, jb.partSize), "f"), _M(this, OS, new ji({ wireframe: !0 }), "f"), _M(this, BS, new wr(new Ns(1e6, 1e6), new ji({ side: 2 })), "f"), CM(this, BS, "f").rotation.x = -Math.PI / 2, CM(this, BS, "f").updateWorldMatrix(!0, !0), n.canvas.addEventListener("mousemove", _M(this, pS, (e => { const t = e.clientX / window.innerWidth * 2 - 1, n = -e.clientY / window.innerHeight * 2 + 1; null == CM(this, GS, "f") ? _M(this, GS, new jt(t, n), "f") : CM(this, GS, "f").set(t, n) }), "f")), n.canvas.addEventListener("mousedown", _M(this, fS, (e => { 0 == e.button && _M(this, HS, !0, "f"), 1 == e.button && e.preventDefault() }), "f")), window.addEventListener("mouseup", _M(this, mS, (e => { 0 == e.button && (_M(this, HS, !1, "f"), _M(this, $S, null, "f")) }), "f")), n.canvas.addEventListener("mouseout", _M(this, gS, (() => { _M(this, GS, null, "f") }), "f")), n.canvas.addEventListener("touchstart", _M(this, vS, (() => { CM(this, qE, "f").touchEnabled && _M(this, jS, Date.now(), "f") }), "f")), n.canvas.addEventListener("click", _M(this, wS, (() => { CM(this, qE, "f").touchEnabled && null != CM(this, jS, "f") && Date.now() - CM(this, jS, "f") < 200 && (_M(this, jS, null, "f"), _M(this, QS, !0, "f")) }), "f")), window.addEventListener("keydown", _M(this, yS, (e => { CM(this, BE, "m", TM).call(this) && (CM(this, KE, "f").isOpen || CM(this, oS, "f").isOpen || null != CM(this, lS, "f") || null != CM(this, hS, "f") || "Escape" == e.code && (CM(this, BE, "m", cM).call(this, p), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorRotatePart) && (_M(this, qS, (CM(this, qS, "f") + 1) % 4, "f"), CM(this, cS, "f").rotation = CM(this, qS, "f"), CM(this, BE, "m", bM).call(this), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorHeightModifier) && (_M(this, SS, !0, "f"), CM(this, ES, "f").enableZoom = !1, e.preventDefault()), u.checkKeyBinding(e, Ix.EditorDelete) && (_M(this, VS, !0, "f"), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorMoveForwards) && (_M(this, MS, !0, "f"), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorMoveRight) && (_M(this, TS, !0, "f"), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorMoveBackwards) && (_M(this, _S, !0, "f"), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorMoveLeft) && (_M(this, CS, !0, "f"), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorRotateViewUp) && (_M(this, PS, !0, "f"), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorRotateViewDown) && (_M(this, IS, !0, "f"), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorRotateViewLeft) && (_M(this, RS, !0, "f"), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorRotateViewRight) && (_M(this, LS, !0, "f"), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorMoveDown) && (_M(this, BE, Math.max(0, CM(this, BE, "a", yM) - 1), "a", AM), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorMoveUp) && (_M(this, BE, CM(this, BE, "a", yM) + 1, "a", AM), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorTest) && (CM(this, BE, "m", hM).call(this), e.preventDefault()), u.checkKeyBinding(e, Ix.EditorPick) && (CM(this, BE, "m", dM).call(this), e.preventDefault())) }), "f")), window.addEventListener("keyup", _M(this, AS, (e => { u.checkKeyBinding(e, Ix.EditorHeightModifier) && (_M(this, SS, !1, "f"), CM(this, ES, "f").enableZoom = !0), u.checkKeyBinding(e, Ix.EditorDelete) && _M(this, VS, !1, "f"), u.checkKeyBinding(e, Ix.EditorMoveForwards) && _M(this, MS, !1, "f"), u.checkKeyBinding(e, Ix.EditorMoveRight) && _M(this, TS, !1, "f"), u.checkKeyBinding(e, Ix.EditorMoveBackwards) && _M(this, _S, !1, "f"), u.checkKeyBinding(e, Ix.EditorMoveLeft) && _M(this, CS, !1, "f"), u.checkKeyBinding(e, Ix.EditorRotateViewUp) && _M(this, PS, !1, "f"), u.checkKeyBinding(e, Ix.EditorRotateViewDown) && _M(this, IS, !1, "f"), u.checkKeyBinding(e, Ix.EditorRotateViewLeft) && _M(this, RS, !1, "f"), u.checkKeyBinding(e, Ix.EditorRotateViewRight) && _M(this, LS, !1, "f") }), "f")), window.addEventListener("wheel", _M(this, bS, (e => { CM(this, SS, "f") && CM(this, JE, "f") && (e.deltaY > 0 ? _M(this, BE, CM(this, BE, "a", yM) + 1, "a", AM) : e.deltaY < 0 && _M(this, BE, Math.max(0, CM(this, BE, "a", yM) - 1), "a", AM)) }), "f")), window.addEventListener("beforeunload", _M(this, xS, (e => !CM(this, DS, "f") && (e.preventDefault(), !0)), "f")); const m = document.getElementById("ui"); if (null == m) throw new Error("Failed to find UI element"); _M(this, $E, document.createElement("div"), "f"), CM(this, $E, "f").className = "hidden", m.appendChild(CM(this, $E, "f")), _M(this, eS, document.createElement("div"), "f"), CM(this, eS, "f").className = "top", CM(this, $E, "f").appendChild(CM(this, eS, "f")); const v = document.createElement("div"); v.className = "button-bar", CM(this, eS, "f").appendChild(v); const y = document.createElement("button"); y.className = "button", y.innerHTML = ' ', y.append(document.createTextNode(CM(this, OE, "f").get("Exit"))), y.addEventListener("click", (() => { CM(this, UE, "f").playUIClick(), CM(this, BE, "m", cM).call(this, p) })), v.appendChild(y); const A = document.createElement("button"); A.className = "button", A.innerHTML = ' ', A.append(CM(this, OE, "f").get("Test")), A.addEventListener("click", (() => { CM(this, UE, "f").playUIClick(), CM(this, BE, "m", hM).call(this) })), v.appendChild(A); const b = document.createElement("button"); b.className = "button", b.innerHTML = ' ', b.append(CM(this, OE, "f").get("Generate")), b.addEventListener("click", (() => { CM(this, UE, "f").playUIClick(); const e = () => { var e; ! function(e) { let t; e.clear(); do { let n = 0, i = 0, r = 0, a = Math.floor(4 * Math.random()); Math.random() < .5 && (i = Math.floor(20 * Math.random())); const s = new Map; function o() { switch (a) { case 0: --r; break; case 1: --n; break; case 2: ++r; break; case 3: ++n } } function l() { switch (a) { case 0: ++r; break; case 1: ++n; break; case 2: --r; break; case 3: --n } } function c() { switch ((a + 1) % 4) { case 0: --r; break; case 1: --n; break; case 2: ++r; break; case 3: ++n } } function h() { switch (((a - 1) % 4 + 4) % 4) { case 0: --r; break; case 1: --n; break; case 2: ++r; break; case 3: ++n } } function d(e, n, i, r = null) { const a = e.toString() + "|" + n.toString() + "|" + i.toString(); s.has(a) && (t = !0), null != r && (r.x = e, r.y = n, r.z = i, "direction" in r && (r.direction = (r.direction % 4 + 4) % 4)), s.set(a, r) } function u(e, t, n) { return !!s.has(e.toString() + "|" + t.toString() + "|" + n.toString()) } function p() { let e = !1; for (let t = 0; t < i; ++t) if (u(n, t, r)) { e = !0; break } if (!e) for (let e = 0; e < i; ++e) { let t; t = 0 == e && e == i - 1 ? 22 : 0 == e ? 21 : e == i - 1 ? 19 : 20, d(n, e, r, { type: t, direction: 0 }) } } function f(e) { e > 0 ? (--e, Math.random() < .2 ? E(e) : Math.random() < .6 ? g(e) : Math.random() < .5 ? y(e, i < 2 || Math.random() < .5) : Math.random() < .5 ? v(e) : w(e)) : x() } function m(e) { e > 0 ? (--e, Math.random() < .1 ? S(e) : Math.random() < .6 ? M(e) : Math.random() < .5 ? C(e, i < 2 || Math.random() < .5) : Math.random() < .5 ? T(e) : _(e)) : S(e) } function g(e) { d(n, i, r, { type: 0, direction: a }), p(), o(), f(e) } function v(e) { d(n, i, r, { type: 1, direction: a - 1 }), p(), a = (a + 1) % 4, o(), e > 0 ? (--e, Math.random() < .4 ? g(e) : Math.random() < .5 ? v(e) : w(e)) : x() } function w(e) { d(n, i, r, { type: 1, direction: a }), p(), a = ((a - 1) % 4 + 4) % 4, o(), e > 0 ? (--e, Math.random() < .4 ? g(e) : Math.random() < .5 ? v(e) : w(e)) : x() } function y(e, t) { let s; s = t ? 2 : 3, t || --i, d(n, i + 1, r), d(n, i, r, { type: s, direction: a }), o(), t && ++i, e > 0 ? (--e, Math.random() < .4 || i <= 3 ? A(e, t) : b(e, t)) : A(e, t) } function A(e, t) { let s; t || --i, d(n, i + 1, r), s = t ? 3 : 2, d(n, i, r, { type: s, direction: a + 2 }), o(), t && ++i, e > 0 ? f(--e) : x() } function b(e, t) { let s; t || (i -= 2), d(n, i + 1, r), d(n, i + 2, r), s = t ? a : a + 2, d(n, i, r, { type: 4, direction: s }), o(), t && (i += 2), e > 0 ? (--e, Math.random() < .4 || i <= 3 ? A(e, t) : b(e, t)) : A(e, t) } function x() { d(n, i, r, { type: 6, direction: a }) } function k(e) { d(n, i, r, { type: 5, direction: a }), p(), o(), f(e) } function E(e) { Math.random() < .5 ? (d(n, i, r, { type: 8, direction: a }), p(), h(), d(n, i, r, { type: 12, direction: a + 2 }), p(), o()) : (d(n, i, r, { type: 9, direction: a }), p(), c(), d(n, i, r, { type: 12, direction: a + 1 }), p(), o(), h()), m(e) } function S(e) { Math.random() < .5 ? (d(n, i, r, { type: 12, direction: a + 3 }), p(), c(), d(n, i, r, { type: 9, direction: a + 2 }), p(), o()) : (d(n, i, r, { type: 8, direction: a + 2 }), p(), c(), d(n, i, r, { type: 12, direction: a }), p(), o(), h()), f(e) } function M(e) { d(n, i, r, { type: 10, direction: a }), p(), c(), d(n, i, r, { type: 10, direction: a + 2 }), p(), h(), o(), m(e) } function T(e) { d(n, i, r, { type: 10, direction: a }), p(), o(), d(n, i, r, { type: 12, direction: a + 3 }), p(), c(), d(n, i, r, { type: 10, direction: a + 1 }), p(), l(), d(n, i, r, { type: 11, direction: a + 3 }), p(), o(), a = (a + 1) % 4, o(), m(e) } function _(e) { d(n, i, r, { type: 11, direction: a }), p(), c(), d(n, i, r, { type: 10, direction: a + 2 }), p(), o(), d(n, i, r, { type: 12, direction: a }), p(), h(), d(n, i, r, { type: 10, direction: a + 1 }), p(), l(), a = ((a - 1) % 4 + 4) % 4, o(), m(e) } function C(e, t) { let s, l; t ? (s = 13, l = 14) : (s = 15, l = 16), t || --i, c(), d(n, i + 1, r), d(n, i, r, { type: s, direction: a }), h(), d(n, i + 1, r), d(n, i, r, { type: l, direction: a }), o(), t && ++i, e > 0 ? (--e, Math.random() < .4 || i <= 3 ? P(e, t) : I(e, t)) : P(e, t) } function P(e, t) { let s, l; t || --i, t ? (s = 16, l = 15) : (s = 14, l = 13), c(), d(n, i + 1, r), d(n, i, r, { type: s, direction: a + 2 }), h(), d(n, i + 1, r), d(n, i, r, { type: l, direction: a + 2 }), o(), t && ++i, m(e) } function I(e, t) { t || (i -= 2), t ? (c(), d(n, i + 1, r), d(n, i + 2, r), d(n, i, r, { type: 17, direction: a }), h(), d(n, i + 1, r), d(n, i + 2, r), d(n, i, r, { type: 18, direction: a })) : (c(), d(n, i + 1, r), d(n, i + 2, r), d(n, i, r, { type: 18, direction: a + 2 }), h(), d(n, i + 1, r), d(n, i + 2, r), d(n, i, r, { type: 17, direction: a + 2 })), o(), t && (i += 2), e > 0 ? (--e, Math.random() < .4 || i <= 3 ? P(e, t) : I(e, t)) : P(e, t) } if (t = !1, k(50), !t) for (const R of s.values()) if (null != R) { let L = null; R.type == eA.Start && (L = 0), e.setPart(4 * R.x, R.y, 4 * R.z, R.type, R.direction, nA.YPositive, Jy.Default, null, L) } } while (t) }(CM(this, VE, "f")), CM(this, VE, "f").generateMeshes(), null === (e = CM(this, nM, "f")) || void 0 === e || e.refresh(CM(this, VE, "f")), CM(this, sS, "f").setFromExistingCheckpoints(CM(this, VE, "f")), _M(this, DS, !0, "f") }; CM(this, DS, "f") ? e() : (CM(this, $E, "f").inert = !0, CM(this, KE, "f").showConfirm(CM(this, OE, "f").get("Are you sure you want to generate a new track?\n\nYour current track will be lost!"), CM(this, OE, "f").get("Cancel"), CM(this, OE, "f").get("Confirm"), (() => { CM(this, $E, "f").inert = !1 }), (() => { e(), CM(this, $E, "f").inert = !1 }))) })), v.appendChild(b), _M(this, oS, new $k(m, CM(this, OE, "f"), CM(this, UE, "f"), CM(this, GE, "f"), CM(this, jE, "f"), CM(this, YE, "f"), CM(this, KE, "f"), CM(this, QE, "f"), !0, (() => { CM(this, $E, "f").className = "editor", CM(this, oS, "f").hide() }), ((e, t) => { var n; const i = CM(this, VE, "f").environment; CM(this, VE, "f").loadTrackData(t, !1), CM(this, VE, "f").environment != i && CM(this, BE, "m", gM).call(this), CM(this, VE, "f").generateMeshes(), null === (n = CM(this, nM, "f")) || void 0 === n || n.refresh(CM(this, VE, "f")), CM(this, sS, "f").setFromExistingCheckpoints(CM(this, VE, "f")), _M(this, DS, !0, "f"), CM(this, BE, "m", lM).call(this, e.name), this.trackAuthor = e.author; const r = CM(this, VE, "f").getStart(); if (null != r) this.resetView(r.x, r.y, r.z); else { const e = CM(this, VE, "f").getBounds(); this.resetView(e.min.x + Math.floor((e.max.x - e.min.x) / 2), 0, e.min.y + Math.floor((e.max.y - e.min.y) / 2)) } CM(this, $E, "f").className = "editor", CM(this, oS, "f").hide() })), "f"), _M(this, cS, new uE(CM(this, $E, "f"), CM(this, UE, "f"), CM(this, qE, "f"), (e => { _M(this, JS, e, "f") }), (e => { _M(this, ZS, e, "f") }), (e => { _M(this, XS, e, "f"), CM(this, cS, "f").rotationAxis = CM(this, XS, "f"), CM(this, BE, "m", bM).call(this) }), (() => { _M(this, qS, (CM(this, qS, "f") + 1) % 4, "f"), CM(this, cS, "f").rotation = CM(this, qS, "f"), CM(this, BE, "m", bM).call(this) })), "f"); const x = document.createElement("button"); x.className = "button", x.innerHTML = ' ', x.append(document.createTextNode(CM(this, OE, "f").get("Load"))), x.addEventListener("click", (() => { CM(this, UE, "f").playUIClick(), CM(this, DS, "f") ? (CM(this, oS, "f").show(), CM(this, $E, "f").className = "hidden") : (CM(this, $E, "f").inert = !0, CM(this, KE, "f").showConfirm(CM(this, OE, "f").get("Are you sure you want to load a new track?\n\nYour current track will be lost!"), CM(this, OE, "f").get("Cancel"), CM(this, OE, "f").get("Confirm"), (() => { CM(this, $E, "f").inert = !1 }), (() => { CM(this, oS, "f").show(), CM(this, $E, "f").className = "hidden", CM(this, $E, "f").inert = !1 }))) })), v.appendChild(x); const k = document.createElement("button"); k.className = "button", k.innerHTML = ' ', k.append(document.createTextNode(CM(this, OE, "f").get("Save"))), k.addEventListener("click", (() => { CM(this, UE, "f").playUIClick(); const e = e => { const t = { name: e, author: this.trackAuthor }, n = CM(this, VE, "f").getTrackData(); CM(this, jE, "f").saveCustomTrack(t, n) ? (CM(this, BE, "m", uM).call(this, CM(this, OE, "f").get("Track saved!"), !0), _M(this, DS, !0, "f")) : CM(this, BE, "m", uM).call(this, CM(this, OE, "f").get("Failed to save!"), !1) }, t = this.getTrackName(); if (null == t) CM(this, $E, "f").className = "hidden", _M(this, dS, new CE(CM(this, UE, "f"), CM(this, OE, "f"), CM(this, eM, "f"), this.trackAuthor, this, CM(this, VE, "f"), (e => { CM(this, BE, "m", mM).call(this, e) }), (e => { var t; CM(this, BE, "m", lM).call(this, e), null === (t = CM(this, dS, "f")) || void 0 === t || t.dispose(), _M(this, dS, null, "f"), CM(this, $E, "f").className = "editor" }), (t => { var n; CM(this, BE, "m", lM).call(this, t), null === (n = CM(this, dS, "f")) || void 0 === n || n.dispose(), _M(this, dS, null, "f"), e(t), CM(this, $E, "f").className = "editor" })), "f"); else { CM(this, jE, "f").checkCustomTrackNameExists(t) ? (CM(this, $E, "f").inert = !0, CM(this, KE, "f").showConfirm(CM(this, OE, "f").get('Are you sure you want to overwrite "{0}"?', [t]), CM(this, OE, "f").get("Cancel"), CM(this, OE, "f").get("Confirm"), (() => { CM(this, $E, "f").inert = !1 }), (() => { e(t), CM(this, $E, "f").inert = !1 }))) : e(t) } })), v.appendChild(k); const E = document.createElement("button"); E.className = "button", E.innerHTML = ' ', E.append(document.createTextNode(CM(this, OE, "f").get("Export"))), E.addEventListener("click", (() => { CM(this, UE, "f").playUIClick(); const e = this.getTrackName(); if (null == e) CM(this, $E, "f").className = "hidden", _M(this, dS, new CE(CM(this, UE, "f"), CM(this, OE, "f"), CM(this, eM, "f"), this.trackAuthor, this, CM(this, VE, "f"), (e => { CM(this, BE, "m", mM).call(this, e) }), (e => { var t; CM(this, BE, "m", lM).call(this, e), null === (t = CM(this, dS, "f")) || void 0 === t || t.dispose(), _M(this, dS, null, "f"), CM(this, $E, "f").className = "editor" }), (e => { var t; CM(this, BE, "m", lM).call(this, e), null === (t = CM(this, dS, "f")) || void 0 === t || t.dispose(), _M(this, dS, null, "f"); const n = { name: e, author: this.trackAuthor }, i = CM(this, VE, "f").getTrackData().toExportString(n); _M(this, lS, new Hx(i, (() => { var e; null === (e = CM(this, lS, "f")) || void 0 === e || e.dispose(), _M(this, lS, null, "f"), CM(this, $E, "f").className = "editor" }), null, !1, CM(this, OE, "f"), CM(this, UE, "f"), CM(this, jE, "f"), CM(this, KE, "f")), "f") })), "f"); else { CM(this, $E, "f").className = "hidden"; const t = { name: e, author: this.trackAuthor }, n = CM(this, VE, "f").getTrackData().toExportString(t); _M(this, lS, new Hx(n, (() => { var e; null === (e = CM(this, lS, "f")) || void 0 === e || e.dispose(), _M(this, lS, null, "f"), CM(this, $E, "f").className = "editor" }), null, !1, CM(this, OE, "f"), CM(this, UE, "f"), CM(this, jE, "f"), CM(this, KE, "f")), "f") } })), v.appendChild(E); const S = document.createElement("button"); S.className = "button", S.innerHTML = ' ', S.append(document.createTextNode(CM(this, OE, "f").get("Help"))), S.addEventListener("click", (() => { CM(this, UE, "f").playUIClick(); const e = CM(this, HE, "f").getPart(eA.Start).colors.get(Jy.Summer); if (null == e) throw new Error("Starting point mesh is null"); const t = NE(e), n = CM(this, HE, "f").getPart(eA.Checkpoint).colors.get(Jy.Summer); if (null == n) throw new Error("Checkpoint mesh is null"); const i = NE(n), r = CM(this, HE, "f").getPart(eA.Finish).colors.get(Jy.Summer); if (null == r) throw new Error("Finish line mesh is null"); const a = NE(r); CM(this, $E, "f").className = "hidden", _M(this, hS, new AE(CM(this, UE, "f"), CM(this, OE, "f"), CM(this, XE, "f"), CM(this, qE, "f"), t, i, a, (() => { var e; null === (e = CM(this, hS, "f")) || void 0 === e || e.dispose(), _M(this, hS, null, "f"), CM(this, $E, "f").className = "editor" })), "f") })), v.appendChild(S); const M = document.createElement("div"); M.className = "track-settings-container", CM(this, eS, "f").appendChild(M), _M(this, uS, document.createElement("button"), "f"), CM(this, uS, "f").className = "button", CM(this, uS, "f").innerHTML = ' ', CM(this, uS, "f").append(document.createTextNode(null !== (f = CM(this, eM, "f")) && void 0 !== f ? f : CM(this, OE, "f").get("Unnamed Track"))), CM(this, uS, "f").addEventListener("click", (() => { CM(this, UE, "f").playUIClick(), CM(this, $E, "f").className = "hidden", _M(this, dS, new CE(CM(this, UE, "f"), CM(this, OE, "f"), CM(this, eM, "f"), this.trackAuthor, this, CM(this, VE, "f"), (e => { CM(this, BE, "m", mM).call(this, e) }), (e => { var t; CM(this, BE, "m", lM).call(this, e), null === (t = CM(this, dS, "f")) || void 0 === t || t.dispose(), _M(this, dS, null, "f"), CM(this, $E, "f").className = "editor" }), null), "f") })), M.appendChild(CM(this, uS, "f")), _M(this, tS, document.createElement("div"), "f"), CM(this, tS, "f").className = "message", CM(this, $E, "f").appendChild(CM(this, tS, "f")); const T = document.createElement("side"); T.className = "side", CM(this, $E, "f").appendChild(T), _M(this, sS, new mx(T, CM(this, OE, "f"), CM(this, UE, "f"), CM(this, qE, "f")), "f"), _M(this, iS, document.createElement("div"), "f"), CM(this, iS, "f").className = "side-panel", T.appendChild(CM(this, iS, "f")), _M(this, rS, document.createElement("div"), "f"), CM(this, rS, "f").className = "category-panel", CM(this, iS, "f").appendChild(CM(this, rS, "f")); const _ = new Ar(4 * jb.partSize, jb.partSize, 4 * jb.partSize); _.translate(0, jb.partSize / 2, 0); const C = new wr(_, CM(this, zS, "f")), P = document.createElement("button"); P.addEventListener("click", (() => { CM(this, UE, "f").playUIClick(), CM(this, BE, "m", vM).call(this, null) })), CM(this, rS, "f").appendChild(P); const I = document.createElement("img"); I.src = "images/erase.svg", P.appendChild(I), CM(this, US, "f").add(C), CM(this, iM, "f").push({ id: null, selectionMesh: C, button: P, image: I, colorPanel: null, colorButtons: [], tiles: new tb([ [-2, 0, -2], [-1, 0, -2], [0, 0, -2], [1, 0, -2], [-2, 0, -1], [-1, 0, -1], [0, 0, -1], [1, 0, -1], [-2, 0, 0], [-1, 0, 0], [0, 0, 0], [1, 0, 0], [-2, 0, 1], [-1, 0, 1], [0, 0, 1], [1, 0, 1] ]), isCheckpoint: !1, isStart: !1, category: null }), _M(this, aS, new Cx(CM(this, $E, "f"), CM(this, OE, "f"), CM(this, qE, "f"), (() => { CM(this, UE, "f").playUIClick(), _M(this, BE, CM(this, BE, "a", yM) + 1, "a", AM) }), (() => { CM(this, UE, "f").playUIClick(), _M(this, BE, Math.max(0, CM(this, BE, "a", yM) - 1), "a", AM) })), "f"), CM(this, aS, "f").refresh(CM(this, BE, "a", yM)) } dispose() { var e, t, n; _M(this, JE, !1, "f"), null === (e = CM(this, nM, "f")) || void 0 === e || e.dispose(), CM(this, aS, "f").dispose(), CM(this, sS, "f").dispose(), null === (t = CM(this, lS, "f")) || void 0 === t || t.dispose(), _M(this, lS, null, "f"), CM(this, oS, "f").dispose(), CM(this, cS, "f").dispose(), null === (n = CM(this, hS, "f")) || void 0 === n || n.dispose(), _M(this, hS, null, "f"); const i = document.getElementById("ui"); if (null == i) throw new Error("Failed to find UI element"); i.removeChild(CM(this, $E, "f")), CM(this, FE, "f").scene.remove(CM(this, kS, "f")), CM(this, ES, "f").dispose(), CM(this, FE, "f").canvas.style.touchAction = "", CM(this, zS, "f").dispose(); for (const e of CM(this, US, "f").children) { const t = e; if (t.geometry.dispose(), Array.isArray(t.material)) for (const e of t.material) e.dispose(); else t.material.dispose() } if (CM(this, FE, "f").scene.remove(CM(this, US, "f")), null != CM(this, WS, "f") && (CM(this, FE, "f").scene.remove(CM(this, WS, "f")), CM(this, WS, "f").dispose(), CM(this, FS, "f").dispose(), CM(this, OS, "f").dispose(), _M(this, WS, null, "f")), CM(this, BS, "f").geometry.dispose(), Array.isArray(CM(this, BS, "f").material)) for (const e of CM(this, BS, "f").material) e.dispose(); else CM(this, BS, "f").material.dispose(); CM(this, FE, "f").canvas.removeEventListener("mousemove", CM(this, pS, "f")), CM(this, FE, "f").canvas.removeEventListener("mousedown", CM(this, fS, "f")), window.removeEventListener("mouseup", CM(this, mS, "f")), CM(this, FE, "f").canvas.removeEventListener("mouseout", CM(this, gS, "f")), CM(this, FE, "f").canvas.removeEventListener("touchstart", CM(this, vS, "f")), CM(this, FE, "f").canvas.removeEventListener("click", CM(this, wS, "f")), window.removeEventListener("keydown", CM(this, yS, "f")), window.removeEventListener("keyup", CM(this, AS, "f")), window.removeEventListener("wheel", CM(this, bS, "f")), window.removeEventListener("beforeunload", CM(this, xS, "f")) } getTrackName() { return CM(this, eM, "f") } setTestCallback(e) { _M(this, ZE, e, "f") } enable() { var e; _M(this, JE, !0, "f"), CM(this, ES, "f").enabled = !0, 1 == CM(this, iM, "f").length && CM(this, BE, "m", pM).call(this), null === (e = CM(this, nM, "f")) || void 0 === e || e.dispose(), _M(this, nM, new ex(CM(this, FE, "f")), "f"), CM(this, nM, "f").refresh(CM(this, VE, "f")), CM(this, cS, "f").show(), CM(this, $E, "f").className = "editor" } disable() { var e, t, n; _M(this, JE, !1, "f"), CM(this, ES, "f").enabled = !1, CM(this, US, "f").visible = !1, null === (e = CM(this, nM, "f")) || void 0 === e || e.dispose(), CM(this, $E, "f").className = "hidden", null === (t = CM(this, lS, "f")) || void 0 === t || t.dispose(), _M(this, lS, null, "f"), CM(this, oS, "f").hide(), CM(this, cS, "f").hide(), null === (n = CM(this, hS, "f")) || void 0 === n || n.dispose(), _M(this, hS, null, "f") } isEnabled() { return CM(this, JE, "f") } resetView(e, t, n) { _M(this, BE, t, "a", AM); const i = new yn(e * jb.partSize, t * jb.partSize, n * jb.partSize); CM(this, kS, "f").position.copy(i).add(new yn(40, 40, -40)), CM(this, ES, "f").target.copy(i), CM(this, ES, "f").update() } get camera() { return CM(this, kS, "f") } update(e) { var t; if (CM(this, BE, "m", MM).call(this, e), CM(this, JE, "f")) { if (CM(this, kS, "f").position.y < .499 && (CM(this, kS, "f").position.y = .5, CM(this, ES, "f").update()), _M(this, YS, CM(this, BE, "m", kM).call(this), "f"), null != CM(this, YS, "f")) { const e = vb(CM(this, qS, "f"), CM(this, XS, "f")), t = new yn(CM(this, YS, "f").x * jb.partSize, CM(this, YS, "f").y * jb.partSize, CM(this, YS, "f").z * jb.partSize); CM(this, US, "f").position.copy(t), CM(this, US, "f").quaternion.copy(e), CM(this, US, "f").visible = !0 } else CM(this, US, "f").visible = !1; const e = CM(this, YS, "f"); if (null != e && null != CM(this, rM, "f")) { const n = CM(this, iM, "f")[CM(this, rM, "f")], i = CM(this, BE, "m", EM).call(this, e, n.tiles); if (null == n.id || CM(this, VS, "f")) i.length > 0 ? (CM(this, zS, "f").color.set(12255232), CM(this, OS, "f").color.set(12255232)) : (CM(this, zS, "f").color.set(12263970), CM(this, OS, "f").color.set(12263970)); else { let t, r; if (CM(this, JS, "f")) t = i.some((({ parts: t }) => t.some((t => t.id == n.id && t.x == e.x && t.y == e.y && t.z == e.z && t.rotation == CM(this, qS, "f") && t.rotationAxis == CM(this, XS, "f"))))), r = !1; else { t = !1; for (const { parts: a } of i) for (const i of a) { if (!CM(this, HE, "f").isPartCombinationAllowed({ id: n.id, x: e.x, y: e.y, z: e.z, rotation: CM(this, qS, "f"), rotationAxis: CM(this, XS, "f") }, { id: i.id, x: i.x, y: i.y, z: i.z, rotation: i.rotation, rotationAxis: i.rotationAxis })) { t = !0; break } r = !0 } } t ? (CM(this, zS, "f").color.set(12303104), CM(this, OS, "f").color.set(12303104)) : r ? (CM(this, zS, "f").color.set(48059), CM(this, OS, "f").color.set(48059)) : (CM(this, zS, "f").color.set(187), CM(this, OS, "f").color.set(187)) } if (CM(this, VS, "f")) CM(this, BE, "m", SM).call(this, i); else if (CM(this, HS, "f") || CM(this, QS, "f")) { if (null == n.id) CM(this, BE, "m", SM).call(this, i); else if (null == CM(this, $S, "f") || CM(this, $S, "f").x != e.x || CM(this, $S, "f").y != e.y || CM(this, $S, "f").z != e.z || CM(this, $S, "f").id != n.id || CM(this, $S, "f").rotation != CM(this, qS, "f") || CM(this, $S, "f").rotationAxis != CM(this, XS, "f")) { if (CM(this, JS, "f")) for (const { parts: t } of i) { const i = t.find((t => t.id == n.id && t.x == e.x && t.y == e.y && t.z == e.z && t.rotation == CM(this, qS, "f") && t.rotationAxis == CM(this, XS, "f"))); null != i && CM(this, VE, "f").deleteSpecificPart(i.id, i.x, i.y, i.z, i.rotation, i.rotationAxis) } else for (const { parts: t } of i) for (const i of t) CM(this, HE, "f").isPartCombinationAllowed({ id: n.id, x: e.x, y: e.y, z: e.z, rotation: CM(this, qS, "f"), rotationAxis: CM(this, XS, "f") }, { id: i.id, x: i.x, y: i.y, z: i.z, rotation: i.rotation, rotationAxis: i.rotationAxis }) || CM(this, VE, "f").deleteSpecificPart(i.id, i.x, i.y, i.z, i.rotation, i.rotationAxis); let r = null; n.isCheckpoint && (r = CM(this, sS, "f").checkpointOrder); let a = null; n.isStart && (a = CM(this, VE, "f").getNextStartOrder()), CM(this, VE, "f").setPart(e.x, e.y, e.z, n.id, CM(this, qS, "f"), CM(this, XS, "f"), CM(this, BE, "m", fM).call(this), r, a), CM(this, BE, "m", xM).call(this), _M(this, $S, { x: e.x, y: e.y, z: e.z, id: n.id, rotation: CM(this, qS, "f"), rotationAxis: CM(this, XS, "f") }, "f"), CM(this, VE, "f").generateMeshes(), null === (t = CM(this, nM, "f")) || void 0 === t || t.refresh(CM(this, VE, "f")), CM(this, sS, "f").setFromExistingCheckpoints(CM(this, VE, "f")), _M(this, DS, !1, "f") } _M(this, QS, !1, "f") } CM(this, US, "f").visible = !0 } else CM(this, US, "f").visible = !1 } } }; var IM, RM, LM, DM, NM, BM, UM, zM = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, OM = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; IM = new WeakMap, RM = new WeakMap, LM = new WeakMap, DM = new WeakMap, NM = new WeakMap, BM = new WeakMap, UM = new WeakMap; const FM = class { constructor(e, t, n, i, r, a, s, o, l, c, h, d, u, p, f, m, g) { IM.set(this, void 0), RM.set(this, void 0), LM.set(this, void 0), DM.set(this, void 0), NM.set(this, void 0), BM.set(this, void 0), UM.set(this, void 0), this.isPaused = !1, zM(this, IM, e, "f"), zM(this, RM, i, "f"), zM(this, LM, r, "f"), zM(this, DM, s, "f"), zM(this, NM, o, "f"), zM(this, BM, l, "f"), zM(this, UM, new PM(a, s, o, c, e, t, n, h, d, u, p, f, l, m), "f"), OM(this, UM, "f").enable(), OM(this, IM, "f").clear(), OM(this, IM, "f").setPart(0, 0, 0, eA.Start, 0, nA.YPositive, Jy.Default, null, 0), OM(this, IM, "f").generateMeshes(), o.setCamera(OM(this, UM, "f").camera), OM(this, UM, "f").setTestCallback((() => { var e; OM(this, UM, "f").disable(); const t = { name: null !== (e = OM(this, UM, "f").getTrackName()) && void 0 !== e ? e : a.get("Unnamed Track"), author: OM(this, UM, "f").trackAuthor }; g(t, OM(this, IM, "f").getTrackData(), (() => { OM(this, UM, "f").enable(), o.setCamera(OM(this, UM, "f").camera) })) })) } dispose() { OM(this, UM, "f").dispose(), OM(this, IM, "f").clear() } update(e) { this.isPaused || OM(this, UM, "f").update(e), OM(this, RM, "f").update(OM(this, IM, "f")), OM(this, LM, "f").update(e, OM(this, NM, "f").camera, OM(this, IM, "f").sunDirection), OM(this, DM, "f").update(e, !1, OM(this, NM, "f"), OM(this, BM, "f")), OM(this, NM, "f").update(new yn, OM(this, IM, "f").sunDirection) } }; var WM = n(5811), VM = {}; VM.styleTagTransform = u(), VM.setAttributes = l(), VM.insert = s().bind(null, "head"), VM.domAPI = r(), VM.insertStyleElement = h(); t()(WM.A, VM); WM.A && WM.A.locals && WM.A.locals; var HM, GM, jM, QM, YM, KM, qM = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, XM = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; HM = new WeakMap, GM = new WeakMap, jM = new WeakMap, QM = new WeakMap, YM = new WeakMap, KM = new WeakMap; const ZM = class { constructor(e, t) { HM.set(this, void 0), GM.set(this, void 0), jM.set(this, void 0), QM.set(this, void 0), YM.set(this, void 0), KM.set(this, null), qM(this, HM, t, "f"), qM(this, GM, e, "f"); const n = document.getElementById("ui"); if (null == n) throw new Error("UI element not found"); qM(this, jM, n, "f"), qM(this, QM, document.createElement("div"), "f"), 0 == XM(this, GM, "f") || "off" == t.getSetting($o.Checkpoints) ? "top" == t.getSetting($o.Checkpoints) ? XM(this, QM, "f").className = "checkpoint up" : XM(this, QM, "f").className = "checkpoint" : XM(this, QM, "f").className = "hidden", XM(this, jM, "f").appendChild(XM(this, QM, "f")); const i = document.createElement("div"); XM(this, QM, "f").appendChild(i); const r = document.createElement("img"); r.src = "images/checkpoint.svg", i.appendChild(r), qM(this, YM, document.createElement("span"), "f"), i.appendChild(XM(this, YM, "f")) } dispose() { XM(this, jM, "f").removeChild(XM(this, QM, "f")) } setOverridePosition(e) { const t = XM(this, HM, "f").getSetting($o.Checkpoints); 0 == XM(this, GM, "f") || "off" == t ? XM(this, QM, "f").className = "hidden" : XM(this, QM, "f").className = (null != e ? e : "top" == t) ? "checkpoint up" : "checkpoint" } update(e) { const t = e.getNextCheckpointIndex().toString() + "/" + XM(this, GM, "f").toString(); t != XM(this, KM, "f") && (XM(this, YM, "f").textContent = t, qM(this, KM, t, "f")) } }; var JM = n(8229), $M = {}; $M.styleTagTransform = u(), $M.setAttributes = l(), $M.insert = s().bind(null, "head"), $M.domAPI = r(), $M.insertStyleElement = h(); t()(JM.A, $M); JM.A && JM.A.locals && JM.A.locals; var eT, tT, nT, iT, rT, aT, sT, oT, lT, cT, hT, dT, uT, pT = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, fT = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; tT = new WeakMap, nT = new WeakMap, iT = new WeakMap, rT = new WeakMap, aT = new WeakMap, sT = new WeakMap, oT = new WeakMap, lT = new WeakMap, cT = new WeakMap, eT = new WeakSet, hT = function(e, t) { fT(this, sT, "f").textContent = e, fT(this, oT, "f").textContent = t, fT(this, aT, "f").className = "hint show" }, dT = function() { pT(this, lT, 2.5, "f"), fT(this, aT, "f").className = "hint hide" }, uT = function() { pT(this, lT, 2.5, "f"), fT(this, aT, "f").className = "hint" }; const mT = class { constructor(e, t, n) { eT.add(this), tT.set(this, void 0), nT.set(this, void 0), iT.set(this, void 0), rT.set(this, void 0), aT.set(this, void 0), sT.set(this, void 0), oT.set(this, void 0), lT.set(this, 2.5), cT.set(this, void 0), pT(this, tT, e, "f"), pT(this, nT, t, "f"), pT(this, iT, n, "f"); const i = document.getElementById("ui"); if (null == i) throw new Error("UI element not found"); pT(this, rT, i, "f"), pT(this, aT, document.createElement("div"), "f"), fT(this, aT, "f").className = "hint", fT(this, rT, "f").appendChild(fT(this, aT, "f")), pT(this, sT, document.createElement("div"), "f"), fT(this, sT, "f").className = "title", fT(this, aT, "f").appendChild(fT(this, sT, "f")), pT(this, oT, document.createElement("div"), "f"), fT(this, oT, "f").className = "subtitle", fT(this, aT, "f").appendChild(fT(this, oT, "f")), pT(this, cT, (() => { fT(this, eT, "m", uT).call(this) }), "f"), fT(this, nT, "f").addChangeListener(fT(this, cT, "f")) } dispose() { fT(this, rT, "f").removeChild(fT(this, aT, "f")), fT(this, nT, "f").removeChangeListener(fT(this, cT, "f")) } update(e, t) { if (e.hasStarted() && !e.getControls().reset && fT(this, iT, "f").getSettingBoolean($o.ResetHintEnabled)) if (e.getSpeedKmh() < 50 || e.hasFinished()) { if (0 != fT(this, lT, "f") && (pT(this, lT, fT(this, lT, "f") - t, "f"), fT(this, lT, "f") <= 0)) { if (fT(this, nT, "f").touchEnabled) fT(this, eT, "m", hT).call(this, fT(this, tT, "f").get("Reset once to return to the last checkpoint"), fT(this, tT, "f").get("Reset again to start over")); else { const e = fT(this, iT, "f").getKeyBindings(Ix.VehicleCheckpointReset).filter((e => null != e)), t = fT(this, iT, "f").getKeyBindings(Ix.VehicleStartReset).filter((e => null != e)); let n = ""; e.length > 0 && (n = fT(this, tT, "f").get("Press {0} to return to the last checkpoint", [e.map((e => "[" + e + "]")).join(" / ")])); let i = ""; t.length > 0 && (i = fT(this, tT, "f").get("Press {0} to start over", [t.map((e => "[" + e + "]")).join(" / ")])), "" != n && "" != i ? fT(this, eT, "m", hT).call(this, n, i) : "" != n ? fT(this, eT, "m", hT).call(this, n, "") : "" != i && fT(this, eT, "m", hT).call(this, i, "") } pT(this, lT, 0, "f") } } else fT(this, eT, "m", dT).call(this); else fT(this, eT, "m", uT).call(this) } }; var gT = n(5151), vT = {}; vT.styleTagTransform = u(), vT.setAttributes = l(), vT.insert = s().bind(null, "head"), vT.domAPI = r(), vT.insertStyleElement = h(); t()(gT.A, vT); gT.A && gT.A.locals && gT.A.locals; var wT, yT, AT, bT, xT, kT, ET, ST = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, MT = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; wT = new WeakMap, yT = new WeakMap, AT = new WeakMap, bT = new WeakMap, xT = new WeakMap, kT = new WeakMap, ET = new WeakMap; const TT = class { constructor(e) { wT.set(this, void 0), yT.set(this, void 0), AT.set(this, void 0), bT.set(this, void 0), xT.set(this, void 0), kT.set(this, null), ET.set(this, void 0), ST(this, wT, e, "f"), ST(this, ET, e.getSettingBoolean($o.ImperialUnitsEnabled), "f"); const t = document.getElementById("ui"); if (null == t) throw new Error("UI element not found"); ST(this, yT, t, "f"), ST(this, AT, document.createElement("div"), "f"), "off" == e.getSetting($o.Speedometer) ? MT(this, AT, "f").className = "speedometer hidden" : "top" == e.getSetting($o.Speedometer) ? MT(this, AT, "f").className = "speedometer up" : MT(this, AT, "f").className = "speedometer", MT(this, yT, "f").appendChild(MT(this, AT, "f")); const n = document.createElement("div"); MT(this, AT, "f").appendChild(n), ST(this, bT, document.createElement("span"), "f"), MT(this, bT, "f").textContent = "0", n.appendChild(MT(this, bT, "f")), ST(this, xT, document.createElement("span"), "f"), MT(this, ET, "f") ? MT(this, xT, "f").textContent = "mph" : MT(this, xT, "f").textContent = "km/h", n.appendChild(MT(this, xT, "f")) } dispose() { MT(this, yT, "f").removeChild(MT(this, AT, "f")) } setOverridePosition(e) { const t = MT(this, wT, "f").getSetting($o.Speedometer); MT(this, AT, "f").className = "off" == t ? "speedometer hidden" : (null != e ? e : "top" == t) ? "speedometer up" : "speedometer" } update(e) { const t = Math.abs(e.getSpeedKmh()); let n; n = MT(this, ET, "f") ? t / 1.609344 : t; const i = Math.trunc(n).toString(); if (i != MT(this, kT, "f")) { MT(this, bT, "f").innerHTML = ""; for (const e of i) { const t = document.createElement("span"); t.textContent = e, MT(this, bT, "f").appendChild(t) } ST(this, kT, i, "f") } } }; var _T = n(2817), CT = {}; CT.styleTagTransform = u(), CT.setAttributes = l(), CT.insert = s().bind(null, "head"), CT.domAPI = r(), CT.insertStyleElement = h(); t()(_T.A, CT); _T.A && _T.A.locals && _T.A.locals; var PT, IT, RT, LT, DT, NT, BT, UT, zT, OT, FT = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, WT = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; PT = new WeakMap, IT = new WeakMap, RT = new WeakMap, LT = new WeakMap, DT = new WeakMap, NT = new WeakMap, BT = new WeakMap, UT = new WeakMap, zT = new WeakMap, OT = new WeakMap; const VT = class { constructor(e, t, n, i, r) { PT.set(this, void 0), IT.set(this, void 0), RT.set(this, void 0), LT.set(this, void 0), DT.set(this, void 0), NT.set(this, void 0), BT.set(this, void 0), UT.set(this, void 0), zT.set(this, void 0), OT.set(this, void 0); const a = document.getElementById("ui"); if (null == a) throw new Error("UI element not found"); if (FT(this, PT, a, "f"), FT(this, IT, document.createElement("div"), "f"), WT(this, IT, "f").className = "time-announcer", FT(this, RT, document.createElement("div"), "f"), WT(this, RT, "f").className = "hidden", WT(this, RT, "f").textContent = e.get("New record"), WT(this, IT, "f").appendChild(WT(this, RT, "f")), FT(this, LT, document.createElement("div"), "f"), WT(this, LT, "f").className = "track-name", WT(this, LT, "f").textContent = t, WT(this, IT, "f").appendChild(WT(this, LT, "f")), FT(this, DT, document.createElement("div"), "f"), WT(this, DT, "f").className = "current", WT(this, IT, "f").appendChild(WT(this, DT, "f")), FT(this, NT, document.createElement("div"), "f"), WT(this, IT, "f").appendChild(WT(this, NT, "f")), FT(this, BT, document.createElement("p"), "f"), WT(this, NT, "f").appendChild(WT(this, BT, "f")), FT(this, UT, document.createElement("div"), "f"), WT(this, IT, "f").appendChild(WT(this, UT, "f")), FT(this, zT, document.createElement("p"), "f"), WT(this, zT, "f").className = "title", WT(this, UT, "f").appendChild(WT(this, zT, "f")), FT(this, OT, document.createElement("p"), "f"), WT(this, UT, "f").appendChild(WT(this, OT, "f")), WT(this, PT, "f").appendChild(WT(this, IT, "f")), WT(this, DT, "f").textContent = fk.formatTimeString(n), null == i) WT(this, RT, "f").className = "record", WT(this, NT, "f").className = "hidden"; else { const e = n.difference(i); WT(this, BT, "f").textContent = fk.formatTimeString(e, !0), e.isNegative() ? (WT(this, RT, "f").className = "record", WT(this, NT, "f").className = "difference") : (WT(this, RT, "f").className = "hidden", WT(this, NT, "f").className = "difference red") } if (null == r) WT(this, UT, "f").className = "hidden"; else { const e = n.difference(r.record); WT(this, zT, "f").textContent = r.name, WT(this, OT, "f").textContent = fk.formatTimeString(e, !0), e.isNegative() ? WT(this, UT, "f").className = "difference" : WT(this, UT, "f").className = "difference red" } } dispose() { WT(this, PT, "f").removeChild(WT(this, IT, "f")) } }; var HT, GT, jT, QT, YT, KT, qT, XT, ZT, JT, $T, e_, t_, n_, i_, r_ = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, a_ = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; HT = new WeakMap, GT = new WeakMap, jT = new WeakMap, QT = new WeakMap, YT = new WeakMap, KT = new WeakMap, qT = new WeakMap, XT = new WeakMap, ZT = new WeakMap, JT = new WeakMap, $T = new WeakMap, e_ = new WeakMap, t_ = new WeakMap, n_ = new WeakMap, i_ = new WeakMap; const s_ = class { constructor(e, t) { HT.set(this, void 0), GT.set(this, void 0), jT.set(this, !1), QT.set(this, []), YT.set(this, void 0), KT.set(this, void 0), qT.set(this, void 0), XT.set(this, void 0), ZT.set(this, void 0), JT.set(this, void 0), $T.set(this, !1), e_.set(this, !1), t_.set(this, !1), n_.set(this, !1), i_.set(this, !1), r_(this, HT, e, "f"), r_(this, GT, new Pr(70, 1, .5, Au.maxViewDistance), "f"), a_(this, GT, "f").position.set(0, 20, 0), window.addEventListener("keydown", r_(this, YT, (e => { t.checkKeyBinding(e, Ix.SpectatorMoveForwards) ? (r_(this, $T, !0, "f"), e.preventDefault()) : t.checkKeyBinding(e, Ix.SpectatorMoveRight) ? (r_(this, e_, !0, "f"), e.preventDefault()) : t.checkKeyBinding(e, Ix.SpectatorMoveBackwards) ? (r_(this, t_, !0, "f"), e.preventDefault()) : t.checkKeyBinding(e, Ix.SpectatorMoveLeft) ? (r_(this, n_, !0, "f"), e.preventDefault()) : t.checkKeyBinding(e, Ix.SpectatorSpeedModifier) && (r_(this, i_, !0, "f"), e.preventDefault()) }), "f")), window.addEventListener("keyup", r_(this, KT, (e => { t.checkKeyBinding(e, Ix.SpectatorMoveForwards) ? r_(this, $T, !1, "f") : t.checkKeyBinding(e, Ix.SpectatorMoveRight) ? r_(this, e_, !1, "f") : t.checkKeyBinding(e, Ix.SpectatorMoveBackwards) ? r_(this, t_, !1, "f") : t.checkKeyBinding(e, Ix.SpectatorMoveLeft) ? r_(this, n_, !1, "f") : t.checkKeyBinding(e, Ix.SpectatorSpeedModifier) && r_(this, i_, !1, "f") }), "f")); let n = !1, i = { x: 0, y: 0 }, r = 0, a = 0; e.canvas.addEventListener("mousedown", r_(this, qT, (e => { n = !0; const t = (new ai).setFromQuaternion(a_(this, GT, "f").quaternion, "YXZ"); r = t.y, a = t.x, i = { x: e.clientX, y: e.clientY } }), "f")), window.addEventListener("mouseup", r_(this, XT, (() => { n = !1 }), "f")), window.addEventListener("mousemove", r_(this, ZT, (e => { if (n) { const t = Math.max(window.innerWidth, window.innerHeight), n = (e.clientX - i.x) / t, s = (e.clientY - i.y) / t; i = { x: e.clientX, y: e.clientY }; const o = 10; r -= n * o, a -= s * o, r %= 2 * Math.PI, a = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, a)), r = Math.round(1e4 * r) / 1e4, a = Math.round(1e4 * a) / 1e4; const l = (new wn).setFromAxisAngle(new yn(1, 0, 0), a), c = (new wn).setFromAxisAngle(new yn(0, 1, 0), r); a_(this, GT, "f").quaternion.copy(c).multiply(l) } }), "f")), window.addEventListener("contextmenu", r_(this, JT, (e => { a_(this, jT, "f") && e.preventDefault() }), "f")) } dispose() { window.removeEventListener("keydown", a_(this, YT, "f")), window.removeEventListener("keyup", a_(this, KT, "f")), a_(this, HT, "f").canvas.removeEventListener("mousedown", a_(this, qT, "f")), window.removeEventListener("mouseup", a_(this, XT, "f")), window.removeEventListener("mousemove", a_(this, ZT, "f")), window.removeEventListener("contextmenu", a_(this, JT, "f")) } addToggleListener(e) { a_(this, QT, "f").push(e) } get isEnabled() { return a_(this, jT, "f") } set isEnabled(e) { if (a_(this, jT, "f") != e) { r_(this, jT, e, "f"); for (const e of a_(this, QT, "f")) e(a_(this, jT, "f")) } } toggle() { this.isEnabled = !a_(this, jT, "f") } update(e) { if (a_(this, jT, "f")) { let t; if (t = a_(this, i_, "f") ? 400 * e : 50 * e, a_(this, $T, "f")) { const e = new yn(0, 0, -1).applyQuaternion(a_(this, GT, "f").quaternion); a_(this, GT, "f").position.add(e.multiplyScalar(t)) } if (a_(this, e_, "f")) { const e = new yn(1, 0, 0).applyQuaternion(a_(this, GT, "f").quaternion); a_(this, GT, "f").position.add(e.multiplyScalar(t)) } if (a_(this, t_, "f")) { const e = new yn(0, 0, 1).applyQuaternion(a_(this, GT, "f").quaternion); a_(this, GT, "f").position.add(e.multiplyScalar(t)) } if (a_(this, n_, "f")) { const e = new yn(-1, 0, 0).applyQuaternion(a_(this, GT, "f").quaternion); a_(this, GT, "f").position.add(e.multiplyScalar(t)) } } } get camera() { return a_(this, GT, "f") } }; var o_ = n(3571), l_ = {}; l_.styleTagTransform = u(), l_.setAttributes = l(), l_.insert = s().bind(null, "head"), l_.domAPI = r(), l_.insertStyleElement = h(); t()(o_.A, l_); o_.A && o_.A.locals && o_.A.locals; var c_, h_, d_, u_ = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, p_ = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; c_ = new WeakMap, h_ = new WeakMap, d_ = new WeakMap; const f_ = class { constructor(e, t, n) { c_.set(this, void 0), h_.set(this, void 0), d_.set(this, void 0); const i = document.getElementById("ui"); if (null == i) throw new Error("UI element not found"); u_(this, c_, i, "f"), u_(this, h_, document.createElement("div"), "f"), p_(this, h_, "f").className = "hidden", p_(this, c_, "f").appendChild(p_(this, h_, "f")); const r = document.createElement("button"); r.className = "reset", r.innerHTML = '', r.addEventListener("touchstart", (() => { t.playUIClick(), r.classList.add("active"), n() })), r.addEventListener("touchend", (() => { r.classList.remove("active") })), p_(this, h_, "f").appendChild(r); const a = document.createElement("div"); a.className = "left-container", p_(this, h_, "f").appendChild(a); const s = document.createElement("div"); s.innerHTML = '', a.appendChild(s); const o = document.createElement("div"); o.innerHTML = '', a.appendChild(o); const l = document.createElement("div"); l.className = "right-container", p_(this, h_, "f").appendChild(l); const c = document.createElement("div"); c.innerHTML = '', l.appendChild(c); const h = document.createElement("div"); h.innerHTML = '', l.appendChild(h), u_(this, d_, (t => { let n = !1, i = !1, r = !1, a = !1; for (let e = 0; e < t.touches.length; e++) { const l = t.touches.item(e); if (null != l) { switch (document.elementFromPoint(l.clientX, l.clientY)) { case s: n = !0; break; case h: i = !0; break; case o: r = !0; break; case c: a = !0 } } } e.up = n, e.right = i, e.down = r, e.left = a, s.className = n ? "active" : "", h.className = i ? "active" : "", o.className = r ? "active" : "", c.className = a ? "active" : "", t.target instanceof HTMLButtonElement || t.preventDefault() }), "f"), window.addEventListener("touchstart", p_(this, d_, "f"), { passive: !1 }), window.addEventListener("touchmove", p_(this, d_, "f"), { passive: !1 }), window.addEventListener("touchend", p_(this, d_, "f"), { passive: !1 }) } setEnabled(e) { p_(this, h_, "f").className = e ? "touch-controls" : "hidden" } dispose() { p_(this, c_, "f").removeChild(p_(this, h_, "f")), window.removeEventListener("touchstart", p_(this, d_, "f")), window.removeEventListener("touchmove", p_(this, d_, "f")), window.removeEventListener("touchend", p_(this, d_, "f")) } }; var m_, g_, v_, w_, y_, A_, b_, x_, k_ = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, E_ = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; m_ = new WeakMap, g_ = new WeakMap, v_ = new WeakMap, w_ = new WeakMap, y_ = new WeakMap, A_ = new WeakMap, b_ = new WeakMap, x_ = new WeakMap; const S_ = class { constructor(e) { m_.set(this, !1), g_.set(this, !1), v_.set(this, !1), w_.set(this, !1), y_.set(this, !1), A_.set(this, void 0), b_.set(this, void 0), x_.set(this, []), window.addEventListener("keydown", k_(this, A_, (t => { e.checkKeyBinding(t, Ix.VehicleAccelerate) ? (this.up = !0, t.preventDefault()) : e.checkKeyBinding(t, Ix.VehicleTurnRight) ? (this.right = !0, t.preventDefault()) : e.checkKeyBinding(t, Ix.VehicleBrake) ? (this.down = !0, t.preventDefault()) : e.checkKeyBinding(t, Ix.VehicleTurnLeft) && (this.left = !0, t.preventDefault()) }), "f")), window.addEventListener("keyup", k_(this, b_, (t => { e.checkKeyBinding(t, Ix.VehicleAccelerate) ? this.up = !1 : e.checkKeyBinding(t, Ix.VehicleTurnRight) ? this.right = !1 : e.checkKeyBinding(t, Ix.VehicleBrake) ? this.down = !1 : e.checkKeyBinding(t, Ix.VehicleTurnLeft) && (this.left = !1) }), "f")) } get up() { return E_(this, m_, "f") } set up(e) { if (E_(this, m_, "f") != e) { k_(this, m_, e, "f"); for (const e of E_(this, x_, "f")) e(this) } } get right() { return E_(this, g_, "f") } set right(e) { if (E_(this, g_, "f") != e) { k_(this, g_, e, "f"); for (const e of E_(this, x_, "f")) e(this) } } get down() { return E_(this, v_, "f") } set down(e) { if (E_(this, v_, "f") != e) { k_(this, v_, e, "f"); for (const e of E_(this, x_, "f")) e(this) } } get left() { return E_(this, w_, "f") } set left(e) { if (E_(this, w_, "f") != e) { k_(this, w_, e, "f"); for (const e of E_(this, x_, "f")) e(this) } } get reset() { return E_(this, y_, "f") } set reset(e) { if (E_(this, y_, "f") != e) { k_(this, y_, e, "f"); for (const e of E_(this, x_, "f")) e(this) } } addChangeCallback(e) { E_(this, x_, "f").push(e) } removeChangeCallback(e) { const t = E_(this, x_, "f").indexOf(e); t >= 0 && E_(this, x_, "f").splice(t, 1) } dispose() { window.removeEventListener("keydown", E_(this, A_, "f")), window.removeEventListener("keyup", E_(this, b_, "f")) } getControls() { return { up: this.up, right: this.right, down: this.down, left: this.left, reset: this.reset } } }; var M_, T_ = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; M_ = new WeakMap; const __ = class { constructor() { M_.set(this, []) } push(e) { if (T_(this, M_, "f").length > 0) { if (e.frames != T_(this, M_, "f")[T_(this, M_, "f").length - 1].frames + 1) throw new Error("Car states are not continuous") } else if (e.frames > 0) throw new Error("First frame must be zero"); T_(this, M_, "f").push(e) } getFrame(e) { return e >= 0 && e < T_(this, M_, "f").length ? T_(this, M_, "f")[e] : null } getLastFrame() { return 0 == T_(this, M_, "f").length ? new xp(0) : new xp(T_(this, M_, "f")[T_(this, M_, "f").length - 1].frames) } }; var C_ = n(4804), P_ = {}; P_.styleTagTransform = u(), P_.setAttributes = l(), P_.insert = s().bind(null, "head"), P_.domAPI = r(), P_.insertStyleElement = h(); t()(C_.A, P_); C_.A && C_.A.locals && C_.A.locals; var I_, R_, L_, D_, N_, B_, U_, z_, O_, F_ = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, W_ = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; R_ = new WeakMap, L_ = new WeakMap, D_ = new WeakMap, N_ = new WeakMap, B_ = new WeakMap, U_ = new WeakMap, z_ = new WeakMap, I_ = new WeakSet, O_ = function() { "top" == W_(this, L_, "f").getSetting($o.Checkpoints) || W_(this, D_, "f").touchEnabled ? W_(this, N_, "f").classList.remove("up") : W_(this, N_, "f").classList.add("up"), W_(this, D_, "f").touchEnabled ? W_(this, N_, "f").classList.add("touch") : W_(this, N_, "f").classList.remove("touch") }; const V_ = class { constructor(e, t, n, i, r, a) { I_.add(this), R_.set(this, void 0), L_.set(this, void 0), D_.set(this, void 0), N_.set(this, void 0), B_.set(this, void 0), U_.set(this, !0), z_.set(this, void 0), F_(this, L_, n, "f"), F_(this, D_, i, "f"); const s = document.getElementById("ui"); if (null == s) throw new Error("UI element not found"); F_(this, R_, s, "f"), F_(this, N_, document.createElement("div"), "f"), W_(this, N_, "f").className = "game-toolbar visible", W_(this, I_, "m", O_).call(this), W_(this, D_, "f").addChangeListener(F_(this, z_, (() => { W_(this, I_, "m", O_).call(this) }), "f")); const o = document.createElement("button"); o.className = "button", o.innerHTML = ' ', o.append(document.createTextNode(t.get("Exit"))), o.addEventListener("click", (() => { e.playUIClick(), r() })), W_(this, N_, "f").appendChild(o), F_(this, B_, document.createElement("button"), "f"), W_(this, B_, "f").className = "button", W_(this, B_, "f").innerHTML = ' ', W_(this, B_, "f").append(document.createTextNode(t.get("Watch"))), W_(this, B_, "f").addEventListener("click", (() => { e.playUIClick(), a() })), W_(this, N_, "f").appendChild(W_(this, B_, "f")), W_(this, R_, "f").appendChild(W_(this, N_, "f")) } dispose() { W_(this, R_, "f").removeChild(W_(this, N_, "f")), W_(this, D_, "f").removeChangeListener(W_(this, z_, "f")) } setWatchButtonEnabled(e) { W_(this, B_, "f").disabled = !e } setVisible(e) { W_(this, U_, "f") != e && (e ? W_(this, N_, "f").classList.add("visible") : W_(this, N_, "f").classList.remove("visible"), W_(this, N_, "f").inert = !e, F_(this, U_, e, "f")) } }; var H_, G_ = function(e, t, n, i) { return new(n || (n = Promise))((function(r, a) { function s(e) { try { l(i.next(e)) } catch (e) { a(e) } } function o(e) { try { l(i.throw(e)) } catch (e) { a(e) } } function l(e) { var t; e.done ? r(e.value) : (t = e.value, t instanceof n ? t : new n((function(e) { e(t) }))).then(s, o) } l((i = i.apply(e, t || [])).next()) })) }; ! function(e) { e[e.Loading = 0] = "Loading", e[e.Error = 1] = "Error", e[e.Ready = 2] = "Ready" }(H_ || (H_ = {})); let j_ = H_.Loading, Q_ = !1, Y_ = !1; function K_() { return G_(this, void 0, void 0, (function*() { try { j_ = H_.Ready } catch (e) { j_ = H_.Error, console.error(e) } })) } function q_() { if (j_ == H_.Ready && !Q_) try { window.CrazyGames ? window.CrazyGames.SDK.game.gameplayStart() : window.PokiSDK ? window.PokiSDK.gameplayStart() : window.adsbygoogle, Q_ = !0 } catch (e) { console.error(e) } } function X_() { if (j_ == H_.Ready && Q_) try { window.CrazyGames ? window.CrazyGames.SDK.game.gameplayStop() : window.PokiSDK ? window.PokiSDK.gameplayStop() : window.adsbygoogle, Q_ = !1 } catch (e) { console.error(e) } } function Z_() { if (j_ == H_.Ready && !Y_) try { window.CrazyGames ? window.CrazyGames.SDK.game.loadingStart() : window.PokiSDK || window.adsbygoogle, Y_ = !0 } catch (e) { console.error(e) } } function J_() { if (j_ == H_.Ready && Y_) try { window.CrazyGames ? window.CrazyGames.SDK.game.loadingStop() : window.PokiSDK || window.adsbygoogle, Y_ = !1 } catch (e) { console.error(e) } } function $_() { if (j_ == H_.Ready) try { window.CrazyGames ? window.CrazyGames.SDK.game.loadingStop() : window.PokiSDK ? window.PokiSDK.gameLoadingFinished() : window.adsbygoogle } catch (e) { console.error(e) } } function eC(e, t) { return G_(this, void 0, void 0, (function*() { if (j_ == H_.Ready) try { if (window.CrazyGames) { const t = window.CrazyGames; yield new Promise(((n, i) => { t.SDK.ad.requestAd("midgame", { adFinished: n, adError: i, adStarted: e }) })) } else if (window.PokiSDK) yield window.PokiSDK.commercialBreak(); else if (window.adsbygoogle) { const n = window.adsbygoogle; yield new Promise((i => { n.push({ type: "start", name: t, beforeAd: e, adBreakDone: i }) })) } } catch (e) { throw console.error(e), e } })) } var tC = n(4538), nC = {}; nC.styleTagTransform = u(), nC.setAttributes = l(), nC.insert = s().bind(null, "head"), nC.domAPI = r(), nC.insertStyleElement = h(); t()(tC.A, nC); tC.A && tC.A.locals && tC.A.locals; var iC, rC, aC, sC = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, oC = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; iC = new WeakMap, rC = new WeakMap, aC = new WeakMap; const lC = class { constructor(e) { iC.set(this, void 0), rC.set(this, void 0), aC.set(this, !1); const t = document.getElementById("ui"); if (null == t) throw new Error("UI element not found"); sC(this, iC, t, "f"), sC(this, rC, document.createElement("div"), "f"), oC(this, rC, "f").className = "pause-screen", oC(this, iC, "f").appendChild(oC(this, rC, "f")); const n = document.createElement("div"); n.className = "title", n.textContent = e.get("Paused"), oC(this, rC, "f").appendChild(n) } dispose() { oC(this, iC, "f").removeChild(oC(this, rC, "f")) } startFadeOut(e) { oC(this, aC, "f") || (sC(this, aC, !0, "f"), oC(this, rC, "f").classList.add("fade-out"), setTimeout(e, 250)) } }; var cC = n(4239), hC = {}; hC.styleTagTransform = u(), hC.setAttributes = l(), hC.insert = s().bind(null, "head"), hC.domAPI = r(), hC.insertStyleElement = h(); t()(cC.A, hC); cC.A && cC.A.locals && cC.A.locals; var dC, uC, pC, fC, mC = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, gC = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; dC = new WeakMap, uC = new WeakMap, pC = new WeakMap, fC = new WeakMap; const vC = class { constructor(e, t) { dC.set(this, void 0), uC.set(this, void 0), pC.set(this, void 0), fC.set(this, void 0), mC(this, dC, t, "f"); const n = document.getElementById("ui"); if (null == n) throw new Error("UI element not found"); mC(this, uC, n, "f"), mC(this, pC, document.createElement("div"), "f"), gC(this, pC, "f").className = "ghost-loading-ui", gC(this, pC, "f").textContent = e.get("Loading replay"), gC(this, uC, "f").appendChild(gC(this, pC, "f")), mC(this, fC, document.createElement("span"), "f"), gC(this, fC, "f").className = "percentage", gC(this, pC, "f").appendChild(gC(this, fC, "f")), this.update(1) } dispose() { gC(this, uC, "f").removeChild(gC(this, pC, "f")) } setOverridePosition(e) { const t = gC(this, dC, "f").getSetting($o.Speedometer); (null != e ? e : "top" == t) ? gC(this, pC, "f").classList.add("down"): gC(this, pC, "f").classList.remove("down") } update(e) { gC(this, fC, "f").textContent = Math.floor(100 * e).toString() + "%", e >= 1 ? gC(this, pC, "f").classList.add("hide") : gC(this, pC, "f").classList.remove("hide") } }; new WeakMap, new WeakMap, new WeakMap, new WeakMap, new WeakMap, new WeakMap; var wC, yC, AC, bC, xC, kC, EC, SC, MC, TC, _C, CC, PC, IC, RC, LC, DC, NC, BC, UC, zC, OC, FC, WC, VC, HC, GC, jC, QC, YC, KC, qC, XC, ZC, JC, $C, eP, tP, nP, iP, rP, aP, sP, oP, lP, cP, hP, dP, uP, pP, fP, mP, gP, vP, wP = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, yP = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; yC = new WeakMap, AC = new WeakMap, bC = new WeakMap, xC = new WeakMap, kC = new WeakMap, EC = new WeakMap, SC = new WeakMap, MC = new WeakMap, TC = new WeakMap, _C = new WeakMap, CC = new WeakMap, PC = new WeakMap, IC = new WeakMap, RC = new WeakMap, LC = new WeakMap, DC = new WeakMap, NC = new WeakMap, BC = new WeakMap, UC = new WeakMap, zC = new WeakMap, OC = new WeakMap, FC = new WeakMap, WC = new WeakMap, VC = new WeakMap, HC = new WeakMap, GC = new WeakMap, jC = new WeakMap, QC = new WeakMap, YC = new WeakMap, KC = new WeakMap, qC = new WeakMap, XC = new WeakMap, ZC = new WeakMap, JC = new WeakMap, $C = new WeakMap, eP = new WeakMap, tP = new WeakMap, nP = new WeakMap, iP = new WeakMap, rP = new WeakMap, aP = new WeakMap, sP = new WeakMap, oP = new WeakMap, lP = new WeakMap, cP = new WeakMap, hP = new WeakMap, wC = new WeakSet, dP = function(e) { var t, n, i, r, a, s, o, l, c; if (e) { const e = yP(this, wC, "m", mP).call(this); wP(this, OC, new mT(yP(this, EC, "f"), yP(this, IC, "f"), yP(this, _C, "f")), "f"), wP(this, FC, new vC(yP(this, EC, "f"), yP(this, _C, "f")), "f"), wP(this, WC, new ZM(yP(this, bC, "f").getTotalNumberOfCheckpointIndices(), yP(this, _C, "f")), "f"), wP(this, VC, new TT(yP(this, _C, "f")), "f"), wP(this, HC, new fk(yP(this, EC, "f"), yP(this, _C, "f")), "f"), null == e || e.settings.isSelf || (yP(this, HC, "f").nickname = e.settings.name), wP(this, jC, new V_(yP(this, MC, "f"), yP(this, EC, "f"), yP(this, _C, "f"), yP(this, IC, "f"), yP(this, LC, "f"), (() => { yP(this, tP, "f").length > 0 && null != yP(this, DC, "f") && yP(this, DC, "f").call(this, yP(this, NC, "f"), yP(this, BC, "f"), yP(this, UC, "f"), yP(this, tP, "f").map((e => e.settings))) })), "f"), yP(this, jC, "f").setWatchButtonEnabled(yP(this, tP, "f").length > 0 && null != yP(this, DC, "f")), yP(this, jC, "f").setVisible(!(null !== (n = null === (t = yP(this, eP, "f")) || void 0 === t ? void 0 : t.hasStarted()) && void 0 !== n && n)), yP(this, IC, "f").touchEnabled ? (yP(this, FC, "f").setOverridePosition(!0), yP(this, WC, "f").setOverridePosition(!0), yP(this, HC, "f").setOverridePosition(!0), yP(this, VC, "f").setOverridePosition(!0)) : (yP(this, FC, "f").setOverridePosition(null), yP(this, WC, "f").setOverridePosition(null), yP(this, HC, "f").setOverridePosition(null), yP(this, VC, "f").setOverridePosition(null)), yP(this, qC, "f").setEnabled(yP(this, IC, "f").touchEnabled), yP(this, wC, "m", vP).call(this) } else null === (i = yP(this, OC, "f")) || void 0 === i || i.dispose(), wP(this, OC, null, "f"), null === (r = yP(this, FC, "f")) || void 0 === r || r.dispose(), wP(this, FC, null, "f"), null === (a = yP(this, WC, "f")) || void 0 === a || a.dispose(), wP(this, WC, null, "f"), null === (s = yP(this, VC, "f")) || void 0 === s || s.dispose(), wP(this, VC, null, "f"), null === (o = yP(this, HC, "f")) || void 0 === o || o.dispose(), wP(this, HC, null, "f"), null === (l = yP(this, GC, "f")) || void 0 === l || l.dispose(), wP(this, GC, null, "f"), null === (c = yP(this, jC, "f")) || void 0 === c || c.dispose(), wP(this, jC, null, "f") }, uP = function() { var e; yP(this, cP, "f") || ((null === (e = yP(this, eP, "f")) || void 0 === e ? void 0 : e.hasFinished()) ? (wP(this, cP, !0, "f"), eC((() => { yP(this, MC, "f").mute() }), "game-finish-reset").finally((() => { wP(this, cP, !1, "f"), yP(this, MC, "f").unmute(), yP(this, wC, "m", pP).call(this), yP(this, wC, "m", fP).call(this) })).catch((e => { console.error(e) }))) : (yP(this, wC, "m", pP).call(this), yP(this, wC, "m", fP).call(this))) }, pP = function() { var e, t; const n = yP(this, TC, "f").getCurrentUserProfile(); let i = !1; null != yP(this, eP, "f") ? (i = yP(this, SC, "f").camera == yP(this, eP, "f").cameraCockpit, yP(this, wC, "m", vP).call(this), yP(this, eP, "f").dispose(), wP(this, eP, null, "f")) : i = yP(this, _C, "f").getSettingBoolean($o.DefaultCameraMode); const r = yP(this, bC, "f").getStartTransform(); if (null == r) throw new Error("Start transform is null"); wP(this, eP, new Aw(yP(this, yC, "f"), r, null, yP(this, JC, "f"), yP(this, SC, "f"), yP(this, MC, "f"), yP(this, xC, "f"), yP(this, bC, "f"), yP(this, _C, "f")), "f"), yP(this, eP, "f").notificationAudioEnabled = !0, yP(this, eP, "f").addResetCallback((() => { yP(this, JC, "f").reset = !1, null == yP(this, eP, "f") ? wP(this, ZC, !1, "f") : (wP(this, ZC, yP(this, eP, "f").getControls().up || yP(this, eP, "f").getControls().down, "f"), yP(this, ZC, "f") && wP(this, $C, new Date, "f")) })), yP(this, eP, "f").addCheckpointCallback((e => { if (null == yP(this, eP, "f") || null == yP(this, HC, "f")) return; const t = yP(this, eP, "f").getTime(); let n = null; const i = yP(this, wC, "m", mP).call(this); null != i && i.checkpointTimes.length > e && (n = i.checkpointTimes[e]), yP(this, HC, "f").showCheckpointTime(t, n) })), yP(this, eP, "f").addFinishCallback((e => { var t, i; const r = e.getTime(), a = e.getRecording(), s = e.getColors(), o = yP(this, iP, "f"); if (null == yP(this, iP, "f") || r.lessThan(yP(this, iP, "f"))) { if (yP(this, RC, "f").call(this, yP(this, bC, "f").getID(), a, r), 0 == yP(this, tP, "f").length) yP(this, tP, "f").push({ car: null, carId: null, hasEnded: !1, loadedFrames: 0, maxFrames: 0, settings: { recording: a, carColors: s, name: n.nickname, time: r, isSelf: !0 }, replay: null, checkpointTimes: [] }), null === (t = yP(this, jC, "f")) || void 0 === t || t.setWatchButtonEnabled(null != yP(this, DC, "f")); else { const e = yP(this, tP, "f").find((e => e.settings.isSelf)); null != e && (e.settings = { recording: a, carColors: s, name: n.nickname, time: r, isSelf: !0 }), null === (i = yP(this, jC, "f")) || void 0 === i || i.setWatchButtonEnabled(null != yP(this, DC, "f")) } wP(this, iP, r, "f") } let l = null; const c = yP(this, wC, "m", mP).call(this); null == c || c.settings.isSelf || (l = { record: c.settings.time, name: c.settings.name }), wP(this, GC, new VT(yP(this, EC, "f"), yP(this, NC, "f").name, r, o, l), "f") })), yP(this, eP, "f").setColors(n.carColors), i ? yP(this, SC, "f").setCamera(yP(this, eP, "f").cameraCockpit) : yP(this, SC, "f").setCamera(yP(this, eP, "f").cameraOrbit), yP(this, sP, "f").isEnabled = !1, null === (e = yP(this, GC, "f")) || void 0 === e || e.dispose(), wP(this, GC, null, "f"), null === (t = yP(this, HC, "f")) || void 0 === t || t.hideCheckpointTime(), yP(this, JC, "f").reset = !1, wP(this, ZC, !1, "f"), wP(this, $C, null, "f") }, fP = function() { var e; if (yP(this, _C, "f").getSettingBoolean($o.GhostCarEnabled)) for (const t of yP(this, tP, "f")) { null != t.car && (t.car.dispose(), t.car = null); const n = yP(this, bC, "f").getStartTransform(); if (null == n) throw new Error("Start transform is null"); if (t.settings.recording != (null === (e = t.replay) || void 0 === e ? void 0 : e.recording) && (null != t.carId && (yP(this, AC, "f").deleteCar(t.carId), t.carId = null), t.replay = null), null == t.replay) { const e = t.settings.time.numberOfFrames + yP(this, hP, "f"), i = new __, r = []; let a = 0; const s = yP(this, AC, "f").createCar(n, yP(this, xC, "f").getMountainVertices(), yP(this, xC, "f").getMountainOffset(), yP(this, bC, "f").getTrackData(), t.settings.recording, (n => { i.push(n), n.nextCheckpointIndex > a && (r.push(new xp(n.frames)), a = n.nextCheckpointIndex), n.frames >= e && null != t.carId && (null != n.finishFrames && n.finishFrames == t.settings.time.numberOfFrames || wP(this, nP, !0, "f"), yP(this, AC, "f").deleteCar(t.carId), t.carId = null), t.loadedFrames = n.frames, t.maxFrames = e })); i.push(s), yP(this, AC, "f").startCar(s.id, new xp(e)), t.carId = s.id, t.loadedFrames = 0, t.maxFrames = e, t.replay = { replay: i, recording: t.settings.recording }, t.checkpointTimes = r } const i = new Aw(null, n, t.settings.recording, null, yP(this, SC, "f"), yP(this, MC, "f"), yP(this, xC, "f"), yP(this, bC, "f"), yP(this, _C, "f")); i.setColors(t.settings.carColors), i.audioVolume = .35, yP(this, wC, "m", gP).call(this), t.car = i, t.hasEnded = !1 } }, mP = function() { let e = null; for (const t of yP(this, tP, "f"))(null == e || t.settings.time.lessThan(e.settings.time) || t.settings.time.equals(e.settings.time) && t.settings.isSelf) && (e = t); return e }, gP = function() { if (null != yP(this, eP, "f")) for (const e of yP(this, tP, "f")) if (null != e.car) { const t = e.car.getPosition().distanceTo(yP(this, eP, "f").getPosition()), n = Math.max(0, Math.min(1, t / 5)); e.car.setOpacity(n) } }, vP = function() { var e; if (null != yP(this, HC, "f")) { const t = yP(this, wC, "m", mP).call(this); yP(this, HC, "f").record = null !== (e = null == t ? void 0 : t.settings.time) && void 0 !== e ? e : null, null == t || t.settings.isSelf ? yP(this, HC, "f").nickname = null : yP(this, HC, "f").nickname = t.settings.name } }; const AP = class { constructor(e, t, n, i, r, a, s, o, l, c, h, d, u, p, f, m, g, v, w, y, A) { if (wC.add(this), yC.set(this, void 0), AC.set(this, void 0), bC.set(this, void 0), xC.set(this, void 0), kC.set(this, void 0), EC.set(this, void 0), SC.set(this, void 0), MC.set(this, void 0), TC.set(this, void 0), _C.set(this, void 0), CC.set(this, void 0), PC.set(this, void 0), IC.set(this, void 0), RC.set(this, void 0), LC.set(this, void 0), DC.set(this, void 0), NC.set(this, void 0), BC.set(this, void 0), UC.set(this, void 0), zC.set(this, !0), OC.set(this, null), FC.set(this, null), WC.set(this, null), VC.set(this, null), HC.set(this, null), GC.set(this, null), jC.set(this, null), QC.set(this, 0), YC.set(this, null), KC.set(this, null), qC.set(this, void 0), XC.set(this, void 0), ZC.set(this, !1), JC.set(this, void 0), $C.set(this, null), eP.set(this, null), tP.set(this, []), nP.set(this, !1), iP.set(this, void 0), rP.set(this, void 0), aP.set(this, void 0), sP.set(this, void 0), oP.set(this, null), lP.set(this, null), cP.set(this, !1), this.isPaused = !1, hP.set(this, 1e4), wP(this, yC, e, "f"), wP(this, AC, t, "f"), wP(this, bC, n, "f"), wP(this, xC, i, "f"), wP(this, kC, r, "f"), wP(this, EC, a, "f"), wP(this, SC, s, "f"), wP(this, MC, o, "f"), wP(this, TC, l, "f"), wP(this, _C, c, "f"), wP(this, CC, h, "f"), wP(this, PC, d, "f"), wP(this, IC, u, "f"), wP(this, RC, w, "f"), wP(this, LC, y, "f"), wP(this, DC, A, "f"), wP(this, iP, v, "f"), wP(this, NC, p, "f"), wP(this, BC, f, "f"), wP(this, UC, m, "f"), n.loadTrackData(f), n.generateMeshes(), i.generateMountains(n.getBounds()), wP(this, tP, g.map((e => ({ car: null, carId: null, hasEnded: !1, loadedFrames: 0, maxFrames: 0, settings: e, replay: null, checkpointTimes: [] }))), "f"), wP(this, JC, new S_(c), "f"), yP(this, JC, "f").addChangeCallback((e => { null == yP(this, eP, "f") || !e.up && !e.down || yP(this, ZC, "f") || (wP(this, ZC, !0, "f"), wP(this, $C, new Date, "f")) })), h.setCursorHiddenWhenInactive(!0), wP(this, qC, new f_(yP(this, JC, "f"), yP(this, MC, "f"), (() => { var e; !yP(this, cP, "f") && (null === (e = yP(this, eP, "f")) || void 0 === e ? void 0 : e.hasStarted()) && (yP(this, eP, "f").hasFinished() || 0 == yP(this, eP, "f").getNextCheckpointIndex() || !yP(this, ZC, "f") || null != yP(this, $C, "f") && (new Date).getTime() - yP(this, $C, "f").getTime() < 250 ? (yP(this, wC, "m", uP).call(this), yP(this, JC, "f").reset = !1) : yP(this, JC, "f").reset = !0) })), "f"), yP(this, qC, "f").setEnabled(yP(this, IC, "f").touchEnabled), yP(this, wC, "m", dP).call(this, !0), yP(this, wC, "m", vP).call(this), wP(this, sP, new s_(s, c), "f"), yP(this, sP, "f").addToggleListener((e => { e ? (yP(this, wC, "m", dP).call(this, !1), s.setCamera(yP(this, sP, "f").camera)) : null != yP(this, eP, "f") && (yP(this, wC, "m", dP).call(this, yP(this, zC, "f")), yP(this, _C, "f").getSettingBoolean($o.DefaultCameraMode) ? yP(this, SC, "f").setCamera(yP(this, eP, "f").cameraCockpit) : yP(this, SC, "f").setCamera(yP(this, eP, "f").cameraOrbit)) })), yP(this, IC, "f").addChangeListener(wP(this, XC, (e => { var t, n, i, r, a, s, o, l; e ? (null === (t = yP(this, FC, "f")) || void 0 === t || t.setOverridePosition(!0), null === (n = yP(this, WC, "f")) || void 0 === n || n.setOverridePosition(!0), null === (i = yP(this, HC, "f")) || void 0 === i || i.setOverridePosition(!0), null === (r = yP(this, VC, "f")) || void 0 === r || r.setOverridePosition(!0)) : (null === (a = yP(this, FC, "f")) || void 0 === a || a.setOverridePosition(null), null === (s = yP(this, WC, "f")) || void 0 === s || s.setOverridePosition(null), null === (o = yP(this, HC, "f")) || void 0 === o || o.setOverridePosition(null), null === (l = yP(this, VC, "f")) || void 0 === l || l.setOverridePosition(null)), yP(this, qC, "f").setEnabled(e) }), "f")), yP(this, wC, "m", pP).call(this), yP(this, wC, "m", fP).call(this), window.addEventListener("keydown", wP(this, rP, (e => { var t, n, i; if (!yP(this, cP, "f")) { if (yP(this, sP, "f").isEnabled) "Escape" == e.code && (yP(this, sP, "f").isEnabled = !1); else if (yP(this, _C, "f").checkKeyBinding(e, Ix.VehicleCheckpointReset)) e.repeat || null == yP(this, YC, "f") && (null === (t = yP(this, eP, "f")) || void 0 === t ? void 0 : t.hasStarted()) && (yP(this, eP, "f").hasFinished() || !yP(this, eP, "f").hasCheckpointToRespawnAt() || !yP(this, ZC, "f") || null != yP(this, $C, "f") && (new Date).getTime() - yP(this, $C, "f").getTime() < 250 ? (yP(this, wC, "m", uP).call(this), yP(this, JC, "f").reset = !1) : yP(this, JC, "f").reset = !0), e.preventDefault(); else if (yP(this, _C, "f").checkKeyBinding(e, Ix.VehicleStartReset)) e.repeat || null == yP(this, YC, "f") && (null === (n = yP(this, eP, "f")) || void 0 === n ? void 0 : n.hasStarted()) && yP(this, wC, "m", uP).call(this), e.preventDefault(); else if (yP(this, _C, "f").checkKeyBinding(e, Ix.VehicleCockpitCamera)) e.repeat || null == yP(this, YC, "f") && (null == yP(this, eP, "f") || yP(this, eP, "f").hasFinished() || (yP(this, _C, "f").getSettingBoolean($o.CockpitCameraToggle) ? yP(this, SC, "f").camera == yP(this, eP, "f").cameraOrbit ? yP(this, SC, "f").setCamera(yP(this, eP, "f").cameraCockpit) : yP(this, SC, "f").setCamera(yP(this, eP, "f").cameraOrbit) : yP(this, _C, "f").getSettingBoolean($o.DefaultCameraMode) ? yP(this, SC, "f").setCamera(yP(this, eP, "f").cameraOrbit) : yP(this, SC, "f").setCamera(yP(this, eP, "f").cameraCockpit))), e.preventDefault(); else if (c.checkKeyBinding(e, Ix.ToggleUI)) wP(this, zC, !yP(this, zC, "f"), "f"), yP(this, wC, "m", dP).call(this, yP(this, zC, "f")), e.preventDefault(); else if (c.checkKeyBinding(e, Ix.Pause)) { if (null == yP(this, YC, "f")) { if (!(null === (i = yP(this, eP, "f")) || void 0 === i ? void 0 : i.hasFinished())) { const e = new Date; (null == yP(this, KC, "f") || Math.abs(e.getTime() - yP(this, KC, "f").getTime()) > 1e3) && (wP(this, YC, new lC(a), "f"), wP(this, KC, e, "f")) } } else yP(this, YC, "f").startFadeOut((() => { var e; null === (e = yP(this, YC, "f")) || void 0 === e || e.dispose(), wP(this, YC, null, "f") })); e.preventDefault() } else "Escape" == e.code && (null != yP(this, YC, "f") ? yP(this, YC, "f").startFadeOut((() => { var e; null === (e = yP(this, YC, "f")) || void 0 === e || e.dispose(), wP(this, YC, null, "f") })) : y(), e.preventDefault()); if (c.checkKeyBinding(e, Ix.ToggleSpectatorCamera) && null != yP(this, eP, "f")) { if (null == yP(this, YC, "f") && !yP(this, eP, "f").hasFinished()) { yP(this, sP, "f").camera.position.copy(yP(this, SC, "f").camera.position); const e = new ai(0, 0, 0, "YXZ").setFromQuaternion(yP(this, SC, "f").camera.quaternion); e.x = Math.round(1e4 * e.x) / 1e4, e.y = Math.round(1e4 * e.y) / 1e4, e.z = 0, yP(this, sP, "f").camera.quaternion.setFromEuler(e), yP(this, sP, "f").toggle() } e.preventDefault() } } }), "f")), window.addEventListener("keyup", wP(this, aP, (e => { yP(this, sP, "f").isEnabled || yP(this, _C, "f").checkKeyBinding(e, Ix.VehicleCockpitCamera) && (null == yP(this, eP, "f") || yP(this, eP, "f").hasFinished() || yP(this, _C, "f").getSettingBoolean($o.CockpitCameraToggle) || (yP(this, _C, "f").getSettingBoolean($o.DefaultCameraMode) ? yP(this, SC, "f").setCamera(yP(this, eP, "f").cameraCockpit) : yP(this, SC, "f").setCamera(yP(this, eP, "f").cameraOrbit))) }), "f")), "official" == m) if ("Summer 1" == p.name) { let e = !1, t = null; (new vl).load("data:application/octet-stream;base64,Z2xURgIAAABABQAAtAIAAEpTT057ImFzc2V0Ijp7ImdlbmVyYXRvciI6Iktocm9ub3MgZ2xURiBCbGVuZGVyIEkvTyB2NC4zLjQ3IiwidmVyc2lvbiI6IjIuMCJ9LCJzY2VuZSI6MCwic2NlbmVzIjpbeyJuYW1lIjoiU2NlbmUiLCJub2RlcyI6WzBdfV0sIm5vZGVzIjpbeyJtZXNoIjowLCJuYW1lIjoiVGltIn1dLCJtZXNoZXMiOlt7Im5hbWUiOiJJY29zcGhlcmUiLCJwcmltaXRpdmVzIjpbeyJhdHRyaWJ1dGVzIjp7IlBPU0lUSU9OIjowfSwiaW5kaWNlcyI6MX1dfV0sImFjY2Vzc29ycyI6W3siYnVmZmVyVmlldyI6MCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjQwLCJtYXgiOlsxLjkyMjk4MTczOTA0NDE4OTUsMC45Nzk5NTkyNDk0OTY0NiwxLjkyMzk4MzIxNjI4NTcwNTZdLCJtaW4iOlstMS42MTkzMzUxNzQ1NjA1NDY5LC0wLjAwMjY1NzAwMzcwMDczMzE4NSwtMS45MjM5ODMyMTYyODU3MDU2XSwidHlwZSI6IlZFQzMifSx7ImJ1ZmZlclZpZXciOjEsImNvbXBvbmVudFR5cGUiOjUxMjMsImNvdW50Ijo3MiwidHlwZSI6IlNDQUxBUiJ9XSwiYnVmZmVyVmlld3MiOlt7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6NDgwLCJieXRlT2Zmc2V0IjowLCJ0YXJnZXQiOjM0OTYyfSx7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6MTQ0LCJieXRlT2Zmc2V0Ijo0ODAsInRhcmdldCI6MzQ5NjN9XSwiYnVmZmVycyI6W3siYnl0ZUxlbmd0aCI6NjI0fV19IHACAABCSU4AYEbPv2KYkj0AAACAVHJ2vwDMGrnP99++pLydPwDMGrk24B2/RCT2PwDMGrkAAACAV3+OP6V5DT8AAACAUM+Fvs+7Sz4Yv+C9RFdmvi6DTT5GfDa+MSy1vwQnJD2OQq2/RVCtv35EKz2hUrO/EL9cPcD2DT44Hmy+lw8GPigmDT7YbnW+soYBvkD287rCHfO/fZtKvSAhLrvWR/S/a+9QP9nDJT70Gmy+jsBkP4VDJj7YG2e+tHeIPwD7eDoVRfa/MSSSP4BTvDp4CfS/slywP3B5qj5wHtq9IVfXP5zeej9eSjG/sqqyP941lz5w8BC+IaXZP9Q8cT+sQjq/urH2vakt/T4AAACAVHJ2vwDMGrnP998+pLydPwDMGrk24B0/UM+Fvs+7Sz4Yv+A9RFdmvi6DTT5GfDY+MSy1vwQnJD2OQq0/RVCtv35EKz2hUrM/EL9cPcD2DT44Hmw+lw8GPigmDT7YbnU+soYBvkD287rCHfM/fZtKvSAhLrvWR/Q/a+9QP9nDJT70Gmw+jsBkP4VDJj7YG2c+tHeIPwD7eDoVRfY/MSSSP4BTvDp4CfQ/slywP3B5qj5wHto9IVfXP5zeej9eSjE/sqqyP941lz5w8BA+IaXZP9Q8cT+sQjo/AgABAAQAAwACAAQAFQABAAAABgAHAAUACgALAAkADgAPAA0AEgATABEAFQAEAAEABgAIAAcACgAMAAsADgAQAA8AEgAUABMAFwAEABYAAwAEABcAFQAAABYAGQAYABoAHQAcAB4AIQAgACIAJQAkACYAFQAWAAQAGQAaABsAHQAeAB8AIQAiACMAJQAmACcA", (n => { if (n.scene.children.length > 1) throw new Error("Model contains more than one object"); if (!(n.scene.children[0] instanceof wr)) throw new Error("Model is not a mesh"); e ? (t = n.scene.children[0], t.geometry.dispose(), t.material.dispose(), t = null) : (t = n.scene.children[0], t.geometry.computeVertexNormals(), t.material = new Fs({ color: 4464662, side: 2 }), t.position.set(-155.65, .209, -21.87), t.rotation.set(0, -2, 0), t.scale.set(.05, .05, .05), s.scene.add(t)) })), wP(this, oP, { dispose: () => { null != t && (yP(this, SC, "f").scene.remove(t), t.geometry.dispose(), t.material.dispose()), e = !0 }, update: () => { null != t && (t.visible = !yP(this, sP, "f").isEnabled) } }, "f") } else if ("Summer 3" == p.name) { const e = (new vo).load("data:image/png;base64,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"), t = new ji({ map: e }), n = new Ns(136 / 157 * 2, 2), i = new wr(n, t); i.position.set(-640, 2, -249.95), i.visible = !1, s.scene.add(i), wP(this, oP, { dispose: () => { yP(this, SC, "f").scene.remove(i), n.dispose(), t.dispose(), e.dispose() }, update: () => { i.visible = !yP(this, sP, "f").isEnabled } }, "f") } } dispose(e = !0) { var t, n, i, r, a; yP(this, CC, "f").setCursorHiddenWhenInactive(!1), yP(this, PC, "f").hide(), yP(this, wC, "m", dP).call(this, !1), yP(this, qC, "f").dispose(), yP(this, IC, "f").removeChangeListener(yP(this, XC, "f")), null === (t = yP(this, YC, "f")) || void 0 === t || t.dispose(), wP(this, YC, null, "f"), e && yP(this, bC, "f").clear(), yP(this, xC, "f").clearMountains(), yP(this, JC, "f").dispose(), null === (n = yP(this, eP, "f")) || void 0 === n || n.dispose(); for (const e of yP(this, tP, "f")) null === (i = e.car) || void 0 === i || i.dispose(), e.car = null, null != e.carId && (yP(this, AC, "f").deleteCar(e.carId), e.carId = null), e.replay = null; window.removeEventListener("keydown", yP(this, rP, "f")), window.removeEventListener("keyup", yP(this, aP, "f")), yP(this, sP, "f").dispose(), null === (r = yP(this, oP, "f")) || void 0 === r || r.dispose(), null === (a = yP(this, lP, "f")) || void 0 === a || a.dispose() } update(e) { var t, n, i, r, a, s, o, l, c, h, d, u, p, f, m; let g; if (g = null == yP(this, eP, "f") || yP(this, sP, "f").isEnabled || this.isPaused || yP(this, cP, "f") || null != yP(this, YC, "f") ? 0 : e, this.isPaused || null != yP(this, YC, "f") || yP(this, cP, "f")) { null != yP(this, eP, "f") && (yP(this, eP, "f").isPaused = !0, yP(this, eP, "f").audioVolume = 0, yP(this, eP, "f").update(g), yP(this, eP, "f").updateCameras(g)); for (const e of yP(this, tP, "f")) null != e.car && (e.car.isPaused = !0, e.car.audioVolume = 0, e.car.update(g)); null === (u = yP(this, jC, "f")) || void 0 === u || u.setVisible(!yP(this, cP, "f")) } else { if (null != yP(this, eP, "f")) { if (yP(this, eP, "f").update(g), yP(this, eP, "f").updateCameras(g), yP(this, sP, "f").isEnabled) yP(this, eP, "f").isPaused = !0, yP(this, eP, "f").audioVolume = 0; else { yP(this, eP, "f").isPaused = !1, yP(this, eP, "f").audioVolume = 1; const c = yP(this, JC, "f").getControls(); (c.up || c.down) && (yP(this, eP, "f").hasStarted() || yP(this, eP, "f").start()), yP(this, eP, "f").hasStarted() && !yP(this, eP, "f").hasFinished() ? q_() : X_(), yP(this, eP, "f").hasStarted() || yP(this, nP, "f") && (yP(this, PC, "f").show(yP(this, EC, "f").get("Invalid replay detected!"), yP(this, EC, "f").get("Ok"), (() => { yP(this, PC, "f").hide() })), wP(this, nP, !1, "f")); const h = yP(this, tP, "f").reduce(((e, t) => e + t.loadedFrames), 0), d = yP(this, tP, "f").reduce(((e, t) => e + t.maxFrames), 0); let u; u = d > 0 ? h / d : 1, null === (t = yP(this, OC, "f")) || void 0 === t || t.update(yP(this, eP, "f"), e), null === (n = yP(this, FC, "f")) || void 0 === n || n.update(u), null === (i = yP(this, VC, "f")) || void 0 === i || i.update(yP(this, eP, "f")), null === (r = yP(this, HC, "f")) || void 0 === r || r.update(yP(this, eP, "f")), null === (a = yP(this, WC, "f")) || void 0 === a || a.update(yP(this, eP, "f")), yP(this, eP, "f").hasStarted() && !yP(this, eP, "f").hasFinished() && yP(this, ZC, "f") ? yP(this, eP, "f").getSpeedKmh() < 50 ? (wP(this, QC, yP(this, QC, "f") + e, "f"), null === (o = yP(this, jC, "f")) || void 0 === o || o.setVisible(yP(this, QC, "f") > 2.25)) : (null === (l = yP(this, jC, "f")) || void 0 === l || l.setVisible(!1), wP(this, QC, 0, "f")) : (null === (s = yP(this, jC, "f")) || void 0 === s || s.setVisible(!0), wP(this, QC, 0, "f")) } yP(this, eP, "f").getTime().numberOfFrames >= cv.maxFrames && yP(this, wC, "m", uP).call(this), null === (c = yP(this, lP, "f")) || void 0 === c || c.updateCar(yP(this, eP, "f")) } for (const e of yP(this, tP, "f")) if (null != e.car) { if (!e.hasEnded) { const t = null === (h = yP(this, eP, "f")) || void 0 === h ? void 0 : h.getTime().numberOfFrames; if (null != t) { for (let n = e.car.getTime().numberOfFrames + 1; n <= t; n++) { const t = null === (d = e.replay) || void 0 === d ? void 0 : d.replay.getFrame(n); if (null == t) { e.hasEnded = !0, e.car.setVisible(!1); break } e.car.setCarState(t) } } e.car.update(g) } e.hasEnded || yP(this, sP, "f").isEnabled ? e.car.audioVolume = 0 : e.car.audioVolume = .35 } yP(this, wC, "m", gP).call(this), yP(this, sP, "f").update(e) } null === (p = yP(this, oP, "f")) || void 0 === p || p.update(), yP(this, xC, "f").update(yP(this, bC, "f")), yP(this, kC, "f").update(g, yP(this, SC, "f").camera, yP(this, bC, "f").sunDirection), yP(this, MC, "f").update(e, !1, yP(this, SC, "f"), yP(this, _C, "f")), yP(this, SC, "f").update(null !== (m = null === (f = yP(this, eP, "f")) || void 0 === f ? void 0 : f.getPosition()) && void 0 !== m ? m : new yn, yP(this, bC, "f").sunDirection) } }; var bP, xP, kP, EP = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }, SP = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }; class MP { constructor(e) { if (xP.set(this, void 0), null != e) { if (!Number.isInteger(e)) throw new Error("Seed must be an integer"); SP(this, xP, e % EP(bP, bP, "f", kP).length, "f") } else SP(this, xP, 0, "f") } next() { var e; return SP(this, xP, (e = EP(this, xP, "f"), ++e), "f"), EP(this, xP, "f") >= EP(bP, bP, "f", kP).length && SP(this, xP, 0, "f"), EP(bP, bP, "f", kP)[EP(this, xP, "f")] } } bP = MP, xP = new WeakMap, kP = { value: [.12047764760664692, .19645762332790628, .5525629082262744, .41272626379209965, .7795036003541387, .13367266027110114, .7999601557377349, .9519714253374205, .1735048382917752, .7513367084489158, .6531386724839523, .9026427867068505, .8543272738216994, .11176849958868162, .6705698284858437, .26628732081296946, .31140322993719605, .45170300835470933, .12615515120247944, .0610638094525735, .291990923385425, .4613983868623317, .6615759832726253, .4373182881232056, .7432890501246443, .39316710322388837, .49444122821563297, .5994296685114344, .060050119050233386, .4165885432422003, .43974364800990084, .1628314496954224, .05787972729968116, .225388541259955, .6075775236386991, .8908354370882479, .47072983115144584, .7662003453186828, .20651036895645647, .03724062137286044, .17110277274376795, .7626426077793496, .8372112804261309, .8761690804447455, .13887024930406633, .8287513367412203, .9794446290917873, .807658524448803, .8465629116398186, .5187285629536083, .33962953580139277, .9798419666114342, .6777071959103609, .5388899884934379, .7863389168762325, .4274591420924474, .25631366937500566, .5695289062505289, .026841382754547727, .18267938207996903, .9853642975717878, .24428485895234409, .5322028747608949, .9655065842019517, .043810183244384016, .541216190236913, .05897981610006209, .2849168541804703, .5349823008832073, .9655676144971486, .22831812764497283, .7698701658704175, .4103995069939841, .25782763124411856, .8490222628872495, .39280879489916987, .31999467883347554, .2860820872456349, .9684928577493004, .9973831481899462, .2930912094664657, .4847128131859766, .7218400909709828, .40407009594106236, .7059298060123587, .45362146566562744, .4640974655488792, .16076769483252273, .5989453525750241, .585759299589679, .9417035568973537, .20117930667657413, .5777873180244959, .1991854396549344, .8743781441651348, .624666386634513, .38720573630932886, .9967931526923675, .49817894572849486, .24585267823751833, .8639168275132305, .2865624029759799, .6163605496913385, .5864748073339972, .8781049154377354, .7497547608938613, .7864098057445887, .0334170452332867, .4875588105294657, .6737395339380896, .21851121231639659, .2923739650597854, .6073797612662293, .41823228947229896, .8531029420136382, .3260916332061783, .6306262204574675, .5268576689601923, .3516570914484707, .8659366375222706, .8447448461834428, .3794548980890986, .9832775904115916, .8442256760399809, .3006550591973338, .9718660619781394, .5103245035851833, .794319831388071] }; const TP = MP; var _P, CP, PP, IP, RP, LP, DP, NP, BP, UP, zP, OP = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, FP = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class WP { constructor(e) { _P.add(this), PP.set(this, void 0), IP.set(this, QA.Summer), RP.set(this, void 0), LP.set(this, void 0), DP.set(this, void 0), NP.set(this, void 0), BP.set(this, null), OP(this, PP, e, "f"), OP(this, RP, new Fs({ depthWrite: !1 }), "f"), OP(this, LP, new Fs, "f"), OP(this, DP, new wr(new Ns(6 * Au.maxViewDistance, 6 * Au.maxViewDistance), FP(this, RP, "f")), "f"), FP(this, DP, "f").rotation.x = -Math.PI / 2, FP(this, DP, "f").renderOrder = -3, e.scene.add(FP(this, DP, "f")), OP(this, NP, new wr(new Ns(120, 120), FP(this, RP, "f")), "f"), FP(this, NP, "f").rotation.x = -Math.PI / 2, FP(this, NP, "f").receiveShadow = !0, FP(this, NP, "f").renderOrder = -2, e.scene.add(FP(this, NP, "f")), FP(this, _P, "m", zP).call(this, QA.Summer) } clearMountains() { null != FP(this, BP, "f") && (FP(this, BP, "f").material.dispose(), FP(this, BP, "f").geometry.dispose(), FP(this, PP, "f").scene.remove(FP(this, BP, "f")), OP(this, BP, null, "f")) } generateMountains(e) { this.clearMountains(); const { vertices: t, offset: n } = CP.createMountainVertices(e), i = new sr; i.setAttribute("position", new qi(new Float32Array(t), 3)), i.computeVertexNormals(); const r = new wr(i, FP(this, LP, "f")); r.position.copy(n), r.receiveShadow = !0, FP(this, PP, "f").scene.add(r), OP(this, BP, r, "f") } static createMountainVertices(e) { const t = new TP, n = Math.max(200, 160 + Math.max(Math.abs(e.max.x - e.min.x) * jb.partSize / 2 * Math.SQRT2, Math.abs(e.max.y - e.min.y) * jb.partSize / 2 * Math.SQRT2)), i = new jt((e.min.x + (e.max.x - e.min.x) / 2) * jb.partSize, (e.min.y + (e.max.y - e.min.y) / 2) * jb.partSize); if (n > 4500) return { vertices: [], offset: new yn }; const r = Math.floor(n / 10), a = []; for (let e = 0; e < r; ++e) { const e = []; for (let n = 0; n < 8; ++n) 0 == n || 7 == n || 1 == n && t.next() < .5 ? e.push(0) : e.push(t.next()); a.push(e) } const s = 100, o = []; for (let e = 0; e < a.length; ++e) { const t = e / a.length * Math.PI * 2, i = (e + 1) / a.length * Math.PI * 2, r = a[e]; let l; l = e + 1 < a.length ? a[e + 1] : a[0]; for (let e = 0; e < r.length - 1; ++e) { const a = n + 100 * e, c = n + 100 * (e + 1); o.push(Math.cos(t) * a, r[e] * s, Math.sin(t) * a), o.push(Math.cos(i) * a, l[e] * s, Math.sin(i) * a), o.push(Math.cos(i) * c, l[e + 1] * s, Math.sin(i) * c), o.push(Math.cos(t) * a, r[e] * s, Math.sin(t) * a), o.push(Math.cos(i) * c, l[e + 1] * s, Math.sin(i) * c), o.push(Math.cos(t) * c, r[e + 1] * s, Math.sin(t) * c) } } return { vertices: o, offset: new yn(i.x, 0, i.y) } } getMountainVertices() { if (null == FP(this, BP, "f")) return []; const e = FP(this, BP, "f").geometry; if (!(e.attributes.position instanceof qi)) throw new Error("Vertices must use BufferAttribute"); return Array.from(e.attributes.position.array) } getMountainOffset() { return null == FP(this, BP, "f") ? new yn : FP(this, BP, "f").position.clone() } raycast(e) { const t = e.intersectObject(FP(this, NP, "f")); if (t.length > 0) return t[0]; if (null != FP(this, BP, "f")) { const t = e.intersectObject(FP(this, BP, "f")); if (t.length > 0) return t[0] } return null } update(e) { e.environment != FP(this, IP, "f") && FP(this, _P, "m", zP).call(this, e.environment); const t = new yn, n = new wn, i = new yn; FP(this, PP, "f").camera.matrix.decompose(t, n, i), FP(this, DP, "f").position.set(t.x, 0, t.z); const r = FP(this, PP, "f").getLightTarget(); FP(this, NP, "f").position.set(r.x, 0, r.z), FP(this, NP, "f").visible = FP(this, NP, "f").position.manhattanDistanceTo(FP(this, DP, "f").position) < 8e3 } } CP = WP, PP = new WeakMap, IP = new WeakMap, RP = new WeakMap, LP = new WeakMap, DP = new WeakMap, NP = new WeakMap, BP = new WeakMap, _P = new WeakSet, UP = function(e) { let t; switch (e) { case QA.Summer: t = new Wi(3495480); break; case QA.Winter: t = new Wi(11053224); break; case QA.Desert: t = new Wi(11171394) } return t }, zP = function(e) { OP(this, IP, e, "f"); const t = FP(CP, CP, "m", UP).call(CP, e); FP(this, RP, "f").color.copy(t), FP(this, LP, "f").color.copy(t) }; const VP = WP; var HP = n(2915), GP = {}; GP.styleTagTransform = u(), GP.setAttributes = l(), GP.insert = s().bind(null, "head"), GP.domAPI = r(), GP.insertStyleElement = h(); t()(HP.A, GP); HP.A && HP.A.locals && HP.A.locals; var jP = n(2927), QP = {}; QP.styleTagTransform = u(), QP.setAttributes = l(), QP.insert = s().bind(null, "head"), QP.domAPI = r(), QP.insertStyleElement = h(); t()(jP.A, QP); jP.A && jP.A.locals && jP.A.locals; var YP, KP, qP = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, XP = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; YP = new WeakMap, KP = new WeakMap; const ZP = class { constructor(e, t, n) { YP.set(this, void 0), KP.set(this, void 0), qP(this, YP, e, "f"), qP(this, KP, document.createElement("div"), "f"), XP(this, KP, "f").className = "loading-ui", e.appendChild(XP(this, KP, "f")); const i = document.createElement("p"); i.textContent = t.get("Loading") + "...", XP(this, KP, "f").appendChild(i); const r = document.createElement("div"); XP(this, KP, "f").appendChild(r); const a = document.createElement("div"); r.appendChild(a); const s = document.createElement("div"); a.appendChild(s), n.addProgressListener((e => { s.style.width = (100 * e).toString() + "%" })) } fadeOut(e) { XP(this, KP, "f").classList.add("fade-out"), setTimeout(e, 250) } dispose() { XP(this, YP, "f").removeChild(XP(this, KP, "f")) } }; var JP = n(1643), $P = {}; $P.styleTagTransform = u(), $P.setAttributes = l(), $P.insert = s().bind(null, "head"), $P.domAPI = r(), $P.insertStyleElement = h(); t()(JP.A, $P); JP.A && JP.A.locals && JP.A.locals; var eI, tI, nI, iI, rI, aI, sI, oI, lI, cI, hI, dI, uI, pI, fI, mI, gI, vI, wI, yI, AI, bI = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, xI = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; tI = new WeakMap, nI = new WeakMap, iI = new WeakMap, rI = new WeakMap, aI = new WeakMap, sI = new WeakMap, oI = new WeakMap, lI = new WeakMap, cI = new WeakMap, hI = new WeakMap, dI = new WeakMap, uI = new WeakMap, eI = new WeakSet, pI = function() { xI(this, oI, "f").className = "hidden" }, fI = function() { xI(this, oI, "f").className = "settings-menu" }, mI = function() { xI(this, lI, "f").innerHTML = "", xI(this, eI, "m", gI).call(this, xI(this, nI, "f").get("Gameplay")), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Units"), [{ title: xI(this, nI, "f").get("Metric"), value: "false" }, { title: xI(this, nI, "f").get("Imperial"), value: "true" }], $o.ImperialUnitsEnabled), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Reset hint"), [{ title: xI(this, nI, "f").get("Disabled"), value: "false" }, { title: xI(this, nI, "f").get("Enabled"), value: "true" }], $o.ResetHintEnabled), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Ghost car"), [{ title: xI(this, nI, "f").get("Disabled"), value: "false" }, { title: xI(this, nI, "f").get("Enabled"), value: "true" }], $o.GhostCarEnabled), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Default camera"), [{ title: xI(this, nI, "f").get("Default"), value: "false" }, { title: xI(this, nI, "f").get("Cockpit"), value: "true" }], $o.DefaultCameraMode), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Cockpit camera mode"), [{ title: xI(this, nI, "f").get("Hold"), value: "false" }, { title: xI(this, nI, "f").get("Toggle"), value: "true" }], $o.CockpitCameraToggle), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Checkpoints"), [{ title: xI(this, nI, "f").get("Off"), value: "off" }, { title: xI(this, nI, "f").get("Bottom"), value: "bottom" }, { title: xI(this, nI, "f").get("Top"), value: "top" }], $o.Checkpoints), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Timer"), [{ title: xI(this, nI, "f").get("Off"), value: "off" }, { title: xI(this, nI, "f").get("Bottom"), value: "bottom" }, { title: xI(this, nI, "f").get("Top"), value: "top" }], $o.Timer), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Speedometer"), [{ title: xI(this, nI, "f").get("Off"), value: "off" }, { title: xI(this, nI, "f").get("Bottom"), value: "bottom" }, { title: xI(this, nI, "f").get("Top"), value: "top" }], $o.Speedometer), xI(this, eI, "m", gI).call(this, xI(this, nI, "f").get("Language")), xI(this, eI, "m", wI).call(this, null, [{ title: "العربية", value: "ar" }, { title: "Deutsch", value: "de-DE" }, { title: "English", value: "en-US" }, { title: "Español", value: "es-ES" }, { title: "Français", value: "fr-FR" }, { title: "Italiano", value: "it-IT" }, { title: "日本語", value: "ja-JP" }, { title: "한국어", value: "ko-KR" }, { title: "Polski", value: "pl-PL" }, { title: "Português (BR)", value: "pt-BR" }, { title: "Português (PT)", value: "pt-PT" }, { title: "Русский", value: "ru-RU" }, { title: "Türkçe", value: "tr-TR" }, { title: "Українська", value: "uk-UA" }, { title: "简体中文", value: "zh-CN" }, { title: "繁體中文", value: "zh-TW" }], $o.Language), xI(this, eI, "m", gI).call(this, xI(this, nI, "f").get("Graphics")), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Car shadow"), [{ title: xI(this, nI, "f").get("Off"), value: "0" }, { title: xI(this, nI, "f").get("Low"), value: "1024" }, { title: xI(this, nI, "f").get("Medium"), value: "2048" }, { title: xI(this, nI, "f").get("High"), value: "4096" }], $o.CarShadowQuality), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Track shadow"), [{ title: xI(this, nI, "f").get("Off"), value: "false" }, { title: xI(this, nI, "f").get("On"), value: "true" }], $o.TrackShadowEnabled, (() => { xI(this, aI, "f").generateMeshes() })), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Clouds"), [{ title: xI(this, nI, "f").get("Off"), value: "false" }, { title: xI(this, nI, "f").get("On"), value: "true" }], $o.CloudsEnabled), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Particles"), [{ title: xI(this, nI, "f").get("Off"), value: "false" }, { title: xI(this, nI, "f").get("On"), value: "true" }], $o.ParticlesEnabled), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Skidmarks"), [{ title: xI(this, nI, "f").get("Off"), value: "false" }, { title: xI(this, nI, "f").get("On"), value: "true" }], $o.SkidmarksEnabled), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Render scale"), [{ title: "25%", value: "0.25" }, { title: "50%", value: "0.5" }, { title: "100%", value: "1" }, { title: "150%", value: "1.5" }, { title: "200%", value: "2" }], $o.RenderScale), xI(this, eI, "m", wI).call(this, xI(this, nI, "f").get("Anti-aliasing (requires restart)"), [{ title: xI(this, nI, "f").get("Off"), value: "false" }, { title: xI(this, nI, "f").get("On"), value: "true" }], $o.Antialiasing), xI(this, eI, "m", gI).call(this, xI(this, nI, "f").get("Audio")), xI(this, eI, "m", yI).call(this, xI(this, nI, "f").get("Sound effect volume"), $o.SoundEffectVolume), xI(this, eI, "m", yI).call(this, xI(this, nI, "f").get("Music volume"), $o.MusicVolume), xI(this, eI, "m", yI).call(this, xI(this, nI, "f").get("Checkpoint volume"), $o.CheckpointVolume), xI(this, eI, "m", gI).call(this, xI(this, nI, "f").get("Controls")), xI(this, eI, "m", vI).call(this, xI(this, nI, "f").get("Vehicle")), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Accelerate"), Ix.VehicleAccelerate), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Brake"), Ix.VehicleBrake), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Turn left"), Ix.VehicleTurnLeft), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Turn right"), Ix.VehicleTurnRight), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Checkpoint reset"), Ix.VehicleCheckpointReset), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Start reset"), Ix.VehicleStartReset), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Cockpit camera"), Ix.VehicleCockpitCamera), xI(this, eI, "m", vI).call(this, xI(this, nI, "f").get("Editor")), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Rotate part"), Ix.EditorRotatePart), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Height modifier"), Ix.EditorHeightModifier), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Delete part"), Ix.EditorDelete), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Move forwards"), Ix.EditorMoveForwards), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Move backwards"), Ix.EditorMoveBackwards), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Move left"), Ix.EditorMoveLeft), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Move right"), Ix.EditorMoveRight), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Rotate view up"), Ix.EditorRotateViewUp), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Rotate view down"), Ix.EditorRotateViewDown), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Rotate view left"), Ix.EditorRotateViewLeft), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Rotate view right"), Ix.EditorRotateViewRight), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Move down"), Ix.EditorMoveDown), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Move up"), Ix.EditorMoveUp), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Test track"), Ix.EditorTest), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Pick part"), Ix.EditorPick), xI(this, eI, "m", vI).call(this, xI(this, nI, "f").get("Spectator")), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Move forwards"), Ix.SpectatorMoveForwards), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Move backwards"), Ix.SpectatorMoveBackwards), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Move left"), Ix.SpectatorMoveLeft), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Move right"), Ix.SpectatorMoveRight), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Speed modifier"), Ix.SpectatorSpeedModifier), xI(this, eI, "m", vI).call(this, xI(this, nI, "f").get("Other")), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Hide UI"), Ix.ToggleUI), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Pause"), Ix.Pause), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Toggle FPS counter"), Ix.ToggleFpsCounter), xI(this, eI, "m", AI).call(this, xI(this, nI, "f").get("Toggle spectator camera"), Ix.ToggleSpectatorCamera) }, gI = function(e) { const t = document.createElement("h2"); t.textContent = e, xI(this, lI, "f").appendChild(t) }, vI = function(e) { const t = document.createElement("h3"); t.textContent = e, xI(this, lI, "f").appendChild(t) }, wI = function(e, t, n, i) { var r; const a = null !== (r = xI(this, dI, "f").get(n)) && void 0 !== r ? r : xI(this, rI, "f").getSetting(n), s = document.createElement("div"); if (s.className = "setting", null != e) { const t = document.createElement("p"); t.textContent = e, s.appendChild(t) } else s.classList.add("wrappable"); const o = document.createElement("div"); o.className = "button-wrapper", s.appendChild(o); const l = []; for (const { title: e, value: r } of t) { const t = document.createElement("button"); t.className = r == a ? "button selected" : "button", t.textContent = e, t.addEventListener("click", (() => { xI(this, iI, "f").playUIClick(); for (const e of l) e.className = "button"; t.className = "button selected", xI(this, dI, "f").set(n, r), xI(this, rI, "f").updateSettings(Array.from(xI(this, dI, "f"))), null != i && i() })), o.appendChild(t), l.push(t) } xI(this, lI, "f").appendChild(s) }, yI = function(e, t, n = 0, i = 1) { var r; let a = parseFloat(null !== (r = xI(this, dI, "f").get(t)) && void 0 !== r ? r : xI(this, rI, "f").getSetting(t)); Number.isNaN(a) && (a = 0); const s = document.createElement("div"); s.className = "setting"; const o = document.createElement("p"); o.textContent = e, s.appendChild(o); const l = document.createElement("input"); l.type = "range", l.min = (20 * n).toString(), l.max = (20 * i).toString(), l.value = (20 * a).toString(), l.addEventListener("input", (() => { const e = parseFloat(l.value) / 20; xI(this, dI, "f").set(t, e.toString()), xI(this, rI, "f").updateSettings(Array.from(xI(this, dI, "f"))) })), s.appendChild(l), xI(this, lI, "f").appendChild(s) }, AI = function(e, t) { var n, i, r; const a = document.createElement("div"); a.className = "setting"; const s = document.createElement("p"); s.textContent = e, a.appendChild(s); const o = document.createElement("div"); o.className = "button-wrapper", a.appendChild(o); const l = null !== (n = xI(this, uI, "f").get(t)) && void 0 !== n ? n : xI(this, rI, "f").getKeyBindings(t), c = document.createElement("button"); c.className = "button key-binding", c.textContent = null !== (i = l[0]) && void 0 !== i ? i : "", c.addEventListener("click", (() => { xI(this, iI, "f").playUIClick(), xI(this, eI, "m", pI).call(this); const e = t => { "Escape" == t.code || "Tab" == t.code || "Enter" == t.code && null != document.activeElement && document.activeElement != document.body || (xI(this, sI, "f").hide(), l[0] = t.code, c.textContent = t.code, xI(this, eI, "m", fI).call(this), window.removeEventListener("keydown", e), t.preventDefault()) }; window.addEventListener("keydown", e), xI(this, sI, "f").showConfirm(xI(this, nI, "f").get("Press any key...\n\nPress [Escape] to cancel."), xI(this, nI, "f").get("Cancel"), xI(this, nI, "f").get("Clear"), (() => { xI(this, eI, "m", fI).call(this), window.removeEventListener("keydown", e) }), (() => { c.textContent = "", l[0] = null, window.removeEventListener("keydown", e), xI(this, eI, "m", fI).call(this) })) })), o.appendChild(c); const h = document.createElement("button"); h.className = "button key-binding", h.textContent = null !== (r = l[1]) && void 0 !== r ? r : "", h.addEventListener("click", (() => { xI(this, iI, "f").playUIClick(), xI(this, eI, "m", pI).call(this); const e = t => { "Escape" == t.code || "Tab" == t.code || "Enter" == t.code && null != document.activeElement && document.activeElement != document.body || (xI(this, sI, "f").hide(), l[1] = t.code, h.textContent = t.code, xI(this, eI, "m", fI).call(this), window.removeEventListener("keydown", e), t.preventDefault()) }; window.addEventListener("keydown", e), xI(this, sI, "f").showConfirm(xI(this, nI, "f").get("Press any key...\n\nPress [Escape] to cancel."), xI(this, nI, "f").get("Cancel"), xI(this, nI, "f").get("Clear"), (() => { xI(this, eI, "m", fI).call(this), window.removeEventListener("keydown", e) }), (() => { h.textContent = "", l[1] = null, window.removeEventListener("keydown", e), xI(this, eI, "m", fI).call(this) })) })), o.appendChild(h), xI(this, lI, "f").appendChild(a) }; const kI = class { constructor(e, t, n, i, r, a, s) { eI.add(this), tI.set(this, void 0), nI.set(this, void 0), iI.set(this, void 0), rI.set(this, void 0), aI.set(this, void 0), sI.set(this, void 0), oI.set(this, void 0), lI.set(this, void 0), cI.set(this, void 0), hI.set(this, new Map), dI.set(this, new Map), uI.set(this, new Map), bI(this, tI, e, "f"), bI(this, nI, t, "f"), bI(this, iI, n, "f"), bI(this, rI, i, "f"), bI(this, aI, r, "f"), bI(this, sI, a, "f"), bI(this, oI, document.createElement("div"), "f"), xI(this, oI, "f").className = "settings-menu", e.appendChild(xI(this, oI, "f")); const o = document.createElement("h2"); o.textContent = t.get("Settings"), xI(this, oI, "f").appendChild(o), bI(this, lI, document.createElement("div"), "f"), xI(this, lI, "f").className = "container", xI(this, oI, "f").appendChild(xI(this, lI, "f")), bI(this, hI, new Map(i.getSettings()), "f"), xI(this, eI, "m", mI).call(this); const l = document.createElement("div"); l.className = "button-wrapper", xI(this, oI, "f").appendChild(l); const c = document.createElement("button"); c.className = "button cancel", c.innerHTML = ' ', c.append(document.createTextNode(t.get("Cancel"))), c.addEventListener("click", (() => { n.playUIClick(), i.updateSettings(Array.from(xI(this, hI, "f"))), r.generateMeshes(), s() })), l.appendChild(c); const h = document.createElement("button"); h.className = "button reset", h.innerHTML = ' ', h.append(document.createTextNode(t.get("Reset"))), h.addEventListener("click", (() => { n.playUIClick(), bI(this, dI, xI(this, rI, "f").defaultSettings(), "f"), i.updateSettings(Array.from(xI(this, dI, "f"))), bI(this, uI, xI(this, rI, "f").defaultKeyBindings(), "f"), r.generateMeshes(), xI(this, eI, "m", mI).call(this) })), l.appendChild(h); const d = document.createElement("button"); d.className = "button apply", d.append(document.createTextNode(t.get("Apply"))), d.innerHTML += ' ', d.addEventListener("click", (() => { n.playUIClick(), i.updateSettings(Array.from(xI(this, dI, "f"))), i.saveSettings(), i.setKeyBindings(Array.from(xI(this, uI, "f"))), r.generateMeshes(), t.language = i.getSetting($o.Language), s() })), l.appendChild(d), window.addEventListener("keydown", bI(this, cI, (e => { "Escape" == e.code && (s(), e.preventDefault()) }), "f")) } dispose() { xI(this, tI, "f").removeChild(xI(this, oI, "f")), window.removeEventListener("keydown", xI(this, cI, "f")) } }; var EI = n(5586), SI = {}; SI.styleTagTransform = u(), SI.setAttributes = l(), SI.insert = s().bind(null, "head"), SI.domAPI = r(), SI.insertStyleElement = h(); t()(EI.A, SI); EI.A && EI.A.locals && EI.A.locals; var MI = n(6657), TI = {}; TI.styleTagTransform = u(), TI.setAttributes = l(), TI.insert = s().bind(null, "head"), TI.domAPI = r(), TI.insertStyleElement = h(); t()(MI.A, TI); MI.A && MI.A.locals && MI.A.locals; var _I = n(5086), CI = {}; CI.styleTagTransform = u(), CI.setAttributes = l(), CI.insert = s().bind(null, "head"), CI.domAPI = r(), CI.insertStyleElement = h(); t()(_I.A, CI); _I.A && _I.A.locals && _I.A.locals; var PI = function(e, t, n, i) { return new(n || (n = Promise))((function(r, a) { function s(e) { try { l(i.next(e)) } catch (e) { a(e) } } function o(e) { try { l(i.throw(e)) } catch (e) { a(e) } } function l(e) { var t; e.done ? r(e.value) : (t = e.value, t instanceof n ? t : new n((function(e) { e(t) }))).then(s, o) } l((i = i.apply(e, t || [])).next()) })) }; let II = null, RI = null, LI = null, DI = null, NI = null; function BI(e, t) { return PI(this, void 0, void 0, (function*() { for (; null != NI;) yield NI; const n = function(e, t) { return new Promise((n => { const i = setTimeout((() => { null != II && null != RI && null != LI && null != DI || (RI = document.createElement("canvas"), RI.width = 200, RI.height = 200, LI = new Au(RI, null, !1, !0), DI = new Io(-1, 1, 1, -1, .1, 1e4), DI.position.set(1e3, 1e3, 1e3), DI.lookAt(0, 0, 0), DI.zoom = .5, DI.position.add(new yn(.1, .3, 0)), DI.updateProjectionMatrix(), LI.scene.add(DI), LI.setCamera(DI), II = new Aw(null, { position: new yn, quaternion: new wn }, null, null, LI, null, null, null, null), II.update(0)), II.setColors(e), LI.update(new yn, new GA), n(RI.toDataURL()) }), 25); t.addCancelCallback((() => { clearTimeout(i), n("") })) })) }(e, t); let i; NI = n; try { i = yield n } finally { NI = null } return i })) } var UI, zI, OI = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }, FI = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }; UI = new WeakMap, zI = new WeakMap; const WI = class { constructor() { UI.set(this, !1), zI.set(this, []) } cancel() { if (!OI(this, UI, "f")) { FI(this, UI, !0, "f"); for (const e of OI(this, zI, "f")) e() } } get isCancelled() { return OI(this, UI, "f") } addCancelCallback(e) { OI(this, zI, "f").push(e), OI(this, UI, "f") && e() } }; var VI, HI; ! function(e) { e[e.Uninitialized = 0] = "Uninitialized", e[e.Ok = 1] = "Ok", e[e.TestFailed = 2] = "TestFailed", e[e.AssetsFailed = 3] = "AssetsFailed" }(VI || (VI = {})), function(e) { e[e.Pending = 0] = "Pending", e[e.Verified = 1] = "Verified", e[e.Invalid = 2] = "Invalid", e[e.InvalidDuplicate = 3] = "InvalidDuplicate", e[e.InvalidManual = 4] = "InvalidManual" }(HI || (HI = {})); var GI, jI, QI, YI, KI, qI, XI, ZI, JI, $I, eR, tR, nR, iR, rR, aR, sR, oR, lR, cR, hR, dR, uR, pR, fR, mR, gR, vR, wR = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, yR = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class AR { constructor(e, t, n, i, r, a, s, o, l, c, h) { GI.add(this), QI.set(this, void 0), YI.set(this, void 0), KI.set(this, void 0), qI.set(this, void 0), XI.set(this, void 0), ZI.set(this, void 0), JI.set(this, void 0), $I.set(this, void 0), eR.set(this, void 0), tR.set(this, void 0), nR.set(this, void 0), iR.set(this, void 0), rR.set(this, void 0), aR.set(this, void 0), sR.set(this, void 0), oR.set(this, null), lR.set(this, !1), cR.set(this, void 0), hR.set(this, 0), dR.set(this, 0), uR.set(this, null), pR.set(this, null), fR.set(this, []), wR(this, QI, t, "f"), wR(this, YI, n, "f"), wR(this, KI, i, "f"), wR(this, qI, r, "f"), wR(this, XI, a, "f"), wR(this, ZI, s, "f"), wR(this, JI, c, "f"), wR(this, $I, h, "f"), wR(this, cR, o.isOfficialTrack(t) || o.isCommunityTrack(t), "f"), wR(this, eR, e, "f"), wR(this, tR, document.createElement("div"), "f"), yR(this, tR, "f").className = "leaderboard", e.appendChild(yR(this, tR, "f")); const d = document.createElement("h2"); d.textContent = n.get("Leaderboard"), yR(this, tR, "f").appendChild(d); const u = document.createElement("h3"), p = iu.replace(/(\d+\.\d+)\.\d+/, "$1"); u.textContent = n.get("Version") + " " + p, yR(this, tR, "f").appendChild(u), wR(this, nR, document.createElement("div"), "f"), yR(this, nR, "f").className = "container", yR(this, tR, "f").appendChild(yR(this, nR, "f")), wR(this, iR, document.createElement("div"), "f"), yR(this, iR, "f").className = "loading-spinner-container", yR(this, nR, "f").appendChild(yR(this, iR, "f")); const f = document.createElement("div"); f.className = "loading-spinner", yR(this, iR, "f").appendChild(f), yR(this, GI, "m", mR).call(this, !1), wR(this, sR, document.createElement("div"), "f"), yR(this, sR, "f").className = "pages", yR(this, tR, "f").appendChild(yR(this, sR, "f")), yR(this, GI, "m", vR).call(this); const m = document.createElement("div"); m.className = "button-wrapper", yR(this, tR, "f").appendChild(m); const g = document.createElement("button"); g.className = "button back", g.innerHTML = ' ', g.append(document.createTextNode(n.get("Back"))), g.addEventListener("click", (() => { r.playUIClick(), l() })), m.appendChild(g), wR(this, rR, document.createElement("button"), "f"), yR(this, rR, "f").className = "button icon-button first", yR(this, rR, "f").innerHTML = '', yR(this, rR, "f").disabled = !0, yR(this, rR, "f").addEventListener("click", (() => { r.playUIClick(), null != yR(this, pR, "f") ? yR(this, pR, "f").scrollIntoView({ behavior: "smooth" }) : null != yR(this, uR, "f") && (wR(this, hR, yR(this, uR, "f"), "f"), yR(this, GI, "m", vR).call(this), yR(this, GI, "m", mR).call(this, !0)) })), m.appendChild(yR(this, rR, "f")), wR(this, aR, document.createElement("button"), "f"), yR(this, aR, "f").className = "button only-verified", yR(this, cR, "f") || yR(this, aR, "f").classList.add("disabled"), yR(this, aR, "f").textContent = yR(this, YI, "f").get("Only verified"), yR(this, aR, "f").innerHTML += '', yR(this, aR, "f").addEventListener("click", (() => { r.playUIClick(), wR(this, cR, !yR(this, cR, "f"), "f"), yR(this, cR, "f") ? yR(this, aR, "f").classList.remove("disabled") : yR(this, aR, "f").classList.add("disabled"), wR(this, hR, 0, "f"), wR(this, dR, 0, "f"), yR(this, GI, "m", vR).call(this), yR(this, GI, "m", mR).call(this, !1) })), m.appendChild(yR(this, aR, "f")) } dispose() { var e; null === (e = yR(this, oR, "f")) || void 0 === e || e.cancel(), yR(this, eR, "f").removeChild(yR(this, tR, "f")) } static getPositionSuffix(e) { if (e <= 0 || !Number.isInteger(e)) throw new Error("Position must be a positive integer."); const t = e % 100; if (t >= 11 && t <= 13) return "th"; switch (e % 10) { case 1: return "st"; case 2: return "nd"; case 3: return "rd"; default: return "th" } } } jI = AR, QI = new WeakMap, YI = new WeakMap, KI = new WeakMap, qI = new WeakMap, XI = new WeakMap, ZI = new WeakMap, JI = new WeakMap, $I = new WeakMap, eR = new WeakMap, tR = new WeakMap, nR = new WeakMap, iR = new WeakMap, rR = new WeakMap, aR = new WeakMap, sR = new WeakMap, oR = new WeakMap, lR = new WeakMap, cR = new WeakMap, hR = new WeakMap, dR = new WeakMap, uR = new WeakMap, pR = new WeakMap, fR = new WeakMap, GI = new WeakSet, mR = function e(t) { var n; null === (n = yR(this, oR, "f")) || void 0 === n || n.cancel(); const i = new WI; wR(this, oR, i, "f"), yR(this, nR, "f").innerHTML = "", yR(this, nR, "f").appendChild(yR(this, iR, "f")), wR(this, pR, null, "f"), setTimeout((() => { if (!i.isCancelled) { const n = 20, r = yR(this, hR, "f") * n; yR(this, KI, "f").getLeaderboard(yR(this, XI, "f").getCurrentUserProfile().tokenHash, yR(this, QI, "f"), r, n, yR(this, cR, "f")).then((({ total: a, entries: s, userEntry: o }) => { if (!i.isCancelled) { wR(this, dR, Math.ceil(a / n), "f"), yR(this, GI, "m", vR).call(this); for (let e = 0; e < s.length; e++) { const { id: t, name: n, time: a, carColors: o, verifiedState: l, isSelf: c } = s[e], h = r + e + 1; yR(this, GI, "m", gR).call(this, h, n, a, o, l, c, t, i) } if (yR(this, KI, "f").determinismState == VI.Ok && (null != o ? (wR(this, uR, Math.floor((o.position - 1) / n), "f"), yR(this, rR, "f").disabled = !1, t && null != yR(this, pR, "f") && yR(this, pR, "f").scrollIntoView(), yR(this, $I, "f").call(this, o)) : (wR(this, uR, null, "f"), yR(this, rR, "f").disabled = !0, yR(this, $I, "f").call(this, null)), !yR(this, lR, "f"))) { wR(this, lR, !0, "f"); let n = null; null != o && (n = { time: o.time, recordingId: o.id }), yR(this, ZI, "f").syncRecord(yR(this, XI, "f").profileSlot, yR(this, QI, "f"), n).then((n => { "Upload" == n && yR(this, GI, "m", e).call(this, t) })).catch((e => { console.warn(e) })) } } })).catch((e => { if (!i.isCancelled) { const e = document.createElement("p"); e.className = "error-message", e.textContent = yR(this, YI, "f").get("Error: Failed to load leaderboard"), yR(this, nR, "f").appendChild(e) } console.error(e) })).finally((() => { i.isCancelled || yR(this, nR, "f").removeChild(yR(this, iR, "f")) })) } }), 500) }, gR = function(e, t, n, i, r, a, s, o) { const l = document.createElement("button"); l.className = "button main", a && (wR(this, pR, l, "f"), l.classList.add("self")), l.addEventListener("click", (() => { yR(this, qI, "f").playUIClick(), yR(this, fR, "f").some((e => e.recordingId == s)) ? (wR(this, fR, yR(this, fR, "f").filter((e => e.recordingId != s)), "f"), l.classList.remove("selected"), yR(this, JI, "f").call(this, yR(this, fR, "f"))) : yR(this, fR, "f").length < 10 && (wR(this, fR, yR(this, fR, "f").concat([{ name: t, recordingId: s, isSelf: a }]), "f"), l.classList.add("selected"), yR(this, JI, "f").call(this, yR(this, fR, "f"))) })), yR(this, nR, "f").appendChild(l), yR(this, fR, "f").some((e => e.recordingId == s)) && l.classList.add("selected"); const c = document.createElement("div"); c.className = "image-container", l.appendChild(c); const h = document.createElement("img"); h.className = "show", h.src = "images/car_thumbnail_placeholder.png", c.appendChild(h); const d = document.createElement("img"); BI(i, o).then((e => { d.src = e, h.classList.remove("show"), d.classList.add("show") })).catch((e => { console.error(e) })), c.appendChild(d); const u = document.createElement("img"); u.className = "checkmark", u.src = "images/checkmark.svg", l.appendChild(u); const p = document.createElement("div"); p.className = "left", l.appendChild(p); const f = document.createElement("p"); f.className = "position", f.textContent = e.toString(), p.appendChild(f); const m = document.createElement("span"); m.textContent = jI.getPositionSuffix(e), f.appendChild(m); const g = document.createElement("p"); g.textContent = fk.formatTimeString(n), p.appendChild(g); const v = document.createElement("div"); v.className = "right", l.appendChild(v); const w = document.createElement("div"); w.className = "name-container", v.appendChild(w); const y = document.createElement("span"); if (y.className = "name", y.textContent = t, w.appendChild(y), a) { const e = document.createElement("span"); e.className = "self", e.textContent = "(" + yR(this, YI, "f").get("You") + ")", w.appendChild(e) } const A = document.createElement("p"); r == HI.Pending ? (A.innerHTML = '', A.prepend(document.createTextNode(yR(this, YI, "f").get("Pending"))), A.className = "verified-state pending") : r == HI.Verified ? (A.innerHTML = '', A.prepend(document.createTextNode(yR(this, YI, "f").get("Verified"))), A.className = "verified-state verified") : r == HI.InvalidDuplicate ? (A.innerHTML = '', A.prepend(document.createTextNode(yR(this, YI, "f").get("Duplicate"))), A.className = "verified-state invalid") : (A.innerHTML = '', A.prepend(document.createTextNode(yR(this, YI, "f").get("Invalid"))), A.className = "verified-state invalid"), v.appendChild(A) }, vR = function e() { yR(this, sR, "f").innerHTML = ""; const t = document.createElement("button"); let n; t.className = "button", t.textContent = "<", yR(this, hR, "f") > 0 ? t.addEventListener("click", (() => { yR(this, qI, "f").playUIClick(), wR(this, hR, yR(this, hR, "f") - 1, "f"), yR(this, GI, "m", e).call(this), yR(this, GI, "m", mR).call(this, !1) })) : t.disabled = !0, yR(this, sR, "f").appendChild(t), n = yR(this, hR, "f") < 1e3 - Math.ceil(3.5) ? 7 : yR(this, hR, "f") < 1e5 - Math.ceil(2.5) ? 5 : 3; const i = Math.max(0, yR(this, hR, "f") - Math.floor(n / 2)); for (let t = i; t < i + n; ++t) { const n = document.createElement("button"); n.textContent = (t + 1).toString(), t >= yR(this, dR, "f") ? (n.className = "button page", n.disabled = !0) : t == yR(this, hR, "f") ? n.className = "button page selected" : (n.className = "button page", n.addEventListener("click", (() => { yR(this, qI, "f").playUIClick(), wR(this, hR, t, "f"), yR(this, GI, "m", e).call(this), yR(this, GI, "m", mR).call(this, !1) }))), yR(this, sR, "f").appendChild(n) } const r = document.createElement("button"); r.className = "button", r.textContent = ">", yR(this, hR, "f") + 1 >= yR(this, dR, "f") ? r.disabled = !0 : r.addEventListener("click", (() => { yR(this, qI, "f").playUIClick(), wR(this, hR, yR(this, hR, "f") + 1, "f"), yR(this, GI, "m", e).call(this), yR(this, GI, "m", mR).call(this, !1) })), yR(this, sR, "f").appendChild(r) }; const bR = AR; var xR, kR, ER, SR, MR, TR, _R, CR, PR, IR, RR, LR, DR, NR, BR, UR, zR = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, OR = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; kR = new WeakMap, ER = new WeakMap, SR = new WeakMap, MR = new WeakMap, TR = new WeakMap, _R = new WeakMap, CR = new WeakMap, PR = new WeakMap, IR = new WeakMap, RR = new WeakMap, LR = new WeakMap, DR = new WeakMap, NR = new WeakMap, BR = new WeakMap, xR = new WeakSet, UR = function() { OR(this, BR, "f").length > 0 ? (OR(this, IR, "f").classList.remove("no-opponents"), 1 == OR(this, BR, "f").length ? OR(this, IR, "f").textContent = OR(this, kR, "f").get("{0} opponent selected", [OR(this, BR, "f").length.toString()]) : OR(this, IR, "f").textContent = OR(this, kR, "f").get("{0} opponents selected", [OR(this, BR, "f").length.toString()])) : (OR(this, IR, "f").classList.add("no-opponents"), OR(this, IR, "f").textContent = OR(this, kR, "f").get("Select opponents to race against from the leaderboard on the left")), OR(this, RR, "f").disabled = 0 == OR(this, BR, "f").length && null == OR(this, SR, "f").getRecord(OR(this, MR, "f").profileSlot, OR(this, TR, "f")) }; const FR = class { constructor(e, t, n, i, r, a, s, o, l, c, h, d, u, p, f, m, g) { var v; xR.add(this), kR.set(this, void 0), ER.set(this, void 0), SR.set(this, void 0), MR.set(this, void 0), TR.set(this, void 0), _R.set(this, void 0), CR.set(this, void 0), PR.set(this, void 0), IR.set(this, void 0), RR.set(this, void 0), LR.set(this, void 0), DR.set(this, void 0), NR.set(this, null), BR.set(this, []), zR(this, kR, t, "f"), zR(this, ER, n, "f"), zR(this, SR, r, "f"), zR(this, MR, i, "f"), zR(this, TR, c, "f"), zR(this, _R, e, "f"), zR(this, CR, document.createElement("div"), "f"), OR(this, CR, "f").className = "track-info", e.appendChild(OR(this, CR, "f")); const w = r.getRecord(i.profileSlot, c); zR(this, LR, new bR(OR(this, CR, "f"), c, t, n, a, i, r, d, u, (e => { zR(this, BR, e, "f"), OR(this, xR, "m", UR).call(this) }), (e => { null == e || null != w && !e.time.lessOrEqual(w.time) ? null != w ? (C.textContent = fk.formatTimeString(w.time), C.classList.remove("no-record")) : (C.textContent = t.get("No record"), C.classList.add("no-record")) : (C.textContent = fk.formatTimeString(e.time) + " - " + e.position.toString() + bR.getPositionSuffix(e.position), C.classList.remove("no-record")) })), "f"), zR(this, PR, document.createElement("div"), "f"), OR(this, PR, "f").className = "side-panel", OR(this, CR, "f").appendChild(OR(this, PR, "f")); const y = document.createElement("h2"); y.textContent = o.name, OR(this, PR, "f").appendChild(y); const A = document.createElement("canvas"); A.width = h.width, A.height = h.height; const b = A.getContext("2d"); null == b ? console.error("Failed to get 2D context for thumbnail canvas") : b.drawImage(h, 0, 0); const x = document.createElement("div"); x.className = "thumbnail", x.appendChild(A), OR(this, PR, "f").appendChild(x); const k = document.createElement("button"); let E; switch (k.className = "button share", k.innerHTML = '', k.addEventListener("click", (() => { a.playUIClick(), OR(this, CR, "f").className = "hidden"; const e = l.toExportString(o); zR(this, NR, new Hx(e, (() => { var e; null === (e = OR(this, NR, "f")) || void 0 === e || e.dispose(), zR(this, NR, null, "f"), OR(this, CR, "f").className = "track-info" }), null, !1, t, a, d, s), "f") })), x.appendChild(k), l.environment) { case QA.Summer: E = "images/summer.svg"; break; case QA.Winter: E = "images/winter.svg"; break; case QA.Desert: E = "images/desert.svg" } const S = document.createElement("img"); S.className = "environment", S.src = E, x.appendChild(S); const M = document.createElement("div"); M.className = "track-author", M.textContent = t.get("Author") + ": " + (null !== (v = o.author) && void 0 !== v ? v : t.get("Unknown")), OR(this, PR, "f").appendChild(M); const T = document.createElement("div"); T.className = "divider", OR(this, PR, "f").appendChild(T); const _ = document.createElement("div"); _.className = "personal-best-title", _.textContent = t.get("Personal best"), OR(this, PR, "f").appendChild(_); const C = document.createElement("div"); C.className = "personal-best", null != w ? (C.textContent = fk.formatTimeString(w.time), C.classList.remove("no-record")) : (C.textContent = t.get("No record"), C.classList.add("no-record")), OR(this, PR, "f").appendChild(C); const P = document.createElement("div"); P.className = "divider", OR(this, PR, "f").appendChild(P); const I = document.createElement("div"); I.className = "opponents-title", I.textContent = t.get("Opponents"), OR(this, PR, "f").appendChild(I), zR(this, IR, document.createElement("div"), "f"), OR(this, IR, "f").className = "opponents-container", OR(this, PR, "f").appendChild(OR(this, IR, "f")), zR(this, RR, document.createElement("button"), "f"), OR(this, RR, "f").className = "button watch", OR(this, RR, "f").innerHTML = '', OR(this, RR, "f").disabled = !0, OR(this, RR, "f").prepend(document.createTextNode(t.get("Watch"))), OR(this, RR, "f").addEventListener("click", (() => { if (a.playUIClick(), l.hasStartingPoint()) { const e = OR(this, BR, "f"); if (e.length > 0) m(OR(this, ER, "f").getRecordings(e.map((e => e.recordingId))).then((t => { if (t.some((e => null == e))) throw new Error("Failed to load at least one recording."); return t.filter((e => null != e)).map(((t, n) => ({ recording: t.recording, carColors: t.carColors, name: e[n].name, time: t.time, isSelf: e[n].isSelf }))) }))); else { const e = r.getRecord(i.profileSlot, c); if (null != e) { const t = i.getCurrentUserProfile(); g([{ recording: e.recording, carColors: t.carColors, name: t.nickname, time: e.time, isSelf: !0 }]) } } } else OR(this, CR, "f").classList.add("hidden"), s.show(t.get("Track is missing starting point"), t.get("Ok"), (() => { OR(this, CR, "f").classList.remove("hidden") })) })), OR(this, PR, "f").appendChild(OR(this, RR, "f")), OR(this, xR, "m", UR).call(this); const R = document.createElement("button"); R.className = "button play", R.innerHTML = '', R.prepend(document.createTextNode(t.get("Play"))), R.addEventListener("click", (() => { if (a.playUIClick(), l.hasStartingPoint()) { const e = OR(this, BR, "f"); if (e.length > 0) p(OR(this, ER, "f").getRecordings(e.map((e => e.recordingId))).then((t => { if (t.some((e => null == e))) throw new Error("Failed to load at least one recording."); return t.filter((e => null != e)).map(((t, n) => ({ recording: t.recording, carColors: t.carColors, name: e[n].name, time: t.time, isSelf: e[n].isSelf }))) }))); else { const e = r.getRecord(i.profileSlot, c); if (null != e) { const t = i.getCurrentUserProfile(); f([{ recording: e.recording, carColors: t.carColors, name: t.nickname, time: e.time, isSelf: !0 }]) } else f([]) } } else OR(this, CR, "f").classList.add("hidden"), s.show(t.get("Track is missing starting point"), t.get("Ok"), (() => { OR(this, CR, "f").classList.remove("hidden") })) })), OR(this, PR, "f").appendChild(R), window.addEventListener("keydown", zR(this, DR, (e => { "Escape" == e.code && (u(), e.preventDefault()) }), "f")) } dispose() { OR(this, LR, "f").dispose(), OR(this, _R, "f").removeChild(OR(this, CR, "f")), window.removeEventListener("keydown", OR(this, DR, "f")) } }; var WR = n(5140), VR = {}; VR.styleTagTransform = u(), VR.setAttributes = l(), VR.insert = s().bind(null, "head"), VR.domAPI = r(), VR.insertStyleElement = h(); t()(WR.A, VR); WR.A && WR.A.locals && WR.A.locals; var HR, GR, jR, QR, YR, KR, qR, XR, ZR, JR, $R = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, eL = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; GR = new WeakMap, jR = new WeakMap, QR = new WeakMap, YR = new WeakMap, KR = new WeakMap, qR = new WeakMap, XR = new WeakMap, ZR = new WeakMap, HR = new WeakSet, JR = function(e, t) { const n = eL(this, YR, "f").getUserProfile(e), i = document.createElement("div"); i.className = "slot"; const r = document.createElement("button"); if (r.className = "button main", e == eL(this, YR, "f").profileSlot && r.classList.add("selected"), r.addEventListener("click", (() => { eL(this, QR, "f").playUIClick(); for (const e of eL(this, qR, "f")) e.classList.remove("selected"); r.classList.add("selected"), t(e) })), i.appendChild(r), eL(this, qR, "f").push(r), null != n) { const e = document.createElement("div"); e.className = "image-container", r.appendChild(e); const t = document.createElement("img"); t.className = "placeholder show", t.src = "images/car_thumbnail_placeholder.png", e.appendChild(t); const i = document.createElement("img"); BI(n.carColors, eL(this, ZR, "f")).then((e => { i.src = e, t.classList.remove("show"), i.classList.add("show") })).catch((e => { console.error(e) })), e.appendChild(i); const a = document.createElement("p"); a.className = "name", a.textContent = n.nickname, r.appendChild(a) } else { const e = document.createElement("div"); e.className = "image-container", r.appendChild(e); const t = document.createElement("img"); t.className = "show", t.src = "images/car_thumbnail_placeholder.png", e.appendChild(t); const n = document.createElement("p"); n.className = "name empty", n.textContent = eL(this, jR, "f").get("Empty"), r.appendChild(n) } eL(this, KR, "f").appendChild(i) }; const tL = class { constructor(e, t, n, i, r, a) { HR.add(this), GR.set(this, void 0), jR.set(this, void 0), QR.set(this, void 0), YR.set(this, void 0), KR.set(this, void 0), qR.set(this, []), XR.set(this, void 0), ZR.set(this, new WI); const s = document.getElementById("ui"); if (null == s) throw new Error("UI element not found"); $R(this, GR, s, "f"), $R(this, jR, e, "f"), $R(this, QR, t, "f"), $R(this, YR, n, "f"), $R(this, KR, document.createElement("div"), "f"), eL(this, KR, "f").className = "profile-selection", eL(this, GR, "f").appendChild(eL(this, KR, "f")); const o = document.createElement("div"); o.className = "top-bar", eL(this, KR, "f").appendChild(o); const l = document.createElement("h2"); l.textContent = e.get("Profiles"), o.appendChild(l); for (let e = 0; e < 3; e++) eL(this, HR, "m", JR).call(this, e, a); const c = document.createElement("div"); c.className = "bottom-bar", eL(this, KR, "f").appendChild(c); const h = document.createElement("button"); h.className = "button", h.innerHTML = ' ', h.append(document.createTextNode(e.get("Back"))), h.addEventListener("click", (() => { t.playUIClick(), i() })), c.appendChild(h); const d = document.createElement("button"); d.className = "button right", d.innerHTML = ' ', d.append(document.createTextNode(e.get("Import"))), d.addEventListener("click", (() => { t.playUIClick(), r() })), c.appendChild(d), window.addEventListener("keydown", $R(this, XR, (e => { "Escape" == e.code && (i(), e.preventDefault()) }), "f")) } dispose() { eL(this, ZR, "f").cancel(), eL(this, GR, "f").removeChild(eL(this, KR, "f")), window.removeEventListener("keydown", eL(this, XR, "f")) } }; var nL = n(6474), iL = {}; iL.styleTagTransform = u(), iL.setAttributes = l(), iL.insert = s().bind(null, "head"), iL.domAPI = r(), iL.insertStyleElement = h(); t()(nL.A, iL); nL.A && nL.A.locals && nL.A.locals; class rL { constructor(e = gL.createToken(), t = gL.defaultNickname, n = Pu.random()) { this.token = e, this.nickname = t, this.carColors = n } get tokenHash() { return (0, LA.sha256)(this.token) } clone() { return new rL(this.token, this.nickname, this.carColors) } } const aL = rL; var sL, oL, lL, cL, hL, dL, uL, pL = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, fL = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class mL { constructor(e) { var t; sL.add(this), lL.set(this, void 0), cL.set(this, void 0), hL.set(this, void 0), pL(this, lL, e, "f"), pL(this, cL, null !== (t = fL(this, lL, "f").loadUserProfileSlot()) && void 0 !== t ? t : 0, "f"), pL(this, hL, fL(this, sL, "m", uL).call(this, fL(this, cL, "f")), "f") } static createToken() { let e = ""; try { const t = new Uint8Array(32); crypto.getRandomValues(t), e += t.toString() } catch (e) {} try { e += crypto.randomUUID() } catch (e) {} if (0 == e.length) throw new Error("Failed to generate user token"); return (0, LA.sha256)(e) } createProfile(e, t, n, i) { return !!this.isValidToken(t) && (fL(this, lL, "f").saveUserProfile(e, t, n, i), null != fL(this, lL, "f").loadUserProfile(e)) } isValidToken(e) { return !(!/^[0-9a-f]*$/.test(e) || 64 != e.length) } hasDuplicateToken(e) { var t; for (let n = 0; n < 3; n++) if ((null === (t = fL(this, lL, "f").loadUserProfile(n)) || void 0 === t ? void 0 : t.token) == e) return !0; return !1 } firstOccupiedProfileSlot() { for (let e = 0; e < 3; e++) if (null != fL(this, lL, "f").loadUserProfile(e)) return e; return null } firstFreeProfileSlot() { for (let e = 0; e < 3; e++) if (null == fL(this, lL, "f").loadUserProfile(e)) return e; return null } deleteProfileSlot(e) { fL(this, lL, "f").deleteAllRecords(e), fL(this, lL, "f").deleteUserProfile(e) } setProfileSlot(e) { if (!Number.isSafeInteger(e) || e < 0) throw new Error("Profile slot is invalid"); pL(this, cL, e, "f"), pL(this, hL, fL(this, sL, "m", uL).call(this, fL(this, cL, "f")), "f"), fL(this, lL, "f").saveUserProfileSlot(fL(this, cL, "f")) } setNickname(e, t = fL(this, cL, "f")) { let n; n = t == fL(this, cL, "f") ? fL(this, hL, "f") : fL(this, sL, "m", uL).call(this, t), n.nickname = e, fL(this, lL, "f").saveUserProfile(t, n.token, n.nickname, n.carColors) } setCarColors(e, t = fL(this, cL, "f")) { let n; n = t == fL(this, cL, "f") ? fL(this, hL, "f") : fL(this, sL, "m", uL).call(this, t), n.carColors = e, fL(this, lL, "f").saveUserProfile(t, n.token, n.nickname, n.carColors) } get profileSlot() { return fL(this, cL, "f") } getCurrentUserProfile() { return fL(this, hL, "f").clone() } getUserProfile(e) { if (e == fL(this, cL, "f")) return this.getCurrentUserProfile(); { const t = fL(this, lL, "f").loadUserProfile(e); return null == t ? null : new aL(t.token, t.nickname, t.carColors) } } syncUserProfile(e) { const t = this.getCurrentUserProfile(); e.getUser(t.token).then((e => { if (null == e) return; const n = this.getCurrentUserProfile(); n.token == t.token && n.nickname == t.nickname && n.carColors.serialize() == t.carColors.serialize() && (this.setNickname(e.name), this.setCarColors(e.carColors)) })).catch((e => { console.error(e) })) } } oL = mL, lL = new WeakMap, cL = new WeakMap, hL = new WeakMap, sL = new WeakSet, dL = function(e) { const t = oL.createToken(), n = oL.defaultNickname, i = Pu.random(); fL(this, lL, "f").saveUserProfile(e, t, n, i) }, uL = function(e) { null == fL(this, lL, "f").loadUserProfile(e) && fL(this, sL, "m", dL).call(this, e); const t = fL(this, lL, "f").loadUserProfile(e); return null == t ? new aL : new aL(t.token, t.nickname, t.carColors) }, mL.defaultNickname = "Anonymous"; const gL = mL; function vL(e) { return new Blob([e]).size } var wL, yL, AL, bL, xL, kL, EL, SL, ML, TL = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, _L = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; yL = new WeakMap, AL = new WeakMap, bL = new WeakMap, xL = new WeakMap, kL = new WeakMap, EL = new WeakMap, SL = new WeakMap, wL = new WeakSet, ML = function() { let e = _L(this, xL, "f").value; return /\S/.test(e) || (e = "Anonymous"), e }; const CL = class { constructor(e, t, n, i, r, a, s, o, l) { wL.add(this), yL.set(this, void 0), AL.set(this, !1), bL.set(this, void 0), xL.set(this, void 0), kL.set(this, null), EL.set(this, null), SL.set(this, void 0); const c = document.getElementById("ui"); if (null == c) throw new Error("UI element not found"); TL(this, yL, c, "f"), TL(this, bL, document.createElement("div"), "f"), _L(this, bL, "f").className = "nickname", _L(this, yL, "f").appendChild(_L(this, bL, "f")); const h = document.createElement("h1"); h.textContent = e.get("Nickname"), _L(this, bL, "f").appendChild(h), TL(this, xL, document.createElement("input"), "f"), _L(this, xL, "f").type = "text", _L(this, xL, "f").placeholder = gL.defaultNickname, _L(this, xL, "f").spellcheck = !1, null != r ? _L(this, xL, "f").value = r : null != i && i.nickname != _L(this, xL, "f").placeholder && (_L(this, xL, "f").value = i.nickname), _L(this, bL, "f").appendChild(_L(this, xL, "f")), _L(this, xL, "f").focus(), _L(this, xL, "f").addEventListener("input", (() => { let e = _L(this, xL, "f").value; for (; vL(e) >= 50;) e = e.substring(0, e.length - 1); _L(this, xL, "f").value = e })), _L(this, xL, "f").addEventListener("keydown", (e => { "Enter" == e.code && (o(_L(this, wL, "m", ML).call(this)), e.preventDefault()) })); const d = document.createElement("p"); d.textContent = e.get("Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time."), _L(this, bL, "f").appendChild(d); const u = document.createElement("button"); u.className = "button delete", u.innerHTML = ' ', u.append(e.get("Delete")), u.addEventListener("click", (() => { t.playUIClick(), a(_L(this, wL, "m", ML).call(this)) })), _L(this, bL, "f").appendChild(u); const p = document.createElement("button"); p.className = "button", p.innerHTML = ' ', p.append(e.get("Export")), p.addEventListener("click", (() => { var e; t.playUIClick(), s(_L(this, wL, "m", ML).call(this), null !== (e = null == i ? void 0 : i.token) && void 0 !== e ? e : "") })), _L(this, bL, "f").appendChild(p); const f = document.createElement("button"); f.className = "button", f.textContent = e.get("Ok"), f.addEventListener("click", (() => { t.playUIClick(), o(_L(this, wL, "m", ML).call(this)) })), _L(this, bL, "f").appendChild(f), null != i && n.getUser(i.token).then((n => { const r = 1 == (null == n ? void 0 : n.isVerifier); !_L(this, AL, "f") && r && (TL(this, kL, document.createElement("button"), "f"), _L(this, kL, "f").className = "button nickname-verifier-button", _L(this, kL, "f").textContent = e.get("Verifier"), _L(this, kL, "f").addEventListener("click", (() => { t.playUIClick(), l(i.token) })), _L(this, yL, "f").appendChild(_L(this, kL, "f"))) })).catch((e => { console.error(e) })), null != (null == i ? void 0 : i.tokenHash) && (TL(this, EL, document.createElement("p"), "f"), _L(this, EL, "f").className = "nickname-user-token", _L(this, EL, "f").textContent = e.get("User ID") + ": " + i.tokenHash, _L(this, yL, "f").appendChild(_L(this, EL, "f"))), window.addEventListener("keydown", TL(this, SL, (e => { "Escape" == e.code && (o(_L(this, wL, "m", ML).call(this)), e.preventDefault()) }), "f")) } dispose() { _L(this, yL, "f").removeChild(_L(this, bL, "f")), null != _L(this, kL, "f") && _L(this, yL, "f").removeChild(_L(this, kL, "f")), null != _L(this, EL, "f") && _L(this, yL, "f").removeChild(_L(this, EL, "f")), window.removeEventListener("keydown", _L(this, SL, "f")), TL(this, AL, !0, "f") } }; var PL = n(7818), IL = {}; IL.styleTagTransform = u(), IL.setAttributes = l(), IL.insert = s().bind(null, "head"), IL.domAPI = r(), IL.insertStyleElement = h(); t()(PL.A, IL); PL.A && PL.A.locals && PL.A.locals; var RL, LL, DL, NL = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, BL = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; RL = new WeakMap, LL = new WeakMap, DL = new WeakMap; const UL = class { constructor(e, t, n, i, r) { RL.set(this, void 0), LL.set(this, void 0), DL.set(this, void 0); const a = document.getElementById("ui"); if (null == a) throw new Error("UI element not found"); NL(this, RL, a, "f"), NL(this, LL, document.createElement("div"), "f"), BL(this, LL, "f").className = "user-export", BL(this, RL, "f").appendChild(BL(this, LL, "f")); const s = document.createElement("textarea"); s.value = n, s.readOnly = null == r, s.placeholder = "Paste user token here...", BL(this, LL, "f").appendChild(s); const o = document.createElement("div"); o.className = "bar", BL(this, LL, "f").appendChild(o); const l = document.createElement("button"); if (l.className = "button", l.innerHTML = ' ', l.append(document.createTextNode(t.get("Back"))), l.addEventListener("click", (() => { e.playUIClick(), i() })), o.appendChild(l), null != r) { const n = document.createElement("button"); n.className = "button right", n.innerHTML = ' ', n.append(document.createTextNode(t.get("Import"))), n.addEventListener("click", (() => { e.playUIClick(), r(s.value) })), o.appendChild(n) } else { const n = document.createElement("button"); n.className = "button right", n.innerHTML = ' ', n.append(document.createTextNode(t.get("Copy"))), n.addEventListener("click", (() => { e.playUIClick(); try { navigator.clipboard.writeText(s.value).catch((e => { console.error(e) })) } catch (e) { console.error(e) } })), o.appendChild(n) } window.addEventListener("keydown", NL(this, DL, (e => { "Escape" == e.code && (i(), e.preventDefault()) }), "f")) } dispose() { BL(this, RL, "f").removeChild(BL(this, LL, "f")), window.removeEventListener("keydown", BL(this, DL, "f")) } }; try { if (void 0 !== window.BroadcastChannel) { const e = new window.BroadcastChannel("polytrack-single-instance"); e.addEventListener("message", (t => { "new-instance" == t.data && zL && e.postMessage("conflict"), "conflict" == t.data && (zL = !1) })), e.postMessage("new-instance"), window.addEventListener("beforeunload", (() => { e.close() })) } } catch (e) { console.error(e) } let zL = !0; function OL() { let e; switch (Jd) { case "kodub": case "electron": case "capacitor": case "jest": e = " "; break; case "itch": e = " "; break; case "armorgames": e = "https://armorgames.com/polytrack-game/19464"; break; case "gato": e = "https://gato.us/game/poly-track"; break; case "crazygames": e = "https://www.crazygames.com/game/polytrack"; break; case "poki": e = "https://poki.com/en/g/polytrack"; break; case "y8": e = "https://www.y8.com/games/poly_track" } return e } var FL, WL, VL, HL, GL, jL, QL, YL, KL, qL, XL, ZL, JL, $L, eD, tD, nD, iD, rD, aD, sD, oD, lD, cD, hD, dD, uD, pD, fD, mD, gD, vD = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, wD = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; WL = new WeakMap, VL = new WeakMap, HL = new WeakMap, GL = new WeakMap, jL = new WeakMap, QL = new WeakMap, YL = new WeakMap, KL = new WeakMap, qL = new WeakMap, XL = new WeakMap, ZL = new WeakMap, JL = new WeakMap, $L = new WeakMap, eD = new WeakMap, tD = new WeakMap, nD = new WeakMap, iD = new WeakMap, rD = new WeakMap, aD = new WeakMap, sD = new WeakMap, oD = new WeakMap, lD = new WeakMap, FL = new WeakSet, cD = function(e, t, n, i, r, a, s, o, l, c) { return new $k(wD(this, GL, "f"), e, t, n, i, r, a, s, !1, (() => { wD(this, qL, "f").hide(), wD(this, FL, "m", pD).call(this), wD(this, FL, "m", mD).call(this) }), ((s, h, d, u, p) => { wD(this, qL, "f").hide(); const f = () => { var e; wD(this, qL, "f").show(), null === (e = wD(this, XL, "f")) || void 0 === e || e.dispose(), vD(this, XL, null, "f") }, m = e => { var t; null === (t = wD(this, XL, "f")) || void 0 === t || t.dispose(), vD(this, XL, null, "f"), l(s, h, d, e) }, g = c => { var y; null === (y = wD(this, XL, "f")) || void 0 === y || y.dispose(), vD(this, XL, null, "f"), o.determinismState != VI.Ok ? a.show(e.get("Cannot load recordings due to non-determinism"), e.get("Ok"), (() => { vD(this, XL, new FR(wD(this, GL, "f"), e, o, r, n, t, a, s, h, u, p, i, f, g, m, v, w), "f") })) : c.then((e => { l(s, h, d, e) })).catch((() => { a.show(e.get("Failed to load recordings"), e.get("Ok"), (() => { vD(this, XL, new FR(wD(this, GL, "f"), e, o, r, n, t, a, s, h, u, p, i, f, g, m, v, w), "f") })) })) }, v = l => { var y; null === (y = wD(this, XL, "f")) || void 0 === y || y.dispose(), vD(this, XL, null, "f"), o.determinismState != VI.Ok ? a.show(e.get("Cannot load recordings due to non-determinism"), e.get("Ok"), (() => { vD(this, XL, new FR(wD(this, GL, "f"), e, o, r, n, t, a, s, h, u, p, i, f, g, m, v, w), "f") })) : l.then((e => { c(s, h, d, e) })).catch((() => { a.show(e.get("Failed to load recordings"), e.get("Ok"), (() => { vD(this, XL, new FR(wD(this, GL, "f"), e, o, r, n, t, a, s, h, u, p, i, f, g, m, v, w), "f") })) })) }, w = e => { var t; null === (t = wD(this, XL, "f")) || void 0 === t || t.dispose(), vD(this, XL, null, "f"), c(s, h, d, e) }; vD(this, XL, new FR(wD(this, GL, "f"), e, o, r, n, t, a, s, h, u, p, i, f, g, m, v, w), "f"), wD(this, FL, "m", fD).call(this) })) }, hD = function e(t, n, i, r, a, s, o, l, c, h, d, u, p, f, m, g) { for (const e of wD(this, iD, "f")) wD(this, nD, "f").removeChild(e); vD(this, iD, [], "f"); for (const e of wD(this, aD, "f")) wD(this, rD, "f").removeChild(e); vD(this, aD, [], "f"); const v = document.createElement("button"); v.className = "button button-image", v.innerHTML = '', v.addEventListener("click", (() => { n.playUIClick(), u() })); const w = document.createElement("p"); w.textContent = t.get("Customize"), v.appendChild(w), wD(this, nD, "f").appendChild(v), wD(this, iD, "f").push(v); const y = document.createElement("button"); y.className = "button button-image", y.innerHTML = '', y.addEventListener("click", (() => { n.playUIClick(), p() })); const A = document.createElement("p"); A.textContent = t.get("Editor"), y.appendChild(A), wD(this, nD, "f").appendChild(y), wD(this, iD, "f").push(y); const b = document.createElement("button"); b.className = "button button-image", b.innerHTML = '', b.addEventListener("click", (() => { n.playUIClick(), wD(this, FL, "m", uD).call(this), wD(this, FL, "m", fD).call(this), vD(this, ZL, new kI(wD(this, GL, "f"), t, n, r, a, d, (() => { var v; null === (v = wD(this, ZL, "f")) || void 0 === v || v.dispose(), vD(this, ZL, null, "f"), wD(this, qL, "f").dispose(), vD(this, qL, wD(this, FL, "m", cD).call(this, t, n, l, s, o, d, c, h, f, m), "f"), wD(this, FL, "m", dD).call(this, t), wD(this, FL, "m", e).call(this, t, n, i, r, a, s, o, l, c, h, d, u, p, f, m, g), wD(this, FL, "m", pD).call(this), wD(this, FL, "m", mD).call(this) })), "f") })); const x = document.createElement("p"); x.textContent = t.get("Settings"), b.appendChild(x), wD(this, nD, "f").appendChild(b), wD(this, iD, "f").push(b); const k = document.createElement("button"); k.className = "button button-image", k.innerHTML = '', k.addEventListener("click", (() => { n.playUIClick(), wD(this, FL, "m", uD).call(this); const e = (i, a) => { vD(this, eD, new UL(n, t, a, (() => { var e; null === (e = wD(this, eD, "f")) || void 0 === e || e.dispose(), vD(this, eD, null, "f"), r() }), (n => { var a; null === (a = wD(this, eD, "f")) || void 0 === a || a.dispose(), vD(this, eD, null, "f"), o.hasDuplicateToken(n) ? d.show(t.get("You cannot have duplicate user profiles"), t.get("Ok"), (() => { e(i, n) })) : o.isValidToken(n) ? h.getUser(n).then((a => { null != a ? o.createProfile(i, n, a.name, a.carColors) ? (o.setProfileSlot(i), wD(this, qL, "f").refresh(), r()) : d.show(t.get("Failed to create user profile"), t.get("Ok"), (() => { e(i, n) })) : d.show(t.get("This user profile does not exist on the server"), t.get("Ok"), (() => { e(i, n) })) })).catch((r => { console.error(r), d.show(t.get("Failed to download user profile from the server"), t.get("Ok"), (() => { e(i, n) })) })) : d.show(t.get("User token is invalid"), t.get("Ok"), (() => { e(i, n) })) })), "f") }, i = (e, a) => { var s; null === (s = wD(this, JL, "f")) || void 0 === s || s.dispose(), vD(this, JL, null, "f"); const l = o.getUserProfile(e); vD(this, $L, new CL(t, n, h, l, a, (n => { var a; null === (a = wD(this, $L, "f")) || void 0 === a || a.dispose(), vD(this, $L, null, "f"), d.showConfirm(t.get('Are you sure you would like to delete "{0}"?', [n]), t.get("Cancel"), t.get("Confirm"), (() => { i(e, n) }), (() => { var t; o.deleteProfileSlot(e), e == o.profileSlot && (o.setProfileSlot(null !== (t = o.firstOccupiedProfileSlot()) && void 0 !== t ? t : 0), wD(this, qL, "f").refresh()), r() })) }), ((r, a) => { var s; null === (s = wD(this, $L, "f")) || void 0 === s || s.dispose(), vD(this, $L, null, "f"), d.showConfirm(t.get("Are you sure you want to display your private key?") + "\n\n" + t.get("DO NOT SHARE THIS KEY WITH ANYONE."), t.get("Cancel"), t.get("Confirm"), (() => { i(e, r) }), (() => { vD(this, eD, new UL(n, t, a, (() => { var t; null === (t = wD(this, eD, "f")) || void 0 === t || t.dispose(), vD(this, eD, null, "f"), i(e, r) }), null), "f") })) }), (t => { var n; if (null === (n = wD(this, $L, "f")) || void 0 === n || n.dispose(), vD(this, $L, null, "f"), t != (null == l ? void 0 : l.nickname)) { o.setNickname(t, e); const n = o.getUserProfile(e); null != n && h.submitUserProfile(n.token, n.nickname, n.carColors).catch((e => { console.warn(e) })) } o.setProfileSlot(e), wD(this, qL, "f").refresh(), r() }), (e => { var t; null === (t = wD(this, $L, "f")) || void 0 === t || t.dispose(), vD(this, $L, null, "f"), g(e), wD(this, FL, "m", pD).call(this) })), "f") }, r = () => { vD(this, JL, new tL(t, n, o, (() => { var e; null === (e = wD(this, JL, "f")) || void 0 === e || e.dispose(), vD(this, JL, null, "f"), wD(this, FL, "m", pD).call(this) }), (() => { var n; null === (n = wD(this, JL, "f")) || void 0 === n || n.dispose(), vD(this, JL, null, "f"); const i = o.firstFreeProfileSlot(); null == i ? d.show(t.get("You need a free user profile slot to import a new user profile"), t.get("Ok"), (() => { r() })) : e(i, "") }), (e => { i(e, null) })), "f") }; r() })); const E = document.createElement("p"); E.textContent = t.get("Profile"), k.appendChild(E), wD(this, nD, "f").appendChild(k), wD(this, iD, "f").push(k); const S = document.createElement("button"); S.className = "button button-image", S.innerHTML = '', S.addEventListener("click", (() => { n.playUIClick(), wD(this, FL, "m", uD).call(this), wD(this, FL, "m", fD).call(this), wD(this, qL, "f").show() })); const M = document.createElement("p"); if (M.textContent = t.get("Play"), S.appendChild(M), wD(this, nD, "f").appendChild(S), wD(this, iD, "f").push(S), window.electron) { const e = document.createElement("button"); e.className = "button small", e.innerHTML = '', e.appendChild(document.createTextNode(" " + t.get("Quit"))), e.addEventListener("click", (() => { var e; n.playUIClick(), null === (e = window.electron) || void 0 === e || e.quit() })), wD(this, rD, "f").appendChild(e), wD(this, aD, "f").push(e) } { const e = document.createElement("button"); e.className = "button small", i.isFullscreen ? (e.innerHTML = '', e.appendChild(document.createTextNode(" " + t.get("Windowed")))) : (e.innerHTML = '', e.appendChild(document.createTextNode(" " + t.get("Fullscreen")))), null != wD(this, lD, "f") && i.removeFullscreenChangeListener(wD(this, lD, "f")), i.addFullscreenChangeListener(vD(this, lD, (() => { i.isFullscreen ? (e.innerHTML = '', e.appendChild(document.createTextNode(" " + t.get("Windowed")))) : (e.innerHTML = '', e.appendChild(document.createTextNode(" " + t.get("Fullscreen")))) }), "f")), e.addEventListener("click", (() => { n.playUIClick(), i.toggleFullscreen().catch((e => { console.error(e) })) })), wD(this, rD, "f").appendChild(e), wD(this, aD, "f").push(e) } }, dD = function(e) { wD(this, YL, "f").innerHTML = ""; const t = document.createElement("a"); t.href = "https://www.kodub.com", t.target = "_blank", t.textContent = "kodub.com - " + e.get("Version") + " " + iu, wD(this, YL, "f").appendChild(t); const n = document.createElement("a"); n.href = "https://opengameart.org/content/sci-fi-theme-1", n.target = "_blank", n.textContent = 'OpenGameArt.org "Sci-fi Theme" by Maou (CC-BY 4.0)', wD(this, YL, "f").appendChild(n), wD(this, YL, "f").appendChild(document.createElement("br")); const i = document.createElement("a"); i.href = "https://www.kodub.com/privacy/polytrack", i.target = "_blank", i.textContent = "Privacy Policy", wD(this, YL, "f").appendChild(i) }, uD = function() { var e; null === (e = wD(this, tD, "f")) || void 0 === e || e.classList.add("hidden"), wD(this, nD, "f").classList.add("hidden"); for (const e of wD(this, iD, "f")) e.classList.remove("button-spawn"); for (const e of wD(this, aD, "f")) e.classList.add("hidden"); null != wD(this, QL, "f") && (wD(this, QL, "f").className = "hidden"), wD(this, YL, "f").className = "hidden" }, pD = function() { var e; null === (e = wD(this, tD, "f")) || void 0 === e || e.classList.remove("hidden"), wD(this, nD, "f").classList.remove("hidden"); for (const e of wD(this, aD, "f")) e.classList.remove("hidden"); null != wD(this, QL, "f") && (wD(this, QL, "f").className = "discord-link"), wD(this, YL, "f").className = "info" }, fD = function() { wD(this, jL, "f").className = "hidden" }, mD = function() { wD(this, jL, "f").className = "logo" }, gD = function() { const e = wD(this, VL, "f").getBounds(), t = new jt((e.min.x + (e.max.x - e.min.x) / 2) * jb.partSize, (e.min.y + (e.max.y - e.min.y) / 2) * jb.partSize); wD(this, sD, "f").position.set(t.x + 250 * Math.cos(wD(this, oD, "f")), 100, t.y - 250 * Math.sin(wD(this, oD, "f"))), wD(this, sD, "f").rotation.y = wD(this, oD, "f") + Math.PI / 2 }; const yD = class { constructor(e, t, n, i, r, a, s, o, l, c, h, d, u, p, f, m, g, v) { FL.add(this), WL.set(this, void 0), VL.set(this, void 0), HL.set(this, void 0), GL.set(this, void 0), jL.set(this, void 0), QL.set(this, void 0), YL.set(this, void 0), KL.set(this, null), qL.set(this, void 0), XL.set(this, null), ZL.set(this, null), JL.set(this, null), $L.set(this, null), eD.set(this, null), tD.set(this, void 0), nD.set(this, void 0), iD.set(this, []), rD.set(this, void 0), aD.set(this, []), sD.set(this, void 0), oD.set(this, Math.random() * Math.PI * 2), lD.set(this, null), vD(this, WL, n, "f"), vD(this, VL, r, "f"); const w = document.getElementById("ui"); if (null == w) throw new Error("UI element not found"); if (vD(this, HL, w, "f"), vD(this, GL, document.createElement("div"), "f"), wD(this, GL, "f").className = "menu", wD(this, HL, "f").appendChild(wD(this, GL, "f")), vD(this, jL, document.createElement("img"), "f"), wD(this, jL, "f").src = "images/logo.svg", wD(this, jL, "f").className = "logo", wD(this, GL, "f").appendChild(wD(this, jL, "f")), function() { let e; switch (Jd) { case "kodub": case "jest": e = [/\.kodub\.com$/]; break; case "electron": case "capacitor": return !1; case "itch": e = [/itch\.io$/, /itch\.zone$/]; break; case "armorgames": e = [/^19464\.cache\.armorgames\.com$/]; break; case "gato": e = [/^gato-files-prod\.s3\.amazonaws\.com$/]; break; case "crazygames": e = [/\.crazygames\.com$/]; break; case "poki": e = [/\.poki\.com$/, /\.poki-gdn\.com$/]; break; case "y8": e = [/\.y8\.com$/] } return !e.some((e => e.test(location.hostname))) }()) { vD(this, tD, document.createElement("div"), "f"), wD(this, tD, "f").className = "warning-message", wD(this, tD, "f").textContent = e.get(" ", ["PolyTrack"]); const t = document.createElement("a"); t.href = OL(), t.textContent = OL(), wD(this, tD, "f").appendChild(t), wD(this, GL, "f").appendChild(wD(this, tD, "f")) } else vD(this, tD, null, "f"); vD(this, qL, wD(this, FL, "m", cD).call(this, e, t, s, c, a, d, o, l, m, g), "f"), vD(this, QL, document.createElement("a"), "f"), wD(this, QL, "f").className = "discord-link", wD(this, QL, "f").href = "https://www.kodub.com/discord/polytrack", wD(this, QL, "f").target = "_blank", wD(this, QL, "f").innerHTML = '', wD(this, GL, "f").appendChild(wD(this, QL, "f")), vD(this, YL, document.createElement("div"), "f"), wD(this, YL, "f").className = "info", wD(this, GL, "f").appendChild(wD(this, YL, "f")), wD(this, FL, "m", dD).call(this, e), vD(this, nD, document.createElement("div"), "f"), wD(this, nD, "f").className = "main-buttons-container hidden", wD(this, GL, "f").appendChild(wD(this, nD, "f")), vD(this, rD, document.createElement("div"), "f"), wD(this, rD, "f").className = "bottom-buttons", wD(this, GL, "f").appendChild(wD(this, rD, "f")), wD(this, FL, "m", hD).call(this, e, t, n, h, r, c, a, s, o, l, d, p, f, m, g, v), i.hasLoaded() ? wD(this, FL, "m", pD).call(this) : (wD(this, GL, "f").classList.add("loading-screen"), vD(this, KL, new ZP(wD(this, GL, "f"), e, i), "f"), i.addCompleteListener((() => { wD(this, GL, "f").classList.remove("loading-screen"); const t = wD(this, KL, "f"); null == t || t.fadeOut((() => { t.dispose(), zL ? l.determinismState == VI.Ok ? wD(this, FL, "m", pD).call(this) : l.determinismState == VI.AssetsFailed ? (wD(this, FL, "m", fD).call(this), d.show(e.get("Non-deterministic game assets found.") + " " + e.get("Some leaderboard features are disabled.") + "\n\n" + e.get("Please try clearing your browser cache."), e.get("Ok"), (() => { wD(this, FL, "m", mD).call(this), wD(this, FL, "m", pD).call(this) }))) : (wD(this, FL, "m", fD).call(this), d.show(e.get("Computer determinism check failed.") + " " + e.get("Some leaderboard features are disabled.") + "\n\n" + e.get("Please try another browser or device."), e.get("Ok"), (() => { wD(this, FL, "m", mD).call(this), wD(this, FL, "m", pD).call(this) }))) : d.showNoButtons(e.get("You already have another instance of PolyTrack open.") + "\n\n" + e.get("Please switch to that tab or window to continue.")); for (let e = 0; e < wD(this, iD, "f").length; e++) { const t = wD(this, iD, "f")[e]; t.classList.add("button-spawn"), t.style.animationDelay = (.3 + .1 * e).toString() + "s" } })), vD(this, KL, null, "f") }))), u && (wD(this, FL, "m", uD).call(this), wD(this, FL, "m", fD).call(this), wD(this, qL, "f").show()), vD(this, sD, new Pr(70, 1, .5, Au.maxViewDistance), "f"), n.scene.add(wD(this, sD, "f")), wD(this, FL, "m", gD).call(this) } dispose() { var e; wD(this, HL, "f").removeChild(wD(this, GL, "f")), wD(this, qL, "f").dispose(), null === (e = wD(this, XL, "f")) || void 0 === e || e.dispose(), vD(this, XL, null, "f"), null != wD(this, lD, "f") && wD(this, WL, "f").removeFullscreenChangeListener(wD(this, lD, "f")) } get camera() { return wD(this, sD, "f") } update(e) { vD(this, oD, wD(this, oD, "f") + .05 * e, "f"), wD(this, FL, "m", gD).call(this) } }; var AD, bD, xD, kD, ED, SD, MD, TD, _D, CD, PD, ID, RD, LD, DD = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, ND = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; bD = new WeakMap, xD = new WeakMap, kD = new WeakMap, ED = new WeakMap, SD = new WeakMap, MD = new WeakMap, TD = new WeakMap, _D = new WeakMap, CD = new WeakMap, PD = new WeakMap, ID = new WeakMap, RD = new WeakMap, AD = new WeakSet, LD = function() { ND(this, xD, "f").loadTrackData(ND(this, SD, "f").getRandomOfficialTrackData()), ND(this, xD, "f").generateMeshes(), ND(this, kD, "f").generateMountains(ND(this, xD, "f").getBounds()); let e = null; const t = ND(this, xD, "f").getID(); if (null != t) { const n = ND(this, MD, "f").getRecord(ND(this, PD, "f").profileSlot, t); null != n && (e = n.recording) } if (null != e) { const t = ND(this, xD, "f").getStartTransform(); if (null == t) throw new Error("Start transform is null"); DD(this, RD, new Aw(ND(this, bD, "f"), t, e, null, ND(this, _D, "f"), ND(this, CD, "f"), ND(this, kD, "f"), ND(this, xD, "f"), ND(this, TD, "f")), "f"), ND(this, RD, "f").audioVolume = 0, ND(this, RD, "f").start() } }; const BD = class { constructor(e, t, n, i, r, a, s, o, l, c, h, d, u, p, f, m, g, v, w, y, A) { AD.add(this), bD.set(this, void 0), xD.set(this, void 0), kD.set(this, void 0), ED.set(this, void 0), SD.set(this, void 0), MD.set(this, void 0), TD.set(this, void 0), _D.set(this, void 0), CD.set(this, void 0), PD.set(this, void 0), ID.set(this, void 0), RD.set(this, null), DD(this, bD, e, "f"), DD(this, xD, t, "f"), DD(this, kD, n, "f"), DD(this, ED, i, "f"), DD(this, SD, r, "f"), DD(this, MD, l, "f"), DD(this, TD, u, "f"), DD(this, _D, c, "f"), DD(this, CD, h, "f"), DD(this, PD, o, "f"), DD(this, ID, new yD(a, h, c, f, t, o, l, d, p, r, u, s, m, g, v, w, y, A), "f"), c.setCamera(ND(this, ID, "f").camera), f.hasLoaded() ? ND(this, AD, "m", LD).call(this) : f.addCompleteListener((() => { ND(this, AD, "m", LD).call(this) })) } dispose() { var e; null === (e = ND(this, RD, "f")) || void 0 === e || e.dispose(), ND(this, ID, "f").dispose(), ND(this, xD, "f").clear(), ND(this, kD, "f").clearMountains() } update(e) { var t, n, i; null === (t = ND(this, RD, "f")) || void 0 === t || t.update(e), ND(this, ID, "f").update(e), ND(this, kD, "f").update(ND(this, xD, "f")), ND(this, ED, "f").update(e, ND(this, _D, "f").camera, ND(this, xD, "f").sunDirection), ND(this, CD, "f").update(e, !0, ND(this, _D, "f"), ND(this, TD, "f")), ND(this, _D, "f").update(null !== (i = null === (n = ND(this, RD, "f")) || void 0 === n ? void 0 : n.getPosition()) && void 0 !== i ? i : new yn, ND(this, xD, "f").sunDirection) } }; var UD = n(5437), zD = {}; zD.styleTagTransform = u(), zD.setAttributes = l(), zD.insert = s().bind(null, "head"), zD.domAPI = r(), zD.insertStyleElement = h(); t()(UD.A, zD); UD.A && UD.A.locals && UD.A.locals; var OD, FD, WD, VD, HD, GD, jD, QD, YD, KD, qD, XD, ZD, JD = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, $D = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; FD = new WeakMap, WD = new WeakMap, VD = new WeakMap, HD = new WeakMap, GD = new WeakMap, jD = new WeakMap, QD = new WeakMap, YD = new WeakMap, KD = new WeakMap, OD = new WeakSet, qD = function() { null == $D(this, KD, "f") && window.addEventListener("keydown", JD(this, KD, (e => { this.isOpen && ("Escape" == e.code ? (null != $D(this, QD, "f") && $D(this, QD, "f").call(this), this.hide(), e.stopImmediatePropagation(), e.preventDefault()) : "Enter" == e.code && "message" == $D(this, FD, "f") && (null != $D(this, YD, "f") && $D(this, YD, "f").call(this), this.hide(), e.stopImmediatePropagation(), e.preventDefault())) }), "f")) }, XD = function() { null != $D(this, KD, "f") && (window.removeEventListener("keydown", $D(this, KD, "f")), JD(this, KD, null, "f")) }, ZD = function() { const e = Math.max(.01, Math.min(window.innerWidth, 1.4375 * window.innerHeight) / 1150); $D(this, VD, "f").style.transform = e < 1 ? "scale(" + e.toString() + ")" : "" }; const eN = class { constructor(e) { OD.add(this), FD.set(this, null), WD.set(this, void 0), VD.set(this, void 0), HD.set(this, void 0), GD.set(this, void 0), jD.set(this, void 0), QD.set(this, null), YD.set(this, null), KD.set(this, null), JD(this, WD, document.createElement("dialog"), "f"), $D(this, WD, "f").className = "hidden", document.body.appendChild($D(this, WD, "f")), JD(this, VD, document.createElement("div"), "f"), $D(this, WD, "f").appendChild($D(this, VD, "f")), JD(this, HD, document.createElement("p"), "f"), $D(this, VD, "f").appendChild($D(this, HD, "f")), JD(this, GD, document.createElement("button"), "f"), $D(this, GD, "f").className = "button", $D(this, GD, "f").addEventListener("click", (() => { e.playUIClick(); const t = $D(this, QD, "f"); this.hide(), null != t && t() })), $D(this, VD, "f").appendChild($D(this, GD, "f")), JD(this, jD, document.createElement("button"), "f"), $D(this, jD, "f").className = "button", $D(this, jD, "f").addEventListener("click", (() => { e.playUIClick(); const t = $D(this, YD, "f"); this.hide(), null != t && t() })), $D(this, VD, "f").appendChild($D(this, jD, "f")), window.addEventListener("resize", (() => { $D(this, OD, "m", ZD).call(this) })), $D(this, OD, "m", ZD).call(this) } get isOpen() { return null != $D(this, FD, "f") } show(e, t, n) { JD(this, FD, "message", "f"), $D(this, WD, "f").className = "message-box message", $D(this, WD, "f").showModal(), $D(this, HD, "f").textContent = e, $D(this, GD, "f").textContent = "", $D(this, jD, "f").textContent = t, $D(this, GD, "f").blur(), $D(this, jD, "f").blur(), JD(this, QD, n, "f"), JD(this, YD, n, "f"), $D(this, OD, "m", qD).call(this) } showConfirm(e, t, n, i, r) { JD(this, FD, "confirm", "f"), $D(this, WD, "f").className = "message-box confirm", $D(this, WD, "f").showModal(), $D(this, HD, "f").textContent = e, $D(this, GD, "f").textContent = t, $D(this, jD, "f").textContent = n, $D(this, GD, "f").blur(), $D(this, jD, "f").blur(), JD(this, QD, i, "f"), JD(this, YD, r, "f"), $D(this, OD, "m", qD).call(this) } showNoButtons(e) { JD(this, FD, "no-buttons", "f"), $D(this, WD, "f").className = "message-box no-buttons", $D(this, WD, "f").showModal(), $D(this, HD, "f").textContent = e, $D(this, GD, "f").textContent = "", $D(this, jD, "f").textContent = "", $D(this, GD, "f").blur(), $D(this, jD, "f").blur(), JD(this, QD, null, "f"), JD(this, YD, null, "f"), $D(this, OD, "m", qD).call(this) } hide() { JD(this, FD, null, "f"), $D(this, WD, "f").className = "hidden", $D(this, WD, "f").close(), $D(this, HD, "f").textContent = "", $D(this, GD, "f").textContent = "", $D(this, jD, "f").textContent = "", JD(this, QD, null, "f"), JD(this, YD, null, "f"), $D(this, OD, "m", XD).call(this) } }; var tN, nN, iN, rN, aN = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }, sN = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }; tN = new WeakMap, nN = new WeakMap, iN = new WeakMap, rN = new WeakMap; const oN = class { constructor() { tN.set(this, 0), nN.set(this, 0), iN.set(this, []), rN.set(this, []) } hasLoaded() { return aN(this, nN, "f") == aN(this, tN, "f") } getProgress() { return aN(this, nN, "f") / aN(this, tN, "f") } addResource() { var e; sN(this, tN, (e = aN(this, tN, "f"), ++e), "f") } loadedResource() { var e; sN(this, nN, (e = aN(this, nN, "f"), ++e), "f"); for (const e of aN(this, iN, "f")) e(this.getProgress()); if (this.hasLoaded()) for (const e of aN(this, rN, "f")) e() } addProgressListener(e) { aN(this, iN, "f").push(e) } addCompleteListener(e) { aN(this, rN, "f").push(e) } preloadImage(e) { this.addResource(); const t = new Image; t.addEventListener("load", (() => { this.loadedResource() })), t.addEventListener("error", (() => { console.error("Failed to preload image: " + e) })), t.src = e } }; var lN, cN, hN, dN, uN, pN, fN, mN, gN = function(e, t, n, i) { return new(n || (n = Promise))((function(r, a) { function s(e) { try { l(i.next(e)) } catch (e) { a(e) } } function o(e) { try { l(i.throw(e)) } catch (e) { a(e) } } function l(e) { var t; e.done ? r(e.value) : (t = e.value, t instanceof n ? t : new n((function(e) { e(t) }))).then(s, o) } l((i = i.apply(e, t || [])).next()) })) }, vN = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, wN = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; cN = new WeakMap, hN = new WeakMap, dN = new WeakMap, uN = new WeakMap, pN = new WeakMap, lN = new WeakSet, fN = function(e, t, n, i) { return gN(this, void 0, void 0, (function*() { var r, a; if (wN(this, hN, "f").determinismState != VI.Ok) return; const s = wN(this, dN, "f").getUserProfile(e); if (null == s) return; const o = e.toString() + "_" + t, l = (null !== (r = wN(this, uN, "f").get(o)) && void 0 !== r ? r : 0) + 1; wN(this, uN, "f").set(o, l); const { uploadId: c } = yield wN(this, hN, "f").submitLeaderboard(s.token, s.nickname, s.carColors, t, n, i); wN(this, uN, "f").get(o) == l && (null === (a = wN(this, dN, "f").getUserProfile(e)) || void 0 === a ? void 0 : a.token) == s.token && wN(this, cN, "f").saveRecord(e, s.tokenHash, t, c, n, i, wN(this, hN, "f").determinismState) })) }, mN = function(e, t, n) { return gN(this, void 0, void 0, (function*() { var i, r; if (wN(this, hN, "f").determinismState != VI.Ok) return; const a = wN(this, dN, "f").getUserProfile(e); if (null == a) return; const s = e.toString() + "_" + t, o = (null !== (i = wN(this, uN, "f").get(s)) && void 0 !== i ? i : 0) + 1; wN(this, uN, "f").set(s, o); const l = yield wN(this, hN, "f").getRecordings([n]); if (l.length < 1 || null == l[0]) throw new Error("Record not found"); const c = l[0]; if (wN(this, uN, "f").get(s) == o && (null === (r = wN(this, dN, "f").getUserProfile(e)) || void 0 === r ? void 0 : r.token) == a.token) { const i = this.getRecordTime(e, t); if (null == i || c.time.lessThan(i)) { wN(this, cN, "f").saveRecord(e, a.tokenHash, t, n, c.time, c.recording, wN(this, hN, "f").determinismState); for (const e of wN(this, pN, "f")) e() } } })) }; const yN = class { constructor(e, t, n) { lN.add(this), cN.set(this, void 0), hN.set(this, void 0), dN.set(this, void 0), uN.set(this, new Map), pN.set(this, []), vN(this, cN, e, "f"), vN(this, hN, t, "f"), vN(this, dN, n, "f") } addRecordChangedCallback(e) { wN(this, pN, "f").push(e) } removeRecordChangedCallback(e) { const t = wN(this, pN, "f").indexOf(e); t >= 0 && wN(this, pN, "f").splice(t, 1) } setRecord(e, t, n, i) { const r = wN(this, dN, "f").getUserProfile(e); if (null != r) { wN(this, cN, "f").saveRecord(e, r.tokenHash, t, null, n, i, wN(this, hN, "f").determinismState), wN(this, lN, "m", fN).call(this, e, t, n, i).catch((e => { console.warn(e) })); for (const e of wN(this, pN, "f")) e() } } syncRecord(e, t, n) { return gN(this, void 0, void 0, (function*() { if (wN(this, hN, "f").determinismState != VI.Ok) return null; const i = this.getRecord(e, t); return null != i && (null == n || i.uploadId != n.recordingId && i.time.lessThan(n.time)) ? (yield wN(this, lN, "m", fN).call(this, e, t, i.time, i.recording), "Upload") : null != n && (null == i || i.uploadId != n.recordingId && n.time.lessThan(i.time)) ? (yield wN(this, lN, "m", mN).call(this, e, t, n.recordingId), "Download") : null })) } getRecordTime(e, t) { const n = this.getRecord(e, t); return null == n ? null : n.time } getRecord(e, t) { const n = wN(this, dN, "f").getUserProfile(e); return null == n ? null : wN(this, cN, "f").loadRecord(e, n.tokenHash, t, wN(this, hN, "f").determinismState) } }; var AN, bN, xN, kN, EN, SN, MN, TN, _N, CN, PN, IN = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, RN = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; bN = new WeakMap, xN = new WeakMap, kN = new WeakMap, EN = new WeakMap, SN = new WeakMap, AN = new WeakSet, MN = function(e, t) { return RN(this, AN, "m", _N).call(this, "tracks/official/" + e, t) }, TN = function(e, t) { return RN(this, AN, "m", _N).call(this, "tracks/community/" + e, t) }, _N = function(e, t) { return t.addResource(), new Promise((n => { const i = new XMLHttpRequest; i.overrideMimeType("text/plain"), i.onreadystatechange = () => { if (4 == i.readyState && 200 == i.status) { t.loadedResource(); const e = Sb.fromExportString(i.responseText); if (null == e) throw new Error("Failed to load bundled track"); const { trackMetadata: r, trackData: a } = e; n({ id: a.getId(), trackMetadata: r, trackData: a, thumbnail: a.createThumbnail(), saveTime: null }) } }, i.open("GET", e, !0), i.send() })) }, CN = function(e) { return new Promise((t => { setTimeout((() => { const n = RN(this, EN, "f").loadCustomTrack(e); if (null != n) { const { trackMetadata: e, trackData: i, saveTime: r } = n, a = { id: i.getId(), trackMetadata: e, trackData: i, thumbnail: i.createThumbnail(), saveTime: r }; t(a) } else t(null) })) })) }, PN = function() { for (const e of RN(this, SN, "f")) e() }; const LN = class { constructor(e, t) { AN.add(this), bN.set(this, []), xN.set(this, []), kN.set(this, []), EN.set(this, void 0), SN.set(this, []), IN(this, EN, t, "f"); Promise.all(["summer1.track", "summer2.track", "summer3.track", "summer4.track", "summer5.track", "summer6.track", "summer7.track", "winter1.track", "winter2.track", "winter3.track", "winter4.track", "desert1.track", "desert2.track", "desert3.track", "desert4.track"].map((t => RN(this, AN, "m", MN).call(this, t, e)))).then((e => { IN(this, bN, e, "f") })).catch((e => { console.error(e) })); Promise.all(["90_reset.track", "arabica.track", "clay_temples.track", "concrete_jungle.track", "desert_stallion.track", "hyperions_sanctuary.track", "las_calles.track", "last_remnant.track", "lu_muvimento.track", "malformations.track", "opal_place_ii.track", "re_akina.track", "sandline_ultimatum.track", "snow_park.track", "winter_hollow.track"].map((t => RN(this, AN, "m", TN).call(this, t, e)))).then((e => { IN(this, xN, e, "f") })).catch((e => { console.error(e) })); const n = RN(this, EN, "f").getAllCustomTrackNames(); if (null != n) { const e = []; for (const t of n) e.push(RN(this, AN, "m", CN).call(this, t)); Promise.all(e).then((e => { IN(this, kN, e.filter((e => null != e)).sort(((e, t) => { var n, i; return (null !== (n = t.saveTime) && void 0 !== n ? n : -1 / 0) - (null !== (i = e.saveTime) && void 0 !== i ? i : -1 / 0) })), "f") })).catch((e => { console.error(e) })) } } saveCustomTrack(e, t) { const n = new Date; if (RN(this, EN, "f").saveCustomTrack(e, t, n)) { const i = { id: t.getId(), trackMetadata: e, trackData: t, thumbnail: t.createThumbnail(), saveTime: n.getTime() }, r = RN(this, kN, "f").findIndex((t => t.trackMetadata.name == e.name)); return r >= 0 ? RN(this, kN, "f")[r] = i : RN(this, kN, "f").unshift(i), RN(this, AN, "m", PN).call(this), !0 } return !1 } deleteCustomTrack(e) { if (RN(this, EN, "f").deleteCustomTrack(e)) { const t = RN(this, kN, "f").findIndex((t => t.trackMetadata.name == e)); if (t >= 0) { const e = RN(this, kN, "f")[t]; RN(this, EN, "f").deleteAllRecordsForTrack(e.id), RN(this, kN, "f").splice(t, 1) } return RN(this, AN, "m", PN).call(this), !0 } return !1 } checkCustomTrackNameExists(e) { return RN(this, kN, "f").some((t => t.trackMetadata.name == e)) } addCustomTracksChangedListener(e) { RN(this, SN, "f").push(e) } removeCustomTracksChangedListener(e) { const t = RN(this, SN, "f").indexOf(e); t >= 0 && RN(this, SN, "f").splice(t, 1) } isCommunityTracksEmpty() { return 0 == RN(this, xN, "f").length } isCustomTracksEmpty() { return 0 == RN(this, kN, "f").length } forEachTrack(e) { this.forEachOfficialTrack(e), this.forEachCommunityTrack(e), this.forEachCustomTrack(e) } forEachOfficialTrack(e) { for (const t of RN(this, bN, "f")) e(t.id, t.trackMetadata, t.trackData, t.thumbnail) } forEachCommunityTrack(e) { for (const t of RN(this, xN, "f")) e(t.id, t.trackMetadata, t.trackData, t.thumbnail) } forEachCustomTrack(e) { for (const t of RN(this, kN, "f")) e(t.id, t.trackMetadata, t.trackData, t.thumbnail) } getRandomOfficialTrackData() { return RN(this, bN, "f")[Math.floor(Math.random() * RN(this, bN, "f").length)].trackData } isOfficialTrack(e) { return RN(this, bN, "f").some((t => t.id == e)) } isCommunityTrack(e) { return RN(this, xN, "f").some((t => t.id == e)) } }, DN = new WeakMap; class NN extends uo { constructor(e) { super(e), this.decoderPath = "", this.decoderConfig = {}, this.decoderBinary = null, this.decoderPending = null, this.workerLimit = 4, this.workerPool = [], this.workerNextTaskID = 1, this.workerSourceURL = "", this.defaultAttributeIDs = { position: "POSITION", normal: "NORMAL", color: "COLOR", uv: "TEX_COORD" }, this.defaultAttributeTypes = { position: "Float32Array", normal: "Float32Array", color: "Float32Array", uv: "Float32Array" } } setDecoderPath(e) { return this.decoderPath = e, this } setDecoderConfig(e) { return this.decoderConfig = e, this } setWorkerLimit(e) { return this.workerLimit = e, this } load(e, t, n, i) { const r = new mo(this.manager); r.setPath(this.path), r.setResponseType("arraybuffer"), r.setRequestHeader(this.requestHeader), r.setWithCredentials(this.withCredentials), r.load(e, (e => { this.parse(e, t, i) }), n, i) } parse(e, t, n = () => {}) { this.decodeDracoFile(e, t, null, null, gt, n).catch(n) } decodeDracoFile(e, t, n, i, r = vt, a = () => {}) { const s = { attributeIDs: n || this.defaultAttributeIDs, attributeTypes: i || this.defaultAttributeTypes, useUniqueIDs: !!n, vertexColorSpace: r }; return this.decodeGeometry(e, s).then(t).catch(a) } decodeGeometry(e, t) { const n = JSON.stringify(t); if (DN.has(e)) { const t = DN.get(e); if (t.key === n) return t.promise; if (0 === e.byteLength) throw new Error("THREE.DRACOLoader: Unable to re-decode a buffer with different settings. Buffer has already been transferred.") } let i; const r = this.workerNextTaskID++, a = e.byteLength, s = this._getWorker(r, a).then((n => (i = n, new Promise(((n, a) => { i._callbacks[r] = { resolve: n, reject: a }, i.postMessage({ type: "decode", id: r, taskConfig: t, buffer: e }, [e]) }))))).then((e => this._createGeometry(e.geometry))); return s.catch((() => !0)).then((() => { i && r && this._releaseTask(i, r) })), DN.set(e, { key: n, promise: s }), s } _createGeometry(e) { const t = new sr; e.index && t.setIndex(new qi(e.index.array, 1)); for (let n = 0; n < e.attributes.length; n++) { const i = e.attributes[n], r = i.name, a = i.array, s = i.itemSize, o = new qi(a, s); "color" === r && (this._assignVertexColorSpace(o, i.vertexColorSpace), o.normalized = a instanceof Float32Array == !1), t.setAttribute(r, o) } return t } _assignVertexColorSpace(e, t) { if (t !== gt) return; const n = new Wi; for (let t = 0, i = e.count; t < i; t++) n.fromBufferAttribute(e, t), nn.toWorkingColorSpace(n, gt), e.setXYZ(t, n.r, n.g, n.b) } _loadLibrary(e, t) { const n = new mo(this.manager); return n.setPath(this.decoderPath), n.setResponseType(t), n.setWithCredentials(this.withCredentials), new Promise(((t, i) => { n.load(e, t, void 0, i) })) } preload() { return this._initDecoder(), this } _initDecoder() { if (this.decoderPending) return this.decoderPending; const e = "object" != typeof WebAssembly || "js" === this.decoderConfig.type, t = []; return e ? t.push(this._loadLibrary("draco_decoder.js", "text")) : (t.push(this._loadLibrary("draco_wasm_wrapper.js", "text")), t.push(this._loadLibrary("draco_decoder.wasm", "arraybuffer"))), this.decoderPending = Promise.all(t).then((t => { const n = t[0]; e || (this.decoderConfig.wasmBinary = t[1]); const i = BN.toString(), r = ["/* draco decoder */", n, "", "/* worker */", i.substring(i.indexOf("{") + 1, i.lastIndexOf("}"))].join("\n"); this.workerSourceURL = URL.createObjectURL(new Blob([r])) })), this.decoderPending } _getWorker(e, t) { return this._initDecoder().then((() => { if (this.workerPool.length < this.workerLimit) { const e = new Worker(this.workerSourceURL); e._callbacks = {}, e._taskCosts = {}, e._taskLoad = 0, e.postMessage({ type: "init", decoderConfig: this.decoderConfig }), e.onmessage = function(t) { const n = t.data; switch (n.type) { case "decode": e._callbacks[n.id].resolve(n); break; case "error": e._callbacks[n.id].reject(n); break; default: console.error('THREE.DRACOLoader: Unexpected message, "' + n.type + '"') } }, this.workerPool.push(e) } else this.workerPool.sort((function(e, t) { return e._taskLoad > t._taskLoad ? -1 : 1 })); const n = this.workerPool[this.workerPool.length - 1]; return n._taskCosts[e] = t, n._taskLoad += t, n })) } _releaseTask(e, t) { e._taskLoad -= e._taskCosts[t], delete e._callbacks[t], delete e._taskCosts[t] } debug() { console.log("Task load: ", this.workerPool.map((e => e._taskLoad))) } dispose() { for (let e = 0; e < this.workerPool.length; ++e) this.workerPool[e].terminate(); return this.workerPool.length = 0, "" !== this.workerSourceURL && URL.revokeObjectURL(this.workerSourceURL), this } } function BN() { let e, t; function n(e, t, n, i, r, a) { const s = a.num_components(), o = n.num_points() * s, l = o * r.BYTES_PER_ELEMENT, c = function(e, t) { switch (t) { case Float32Array: return e.DT_FLOAT32; case Int8Array: return e.DT_INT8; case Int16Array: return e.DT_INT16; case Int32Array: return e.DT_INT32; case Uint8Array: return e.DT_UINT8; case Uint16Array: return e.DT_UINT16; case Uint32Array: return e.DT_UINT32 } }(e, r), h = e._malloc(l); t.GetAttributeDataArrayForAllPoints(n, a, c, l, h); const d = new r(e.HEAPF32.buffer, h, o).slice(); return e._free(h), { name: i, array: d, itemSize: s } } onmessage = function(i) { const r = i.data; switch (r.type) { case "init": e = r.decoderConfig, t = new Promise((function(t) { e.onModuleLoaded = function(e) { t({ draco: e }) }, DracoDecoderModule(e) })); break; case "decode": const i = r.buffer, a = r.taskConfig; t.then((e => { const t = e.draco, s = new t.Decoder; try { const e = function(e, t, i, r) { const a = r.attributeIDs, s = r.attributeTypes; let o, l; const c = t.GetEncodedGeometryType(i); if (c === e.TRIANGULAR_MESH) o = new e.Mesh, l = t.DecodeArrayToMesh(i, i.byteLength, o); else { if (c !== e.POINT_CLOUD) throw new Error("THREE.DRACOLoader: Unexpected geometry type."); o = new e.PointCloud, l = t.DecodeArrayToPointCloud(i, i.byteLength, o) } if (!l.ok() || 0 === o.ptr) throw new Error("THREE.DRACOLoader: Decoding failed: " + l.error_msg()); const h = { index: null, attributes: [] }; for (const i in a) { const l = self[s[i]]; let c, d; if (r.useUniqueIDs) d = a[i], c = t.GetAttributeByUniqueId(o, d); else { if (d = t.GetAttributeId(o, e[a[i]]), -1 === d) continue; c = t.GetAttribute(o, d) } const u = n(e, t, o, i, l, c); "color" === i && (u.vertexColorSpace = r.vertexColorSpace), h.attributes.push(u) } c === e.TRIANGULAR_MESH && (h.index = function(e, t, n) { const i = n.num_faces(), r = 3 * i, a = 4 * r, s = e._malloc(a); t.GetTrianglesUInt32Array(n, a, s); const o = new Uint32Array(e.HEAPF32.buffer, s, r).slice(); return e._free(s), { array: o, itemSize: 1 } }(e, t, o)); return e.destroy(o), h }(t, s, new Int8Array(i), a), o = e.attributes.map((e => e.array.buffer)); e.index && o.push(e.index.array.buffer), self.postMessage({ type: "decode", id: r.id, geometry: e }, o) } catch (e) { console.error(e), self.postMessage({ type: "error", id: r.id, error: e.message }) } finally { t.destroy(s) } })) } } } var UN, zN, ON, FN, WN, VN = function(e, t, n, i) { return new(n || (n = Promise))((function(r, a) { function s(e) { try { l(i.next(e)) } catch (e) { a(e) } } function o(e) { try { l(i.throw(e)) } catch (e) { a(e) } } function l(e) { var t; e.done ? r(e.value) : (t = e.value, t instanceof n ? t : new n((function(e) { e(t) }))).then(s, o) } l((i = i.apply(e, t || [])).next()) })) }, HN = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class GN { constructor() { UN.add(this), zN.set(this, new Map), ON.set(this, new Map) } init(e) { return VN(this, void 0, void 0, (function*() { const t = new vl, n = new NN; n.setDecoderPath("lib/draco/"), t.setDRACOLoader(n); const i = (r = ["models/blocks.glb", "models/pillar.glb", "models/planes.glb", "models/road.glb", "models/road_wide.glb", "models/signs.glb", "models/wall_track.glb"], Promise.all(r.map((e => { return n = e, new Promise((e => { t.load(n, (t => { e(t) })) })); var n })))); var r; const a = new Fs({ vertexColors: !0 }), s = t => VN(this, void 0, void 0, (function*() { var n, r, s; if (e.addResource(), HN(this, zN, "f").has(t.id)) throw new Error("Track part types have same Id"); const o = { configuration: t, colors: new Map(t.colors.map((({ id: e }) => [e, null]))), physicsShapeVertices: null }; HN(this, zN, "f").set(t.id, o); const l = yield i; function c(e, t, n, i, r, a) { const s = l.find((t => t.scene.name == e)); if (null == s) throw new Error('Scene "' + e + '" does not exist'); const o = s.scene.getObjectByName(t); if (null == o) throw new Error('Mesh "' + t + '" does not exist in scene "' + e + '"'); let c; if (0 == o.children.length) { const e = o, t = h(e, a); e.updateMatrixWorld(!0), t.applyMatrix4(e.matrix), c = [t] } else { c = o.children.map((e => h(e, a))), o.updateMatrixWorld(!0); for (const e of c) e.applyMatrix4(o.matrix) } let d = -1 / 0; if (i) for (const e of c) for (let t = 0; t < e.attributes.position.array.length; t += 3) d = Math.max(d, e.attributes.position.array[t + 1]); for (const e of c) { if (e.applyMatrix4((new qn).makeScale(n ? -1 : 1, i ? -1 : 1, r ? -1 : 1)), n || i || r) { const t = e.index; if (null != t) for (let e = 0; e < t.count; e += 3) { const n = t.getX(e), i = t.getX(e + 1), r = t.getX(e + 2); t.setXYZ(e, n, r, i) } else { const t = e.attributes.position; for (let e = 0; e < t.count; e += 3) { const n = e, i = e + 1, r = e + 2, a = t.getX(n), s = t.getY(n), o = t.getZ(n), l = t.getX(i), c = t.getY(i), h = t.getZ(i), d = t.getX(r), u = t.getY(r), p = t.getZ(r); t.setXYZ(n, a, s, o), t.setXYZ(i, d, u, p), t.setXYZ(r, l, c, h) } } } i && e.translate(0, d, 0) } return c } function h(e, t) { const n = e.material; if (!(n instanceof zs)) throw new Error("Material is not a MeshStandardMaterial"); let i, r, a; if (Object.prototype.hasOwnProperty.call(t, n.name)) { const e = new Wi(t[n.name]); i = e.r, r = e.g, a = e.b } else i = n.color.r, r = n.color.g, a = n.color.b; const s = e.geometry.clone(), o = new Float32Array(s.attributes.position.array.length); for (let e = 0; e < o.length; e += 3) o[e + 0] = i, o[e + 1] = r, o[e + 2] = a; return s.attributes.color = new qi(o, 3), s } let d = null; for (const e of t.colors) { const i = []; for (const [a, o, l] of t.models) { const t = c(a, o, null !== (n = null == l ? void 0 : l.flipX) && void 0 !== n && n, null !== (r = null == l ? void 0 : l.flipY) && void 0 !== r && r, null !== (s = null == l ? void 0 : l.flipZ) && void 0 !== s && s, e.colors); for (const e of t) i.push(e) } const l = pl(i, !0).toNonIndexed(); l.computeVertexNormals(); const h = ml(l), u = new wr(h, a); o.colors.set(e.id, u), null != d || (d = l) } if (null == d) throw new Error("Physics geometry is missing"); if (!(d.attributes.position instanceof qi)) throw new Error("Vertices must use BufferAttribute"); o.physicsShapeVertices = new Float32Array(d.attributes.position.array), e.loadedResource() })), o = yield Promise.all(ab.map((e => s(e)))).then((() => VN(this, void 0, void 0, (function*() { return yield HN(this, UN, "m", WN).call(this) })))), l = (e, t, n = null) => { let i = HN(this, ON, "f").get(e); null == i && (i = new Map, HN(this, ON, "f").set(e, i)), null == n && (n = (e, t) => e.x == t.x && e.y == t.y && e.z == t.z && e.rotation == t.rotation && e.rotationAxis == t.rotationAxis), i.set(t, n) }; l(eA.BlockSlopeUp, eA.SlopeUp), l(eA.BlockSlopeUp, eA.SlopeUpLeftWide), l(eA.BlockSlopeUp, eA.SlopeUpRightWide), l(eA.BlockSlopeUp, eA.PlaneSlopeUp), l(eA.BlockSlopedUp, eA.Slope), l(eA.BlockSlopedUp, eA.SlopeLeftWide), l(eA.BlockSlopedUp, eA.SlopeRightWide), l(eA.BlockSlopedUp, eA.PlaneSlope), l(eA.BlockSlopeDown, eA.SlopeDown), l(eA.BlockSlopeDown, eA.SlopeDownLeftWide), l(eA.BlockSlopeDown, eA.SlopeDownRightWide), l(eA.BlockSlopeDown, eA.PlaneSlopeDown), l(eA.BlockSlopeDownLong, eA.SlopeDownLong), l(eA.BlockSlopeDownLong, eA.SlopeDownLongLeftWide), l(eA.BlockSlopeDownLong, eA.SlopeDownLongRightWide), l(eA.BlockSlopeDownLong, eA.PlaneSlopeDownLong), l(eA.BlockSlopeUpLong, eA.SlopeUpLong), l(eA.BlockSlopeUpLong, eA.SlopeUpLongLeftWide), l(eA.BlockSlopeUpLong, eA.SlopeUpLongRightWide), l(eA.BlockSlopeUpLong, eA.PlaneSlopeUpLong), l(eA.BlockSlopeVerticalTop, eA.WallTrackTop), l(eA.BlockSlopeVerticalInnerCornerTop, eA.WallTrackTopInnerCorner), l(eA.BlockSlopeVerticalInnerCornerBottom, eA.WallTrackBottomInnerCorner), l(eA.BlockInnerCorner, eA.WallTrackMiddleCorner); const c = (e, t) => e.x == t.x && e.y == t.y && e.z == t.z && e.rotation == t.rotation && e.rotationAxis == t.rotationAxis || e.x == t.x && e.y == t.y + 3 && e.z == t.z && e.rotation == t.rotation && (e.rotationAxis == nA.YPositive && t.rotationAxis == nA.YNegative || e.rotationAxis == nA.YNegative && t.rotationAxis == nA.YPositive || e.rotationAxis == nA.XPositive && t.rotationAxis == nA.XNegative || e.rotationAxis == nA.XNegative && t.rotationAxis == nA.XPositive || e.rotationAxis == nA.ZPositive && t.rotationAxis == nA.ZNegative || e.rotationAxis == nA.ZNegative && t.rotationAxis == nA.ZPositive); return l(eA.BlockSlopeVerticalBottom, eA.PlaneSlopeVerticalBottom, c), l(eA.BlockSlopeVerticalBottom, eA.WallTrackBottom, c), l(eA.BlockSlopeVerticalBottom, eA.SlopeUpVertical, c), l(eA.BlockSlopeVerticalBottom, eA.SlopeUpVerticalLeftWide, c), l(eA.BlockSlopeVerticalBottom, eA.SlopeUpVerticalRightWide, c), l(eA.BlockSlopeVerticalCornerBottom, eA.WallTrackBottomCorner), l(eA.BlockSlopeVerticalCornerTop, eA.WallTrackTopCorner), l(eA.BlockSlopeToVertical, eA.PlaneSlopeToVertical), l(eA.BlockSlopeToVertical, eA.WallTrackSlopeToVertical), l(eA.HalfBlock, eA.HalfBlock, ((e, t) => e.rotation == (t.rotation + 2) % 4 && e.x == t.x && e.y == t.y && e.z == t.z && e.rotationAxis == t.rotationAxis)), l(eA.HalfBlock, eA.HalfPlane, ((e, t) => e.rotation == (t.rotation + 2) % 4 && e.x == t.x && e.y == t.y && e.z == t.z && e.rotationAxis == t.rotationAxis)), l(eA.HalfBlock, eA.QuarterBlock, ((e, t) => e.rotation != t.rotation && (e.rotation + 1) % 4 != t.rotation && e.x == t.x && e.y == t.y && e.z == t.z && e.rotationAxis == t.rotationAxis)), l(eA.HalfBlock, eA.QuarterPlane, ((e, t) => e.rotation != t.rotation && (e.rotation + 1) % 4 != t.rotation && e.x == t.x && e.y == t.y && e.z == t.z && e.rotationAxis == t.rotationAxis)), l(eA.QuarterBlock, eA.QuarterBlock, ((e, t) => e.rotation != t.rotation && e.x == t.x && e.y == t.y && e.z == t.z && e.rotationAxis == t.rotationAxis)), l(eA.QuarterBlock, eA.HalfPlane, ((e, t) => e.rotation != t.rotation && e.rotation != (t.rotation + 1) % 4 && e.x == t.x && e.y == t.y && e.z == t.z && e.rotationAxis == t.rotationAxis)), l(eA.QuarterBlock, eA.QuarterPlane, ((e, t) => e.rotation != t.rotation && e.x == t.x && e.y == t.y && e.z == t.z && e.rotationAxis == t.rotationAxis)), l(eA.HalfPlane, eA.HalfPlane, ((e, t) => e.rotation == (t.rotation + 2) % 4 && e.x == t.x && e.y == t.y && e.z == t.z && e.rotationAxis == t.rotationAxis)), l(eA.HalfPlane, eA.QuarterPlane, ((e, t) => e.rotation != t.rotation && (e.rotation + 1) % 4 != t.rotation && e.x == t.x && e.y == t.y && e.z == t.z && e.rotationAxis == t.rotationAxis)), l(eA.QuarterPlane, eA.QuarterPlane, ((e, t) => e.rotation != t.rotation && e.x == t.x && e.y == t.y && e.z == t.z && e.rotationAxis == t.rotationAxis)), l(eA.WallTrackTopInnerCorner, eA.WallTrackCeilingCorner, ((e, t) => { let n; switch (e.rotationAxis) { case nA.YPositive: n = new yn(0, 1, 0); break; case nA.YNegative: n = new yn(0, -1, 0); break; case nA.XPositive: n = new yn(1, 0, 0); break; case nA.XNegative: n = new yn(-1, 0, 0); break; case nA.ZPositive: n = new yn(0, 0, 1); break; case nA.ZNegative: n = new yn(0, 0, -1); break; default: throw new Error("Invalid rotation axis") } return e.rotation == t.rotation && e.x + 3 * n.x == t.x && e.y + 3 * n.y == t.y && e.z + 3 * n.z == t.z && e.rotationAxis == t.rotationAxis })), l(eA.WallTrackTopInnerCorner, eA.WallTrackCeilingPlaneCorner, ((e, t) => { let n; switch (e.rotationAxis) { case nA.YPositive: n = new yn(0, 1, 0); break; case nA.YNegative: n = new yn(0, -1, 0); break; case nA.XPositive: n = new yn(1, 0, 0); break; case nA.XNegative: n = new yn(-1, 0, 0); break; case nA.ZPositive: n = new yn(0, 0, 1); break; case nA.ZNegative: n = new yn(0, 0, -1); break; default: throw new Error("Invalid rotation axis") } return e.rotation == t.rotation && e.x + 3 * n.x == t.x && e.y + 3 * n.y == t.y && e.z + 3 * n.z == t.z && e.rotationAxis == t.rotationAxis })), l(eA.WallTrackBottomInnerCorner, eA.WallTrackFloorCorner), l(eA.WallTrackBottomInnerCorner, eA.WallTrackFloorPlaneCorner), o })) } isPartCombinationAllowed(e, t) { const n = HN(this, UN, "m", FN).call(this, e.id, t.id); if (null == n ? void 0 : n(e, t)) return !0; const i = HN(this, UN, "m", FN).call(this, t.id, e.id); return !!(null == i ? void 0 : i(t, e)) } getPhysicsParts() { var e, t; const n = []; for (const { configuration: i, physicsShapeVertices: r } of HN(this, zN, "f").values()) { if (null == r) throw new Error("Part model has not been loaded yet"); n.push({ id: i.id, vertices: r, detector: i.detector, startOffset: null !== (t = null === (e = i.startOffset) || void 0 === e ? void 0 : e.toArray()) && void 0 !== t ? t : null }) } return n } hasPart(e) { return HN(this, zN, "f").has(e) } getPart(e) { const t = HN(this, zN, "f").get(e); if (null == t) throw new Error('Track part with the id "' + e.toString() + '" does not exist'); return t } getAllParts() { return Array.from(HN(this, zN, "f").values()) } getPartStartOffset(e) { var t, n; const i = HN(this, zN, "f").get(e); if (null == i) throw new Error('Track part with the id "' + e.toString() + '" does not exist'); return null !== (n = null === (t = i.configuration.startOffset) || void 0 === t ? void 0 : t.clone()) && void 0 !== n ? n : null } getPartTypesWithDetector(e) { const t = []; for (const [n, i] of HN(this, zN, "f").entries()) null != i.configuration.detector && i.configuration.detector.type == e && t.push(n); return t } getStartPartTypes() { const e = []; for (const [t, n] of HN(this, zN, "f").entries()) null != n.configuration.startOffset && e.push(t); return e } getCategoryMesh(e, t) { let n, i; switch (e) { case KA.Special: n = this.getPart(eA.Start); break; case KA.Road: n = this.getPart(eA.Straight); break; case KA.RoadTurns: n = this.getPart(eA.TurnShort); break; case KA.RoadWide: n = this.getPart(eA.OuterCornerWide); break; case KA.Plane: n = this.getPart(eA.Plane); break; case KA.Block: n = this.getPart(eA.Block); break; case KA.WallTrack: n = this.getPart(eA.WallTrackBottom); break; case KA.Pillar: n = this.getPart(eA.PillarShort); break; case KA.Sign: n = this.getPart(eA.SignArrowLeft) } switch (t) { case QA.Summer: i = Jy.Summer; break; case QA.Winter: i = Jy.Winter; break; case QA.Desert: i = Jy.Desert } const r = n.colors.get(i); if (null == r) throw new Error("Category mesh is not loaded"); return r } } zN = new WeakMap, ON = new WeakMap, UN = new WeakSet, FN = function(e, t) { var n; const i = HN(this, ON, "f").get(e); return null == i ? null : null !== (n = i.get(t)) && void 0 !== n ? n : null }, WN = function() { return VN(this, void 0, void 0, (function*() { const e = Object.values(eA).filter((e => "string" != typeof e)); let t = !0; for (const n of e) { const e = HN(this, zN, "f").get(n); if (null == e) throw new Error("Part with id " + n.toString() + " does not exist"); const i = e.physicsShapeVertices; if (null == i) throw new Error("Part model with id " + n.toString() + " has not been loaded yet"); const r = yield window.crypto.subtle.digest("SHA-256", i), a = Array.from(new Uint8Array(r)).map((e => e.toString(16).padStart(2, "0"))).join(""); a != e.configuration.checksum && (console.error("Part id " + n.toString() + " " + eA[n] + " checksum mismatch: " + a + " != " + e.configuration.checksum), t = !1) } return t })) }; var jN = n(9207), QN = {}; QN.styleTagTransform = u(), QN.setAttributes = l(), QN.insert = s().bind(null, "head"), QN.domAPI = r(), QN.insertStyleElement = h(); t()(jN.A, QN); jN.A && jN.A.locals && jN.A.locals; var YN, KN, qN = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }, XN = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }; YN = new WeakMap, KN = new WeakMap; const ZN = class { constructor() { YN.set(this, document.getElementById("transition-layer")), KN.set(this, null) } trigger(e) { const t = qN(this, YN, "f"); if (null == t) throw new Error("Failed to find transition layer"); null == qN(this, KN, "f") && (t.style.opacity = "1", setTimeout((() => { if (null != qN(this, KN, "f")) { const e = qN(this, KN, "f").call(this); null == e ? (t.style.opacity = "0", XN(this, KN, null, "f")) : e.catch((e => { console.error(e) })).finally((() => { t.style.opacity = "0", XN(this, KN, null, "f") })) } }), 250)), XN(this, KN, e, "f") } }; var JN, $N, eB, tB, nB = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, iB = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; JN = new WeakMap, $N = new WeakMap, eB = new WeakMap, tB = new WeakMap; const rB = class { constructor(e, t, n) { JN.set(this, void 0), $N.set(this, void 0), eB.set(this, new jt(100 * Math.random(), 100 * Math.random())), tB.set(this, new jt(100 * Math.random(), 100 * Math.random())), nB(this, JN, t, "f"), n.addResource(); const i = (new vo).load("images/clouds.jpg", (() => { n.loadedResource() })); i.wrapT = re, i.wrapS = re; const r = new Us(1e6, 5, 2, 0, 2 * Math.PI, 0, Math.PI), a = new Sr({ defines: { CLOUDS_ENABLED: t.getSettingBoolean($o.CloudsEnabled) }, uniforms: { scrollA: { value: iB(this, eB, "f") }, scrollB: { value: iB(this, tB, "f") }, sampler: { value: i }, cloudDensity: { value: .6 }, cloudLight: { value: new yn(.75, .75, .75) }, sunPosition: { value: new yn } }, vertexShader: "\n\t\t\t\tvarying vec3 fPos;\n\t\t\t\t\n\t\t\t\tvoid main() {\n\t\t\t\t\tvec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);\n\t\t\t\t\tgl_Position = projectionMatrix * modelViewPosition;\n\t\t\t\t\tgl_Position.z = 0.0;\n\t\t\t\t\tfPos = position;\n\t\t\t\t}\n\t\t\t", fragmentShader: "\n\t\t\t\tvarying vec3 fPos;\n\n\t\t\t\tuniform vec2 offset;\n\t\t\t\tuniform vec2 scrollA;\n\t\t\t\tuniform vec2 scrollB;\n\t\t\t\tuniform sampler2D sampler;\n\n\t\t\t\tuniform float cloudDensity;\n\t\t\t\tuniform vec3 cloudLight;\n\n\t\t\t\tuniform vec3 sunPosition;\n\n\t\t\t\tvoid main()\n\t\t\t\t{\n\t\t\t\t\t#ifdef CLOUDS_ENABLED\n\t\t\t\t\t\tfloat c00 = texture2D(sampler, vec2(fPos.x / ((fPos.y + 0.06) / 0.1) - scrollB.x * 0.981, fPos.z / ((fPos.y + 0.06) / 0.1) - scrollB.y * 1.041) + scrollA).r;\n\t\t\t\t\t\tfloat c10 = texture2D(sampler, vec2(fPos.x / ((fPos.y + 0.06) / 0.1) + scrollB.x * 0.821, fPos.z / ((fPos.y + 0.06) / 0.1) - scrollB.y * 0.951) + scrollA).r;\n\t\t\t\t\t\tfloat c01 = texture2D(sampler, vec2(fPos.x / ((fPos.y + 0.06) / 0.1) - scrollB.x * 1.043, fPos.z / ((fPos.y + 0.06) / 0.1) + scrollB.y * 0.899) + scrollA).r;\n\t\t\t\t\t\tfloat c11 = texture2D(sampler, vec2(fPos.x / ((fPos.y + 0.06) / 0.1) + scrollB.x * 0.901, fPos.z / ((fPos.y + 0.06) / 0.1) + scrollB.y * 1.045) + scrollA).r;\n\t\t\t\t\t\tfloat cloud = min(1.0, max(0.0, (c00 + c10 + c01 + c11) / 4.0 - (1.0 - cloudDensity)) * 3.0);\n\n\t\t\t\t\t\tvec3 cloudColor = vec3(min(1.0, (c00 + c10 + c01 + c11) / 4.0 - (1.0 - cloudDensity)) * 4.0 + cloudDensity) * cloudLight;\n\t\t\t\t\t\tfloat cloudIntensity = cloud * min(1.0, max(0.0, fPos.y * 2.0 / 1000000.0));\n\t\t\t\t\t#else\n\t\t\t\t\t\tvec3 cloudColor = vec3(0.0);\n\t\t\t\t\t\tfloat cloudIntensity = 0.0;\n\t\t\t\t\t#endif\n\t\t\t\t\t\n\t\t\t\t\tvec3 horizonColor = vec3(255.0 / 255.0, 255.0 / 255.0, 255.0 / 255.0);\n\t\t\t\t\tvec3 zenithColor = vec3(5.0 / 255.0, 140.0 / 255.0, 255.0 / 255.0);\n\t\t\t\t\tfloat h = pow(clamp(fPos.y / 1000000.0, 0.01, 1.0), 0.2);\n\t\t\t\t\tvec3 skyColor = zenithColor * h + horizonColor * (1.0 - h);\n\n\t\t\t\t\tvec3 normal = normalize(-fPos);\n\t\t\t\t\tfloat sun = pow(max(0.0, max(0.0, dot(normal, sunPosition)) - 0.999), 4.0) * 60000000000.0;\n\t\t\t\t\tvec3 sunColor = vec3(20.0 * sun, 20.0 * sun, 19.0 * sun);\n\n\t\t\t\t\tgl_FragColor = vec4((skyColor * (1.0 - cloudIntensity) + cloudColor * cloudIntensity) * max(vec3(0.0), vec3(1.0) - sunColor) + sunColor, 1.0);\n\t\t\t\t}\n\t\t\t" }); a.side = 1, a.depthWrite = !1, nB(this, $N, new wr(r, a), "f"), iB(this, $N, "f").renderOrder = -3, iB(this, $N, "f").matrixAutoUpdate = !1, iB(this, $N, "f").updateMatrix(), e.scene.add(iB(this, $N, "f")) } update(e, t, n) { iB(this, JN, "f").getSettingBoolean($o.CloudsEnabled) ? (iB(this, eB, "f").x += .00226 * e, iB(this, eB, "f").y += .001646 * e, iB(this, tB, "f").x += .001752 * e, iB(this, tB, "f").y += .001057 * e, 1 != iB(this, $N, "f").material.defines.CLOUDS_ENABLED && (iB(this, $N, "f").material.defines.CLOUDS_ENABLED = !0, iB(this, $N, "f").material.needsUpdate = !0)) : 0 != iB(this, $N, "f").material.defines.CLOUDS_ENABLED && (iB(this, $N, "f").material.defines.CLOUDS_ENABLED = !1, iB(this, $N, "f").material.needsUpdate = !0); const i = n.getSunPosition(); iB(this, $N, "f").material.uniforms.sunPosition.value.copy(i.negate()), iB(this, $N, "f").position.copy(t.position), iB(this, $N, "f").updateMatrix() } }; var aB, sB, oB, lB, cB, hB, dB, uB, pB, fB, mB, gB, vB, wB, yB, AB, bB, xB, kB, EB, SB = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, MB = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class TB { constructor(e) { aB.add(this), oB.set(this, void 0), SB(this, oB, null == e ? { getItem: e => window.localStorage.getItem(e), setItem: (e, t) => { window.localStorage.setItem(e, t) }, removeItem: e => { window.localStorage.removeItem(e) }, getAllKeys: () => Object.keys(window.localStorage) } : e, "f") } migrate() { const e = MB(this, aB, "m", vB).call(this); "v4" == e || ("v3" == e ? (MB(this, aB, "m", uB).call(this), MB(this, aB, "m", gB).call(this)) : (MB(this, aB, "m", cB).call(this), MB(this, aB, "m", hB).call(this), MB(this, aB, "m", dB).call(this), MB(this, aB, "m", uB).call(this), MB(this, aB, "m", gB).call(this))) } saveRecord(e, t, n, i, r, a, s) { if (!Number.isSafeInteger(e) || e < 0) throw new Error("Profile slot is invalid"); try { let o; o = s == VI.Ok ? MB(sB, sB, "f", wB) + e.toString() + "_default_" + n : MB(sB, sB, "f", wB) + e.toString() + "_undeterministic_" + n, MB(this, oB, "f").setItem(o, JSON.stringify({ uploadId: i, tokenHash: t, frames: r.numberOfFrames.toString(), recording: a.serialize() })) } catch (e) { console.error(e) } } loadRecord(e, t, n, i) { if (!Number.isSafeInteger(e) || e < 0) throw new Error("Profile slot is invalid"); try { let r; r = i == VI.Ok ? MB(sB, sB, "f", wB) + e.toString() + "_default_" + n : MB(sB, sB, "f", wB) + e.toString() + "_undeterministic_" + n; const a = MB(this, oB, "f").getItem(r); if (null == a) return null; const s = JSON.parse(a); if ("object" != typeof s) return null; if (!("uploadId" in s)) return null; let o; if (null == s.uploadId) o = null; else if (o = Number.parseInt(s.uploadId, 10), !Number.isSafeInteger(o)) return null; if (!("tokenHash" in s)) return null; const l = s.tokenHash; if ("string" != typeof l) return null; if (l != t) return null; if (!("frames" in s)) return null; const c = Number.parseInt(s.frames, 10); if (!Number.isSafeInteger(c)) return null; const h = new xp(c); if (!("recording" in s)) return null; const d = cv.deserialize(s.recording); return null == d ? null : { uploadId: o, time: h, recording: d } } catch (e) { console.error(e) } return null } deleteAllRecords(e) { if (!Number.isSafeInteger(e) || e < 0) throw new Error("Profile slot is invalid"); try { const t = MB(this, oB, "f").getAllKeys(); for (const n of t) n.startsWith(MB(sB, sB, "f", wB) + e.toString() + "_") && MB(this, oB, "f").removeItem(n) } catch (e) { console.error(e) } } deleteAllRecordsForTrack(e) { for (let t = 0; t < 3; t++) try { MB(this, oB, "f").removeItem(MB(sB, sB, "f", wB) + t.toString() + "_" + e) } catch (e) { console.error(e) } } saveCustomTrack(e, t, n) { const i = t.toExportString(e); try { return MB(this, oB, "f").setItem(MB(sB, sB, "f", yB) + e.name, JSON.stringify({ data: i, saveTime: n.getTime() })), !0 } catch (e) { return console.error(e), !1 } } loadCustomTrack(e) { let t, n; try { const i = MB(this, oB, "f").getItem(MB(sB, sB, "f", yB) + e); if (null == i) return null; const r = JSON.parse(i); if ("string" != typeof r.data) return null; if ("number" != typeof r.saveTime) return null; t = r.data, n = r.saveTime } catch (e) { return console.error(e), null } const i = Sb.fromExportString(t); return null == i ? null : { trackMetadata: i.trackMetadata, trackData: i.trackData, saveTime: n } } deleteCustomTrack(e) { try { return MB(this, oB, "f").removeItem(MB(sB, sB, "f", yB) + e), !0 } catch (e) { return console.error(e), !1 } } getAllCustomTrackNames() { let e; try { e = MB(this, oB, "f").getAllKeys() } catch (e) { return console.error(e), null } return e.filter((e => e.startsWith(MB(sB, sB, "f", yB)))).map((e => e.substring(MB(sB, sB, "f", yB).length))) } saveUserProfileSlot(e) { if (!Number.isSafeInteger(e) || e < 0) throw new Error("Profile slot is invalid"); try { MB(this, oB, "f").setItem(MB(sB, sB, "f", AB), JSON.stringify(e)) } catch (e) { console.error(e) } } loadUserProfileSlot() { try { const e = MB(this, oB, "f").getItem(MB(sB, sB, "f", AB)); if (null != e) try { const t = JSON.parse(e); if (!Number.isSafeInteger(t) || t < 0) throw new Error("Profile slot is invalid"); return t } catch (e) { console.error(e) } } catch (e) { console.error(e) } return null } saveUserProfile(e, t, n, i) { if (!Number.isSafeInteger(e) || e < 0) throw new Error("Profile slot is invalid"); try { MB(this, oB, "f").setItem(MB(sB, sB, "f", bB) + e.toString(), JSON.stringify({ token: t, nickname: n, carColors: i.serialize() })) } catch (e) { console.error(e) } } loadUserProfile(e) { if (!Number.isSafeInteger(e) || e < 0) throw new Error("Profile slot is invalid"); try { const t = MB(this, oB, "f").getItem(MB(sB, sB, "f", bB) + e.toString()); if (null != t) { const e = JSON.parse(t); if ("object" != typeof e) throw new Error("User profile is not an object"); if ("string" != typeof e.token) throw new Error("User profile token field has invalid type"); if ("string" != typeof e.nickname) throw new Error("User profile nickname field has invalid type"); if ("string" != typeof e.carColors) throw new Error("User profile carColors field has invalid type"); return { token: e.token, nickname: e.nickname, carColors: Pu.deserialize(e.carColors) } } } catch (e) { console.error(e) } return null } deleteUserProfile(e) { try { MB(this, oB, "f").removeItem(MB(sB, sB, "f", bB) + e.toString()) } catch (e) { console.error(e) } } saveSettings(e) { try { const t = []; for (const [n, i] of e.entries()) t.push([$o[n], i]); MB(this, oB, "f").setItem(MB(sB, sB, "f", xB), JSON.stringify(t)) } catch (e) { console.error(e) } } loadSettings() { try { const e = MB(this, oB, "f").getItem(MB(sB, sB, "f", xB)); if (null == e) return null; const t = JSON.parse(e); if (!Array.isArray(t)) return null; const n = []; for (const e of t) { if (!Array.isArray(e)) continue; if (2 != e.length) continue; if ("string" != typeof e[0]) continue; const t = e[0]; if (!(t in $o)) continue; const i = $o[t], r = e[1]; "string" == typeof e[1] && n.push([i, r]) } return n } catch (e) { console.error(e) } return null } saveKeyBindings(e) { try { const t = []; for (const [n, i] of e.entries()) t.push([Ix[n], i]); MB(this, oB, "f").setItem(MB(sB, sB, "f", kB), JSON.stringify(t)) } catch (e) { console.error(e) } } loadKeyBindings() { try { const e = MB(this, oB, "f").getItem(MB(sB, sB, "f", kB)); if (null == e) return null; const t = JSON.parse(e); if (!Array.isArray(t)) return null; const n = []; for (const e of t) { if (!Array.isArray(e)) continue; if (2 != e.length) continue; if ("string" != typeof e[0]) continue; const t = e[0]; if (!(t in Ix)) continue; const i = Ix[t], r = e[1]; Array.isArray(r) && (2 == r.length && (null !== r[0] && "string" != typeof r[0] || null !== r[1] && "string" != typeof r[1] || n.push([i, r]))) } return n } catch (e) { console.error(e) } return null } saveTrackSelectionTab(e) { try { MB(this, oB, "f").setItem(MB(sB, sB, "f", EB), e) } catch (e) { console.error(e) } } loadTrackSelectionTab() { try { const e = MB(this, oB, "f").getItem(MB(sB, sB, "f", EB)); if ("official" == e || "community" == e || "custom" == e) return e } catch (e) { console.error(e) } return "official" } } sB = TB, oB = new WeakMap, aB = new WeakSet, cB = function() { try { const e = MB(this, oB, "f").getAllKeys(); try { const e = MB(this, oB, "f").getItem("car_colors"); if (null != e) { const t = JSON.parse(e), n = new Pu(new Wi(t[0]), new Wi(t[1]), new Wi(t[2]), new Wi(t[3])); MB(this, aB, "m", fB).call(this, n), MB(this, oB, "f").removeItem("car_colors") } } catch (e) { console.error(e) } for (const t of e) { if (t.startsWith("record_")) try { MB(this, oB, "f").removeItem(t) } catch (e) { console.error(e) } if (t.startsWith("custom_track_")) try { const e = MB(this, oB, "f").getItem(t); if (null != e) { const n = db(e); if (null != n) { const { trackMetadata: e, trackData: i } = n; this.saveCustomTrack(e, i, new Date) && MB(this, oB, "f").removeItem(t) } } } catch (e) { console.error(e) } } } catch (e) { console.error(e) } }, hB = function() { try { const e = MB(this, oB, "f").getAllKeys(); try { const e = MB(this, oB, "f").getItem("v1_car"); if (null != e) { const t = JSON.parse(e), n = new Pu(new Wi(t[0]), new Wi(t[1]), new Wi(t[2]), new Wi(t[3])); MB(this, aB, "m", fB).call(this, n), MB(this, oB, "f").removeItem("v1_car") } } catch (e) { console.error(e) } for (const t of e) { if (t.startsWith("v1_record_")) try { MB(this, oB, "f").removeItem(t) } catch (e) { console.error(e) } if (t.startsWith("v1_track_")) try { const e = MB(this, oB, "f").getItem(t); if (null != e) { const n = { name: t.substring(9), author: null }, i = ub(e); if (null == i) throw new Error("Failed to load v1 track for migration"); if (!this.saveCustomTrack(n, i, new Date)) throw new Error("Failed to save v1 track for migration"); MB(this, oB, "f").removeItem(t) } } catch (e) { console.error(e) } } } catch (e) { console.error(e) } }, dB = function() { try { const e = MB(this, oB, "f").getAllKeys(); try { const e = MB(this, oB, "f").getItem("v2_user"); if (null != e) { const t = JSON.parse(e); if (Array.isArray(t) || "object" != typeof t) throw new Error("User profile is not an object"); const n = t.token; if (null != n && "string" != typeof n) throw new Error("User profile token is not a string or null"); const i = t.nickname; if ("string" != typeof i) throw new Error("User profile nickname is not a string"); const r = Pu.random(); MB(this, aB, "m", pB).call(this, n, i, r), MB(this, oB, "f").removeItem("v2_user") } } catch (e) { console.error(e) } try { const e = MB(this, oB, "f").getItem("v2_car"); if (null != e) { const t = Pu.deserialize(e); MB(this, aB, "m", fB).call(this, t), MB(this, oB, "f").removeItem("v2_car") } } catch (e) { console.error(e) } try { MB(this, oB, "f").removeItem("v2_settings") } catch (e) { console.error(e) } try { MB(this, oB, "f").removeItem("v2_key_bindings") } catch (e) { console.error(e) } for (const t of e) if (t.startsWith("v2_record_")) try { MB(this, oB, "f").removeItem(t) } catch (e) { console.error(e) } else if (t.startsWith("v2_track_")) try { const e = MB(this, oB, "f").getItem(t); if (null != e) { const n = { name: t.substring(9), author: null }, i = pb(e); if (null == i) throw new Error("Failed to load v2 track for migration"); if (!this.saveCustomTrack(n, i, new Date)) throw new Error("Failed to save v2 track for migration"); MB(this, oB, "f").removeItem(t) } } catch (e) { console.error(e) } } catch (e) { console.error(e) } }, uB = function() { try { const e = MB(this, oB, "f").getAllKeys(); try { const e = MB(this, oB, "f").getItem("polytrack_v3_user_slot"); if (null != e) { const t = Number.parseInt(e, 10); Number.isSafeInteger(t) && t >= 0 && t <= 2 && (this.saveUserProfileSlot(t), MB(this, oB, "f").removeItem("polytrack_v3_user_slot")) } } catch (e) { console.error(e) } try { const e = MB(this, oB, "f").getItem("polytrack_v3_settings"); if (null != e) { const t = JSON.parse(e); if (Array.isArray(t)) { const e = new Map; for (const n of t) { if (!Array.isArray(n) || 2 != n.length) continue; const t = n[0]; if ("string" != typeof t || !(t in $o)) continue; const i = n[1]; "string" == typeof i && e.set($o[t], i) } this.saveSettings(e), MB(this, oB, "f").removeItem("polytrack_v3_settings") } } } catch (e) { console.error(e) } try { const e = MB(this, oB, "f").getItem("polytrack_v3_key_bindings"); if (null != e) { const t = JSON.parse(e); if (Array.isArray(t)) { const e = new Map; for (const n of t) { if (!Array.isArray(n) || 2 != n.length) continue; const t = n[0]; if ("string" != typeof t || !(t in Ix)) continue; const i = n[1]; if (!Array.isArray(i) || 2 != i.length) continue; const r = i[0]; if (null !== r && "string" != typeof r) continue; const a = i[1]; null !== a && "string" != typeof a || e.set(Ix[t], [r, a]) } this.saveKeyBindings(e), MB(this, oB, "f").removeItem("polytrack_v3_key_bindings") } } } catch (e) { console.error(e) } for (const t of e) if (t.startsWith("polytrack_v3_user_")) { let e; switch (t) { case "polytrack_v3_user_0": e = 0; break; case "polytrack_v3_user_1": e = 1; break; case "polytrack_v3_user_2": e = 2; break; default: e = null } if (null != e) try { const n = MB(this, oB, "f").getItem(t); if (null != n) { const i = JSON.parse(n); if ("object" != typeof i) throw new Error("User profile is not an object"); if (null != i.token && "string" != typeof i.token) throw new Error("User profile token field has invalid type"); if ("string" != typeof i.nickname) throw new Error("User profile nickname field has invalid type"); if ("string" != typeof i.carColors) throw new Error("User profile carColors field has invalid type"); const r = i.token, a = i.nickname, s = Pu.deserialize(i.carColors); this.saveUserProfile(e, null != r ? r : gL.createToken(), a, s), MB(this, oB, "f").removeItem(t) } } catch (e) { console.error(e) } } else if (t.startsWith("polytrack_v3_record_")) try { MB(this, oB, "f").removeItem(t) } catch (e) { console.error(e) } else if (t.startsWith("polytrack_v3_track_")) try { const e = MB(this, oB, "f").getItem(t); if (null != e) { const n = { name: t.substring(19), author: null }, i = JSON.parse(e); if (null == i || "object" != typeof i) throw new Error("Track data is not an object"); if (null == i.data || "string" != typeof i.data) throw new Error("Track data field is invalid"); if (null == i.saveTime || "number" != typeof i.saveTime || !Number.isSafeInteger(i.saveTime) || i.saveTime < 0) throw new Error("Track save time field is invalid"); const r = fb(i.data); if (null == r) throw new Error("Failed to load v2 track for migration"); if (!this.saveCustomTrack(n, r, new Date(i.saveTime))) throw new Error("Failed to save v2 track for migration"); MB(this, oB, "f").removeItem(t) } } catch (e) { console.error(e) } try { MB(this, oB, "f").removeItem("polytrack_v3_migrated") } catch (e) { console.error(e) } } catch (e) { console.error(e) } }, pB = function(e, t, n) { null == this.loadUserProfile(0) && this.saveUserProfile(0, null != e ? e : gL.createToken(), t, n) }, fB = function(e) { const t = this.loadUserProfile(0); null == t ? this.saveUserProfile(0, gL.createToken(), gL.defaultNickname, e) : this.saveUserProfile(0, t.token, t.nickname, e) }, gB = function() { try { MB(this, oB, "f").setItem(MB(sB, sB, "f", mB), "") } catch (e) { console.error(e) } }, vB = function() { try { if (null != MB(this, oB, "f").getItem(MB(sB, sB, "f", mB))) return "v4"; if (null != MB(this, oB, "f").getItem("polytrack_v3_migrated")) return "v3" } catch (e) { console.error(e) } return null }, lB = { value: (() => { let e = "polytrack_v4_"; return e += "prod_", e })() }, mB = { value: MB(sB, sB, "f", lB) + "migrated" }, wB = { value: MB(sB, sB, "f", lB) + "record_" }, yB = { value: MB(sB, sB, "f", lB) + "track_" }, AB = { value: MB(sB, sB, "f", lB) + "user_slot" }, bB = { value: MB(sB, sB, "f", lB) + "user_" }, xB = { value: MB(sB, sB, "f", lB) + "settings" }, kB = { value: MB(sB, sB, "f", lB) + "key_bindings" }, EB = { value: MB(sB, sB, "f", lB) + "selected_track_tab" }; const _B = TB; var CB, PB, IB, RB, LB, DB, NB, BB = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, UB = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; class zB { constructor() { CB.add(this), IB.set(this, void 0), RB.set(this, !1), LB.set(this, null); const e = document.getElementById("ui"); if (null == e) throw new Error("Failed to find UI element"); BB(this, IB, e, "f"), window.addEventListener("mousemove", (() => { document.body.classList.remove("hide-cursor"), UB(this, RB, "f") && (null != UB(this, LB, "f") && clearTimeout(UB(this, LB, "f")), BB(this, LB, setTimeout((() => { document.body.classList.add("hide-cursor"), BB(this, LB, null, "f") }), UB(PB, PB, "f", DB)), "f")) })), document.addEventListener("gesturestart", (function(e) { e.preventDefault() })), window.addEventListener("resize", (() => { UB(this, CB, "m", NB).call(this) })), UB(this, CB, "m", NB).call(this) } setCursorHiddenWhenInactive(e) { BB(this, RB, e, "f"), e ? BB(this, LB, setTimeout((() => { document.body.classList.add("hide-cursor"), BB(this, LB, null, "f") }), UB(PB, PB, "f", DB)), "f") : (document.body.classList.remove("hide-cursor"), null != UB(this, LB, "f") && (clearTimeout(UB(this, LB, "f")), BB(this, LB, null, "f"))) } } PB = zB, IB = new WeakMap, RB = new WeakMap, LB = new WeakMap, CB = new WeakSet, NB = function() { const e = Math.max(.01, Math.min(window.innerWidth, 1.4375 * window.innerHeight) / 1150); e < 1 ? (UB(this, IB, "f").style.width = "calc(100% / " + e.toString() + ")", UB(this, IB, "f").style.height = "calc(100% / " + e.toString() + ")", UB(this, IB, "f").style.transform = "scale(" + e.toString() + ")") : (UB(this, IB, "f").style.width = "", UB(this, IB, "f").style.height = "", UB(this, IB, "f").style.transform = "") }, DB = { value: 1e3 }; const OB = zB; var FB, WB, VB = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; FB = new WeakMap, WB = new WeakMap; const HB = class { constructor() { this.determinismState = VI.Uninitialized, FB.set(this, 2e4), WB.set(this, 1e4) } getLeaderboard(e, t, n, i, r) { let a = eu + "leaderboard?version=" + iu + "&trackId=" + t + "&skip=" + n.toString() + "&amount=" + i.toString() + "&onlyVerified=" + r.toString(); return this.determinismState == VI.Ok && (a += "&userTokenHash=" + encodeURIComponent(e)), new Promise(((t, n) => { const i = new XMLHttpRequest; i.timeout = VB(this, FB, "f"), i.overrideMimeType("text/plain"), i.onreadystatechange = () => { if (i.readyState == XMLHttpRequest.DONE) if (200 == i.status) try { const r = JSON.parse(i.responseText), a = r.total; if ("number" != typeof a) return void n(new Error("Total is not a number")); if (!Number.isSafeInteger(a)) return void n(new Error("Total is not a safe integer")); const s = r.entries; if (!Array.isArray(s)) return void n(new Error("Entries is not an array")); const o = []; for (const t of s) { if (null == t) return void n(new Error("Entry is missing")); if (!Object.prototype.hasOwnProperty.call(t, "id")) return void n(new Error('Entry is missing "id" field')); if (!Object.prototype.hasOwnProperty.call(t, "userId")) return void n(new Error('Entry is missing "userId" field')); if (!Object.prototype.hasOwnProperty.call(t, "name")) return void n(new Error('Entry is missing "name" field')); if (!Object.prototype.hasOwnProperty.call(t, "frames")) return void n(new Error('Entry is missing "frames" field')); if (!Object.prototype.hasOwnProperty.call(t, "carColors")) return void n(new Error('Entry is missing "carColors" field')); if (!Object.prototype.hasOwnProperty.call(t, "verifiedState")) return void n(new Error('Entry is missing "verifiedState" field')); if ("number" != typeof t.id) return void n(new Error('"id" field has incorrect type')); if ("string" != typeof t.userId) return void n(new Error('"userId" field has incorrect type')); if ("string" != typeof t.name) return void n(new Error('"name" field has incorrect type')); if ("number" != typeof t.frames) return void n(new Error('"frames" field has incorrect type')); if (!Number.isSafeInteger(t.frames) || t.frames <= 0 || t.frames > cv.maxFrames) return void n(new Error('"frames" field has an invalid value')); if ("string" != typeof t.carColors) return void n(new Error('"carColors" field has incorrect type')); if (!Number.isSafeInteger(t.verifiedState) || t.verifiedState < 0) return void n(new Error('"verifiedState" field has an invalid value')); o.push({ id: t.id, name: t.name, time: new xp(t.frames), carColors: Pu.deserialize(t.carColors), verifiedState: t.verifiedState, isSelf: t.userId == e }) } let l = null; if (null != r.userEntry) { const e = r.userEntry.position; if ("number" != typeof e) return void n(new Error("User position is not a number")); if (!Number.isSafeInteger(e)) return void n(new Error("User position is not a safe integer")); const t = r.userEntry.frames; if ("number" != typeof t) return void n(new Error("User frames is not a number")); if (!Number.isSafeInteger(t)) return void n(new Error("User frames is not a safe integer")); const i = new xp(t), a = r.userEntry.id; if ("number" != typeof a) return void n(new Error("User record id is not a number")); if (!Number.isSafeInteger(a)) return void n(new Error("User record id is not a safe integer")); l = { position: e, time: i, id: a } } t({ total: a, entries: o, userEntry: l }) } catch (e) { n(new Error("Unknown error: " + String(e))) } else n(new Error("Failed to connect to server, status: " + i.status.toString())) }, i.open("GET", a, !0), i.send() })) } getRecordings(e) { const t = eu + "recordings?version=" + iu + "&recordingIds=" + e.join(","); return new Promise(((e, n) => { if (this.determinismState != VI.Ok) n(new Error("Getting recordings not allowed")); else { const i = new XMLHttpRequest; i.timeout = VB(this, FB, "f"), i.overrideMimeType("text/plain"), i.onreadystatechange = () => { if (i.readyState == XMLHttpRequest.DONE) if (200 == i.status) try { const t = JSON.parse(i.responseText); if (!Array.isArray(t)) return void n(new Error("Response is not an array")); const r = []; for (const e of t) { if (null == e) { r.push(null); continue } if ("object" != typeof e || Array.isArray(e)) return void n(new Error("JSON item is not an object")); if ("string" != typeof e.recording) return void n(new Error("JSON item recording field has incorrect type")); const t = cv.deserialize(e.recording); if (null == t) return void n(new Error("Failed to deserialize recording")); if ("number" != typeof e.verifiedState) return void n(new Error("JSON item verifiedState field has incorrect type")); const i = e.verifiedState; if (!Number.isSafeInteger(i) || i < 0) return void n(new Error("JSON item verifiedState is not a safe integer")); if ("number" != typeof e.frames) return void n(new Error("JSON item frames field has incorrect type")); const a = e.frames; if (!Number.isSafeInteger(a) || a <= 0 || a > cv.maxFrames) return void n(new Error("JSON item frames is not a safe integer")); const s = new xp(a); if ("string" != typeof e.carColors) return void n(new Error("JSON item carColors field has incorrect type")); const o = Pu.deserialize(e.carColors); r.push({ recording: t, time: s, verifiedState: i, carColors: o }) } e(r) } catch (e) { n(new Error("Unknown error: " + String(e))) } else n(new Error("Failed to connect to server, status: " + i.status.toString())) }, i.open("GET", t, !0), i.send() } })) } submitLeaderboard(e, t, n, i, r, a) { return new Promise(((s, o) => { if (this.determinismState != VI.Ok) o(new Error("Submit not allowed")); else { const l = a.serialize(); if (l.length >= VB(this, WB, "f")) o(new Error("Recording is too large")); else { const a = eu + "leaderboard", c = "version=" + iu + "&userToken=" + encodeURIComponent(e) + "&name=" + encodeURIComponent(t) + "&carColors=" + n.serialize() + "&trackId=" + i + "&frames=" + r.numberOfFrames.toString() + "&recording=" + l, h = new XMLHttpRequest; h.timeout = VB(this, FB, "f"), h.overrideMimeType("text/plain"), h.onreadystatechange = () => { if (4 == h.readyState) if (200 == h.status) try { const e = JSON.parse(h.responseText); if (null == e) s({ uploadId: null }); else { const t = Number.parseInt(e, 10); Number.isSafeInteger(t) ? s({ uploadId: t }) : o(new Error("UploadId is not a safe integer")) } } catch (e) { o(new Error("Unknown error: " + String(e))) } else o(new Error("Failed to connect to server, status: " + h.status.toString())) }, h.open("POST", a, !0), h.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"), h.send(c) } } })) } submitUserProfile(e, t, n) { return new Promise(((i, r) => { const a = eu + "user", s = "version=" + iu + "&userToken=" + encodeURIComponent(e) + "&name=" + encodeURIComponent(t) + "&carColors=" + n.serialize(), o = new XMLHttpRequest; o.timeout = VB(this, FB, "f"), o.overrideMimeType("text/plain"), o.onreadystatechange = () => { 4 == o.readyState && (200 == o.status ? i() : r(new Error("Failed to connect to server, status: " + o.status.toString()))) }, o.open("POST", a, !0), o.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"), o.send(s) })) } verifyRecordings(e, t, n, i, r) { return new Promise(((a, s) => { if (this.determinismState != VI.Ok) s(new Error("Submit not allowed")); else { const o = eu + "verifyRecordings", l = "version=" + iu + "&userToken=" + encodeURIComponent(e) + (null != t ? "&trackId=" + t : "") + "&maxFrames=" + n.toString() + "&getEstimatedRemaining=" + i.toString() + "&recordings=" + encodeURIComponent(JSON.stringify(r)), c = new XMLHttpRequest; c.timeout = VB(this, FB, "f"), c.overrideMimeType("text/plain"), c.onreadystatechange = () => { if (4 == c.readyState) if (200 == c.status) try { if ("" == c.responseText) return void a({ unverifiedRecordings: [], exhaustive: !0, estimatedRemaining: 0 }); const e = JSON.parse(c.responseText); if (!("exhaustive" in e)) return void s(new Error('Field "exhaustive" does not exist')); const t = 1 == e.exhaustive; if (!("estimatedRemaining" in e)) return void s(new Error('Field "estimatedRemaining" does not exist')); let n; if (null == e.estimatedRemaining) n = null; else if (n = parseInt(e.estimatedRemaining, 10), !Number.isSafeInteger(n) || n < 0) return void s(new Error("Estimated remaining is not a valid integer")); if (!("unverifiedRecordings" in e)) return void s(new Error('Field "unverifiedRecordings" does not exist')); const i = e.unverifiedRecordings; if (!Array.isArray(i)) return void s(new Error('Field "unverifiedRecordings" is not an array')); for (const e of i) { if ("object" != typeof e) return void s(new Error("Recording is not an object")); if ("number" != typeof e.id || !Number.isSafeInteger(e.id)) return void s(new Error("Recording id is not a valid integer")); if ("string" != typeof e.recording) return void s(new Error("Recording recording is not a string")); if ("number" != typeof e.frames || !Number.isSafeInteger(e.frames) || e.frames <= 0 || e.frames > cv.maxFrames) return void s(new Error("Recording frames is not a valid integer")) } a({ unverifiedRecordings: i, exhaustive: t, estimatedRemaining: n }) } catch (e) { s(new Error("Unknown error: " + String(e))) } else 403 == c.status ? s(new Error("User is not a verifier")) : s(new Error("Failed to connect to server, status: " + c.status.toString())) }, c.open("POST", o, !0), c.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"), c.send(l) } })) } getUser(e) { return new Promise(((t, n) => { const i = eu + "user?version=" + iu + "&userToken=" + encodeURIComponent(e), r = new XMLHttpRequest; r.timeout = VB(this, FB, "f"), r.overrideMimeType("text/plain"), r.onreadystatechange = () => { if (r.readyState == XMLHttpRequest.DONE) if (200 == r.status) try { const e = JSON.parse(r.responseText); if (null == e) return void t(null); const i = e.name; if ("string" != typeof i) return void n(new Error("Name is not a string")); const a = vL(i); if (0 == a || a > 50) return void n(new Error("Name as invalid length")); const s = e.carColors; if ("string" != typeof s) return void n(new Error("CarColors data is not a string")); const o = Pu.deserialize(s), l = e.isVerifier; if ("boolean" != typeof l) return void n(new Error("IsVerifier is not a boolean")); t({ name: i, carColors: o, isVerifier: l }) } catch (e) { n(new Error("Unknown error: " + String(e))) } else n(new Error("Failed to connect to server, status: " + r.status.toString())) }, r.open("GET", i, !0), r.send() })) } }; var GB, jB, QB, YB, KB, qB = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, XB = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; jB = new WeakMap, QB = new WeakMap, YB = new WeakMap, GB = new WeakSet, KB = function(e) { for (const [t, n] of e) { if (!XB(this, YB, "f").has(t)) throw new Error("Key binding is missing"); XB(this, YB, "f").set(t, n) } }; const ZB = class { constructor(e) { GB.add(this), jB.set(this, void 0), QB.set(this, this.defaultSettings()), YB.set(this, this.defaultKeyBindings()), qB(this, jB, e, "f"); const t = e.loadSettings(); null != t && this.updateSettings(t); const n = e.loadKeyBindings(); null != n && XB(this, GB, "m", KB).call(this, n) } defaultSettings() { return new Map([ [$o.ImperialUnitsEnabled, "false"], [$o.ResetHintEnabled, "true"], [$o.GhostCarEnabled, "true"], [$o.DefaultCameraMode, "false"], [$o.CockpitCameraToggle, "true"], [$o.Checkpoints, "bottom"], [$o.Timer, "bottom"], [$o.Speedometer, "bottom"], [$o.Language, "en-US"], [$o.CarShadowQuality, "2048"], [$o.TrackShadowEnabled, "true"], [$o.CloudsEnabled, "true"], [$o.ParticlesEnabled, "true"], [$o.SkidmarksEnabled, "true"], [$o.RenderScale, "1"], [$o.Antialiasing, "true"], [$o.SoundEffectVolume, "1"], [$o.MusicVolume, "1"], [$o.CheckpointVolume, "1"] ]) } defaultKeyBindings() { return new Map([ [Ix.VehicleAccelerate, ["KeyW", "ArrowUp"]], [Ix.VehicleTurnRight, ["KeyD", "ArrowRight"]], [Ix.VehicleBrake, ["KeyS", "ArrowDown"]], [Ix.VehicleTurnLeft, ["KeyA", "ArrowLeft"]], [Ix.VehicleCheckpointReset, ["KeyR", "Enter"]], [Ix.VehicleStartReset, ["KeyT", "Backspace"]], [Ix.VehicleCockpitCamera, ["KeyC", "KeyM"]], [Ix.ToggleUI, ["KeyH", null]], [Ix.Pause, ["KeyP", "Space"]], [Ix.EditorRotatePart, ["KeyR", "Space"]], [Ix.EditorHeightModifier, ["ShiftLeft", "ShiftRight"]], [Ix.EditorDelete, ["Delete", "KeyX"]], [Ix.EditorMoveForwards, ["KeyW", "ArrowUp"]], [Ix.EditorMoveRight, ["KeyD", "ArrowRight"]], [Ix.EditorMoveBackwards, ["KeyS", "ArrowDown"]], [Ix.EditorMoveLeft, ["KeyA", "ArrowLeft"]], [Ix.EditorRotateViewUp, ["KeyY", null]], [Ix.EditorRotateViewDown, ["KeyH", null]], [Ix.EditorRotateViewLeft, ["KeyQ", null]], [Ix.EditorRotateViewRight, ["KeyE", null]], [Ix.EditorMoveDown, ["KeyZ", null]], [Ix.EditorMoveUp, ["KeyC", null]], [Ix.EditorTest, ["KeyT", null]], [Ix.EditorPick, ["KeyG", null]], [Ix.ToggleFpsCounter, ["Comma", null]], [Ix.ToggleSpectatorCamera, ["Period", null]], [Ix.SpectatorMoveForwards, ["KeyW", "ArrowUp"]], [Ix.SpectatorMoveRight, ["KeyD", "ArrowRight"]], [Ix.SpectatorMoveBackwards, ["KeyS", "ArrowDown"]], [Ix.SpectatorMoveLeft, ["KeyA", "ArrowLeft"]], [Ix.SpectatorSpeedModifier, ["ShiftLeft", "ShiftRight"]] ]) } getSettings() { return Array.from(XB(this, QB, "f")) } getSetting(e) { const t = XB(this, QB, "f").get(e); if (null == t) throw new Error("Setting name is missing"); return t } getSettingBoolean(e) { return "true" == this.getSetting(e) } getSettingFloat(e) { return parseFloat(this.getSetting(e)) } getSettingInteger(e) { return parseInt(this.getSetting(e), 10) } updateSettings(e) { for (const [t, n] of e) { if (!XB(this, QB, "f").has(t)) throw new Error("Setting name is missing"); XB(this, QB, "f").set(t, n) } } saveSettings() { XB(this, jB, "f").saveSettings(XB(this, QB, "f")) } getKeyBindings(e) { var t; return null !== (t = XB(this, YB, "f").get(e)) && void 0 !== t ? t : [null, null] } setKeyBindings(e) { XB(this, GB, "m", KB).call(this, e), XB(this, jB, "f").saveKeyBindings(XB(this, YB, "f")) } checkKeyBinding(e, t) { var n; const i = null !== (n = XB(this, YB, "f").get(t)) && void 0 !== n ? n : []; for (const t of i) if (null != t && e.code == t) return !0; return !1 } }; var JB; ! function(e) { e[e.Init = 0] = "Init", e[e.Verify = 1] = "Verify", e[e.TestDeterminism = 2] = "TestDeterminism", e[e.CreateCar = 3] = "CreateCar", e[e.DeleteCar = 4] = "DeleteCar", e[e.StartCar = 5] = "StartCar", e[e.ControlCar = 6] = "ControlCar", e[e.PauseCar = 7] = "PauseCar", e[e.VerifyResult = 8] = "VerifyResult", e[e.DeterminismResult = 9] = "DeterminismResult", e[e.UpdateResult = 10] = "UpdateResult" }(JB || (JB = {})); const $B = JB; var eU, tU, nU, iU, rU, aU, sU, oU = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, lU = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; tU = new WeakMap, nU = new WeakMap, iU = new WeakMap, rU = new WeakMap, aU = new WeakMap, eU = new WeakSet, sU = function(e, t) { const n = t.getPhysicsParts(); lU(this, nU, "f").postMessage({ messageType: $B.Init, isRealtime: e, trackParts: n }) }; const cU = class { constructor(e, t, n) { eU.add(this), tU.set(this, void 0), nU.set(this, void 0), iU.set(this, !1), rU.set(this, 0), aU.set(this, new Map), oU(this, nU, new Worker("simulation_worker.bundle.js"), "f"), null != t && null != n ? (oU(this, tU, t, "f"), n.hasLoaded() ? lU(this, eU, "m", sU).call(this, e, t) : n.addCompleteListener((() => { lU(this, eU, "m", sU).call(this, e, t) }))) : oU(this, tU, null, "f") } dispose() { lU(this, nU, "f").terminate(), oU(this, iU, !0, "f") } validate(e, t, n) { return new Promise(((i, r) => { var a, s; if (null == lU(this, tU, "f")) throw new Error("TrackPartManager is not initialized"); if (null == e.getStartTransform()) i(!1); else { const o = VP.createMountainVertices(e.getBounds()); if (null == Aw.models) throw new Error("Car collision model not loaded"); const l = (oU(this, rU, (s = lU(this, rU, "f"), a = s++, s), "f"), a), c = setInterval((() => { lU(this, iU, "f") && (clearInterval(c), r(new Error("Simulation has been disposed"))) }), 10), h = e => { e.data.messageType == $B.VerifyResult && e.data.carId == l && (clearInterval(c), lU(this, nU, "f").removeEventListener("message", h), i(e.data.result)) }; lU(this, nU, "f").addEventListener("message", h), lU(this, nU, "f").postMessage({ messageType: $B.Verify, mountainVertices: o.vertices, mountainOffset: { x: o.offset.x, y: o.offset.y, z: o.offset.z }, trackData: e.toSaveString(), carId: l, carCollisionShapeVertices: Aw.models.collisionShapeVertices, carMassOffset: Aw.massOffset, carRecording: t.serialize(), targetFrames: n.numberOfFrames }) } })) } testDeterminism() { return new Promise((e => { const t = n => { if (n.data.messageType === $B.DeterminismResult) lU(this, nU, "f").removeEventListener("message", t), e(n.data.isDeterminstic) }; lU(this, nU, "f").addEventListener("message", t), lU(this, nU, "f").postMessage({ messageType: $B.TestDeterminism }) })) } createCar(e, t, n, i, r, a) { var s, o; if (null == lU(this, tU, "f")) throw new Error("TrackPartManager is not initialized"); if (null == Aw.models) throw new Error("Car collision model not loaded"); const l = (oU(this, rU, (o = lU(this, rU, "f"), s = o++, o), "f"), s), c = e => { if (e.data.messageType == $B.UpdateResult) { const t = e.data.carStates; for (const e of t) e.id == l && a(e) } }; lU(this, nU, "f").addEventListener("message", c), lU(this, aU, "f").set(l, c), lU(this, nU, "f").postMessage({ messageType: $B.CreateCar, mountainVertices: t, mountainOffset: { x: n.x, y: n.y, z: n.z }, trackData: i.toSaveString(), carId: l, carCollisionShapeVertices: Aw.models.collisionShapeVertices, carMassOffset: Aw.massOffset, carRecording: null == r ? void 0 : r.serialize() }); const h = [new yn(.627909, .27 - Aw.suspensionResetLengthFront, 1.3478).applyQuaternion(e.quaternion).add(e.position), new yn(-.627909, .27 - Aw.suspensionResetLengthFront, 1.3478).applyQuaternion(e.quaternion).add(e.position), new yn(.720832, .27 - Aw.suspensionResetLengthRear, -1.52686).applyQuaternion(e.quaternion).add(e.position), new yn(-.720832, .27 - Aw.suspensionResetLengthRear, -1.52686).applyQuaternion(e.quaternion).add(e.position)], d = [(new wn).setFromEuler((new ai).set(0, Math.PI, 0)).multiply(e.quaternion), (new wn).setFromEuler((new ai).set(0, Math.PI, 0)).multiply(e.quaternion), (new wn).setFromEuler((new ai).set(0, Math.PI, 0)).multiply(e.quaternion), (new wn).setFromEuler((new ai).set(0, Math.PI, 0)).multiply(e.quaternion)]; return { id: l, frames: 0, speedKmh: 0, hasStarted: !1, finishFrames: null, nextCheckpointIndex: 0, hasCheckpointToRespawnAt: !1, position: { x: e.position.x, y: e.position.y, z: e.position.z }, quaternion: { x: e.quaternion.x, y: e.quaternion.y, z: e.quaternion.z, w: e.quaternion.w }, collisionImpulses: [], wheelInContact: [!1, !1, !1, !1], wheelSuspensionLength: [Aw.suspensionResetLengthFront, Aw.suspensionResetLengthFront, Aw.suspensionResetLengthRear, Aw.suspensionResetLengthRear], wheelSuspensionVelocity: [0, 0, 0, 0], wheelRotation: [0, 0, 0, 0], wheelDeltaRotation: [0, 0, 0, 0], wheelSkidInfo: [0, 0, 0, 0], wheelPosition: h, wheelQuaternion: d, brakeLightEnabled: !1, controls: { up: !1, right: !1, down: !1, left: !1, reset: !1 } } } deleteCar(e) { lU(this, nU, "f").postMessage({ messageType: $B.DeleteCar, carId: e }); const t = lU(this, aU, "f").get(e); if (null == t) throw new Error("Deleting non-existant car"); lU(this, nU, "f").removeEventListener("message", t), lU(this, aU, "f").delete(e) } startCar(e, t) { lU(this, nU, "f").postMessage({ messageType: $B.StartCar, carId: e, targetSimulationTimeFrames: null == t ? void 0 : t.numberOfFrames }) } controlCar(e, t, n, i, r, a) { lU(this, nU, "f").postMessage({ messageType: $B.ControlCar, carId: e, up: t, right: n, down: i, left: r, reset: a }) } pauseCar(e, t) { lU(this, nU, "f").postMessage({ messageType: $B.PauseCar, carId: e, isPaused: t }) } }; var hU = n(2796), dU = {}; dU.styleTagTransform = u(), dU.setAttributes = l(), dU.insert = s().bind(null, "head"), dU.domAPI = r(), dU.insertStyleElement = h(); t()(hU.A, dU); hU.A && hU.A.locals && hU.A.locals; var uU, pU, fU, mU, gU, vU, wU, yU = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, AU = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; uU = new WeakMap, pU = new WeakMap, fU = new WeakMap, mU = new WeakMap, gU = new WeakMap, vU = new WeakMap, wU = new WeakMap; const bU = class { constructor(e, t, n, i, r, a) { uU.set(this, void 0), pU.set(this, void 0), fU.set(this, void 0), mU.set(this, void 0), gU.set(this, void 0), vU.set(this, void 0), wU.set(this, new Map); const s = document.getElementById("ui"); if (null == s) throw new Error("UI element not found"); yU(this, uU, s, "f"), yU(this, pU, document.createElement("div"), "f"), AU(this, pU, "f").className = "verifier-ui", AU(this, uU, "f").appendChild(AU(this, pU, "f")), yU(this, fU, document.createElement("p"), "f"), AU(this, pU, "f").appendChild(AU(this, fU, "f")); const o = document.createElement("p"); o.textContent = "Number of threads: " + t.toString(), AU(this, pU, "f").appendChild(o); const l = document.createElement("input"); l.type = "range", l.min = "0", l.max = t.toString(), l.value = t.toString(), l.addEventListener("change", (() => { const e = parseInt(l.value, 10); o.textContent = "Number of threads: " + e.toString(), r(e) })), AU(this, pU, "f").appendChild(l); const c = document.createElement("p"); c.textContent = "Max time: " + Math.floor(n / 60 / 1e3).toString() + " minutes", AU(this, pU, "f").appendChild(c); const h = document.createElement("input"); h.type = "range", h.min = 6e4.toString(), h.max = cv.maxFrames.toString(), h.value = n.toString(), h.addEventListener("input", (() => { const e = parseInt(h.value, 10); c.textContent = "Max time: " + Math.floor(e / 60 / 1e3).toString() + " minutes", a(e) })), AU(this, pU, "f").appendChild(h); const d = document.createElement("table"); AU(this, pU, "f").appendChild(d), yU(this, mU, d.createTHead(), "f"), yU(this, gU, d.createTBody(), "f"); const u = AU(this, mU, "f").insertRow(); for (const e of ["Track", "State", "Verified", "Invalid", "Estimated remaining"]) { const t = document.createElement("th"); t.textContent = e, u.appendChild(t) } const p = document.createElement("button"); p.className = "button", p.textContent = "Stop", p.addEventListener("click", (() => { e.playUIClick(), i() })), AU(this, pU, "f").appendChild(p), window.addEventListener("keydown", yU(this, vU, (e => { "Escape" == e.code && (i(), e.preventDefault()) }), "f")) } dispose() { AU(this, uU, "f").removeChild(AU(this, pU, "f")), window.removeEventListener("keydown", AU(this, vU, "f")) } setText(e) { AU(this, fU, "f").textContent = e } setTracks(e) { for (const t of e) { let e = AU(this, wU, "f").get(t.id); if (null == e) { e = { element: AU(this, gU, "f").insertRow(), name: t.name, exhausted: t.exhausted, recordingsVerified: t.recordingsVerified, invalidRecordings: t.invalidRecordings, estimatedRemaining: t.estimatedRemaining }, AU(this, wU, "f").set(t.id, e); e.element.insertCell().textContent = t.name; e.element.insertCell().textContent = t.exhausted ? "Empty" : "Processing"; e.element.insertCell().textContent = t.recordingsVerified.toString(); e.element.insertCell().textContent = t.invalidRecordings.toString(); const n = e.element.insertCell(); null != t.estimatedRemaining ? n.textContent = t.estimatedRemaining.toString() : n.textContent = "?" } else e.name != t.name && (e.element.cells[0].textContent = t.name, e.name = t.name), e.exhausted != t.exhausted && (e.element.cells[1].textContent = t.exhausted ? "Empty" : "Processing", e.exhausted = t.exhausted), e.recordingsVerified != t.recordingsVerified && (e.element.cells[2].textContent = t.recordingsVerified.toString(), e.recordingsVerified = t.recordingsVerified), e.invalidRecordings != t.invalidRecordings && (e.element.cells[3].textContent = t.invalidRecordings.toString(), e.invalidRecordings = t.invalidRecordings), e.estimatedRemaining != t.estimatedRemaining && (null != t.estimatedRemaining ? e.element.cells[4].textContent = t.estimatedRemaining.toString() : e.element.cells[4].textContent = "?", e.estimatedRemaining = t.estimatedRemaining) } } }; var xU, kU, EU, SU, MU, TU, _U, CU, PU, IU, RU, LU, DU, NU, BU, UU, zU, OU, FU, WU, VU, HU, GU, jU, QU, YU, KU, qU, XU, ZU, JU, $U, ez, tz = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, nz = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; kU = new WeakMap, EU = new WeakMap, SU = new WeakMap, MU = new WeakMap, TU = new WeakMap, _U = new WeakMap, CU = new WeakMap, PU = new WeakMap, IU = new WeakMap, RU = new WeakMap, LU = new WeakMap, DU = new WeakMap, NU = new WeakMap, BU = new WeakMap, UU = new WeakMap, zU = new WeakMap, OU = new WeakMap, FU = new WeakMap, WU = new WeakMap, VU = new WeakMap, HU = new WeakMap, GU = new WeakMap, jU = new WeakMap, QU = new WeakMap, YU = new WeakMap, KU = new WeakMap, qU = new WeakMap, XU = new WeakMap, ZU = new WeakMap, xU = new WeakSet, JU = function(e) { const t = nz(this, IU, "f").slice(); do { const n = Math.floor(Math.random() * t.length), i = t.splice(n, 1)[0]; if (e > i.timeout) return i } while (t.length > 0); return null }, $U = function() { var e; const t = new Date; if (!nz(this, LU, "f") && nz(this, NU, "f").length < nz(this, jU, "f") && Math.abs(t.getTime() - nz(this, DU, "f").getTime()) >= nz(this, QU, "f")) { tz(this, LU, !0, "f"), tz(this, DU, t, "f"); const n = nz(this, xU, "m", JU).call(this, t); if (null != n || nz(this, RU, "f").length > 0 && 0 == nz(this, NU, "f").length || nz(this, RU, "f").length > nz(this, GU, "f")) { const i = nz(this, RU, "f"); tz(this, RU, [], "f"); const r = null != n && (null == n.lastEstimatedRemainingTime || Math.abs(t.getTime() - n.lastEstimatedRemainingTime.getTime()) >= nz(this, YU, "f")); nz(this, MU, "f").verifyRecordings(nz(this, _U, "f"), null !== (e = null == n ? void 0 : n.id) && void 0 !== e ? e : null, nz(this, KU, "f"), r, i).then((({ unverifiedRecordings: e, exhaustive: i, estimatedRemaining: r }) => { null != n && (tz(this, NU, nz(this, NU, "f").concat(e.map((({ id: e, recording: t, frames: i }) => ({ track: n, trackData: n.data, recordingId: e, recording: cv.deserialize(t), time: new xp(i) })))), "f"), i && (n.timeout = new Date(t.getTime() + Math.floor(432e5 + 12 * Math.random() * 60 * 60 * 1e3))), null != r && (n.estimatedRemaining = r, n.lastEstimatedRemainingTime = t)) })).catch((e => { console.error(e), nz(this, MU, "f").getUser(nz(this, _U, "f")).then((e => { (null == e ? void 0 : e.isVerifier) || tz(this, BU, !1, "f") })).catch((e => { console.warn(e) })) })).finally((() => { tz(this, LU, !1, "f") })) } else tz(this, LU, !1, "f") } }, ez = function() { var e, t, n; if (nz(this, TU, "f").hasLoaded() && nz(this, BU, "f")) { nz(this, xU, "m", $U).call(this); for (const i of nz(this, PU, "f")) if (!i.isBusy && nz(this, NU, "f").length > 0) { i.isBusy = !0; const { track: r, trackData: a, recordingId: s, recording: o, time: l } = nz(this, NU, "f").splice(0, 1)[0]; null == o ? (tz(this, WU, (e = nz(this, WU, "f"), ++e), "f"), r.recordingsVerified++, tz(this, VU, (t = nz(this, VU, "f"), ++t), "f"), r.invalidRecordings++, null != r.estimatedRemaining && (r.estimatedRemaining = Math.max(0, r.estimatedRemaining - 1)), nz(this, RU, "f").push({ id: s, verifiedState: HI.Invalid }), i.isBusy = !1) : (tz(this, FU, (n = nz(this, FU, "f"), ++n), "f"), i.simulation.validate(a, o, l).then((e => { var t, n; tz(this, WU, (t = nz(this, WU, "f"), ++t), "f"), r.recordingsVerified++, e || (tz(this, VU, (n = nz(this, VU, "f"), ++n), "f"), r.invalidRecordings++), null != r.estimatedRemaining && (r.estimatedRemaining = Math.max(0, r.estimatedRemaining - 1)), tz(this, HU, nz(this, HU, "f") + l.numberOfFrames, "f"), nz(this, RU, "f").push({ id: s, verifiedState: e ? HI.Verified : HI.Invalid }) })).catch((e => { if (!i.isDisposed) throw e })).finally((() => { var e; i.isBusy = !1, tz(this, FU, (e = nz(this, FU, "f"), --e), "f") }))) } } }; const iz = class { constructor(e, t, n, i, r, a, s, o, l) { xU.add(this), kU.set(this, void 0), EU.set(this, void 0), SU.set(this, void 0), MU.set(this, void 0), TU.set(this, void 0), _U.set(this, void 0), CU.set(this, void 0), PU.set(this, []), IU.set(this, []), RU.set(this, []), LU.set(this, !1), DU.set(this, new Date), NU.set(this, []), BU.set(this, !0), UU.set(this, void 0), zU.set(this, !1), OU.set(this, new Date), FU.set(this, 0), WU.set(this, 0), VU.set(this, 0), HU.set(this, 0), GU.set(this, 100), jU.set(this, 100), QU.set(this, 1e3), YU.set(this, 36e5), KU.set(this, 6e5), qU.set(this, 4), XU.set(this, void 0), ZU.set(this, null), tz(this, kU, e, "f"), tz(this, EU, t, "f"), tz(this, SU, a, "f"), tz(this, MU, n, "f"), tz(this, TU, s, "f"), tz(this, _U, o, "f"), "undefined" != typeof navigator && "hardwareConcurrency" in navigator && navigator.hardwareConcurrency > 0 && tz(this, qU, navigator.hardwareConcurrency, "f"), tz(this, XU, nz(this, qU, "f"), "f"), t.clear(), tz(this, CU, new bU(e, nz(this, qU, "f"), nz(this, KU, "f"), l, (e => { for (tz(this, XU, e, "f"); nz(this, PU, "f").length < nz(this, XU, "f");) nz(this, PU, "f").push({ simulation: new cU(!1, r, s), isBusy: !1, isDisposed: !1 }); for (; nz(this, PU, "f").length > nz(this, XU, "f");) { const e = nz(this, PU, "f").pop(); null != e && (e.simulation.dispose(), e.isDisposed = !0) } }), (e => { tz(this, KU, e, "f"); for (const e of nz(this, IU, "f")) e.timeout = new Date, e.estimatedRemaining = null })), "f"); for (let e = 0; e < nz(this, XU, "f"); e++) nz(this, PU, "f").push({ simulation: new cU(!1, r, nz(this, TU, "f")), isBusy: !1, isDisposed: !1 }); i.forEachTrack(((e, t, n) => { nz(this, IU, "f").push({ id: e, name: t.name, data: n, timeout: new Date, recordingsVerified: 0, invalidRecordings: 0, estimatedRemaining: null, lastEstimatedRemainingTime: null }) })), tz(this, UU, setInterval((() => { nz(this, xU, "m", ez).call(this) }), 10), "f"); try { navigator.wakeLock.request("screen").then((e => { nz(this, zU, "f") ? e.release().catch((e => { console.error(e) })) : tz(this, ZU, e, "f") })).catch((e => { console.warn(e) })) } catch (e) { console.error(e) } } dispose() { tz(this, zU, !0, "f"), nz(this, CU, "f").dispose(); for (const e of nz(this, PU, "f")) e.simulation.dispose(), e.isDisposed = !0; nz(this, PU, "f").length = 0, clearInterval(nz(this, UU, "f")), null != nz(this, ZU, "f") && nz(this, ZU, "f").release().catch((e => { console.error(e) })) } update(e) { if (nz(this, TU, "f").hasLoaded()) { const e = new Date, t = (e.getTime() - nz(this, OU, "f").getTime()) / 1e3; let n = ""; nz(this, BU, "f") ? n += "Recordings are being verified...\n" : n += "Error: User is no longer a verifier\n", n += "\nBacklog: " + nz(this, NU, "f").length.toString(), n += "\nProcessing: " + nz(this, FU, "f").toString(), n += "\nRecordings verified: " + nz(this, WU, "f").toString(), n += "\nInvalid recordings found: " + nz(this, VU, "f").toString(), n += "\n", n += "\nVerifications per second: " + (nz(this, WU, "f") / t).toFixed(2), n += "\nSimulated frames per second: " + Math.floor(nz(this, HU, "f") / t).toString(), nz(this, CU, "f").setTracks(nz(this, IU, "f").map((({ id: t, name: n, timeout: i, recordingsVerified: r, invalidRecordings: a, estimatedRemaining: s }) => ({ id: t, name: n, exhausted: i > e, recordingsVerified: r, invalidRecordings: a, estimatedRemaining: s })))), nz(this, CU, "f").setText(n) } nz(this, kU, "f").update(e, !1, nz(this, EU, "f"), nz(this, SU, "f")) } }, rz = { "Checkpoint order": "ترتيب النقاط التفتيشية", Height: "الارتفاع", Exit: "خروج", Random: "عشوائي", Primary: "أساسي", Secondary: "ثانوي", Frame: "الإطار", Rims: "الجنوط", "Are you sure you want to exit without saving?": "هل أنت متأكد من أنك تريد الخروج دون حفظ؟", "All changes will be lost!": "سيتم فقدان جميع التغييرات!", "Car saved!": "تم حفظ السيارة!", Test: "اختبار", "Starting point is missing!": "نقطة البداية مفقودة!", Generate: "إنشاء", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "هل أنت متأكد من أنك تريد إنشاء مسار جديد؟\n\nسيتم فقدان المسار الحالي!", Load: "تحميل", Save: "حفظ", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "هل أنت متأكد من أنك تريد تحميل مسار جديد؟\n\nسيتم فقدان المسار الحالي!", "Track saved!": "تم حفظ المسار!", "Failed to save!": "فشل الحفظ!", 'Are you sure you want to overwrite "{0}"?': 'هل أنت متأكد من أنك تريد الكتابة فوق "{0}"؟', Export: "تصدير", Help: "مساعدة", "Are you sure you want to exit the editor?": "هل أنت متأكد من أنك تريد الخروج من المحرر؟", "All unsaved data will be lost!": "سيتم فقدان جميع البيانات غير المحفوظة!", "Track settings": "إعدادات المسار", "Unnamed Track": "مسار بدون اسم", "Track name": "اسم المسار", Author: "المؤلف", Unknown: "غير معروف", Environment: "البيئة", Summer: "الصيف", Winter: "الشتاء", Desert: "الصحراء", "Sun direction": "اتجاه الشمس", "How to use the editor": "كيفية استخدام المحرر", "Camera controls": "ضوابط الكاميرا", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "يمكن تحريك الكاميرا بالنقر بزر الماوس الأيمن وسحب الماوس. قم بتدوير الكاميرا بالنقر على زر الماوس الأوسط (عجلة الماوس) أو بالضغط على مفتاح التحكم والنقر بزر الماوس الأيمن وسحب الماوس. قم بالتكبير والتصغير عن طريق تمرير عجلة الماوس.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "بدلاً من ذلك، يمكن أيضًا التحكم في الكاميرا باستخدام مفاتيح لوحة المفاتيح التالية:", "Move forwards:": "تحرك للأمام:", "Move backwards:": "تحرك للخلف:", "Move left:": "تحرك لليسار:", "Move right:": "تحرك لليمين:", "Rotate left:": "تدوير لليسار:", "Rotate right:": "تدوير لليمين:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "يمكن تغيير الارتفاع المحرر إما باستخدام اختيار الارتفاع في الزاوية السفلية اليسرى، أو بالضغط على مفتاح Shift وتمرير عجلة الماوس. بدلاً من ذلك، يمكنك استخدام مفاتيح لوحة المفاتيح التالية:", "Move up:": "تحرك لأعلى:", "Move down:": "تحرك لأسفل:", Editing: "تحرير", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "يمكن اختيار أجزاء المسار في القائمة الموجودة على اليمين وبعد ذلك يمكن وضعها بالنقر بزر الماوس الأيسر.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "بدلاً من ذلك، يمكن اختيار جزء المسار الذي يتم تحويمه حاليًا بواسطة الماوس باستخدام اختصار لوحة المفاتيح التالي:", "The selected part can then be rotated using the following keyboard shortcut:": "يمكن بعد ذلك تدوير الجزء المحدد باستخدام اختصار لوحة المفاتيح التالي:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "يمكن حذف أجزاء المسار باستخدام أداة الحذف في القائمة الجانبية اليمنى أو بالضغط على المفتاح التالي:", "Starting points, checkpoints and the finish line": "نقاط البداية ونقاط التفتيش وخط النهاية", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "يمكن اختيار نقاط البداية ونقاط التفتيش وخطوط النهاية جميعها في الفئة العليا في القائمة الجانبية اليمنى.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "يجب أن يحتوي كل مسار على نقطة بداية واحدة على الأقل. إذا كانت هناك نقاط بداية متعددة، فسيتم استخدام آخر نقطة تم وضعها.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "يجب وضع نقاط التفتيش بين نقطة البداية وخط النهاية. عند اختيار جزء مسار نقطة التفتيش، سيكون هناك أداة في الزاوية السفلية اليمنى لاختيار ترتيب نقطة التفتيش. يحدد هذا الترتيب الذي يجب أن تمر به نقاط التفتيش قبل القيادة إلى خط النهاية. لاحظ أنه من الممكن أن يكون هناك نقاط تفتيش متعددة بنفس ترتيب نقطة التفتيش.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "خط النهاية هو المكان الذي ينتهي فيه المسار ولكنه سيصبح نشطًا فقط بعد اجتياز جميع نقاط التفتيش. من الممكن أيضًا أن يكون هناك خطوط نهاية متعددة.", "Starting point": "نقطة البداية", Checkpoint: "نقطة التفتيش", "Finish line": "خط النهاية", "Exporting the track": "تصدير المسار", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "عند الانتهاء من المسار، يمكن إدخال اسم للمسار في الزاوية العلوية اليسرى وبعد ذلك يمكن تصدير المسار باستخدام زر التصدير. سيظهر رمز المسار الذي يمكن إرساله إلى مستخدمين آخرين حتى يتمكنوا من استيراد وتشغيل المسار.", Close: "إغلاق", "Not set": "غير محدد", or: "أو", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "يمكن تحريك الكاميرا بالنقر بزر الماوس الأيمن وسحب الماوس. قم بتدوير الكاميرا بالنقر على زر الماوس الأوسط (عجلة الماوس) أو بالضغط على مفتاح التحكم والنقر بزر الماوس الأيمن وسحب الماوس. قم بالتكبير والتصغير عن طريق تمرير عجلة الماوس.", "The edited height can be changed by using the height selection in the bottom left corner.": "يمكن تغيير الارتفاع المحرر باستخدام اختيار الارتفاع في الزاوية السفلية اليسرى.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "يمكن اختيار أجزاء المسار في القائمة الموجودة على اليمين وبعد ذلك يمكن وضعها بالنقر على الشاشة.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "يمكن بعد ذلك تدوير الجزء المحدد بالنقر على زر الدوران في الزاوية السفلية اليسرى.", "Track parts can be deleted by using the delete tool in the right side menu.": "يمكن حذف أجزاء المسار باستخدام أداة الحذف في القائمة الجانبية اليمنى.", Watch: "مشاهدة", "Loading replay": "جاري تحميل التسجيل", "Press {0} to return to the last checkpoint": "اضغط {0} للعودة إلى آخر نقطة تفتيش", "Press {0} to start over": "اضغط {0} للبدء من جديد", "Reset once to return to the last checkpoint": "إعادة تعيين مرة واحدة للعودة إلى آخر نقطة تفتيش", "Reset again to start over": "إعادة تعيين مرة أخرى للبدء من جديد", Leaderboard: "التصنيف", Back: "عودة", "Error: Failed to load leaderboard": "خطأ: فشل تحميل التصنيف", Pending: "قيد الانتظار", Verified: "تم التحقق", Invalid: "غير صالح", Duplicate: "مكرر", You: "أنت", "Only verified": "المحققون فقط", Loading: "جاري التحميل", "Failed to load recordings": "فشل تحميل التسجيلات", "Cannot load recordings due to non-determinism": "لا يمكن تحميل التسجيلات بسبب عدم التحديد", Ok: "موافق", "Track is missing starting point": "المسار يفتقد نقطة البداية", "Some leaderboard features are disabled.": "تم تعطيل بعض ميزات التصنيف.", "Please try another browser or device.": "يرجى محاولة متصفح أو جهاز آخر.", "You already have another instance of PolyTrack open.": "لديك بالفعل نسخة أخرى من PolyTrack مفتوحة.", "Please switch to that tab or window to continue.": "يرجى التبديل إلى تلك التبويب أو النافذة للمتابعة.", "Computer determinism check failed.": "فشل فحص التحديد الحاسوبي.", "Non-deterministic game assets found.": "تم العثور على موارد اللعبة غير الحاسوبية.", "Please try clearing your browser cache.": "يرجى محاولة مسح ذاكرة التخزين المؤقت للمتصفح.", Customize: "تخصيص", Editor: "المحرر", Settings: "الإعدادات", Profile: "الملف الشخصي", Play: "إلعب", Version: "الإصدار", "You cannot have duplicate user profiles": "لا يمكنك امتلاك ملفات تعريف مستخدم مكررة", "Failed to create user profile": "فشل في إنشاء ملف تعريف المستخدم", "This user profile does not exist on the server": "هذا الملف الشخصي للمستخدم غير موجود على الخادم", "Failed to download user profile from the server": "فشل في تحميل ملف تعريف المستخدم من الخادم", "User token is invalid": "رمز المستخدم غير صالح", "Are you sure you want to display your private key?": "هل أنت متأكد أنك تريد عرض المفتاح الخاص؟", "DO NOT SHARE THIS KEY WITH ANYONE.": "لا تشارك هذا المفتاح مع أي شخص.", "You need a free user profile slot to import a new user profile": "تحتاج إلى فتحة ملف تعريف مستخدم فارغة لاستيراد ملف تعريف مستخدم جديد", Quit: "الخروج", Fullscreen: "ملء الشاشة", Windowed: "نافذة", " ": "يبدو أنك تلعب نسخة غير رسمية من {0}. للحصول على أحدث إصدار يرجى زيارة المصدر الأصلي:", Nickname: "اسم المستخدم", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "اختر اسم مستخدم ليظهر في التصنيف. يمكنك تغيير اسم المستخدم في أي وقت.", Cancel: "إلغاء", Confirm: "تأكيد", Verifier: "التحقق", "User ID": "معرف المستخدم", Paused: "متوقف", "Switch car": "تبديل السيارة", Profiles: "الملفات", 'Are you sure you would like to delete "{0}"?': 'هل أنت متأكد أنك تريد حذف "{0}"؟', Empty: "فارغ", Reset: "إعادة تعيين", Apply: "تطبيق", Gameplay: "أسلوب اللعب", Units: "الوحدات", Metric: "متري", Imperial: "إمبراطوري", "Reset hint": "إعادة تعيين التلميح", Disabled: "معطل", Enabled: "مفعل", "Ghost car": "سيارة الشبح", "Default camera": "الكاميرا الافتراضية", Default: "افتراضي", Cockpit: "القمرة", "Cockpit camera mode": "وضع الكاميرا في القمرة", Hold: "استمرار", Toggle: "تبديل", Checkpoints: "نقاط التفتيش", Timer: "المؤقت", Speedometer: "عداد السرعة", Bottom: "أسفل", Top: "أعلى", Language: "اللغة", Graphics: "الجرافيكس", "Car shadow": "ظل السيارة", "Track shadow": "ظل المسار", Off: "إيقاف", On: "تشغيل", Low: "منخفض", Medium: "متوسط", High: "عالي", Clouds: "السحب", Particles: "الجسيمات", Skidmarks: "علامات الانزلاق", "Render scale": "مقياس الرسم", "Anti-aliasing (requires restart)": "تمويه الحواف (يتطلب إعادة التشغيل)", Audio: "الصوت", "Sound effect volume": "مستوى تأثير الصوت", "Music volume": "مستوى الموسيقى", "Checkpoint volume": "مستوى نقطة التفتيش", Controls: "التحكم", Vehicle: "المركبة", Accelerate: "التسارع", Brake: "الفرامل", "Turn left": "الدوران لليسار", "Turn right": "الدوران لليمين", "Checkpoint reset": "إعادة تعيين نقطة التفتيش", "Start reset": "إعادة تعيين البداية", "Cockpit camera": "كاميرا القمرة", "Rotate part": "تدوير الجزء", "Height modifier": "معدل الارتفاع", "Delete part": "حذف الجزء", "Move forwards": "تحرك للأمام", "Move backwards": "تحرك للخلف", "Move left": "تحرك لليسار", "Move right": "تحرك لليمين", "Rotate view up": "تدوير العرض لأعلى", "Rotate view down": "تدوير العرض لأسفل", "Rotate view left": "تدوير العرض لليسار", "Rotate view right": "تدوير العرض لليمين", "Move down": "تحرك لأسفل", "Move up": "تحرك لأعلى", "Test track": "اختبار المسار", "Pick part": "اختيار الجزء", Spectator: "المشاهد", "Speed modifier": "معدل السرعة", Other: "أخرى", "Hide UI": "إخفاء واجهة المستخدم", Pause: "إيقاف مؤقت", "Toggle FPS counter": "تبديل عداد الإطارات في الثانية", "Toggle spectator camera": "تبديل كاميرا المشاهد", "Press any key...\n\nPress [Escape] to cancel.": "اضغط على أي مفتاح...\n\nاضغط [إلغاء] للإلغاء.", Clear: "مسح", "New record": "رقم قياسي جديد", Record: "الرقم القياسي", Current: "الحالي", Difference: "الفرق", Copy: "نسخ", Import: "استيراد", "Failed to import track": "فشل استيراد المسار", 'The track "{0}" already exists. Do you wish to overwrite it?': 'المسار "{0}" موجود بالفعل. هل ترغب في الكتابة فوقه؟', Overwrite: "الكتابة فوقه", "Paste track data here...": "الصق بيانات المسار هنا...", Rank: "التصنيف", "Personal best": "الرقم القياسي الشخصي", Opponents: "المنافسون", "{0} opponent selected": "{0} منافس محدد", "{0} opponents selected": "{0} منافسين محددين", "Select opponents to race against from the leaderboard on the left": "اختر المنافسين للسباق ضدهم من لوحة المتصدرين على اليسار", "No record": "لا يوجد تسجيل", "Official tracks": "المسارات الرسمية", "Community tracks": "المسارات المجتمعية", "Custom tracks": "المسارات المخصصة", 'Are you sure you want to delete "{0}"?': 'هل أنت متأكد من أنك تريد حذف "{0}"؟', Delete: "حذف", "No community tracks": "لا توجد مسارات مجتمعية", "Community tracks are coming soon": "المسارات المجتمعية قادمة قريبًا", "No custom tracks": "لا توجد مسارات مخصصة", "Create a track using the editor or import a track code": "أنشئ مسارًا باستخدام المحرر أو استورد رمز مسار", "Search tracks...": "البحث عن مسارات...", "Invalid replay detected!": "تم اكتشاف تسجيل غير صالح!" }, az = { "Checkpoint order": "Kontrollpunktreihenfolge", Height: "Höhe", Exit: "Beenden", Random: "Zufällig", Primary: "Primär", Secondary: "Sekundär", Frame: "Rahmen", Rims: "Felgen", "Are you sure you want to exit without saving?": "Sind Sie sicher, dass Sie ohne Speichern beenden möchten?", "All changes will be lost!": "Alle Änderungen gehen verloren!", "Car saved!": "Auto gespeichert!", Test: "Test", "Starting point is missing!": "Startpunkt fehlt!", Generate: "Generieren", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "Sind Sie sicher, dass Sie eine neue Strecke generieren möchten?\n\nIhre aktuelle Strecke geht verloren!", Load: "Laden", Save: "Speichern", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "Sind Sie sicher, dass Sie eine neue Strecke laden möchten?\n\nIhre aktuelle Strecke geht verloren!", "Track saved!": "Strecke gespeichert!", "Failed to save!": "Speichern fehlgeschlagen!", 'Are you sure you want to overwrite "{0}"?': 'Sind Sie sicher, dass Sie "{0}" überschreiben möchten?', Export: "Exportieren", Help: "Hilfe", "Are you sure you want to exit the editor?": "Sind Sie sicher, dass Sie den Editor verlassen möchten?", "All unsaved data will be lost!": "Alle nicht gespeicherten Daten gehen verloren!", "Track settings": "Streckeneinstellungen", "Unnamed Track": "Unbenannte Strecke", "Track name": "Streckenname", Author: "Autor", Unknown: "Unbekannt", Environment: "Umgebung", Summer: "Sommer", Winter: "Winter", Desert: "Wüste", "Sun direction": "Sonnenrichtung", "How to use the editor": "Wie man den Editor benutzt", "Camera controls": "Kamerasteuerung", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "Die Kamera kann durch Rechtsklick und Ziehen der Maus bewegt werden. Drehen Sie die Kamera, indem Sie die mittlere Maustaste (Mausrad) klicken oder die Steuerungstaste gedrückt halten und mit der rechten Maustaste ziehen. Zoomen Sie mit dem Mausrad rein und raus.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "Alternativ kann die Kamera auch mit den folgenden Tasten gesteuert werden:", "Move forwards:": "Nach vorne bewegen:", "Move backwards:": "Nach hinten bewegen:", "Move left:": "Nach links bewegen:", "Move right:": "Nach rechts bewegen:", "Rotate left:": "Nach links drehen:", "Rotate right:": "Nach rechts drehen:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "Die bearbeitete Höhe kann entweder durch Verwendung der Höhenauswahl in der unteren linken Ecke geändert werden oder indem Sie die Umschalttaste gedrückt halten und das Mausrad scrollen. Alternativ können Sie die folgenden Tasten verwenden:", "Move up:": "Nach oben bewegen:", "Move down:": "Nach unten bewegen:", Editing: "Bearbeiten", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "Streckenteile können im Menü auf der rechten Seite ausgewählt werden, danach können sie durch Linksklick mit der Maus platziert werden.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "Alternativ kann das Streckenteil, über das die Maus gerade schwebt, mit der folgenden Tastenkombination ausgewählt werden:", "The selected part can then be rotated using the following keyboard shortcut:": "Das ausgewählte Teil kann dann mit der folgenden Tastenkombination gedreht werden:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "Streckenteile können mit dem Löschwerkzeug im Menü auf der rechten Seite gelöscht werden oder indem Sie die folgende Taste gedrückt halten:", "Starting points, checkpoints and the finish line": "Startpunkte, Kontrollpunkte und die Ziellinie", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "Startpunkte, Kontrollpunkte und Ziellinien können alle in der obersten Kategorie im Menü auf der rechten Seite ausgewählt werden.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Jede Strecke muss mindestens einen Startpunkt haben. Wenn es mehrere Startpunkte gibt, wird der zuletzt platzierte verwendet.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "Kontrollpunkte sollten zwischen dem Startpunkt und der Ziellinie platziert werden. Wenn ein Kontrollpunkt-Streckenteil ausgewählt ist, gibt es unten rechts ein Werkzeug, um die Reihenfolge des Kontrollpunkts auszuwählen. Dies bestimmt die Reihenfolge, in der die Kontrollpunkte passiert werden müssen, bevor man zur Ziellinie fährt. Beachten Sie, dass es möglich ist, mehrere Kontrollpunkte mit derselben Kontrollpunkt-Reihenfolge zu haben.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "Die Ziellinie ist der Ort, an dem die Strecke endet, wird aber erst aktiv, nachdem alle Kontrollpunkte passiert wurden. Es ist auch möglich, mehrere Ziellinien zu haben.", "Starting point": "Startpunkt", Checkpoint: "Kontrollpunkt", "Finish line": "Ziellinie", "Exporting the track": "Exportieren der Strecke", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "Wenn die Strecke fertig ist, kann oben links ein Name für die Strecke eingegeben werden, danach kann die Strecke mit dem Export-Button exportiert werden. Dadurch wird ein Streckencode angezeigt, der an andere Benutzer gesendet werden kann, damit sie die Strecke importieren und spielen können.", Close: "Schließen", "Not set": "Nicht festgelegt", or: "oder", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "Die Kamera kann durch Ziehen mit einem Finger bewegt werden. Drehen Sie die Kamera, indem Sie mit zwei Fingern ziehen. Zoomen Sie rein und raus, indem Sie kneifen.", "The edited height can be changed by using the height selection in the bottom left corner.": "Die bearbeitete Höhe kann durch Verwendung der Höhenauswahl in der unteren linken Ecke geändert werden.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "Streckenteile können im Menü auf der rechten Seite ausgewählt werden, danach können sie durch Antippen des Bildschirms platziert werden.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "Das ausgewählte Teil kann dann durch Antippen der Drehen-Schaltfläche in der unteren linken Ecke gedreht werden.", "Track parts can be deleted by using the delete tool in the right side menu.": "Streckenteile können mit dem Löschwerkzeug im Menü auf der rechten Seite gelöscht werden.", Watch: "Zuschauen", "Loading replay": "Wiederholung laden", "Press {0} to return to the last checkpoint": "Drücken Sie {0}, um zum letzten Kontrollpunkt zurückzukehren", "Press {0} to start over": "Drücken Sie {0}, um von vorne zu beginnen", "Reset once to return to the last checkpoint": "Einmal zurücksetzen, um zum letzten Kontrollpunkt zurückzukehren", "Reset again to start over": "Erneut zurücksetzen, um von vorne zu beginnen", Leaderboard: "Bestenliste", Back: "Zurück", "Error: Failed to load leaderboard": "Fehler: Laden der Bestenliste fehlgeschlagen", Pending: "Ausstehend", Verified: "Verifiziert", Invalid: "Ungültig", Duplicate: "Duplikat", You: "Sie", "Only verified": "Nur verifizierte", Loading: "Laden", "Failed to load recordings": "Aufnahmen konnten nicht geladen werden", "Cannot load recordings due to non-determinism": "Aufgrund von Nicht-Determinismus können keine Aufnahmen geladen werden", Ok: "Ok", "Track is missing starting point": "Strecke hat keinen Startpunkt", "Some leaderboard features are disabled.": "Einige Bestenlistenfunktionen sind deaktiviert.", "Please try another browser or device.": "Bitte versuchen Sie einen anderen Browser oder ein anderes Gerät.", "You already have another instance of PolyTrack open.": "Sie haben bereits eine andere Instanz von PolyTrack geöffnet.", "Please switch to that tab or window to continue.": "Bitte wechseln Sie zu diesem Tab oder Fenster, um fortzufahren.", "Computer determinism check failed.": "Der Computer-Determinismus-Check ist fehlgeschlagen.", "Non-deterministic game assets found.": "Nicht-deterministische Spiel-Assets gefunden.", "Please try clearing your browser cache.": "Bitte versuchen Sie, Ihren Browser-Cache zu löschen.", Customize: "Anpassen", Editor: "Editor", Settings: "Einstellungen", Profile: "Profil", Play: "Spielen", Version: "Version", "You cannot have duplicate user profiles": "Sie können keine doppelten Benutzerprofile haben", "Failed to create user profile": "Benutzerprofil konnte nicht erstellt werden", "This user profile does not exist on the server": "Dieses Benutzerprofil existiert nicht auf dem Server", "Failed to download user profile from the server": "Benutzerprofil konnte nicht vom Server heruntergeladen werden", "User token is invalid": "Benutzertoken ist ungültig", "Are you sure you want to display your private key?": "Möchten Sie Ihren privaten Schlüssel wirklich anzeigen?", "DO NOT SHARE THIS KEY WITH ANYONE.": "TEILEN SIE DIESEN SCHLÜSSEL NICHT MIT JEMANDEM.", "You need a free user profile slot to import a new user profile": "Sie benötigen einen freien Benutzerprofil-Slot, um ein neues Benutzerprofil zu importieren", Quit: "Beenden", Fullscreen: "Vollbild", Windowed: "Fenstermodus", " ": "Es scheint, dass Sie eine inoffizielle Version von {0} spielen. Für die aktuellste Version besuchen Sie bitte die Originalquelle:", Nickname: "Spitzname", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Wählen Sie einen Spitznamen, der in der Bestenliste angezeigt wird. Ihr Spitzname kann jederzeit geändert werden.", Cancel: "Abbrechen", Confirm: "Bestätigen", Verifier: "Verifizierer", "User ID": "Benutzer-ID", Paused: "Pausiert", "Switch car": "Auto wechseln", Profiles: "Profile", 'Are you sure you would like to delete "{0}"?': 'Möchten Sie "{0}" wirklich löschen?', Empty: "Leer", Reset: "Zurücksetzen", Apply: "Anwenden", Gameplay: "Spielablauf", Units: "Einheiten", Metric: "Metrisch", Imperial: "Imperial", "Reset hint": "Hinweis zurücksetzen", Disabled: "Deaktiviert", Enabled: "Aktiviert", "Ghost car": "Geisterauto", "Default camera": "Standardkamera", Default: "Standard", Cockpit: "Cockpit", "Cockpit camera mode": "Cockpit-Kameramodus", Hold: "Halten", Toggle: "Umschalten", Checkpoints: "Kontrollpunkte", Timer: "Timer", Speedometer: "Tachometer", Bottom: "Unten", Top: "Oben", Language: "Sprache", Graphics: "Grafik", "Car shadow": "Auto-Schatten", "Track shadow": "Strecken-Schatten", Off: "Aus", On: "An", Low: "Niedrig", Medium: "Mittel", High: "Hoch", Clouds: "Wolken", Particles: "Partikel", Skidmarks: "Reifenspuren", "Render scale": "Render-Skalierung", "Anti-aliasing (requires restart)": "Antialiasing (erfordert Neustart)", Audio: "Audio", "Sound effect volume": "Lautstärke Soundeffekte", "Music volume": "Lautstärke Musik", "Checkpoint volume": "Lautstärke Kontrollpunkt", Controls: "Steuerung", Vehicle: "Fahrzeug", Accelerate: "Beschleunigen", Brake: "Bremsen", "Turn left": "Nach links lenken", "Turn right": "Nach rechts lenken", "Checkpoint reset": "Kontrollpunkt zurücksetzen", "Start reset": "Start zurücksetzen", "Cockpit camera": "Cockpit-Kamera", "Rotate part": "Teil drehen", "Height modifier": "Höhenmodifikator", "Delete part": "Teil löschen", "Move forwards": "Nach vorne bewegen", "Move backwards": "Nach hinten bewegen", "Move left": "Nach links bewegen", "Move right": "Nach rechts bewegen", "Rotate view up": "Ansicht nach oben drehen", "Rotate view down": "Ansicht nach unten drehen", "Rotate view left": "Ansicht nach links drehen", "Rotate view right": "Ansicht nach rechts drehen", "Move down": "Nach unten bewegen", "Move up": "Nach oben bewegen", "Test track": "Strecke testen", "Pick part": "Teil auswählen", Spectator: "Zuschauer", "Speed modifier": "Geschwindigkeitsmodifikator", Other: "Sonstiges", "Hide UI": "UI ausblenden", Pause: "Pause", "Toggle FPS counter": "FPS-Zähler umschalten", "Toggle spectator camera": "Zuschauerkamera umschalten", "Press any key...\n\nPress [Escape] to cancel.": "Drücken Sie eine beliebige Taste...\n\nDrücken Sie [Escape], um abzubrechen.", Clear: "Löschen", "New record": "Neuer Rekord", Record: "Rekord", Current: "Aktuell", Difference: "Differenz", Copy: "Kopieren", Import: "Importieren", "Failed to import track": "Import der Strecke fehlgeschlagen", 'The track "{0}" already exists. Do you wish to overwrite it?': 'Die Strecke "{0}" existiert bereits. Möchten Sie sie überschreiben?', Overwrite: "Überschreiben", "Paste track data here...": "Streckendaten hier einfügen...", Rank: "Rang", "Personal best": "Persönlicher Rekord", Opponents: "Gegner", "{0} opponent selected": "{0} Gegner ausgewählt", "{0} opponents selected": "{0} Gegner ausgewählt", "Select opponents to race against from the leaderboard on the left": "Wählen Sie Gegner aus der Bestenliste links aus, gegen die Sie antreten möchten", "No record": "Kein Rekord", "Official tracks": "Offizielle Strecken", "Community tracks": "Community-Strecken", "Custom tracks": "Benutzerdefinierte Strecken", 'Are you sure you want to delete "{0}"?': 'Sind Sie sicher, dass Sie "{0}" löschen möchten?', Delete: "Löschen", "No community tracks": "Keine Community-Strecken", "Community tracks are coming soon": "Community-Strecken kommen bald", "No custom tracks": "Keine benutzerdefinierten Strecken", "Create a track using the editor or import a track code": "Erstellen Sie eine Strecke mit dem Editor oder importieren Sie einen Streckencode", "Search tracks...": "Strecken suchen...", "Invalid replay detected!": "Ungültige Wiederholung erkannt!" }, sz = { "Checkpoint order": "Checkpoint order", Height: "Height", Exit: "Exit", Random: "Random", Primary: "Primary", Secondary: "Secondary", Frame: "Frame", Rims: "Rims", "Are you sure you want to exit without saving?": "Are you sure you want to exit without saving?", "All changes will be lost!": "All changes will be lost!", "Car saved!": "Car saved!", Test: "Test", "Starting point is missing!": "Starting point is missing!", Generate: "Generate", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "Are you sure you want to generate a new track?\n\nYour current track will be lost!", Load: "Load", Save: "Save", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "Are you sure you want to load a new track?\n\nYour current track will be lost!", "Track saved!": "Track saved!", "Failed to save!": "Failed to save!", 'Are you sure you want to overwrite "{0}"?': 'Are you sure you want to overwrite "{0}"?', Export: "Export", Help: "Help", "Are you sure you want to exit the editor?": "Are you sure you want to exit the editor?", "All unsaved data will be lost!": "All unsaved data will be lost!", "Track settings": "Track settings", "Unnamed Track": "Unnamed Track", "Track name": "Track name", Author: "Author", Unknown: "Unknown", Environment: "Environment", Summer: "Summer", Winter: "Winter", Desert: "Desert", "Sun direction": "Sun direction", "How to use the editor": "How to use the editor", "Camera controls": "Camera controls", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "Alternatively, the camera can also be controlled using the following keyboard keys:", "Move forwards:": "Move forwards:", "Move backwards:": "Move backwards:", "Move left:": "Move left:", "Move right:": "Move right:", "Rotate left:": "Rotate left:", "Rotate right:": "Rotate right:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:", "Move up:": "Move up:", "Move down:": "Move down:", Editing: "Editing", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:", "The selected part can then be rotated using the following keyboard shortcut:": "The selected part can then be rotated using the following keyboard shortcut:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:", "Starting points, checkpoints and the finish line": "Starting points, checkpoints and the finish line", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.", "Starting point": "Starting point", Checkpoint: "Checkpoint", "Finish line": "Finish line", "Exporting the track": "Exporting the track", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.", Close: "Close", "Not set": "Not set", or: "or", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.", "The edited height can be changed by using the height selection in the bottom left corner.": "The edited height can be changed by using the height selection in the bottom left corner.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "The selected part can then be rotated by tapping the rotate button in the bottom left corner.", "Track parts can be deleted by using the delete tool in the right side menu.": "Track parts can be deleted by using the delete tool in the right side menu.", Watch: "Watch", "Loading replay": "Loading replay", "Press {0} to return to the last checkpoint": "Press {0} to return to the last checkpoint", "Press {0} to start over": "Press {0} to start over", "Reset once to return to the last checkpoint": "Reset once to return to the last checkpoint", "Reset again to start over": "Reset again to start over", Leaderboard: "Leaderboard", Back: "Back", "Error: Failed to load leaderboard": "Error: Failed to load leaderboard", Pending: "Pending", Verified: "Verified", Invalid: "Invalid", Duplicate: "Duplicate", You: "You", "Only verified": "Only verified", Loading: "Loading", "Failed to load recordings": "Failed to load recordings", "Cannot load recordings due to non-determinism": "Cannot load recordings due to non-determinism", Ok: "Ok", "Track is missing starting point": "Track is missing starting point", "Some leaderboard features are disabled.": "Some leaderboard features are disabled.", "Please try another browser or device.": "Please try another browser or device.", "You already have another instance of PolyTrack open.": "You already have another instance of PolyTrack open.", "Please switch to that tab or window to continue.": "Please switch to that tab or window to continue.", "Computer determinism check failed.": "Computer determinism check failed.", "Non-deterministic game assets found.": "Non-deterministic game assets found.", "Please try clearing your browser cache.": "Please try clearing your browser cache.", Customize: "Customize", Editor: "Editor", Settings: "Settings", Profile: "Profile", Play: "Play", Version: "Version", "You cannot have duplicate user profiles": "You cannot have duplicate user profiles", "Failed to create user profile": "Failed to create user profile", "This user profile does not exist on the server": "This user profile does not exist on the server", "Failed to download user profile from the server": "Failed to download user profile from the server", "User token is invalid": "User token is invalid", "Are you sure you want to display your private key?": "Are you sure you want to display your private key?", "DO NOT SHARE THIS KEY WITH ANYONE.": "DO NOT SHARE THIS KEY WITH ANYONE.", "You need a free user profile slot to import a new user profile": "You need a free user profile slot to import a new user profile", Quit: "Quit", Fullscreen: "Fullscreen", Windowed: "Windowed", " ": " ", Nickname: "Nickname", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.", Cancel: "Cancel", Confirm: "Confirm", Verifier: "Verifier", "User ID": "User ID", Paused: "Paused", "Switch car": "Switch car", Profiles: "Profiles", 'Are you sure you would like to delete "{0}"?': 'Are you sure you would like to delete "{0}"?', Empty: "Empty", Reset: "Reset", Apply: "Apply", Gameplay: "Gameplay", Units: "Units", Metric: "Metric", Imperial: "Imperial", "Reset hint": "Reset hint", Disabled: "Disabled", Enabled: "Enabled", "Ghost car": "Ghost car", "Default camera": "Default camera", Default: "Default", Cockpit: "Cockpit", "Cockpit camera mode": "Cockpit camera mode", Hold: "Hold", Toggle: "Toggle", Checkpoints: "Checkpoints", Timer: "Timer", Speedometer: "Speedometer", Bottom: "Bottom", Top: "Top", Language: "Language", Graphics: "Graphics", "Car shadow": "Car shadow", "Track shadow": "Track shadow", Off: "Off", On: "On", Low: "Low", Medium: "Medium", High: "High", Clouds: "Clouds", Particles: "Particles", Skidmarks: "Skidmarks", "Render scale": "Render scale", "Anti-aliasing (requires restart)": "Anti-aliasing (requires restart)", Audio: "Audio", "Sound effect volume": "Sound effect volume", "Music volume": "Music volume", "Checkpoint volume": "Checkpoint volume", Controls: "Controls", Vehicle: "Vehicle", Accelerate: "Accelerate", Brake: "Brake", "Turn left": "Turn left", "Turn right": "Turn right", "Checkpoint reset": "Checkpoint reset", "Start reset": "Start reset", "Cockpit camera": "Cockpit camera", "Rotate part": "Rotate part", "Height modifier": "Height modifier", "Delete part": "Delete part", "Move forwards": "Move forwards", "Move backwards": "Move backwards", "Move left": "Move left", "Move right": "Move right", "Rotate view up": "Rotate view up", "Rotate view down": "Rotate view down", "Rotate view left": "Rotate view left", "Rotate view right": "Rotate view right", "Move down": "Move down", "Move up": "Move up", "Test track": "Test track", "Pick part": "Pick part", Spectator: "Spectator", "Speed modifier": "Speed modifier", Other: "Other", "Hide UI": "Hide UI", Pause: "Pause", "Toggle FPS counter": "Toggle FPS counter", "Toggle spectator camera": "Toggle spectator camera", "Press any key...\n\nPress [Escape] to cancel.": "Press any key...\n\nPress [Escape] to cancel.", Clear: "Clear", "New record": "New record", Record: "Record", Current: "Current", Difference: "Difference", Copy: "Copy", Import: "Import", "Failed to import track": "Failed to import track", 'The track "{0}" already exists. Do you wish to overwrite it?': 'The track "{0}" already exists. Do you wish to overwrite it?', Overwrite: "Overwrite", "Paste track data here...": "Paste track data here...", Rank: "Rank", "Personal best": "Personal best", Opponents: "Opponents", "{0} opponent selected": "{0} opponent selected", "{0} opponents selected": "{0} opponents selected", "Select opponents to race against from the leaderboard on the left": "Select opponents to race against from the leaderboard on the left", "No record": "No record", "Official tracks": "Official tracks", "Community tracks": "Community tracks", "Custom tracks": "Custom tracks", 'Are you sure you want to delete "{0}"?': 'Are you sure you want to delete "{0}"?', Delete: "Delete", "No community tracks": "No community tracks", "Community tracks are coming soon": "Community tracks are coming soon", "No custom tracks": "No custom tracks", "Create a track using the editor or import a track code": "Create a track using the editor or import a track code", "Search tracks...": "Search tracks...", "Invalid replay detected!": "Invalid replay detected!" }, oz = { "Checkpoint order": "Orden de puntos de control", Height: "Altura", Exit: "Salir", Random: "Aleatorio", Primary: "Primario", Secondary: "Secundario", Frame: "Marco", Rims: "Llantas", "Are you sure you want to exit without saving?": "¿Estás seguro de que deseas salir sin guardar?", "All changes will be lost!": "¡Todos los cambios se perderán!", "Car saved!": "¡Coche guardado!", Test: "Prueba", "Starting point is missing!": "¡Falta el punto de inicio!", Generate: "Generar", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "¿Estás seguro de que deseas generar una nueva pista?\n\n¡Tu pista actual se perderá!", Load: "Cargar", Save: "Guardar", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "¿Estás seguro de que deseas cargar una nueva pista?\n\n¡Tu pista actual se perderá!", "Track saved!": "¡Pista guardada!", "Failed to save!": "Error al guardar!", 'Are you sure you want to overwrite "{0}"?': '¿Estás seguro de que deseas sobrescribir "{0}"?', Export: "Exportar", Help: "Ayuda", "Are you sure you want to exit the editor?": "¿Estás seguro de que deseas salir del editor?", "All unsaved data will be lost!": "¡Se perderán todos los datos no guardados!", "Track settings": "Configuración de la pista", "Unnamed Track": "Pista sin nombre", "Track name": "Nombre de la pista", Author: "Autor", Unknown: "Desconocido", Environment: "Entorno", Summer: "Verano", Winter: "Invierno", Desert: "Desierto", "Sun direction": "Dirección del sol", "How to use the editor": "Cómo usar el editor", "Camera controls": "Controles de la cámara", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "La cámara se puede mover haciendo clic derecho y arrastrando el ratón. Gira la cámara haciendo clic con el botón central del ratón (rueda del ratón) o manteniendo presionada la tecla de control y haciendo clic derecho y arrastrando el ratón. Acércate y aléjate desplazando la rueda del ratón.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "Alternativamente, la cámara también se puede controlar usando las siguientes teclas del teclado:", "Move forwards:": "Mover hacia adelante:", "Move backwards:": "Mover hacia atrás:", "Move left:": "Mover a la izquierda:", "Move right:": "Mover a la derecha:", "Rotate left:": "Girar a la izquierda:", "Rotate right:": "Girar a la derecha:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "La altura editada se puede cambiar ya sea usando la selección de altura en la esquina inferior izquierda, o manteniendo presionada la tecla de mayúsculas y desplazando la rueda del ratón. Alternativamente, puedes usar las siguientes teclas del teclado:", "Move up:": "Mover hacia arriba:", "Move down:": "Mover hacia abajo:", Editing: "Edición", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "Las partes de la pista se pueden seleccionar en el menú de la derecha, después de lo cual se pueden colocar haciendo clic izquierdo con el ratón.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "Alternativamente, la parte de la pista actualmente sobrevolada por el ratón se puede seleccionar con el siguiente atajo de teclado:", "The selected part can then be rotated using the following keyboard shortcut:": "La parte seleccionada se puede girar usando el siguiente atajo de teclado:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "Las partes de la pista se pueden eliminar usando la herramienta de eliminación en el menú del lado derecho o manteniendo presionada la siguiente tecla:", "Starting points, checkpoints and the finish line": "Puntos de inicio, puntos de control y la línea de meta", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "Los puntos de inicio, puntos de control y líneas de meta se pueden seleccionar en la categoría superior del menú del lado derecho.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Cada pista debe tener al menos un punto de inicio. Si hay varios puntos de inicio, se usará el último colocado.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "Los puntos de control deben colocarse entre el punto de inicio y la línea de meta. Cuando se selecciona una parte de la pista de punto de control, habrá una herramienta en la parte inferior derecha para seleccionar el orden del punto de control. Esto determina el orden en que se deben pasar los puntos de control antes de conducir hacia la línea de meta. Ten en cuenta que es posible tener varios puntos de control con el mismo orden de punto de control.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "La línea de meta es donde termina la pista, pero solo se activará después de que se hayan pasado todos los puntos de control. También es posible tener varias líneas de meta.", "Starting point": "Punto de inicio", Checkpoint: "Punto de control", "Finish line": "Línea de meta", "Exporting the track": "Exportando la pista", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "Cuando la pista esté terminada, se puede ingresar un nombre para la pista en la parte superior izquierda, después de lo cual se puede exportar la pista usando el botón de exportación. Esto revelará un código de pista que se puede enviar a otros usuarios para que puedan importar y jugar la pista.", Close: "Cerrar", "Not set": "No establecido", or: "o", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "La cámara se puede mover arrastrando con un dedo. Gira la cámara arrastrando con dos dedos. Acércate y aléjate pellizcando.", "The edited height can be changed by using the height selection in the bottom left corner.": "La altura editada se puede cambiar usando la selección de altura en la esquina inferior izquierda.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "Las partes de la pista se pueden seleccionar en el menú de la derecha, después de lo cual se pueden colocar tocando la pantalla.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "La parte seleccionada se puede girar tocando el botón de rotación en la esquina inferior izquierda.", "Track parts can be deleted by using the delete tool in the right side menu.": "Las partes de la pista se pueden eliminar usando la herramienta de eliminación en el menú del lado derecho.", Watch: "Ver", "Loading replay": "Cargando repetición", "Press {0} to return to the last checkpoint": "Presiona {0} para volver al último punto de control", "Press {0} to start over": "Presiona {0} para empezar de nuevo", "Reset once to return to the last checkpoint": "Restablecer una vez para volver al último punto de control", "Reset again to start over": "Restablecer de nuevo para empezar de nuevo", Leaderboard: "Tabla de clasificación", Back: "Volver", "Error: Failed to load leaderboard": "Error: No se pudo cargar la tabla de clasificación", Pending: "Pendiente", Verified: "Verificado", Invalid: "Inválido", Duplicate: "Duplicado", You: "Tú", "Only verified": "Solo verificados", Loading: "Cargando", "Failed to load recordings": "Error al cargar las grabaciones", "Cannot load recordings due to non-determinism": "No se pueden cargar las grabaciones debido a la no determinismo", Ok: "Aceptar", "Track is missing starting point": "Falta el punto de inicio en la pista", "Some leaderboard features are disabled.": "Algunas funciones de la tabla de clasificación están desactivadas.", "Please try another browser or device.": "Por favor, prueba otro navegador o dispositivo.", "You already have another instance of PolyTrack open.": "Ya tienes otra instancia de PolyTrack abierta.", "Please switch to that tab or window to continue.": "Por favor, cambia a esa pestaña o ventana para continuar.", "Computer determinism check failed.": "Falló la comprobación de determinismo del ordenador.", "Non-deterministic game assets found.": "Se encontraron activos de juego no deterministas.", "Please try clearing your browser cache.": "Por favor, intenta borrar la caché de tu navegador.", Customize: "Personalizar", Editor: "Editor", Settings: "Configuración", Profile: "Perfil", Play: "Jugar", Version: "Versión", "You cannot have duplicate user profiles": "No puedes tener perfiles de usuario duplicados", "Failed to create user profile": "No se pudo crear el perfil de usuario", "This user profile does not exist on the server": "Este perfil de usuario no existe en el servidor", "Failed to download user profile from the server": "No se pudo descargar el perfil de usuario desde el servidor", "User token is invalid": "El token de usuario no es válido", "Are you sure you want to display your private key?": "¿Estás seguro de que quieres mostrar tu clave privada?", "DO NOT SHARE THIS KEY WITH ANYONE.": "NO COMPARTAS ESTA CLAVE CON NADIE.", "You need a free user profile slot to import a new user profile": "Necesitas un espacio libre de perfil de usuario para importar un nuevo perfil de usuario", Quit: "Salir", Fullscreen: "Pantalla completa", Windowed: "Ventana", " ": "Parece que estás jugando una versión no oficial de {0}. Para la versión más actualizada, visita la fuente original:", Nickname: "Apodo", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Elige un apodo para que aparezca en la tabla de clasificación. Puedes cambiar tu apodo en cualquier momento.", Cancel: "Cancelar", Confirm: "Confirmar", Verifier: "Verificador", "User ID": "ID de usuario", Paused: "Pausado", "Switch car": "Cambiar coche", Profiles: "Perfiles", 'Are you sure you would like to delete "{0}"?': '¿Estás seguro de que quieres eliminar "{0}"?', Empty: "Vacío", Reset: "Restablecer", Apply: "Aplicar", Gameplay: "Jugabilidad", Units: "Unidades", Metric: "Métrico", Imperial: "Imperial", "Reset hint": "Restablecer pista", Disabled: "Desactivado", Enabled: "Activado", "Ghost car": "Coche fantasma", "Default camera": "Cámara predeterminada", Default: "Predeterminado", Cockpit: "Cabina", "Cockpit camera mode": "Modo de cámara en la cabina", Hold: "Mantener", Toggle: "Alternar", Checkpoints: "Puntos de control", Timer: "Temporizador", Speedometer: "Velocímetro", Bottom: "Inferior", Top: "Superior", Language: "Idioma", Graphics: "Gráficos", "Car shadow": "Sombra del coche", "Track shadow": "Sombra de la pista", Off: "Apagar", On: "Encender", Low: "Bajo", Medium: "Medio", High: "Alto", Clouds: "Nubes", Particles: "Partículas", Skidmarks: "Marcas de derrape", "Render scale": "Escala de renderizado", "Anti-aliasing (requires restart)": "Anti-aliasing (requiere reinicio)", Audio: "Audio", "Sound effect volume": "Volumen de efectos de sonido", "Music volume": "Volumen de música", "Checkpoint volume": "Volumen de puntos de control", Controls: "Controles", Vehicle: "Vehículo", Accelerate: "Acelerar", Brake: "Frenar", "Turn left": "Girar a la izquierda", "Turn right": "Girar a la derecha", "Checkpoint reset": "Restablecer punto de control", "Start reset": "Restablecer inicio", "Cockpit camera": "Cámara en la cabina", "Rotate part": "Girar parte", "Height modifier": "Modificador de altura", "Delete part": "Eliminar parte", "Move forwards": "Mover hacia adelante", "Move backwards": "Mover hacia atrás", "Move left": "Mover a la izquierda", "Move right": "Mover a la derecha", "Rotate view up": "Girar vista hacia arriba", "Rotate view down": "Girar vista hacia abajo", "Rotate view left": "Girar vista a la izquierda", "Rotate view right": "Girar vista a la derecha", "Move down": "Mover hacia abajo", "Move up": "Mover hacia arriba", "Test track": "Probar pista", "Pick part": "Seleccionar parte", Spectator: "Espectador", "Speed modifier": "Modificador de velocidad", Other: "Otro", "Hide UI": "Ocultar IU", Pause: "Pausa", "Toggle FPS counter": "Alternar contador de FPS", "Toggle spectator camera": "Alternar cámara de espectador", "Press any key...\n\nPress [Escape] to cancel.": "Presiona cualquier tecla...\n\nPresiona [Escape] para cancelar.", Clear: "Borrar", "New record": "Nuevo récord", Record: "Récord", Current: "Actual", Difference: "Diferencia", Copy: "Copiar", Import: "Importar", "Failed to import track": "Error al importar la pista", 'The track "{0}" already exists. Do you wish to overwrite it?': 'La pista "{0}" ya existe. ¿Deseas sobrescribirla?', Overwrite: "Sobrescribir", "Paste track data here...": "Pegar datos de la pista aquí...", Rank: "Rango", "Personal best": "Mejor marca personal", Opponents: "Oponentes", "{0} opponent selected": "{0} oponente seleccionado", "{0} opponents selected": "{0} oponente seleccionado", "Select opponents to race against from the leaderboard on the left": "Selecciona oponentes con los que competir en la tabla de clasificación de la izquierda", "No record": "Sin récord", "Official tracks": "Pistas oficiales", "Community tracks": "Pistas de la comunidad", "Custom tracks": "Pistas personalizadas", 'Are you sure you want to delete "{0}"?': '¿Estás seguro de que deseas eliminar "{0}"?', Delete: "Eliminar", "No community tracks": "No hay pistas de la comunidad", "Community tracks are coming soon": "Las pistas de la comunidad llegarán pronto", "No custom tracks": "No hay pistas personalizadas", "Create a track using the editor or import a track code": "Crea una pista usando el editor o importa un código de pista", "Search tracks...": "Buscar pistas...", "Invalid replay detected!": "¡Se detectó una repetición no válida!" }, lz = { "Checkpoint order": "Ordre des points de contrôle", Height: "Hauteur", Exit: "Quitter", Random: "Aléatoire", Primary: "Principal", Secondary: "Secondaire", Frame: "Cadre", Rims: "Jantes", "Are you sure you want to exit without saving?": "Êtes-vous sûr de vouloir quitter sans sauvegarder ?", "All changes will be lost!": "Tous les changements seront perdus !", "Car saved!": "Voiture sauvegardée !", Test: "Test", "Starting point is missing!": "Point de départ manquant !", Generate: "Générer", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "Êtes-vous sûr de vouloir générer une nouvelle piste ?\n\nVotre piste actuelle sera perdue !", Load: "Charger", Save: "Enregistrer", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "Êtes-vous sûr de vouloir charger une nouvelle piste ?\n\nVotre piste actuelle sera perdue !", "Track saved!": "Piste enregistrée !", "Failed to save!": "Échec de l'enregistrement !", 'Are you sure you want to overwrite "{0}"?': 'Êtes-vous sûr de vouloir écraser "{0}" ?', Export: "Exporter", Help: "Aide", "Are you sure you want to exit the editor?": "Êtes-vous sûr de vouloir quitter l'éditeur ?", "All unsaved data will be lost!": "Toutes les données non sauvegardées seront perdues !", "Track settings": "Paramètres de la piste", "Unnamed Track": "Piste sans nom", "Track name": "Nom de la piste", Author: "Auteur", Unknown: "Inconnu", Environment: "Environnement", Summer: "Été", Winter: "Hiver", Desert: "Désert", "Sun direction": "Direction du soleil", "How to use the editor": "Comment utiliser l'éditeur", "Camera controls": "Contrôles de la caméra", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "La caméra peut être déplacée en cliquant avec le bouton droit et en faisant glisser la souris. Faites pivoter la caméra en cliquant sur le bouton central de la souris (molette) ou en maintenant la touche de contrôle enfoncée et en cliquant avec le bouton droit et en faisant glisser la souris. Zoomez en avant et en arrière en faisant défiler la molette de la souris.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "Alternativement, la caméra peut également être contrôlée en utilisant les touches de clavier suivantes :", "Move forwards:": "Avancer :", "Move backwards:": "Reculer :", "Move left:": "Déplacer à gauche :", "Move right:": "Déplacer à droite :", "Rotate left:": "Pivoter à gauche :", "Rotate right:": "Pivoter à droite :", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "La hauteur modifiée peut être changée en utilisant la sélection de hauteur dans le coin inférieur gauche, ou en maintenant la touche Maj enfoncée et en faisant défiler la molette de la souris. Alternativement, vous pouvez utiliser les touches de clavier suivantes :", "Move up:": "Monter :", "Move down:": "Descendre :", Editing: "Édition", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "Les parties de la piste peuvent être sélectionnées dans le menu de droite, après quoi elles peuvent être placées en cliquant avec le bouton gauche de la souris.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "Alternativement, la partie de la piste actuellement survolée par la souris peut être sélectionnée avec le raccourci clavier suivant :", "The selected part can then be rotated using the following keyboard shortcut:": "La partie sélectionnée peut ensuite être pivotée en utilisant le raccourci clavier suivant :", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "Les parties de la piste peuvent être supprimées en utilisant l'outil de suppression dans le menu de droite ou en maintenant la touche suivante enfoncée :", "Starting points, checkpoints and the finish line": "Points de départ, points de contrôle et ligne d'arrivée", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "Les points de départ, les points de contrôle et les lignes d'arrivée peuvent tous être sélectionnés dans la catégorie la plus haute du menu de droite.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Chaque piste doit avoir au moins un point de départ. S'il y a plusieurs points de départ, le dernier placé sera utilisé.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "Les points de contrôle doivent être placés entre le point de départ et la ligne d'arrivée. Lorsqu'une partie de la piste de point de contrôle est sélectionnée, il y aura un outil en bas à droite pour sélectionner l'ordre du point de contrôle. Cela détermine l'ordre dans lequel les points de contrôle doivent être passés avant de conduire jusqu'à la ligne d'arrivée. Notez qu'il est possible d'avoir plusieurs points de contrôle avec le même ordre de point de contrôle.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "La ligne d'arrivée est l'endroit où la piste se termine mais ne deviendra active qu'après que tous les points de contrôle aient été passés. Il est également possible d'avoir plusieurs lignes d'arrivée.", "Starting point": "Point de départ", Checkpoint: "Point de contrôle", "Finish line": "Ligne d'arrivée", "Exporting the track": "Exportation de la piste", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "Lorsque la piste est terminée, un nom pour la piste peut être entré en haut à gauche, après quoi la piste peut être exportée en utilisant le bouton d'exportation. Cela révélera un code de piste qui peut être envoyé à d'autres utilisateurs afin qu'ils puissent importer et jouer la piste.", Close: "Fermer", "Not set": "Non défini", or: "ou", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "La caméra peut être déplacée en faisant glisser un doigt. Faites pivoter la caméra en faisant glisser deux doigts. Zoomez avant et arrière en pinçant.", "The edited height can be changed by using the height selection in the bottom left corner.": "La hauteur modifiée peut être changée en utilisant la sélection de hauteur dans le coin inférieur gauche.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "Les parties de la piste peuvent être sélectionnées dans le menu de droite, après quoi elles peuvent être placées en tapant sur l'écran.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "La partie sélectionnée peut ensuite être pivotée en tapant sur le bouton de rotation dans le coin inférieur gauche.", "Track parts can be deleted by using the delete tool in the right side menu.": "Les parties de la piste peuvent être supprimées en utilisant l'outil de suppression dans le menu de droite.", Watch: "Regarder", "Loading replay": "Chargement de l'enregistrement", "Press {0} to return to the last checkpoint": "Appuyez sur {0} pour retourner au dernier point de contrôle", "Press {0} to start over": "Appuyez sur {0} pour recommencer", "Reset once to return to the last checkpoint": "Réinitialisez une fois pour retourner au dernier point de contrôle", "Reset again to start over": "Réinitialisez à nouveau pour recommencer", Leaderboard: "Classement", Back: "Retour", "Error: Failed to load leaderboard": "Erreur : Échec du chargement du classement", Pending: "En attente", Verified: "Vérifié", Invalid: "Invalide", Duplicate: "Doublon", You: "Vous", "Only verified": "Uniquement vérifiés", Loading: "Chargement", "Failed to load recordings": "Échec du chargement des enregistrements", "Cannot load recordings due to non-determinism": "Impossible de charger les enregistrements en raison du non-déterminisme", Ok: "OK", "Track is missing starting point": "La piste n'a pas de point de départ", "Some leaderboard features are disabled.": "Certaines fonctionnalités du classement sont désactivées.", "Please try another browser or device.": "Veuillez essayer un autre navigateur ou appareil.", "You already have another instance of PolyTrack open.": "Vous avez déjà une autre instance de PolyTrack ouverte.", "Please switch to that tab or window to continue.": "Veuillez basculer vers cet onglet ou cette fenêtre pour continuer.", "Computer determinism check failed.": "Échec de la vérification du déterminisme de l'ordinateur.", "Non-deterministic game assets found.": "Actifs de jeu non déterministes trouvés.", "Please try clearing your browser cache.": "Veuillez essayer de vider le cache de votre navigateur.", Customize: "Personnaliser", Editor: "Éditeur", Settings: "Paramètres", Profile: "Profil", Play: "Jouer", Version: "Version", "You cannot have duplicate user profiles": "Vous ne pouvez pas avoir de profils d'utilisateur en double", "Failed to create user profile": "Échec de la création du profil utilisateur", "This user profile does not exist on the server": "Ce profil utilisateur n'existe pas sur le serveur", "Failed to download user profile from the server": "Échec du téléchargement du profil utilisateur depuis le serveur", "User token is invalid": "Le jeton utilisateur n'est pas valide", "Are you sure you want to display your private key?": "Êtes-vous sûr de vouloir afficher votre clé privée ?", "DO NOT SHARE THIS KEY WITH ANYONE.": "NE PARTAGEZ PAS CETTE CLÉ AVEC PERSONNE.", "You need a free user profile slot to import a new user profile": "Vous avez besoin d'un emplacement de profil utilisateur libre pour importer un nouveau profil utilisateur", Quit: "Quitter", Fullscreen: "Plein écran", Windowed: "Fenêtré", " ": "Il semble que vous jouiez à une version non officielle de {0}. Pour la version la plus récente, veuillez visiter la source originale :", Nickname: "Pseudonyme", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Choisissez un pseudonyme à afficher dans le classement. Vous pouvez changer votre pseudonyme à tout moment.", Cancel: "Annuler", Confirm: "Confirmer", Verifier: "Vérificateur", "User ID": "ID utilisateur", Paused: "En pause", "Switch car": "Changer de voiture", Profiles: "Profils", 'Are you sure you would like to delete "{0}"?': 'Êtes-vous sûr de vouloir supprimer "{0}"?', Empty: "Vide", Reset: "Réinitialiser", Apply: "Appliquer", Gameplay: "Jouabilité", Units: "Unités", Metric: "Métrique", Imperial: "Impérial", "Reset hint": "Réinitialiser l'astuce", Disabled: "Désactivé", Enabled: "Activé", "Ghost car": "Voiture fantôme", "Default camera": "Caméra par défaut", Default: "Défaut", Cockpit: "Cockpit", "Cockpit camera mode": "Mode caméra cockpit", Hold: "Maintenir", Toggle: "Basculer", Checkpoints: "Points de contrôle", Timer: "Minuteur", Speedometer: "Compteur de vitesse", Bottom: "Bas", Top: "Haut", Language: "Langue", Graphics: "Graphismes", "Car shadow": "Ombre de la voiture", "Track shadow": "Ombre de la piste", Off: "Désactivé", On: "Activé", Low: "Faible", Medium: "Moyen", High: "Élevé", Clouds: "Nuages", Particles: "Particules", Skidmarks: "Marques de dérapage", "Render scale": "Échelle de rendu", "Anti-aliasing (requires restart)": "Anticrénelage (nécessite un redémarrage)", Audio: "Audio", "Sound effect volume": "Volume des effets sonores", "Music volume": "Volume de la musique", "Checkpoint volume": "Volume des points de contrôle", Controls: "Commandes", Vehicle: "Véhicule", Accelerate: "Accélérer", Brake: "Freiner", "Turn left": "Tourner à gauche", "Turn right": "Tourner à droite", "Checkpoint reset": "Réinitialisation du point de contrôle", "Start reset": "Réinitialisation du départ", "Cockpit camera": "Caméra cockpit", "Rotate part": "Pivoter la partie", "Height modifier": "Modificateur de hauteur", "Delete part": "Supprimer la partie", "Move forwards": "Avancer", "Move backwards": "Reculer", "Move left": "Déplacer à gauche", "Move right": "Déplacer à droite", "Rotate view up": "Pivoter la vue vers le haut", "Rotate view down": "Pivoter la vue vers le bas", "Rotate view left": "Pivoter la vue à gauche", "Rotate view right": "Pivoter la vue à droite", "Move down": "Descendre", "Move up": "Monter", "Test track": "Tester la piste", "Pick part": "Choisir la partie", Spectator: "Spectateur", "Speed modifier": "Modificateur de vitesse", Other: "Autre", "Hide UI": "Masquer l'interface utilisateur", Pause: "Pause", "Toggle FPS counter": "Basculer le compteur FPS", "Toggle spectator camera": "Basculer la caméra spectateur", "Press any key...\n\nPress [Escape] to cancel.": "Appuyez sur n'importe quelle touche...\n\nAppuyez sur [Échap] pour annuler.", Clear: "Effacer", "New record": "Nouveau record", Record: "Record", Current: "Actuel", Difference: "Différence", Copy: "Copier", Import: "Importer", "Failed to import track": "Échec de l'importation de la piste", 'The track "{0}" already exists. Do you wish to overwrite it?': 'La piste "{0}" existe déjà. Souhaitez-vous l\'écraser ?', Overwrite: "Écraser", "Paste track data here...": "Collez les données de la piste ici...", Rank: "Classement", "Personal best": "Meilleur temps personnel", Opponents: "Adversaires", "{0} opponent selected": "{0} adversaire sélectionné", "{0} opponents selected": "{0} adversaires sélectionnés", "Select opponents to race against from the leaderboard on the left": "Sélectionnez des adversaires contre lesquels courir dans le classement sur la gauche", "No record": "Pas de record", "Official tracks": "Pistes officielles", "Community tracks": "Pistes communautaires", "Custom tracks": "Pistes personnalisées", 'Are you sure you want to delete "{0}"?': 'Êtes-vous sûr de vouloir supprimer "{0}" ?', Delete: "Supprimer", "No community tracks": "Pas de pistes communautaires", "Community tracks are coming soon": "Les pistes communautaires arrivent bientôt", "No custom tracks": "Pas de pistes personnalisées", "Create a track using the editor or import a track code": "Créez une piste en utilisant l'éditeur ou importez un code de piste", "Search tracks...": "Rechercher des pistes...", "Invalid replay detected!": "Rejouer invalide détecté!" }, cz = { "Checkpoint order": "Ordine dei checkpoint", Height: "Altezza", Exit: "Esci", Random: "Casuale", Primary: "Primario", Secondary: "Secondario", Frame: "Telaio", Rims: "Cerchioni", "Are you sure you want to exit without saving?": "Sei sicuro di voler uscire senza salvare?", "All changes will be lost!": "Tutte le modifiche andranno perse!", "Car saved!": "Auto salvata!", Test: "Test", "Starting point is missing!": "Punto di partenza mancante!", Generate: "Genera", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "Sei sicuro di voler generare un nuovo percorso?\n\nIl tuo percorso attuale verrà perso!", Load: "Carica", Save: "Salva", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "Sei sicuro di voler caricare un nuovo percorso?\n\nIl tuo percorso attuale verrà perso!", "Track saved!": "Percorso salvato!", "Failed to save!": "Salvataggio non riuscito!", 'Are you sure you want to overwrite "{0}"?': 'Sei sicuro di voler sovrascrivere "{0}"?', Export: "Esporta", Help: "Aiuto", "Are you sure you want to exit the editor?": "Sei sicuro di voler uscire dall'editor?", "All unsaved data will be lost!": "Tutti i dati non salvati andranno persi!", "Track settings": "Impostazioni del percorso", "Unnamed Track": "Percorso senza nome", "Track name": "Nome del percorso", Author: "Autore", Unknown: "Sconosciuto", Environment: "Ambiente", Summer: "Estate", Winter: "Inverno", Desert: "Deserto", "Sun direction": "Direzione del sole", "How to use the editor": "Come usare l'editor", "Camera controls": "Controlli della telecamera", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "La telecamera può essere spostata facendo clic con il tasto destro del mouse e trascinando. Ruota la telecamera facendo clic con il pulsante centrale del mouse (rotella) o tenendo premuto il tasto di controllo e facendo clic con il tasto destro del mouse e trascinando. Zoom avanti e indietro scorrendo la rotella del mouse.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "In alternativa, la telecamera può essere controllata utilizzando i seguenti tasti della tastiera:", "Move forwards:": "Muovi avanti:", "Move backwards:": "Muovi indietro:", "Move left:": "Muovi a sinistra:", "Move right:": "Muovi a destra:", "Rotate left:": "Ruota a sinistra:", "Rotate right:": "Ruota a destra:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "L'altezza modificata può essere cambiata utilizzando la selezione dell'altezza nell'angolo in basso a sinistra, o tenendo premuto il tasto shift e scorrendo la rotella del mouse. In alternativa, puoi utilizzare i seguenti tasti della tastiera:", "Move up:": "Muovi su:", "Move down:": "Muovi giù:", Editing: "Modifica", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "Le parti del percorso possono essere selezionate nel menu a destra, dopodiché possono essere posizionate facendo clic con il tasto sinistro del mouse.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "In alternativa, la parte del percorso attualmente sotto il cursore del mouse può essere selezionata con la seguente scorciatoia da tastiera:", "The selected part can then be rotated using the following keyboard shortcut:": "La parte selezionata può quindi essere ruotata utilizzando la seguente scorciatoia da tastiera:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "Le parti del percorso possono essere eliminate utilizzando lo strumento di eliminazione nel menu a destra o tenendo premuto il seguente tasto:", "Starting points, checkpoints and the finish line": "Punti di partenza, checkpoint e linea di arrivo", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "I punti di partenza, i checkpoint e le linee di arrivo possono essere selezionati nella categoria più alta nel menu a destra.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Ogni percorso deve avere almeno un punto di partenza. Se ci sono più punti di partenza, verrà utilizzato l'ultimo posizionato.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "I checkpoint devono essere posizionati tra il punto di partenza e la linea di arrivo. Quando viene selezionata una parte del percorso checkpoint, ci sarà uno strumento in basso a destra per selezionare l'ordine del checkpoint. Questo determina l'ordine in cui i checkpoint devono essere superati prima di arrivare alla linea di arrivo. Nota che è possibile avere più checkpoint con lo stesso ordine di checkpoint.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "La linea di arrivo è dove finisce il percorso, ma diventerà attiva solo dopo che tutti i checkpoint sono stati superati. È anche possibile avere più linee di arrivo.", "Starting point": "Punto di partenza", Checkpoint: "Checkpoint", "Finish line": "Linea di arrivo", "Exporting the track": "Esportazione del percorso", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "Quando il percorso è terminato, è possibile inserire un nome per il percorso in alto a sinistra, dopodiché il percorso può essere esportato utilizzando il pulsante di esportazione. Questo rivelerà un codice del percorso che può essere inviato ad altri utenti in modo che possano importare e giocare il percorso.", Close: "Chiudi", "Not set": "Non impostato", or: "o", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "La telecamera può essere spostata trascinando con un dito. Ruota la telecamera trascinando con due dita. Zoom avanti e indietro pizzicando.", "The edited height can be changed by using the height selection in the bottom left corner.": "L'altezza modificata può essere cambiata utilizzando la selezione dell'altezza nell'angolo in basso a sinistra.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "Le parti del percorso possono essere selezionate nel menu a destra, dopodiché possono essere posizionate toccando lo schermo.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "La parte selezionata può quindi essere ruotata toccando il pulsante di rotazione nell'angolo in basso a sinistra.", "Track parts can be deleted by using the delete tool in the right side menu.": "Le parti del percorso possono essere eliminate utilizzando lo strumento di eliminazione nel menu a destra.", Watch: "Guarda", "Loading replay": "Caricamento riproduzione", "Press {0} to return to the last checkpoint": "Premi {0} per tornare all'ultimo checkpoint", "Press {0} to start over": "Premi {0} per ricominciare", "Reset once to return to the last checkpoint": "Resetta una volta per tornare all'ultimo checkpoint", "Reset again to start over": "Resetta di nuovo per ricominciare", Leaderboard: "Classifica", Back: "Indietro", "Error: Failed to load leaderboard": "Errore: impossibile caricare la classifica", Pending: "In sospeso", Verified: "Verificato", Invalid: "Non valido", Duplicate: "Duplicato", You: "Tu", "Only verified": "Solo verificati", Loading: "Caricamento", "Failed to load recordings": "Impossibile caricare le registrazioni", "Cannot load recordings due to non-determinism": "Impossibile caricare le registrazioni a causa del non determinismo", Ok: "Ok", "Track is missing starting point": "Il percorso non ha un punto di partenza", "Some leaderboard features are disabled.": "Alcune funzionalità della classifica sono disabilitate.", "Please try another browser or device.": "Si prega di provare un altro browser o dispositivo.", "You already have another instance of PolyTrack open.": "Hai già un'altra istanza di PolyTrack aperta.", "Please switch to that tab or window to continue.": "Si prega di passare a quella scheda o finestra per continuare.", "Computer determinism check failed.": "Verifica del determinismo del computer fallita.", "Non-deterministic game assets found.": "Asset di gioco non deterministici trovati.", "Please try clearing your browser cache.": "Si prega di provare a cancellare la cache del browser.", Customize: "Personalizza", Editor: "Editor", Settings: "Impostazioni", Profile: "Profilo", Play: "Gioca", Version: "Versione", "You cannot have duplicate user profiles": "Non è possibile avere profili utente duplicati", "Failed to create user profile": "Impossibile creare il profilo utente", "This user profile does not exist on the server": "Questo profilo utente non esiste sul server", "Failed to download user profile from the server": "Impossibile scaricare il profilo utente dal server", "User token is invalid": "Token utente non valido", "Are you sure you want to display your private key?": "Sei sicuro di voler mostrare la tua chiave privata?", "DO NOT SHARE THIS KEY WITH ANYONE.": "NON CONDIVIDERE QUESTA CHIAVE CON NESSUNO.", "You need a free user profile slot to import a new user profile": "Hai bisogno di uno slot di profilo utente libero per importare un nuovo profilo utente", Quit: "Esci", Fullscreen: "Schermo intero", Windowed: "Finestra", " ": "Sembra che tu stia giocando a una versione non ufficiale di {0}. Per la versione più aggiornata visita la fonte originale:", Nickname: "Nickname", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Scegli un nickname da mostrare nella classifica. Puoi cambiarlo in qualsiasi momento.", Cancel: "Annulla", Confirm: "Conferma", Verifier: "Verificatore", "User ID": "ID Utente", Paused: "In pausa", "Switch car": "Cambia auto", Profiles: "Profili", 'Are you sure you would like to delete "{0}"?': 'Sei sicuro di voler eliminare "{0}"?', Empty: "Vuoto", Reset: "Resetta", Apply: "Applica", Gameplay: "Modalità di gioco", Units: "Unità", Metric: "Metrico", Imperial: "Imperiale", "Reset hint": "Resetta suggerimento", Disabled: "Disattivato", Enabled: "Attivato", "Ghost car": "Auto fantasma", "Default camera": "Telecamera predefinita", Default: "Predefinita", Cockpit: "Cabina", "Cockpit camera mode": "Modalità telecamera cabina", Hold: "Tieni", Toggle: "Attiva/Disattiva", Checkpoints: "Checkpoint", Timer: "Timer", Speedometer: "Contachilometri", Bottom: "In basso", Top: "In alto", Language: "Lingua", Graphics: "Grafica", "Car shadow": "Ombra dell'auto", "Track shadow": "Ombra del percorso", Off: "Disattivato", On: "Attivato", Low: "Basso", Medium: "Medio", High: "Alto", Clouds: "Nuvole", Particles: "Particelle", Skidmarks: "Segni di frenata", "Render scale": "Scala di rendering", "Anti-aliasing (requires restart)": "Anti-aliasing (richiede riavvio)", Audio: "Audio", "Sound effect volume": "Volume degli effetti sonori", "Music volume": "Volume della musica", "Checkpoint volume": "Volume dei checkpoint", Controls: "Controlli", Vehicle: "Veicolo", Accelerate: "Accelerare", Brake: "Frenare", "Turn left": "Svolta a sinistra", "Turn right": "Svolta a destra", "Checkpoint reset": "Reset checkpoint", "Start reset": "Reset partenza", "Cockpit camera": "Telecamera cabina", "Rotate part": "Ruota parte", "Height modifier": "Modificatore altezza", "Delete part": "Elimina parte", "Move forwards": "Muovi avanti", "Move backwards": "Muovi indietro", "Move left": "Muovi a sinistra", "Move right": "Muovi a destra", "Rotate view up": "Ruota vista in alto", "Rotate view down": "Ruota vista in basso", "Rotate view left": "Ruota vista a sinistra", "Rotate view right": "Ruota vista a destra", "Move down": "Muovi giù", "Move up": "Muovi su", "Test track": "Test percorso", "Pick part": "Seleziona parte", Spectator: "Spettatore", "Speed modifier": "Modificatore velocità", Other: "Altro", "Hide UI": "Nascondi UI", Pause: "Pausa", "Toggle FPS counter": "Attiva/Disattiva contatore FPS", "Toggle spectator camera": "Attiva/Disattiva telecamera spettatore", "Press any key...\n\nPress [Escape] to cancel.": "Premi un tasto qualsiasi...\n\nPremi [Esc] per annullare.", Clear: "Cancella", "New record": "Nuovo record", Record: "Record", Current: "Attuale", Difference: "Differenza", Copy: "Copia", Import: "Importa", "Failed to import track": "Importazione percorso non riuscita", 'The track "{0}" already exists. Do you wish to overwrite it?': 'Il percorso "{0}" esiste già. Vuoi sovrascriverlo?', Overwrite: "Sovrascrivi", "Paste track data here...": "Incolla dati del percorso qui...", Rank: "Posizione", "Personal best": "Miglior tempo personale", Opponents: "Avversari", "{0} opponent selected": "{0} avversario selezionato", "{0} opponents selected": "{0} avversari selezionati", "Select opponents to race against from the leaderboard on the left": "Seleziona gli avversari con cui gareggiare dalla classifica a sinistra", "No record": "Nessun record", "Official tracks": "Percorsi ufficiali", "Community tracks": "Percorsi della community", "Custom tracks": "Percorsi personalizzati", 'Are you sure you want to delete "{0}"?': 'Sei sicuro di voler eliminare "{0}"?', Delete: "Elimina", "No community tracks": "Nessun percorso della community", "Community tracks are coming soon": "I percorsi della community arriveranno presto", "No custom tracks": "Nessun percorso personalizzato", "Create a track using the editor or import a track code": "Crea un percorso utilizzando l'editor o importa un codice percorso", "Search tracks...": "Cerca percorso...", "Invalid replay detected!": "Riproduzione non valida rilevata!" }, hz = { "Checkpoint order": "チェックポイントの順序", Height: "高さ", Exit: "終了", Random: "ランダム", Primary: "プライマリ", Secondary: "セカンダリ", Frame: "フレーム", Rims: "リム", "Are you sure you want to exit without saving?": "保存せずに終了してもよろしいですか?", "All changes will be lost!": "すべての変更が失われます!", "Car saved!": "車両が保存されました!", Test: "テスト", "Starting point is missing!": "スタート地点がありません!", Generate: "生成", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "新しいトラックを生成してもよろしいですか?\n\n現在のトラックは失われます!", Load: "読み込み", Save: "保存", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "新しいトラックを読み込んでもよろしいですか?\n\n現在のトラックは失われます!", "Track saved!": "トラックが保存されました!", "Failed to save!": "保存に失敗しました!", 'Are you sure you want to overwrite "{0}"?': '"{0}" を上書きしてもよろしいですか?', Export: "エクスポート", Help: "ヘルプ", "Are you sure you want to exit the editor?": "エディタを終了してもよろしいですか?", "All unsaved data will be lost!": "保存されていないデータはすべて失われます!", "Track settings": "トラック設定", "Unnamed Track": "無名のトラック", "Track name": "トラック名", Author: "作者", Unknown: "不明", Environment: "環境", Summer: "サマー", Winter: "ウィンター", Desert: "デザート", "Sun direction": "太陽の方向", "How to use the editor": "エディタの使い方", "Camera controls": "カメラの操作方法", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "カメラは右クリックしてマウスをドラッグすることで移動できます。カメラを回転させるには、マウスの中ボタン(マウスホイール)をクリックするか、コントロールキーを押しながら右クリックしてマウスをドラッグします。マウスホイールをスクロールすることでズームインとズームアウトができます。", "Alternatively, the camera can also be controlled using the following keyboard keys:": "また、以下のキーボードのキーを使用してカメラを制御することもできます:", "Move forwards:": "前に移動:", "Move backwards:": "後ろに移動:", "Move left:": "左に移動:", "Move right:": "右に移動:", "Rotate left:": "左に回転:", "Rotate right:": "右に回転:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "編集された高さは、左下隅の高さ選択を使用するか、Shiftキーを押しながらマウスホイールをスクロールすることで変更できます。また、以下のキーボードキーを使用することもできます:", "Move up:": "上に移動:", "Move down:": "下に移動:", Editing: "編集", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "トラックパーツは、右側のメニューで選択してから、マウスで左クリックすることで配置できます。", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "また、マウスで現在ホバーしているトラックパーツは、以下のキーボードショートカットで選択できます:", "The selected part can then be rotated using the following keyboard shortcut:": "選択したパーツは、以下のキーボードショートカットを使用して回転させることができます:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "トラックパーツは、右側のメニューの削除ツールを使用するか、以下のキーを押しながら削除することができます:", "Starting points, checkpoints and the finish line": "スタート地点、チェックポイント、フィニッシュライン", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "スタート地点、チェックポイント、フィニッシュラインは、右側のメニューの最上位カテゴリで選択できます。", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "各トラックには少なくとも1つのスタート地点が必要です。複数のスタート地点がある場合は、最後に配置されたものが使用されます。", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "チェックポイントは、スタート地点とフィニッシュラインの間に配置する必要があります。チェックポイントのトラックパーツが選択されると、右下にチェックポイントの順序を選択するためのツールが表示されます。これにより、チェックポイントを通過する順序が決まります。同じチェックポイント順序で複数のチェックポイントを持つことも可能です。", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "フィニッシュラインはトラックの終わりですが、すべてのチェックポイントを通過した後にのみアクティブになります。複数のフィニッシュラインを持つことも可能です。", "Starting point": "スタート地点", Checkpoint: "チェックポイント", "Finish line": "フィニッシュライン", "Exporting the track": "トラックのエクスポート", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "トラックが完成したら、トップ左にトラックの名前を入力し、エクスポートボタンを使用してトラックをエクスポートできます。これにより、他のユーザーがトラックをインポートして再生できるトラックコードが表示されます。", Close: "閉じる", "Not set": "未設定", or: "または", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "カメラは1本の指でドラッグすることで移動できます。カメラを回転させるには、2本の指でドラッグします。ピンチインとピンチアウトでズームインとズームアウトができます。", "The edited height can be changed by using the height selection in the bottom left corner.": "編集された高さは、左下隅の高さ選択を使用することで変更できます。", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "トラックパーツは、右側のメニューで選択してから、画面をタップすることで配置できます。", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "選択したパーツは、左下隅の回転ボタンをタップすることで回転させることができます。", "Track parts can be deleted by using the delete tool in the right side menu.": "トラックパーツは、右側のメニューの削除ツールを使用することで削除できます。", Watch: "視聴", "Loading replay": "リプレイを読み込み中", "Press {0} to return to the last checkpoint": "最後のチェックポイントに戻るには {0} を押してください", "Press {0} to start over": "最初からやり直すには {0} を押してください", "Reset once to return to the last checkpoint": "最後のチェックポイントに戻るには1回リセットしてください", "Reset again to start over": "最初からやり直すにはもう一度リセットしてください", Leaderboard: "リーダーボード", Back: "戻る", "Error: Failed to load leaderboard": "エラー:リーダーボードの読み込みに失敗しました", Pending: "保留中", Verified: "検証済み", Invalid: "無効", Duplicate: "重複", You: "あなた", "Only verified": "検証済みのみ", Loading: "読み込み中", "Failed to load recordings": "録画の読み込みに失敗しました", "Cannot load recordings due to non-determinism": "非決定論により録画を読み込むことができません", Ok: "OK", "Track is missing starting point": "トラックにスタート地点がありません", "Some leaderboard features are disabled.": "一部のリーダーボード機能が無効になっています。", "Please try another browser or device.": "別のブラウザまたはデバイスをお試しください。", "You already have another instance of PolyTrack open.": "すでに別のPolyTrackインスタンスが開いています。", "Please switch to that tab or window to continue.": "続行するには、そのタブまたはウィンドウに切り替えてください。", "Computer determinism check failed.": "コンピューターの決定論チェックに失敗しました。", "Non-deterministic game assets found.": "非決定論的なゲームアセットが見つかりました。", "Please try clearing your browser cache.": "ブラウザのキャッシュをクリアしてみてください。", Customize: "カスタマイズ", Editor: "エディタ", Settings: "設定", Profile: "プロフィール", Play: "再生", Version: "バージョン", "You cannot have duplicate user profiles": "重複するユーザープロファイルを持つことはできません", "Failed to create user profile": "ユーザープロファイルの作成に失敗しました", "This user profile does not exist on the server": "このユーザープロファイルはサーバーに存在しません", "Failed to download user profile from the server": "サーバーからユーザープロファイルをダウンロードできませんでした", "User token is invalid": "ユーザートークンが無効です", "Are you sure you want to display your private key?": "本当に秘密鍵を表示しますか?", "DO NOT SHARE THIS KEY WITH ANYONE.": "この鍵を誰とも共有しないでください。", "You need a free user profile slot to import a new user profile": "新しいユーザープロファイルをインポートするには空きユーザープロファイルスロットが必要です", Quit: "終了", Fullscreen: "フルスクリーン", Windowed: "ウィンドウ", " ": "{0} の非公式バージョンをプレイしているようです。最新バージョンについては、元のソースをご覧ください:", Nickname: "ニックネーム", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "リーダーボードに表示されるニックネームを選択してください。ニックネームはいつでも変更できます。", Cancel: "キャンセル", Confirm: "確認", Verifier: "検証者", "User ID": "ユーザーID", Paused: "一時停止", "Switch car": "車両を切り替え", Profiles: "プロフィール", 'Are you sure you would like to delete "{0}"?': '"{0}"を削除してもよろしいですか?', Empty: "空", Reset: "リセット", Apply: "適用", Gameplay: "ゲームプレイ", Units: "単位", Metric: "メトリック", Imperial: "インペリアル", "Reset hint": "ヒントをリセット", Disabled: "無効", Enabled: "有効", "Ghost car": "ゴーストカー", "Default camera": "デフォルトカメラ", Default: "デフォルト", Cockpit: "コクピット", "Cockpit camera mode": "コクピットカメラモード", Hold: "押し続ける", Toggle: "トグル", Checkpoints: "チェックポイント", Timer: "タイマー", Speedometer: "スピードメーター", Bottom: "下", Top: "上", Language: "言語", Graphics: "グラフィック", "Car shadow": "車の影", "Track shadow": "トラックの影", Off: "オフ", On: "オン", Low: "低", Medium: "中", High: "高", Clouds: "雲", Particles: "パーティクル", Skidmarks: "スキッドマーク", "Render scale": "レンダースケール", "Anti-aliasing (requires restart)": "アンチエイリアシング(再起動が必要)", Audio: "オーディオ", "Sound effect volume": "効果音の音量", "Music volume": "音楽の音量", "Checkpoint volume": "チェックポイントの音量", Controls: "コントロール", Vehicle: "車両", Accelerate: "アクセル", Brake: "ブレーキ", "Turn left": "左に曲がる", "Turn right": "右に曲がる", "Checkpoint reset": "チェックポイントリセット", "Start reset": "スタートリセット", "Cockpit camera": "コクピットカメラ", "Rotate part": "パーツを回転", "Height modifier": "高さ変更", "Delete part": "パーツを削除", "Move forwards": "前に移動", "Move backwards": "後ろに移動", "Move left": "左に移動", "Move right": "右に移動", "Rotate view up": "ビューを上に回転", "Rotate view down": "ビューを下に回転", "Rotate view left": "ビューを左に回転", "Rotate view right": "ビューを右に回転", "Move down": "下に移動", "Move up": "上に移動", "Test track": "トラックをテスト", "Pick part": "パーツを選択", Spectator: "スペクテーター", "Speed modifier": "スピード変更", Other: "その他", "Hide UI": "UIを非表示", Pause: "一時停止", "Toggle FPS counter": "FPSカウンターを切り替え", "Toggle spectator camera": "スペクテーターカメラを切り替え", "Press any key...\n\nPress [Escape] to cancel.": "任意のキーを押してください...\n\n[Escape] を押してキャンセル。", Clear: "クリア", "New record": "新記録", Record: "記録", Current: "現在", Difference: "差分", Copy: "コピー", Import: "インポート", "Failed to import track": "トラックのインポートに失敗しました", 'The track "{0}" already exists. Do you wish to overwrite it?': "トラック「{0}」は既に存在します。上書きしますか?", Overwrite: "上書き", "Paste track data here...": "トラックデータをここに貼り付けてください...", Rank: "ランク", "Personal best": "個人ベスト", Opponents: "対戦相手", "{0} opponent selected": "{0} 人の対戦相手が選択されました", "{0} opponents selected": "{0} 人の対戦相手が選択されました", "Select opponents to race against from the leaderboard on the left": "左のリーダーボードから対戦相手を選択してください", "No record": "記録なし", "Official tracks": "公式トラック", "Community tracks": "コミュニティトラック", "Custom tracks": "カスタムトラック", 'Are you sure you want to delete "{0}"?': '"{0}" を削除してもよろしいですか?', Delete: "削除", "No community tracks": "コミュニティトラックはありません", "Community tracks are coming soon": "コミュニティトラックは近日公開予定です", "No custom tracks": "カスタムトラックはありません", "Create a track using the editor or import a track code": "エディタを使用してトラックを作成するか、トラックコードをインポートしてトラックを作成します", "Search tracks...": "トラックを検索...", "Invalid replay detected!": "無効なリプレイが検出されました!" }, dz = { "Checkpoint order": "체크포인트 순서", Height: "높이", Exit: "나가기", Random: "랜덤", Primary: "기본", Secondary: "보조", Frame: "프레임", Rims: "림", "Are you sure you want to exit without saving?": "저장하지 않고 나가시겠습니까?", "All changes will be lost!": "모든 변경 사항이 손실됩니다!", "Car saved!": "차량이 저장되었습니다!", Test: "테스트", "Starting point is missing!": "출발 지점이 없습니다!", Generate: "생성", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "새로운 트랙을 생성하시겠습니까?\n\n현재 트랙은 손실됩니다!", Load: "불러오기", Save: "저장", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "새로운 트랙을 불러오시겠습니까?\n\n현재 트랙은 손실됩니다!", "Track saved!": "트랙이 저장되었습니다!", "Failed to save!": "저장 실패!", 'Are you sure you want to overwrite "{0}"?': '"{0}"을(를) 덮어쓰시겠습니까?', Export: "내보내기", Help: "도움말", "Are you sure you want to exit the editor?": "편집기를 나가시겠습니까?", "All unsaved data will be lost!": "저장되지 않은 모든 데이터가 손실됩니다!", "Track settings": "트랙 설정", "Unnamed Track": "이름 없는 트랙", "Track name": "트랙 이름", Author: "제작자", Unknown: "알 수 없음", Environment: "환경", Summer: "여름", Winter: "겨울", Desert: "사막", "Sun direction": "태양 방향", "How to use the editor": "에디터 사용 방법", "Camera controls": "카메라 컨트롤", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "카메라는 마우스 오른쪽 버튼을 클릭하고 드래그하여 이동할 수 있습니다. 카메라를 회전하려면 마우스 중간 버튼(휠)을 클릭하거나 컨트롤 키를 누른 상태에서 마우스 오른쪽 버튼을 클릭하고 드래그하면 됩니다. 마우스 휠을 스크롤하여 확대 및 축소할 수 있습니다.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "또는 다음 키보드 키를 사용하여 카메라를 제어할 수도 있습니다.", "Move forwards:": "앞으로 이동:", "Move backwards:": "뒤로 이동:", "Move left:": "왼쪽으로 이동:", "Move right:": "오른쪽으로 이동:", "Rotate left:": "왼쪽으로 회전:", "Rotate right:": "오른쪽으로 회전:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "편집된 높이는 왼쪽 하단 모서리의 높이 선택을 사용하거나 Shift 키를 누른 상태에서 마우스 휠을 스크롤하여 변경할 수 있습니다. 또는 다음 키보드 키를 사용할 수도 있습니다.", "Move up:": "위로 이동:", "Move down:": "아래로 이동:", Editing: "편집", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "트랙 부품은 오른쪽 메뉴에서 선택한 후 마우스로 왼쪽 클릭하여 배치할 수 있습니다.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "또는 현재 마우스로 가리키고 있는 트랙 부품을 다음 키보드 단축키로 선택할 수도 있습니다.", "The selected part can then be rotated using the following keyboard shortcut:": "선택한 부품은 다음 키보드 단축키를 사용하여 회전할 수 있습니다.", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "트랙 부품은 오른쪽 메뉴의 삭제 도구를 사용하거나 다음 키를 누른 상태에서 삭제할 수 있습니다.", "Starting points, checkpoints and the finish line": "시작 지점, 체크포인트 및 완주 선", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "시작 지점, 체크포인트 및 완주 선은 모두 오른쪽 메뉴의 가장 상위 카테고리에서 선택할 수 있습니다.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "각 트랙은 최소한 하나의 시작 지점이 있어야 합니다. 여러 개의 시작 지점이 있는 경우 마지막으로 배치된 지점이 사용됩니다.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "체크포인트는 시작 지점과 완주 선 사이에 배치되어야 합니다. 체크포인트 트랙 부품이 선택되면 하단 오른쪽에 체크포인트 순서를 선택할 수 있는 도구가 있습니다. 이는 완주 선으로 이동하기 전에 체크포인트를 통과해야 하는 순서를 결정합니다. 동일한 체크포인트 순서를 가진 여러 개의 체크포인트를 가질 수 있다는 점에 유의하세요.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "완주 선은 트랙이 끝나는 곳이지만 모든 체크포인트를 통과한 후에만 활성화됩니다. 여러 개의 완주 선을 가질 수도 있습니다.", "Starting point": "시작 지점", Checkpoint: "체크포인트", "Finish line": "완주 선", "Exporting the track": "트랙 내보내기", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "트랙이 완성되면 왼쪽 상단에 트랙 이름을 입력한 후 내보내기 버튼을 사용하여 트랙을 내보낼 수 있습니다. 이렇게 하면 다른 사용자가 트랙을 가져와서 재생할 수 있는 트랙 코드가 표시됩니다.", Close: "닫기", "Not set": "설정되지 않음", or: "또는", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "카메라는 한 손가락으로 드래그하여 이동할 수 있습니다. 카메라를 두 손가락으로 드래그하여 회전할 수 있습니다. 확대 및 축소하려면 핀치 동작을 사용하십시오.", "The edited height can be changed by using the height selection in the bottom left corner.": "편집된 높이는 왼쪽 하단의 높이 선택을 사용하여 변경할 수 있습니다.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "트랙 부품은 오른쪽 메뉴에서 선택한 후 화면을 탭하여 배치할 수 있습니다.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "선택한 부품은 왼쪽 하단의 회전 버튼을 탭하여 회전할 수 있습니다.", "Track parts can be deleted by using the delete tool in the right side menu.": "트랙 부품은 오른쪽 메뉴의 삭제 도구를 사용하여 삭제할 수 있습니다.", Watch: "관전", "Loading replay": "리플레이 로딩", "Press {0} to return to the last checkpoint": "마지막 체크포인트로 돌아가려면 {0}을(를) 누르십시오", "Press {0} to start over": "처음부터 시작하려면 {0}을(를) 누르십시오", "Reset once to return to the last checkpoint": "한 번 리셋하여 마지막 체크포인트로 돌아가세요", "Reset again to start over": "다시 리셋하여 처음부터 시작하세요", Leaderboard: "리더보드", Back: "뒤로", "Error: Failed to load leaderboard": "오류: 리더보드 불러오기 실패", Pending: "대기 중", Verified: "확인됨", Invalid: "유효하지 않음", Duplicate: "중복", You: "당신", "Only verified": "확인된 것만", Loading: "로딩 중", "Failed to load recordings": "녹화 불러오기 실패", "Cannot load recordings due to non-determinism": "결정론적이지 않아 녹화를 불러올 수 없습니다", Ok: "확인", "Track is missing starting point": "트랙에 출발 지점이 없습니다", "Some leaderboard features are disabled.": "일부 리더보드 기능이 비활성화되었습니다.", "Please try another browser or device.": "다른 브라우저나 기기를 시도해보십시오.", "You already have another instance of PolyTrack open.": "이미 다른 PolyTrack 인스턴스가 열려 있습니다.", "Please switch to that tab or window to continue.": "계속하려면 해당 탭이나 창으로 전환하십시오.", "Computer determinism check failed.": "컴퓨터 결정론 검사 실패.", "Non-deterministic game assets found.": "결정론적이지 않은 게임 자산 발견.", "Please try clearing your browser cache.": "브라우저 캐시를 지우는 것을 시도해보십시오.", Customize: "사용자 설정", Editor: "편집기", Settings: "설정", Profile: "프로필", Play: "재생", Version: "버전", "You cannot have duplicate user profiles": "중복 사용자 프로필을 가질 수 없습니다", "Failed to create user profile": "사용자 프로필 생성에 실패했습니다", "This user profile does not exist on the server": "이 사용자 프로필은 서버에 존재하지 않습니다", "Failed to download user profile from the server": "서버에서 사용자 프로필을 다운로드하지 못했습니다", "User token is invalid": "사용자 토큰이 유효하지 않습니다", "Are you sure you want to display your private key?": "개인 키를 표시하시겠습니까?", "DO NOT SHARE THIS KEY WITH ANYONE.": "이 키를 아무와도 공유하지 마십시오.", "You need a free user profile slot to import a new user profile": "새로운 사용자 프로필을 가져오려면 빈 사용자 프로필 슬롯이 필요합니다", Quit: "종료", Fullscreen: "전체 화면", Windowed: "창 모드", " ": "{0}의 비공식 버전을 플레이 중인 것 같습니다. 최신 버전은 원본 소스에서 확인하십시오:", Nickname: "닉네임", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "리더보드에 표시될 닉네임을 선택하십시오. 닉네임은 언제든지 변경할 수 있습니다.", Cancel: "취소", Confirm: "확인", Verifier: "확인자", "User ID": "사용자 ID", Paused: "일시 정지", "Switch car": "차량 전환", Profiles: "프로필", 'Are you sure you would like to delete "{0}"?': '"{0}"를 삭제하시겠습니까?', Empty: "비어 있음", Reset: "재설정", Apply: "적용", Gameplay: "게임 플레이", Units: "단위", Metric: "미터법", Imperial: "영국/미국 단위", "Reset hint": "힌트 재설정", Disabled: "비활성화", Enabled: "활성화", "Ghost car": "유령 자동차", "Default camera": "기본 카메라", Default: "기본", Cockpit: "콕핏", "Cockpit camera mode": "콕핏 카메라 모드", Hold: "유지", Toggle: "전환", Checkpoints: "체크포인트", Timer: "타이머", Speedometer: "속도계", Bottom: "하단", Top: "상단", Language: "언어", Graphics: "그래픽", "Car shadow": "자동차 그림자", "Track shadow": "트랙 그림자", Off: "끄기", On: "켜기", Low: "낮음", Medium: "중간", High: "높음", Clouds: "구름", Particles: "파티클", Skidmarks: "스키드 마크", "Render scale": "렌더링 스케일", "Anti-aliasing (requires restart)": "안티 앨리어싱 (재시작 필요)", Audio: "오디오", "Sound effect volume": "사운드 효과 볼륨", "Music volume": "음악 볼륨", "Checkpoint volume": "체크포인트 볼륨", Controls: "컨트롤", Vehicle: "차량", Accelerate: "가속", Brake: "브레이크", "Turn left": "왼쪽으로 회전", "Turn right": "오른쪽으로 회전", "Checkpoint reset": "체크포인트 리셋", "Start reset": "시작 리셋", "Cockpit camera": "콕핏 카메라", "Rotate part": "부품 회전", "Height modifier": "높이 조절", "Delete part": "부품 삭제", "Move forwards": "앞으로 이동", "Move backwards": "뒤로 이동", "Move left": "왼쪽으로 이동", "Move right": "오른쪽으로 이동", "Rotate view up": "뷰 위로 회전", "Rotate view down": "뷰 아래로 회전", "Rotate view left": "뷰 왼쪽으로 회전", "Rotate view right": "뷰 오른쪽으로 회전", "Move down": "아래로 이동", "Move up": "위로 이동", "Test track": "트랙 테스트", "Pick part": "부품 선택", Spectator: "관전자", "Speed modifier": "속도 조절", Other: "기타", "Hide UI": "UI 숨기기", Pause: "일시 정지", "Toggle FPS counter": "FPS 카운터 전환", "Toggle spectator camera": "관전 카메라 전환", "Press any key...\n\nPress [Escape] to cancel.": "아무 키나 누르십시오...\n\n[Escape]를 눌러 취소하십시오.", Clear: "지우기", "New record": "새 기록", Record: "기록", Current: "현재", Difference: "차이", Copy: "복사", Import: "가져오기", "Failed to import track": "트랙 가져오기 실패", 'The track "{0}" already exists. Do you wish to overwrite it?': '"{0}" 트랙이 이미 존재합니다. 덮어쓰시겠습니까?', Overwrite: "덮어쓰기", "Paste track data here...": "트랙 데이터를 여기에 붙여넣으십시오...", Rank: "순위", "Personal best": "개인 최고 기록", Opponents: "상대방", "{0} opponent selected": "{0} 상대방 선택됨", "{0} opponents selected": "{0} 상대방 선택됨", "Select opponents to race against from the leaderboard on the left": "왼쪽의 리더보드에서 경주할 상대방을 선택하세요", "No record": "기록 없음", "Official tracks": "공식 트랙", "Community tracks": "커뮤니티 트랙", "Custom tracks": "사용자 정의 트랙", 'Are you sure you want to delete "{0}"?': '"{0}"을(를) 삭제하시겠습니까?', Delete: "삭제", "No community tracks": "커뮤니티 트랙 없음", "Community tracks are coming soon": "커뮤니티 트랙이 곧 출시됩니다", "No custom tracks": "사용자 정의 트랙 없음", "Create a track using the editor or import a track code": "에디터를 사용하여 트랙을 만들거나 트랙 코드를 가져와서 트랙을 만드세요", "Search tracks...": "트랙 검색...", "Invalid replay detected!": "유효하지 않은 리플레이가 감지되었습니다!" }, uz = { "Checkpoint order": "Kolejność punktów kontrolnych", Height: "Wysokość", Exit: "Wyjście", Random: "Losowe", Primary: "Główny", Secondary: "Dodatkowy", Frame: "Rama", Rims: "Obręcze", "Are you sure you want to exit without saving?": "Czy na pewno chcesz wyjść bez zapisywania?", "All changes will be lost!": "Wszystkie zmiany zostaną utracone!", "Car saved!": "Samochód zapisany!", Test: "Test", "Starting point is missing!": "Brak punktu startowego!", Generate: "Generuj", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "Czy na pewno chcesz wygenerować nową trasę?\n\nTwoja obecna trasa zostanie utracona!", Load: "Wczytaj", Save: "Zapisz", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "Czy na pewno chcesz wczytać nową trasę?\n\nTwoja obecna trasa zostanie utracona!", "Track saved!": "Trasa została zapisana!", "Failed to save!": "Nie udało się zapisać!", 'Are you sure you want to overwrite "{0}"?': "Czy na pewno chcesz nadpisać „{0}”?", Export: "Eksportuj", Help: "Pomoc", "Are you sure you want to exit the editor?": "Czy na pewno chcesz wyjść z edytora?", "All unsaved data will be lost!": "Wszystkie niezapisane dane zostaną utracone!", "Track settings": "Ustawienia trasy", "Unnamed Track": "Bez nazwy", "Track name": "Nazwa trasy", Author: "Autor", Unknown: "Nieznany", Environment: "Środowisko", Summer: "Lato", Winter: "Zima", Desert: "Pustynia", "Sun direction": "Kierunek słońca", "How to use the editor": "Jak korzystać z edytora", "Camera controls": "Sterowanie kamerą", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "Kamerę można przesuwać, klikając prawym przyciskiem myszy i przeciągając. Obróć kamerę, klikając środkowy przycisk myszy (koło myszy) lub przytrzymując klawisz Ctrl i klikając prawym przyciskiem myszy i przeciągając. Przybliż i oddal obraz, przewijając kółko myszy.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "Alternatywnie, kamerą można również sterować za pomocą następujących klawiszy na klawiaturze:", "Move forwards:": "Poruszaj się do przodu:", "Move backwards:": "Poruszaj się do tyłu:", "Move left:": "Poruszaj się w lewo:", "Move right:": "Poruszaj się w prawo:", "Rotate left:": "Obróć w lewo:", "Rotate right:": "Obróć w prawo:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "Edytowaną wysokość można zmienić, korzystając z wyboru wysokości w lewym dolnym rogu lub przytrzymując klawisz Shift i przewijając kółko myszy. Alternatywnie można użyć następujących klawiszy na klawiaturze:", "Move up:": "Przesuń w górę:", "Move down:": "Przesuń w dół:", Editing: "Edycja", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "Części toru można wybrać w menu po prawej stronie, a następnie można je umieścić, klikając lewym przyciskiem myszy.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "Alternatywnie, aktualnie zaznaczoną część toru można wybrać za pomocą następującego skrótu klawiaturowego:", "The selected part can then be rotated using the following keyboard shortcut:": "Wybraną część można następnie obrócić za pomocą następującego skrótu klawiaturowego:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "Części toru można usunąć, korzystając z narzędzia usuwania w menu po prawej stronie lub przytrzymując następujący klawisz:", "Starting points, checkpoints and the finish line": "Punkty startowe, punkty kontrolne i linia mety", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "Punkty startowe, punkty kontrolne i linie mety można wybrać we wszystkich kategoriach w menu po prawej stronie.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Każda trasa musi mieć co najmniej jeden punkt startowy. Jeśli istnieje wiele punktów startowych, zostanie użyty ostatnio umieszczony.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "Punkty kontrolne powinny być umieszczone między punktem startowym a linią mety. Po wybraniu części toru punktu kontrolnego pojawi się narzędzie w prawym dolnym rogu, które pozwoli wybrać kolejność punktu kontrolnego. Określa to kolejność, w jakiej punkty kontrolne muszą być przechodzone przed dojazdem do linii mety. Zauważ, że możliwe jest posiadanie wielu punktów kontrolnych o tej samej kolejności.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "Linia mety to miejsce, gdzie kończy się tor, ale staje się aktywna dopiero po przejściu wszystkich punktów kontrolnych. Możliwe jest również posiadanie wielu linii mety.", "Starting point": "Punkt startowy", Checkpoint: "Punkt kontrolny", "Finish line": "Linia mety", "Exporting the track": "Eksportowanie trasy", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "Po zakończeniu trasy można wprowadzić jej nazwę w lewym górnym rogu, a następnie można ją wyeksportować, korzystając z przycisku eksportu. To ujawni kod trasy, który można przesłać innym użytkownikom, aby mogli zaimportować i odtworzyć trasę.", Close: "Zamknij", "Not set": "Nie ustawiono", or: "lub", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "Kamerę można przesuwać, przeciągając jednym palcem. Obróć kamerę, przeciągając dwoma palcami. Przybliż i oddal obraz, ściskając palcami.", "The edited height can be changed by using the height selection in the bottom left corner.": "Edytowaną wysokość można zmienić, korzystając z wyboru wysokości w lewym dolnym rogu.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "Części toru można wybrać w menu po prawej stronie, a następnie można je umieścić, dotykając ekranu.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "Wybraną część można następnie obrócić, dotykając przycisku obracania w lewym dolnym rogu.", "Track parts can be deleted by using the delete tool in the right side menu.": "Części toru można usunąć, korzystając z narzędzia usuwania w menu po prawej stronie.", Watch: "Oglądaj", "Loading replay": "Wczytywanie nagrania", "Press {0} to return to the last checkpoint": "Naciśnij {0}, aby wrócić do ostatniego punktu kontrolnego", "Press {0} to start over": "Naciśnij {0}, aby zacząć od nowa", "Reset once to return to the last checkpoint": "Resetuj raz, aby wrócić do ostatniego punktu kontrolnego", "Reset again to start over": "Resetuj ponownie, aby zacząć od nowa", Leaderboard: "Tabela wyników", Back: "Powrót", "Error: Failed to load leaderboard": "Błąd: Nie można wczytać tabeli wyników", Pending: "Oczekujący", Verified: "Zweryfikowany", Invalid: "Nieprawidłowy", Duplicate: "Duplikat", You: "Ty", "Only verified": "Tylko zweryfikowane", Loading: "Ładowanie", "Failed to load recordings": "Nie udało się wczytać nagrań", "Cannot load recordings due to non-determinism": "Nie można wczytać nagrań z powodu nieterminizmu", Ok: "Ok", "Track is missing starting point": "Brak punktu startowego na trasie", "Some leaderboard features are disabled.": "Niektóre funkcje tabeli wyników są wyłączone.", "Please try another browser or device.": "Proszę spróbować inną przeglądarkę lub urządzenie.", "You already have another instance of PolyTrack open.": "Masz już otwartą inną instancję PolyTrack.", "Please switch to that tab or window to continue.": "Proszę przełączyć się na ten kartę lub okno, aby kontynuować.", "Computer determinism check failed.": "Nie udało się sprawdzić determinizmu komputera.", "Non-deterministic game assets found.": "Znaleziono nieterministyczne zasoby gry.", "Please try clearing your browser cache.": "Proszę spróbować wyczyścić pamięć podręczną przeglądarki.", Customize: "Dostosuj", Editor: "Edytor", Settings: "Ustawienia", Profile: "Profil", Play: "Graj", Version: "Wersja", "You cannot have duplicate user profiles": "Nie możesz mieć zduplikowanych profili użytkownika", "Failed to create user profile": "Nie udało się utworzyć profilu użytkownika", "This user profile does not exist on the server": "Ten profil użytkownika nie istnieje na serwerze", "Failed to download user profile from the server": "Nie udało się pobrać profilu użytkownika z serwera", "User token is invalid": "Token użytkownika jest nieprawidłowy", "Are you sure you want to display your private key?": "Czy na pewno chcesz wyświetlić swój klucz prywatny?", "DO NOT SHARE THIS KEY WITH ANYONE.": "NIE UDOSTĘPNIAJ TEGO KLUCZA NIKOMU.", "You need a free user profile slot to import a new user profile": "Potrzebujesz wolnego miejsca na profil użytkownika, aby zaimportować nowy profil użytkownika", Quit: "Wyjdź", Fullscreen: "Pełny ekran", Windowed: "Okno", " ": "Wygląda na to, że grasz w nieoficjalną wersję {0}. Aby uzyskać najnowszą wersję, odwiedź oryginalne źródło:", Nickname: "Pseudonim", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Wybierz pseudonim, który będzie wyświetlany w tabeli wyników. Możesz go zmieniać w dowolnym momencie.", Cancel: "Anuluj", Confirm: "Potwierdź", Verifier: "Weryfikator", "User ID": "ID użytkownika", Paused: "Wstrzymano", "Switch car": "Zmień samochód", Profiles: "Profile", 'Are you sure you would like to delete "{0}"?': 'Czy na pewno chcesz usunąć "{0}"?', Empty: "Puste", Reset: "Resetuj", Apply: "Zastosuj", Gameplay: "Rozgrywka", Units: "Jednostki", Metric: "Metryczne", Imperial: "Imperialne", "Reset hint": "Resetuj wskazówkę", Disabled: "Wyłączone", Enabled: "Włączone", "Ghost car": "Duch samochodu", "Default camera": "Domyślna kamera", Default: "Domyślny", Cockpit: "Kokpit", "Cockpit camera mode": "Tryb kamery kokpitu", Hold: "Przytrzymaj", Toggle: "Przełącz", Checkpoints: "Punkty kontrolne", Timer: "Stoper", Speedometer: "Prędkościomierz", Bottom: "Dół", Top: "Góra", Language: "Język", Graphics: "Grafika", "Car shadow": "Cień samochodu", "Track shadow": "Cień trasy", Off: "Wyłącz", On: "Włącz", Low: "Niska", Medium: "Średnia", High: "Wysoka", Clouds: "Chmury", Particles: "Cząsteczki", Skidmarks: "Ślady opon", "Render scale": "Skala renderowania", "Anti-aliasing (requires restart)": "Anti-aliasing (wymaga restartu)", Audio: "Dźwięk", "Sound effect volume": "Głośność efektów dźwiękowych", "Music volume": "Głośność muzyki", "Checkpoint volume": "Głośność punktów kontrolnych", Controls: "Sterowanie", Vehicle: "Pojazd", Accelerate: "Przyspiesz", Brake: "Hamuj", "Turn left": "Skręć w lewo", "Turn right": "Skręć w prawo", "Checkpoint reset": "Reset punktu kontrolnego", "Start reset": "Reset startu", "Cockpit camera": "Kamera kokpitu", "Rotate part": "Obróć część", "Height modifier": "Modyfikator wysokości", "Delete part": "Usuń część", "Move forwards": "Poruszaj się do przodu", "Move backwards": "Poruszaj się do tyłu", "Move left": "Poruszaj się w lewo", "Move right": "Poruszaj się w prawo", "Rotate view up": "Obróć widok w górę", "Rotate view down": "Obróć widok w dół", "Rotate view left": "Obróć widok w lewo", "Rotate view right": "Obróć widok w prawo", "Move down": "Przesuń w dół", "Move up": "Przesuń w górę", "Test track": "Testuj trasę", "Pick part": "Wybierz część", Spectator: "Widz", "Speed modifier": "Modyfikator prędkości", Other: "Inne", "Hide UI": "Ukryj UI", Pause: "Pauza", "Toggle FPS counter": "Przełącz licznik FPS", "Toggle spectator camera": "Przełącz kamerę widza", "Press any key...\n\nPress [Escape] to cancel.": "Naciśnij dowolny klawisz...\n\nNaciśnij [Escape], aby anulować.", Clear: "Wyczyść", "New record": "Nowy rekord", Record: "Rekord", Current: "Aktualny", Difference: "Różnica", Copy: "Kopiuj", Import: "Importuj", "Failed to import track": "Import trasy nie powiódł się", 'The track "{0}" already exists. Do you wish to overwrite it?': "Trasa „{0}” już istnieje. Czy chcesz ją nadpisać?", Overwrite: "Nadpisz", "Paste track data here...": "Wklej dane trasy tutaj...", Rank: "Ranking", "Personal best": "Najlepszy wynik", Opponents: "Przeciwnicy", "{0} opponent selected": "{0} przeciwnik wybrany", "{0} opponents selected": "{0} przeciwników wybranych", "Select opponents to race against from the leaderboard on the left": "Wybierz przeciwników, przeciwko którym chcesz ścigać się z tabeli wyników po lewej stronie", "No record": "Brak rekordu", "Official tracks": "Oficjalne trasy", "Community tracks": "Trasy społeczności", "Custom tracks": "Niestandardowe trasy", 'Are you sure you want to delete "{0}"?': "Czy na pewno chcesz usunąć „{0}”?", Delete: "Usuń", "No community tracks": "Brak tras społeczności", "Community tracks are coming soon": "Trasy społeczności wkrótce", "No custom tracks": "Brak niestandardowych tras", "Create a track using the editor or import a track code": "Utwórz trasę za pomocą edytora lub zaimportuj kod trasy", "Search tracks...": "Szukaj tras...", "Invalid replay detected!": "Wykryto nieprawidłowe nagranie!" }, pz = { "Checkpoint order": "Ordem dos Pontos de Verificação", Height: "Altura", Exit: "Sair", Random: "Aleatório", Primary: "Principal", Secondary: "Secundário", Frame: "Estrutura", Rims: "Aros", "Are you sure you want to exit without saving?": "Tem certeza de que deseja sair sem salvar?", "All changes will be lost!": "Todas as alterações serão perdidas!", "Car saved!": "Carro salvo!", Test: "Testar", "Starting point is missing!": "Ponto de partida está faltando!", Generate: "Gerar", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "Tem certeza de que deseja gerar uma nova pista?\n\nSua pista atual será perdida!", Load: "Carregar", Save: "Salvar", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "Tem certeza de que deseja carregar uma nova pista?\n\nSua pista atual será perdida!", "Track saved!": "Pista salva!", "Failed to save!": "Falha ao salvar!", 'Are you sure you want to overwrite "{0}"?': 'Tem certeza de que deseja sobrescrever "{0}"?', Export: "Exportar", Help: "Ajuda", "Are you sure you want to exit the editor?": "Tem certeza de que deseja sair do editor?", "All unsaved data will be lost!": "Todos os dados não salvos serão perdidos!", "Track settings": "Configurações da pista", "Unnamed Track": "Pista sem nome", "Track name": "Nome da pista", Author: "Autor", Unknown: "Desconhecido", Environment: "Ambiente", Summer: "Verão", Winter: "Inverno", Desert: "Deserto", "Sun direction": "Direção do sol", "How to use the editor": "Como usar o editor", "Camera controls": "Controles da câmera", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "A câmera pode ser movida clicando com o botão direito do mouse e arrastando. Gire a câmera clicando no botão do meio do mouse (roda do mouse) ou segurando a tecla de controle e clicando com o botão direito do mouse e arrastando. Amplie e reduza o zoom rolando a roda do mouse.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "Alternativamente, a câmera também pode ser controlada usando as seguintes teclas do teclado:", "Move forwards:": "Mover para frente:", "Move backwards:": "Mover para trás:", "Move left:": "Mover para a esquerda:", "Move right:": "Mover para a direita:", "Rotate left:": "Girar para a esquerda:", "Rotate right:": "Girar para a direita:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "A altura editada pode ser alterada usando a seleção de altura no canto inferior esquerdo ou segurando a tecla shift e rolando a roda do mouse. Alternativamente, você pode usar as seguintes teclas do teclado:", "Move up:": "Mover para cima:", "Move down:": "Mover para baixo:", Editing: "Edição", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "As partes da pista podem ser selecionadas no menu à direita e, em seguida, podem ser colocadas clicando com o botão esquerdo do mouse.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "Alternativamente, a parte da pista atualmente destacada pelo mouse pode ser selecionada com o seguinte atalho de teclado:", "The selected part can then be rotated using the following keyboard shortcut:": "A parte selecionada pode então ser girada usando o seguinte atalho de teclado:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "As partes da pista podem ser excluídas usando a ferramenta de exclusão no menu lateral direito ou segurando a seguinte tecla:", "Starting points, checkpoints and the finish line": "Pontos de partida, checkpoints e linha de chegada", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "Pontos de partida, checkpoints e linhas de chegada podem ser selecionados na categoria mais alta do menu lateral direito.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Cada pista deve ter pelo menos um ponto de partida. Se houver vários pontos de partida, o último colocado será usado.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "Os checkpoints devem ser colocados entre o ponto de partida e a linha de chegada. Quando uma parte da pista de checkpoint é selecionada, haverá uma ferramenta no canto inferior direito para selecionar a ordem do checkpoint. Isso determina a ordem em que os checkpoints devem ser passados antes de dirigir até a linha de chegada. Observe que é possível ter vários checkpoints com a mesma ordem de checkpoint.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "A linha de chegada é onde a pista termina, mas só se tornará ativa depois que todos os checkpoints forem passados. Também é possível ter várias linhas de chegada.", "Starting point": "Ponto de partida", Checkpoint: "Checkpoint", "Finish line": "Linha de chegada", "Exporting the track": "Exportando a pista", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "Quando a pista estiver pronta, um nome para a pista pode ser inserido no canto superior esquerdo e, em seguida, a pista pode ser exportada usando o botão de exportação. Isso revelará um código de pista que pode ser enviado para outros usuários para que eles possam importar e jogar a pista.", Close: "Fechar", "Not set": "Não definido", or: "ou", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "A câmera pode ser movida arrastando com um dedo. Gire a câmera arrastando com dois dedos. Amplie e reduza o zoom beliscando.", "The edited height can be changed by using the height selection in the bottom left corner.": "A altura editada pode ser alterada usando a seleção de altura no canto inferior esquerdo.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "As partes da pista podem ser selecionadas no menu à direita e, em seguida, podem ser colocadas tocando na tela.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "A parte selecionada pode então ser girada tocando no botão de rotação no canto inferior esquerdo.", "Track parts can be deleted by using the delete tool in the right side menu.": "As partes da pista podem ser excluídas usando a ferramenta de exclusão no menu lateral direito.", Watch: "Assistir", "Loading replay": "Carregando replay", "Press {0} to return to the last checkpoint": "Pressione {0} para retornar ao último checkpoint", "Press {0} to start over": "Pressione {0} para começar de novo", "Reset once to return to the last checkpoint": "Redefinir uma vez para retornar ao último checkpoint", "Reset again to start over": "Redefinir novamente para começar de novo", Leaderboard: "Quadro de Líderes", Back: "Voltar", "Error: Failed to load leaderboard": "Erro: Falha ao carregar o quadro de líderes", Pending: "Pendente", Verified: "Verificado", Invalid: "Inválido", Duplicate: "Duplicado", You: "Você", "Only verified": "Apenas verificados", Loading: "Carregando", "Failed to load recordings": "Falha ao carregar gravações", "Cannot load recordings due to non-determinism": "Não é possível carregar gravações devido a não determinismo", Ok: "Ok", "Track is missing starting point": "Pista está sem ponto de partida", "Some leaderboard features are disabled.": "Alguns recursos do quadro de líderes estão desativados.", "Please try another browser or device.": "Por favor, tente outro navegador ou dispositivo.", "You already have another instance of PolyTrack open.": "Você já tem outra instância do PolyTrack aberta.", "Please switch to that tab or window to continue.": "Por favor, mude para aquela guia ou janela para continuar.", "Computer determinism check failed.": "Falha na verificação de determinismo do computador.", "Non-deterministic game assets found.": "Assets de jogo não determinísticos encontrados.", "Please try clearing your browser cache.": "Por favor, tente limpar o cache do seu navegador.", Customize: "Personalizar", Editor: "Editor", Settings: "Configurações", Profile: "Perfil", Play: "Jogar", Version: "Versão", "You cannot have duplicate user profiles": "Você não pode ter perfis de usuário duplicados", "Failed to create user profile": "Falha ao criar perfil de usuário", "This user profile does not exist on the server": "Este perfil de usuário não existe no servidor", "Failed to download user profile from the server": "Falha ao baixar perfil de usuário do servidor", "User token is invalid": "Token de usuário inválido", "Are you sure you want to display your private key?": "Tem certeza de que deseja exibir sua chave privada?", "DO NOT SHARE THIS KEY WITH ANYONE.": "NÃO COMPARTILHE ESTA CHAVE COM NINGUÉM.", "You need a free user profile slot to import a new user profile": "Você precisa de um slot de perfil de usuário livre para importar um novo perfil de usuário", Quit: "Sair", Fullscreen: "Tela Cheia", Windowed: "Janela", " ": "Parece que você está jogando uma versão não oficial de {0}. Para a versão mais atualizada, visite a fonte original:", Nickname: "Apelido", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Escolha um apelido para ser exibido no quadro de líderes. Seu apelido pode ser alterado a qualquer momento.", Cancel: "Cancelar", Confirm: "Confirmar", Verifier: "Verificador", "User ID": "ID de Usuário", Paused: "Pausado", "Switch car": "Trocar carro", Profiles: "Perfis", 'Are you sure you would like to delete "{0}"?': 'Tem certeza de que deseja excluir "{0}"?', Empty: "Vazio", Reset: "Redefinir", Apply: "Aplicar", Gameplay: "Jogabilidade", Units: "Unidades", Metric: "Métrico", Imperial: "Imperial", "Reset hint": "Redefinir dica", Disabled: "Desativado", Enabled: "Ativado", "Ghost car": "Carro Fantasma", "Default camera": "Câmera Padrão", Default: "Padrão", Cockpit: "Cockpit", "Cockpit camera mode": "Modo de câmera do cockpit", Hold: "Manter", Toggle: "Alternar", Checkpoints: "Pontos de Verificação", Timer: "Temporizador", Speedometer: "Velocímetro", Bottom: "Inferior", Top: "Superior", Language: "Idioma", Graphics: "Gráficos", "Car shadow": "Sombra do Carro", "Track shadow": "Sombra da Pista", Off: "Desligado", On: "Ligado", Low: "Baixo", Medium: "Médio", High: "Alto", Clouds: "Nuvens", Particles: "Partículas", Skidmarks: "Marcas de Derrapagem", "Render scale": "Escala de Renderização", "Anti-aliasing (requires restart)": "Anti-aliasing (requer reinício)", Audio: "Áudio", "Sound effect volume": "Volume de Efeitos Sonoros", "Music volume": "Volume de Música", "Checkpoint volume": "Volume dos Pontos de Verificação", Controls: "Controles", Vehicle: "Veículo", Accelerate: "Acelerar", Brake: "Freio", "Turn left": "Virar à Esquerda", "Turn right": "Virar à Direita", "Checkpoint reset": "Redefinir Ponto de Verificação", "Start reset": "Redefinir Início", "Cockpit camera": "Câmera do Cockpit", "Rotate part": "Girar Parte", "Height modifier": "Modificador de Altura", "Delete part": "Excluir Parte", "Move forwards": "Mover para Frente", "Move backwards": "Mover para Trás", "Move left": "Mover para a Esquerda", "Move right": "Mover para a Direita", "Rotate view up": "Girar Visão para Cima", "Rotate view down": "Girar Visão para Baixo", "Rotate view left": "Girar Visão para a Esquerda", "Rotate view right": "Girar Visão para a Direita", "Move down": "Mover para Baixo", "Move up": "Mover para Cima", "Test track": "Testar Pista", "Pick part": "Escolher Parte", Spectator: "Espectador", "Speed modifier": "Modificador de Velocidade", Other: "Outro", "Hide UI": "Ocultar UI", Pause: "Pausar", "Toggle FPS counter": "Alternar Contador de FPS", "Toggle spectator camera": "Alternar Câmera de Espectador", "Press any key...\n\nPress [Escape] to cancel.": "Pressione qualquer tecla...\n\nPressione [Escape] para cancelar.", Clear: "Limpar", "New record": "Novo recorde", Record: "Recorde", Current: "Atual", Difference: "Diferença", Copy: "Copiar", Import: "Importar", "Failed to import track": "Falha ao importar a pista", 'The track "{0}" already exists. Do you wish to overwrite it?': 'A pista "{0}" já existe. Deseja sobrescrevê-la?', Overwrite: "Sobrescrever", "Paste track data here...": "Cole os dados da pista aqui...", Rank: "Classificação", "Personal best": "Melhor pessoal", Opponents: "Oponentes", "{0} opponent selected": "{0} oponente selecionado", "{0} opponents selected": "{0} oponentes selecionados", "Select opponents to race against from the leaderboard on the left": "Selecione os oponentes para competir no quadro de líderes à esquerda", "No record": "Sem recorde", "Official tracks": "Pistas Oficiais", "Community tracks": "Pistas Comunitárias", "Custom tracks": "Pistas Personalizadas", 'Are you sure you want to delete "{0}"?': 'Tem certeza de que deseja excluir "{0}"?', Delete: "Excluir", "No community tracks": "Sem pistas comunitárias", "Community tracks are coming soon": "Pistas comunitárias em breve", "No custom tracks": "Sem pistas personalizadas", "Create a track using the editor or import a track code": "Crie uma pista usando o editor ou importe um código de pista", "Search tracks...": "Pesquisar pistas...", "Invalid replay detected!": "Replay inválido detectado!" }, fz = { "Checkpoint order": "Ordem dos Pontos de Verificação", Height: "Altura", Exit: "Sair", Random: "Aleatório", Primary: "Primário", Secondary: "Secundário", Frame: "Estrutura", Rims: "Aros", "Are you sure you want to exit without saving?": "Tem a certeza de que deseja sair sem guardar?", "All changes will be lost!": "Todas as alterações serão perdidas!", "Car saved!": "Carro guardado!", Test: "Testar", "Starting point is missing!": "Ponto de partida em falta!", Generate: "Gerar", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "Tem a certeza de que deseja gerar uma nova pista?\n\nA pista atual será perdida!", Load: "Carregar", Save: "Guardar", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "Tem a certeza de que deseja carregar uma nova pista?\n\nA pista atual será perdida!", "Track saved!": "Pista guardada!", "Failed to save!": "Falha ao guardar!", 'Are you sure you want to overwrite "{0}"?': 'Tem a certeza de que deseja substituir "{0}"?', Export: "Exportar", Help: "Ajuda", "Are you sure you want to exit the editor?": "Tem a certeza de que deseja sair do editor?", "All unsaved data will be lost!": "Todos os dados não guardados serão perdidos!", "Track settings": "Definições da pista", "Unnamed Track": "Pista sem nome", "Track name": "Nome da pista", Author: "Autor", Unknown: "Desconhecido", Environment: "Ambiente", Summer: "Verão", Winter: "Inverno", Desert: "Deserto", "Sun direction": "Direção do sol", "How to use the editor": "Como usar o editor", "Camera controls": "Controlos da câmera", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "A câmera pode ser movida clicando com o botão direito do mouse e arrastando. Rode a câmera clicando no botão do meio do mouse (roda do mouse) ou segurando a tecla de controle e clicando com o botão direito do mouse e arrastando. Aproxime e afaste o zoom rolando a roda do mouse.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "Alternativamente, a câmera também pode ser controlada usando as seguintes teclas do teclado:", "Move forwards:": "Mover para a frente:", "Move backwards:": "Mover para trás:", "Move left:": "Mover para a esquerda:", "Move right:": "Mover para a direita:", "Rotate left:": "Rodar para a esquerda:", "Rotate right:": "Rodar para a direita:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "A altura editada pode ser alterada usando a seleção de altura no canto inferior esquerdo ou segurando a tecla shift e rolando a roda do mouse. Alternativamente, você pode usar as seguintes teclas do teclado:", "Move up:": "Mover para cima:", "Move down:": "Mover para baixo:", Editing: "Edição", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "As partes da pista podem ser selecionadas no menu à direita e depois podem ser colocadas clicando com o botão esquerdo do mouse.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "Alternativamente, a parte da pista atualmente destacada pelo mouse pode ser selecionada com o seguinte atalho de teclado:", "The selected part can then be rotated using the following keyboard shortcut:": "A parte selecionada pode então ser girada usando o seguinte atalho de teclado:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "As partes da pista podem ser excluídas usando a ferramenta de exclusão no menu lateral direito ou segurando a seguinte tecla:", "Starting points, checkpoints and the finish line": "Pontos de partida, checkpoints e linha de chegada", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "Pontos de partida, checkpoints e linhas de chegada podem ser selecionados na categoria mais alta do menu lateral direito.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Cada pista deve ter pelo menos um ponto de partida. Se houver vários pontos de partida, o último colocado será usado.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "Os checkpoints devem ser colocados entre o ponto de partida e a linha de chegada. Quando uma parte da pista de checkpoint é selecionada, haverá uma ferramenta no canto inferior direito para selecionar a ordem do checkpoint. Isso determina a ordem em que os checkpoints devem ser passados antes de dirigir até a linha de chegada. Observe que é possível ter vários checkpoints com a mesma ordem de checkpoint.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "A linha de chegada é onde a pista termina, mas só se tornará ativa depois que todos os checkpoints forem passados. Também é possível ter várias linhas de chegada.", "Starting point": "Ponto de partida", Checkpoint: "Checkpoint", "Finish line": "Linha de chegada", "Exporting the track": "Exportando a pista", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "Quando a pista estiver pronta, um nome para a pista pode ser inserido no canto superior esquerdo, após o qual a pista pode ser exportada usando o botão de exportação. Isso revelará um código de pista que pode ser enviado para outros usuários para que eles possam importar e jogar a pista.", Close: "Fechar", "Not set": "Não definido", or: "ou", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "A câmera pode ser movida arrastando com um dedo. Rode a câmera arrastando com dois dedos. Aproxime e afaste o zoom beliscando.", "The edited height can be changed by using the height selection in the bottom left corner.": "A altura editada pode ser alterada usando a seleção de altura no canto inferior esquerdo.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "As partes da pista podem ser selecionadas no menu à direita e depois podem ser colocadas tocando na tela.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "A parte selecionada pode então ser girada tocando no botão de rotação no canto inferior esquerdo.", "Track parts can be deleted by using the delete tool in the right side menu.": "As partes da pista podem ser excluídas usando a ferramenta de exclusão no menu lateral direito.", Watch: "Ver", "Loading replay": "A carregar replay", "Press {0} to return to the last checkpoint": "Pressione {0} para voltar ao último checkpoint", "Press {0} to start over": "Pressione {0} para começar de novo", "Reset once to return to the last checkpoint": "Repor uma vez para voltar ao último checkpoint", "Reset again to start over": "Repor novamente para começar de novo", Leaderboard: "Tabela de Classificação", Back: "Voltar", "Error: Failed to load leaderboard": "Erro: Falha ao carregar a tabela de classificação", Pending: "Pendente", Verified: "Verificado", Invalid: "Inválido", Duplicate: "Duplicado", You: "Você", "Only verified": "Apenas verificados", Loading: "A Carregar", "Failed to load recordings": "Falha ao carregar as gravações", "Cannot load recordings due to non-determinism": "Não é possível carregar as gravações devido ao não determinismo", Ok: "Ok", "Track is missing starting point": "A pista não tem ponto de partida", "Some leaderboard features are disabled.": "Algumas funcionalidades da tabela de classificação estão desativadas.", "Please try another browser or device.": "Por favor, tente outro navegador ou dispositivo.", "You already have another instance of PolyTrack open.": "Já tem outra instância do PolyTrack aberta.", "Please switch to that tab or window to continue.": "Por favor, mude para essa aba ou janela para continuar.", "Computer determinism check failed.": "Falha na verificação de determinismo do computador.", "Non-deterministic game assets found.": "Ativos de jogo não determinísticos encontrados.", "Please try clearing your browser cache.": "Por favor, tente limpar o cache do seu navegador.", Customize: "Personalizar", Editor: "Editor", Settings: "Definições", Profile: "Perfil", Play: "Jogar", Version: "Versão", "You cannot have duplicate user profiles": "Não pode ter perfis de utilizador duplicados", "Failed to create user profile": "Falha ao criar o perfil de utilizador", "This user profile does not exist on the server": "Este perfil de utilizador não existe no servidor", "Failed to download user profile from the server": "Falha ao descarregar o perfil de utilizador do servidor", "User token is invalid": "Token de utilizador inválido", "Are you sure you want to display your private key?": "Tem a certeza de que pretende mostrar a sua chave privada?", "DO NOT SHARE THIS KEY WITH ANYONE.": "NÃO PARTILHE ESTA CHAVE COM NINGUÉM.", "You need a free user profile slot to import a new user profile": "Necessita de um slot de perfil de utilizador livre para importar um novo perfil de utilizador", Quit: "Sair", Fullscreen: "Ecrã Inteiro", Windowed: "Janela", " ": "Parece que está a jogar uma versão não oficial de {0}. Para a versão mais atualizada, visite a fonte original:", Nickname: "Alcunha", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Escolha uma alcunha para ser exibida na tabela de classificação. A sua alcunha pode ser alterada a qualquer momento.", Cancel: "Cancelar", Confirm: "Confirmar", Verifier: "Verificador", "User ID": "ID de Utilizador", Paused: "Pausado", "Switch car": "Mudar de carro", Profiles: "Perfis", 'Are you sure you would like to delete "{0}"?': 'Tem a certeza de que pretende eliminar "{0}"?', Empty: "Vazio", Reset: "Repor", Apply: "Aplicar", Gameplay: "Jogabilidade", Units: "Unidades", Metric: "Métrico", Imperial: "Imperial", "Reset hint": "Repor dica", Disabled: "Desativado", Enabled: "Ativado", "Ghost car": "Carro Fantasma", "Default camera": "Câmera Padrão", Default: "Padrão", Cockpit: "Cabine", "Cockpit camera mode": "Modo da câmera de cabine", Hold: "Manter", Toggle: "Alternar", Checkpoints: "Pontos de Verificação", Timer: "Temporizador", Speedometer: "Velocímetro", Bottom: "Inferior", Top: "Superior", Language: "Idioma", Graphics: "Gráficos", "Car shadow": "Sombra do Carro", "Track shadow": "Sombra da Pista", Off: "Desligado", On: "Ligado", Low: "Baixo", Medium: "Médio", High: "Alto", Clouds: "Nuvens", Particles: "Partículas", Skidmarks: "Marcas de Derrapagem", "Render scale": "Escala de Renderização", "Anti-aliasing (requires restart)": "Anti-aliasing (necessita de reiniciar)", Audio: "Áudio", "Sound effect volume": "Volume dos Efeitos Sonoros", "Music volume": "Volume da Música", "Checkpoint volume": "Volume dos Pontos de Verificação", Controls: "Controlos", Vehicle: "Veículo", Accelerate: "Acelerar", Brake: "Travar", "Turn left": "Virar à Esquerda", "Turn right": "Virar à Direita", "Checkpoint reset": "Repor o Ponto de Verificação", "Start reset": "Repor o Início", "Cockpit camera": "Câmera de Cabine", "Rotate part": "Rodar Parte", "Height modifier": "Modificador de Altura", "Delete part": "Eliminar Parte", "Move forwards": "Mover para a frente", "Move backwards": "Mover para trás", "Move left": "Mover para a esquerda", "Move right": "Mover para a direita", "Rotate view up": "Rodar a vista para cima", "Rotate view down": "Rodar a vista para baixo", "Rotate view left": "Rodar a vista para a esquerda", "Rotate view right": "Rodar a vista para a direita", "Move down": "Mover para baixo", "Move up": "Mover para cima", "Test track": "Testar Pista", "Pick part": "Escolher Parte", Spectator: "Espectador", "Speed modifier": "Modificador de Velocidade", Other: "Outro", "Hide UI": "Esconder UI", Pause: "Pausa", "Toggle FPS counter": "Alternar Contador de FPS", "Toggle spectator camera": "Alternar Câmara de Espectador", "Press any key...\n\nPress [Escape] to cancel.": "Pressione qualquer tecla...\n\nPressione [Escape] para cancelar.", Clear: "Limpar", "New record": "Novo Recorde", Record: "Recorde", Current: "Atual", Difference: "Diferença", Copy: "Copiar", Import: "Importar", "Failed to import track": "Falha ao importar a pista", 'The track "{0}" already exists. Do you wish to overwrite it?': 'A pista "{0}" já existe. Deseja substituí-la?', Overwrite: "Substituir", "Paste track data here...": "Cole os dados da pista aqui...", Rank: "Classificação", "Personal best": "Melhor Pessoal", Opponents: "Oponentes", "{0} opponent selected": "{0} oponente selecionado", "{0} opponents selected": "{0} oponentes selecionados", "Select opponents to race against from the leaderboard on the left": "Selecione os oponentes para competir na tabela de classificação à esquerda", "No record": "Sem Registo", "Official tracks": "Pistas Oficiais", "Community tracks": "Pistas da Comunidade", "Custom tracks": "Pistas Personalizadas", 'Are you sure you want to delete "{0}"?': 'Tem a certeza de que deseja eliminar "{0}"?', Delete: "Eliminar", "No community tracks": "Sem pistas da comunidade", "Community tracks are coming soon": "Pistas da comunidade em breve", "No custom tracks": "Sem pistas personalizadas", "Create a track using the editor or import a track code": "Crie uma pista usando o editor ou importe um código de pista", "Search tracks...": "Procurar pistas...", "Invalid replay detected!": "Replay inválido detetado!" }, mz = { "Checkpoint order": "Порядок контрольных точек", Height: "Высота", Exit: "Выход", Random: "Случайный", Primary: "Основной", Secondary: "Вторичный", Frame: "Каркас", Rims: "Диски", "Are you sure you want to exit without saving?": "Вы уверены, что хотите выйти без сохранения?", "All changes will be lost!": "Все изменения будут потеряны!", "Car saved!": "Автомобиль сохранен!", Test: "Тест", "Starting point is missing!": "Отсутствует стартовая точка!", Generate: "Генерировать", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "Вы уверены, что хотите создать новую трассу?\n\nВаша текущая трасса будет потеряна!", Load: "Загрузить", Save: "Сохранить", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "Вы уверены, что хотите загрузить новую трассу?\n\nВаша текущая трасса будет потеряна!", "Track saved!": "Трасса сохранена!", "Failed to save!": "Не удалось сохранить!", 'Are you sure you want to overwrite "{0}"?': 'Вы уверены, что хотите перезаписать "{0}"?', Export: "Экспорт", Help: "Помощь", "Are you sure you want to exit the editor?": "Вы уверены, что хотите выйти из редактора?", "All unsaved data will be lost!": "Все несохраненные данные будут потеряны!", "Track settings": "Настройки трассы", "Unnamed Track": "Безымянная трасса", "Track name": "Имя трассы", Author: "Автор", Unknown: "Неизвестно", Environment: "Окружение", Summer: "Лето", Winter: "Зима", Desert: "Пустыня", "Sun direction": "Направление солнца", "How to use the editor": "Как использовать редактор", "Camera controls": "Управление камерой", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "Камеру можно перемещать, щелкая правой кнопкой мыши и перетаскивая мышь. Вращайте камеру, щелкнув средней кнопкой мыши (колесиком) или удерживая клавишу Ctrl и щелкнув правой кнопкой мыши и перетаскивая мышь. Масштабируйте внутрь и наружу, прокручивая колесико мыши.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "Кроме того, камеру можно управлять с помощью следующих клавиш клавиатуры:", "Move forwards:": "Двигаться вперед:", "Move backwards:": "Двигаться назад:", "Move left:": "Двигаться влево:", "Move right:": "Двигаться вправо:", "Rotate left:": "Повернуть влево:", "Rotate right:": "Повернуть вправо:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "Изменять высоту редактируемой части можно с помощью выбора высоты в левом нижнем углу или удерживая клавишу Shift и прокручивая колесико мыши. Кроме того, можно использовать следующие клавиши клавиатуры:", "Move up:": "Двигаться вверх:", "Move down:": "Двигаться вниз:", Editing: "Редактирование", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "Части трассы можно выбирать в меню справа, после чего их можно размещать, щелкнув левой кнопкой мыши.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "Кроме того, текущую часть трассы, на которую указывает мышь, можно выбрать с помощью следующей комбинации клавиш:", "The selected part can then be rotated using the following keyboard shortcut:": "Выбранную часть можно повернуть с помощью следующей комбинации клавиш:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "Части трассы можно удалять с помощью инструмента удаления в правом меню или удерживая следующую клавишу:", "Starting points, checkpoints and the finish line": "Стартовые точки, контрольные точки и финишная линия", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "Стартовые точки, контрольные точки и финишные линии можно выбрать в верхней категории правого меню.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Каждая трасса должна иметь как минимум одну стартовую точку. Если есть несколько стартовых точек, будет использована последняя размещенная.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "Контрольные точки следует размещать между стартовой точкой и финишной линией. При выборе части трассы контрольной точки в правом нижнем углу появится инструмент для выбора порядка контрольной точки. Это определяет порядок, в котором контрольные точки должны быть пройдены перед движением к финишной линии. Обратите внимание, что возможно наличие нескольких контрольных точек с одним и тем же порядком контрольных точек.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "Финишная линия - это место, где заканчивается трасса, но она становится активной только после прохождения всех контрольных точек. Также возможно наличие нескольких финишных линий.", "Starting point": "Стартовая точка", Checkpoint: "Контрольная точка", "Finish line": "Финишная линия", "Exporting the track": "Экспорт трассы", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "Когда трасса готова, в верхнем левом углу можно ввести имя трассы, после чего трассу можно экспортировать с помощью кнопки экспорта. Это позволит получить код трассы, который можно отправить другим пользователям, чтобы они могли импортировать и играть на трассе.", Close: "Закрыть", "Not set": "Не установлено", or: "или", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "Камеру можно перемещать, перетаскивая одним пальцем. Вращайте камеру, перетаскивая двумя пальцами. Масштабируйте внутрь и наружу, сжимая и разжимая пальцами.", "The edited height can be changed by using the height selection in the bottom left corner.": "Изменять высоту редактируемой части можно с помощью выбора высоты в левом нижнем углу.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "Части трассы можно выбирать в меню справа, после чего их можно размещать, касаясь экрана.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "Выбранную часть можно повернуть, касаясь кнопки поворота в левом нижнем углу.", "Track parts can be deleted by using the delete tool in the right side menu.": "Части трассы можно удалять с помощью инструмента удаления в правом меню.", Watch: "Смотреть", "Loading replay": "Загрузка записи", "Press {0} to return to the last checkpoint": "Нажмите {0}, чтобы вернуться к последней контрольной точке", "Press {0} to start over": "Нажмите {0}, чтобы начать заново", "Reset once to return to the last checkpoint": "Сбросьте один раз, чтобы вернуться к последней контрольной точке", "Reset again to start over": "Сбросьте еще раз, чтобы начать заново", Leaderboard: "Таблица лидеров", Back: "Назад", "Error: Failed to load leaderboard": "Ошибка: не удалось загрузить таблицу лидеров", Pending: "В ожидании", Verified: "Подтверждено", Invalid: "Недействительно", Duplicate: "Дубликат", You: "Вы", "Only verified": "Только подтвержденные", Loading: "Загрузка", "Failed to load recordings": "Не удалось загрузить записи", "Cannot load recordings due to non-determinism": "Невозможно загрузить записи из-за недетерминизма", Ok: "Ок", "Track is missing starting point": "Отсутствует стартовая точка на трассе", "Some leaderboard features are disabled.": "Некоторые функции таблицы лидеров отключены.", "Please try another browser or device.": "Пожалуйста, попробуйте другой браузер или устройство.", "You already have another instance of PolyTrack open.": "У вас уже открыт другой экземпляр PolyTrack.", "Please switch to that tab or window to continue.": "Пожалуйста, переключитесь на эту вкладку или окно, чтобы продолжить.", "Computer determinism check failed.": "Проверка детерминизма компьютера не удалась.", "Non-deterministic game assets found.": "Недетерминированные игровые ресурсы найдены.", "Please try clearing your browser cache.": "Пожалуйста, попробуйте очистить кеш браузера.", Customize: "Настройка", Editor: "Редактор", Settings: "Настройки", Profile: "Профиль", Play: "Играть", Version: "Версия", "You cannot have duplicate user profiles": "Нельзя иметь дублирующиеся профили пользователей", "Failed to create user profile": "Не удалось создать профиль пользователя", "This user profile does not exist on the server": "Этот профиль пользователя не существует на сервере", "Failed to download user profile from the server": "Не удалось загрузить профиль пользователя с сервера", "User token is invalid": "Недействительный токен пользователя", "Are you sure you want to display your private key?": "Вы уверены, что хотите отобразить свой личный ключ?", "DO NOT SHARE THIS KEY WITH ANYONE.": "НЕ ДЕЛИТЕСЬ ЭТИМ КЛЮЧОМ НИ С КЕМ.", "You need a free user profile slot to import a new user profile": "Вам нужен свободный слот профиля пользователя для импорта нового профиля пользователя", Quit: "Выйти", Fullscreen: "Полноэкранный", Windowed: "Оконный", " ": "Похоже, вы играете в неофициальную версию {0}. Для самой актуальной версии посетите оригинальный источник:", Nickname: "Никнейм", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Выберите никнейм, который будет отображаться в таблице лидеров. Вы можете изменить никнейм в любое время.", Cancel: "Отмена", Confirm: "Подтвердить", Verifier: "Подтверждающий", "User ID": "Идентификатор пользователя", Paused: "Пауза", "Switch car": "Сменить автомобиль", Profiles: "Профили", 'Are you sure you would like to delete "{0}"?': 'Вы уверены, что хотите удалить "{0}"?', Empty: "Пусто", Reset: "Сброс", Apply: "Применить", Gameplay: "Игровой процесс", Units: "Единицы измерения", Metric: "Метрическая", Imperial: "Имперская", "Reset hint": "Сбросить подсказку", Disabled: "Выключено", Enabled: "Включено", "Ghost car": "Призрачная машина", "Default camera": "Камера по умолчанию", Default: "По умолчанию", Cockpit: "Кабина", "Cockpit camera mode": "Режим кабины", Hold: "Удерживать", Toggle: "Переключить", Checkpoints: "Контрольные точки", Timer: "Таймер", Speedometer: "Спидометр", Bottom: "Снизу", Top: "Сверху", Language: "Язык", Graphics: "Графика", "Car shadow": "Тень автомобиля", "Track shadow": "Тень трассы", Off: "Выключено", On: "Включено", Low: "Низкая", Medium: "Средняя", High: "Высокая", Clouds: "Облака", Particles: "Частицы", Skidmarks: "Отметины от скольжения", "Render scale": "Масштаб рендера", "Anti-aliasing (requires restart)": "Сглаживание (требуется перезапуск)", Audio: "Звук", "Sound effect volume": "Громкость звуковых эффектов", "Music volume": "Громкость музыки", "Checkpoint volume": "Громкость контрольных точек", Controls: "Управление", Vehicle: "Транспорт", Accelerate: "Ускорить", Brake: "Тормоз", "Turn left": "Повернуть налево", "Turn right": "Повернуть направо", "Checkpoint reset": "Сброс контрольной точки", "Start reset": "Сброс старта", "Cockpit camera": "Камера кабины", "Rotate part": "Повернуть часть", "Height modifier": "Модификатор высоты", "Delete part": "Удалить часть", "Move forwards": "Двигаться вперед", "Move backwards": "Двигаться назад", "Move left": "Двигаться влево", "Move right": "Двигаться вправо", "Rotate view up": "Повернуть вид вверх", "Rotate view down": "Повернуть вид вниз", "Rotate view left": "Повернуть вид влево", "Rotate view right": "Повернуть вид вправо", "Move down": "Двигаться вниз", "Move up": "Двигаться вверх", "Test track": "Тестировать трассу", "Pick part": "Выбрать часть", Spectator: "Наблюдатель", "Speed modifier": "Модификатор скорости", Other: "Другое", "Hide UI": "Скрыть интерфейс", Pause: "Пауза", "Toggle FPS counter": "Переключить счетчик FPS", "Toggle spectator camera": "Переключить камеру наблюдателя", "Press any key...\n\nPress [Escape] to cancel.": "Нажмите любую клавишу...\n\nНажмите [Escape], чтобы отменить.", Clear: "Очистить", "New record": "Новый рекорд", Record: "Рекорд", Current: "Текущее", Difference: "Разница", Copy: "Копировать", Import: "Импортировать", "Failed to import track": "Не удалось импортировать трассу", 'The track "{0}" already exists. Do you wish to overwrite it?': 'Трасса "{0}" уже существует. Хотите перезаписать её?', Overwrite: "Перезаписать", "Paste track data here...": "Вставьте данные трассы сюда...", Rank: "Ранг", "Personal best": "Личный рекорд", Opponents: "Противники", "{0} opponent selected": "{0} противник выбран", "{0} opponents selected": "{0} противников выбрано", "Select opponents to race against from the leaderboard on the left": "Выберите противников для гонки из таблицы лидеров слева", "No record": "Нет рекорда", "Official tracks": "Официальные трассы", "Community tracks": "Трассы сообщества", "Custom tracks": "Пользовательские трассы", 'Are you sure you want to delete "{0}"?': 'Вы уверены, что хотите удалить "{0}"?', Delete: "Удалить", "No community tracks": "Нет трасс сообщества", "Community tracks are coming soon": "Трассы сообщества скоро появятся", "No custom tracks": "Нет пользовательских трасс", "Create a track using the editor or import a track code": "Создайте трассу с помощью редактора или импортируйте код трассы", "Search tracks...": "Поиск трасс...", "Invalid replay detected!": "Обнаружена недействительная запись!" }, gz = { "Checkpoint order": "Kontrol noktası sırası", Height: "Yükseklik", Exit: "Çıkış", Random: "Rastgele", Primary: "Birincil", Secondary: "İkincil", Frame: "Çerçeve", Rims: "Jantlar", "Are you sure you want to exit without saving?": "Kaydetmeden çıkmak istediğinizden emin misiniz?", "All changes will be lost!": "Tüm değişiklikler kaybolacak!", "Car saved!": "Araba kaydedildi!", Test: "Test", "Starting point is missing!": "Başlangıç noktası eksik!", Generate: "Oluştur", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "Yeni bir rota oluşturmak istediğinizden emin misiniz?\n\nMevcut rotanız kaybolacak!", Load: "Yükle", Save: "Kaydet", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "Yeni bir rota yüklemek istediğinizden emin misiniz?\n\nMevcut rotanız kaybolacak!", "Track saved!": "Rota kaydedildi!", "Failed to save!": "Kaydetme başarısız!", 'Are you sure you want to overwrite "{0}"?': '"{0}" üzerine yazmak istediğinizden emin misiniz?', Export: "Dışa Aktar", Help: "Yardım", "Are you sure you want to exit the editor?": "Editörden çıkmak istediğinizden emin misiniz?", "All unsaved data will be lost!": "Tüm kaydedilmemiş veriler kaybolacak!", "Track settings": "Rota ayarları", "Unnamed Track": "Adsız Rota", "Track name": "Rota adı", Author: "Yazar", Unknown: "Bilinmiyor", Environment: "Çevre", Summer: "Yaz", Winter: "Kış", Desert: "Çöl", "Sun direction": "Güneş yönü", "How to use the editor": "Editörü nasıl kullanılır", "Camera controls": "Kamera kontrolleri", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "Kamerayı sağ tıklayarak ve fareyi sürükleyerek hareket ettirebilirsiniz. Kamerayı orta fare düğmesine (fare tekerleği) tıklayarak veya kontrol tuşunu basılı tutarak sağ tıklayarak ve fareyi sürükleyerek döndürebilirsiniz. Fare tekerleği ile yakınlaştırma ve uzaklaştırma yapabilirsiniz.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "Alternatif olarak, kamera aşağıdaki klavye tuşları kullanılarak da kontrol edilebilir:", "Move forwards:": "İleri hareket et:", "Move backwards:": "Geri hareket et:", "Move left:": "Sola hareket et:", "Move right:": "Sağa hareket et:", "Rotate left:": "Sola döndür:", "Rotate right:": "Sağa döndür:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "Düzenlenen yükseklik, sol alt köşedeki yükseklik seçimini kullanarak veya Shift tuşunu basılı tutarak ve fare tekerleğini kaydırarak değiştirilebilir. Alternatif olarak, aşağıdaki klavye tuşlarını kullanabilirsiniz:", "Move up:": "Yukarı hareket et:", "Move down:": "Aşağı hareket et:", Editing: "Düzenleme", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "Parçalar, fareyle sol tıklayarak yerleştirilebilecekleri sağ taraftaki menüden seçilebilir.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "Alternatif olarak, fare tarafından üzerine gelinen rota parçası aşağıdaki klavye kısayoluyla seçilebilir:", "The selected part can then be rotated using the following keyboard shortcut:": "Seçilen parça aşağıdaki klavye kısayoluyla döndürülebilir:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "Rota parçaları, sağ taraftaki menüdeki silme aracı kullanılarak veya aşağıdaki tuşa basılı tutarak silinebilir:", "Starting points, checkpoints and the finish line": "Başlangıç noktaları, kontrol noktaları ve bitiş çizgisi", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "Başlangıç noktaları, kontrol noktaları ve bitiş çizgileri, sağ taraftaki menünün en üst kategorisinde seçilebilir.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Her rota en az bir başlangıç noktasına sahip olmalıdır. Birden fazla başlangıç noktası varsa, en son yerleştirilen kullanılacaktır.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "Kontrol noktaları, başlangıç noktası ile bitiş çizgisi arasına yerleştirilmelidir. Bir kontrol noktası rota parçası seçildiğinde, kontrol noktasının sırasını seçmek için sağ alt köşede bir araç bulunur. Bu, kontrol noktalarının bitiş çizgisine gitmeden önce geçilmesi gereken sırayı belirler. Aynı kontrol noktası sırasına sahip birden fazla kontrol noktası olabileceğine dikkat edin.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "Bitiş çizgisi, rotanın bittiği yerdir, ancak tüm kontrol noktaları geçildikten sonra aktif hale gelir. Birden fazla bitiş çizgisi de olabilir.", "Starting point": "Başlangıç noktası", Checkpoint: "Kontrol noktası", "Finish line": "Bitiş çizgisi", "Exporting the track": "Rotanın dışa aktarılması", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "Rota tamamlandığında, rota için bir ad girilebilir ve ardından rota düğmesini kullanarak rota dışa aktarılabilir. Bu, diğer kullanıcılara gönderilebilecek bir rota kodunu ortaya çıkarır, böylece rota içe aktarılabilir ve oynanabilir.", Close: "Kapat", "Not set": "Ayarlanmadı", or: "veya", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "Kamerayı bir parmakla sürükleyerek hareket ettirebilirsiniz. Kamerayı iki parmakla sürükleyerek döndürebilirsiniz. Yakınlaştırmak ve uzaklaştırmak için sıkıştırabilirsiniz.", "The edited height can be changed by using the height selection in the bottom left corner.": "Düzenlenen yükseklik, sol alt köşedeki yükseklik seçimi kullanılarak değiştirilebilir.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "Parçalar, ekrana dokunarak yerleştirilebilecekleri sağ taraftaki menüden seçilebilir.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "Seçilen parça, sol alt köşedeki döndür düğmesine dokunarak döndürülebilir.", "Track parts can be deleted by using the delete tool in the right side menu.": "Parçalar, sağ taraftaki menüdeki silme aracı kullanılarak silinebilir.", Watch: "İzle", "Loading replay": "Tekrar yükleniyor", "Press {0} to return to the last checkpoint": "Son kontrol noktasına dönmek için {0} tuşuna basın", "Press {0} to start over": "Baştan başlamak için {0} tuşuna basın", "Reset once to return to the last checkpoint": "Son kontrol noktasına dönmek için bir kez sıfırlayın", "Reset again to start over": "Baştan başlamak için tekrar sıfırlayın", Leaderboard: "Liderlik Tablosu", Back: "Geri", "Error: Failed to load leaderboard": "Hata: Liderlik tablosu yüklenemedi", Pending: "Beklemede", Verified: "Doğrulandı", Invalid: "Geçersiz", Duplicate: "Çift", You: "Sen", "Only verified": "Sadece doğrulanmış", Loading: "Yükleniyor", "Failed to load recordings": "Kayıtlar yüklenemedi", "Cannot load recordings due to non-determinism": "Belirlenim dışılıktan dolayı kayıtlar yüklenemiyor", Ok: "Tamam", "Track is missing starting point": "Rota başlangıç noktası eksik", "Some leaderboard features are disabled.": "Bazı liderlik tablosu özellikleri devre dışı bırakıldı.", "Please try another browser or device.": "Lütfen başka bir tarayıcı veya cihaz deneyin.", "You already have another instance of PolyTrack open.": "Zaten PolyTrack'in başka bir örneğini açtınız.", "Please switch to that tab or window to continue.": "Devam etmek için lütfen o sekmeye veya pencereye geçin.", "Computer determinism check failed.": "Bilgisayar belirlenim kontrolü başarısız oldu.", "Non-deterministic game assets found.": "Belirlenim dışı oyun varlıkları bulundu.", "Please try clearing your browser cache.": "Lütfen tarayıcı önbelleğinizi temizlemeyi deneyin.", Customize: "Özelleştir", Editor: "Editör", Settings: "Ayarlar", Profile: "Profil", Play: "Oyna", Version: "Sürüm", "You cannot have duplicate user profiles": "Çift kullanıcı profili oluşturamazsınız", "Failed to create user profile": "Kullanıcı profili oluşturulamadı", "This user profile does not exist on the server": "Bu kullanıcı profili sunucuda mevcut değil", "Failed to download user profile from the server": "Kullanıcı profili sunucudan indirilemedi", "User token is invalid": "Kullanıcı belirteci geçersiz", "Are you sure you want to display your private key?": "Gizli anahtarınızı göstermek istediğinizden emin misiniz?", "DO NOT SHARE THIS KEY WITH ANYONE.": "BU ANAHTARI KİMSEYLE PAYLAŞMAYIN.", "You need a free user profile slot to import a new user profile": "Yeni bir kullanıcı profili eklemek için boş bir kullanıcı profili yuvasına ihtiyacınız var", Quit: "Çıkış", Fullscreen: "Tam Ekran", Windowed: "Pencere Modu", " ": "{0} adlı resmi olmayan bir sürüm oynuyor gibi görünüyorsunuz. En güncel sürüm için lütfen orijinal kaynağı ziyaret edin:", Nickname: "Kullanıcı Adı", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Liderlik tablosunda gösterilecek bir kullanıcı adı seçin. Kullanıcı adınızı istediğiniz zaman değiştirebilirsiniz.", Cancel: "İptal", Confirm: "Onayla", Verifier: "Doğrulayıcı", "User ID": "Kullanıcı Kimliği", Paused: "Duraklatıldı", "Switch car": "Araba değiştir", Profiles: "Profiller", 'Are you sure you would like to delete "{0}"?': '"{0}" silmek istediğinizden emin misiniz?', Empty: "Boş", Reset: "Sıfırla", Apply: "Uygula", Gameplay: "Oynanış", Units: "Birimler", Metric: "Metrik", Imperial: "İngiliz", "Reset hint": "İpucunu sıfırla", Disabled: "Devre Dışı", Enabled: "Etkin", "Ghost car": "Hayalet araba", "Default camera": "Varsayılan kamera", Default: "Varsayılan", Cockpit: "Kokpit", "Cockpit camera mode": "Kokpit kamera modu", Hold: "Basılı Tut", Toggle: "Değiştir", Checkpoints: "Kontrol Noktaları", Timer: "Zamanlayıcı", Speedometer: "Hızölçer", Bottom: "Alt", Top: "Üst", Language: "Dil", Graphics: "Grafikler", "Car shadow": "Araba gölgesi", "Track shadow": "Rota gölgesi", Off: "Kapalı", On: "Açık", Low: "Düşük", Medium: "Orta", High: "Yüksek", Clouds: "Bulutlar", Particles: "Partiküller", Skidmarks: "Lastik izleri", "Render scale": "Görüntü ölçeği", "Anti-aliasing (requires restart)": "Kenar yumuşatma (yeniden başlatma gerektirir)", Audio: "Ses", "Sound effect volume": "Ses efekti ses seviyesi", "Music volume": "Müzik ses seviyesi", "Checkpoint volume": "Kontrol noktası ses seviyesi", Controls: "Kontroller", Vehicle: "Araç", Accelerate: "Hızlan", Brake: "Fren", "Turn left": "Sola dön", "Turn right": "Sağa dön", "Checkpoint reset": "Kontrol noktası sıfırla", "Start reset": "Başlangıç sıfırla", "Cockpit camera": "Kokpit kamera", "Rotate part": "Parçayı döndür", "Height modifier": "Yükseklik değiştir", "Delete part": "Parçayı sil", "Move forwards": "İleri git", "Move backwards": "Geri git", "Move left": "Sola git", "Move right": "Sağa git", "Rotate view up": "Görünümü yukarı döndür", "Rotate view down": "Görünümü aşağı döndür", "Rotate view left": "Görünümü sola döndür", "Rotate view right": "Görünümü sağa döndür", "Move down": "Aşağı git", "Move up": "Yukarı git", "Test track": "Rota test et", "Pick part": "Parça seç", Spectator: "Seyirci", "Speed modifier": "Hız değiştir", Other: "Diğer", "Hide UI": "UI'yi gizle", Pause: "Duraklat", "Toggle FPS counter": "FPS sayacını değiştir", "Toggle spectator camera": "Seyirci kamerasını değiştir", "Press any key...\n\nPress [Escape] to cancel.": "Herhangi bir tuşa basın...\n\nİptal etmek için [Escape] tuşuna basın", Clear: "Temizle", "New record": "Yeni kayıt", Record: "Kayıt", Current: "Mevcut", Difference: "Fark", Copy: "Kopyala", Import: "İçe Aktar", "Failed to import track": "Rota içe aktarma başarısız oldu", 'The track "{0}" already exists. Do you wish to overwrite it?': '"{0}" rota zaten var. Üzerine yazmak istiyor musunuz?', Overwrite: "Üzerine yaz", "Paste track data here...": "Rota verilerini buraya yapıştır...", Rank: "Sıra", "Personal best": "Kişisel en iyi", Opponents: "Rakipler", "{0} opponent selected": "{0} rakip seçildi", "{0} opponents selected": "{0} rakip seçildi", "Select opponents to race against from the leaderboard on the left": "Soldaki liderlik tablosundan yarışmak için rakipleri seçin", "No record": "Kayıt yok", "Official tracks": "Resmi rotalar", "Community tracks": "Topluluk rotaları", "Custom tracks": "Özel rotalar", 'Are you sure you want to delete "{0}"?': '"{0}" silmek istediğinizden emin misiniz?', Delete: "Sil", "No community tracks": "Topluluk rotası yok", "Community tracks are coming soon": "Topluluk rotaları yakında gelecek", "No custom tracks": "Özel rotalar yok", "Create a track using the editor or import a track code": "Editörü kullanarak bir rota oluşturun veya bir rota kodu içe aktarın", "Search tracks...": "Rotayı ara...", "Invalid replay detected!": "Geçersiz tekrar algılandı!" }, vz = { "Checkpoint order": "Порядок пунктів контролю", Height: "Висота", Exit: "Вихід", Random: "Випадково", Primary: "Основний", Secondary: "Додатковий", Frame: "Рама", Rims: "Дисків", "Are you sure you want to exit without saving?": "Ви впевнені, що хочете вийти без збереження?", "All changes will be lost!": "Всі зміни будуть втрачені!", "Car saved!": "Автомобіль збережено!", Test: "Тест", "Starting point is missing!": "Відсутня стартова точка!", Generate: "Генерувати", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "Ви впевнені, що хочете згенерувати новий трек?\n\nВаш поточний трек буде втрачено!", Load: "Завантажити", Save: "Зберегти", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "Ви впевнені, що хочете завантажити новий трек?\n\nВаш поточний трек буде втрачено!", "Track saved!": "Трек збережено!", "Failed to save!": "Не вдалося зберегти!", 'Are you sure you want to overwrite "{0}"?': 'Ви впевнені, що хочете перезаписати "{0}"?', Export: "Експорт", Help: "Довідка", "Are you sure you want to exit the editor?": "Ви впевнені, що хочете вийти з редактора?", "All unsaved data will be lost!": "Всі не збережені дані будуть втрачені!", "Track settings": "Налаштування треку", "Unnamed Track": "Безіменний трек", "Track name": "Назва треку", Author: "Автор", Unknown: "Невідомий", Environment: "Середовище", Summer: "Літо", Winter: "Зима", Desert: "Пустеля", "Sun direction": "Напрямок сонця", "How to use the editor": "Як користуватися редактором", "Camera controls": "Управління камерою", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "Камеру можна переміщувати, натискаючи праву кнопку миші і перетягуючи її. Повертайте камеру, натискаючи середню кнопку миші (колесо миші) або утримуючи клавішу Control і натискаючи праву кнопку миші і перетягуючи її. Збільшуйте та зменшуйте масштаб, прокручуючи колесо миші.", "Alternatively, the camera can also be controlled using the following keyboard keys:": "Також камеру можна керувати за допомогою наступних клавіш на клавіатурі:", "Move forwards:": "Рухатися вперед:", "Move backwards:": "Рухатися назад:", "Move left:": "Рухатися вліво:", "Move right:": "Рухатися вправо:", "Rotate left:": "Повернути вліво:", "Rotate right:": "Повернути вправо:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "Редаговану висоту можна змінити, використовуючи вибір висоти в нижньому лівому куті або утримуючи клавішу Shift і прокручуючи колесо миші. Альтернативно, ви можете використовувати наступні клавіші на клавіатурі:", "Move up:": "Рухатися вгору:", "Move down:": "Рухатися вниз:", Editing: "Редагування", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "Частини треку можна вибрати в меню справа, після чого їх можна розмістити, натиснувши ліву кнопку миші.", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "Альтернативно, частину треку, над якою зараз знаходиться курсор миші, можна вибрати за допомогою наступної комбінації клавіш на клавіатурі:", "The selected part can then be rotated using the following keyboard shortcut:": "Вибрану частину можна повернути за допомогою наступної комбінації клавіш на клавіатурі:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "Частини треку можна видалити, використовуючи інструмент видалення в бічному меню справа або утримуючи наступну клавішу:", "Starting points, checkpoints and the finish line": "Стартові точки, контрольні пункти та фінішна лінія", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "Стартові точки, контрольні пункти та фінішна лінія можуть бути вибрані в найвищій категорії в бічному меню справа.", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "Кожен трек повинен мати принаймні одну стартову точку. Якщо є кілька стартових точок, буде використана остання розміщена.", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "Контрольні пункти слід розміщувати між стартовою точкою та фінішною лінією. Коли вибрана частина треку контрольного пункту, внизу справа з'явиться інструмент для вибору порядку контрольного пункту. Це визначає порядок, в якому контрольні пункти повинні бути пройдені перед рухом до фінішної лінії. Зверніть увагу, що можливо мати кілька контрольних пунктів з однаковим порядком контрольних пунктів.", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "Фінішна лінія - це місце, де закінчується трек, але вона стане активною лише після проходження всіх контрольних пунктів. Також можливо мати кілька фінішних ліній.", "Starting point": "Стартова точка", Checkpoint: "Контрольний пункт", "Finish line": "Фінішна лінія", "Exporting the track": "Експорт треку", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "Коли трек готовий, вгорі зліва можна ввести назву треку, після чого трек можна експортувати, використовуючи кнопку експорту. Це розкриє код треку, який можна надіслати іншим користувачам, щоб вони могли імпортувати й грати трек.", Close: "Закрити", "Not set": "Не встановлено", or: "або", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "Камеру можна переміщувати, перетягуючи одним пальцем. Повертайте камеру, перетягуючи двома пальцями. Збільшуйте та зменшуйте масштаб, стискаючи пальці.", "The edited height can be changed by using the height selection in the bottom left corner.": "Редаговану висоту можна змінити, використовуючи вибір висоти в нижньому лівому куті.", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "Частини треку можна вибрати в меню справа, після чого їх можна розмістити, натиснувши на екран.", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "Вибрану частину можна повернути, натиснувши кнопку повороту в нижньому лівому куті.", "Track parts can be deleted by using the delete tool in the right side menu.": "Частини треку можна видалити, використовуючи інструмент видалення в бічному меню справа.", Watch: "Перегляд", "Loading replay": "Завантаження повтору", "Press {0} to return to the last checkpoint": "Натисніть {0}, щоб повернутися до останнього контрольного пункту", "Press {0} to start over": "Натисніть {0}, щоб почати спочатку", "Reset once to return to the last checkpoint": "Скинути один раз, щоб повернутися до останнього контрольного пункту", "Reset again to start over": "Скинути ще раз, щоб почати спочатку", Leaderboard: "Таблиця лідерів", Back: "Назад", "Error: Failed to load leaderboard": "Помилка: не вдалося завантажити таблицю лідерів", Pending: "Очікує на підтвердження", Verified: "Підтверджено", Invalid: "Недійсний", Duplicate: "Дубльований", You: "Ви", "Only verified": "Тільки підтверджені", Loading: "Завантаження", "Failed to load recordings": "Не вдалося завантажити записи", "Cannot load recordings due to non-determinism": "Не вдається завантажити записи через недетермінізм", Ok: "Ок", "Track is missing starting point": "В треку відсутня стартова точка", "Some leaderboard features are disabled.": "Деякі функції таблиці лідерів вимкнені.", "Please try another browser or device.": "Будь ласка, спробуйте інший браузер або пристрій.", "You already have another instance of PolyTrack open.": "У вас вже є інший екземпляр PolyTrack відкритий.", "Please switch to that tab or window to continue.": "Будь ласка, перейдіть на ту вкладку або вікно, щоб продовжити.", "Computer determinism check failed.": "Перевірка детермінізму комп'ютера не вдалася.", "Non-deterministic game assets found.": "Знайдено недетерміністичні ігрові ресурси.", "Please try clearing your browser cache.": "Спробуйте очистити кеш браузера.", Customize: "Налаштувати", Editor: "Редактор", Settings: "Налаштування", Profile: "Профіль", Play: "Грати", Version: "Версія", "You cannot have duplicate user profiles": "Ви не можете мати дубльовані профілі користувачів", "Failed to create user profile": "Не вдалося створити профіль користувача", "This user profile does not exist on the server": "Цей профіль користувача не існує на сервері", "Failed to download user profile from the server": "Не вдалося завантажити профіль користувача з сервера", "User token is invalid": "Недійсний токен користувача", "Are you sure you want to display your private key?": "Ви впевнені, що хочете відобразити свій приватний ключ?", "DO NOT SHARE THIS KEY WITH ANYONE.": "НЕ ДІЛІТЬСЯ ЦИМ КЛЮЧЕМ З КИМБУДЬ.", "You need a free user profile slot to import a new user profile": "Вам потрібен вільний слот профілю користувача для імпорту нового профілю користувача", Quit: "Вийти", Fullscreen: "Повноекранний", Windowed: "У вікні", " ": "Здається, ви граєте в неофіційну версію {0}. Для найновішої версії відвідайте оригінальне джерело:", Nickname: "Псевдонім", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "Виберіть псевдонім для відображення в таблиці лідерів. Ви можете змінити псевдонім в будь-який час.", Cancel: "Скасувати", Confirm: "Підтвердити", Verifier: "Підтверджувач", "User ID": "ID користувача", Paused: "Пауза", "Switch car": "Перемикання автомобіля", Profiles: "Профілі", 'Are you sure you would like to delete "{0}"?': 'Ви впевнені, що хочете видалити "{0}"?', Empty: "Порожній", Reset: "Скинути", Apply: "Застосувати", Gameplay: "Ігровий процес", Units: "Одиниці вимірювання", Metric: "Метричні", Imperial: "Імперські", "Reset hint": "Скинути підказку", Disabled: "Вимкнено", Enabled: "Увімкнено", "Ghost car": "Привид автомобіля", "Default camera": "Камера за замовчуванням", Default: "За замовчуванням", Cockpit: "Кабіна кокпіту", "Cockpit camera mode": "Режим кабіни кокпіту", Hold: "Тримати", Toggle: "Перемикання", Checkpoints: "Контрольні пункти", Timer: "Таймер", Speedometer: "Спідометр", Bottom: "Знизу", Top: "Зверху", Language: "Мова", Graphics: "Графіка", "Car shadow": "Тінь автомобіля", "Track shadow": "Тінь треку", Off: "Вимкнено", On: "Увімкнено", Low: "Низькі", Medium: "Середні", High: "Високі", Clouds: "Хмари", Particles: "Частинки", Skidmarks: "Сліди", "Render scale": "Масштаб рендерингу", "Anti-aliasing (requires restart)": "Антиаліасинг (потребує перезапуску)", Audio: "Звук", "Sound effect volume": "Гучність звукових ефектів", "Music volume": "Гучність музики", "Checkpoint volume": "Гучність пунктів контролю", Controls: "Управління", Vehicle: "Транспортний засіб", Accelerate: "Прискорити", Brake: "Гальмо", "Turn left": "Повернути ліворуч", "Turn right": "Повернути праворуч", "Checkpoint reset": "Скидання контрольної точки", "Start reset": "Скидання старту", "Cockpit camera": "Камера кабіни кокпіту", "Rotate part": "Повернути частину", "Height modifier": "Модифікатор висоти", "Delete part": "Видалити частину", "Move forwards": "Рухатися вперед", "Move backwards": "Рухатися назад", "Move left": "Рухатися вліво", "Move right": "Рухатися вправо", "Rotate view up": "Повернути вид вгору", "Rotate view down": "Повернути вид вниз", "Rotate view left": "Повернути вид вліво", "Rotate view right": "Повернути вид вправо", "Move down": "Рухатися вниз", "Move up": "Рухатися вгору", "Test track": "Тестовий трек", "Pick part": "Вибрати частину", Spectator: "Спостерігач", "Speed modifier": "Модифікатор швидкості", Other: "Інше", "Hide UI": "Приховати інтерфейс", Pause: "Пауза", "Toggle FPS counter": "Перемикання лічильника FPS", "Toggle spectator camera": "Перемикання камери спостерігача", "Press any key...\n\nPress [Escape] to cancel.": "Натисніть будь-яку клавішу...\n\nНатисніть [Escape], щоб скасувати.", Clear: "Очистити", "New record": "Новий рекорд", Record: "Рекорд", Current: "Поточний", Difference: "Різниця", Copy: "Копіювати", Import: "Імпортувати", "Failed to import track": "Не вдалося імпортувати трек", 'The track "{0}" already exists. Do you wish to overwrite it?': 'Трек "{0}" вже існує. Бажаєте перезаписати його?', Overwrite: "Перезаписати", "Paste track data here...": "Вставте дані треку сюди...", Rank: "Ранг", "Personal best": "Особистий рекорд", Opponents: "Супротивники", "{0} opponent selected": "{0} супротивник вибраний", "{0} opponents selected": "{0} супротивників вибрано", "Select opponents to race against from the leaderboard on the left": "Виберіть супротивників для гонки з таблиці лідерів зліва", "No record": "Немає записів", "Official tracks": "Офіційні треки", "Community tracks": "Спільнота треків", "Custom tracks": "Власні треки", 'Are you sure you want to delete "{0}"?': 'Ви впевнені, що хочете видалити "{0}"?', Delete: "Видалити", "No community tracks": "Спільнота треків відсутня", "Community tracks are coming soon": "Спільнота треків незабаром", "No custom tracks": "Власні треки відсутні", "Create a track using the editor or import a track code": "Створіть трек за допомогою редактора або імпортуйте код треку", "Search tracks...": "Пошук треків...", "Invalid replay detected!": "Виявлено недійсний повтор!" }, wz = { "Checkpoint order": "检查点顺序", Height: "高度", Exit: "退出", Random: "随机", Primary: "主要", Secondary: "次要", Frame: "框架", Rims: "轮辋", "Are you sure you want to exit without saving?": "确定要退出而不保存吗?", "All changes will be lost!": "所有更改将丢失!", "Car saved!": "车辆已保存!", Test: "测试", "Starting point is missing!": "起点缺失!", Generate: "生成", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "确定要生成新赛道吗?\n\n当前赛道将丢失!", Load: "加载", Save: "保存", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "确定要加载新赛道吗?\n\n当前赛道将丢失!", "Track saved!": "赛道已保存!", "Failed to save!": "保存失败!", 'Are you sure you want to overwrite "{0}"?': '确定要覆盖 "{0}" 吗?', Export: "导出", Help: "帮助", "Are you sure you want to exit the editor?": "确定要退出编辑器吗?", "All unsaved data will be lost!": "所有未保存的数据将丢失!", "Track settings": "赛道设置", "Unnamed Track": "未命名赛道", "Track name": "赛道名称", Author: "作者", Unknown: "未知", Environment: "环境", Summer: "夏季", Winter: "冬季", Desert: "沙漠", "Sun direction": "太阳方向", "How to use the editor": "如何使用编辑器", "Camera controls": "相机控制", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "可以通过右键单击并拖动鼠标来移动相机。通过单击中间鼠标按钮(鼠标滚轮)或按住Ctrl键并右键单击并拖动鼠标来旋转相机。通过滚动鼠标滚轮进行缩放。", "Alternatively, the camera can also be controlled using the following keyboard keys:": "或者,还可以使用以下键盘按键来控制相机:", "Move forwards:": "向前移动:", "Move backwards:": "向后移动:", "Move left:": "向左移动:", "Move right:": "向右移动:", "Rotate left:": "向左旋转:", "Rotate right:": "向右旋转:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "可以通过使用左下角的高度选择器来更改编辑的高度,也可以按住Shift键并滚动鼠标滚轮。或者,您可以使用以下键盘按键:", "Move up:": "向上移动:", "Move down:": "向下移动:", Editing: "编辑", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "可以在右侧菜单中选择轨道部件,然后可以使用鼠标左键单击放置。", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "或者,可以使用以下键盘快捷键选择当前鼠标悬停的轨道部件:", "The selected part can then be rotated using the following keyboard shortcut:": "然后可以使用以下键盘快捷键旋转所选部件:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "可以使用右侧菜单中的删除工具或按住以下键来删除轨道部件:", "Starting points, checkpoints and the finish line": "起点、检查点和终点", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "起点、检查点和终点都可以在右侧菜单的最上方类别中选择。", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "每个赛道必须至少有一个起点。如果有多个起点,则将使用最后放置的起点。", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "检查点应该放置在起点和终点之间。当选择检查点轨道部件时,底部右侧将有一个工具来选择检查点的顺序。这决定了在驶向终点之前必须通过检查点的顺序。请注意,可以有多个具有相同检查点顺序的检查点。", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "终点是赛道结束的地方,但只有在通过所有检查点后才会变为活动状态。也可以有多个终点。", "Starting point": "起点", Checkpoint: "检查点", "Finish line": "终点", "Exporting the track": "导出赛道", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "当赛道完成后,可以在左上角输入赛道名称,然后可以使用导出按钮导出赛道。这将显示一个赛道代码,可以将其发送给其他用户,以便他们可以导入和播放赛道。", Close: "关闭", "Not set": "未设置", or: "或", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "相机可以通过用一根手指拖动来移动。通过用两根手指拖动来旋转相机。通过捏合来放大和缩小。", "The edited height can be changed by using the height selection in the bottom left corner.": "可以通过使用左下角的高度选择器来更改编辑的高度。", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "可以在右侧菜单中选择轨道部件,然后可以通过点击屏幕来放置。", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "然后可以通过点击左下角的旋转按钮来旋转所选部件。", "Track parts can be deleted by using the delete tool in the right side menu.": "可以使用右侧菜单中的删除工具来删除轨道部件。", Watch: "观看", "Loading replay": "加载录像", "Press {0} to return to the last checkpoint": "按 {0} 返回到上一个检查点", "Press {0} to start over": "按 {0} 重新开始", "Reset once to return to the last checkpoint": "重置一次返回到上一个检查点", "Reset again to start over": "再次重置重新开始", Leaderboard: "排行榜", Back: "返回", "Error: Failed to load leaderboard": "错误:加载排行榜失败", Pending: "待处理", Verified: "已验证", Invalid: "无效", Duplicate: "重复", You: "您", "Only verified": "仅验证", Loading: "加载中", "Failed to load recordings": "加载录像失败", "Cannot load recordings due to non-determinism": "由于非确定性无法加载录像", Ok: "确定", "Track is missing starting point": "赛道缺失起点", "Some leaderboard features are disabled.": "一些排行榜功能已禁用。", "Please try another browser or device.": "请尝试其他浏览器或设备。", "You already have another instance of PolyTrack open.": "您已经打开了另一个PolyTrack实例。", "Please switch to that tab or window to continue.": "请切换到该选项卡或窗口继续。", "Computer determinism check failed.": "计算机确定性检查失败。", "Non-deterministic game assets found.": "发现非确定性游戏资源。", "Please try clearing your browser cache.": "请尝试清除浏览器缓存。", Customize: "自定义", Editor: "编辑器", Settings: "设置", Profile: "个人资料", Play: "游戏", Version: "版本", "You cannot have duplicate user profiles": "您不能拥有重复的用户配置文件", "Failed to create user profile": "创建用户配置文件失败", "This user profile does not exist on the server": "服务器上不存在此用户配置文件", "Failed to download user profile from the server": "无法从服务器下载用户配置文件", "User token is invalid": "用户令牌无效", "Are you sure you want to display your private key?": "确定要显示您的私钥吗?", "DO NOT SHARE THIS KEY WITH ANYONE.": "请勿与任何人分享此密钥。", "You need a free user profile slot to import a new user profile": "您需要一个空闲的用户配置文件槽来导入新的用户配置文件", Quit: "退出", Fullscreen: "全屏", Windowed: "窗口", " ": "您似乎正在玩 {0} 的非官方版本。请访问原始来源获取最新版本:", Nickname: "昵称", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "选择在排行榜中显示的昵称。您可以随时更改昵称。", Cancel: "取消", Confirm: "确认", Verifier: "验证器", "User ID": "用户ID", Paused: "暂停", "Switch car": "切换车辆", Profiles: "配置文件", 'Are you sure you would like to delete "{0}"?': '您确定要删除 "{0}" 吗?', Empty: "空", Reset: "重置", Apply: "应用", Gameplay: "游戏方式", Units: "单位", Metric: "公制", Imperial: "英制", "Reset hint": "重置提示", Disabled: "禁用", Enabled: "启用", "Ghost car": "幽灵车", "Default camera": "默认摄像头", Default: "默认", Cockpit: "座舱", "Cockpit camera mode": "座舱摄像头模式", Hold: "按住", Toggle: "切换", Checkpoints: "检查点", Timer: "计时器", Speedometer: "速度计", Bottom: "底部", Top: "顶部", Language: "语言", Graphics: "图形", "Car shadow": "车辆阴影", "Track shadow": "赛道阴影", Off: "关闭", On: "打开", Low: "低", Medium: "中", High: "高", Clouds: "云", Particles: "粒子", Skidmarks: "打滑痕迹", "Render scale": "渲染比例", "Anti-aliasing (requires restart)": "抗锯齿(需要重启)", Audio: "音频", "Sound effect volume": "音效音量", "Music volume": "音乐音量", "Checkpoint volume": "检查点音量", Controls: "控制", Vehicle: "车辆", Accelerate: "加速", Brake: "刹车", "Turn left": "左转", "Turn right": "右转", "Checkpoint reset": "检查点重置", "Start reset": "起点重置", "Cockpit camera": "座舱摄像头", "Rotate part": "旋转部件", "Height modifier": "高度调整", "Delete part": "删除部件", "Move forwards": "向前移动", "Move backwards": "向后移动", "Move left": "向左移动", "Move right": "向右移动", "Rotate view up": "向上旋转视图", "Rotate view down": "向下旋转视图", "Rotate view left": "向左旋转视图", "Rotate view right": "向右旋转视图", "Move down": "向下移动", "Move up": "向上移动", "Test track": "测试赛道", "Pick part": "选择部件", Spectator: "观众", "Speed modifier": "速度调整", Other: "其他", "Hide UI": "隐藏UI", Pause: "暂停", "Toggle FPS counter": "切换FPS计数器", "Toggle spectator camera": "切换观众摄像头", "Press any key...\n\nPress [Escape] to cancel.": "按任意键...\n\n按 [Escape] 取消。", Clear: "清除", "New record": "新记录", Record: "记录", Current: "当前", Difference: "差异", Copy: "复制", Import: "导入", "Failed to import track": "导入赛道失败", 'The track "{0}" already exists. Do you wish to overwrite it?': '赛道 "{0}" 已存在。您是否要覆盖它?', Overwrite: "覆盖", "Paste track data here...": "在此粘贴赛道数据...", Rank: "排名", "Personal best": "个人最佳", Opponents: "对手", "{0} opponent selected": "{0} 个对手已选择", "{0} opponents selected": "{0} 个对手已选择", "Select opponents to race against from the leaderboard on the left": "从左侧的排行榜中选择对手进行比赛", "No record": "无记录", "Official tracks": "官方赛道", "Community tracks": "社区赛道", "Custom tracks": "自定义赛道", 'Are you sure you want to delete "{0}"?': '确定要删除 "{0}" 吗?', Delete: "删除", "No community tracks": "没有社区赛道", "Community tracks are coming soon": "社区赛道即将推出", "No custom tracks": "没有自定义赛道", "Create a track using the editor or import a track code": "使用编辑器创建赛道或导入赛道代码", "Search tracks...": "搜索赛道...", "Invalid replay detected!": "检测到无效的重放!" }, yz = { "Checkpoint order": "檢查點順序", Height: "高度", Exit: "退出", Random: "隨機", Primary: "主要", Secondary: "次要", Frame: "框架", Rims: "輪框", "Are you sure you want to exit without saving?": "您確定要退出而不保存嗎?", "All changes will be lost!": "所有更改將遺失!", "Car saved!": "車輛已保存!", Test: "測試", "Starting point is missing!": "起點缺失!", Generate: "生成", "Are you sure you want to generate a new track?\n\nYour current track will be lost!": "您確定要生成新賽道嗎?\n\n您當前的賽道將會丟失!", Load: "載入", Save: "保存", "Are you sure you want to load a new track?\n\nYour current track will be lost!": "您確定要載入新賽道嗎?\n\n您當前的賽道將會丟失!", "Track saved!": "賽道已保存!", "Failed to save!": "保存失敗!", 'Are you sure you want to overwrite "{0}"?': '您確定要覆蓋 "{0}" 嗎?', Export: "匯出", Help: "幫助", "Are you sure you want to exit the editor?": "您確定要退出編輯器嗎?", "All unsaved data will be lost!": "所有未儲存的資料將遺失!", "Track settings": "賽道設定", "Unnamed Track": "未命名賽道", "Track name": "賽道名稱", Author: "作者", Unknown: "未知", Environment: "環境", Summer: "夏季", Winter: "冬季", Desert: "沙漠", "Sun direction": "太陽方向", "How to use the editor": "如何使用編輯器", "Camera controls": "攝影機控制", "The camera can be moved by right clicking and dragging the mouse. Rotate the camera by clicking the middle mouse button (mouse wheel) or holding the control key and right clicking and dragging the mouse. Zoom in and out by scrolling the mouse wheel.": "攝影機可以通過右鍵點擊並拖動鼠標來移動。通過點擊中間的鼠標按鈕(滾輪)或按住Ctrl鍵並右鍵點擊並拖動鼠標來旋轉攝影機。通過滾動鼠標滾輪來放大和縮小。", "Alternatively, the camera can also be controlled using the following keyboard keys:": "或者,攝影機也可以使用以下鍵盤按鍵進行控制:", "Move forwards:": "向前移動:", "Move backwards:": "向後移動:", "Move left:": "向左移動:", "Move right:": "向右移動:", "Rotate left:": "向左旋轉:", "Rotate right:": "向右旋轉:", "The edited height can be changed either by using the height selection in the bottom left corner, or holding the shift key and scrolling the mouse wheel. Alternatively, you can use the following keyboard keys:": "可以通過使用左下角的高度選擇器來更改編輯的高度,也可以按住Shift鍵並滾動鼠標滾輪。或者,您可以使用以下鍵盤按鍵:", "Move up:": "向上移動:", "Move down:": "向下移動:", Editing: "編輯", "Track parts can be selected in the menu on the right after which they can be placed by left clicking with the mouse.": "可以在右側的菜單中選擇軌道部件,然後可以使用鼠標左鍵點擊放置。", "Alternatively, the track part currently hovered by the mouse can be selected with the following keyboard shortcut:": "或者,可以使用以下鍵盤快捷鍵選擇當前鼠標懸停的軌道部件:", "The selected part can then be rotated using the following keyboard shortcut:": "然後可以使用以下鍵盤快捷鍵旋轉所選部分:", "Track parts can be deleted by using the delete tool in the right side menu or by holding the following key:": "可以使用右側菜單中的刪除工具或按住以下鍵來刪除軌道部件:", "Starting points, checkpoints and the finish line": "起點、檢查點和終點", "Starting points, checkpoints and finish lines can all be selected in the uppermost category in the right side menu.": "起點、檢查點和終點都可以在右側菜單的最上方類別中選擇。", "Each track must have at least one starting point. If there are multiple starting points, the last placed one will be used.": "每個賽道必須至少有一個起點。如果有多個起點,則使用最後放置的起點。", "Checkpoints should be placed between the starting point and the finish line. When a checkpoint track part is selected there will be a tool in the bottom right to select the order of the checkpoint. This determines the order in which the checkpoints must be passed before driving to the finish line. Notice that it is possible to have multiple checkpoints with the same checkpoint order.": "檢查點應該放置在起點和終點之間。當選擇檢查點軌道部件時,底部右側將有一個工具來選擇檢查點的順序。這決定了在開始行駛到終點之前必須通過檢查點的順序。請注意,可以有多個具有相同檢查點順序的檢查點。", "The finish line is where the track ends but will only become active after all checkpoints have been passed. It is also possible to have multiple finish lines.": "終點是賽道結束的地方,但只有在通過所有檢查點後才會變為活動狀態。也可以有多個終點。", "Starting point": "起點", Checkpoint: "檢查點", "Finish line": "終點", "Exporting the track": "導出賽道", "When the track is finished, a name for the track can be entered in top left after which the track can be exported using the export button. This will reveal a track code which can be sent to other users so they can import and play the track.": "完成賽道後,可以在左上角輸入賽道名稱,然後使用導出按鈕導出賽道。這將顯示一個賽道代碼,可以將其發送給其他用戶,以便他們可以導入並播放賽道。", Close: "關閉", "Not set": "未設置", or: "或", "The camera can be moved by dragging with one finger. Rotate the camera by dragging with two fingers. Zoom in and out by pinching.": "攝影機可以通過用一根手指拖動來移動。通過用兩根手指拖動來旋轉攝影機。通過捏合來放大和縮小。", "The edited height can be changed by using the height selection in the bottom left corner.": "可以通過使用左下角的高度選擇器來更改編輯的高度。", "Track parts can be selected in the menu on the right after which they can be placed by tapping on the screen.": "可以在右側的菜單中選擇軌道部件,然後可以通過點擊屏幕來放置。", "The selected part can then be rotated by tapping the rotate button in the bottom left corner.": "然後可以通過點擊左下角的旋轉按鈕來旋轉所選部分。", "Track parts can be deleted by using the delete tool in the right side menu.": "可以使用右側菜單中的刪除工具來刪除軌道部件。", Watch: "觀看", "Loading replay": "載入錄影", "Press {0} to return to the last checkpoint": "按 {0} 返回到上一個檢查點", "Press {0} to start over": "按 {0} 重新開始", "Reset once to return to the last checkpoint": "重設一次返回到上一個檢查點", "Reset again to start over": "再次重設重新開始", Leaderboard: "排行榜", Back: "返回", "Error: Failed to load leaderboard": "錯誤:無法載入排行榜", Pending: "待定", Verified: "已驗證", Invalid: "無效", Duplicate: "重複", You: "您", "Only verified": "僅驗證", Loading: "載入中", "Failed to load recordings": "無法載入錄影", "Cannot load recordings due to non-determinism": "由於非確定性,無法載入錄影", Ok: "確定", "Track is missing starting point": "賽道缺少起點", "Some leaderboard features are disabled.": "一些排行榜功能已禁用。", "Please try another browser or device.": "請嘗試其他瀏覽器或設備。", "You already have another instance of PolyTrack open.": "您已經打開了另一個 PolyTrack 實例。", "Please switch to that tab or window to continue.": "請切換到該標籤或窗口以繼續。", "Computer determinism check failed.": "電腦確定性檢查失敗。", "Non-deterministic game assets found.": "發現非確定性遊戲資產。", "Please try clearing your browser cache.": "請嘗試清除瀏覽器快取。", Customize: "自訂", Editor: "編輯器", Settings: "設定", Profile: "個人資料", Play: "遊玩", Version: "版本", "You cannot have duplicate user profiles": "您不能擁有重複的使用者檔案", "Failed to create user profile": "無法建立使用者檔案", "This user profile does not exist on the server": "此使用者檔案不存在於伺服器上", "Failed to download user profile from the server": "無法從伺服器下載使用者檔案", "User token is invalid": "使用者令牌無效", "Are you sure you want to display your private key?": "確定要顯示您的私密金鑰嗎?", "DO NOT SHARE THIS KEY WITH ANYONE.": "請勿與任何人分享此金鑰。", "You need a free user profile slot to import a new user profile": "您需要一個空閒的使用者檔案插槽以匯入新的使用者檔案", Quit: "退出", Fullscreen: "全螢幕", Windowed: "視窗", " ": "您似乎正在玩非官方版本的 {0}。請訪問原始來源以獲取最新版本:", Nickname: "暱稱", "Choose a nickname to be shown in the leaderboard. Your nickname can be changed at any time.": "選擇一個在排行榜中顯示的暱稱。您隨時可以更改您的暱稱。", Cancel: "取消", Confirm: "確認", Verifier: "驗證者", "User ID": "使用者 ID", Paused: "暫停", "Switch car": "切換車輛", Profiles: "配置檔", 'Are you sure you would like to delete "{0}"?': '您確定要刪除 "{0}" 嗎?', Empty: "空", Reset: "重設", Apply: "套用", Gameplay: "遊戲玩法", Units: "單位", Metric: "公制", Imperial: "英制", "Reset hint": "重設提示", Disabled: "禁用", Enabled: "啟用", "Ghost car": "鬼車", "Default camera": "預設攝影機", Default: "預設", Cockpit: "座艙", "Cockpit camera mode": "座艙攝影機模式", Hold: "按住", Toggle: "切換", Checkpoints: "檢查點", Timer: "計時器", Speedometer: "速度計", Bottom: "底部", Top: "頂部", Language: "語言", Graphics: "圖形", "Car shadow": "車影", "Track shadow": "賽道影子", Off: "關", On: "開", Low: "低", Medium: "中", High: "高", Clouds: "雲彩", Particles: "粒子", Skidmarks: "滑胎痕跡", "Render scale": "渲染比例", "Anti-aliasing (requires restart)": "抗鋸齒 (需要重新啟動)", Audio: "音效", "Sound effect volume": "音效音量", "Music volume": "音樂音量", "Checkpoint volume": "檢查點音量", Controls: "控制", Vehicle: "車輛", Accelerate: "加速", Brake: "剎車", "Turn left": "左轉", "Turn right": "右轉", "Checkpoint reset": "檢查點重設", "Start reset": "起點重設", "Cockpit camera": "座艙攝影機", "Rotate part": "旋轉部件", "Height modifier": "高度調整", "Delete part": "刪除部件", "Move forwards": "前進", "Move backwards": "後退", "Move left": "左移", "Move right": "右移", "Rotate view up": "向上旋轉視圖", "Rotate view down": "向下旋轉視圖", "Rotate view left": "向左旋轉視圖", "Rotate view right": "向右旋轉視圖", "Move down": "向下移動", "Move up": "向上移動", "Test track": "測試賽道", "Pick part": "選擇部件", Spectator: "觀眾", "Speed modifier": "速度調整", Other: "其他", "Hide UI": "隱藏 UI", Pause: "暫停", "Toggle FPS counter": "切換 FPS 計數器", "Toggle spectator camera": "切換觀眾攝影機", "Press any key...\n\nPress [Escape] to cancel.": "按下任意鍵...\n\n按 [Escape] 取消。", Clear: "清除", "New record": "新紀錄", Record: "紀錄", Current: "目前", Difference: "差異", Copy: "複製", Import: "匯入", "Failed to import track": "匯入賽道失敗", 'The track "{0}" already exists. Do you wish to overwrite it?': '賽道 "{0}" 已存在。您要覆蓋它嗎?', Overwrite: "覆蓋", "Paste track data here...": "在此粘貼賽道數據...", Rank: "排名", "Personal best": "個人最佳", Opponents: "對手", "{0} opponent selected": "{0} 對手已選擇", "{0} opponents selected": "{0} 對手已選擇", "Select opponents to race against from the leaderboard on the left": "從左側的排行榜中選擇對手進行比賽", "No record": "無紀錄", "Official tracks": "官方賽道", "Community tracks": "社區賽道", "Custom tracks": "自訂賽道", 'Are you sure you want to delete "{0}"?': '您確定要刪除 "{0}" 嗎?', Delete: "刪除", "No community tracks": "沒有社區賽道", "Community tracks are coming soon": "社區賽道即將推出", "No custom tracks": "沒有自訂賽道", "Create a track using the editor or import a track code": "使用編輯器創建賽道或匯入賽道代碼", "Search tracks...": "搜索賽道...", "Invalid replay detected!": "檢測到無效的重播!" }; var Az, bz, xz, kz, Ez = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }, Sz = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }; bz = new WeakMap, xz = new WeakMap, Az = new WeakSet, kz = function(e) { const t = Ez(this, xz, "f").get(e); return null != t ? t : sz }; const Mz = class { constructor(e) { Az.add(this), bz.set(this, void 0), xz.set(this, new Map([ ["ar", rz], ["de-DE", az], ["es-ES", oz], ["fr-FR", lz], ["it-IT", cz], ["ja-JP", hz], ["ko-KR", dz], ["pl-PL", uz], ["pt-BR", pz], ["pt-PT", fz], ["ru-RU", mz], ["tr-TR", gz], ["uk-UA", vz], ["zh-CN", wz], ["zh-TW", yz] ])), Sz(this, bz, Ez(this, Az, "m", kz).call(this, e), "f") } set language(e) { Sz(this, bz, Ez(this, Az, "m", kz).call(this, e), "f") } get(e, t) { let n; if (n = e in Ez(this, bz, "f") ? Ez(this, bz, "f")[e] : e, null != t) for (const [e, i] of t.entries()) n = n.replace(new RegExp("\\{" + e.toString() + "\\}", "g"), i); return n } }; var Tz = n(1465), _z = {}; _z.styleTagTransform = u(), _z.setAttributes = l(), _z.insert = s().bind(null, "head"), _z.domAPI = r(), _z.insertStyleElement = h(); t()(Tz.A, _z); Tz.A && Tz.A.locals && Tz.A.locals; var Cz, Pz, Iz, Rz, Lz, Dz, Nz = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, Bz = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; Cz = new WeakMap, Pz = new WeakMap, Iz = new WeakMap, Rz = new WeakMap, Lz = new WeakMap, Dz = new WeakMap; const Uz = class { constructor() { Cz.set(this, void 0), Pz.set(this, void 0), Iz.set(this, void 0), Rz.set(this, void 0), Lz.set(this, void 0), Dz.set(this, void 0); const e = document.getElementById("ui"); if (null == e) throw new Error("UI element not found"); Nz(this, Cz, e, "f"), Nz(this, Pz, document.createElement("div"), "f"), Bz(this, Pz, "f").className = "input-visualizer", Bz(this, Cz, "f").appendChild(Bz(this, Pz, "f")), Nz(this, Iz, document.createElement("div"), "f"), Bz(this, Iz, "f").className = "arrow-up", Bz(this, Iz, "f").innerHTML = '', Bz(this, Pz, "f").appendChild(Bz(this, Iz, "f")), Nz(this, Rz, document.createElement("div"), "f"), Bz(this, Rz, "f").className = "arrow-right", Bz(this, Rz, "f").innerHTML = '', Bz(this, Pz, "f").appendChild(Bz(this, Rz, "f")), Nz(this, Lz, document.createElement("div"), "f"), Bz(this, Lz, "f").className = "arrow-down", Bz(this, Lz, "f").innerHTML = '', Bz(this, Pz, "f").appendChild(Bz(this, Lz, "f")), Nz(this, Dz, document.createElement("div"), "f"), Bz(this, Dz, "f").className = "arrow-left", Bz(this, Dz, "f").innerHTML = '', Bz(this, Pz, "f").appendChild(Bz(this, Dz, "f")) } dispose() { Bz(this, Cz, "f").removeChild(Bz(this, Pz, "f")) } update(e) { Bz(this, Iz, "f").className = e.up ? "active arrow-up" : "arrow-up", Bz(this, Rz, "f").className = e.right ? "active arrow-right" : "arrow-right", Bz(this, Lz, "f").className = e.down ? "active arrow-down" : "arrow-down", Bz(this, Dz, "f").className = e.left ? "active arrow-left" : "arrow-left" } }; var zz = n(4543), Oz = {}; Oz.styleTagTransform = u(), Oz.setAttributes = l(), Oz.insert = s().bind(null, "head"), Oz.domAPI = r(), Oz.insertStyleElement = h(); t()(zz.A, Oz); zz.A && zz.A.locals && zz.A.locals; var Fz, Wz, Vz, Hz, Gz, jz, Qz, Yz, Kz, qz, Xz, Zz, Jz, $z, eO, tO, nO, iO, rO = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, aO = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; Wz = new WeakMap, Vz = new WeakMap, Hz = new WeakMap, Gz = new WeakMap, jz = new WeakMap, Qz = new WeakMap, Yz = new WeakMap, Kz = new WeakMap, qz = new WeakMap, Xz = new WeakMap, Zz = new WeakMap, Jz = new WeakMap, $z = new WeakMap, eO = new WeakMap, Fz = new WeakSet, tO = function(e) { const t = aO(this, jz, "f").getBoundingClientRect(), n = (e.clientX - t.left) / (t.width - 8), i = new xp(Math.max(0, Math.min(aO(this, Zz, "f").numberOfFrames, Math.floor(n * aO(this, Zz, "f").numberOfFrames)))); aO(this, Vz, "f").call(this, i) }, nO = function() { aO(this, Xz, "f") ? aO(this, Gz, "f").innerHTML = '' : aO(this, qz, "f") ? aO(this, Gz, "f").innerHTML = '' : aO(this, Gz, "f").innerHTML = '' }, iO = function() { if (aO(this, Kz, "f").innerHTML = "", aO(this, Zz, "f").time < 1e4) { let e, t; aO(this, Zz, "f").time > 2e3 ? (e = 60, t = 600) : aO(this, Zz, "f").time > 200 ? (e = 10, t = 60) : (e = 1, t = 10); for (let n = e; n < aO(this, Zz, "f").time; n += e) { const e = document.createElement("div"); e.className = n % t == 0 ? "dash long" : "dash", e.style.left = "calc(" + (n / aO(this, Zz, "f").time * 100).toString() + "% - 1px)", aO(this, Kz, "f").appendChild(e) } } }; const sO = class { constructor(e, t, n, i) { Fz.add(this), Wz.set(this, void 0), Vz.set(this, void 0), Hz.set(this, void 0), Gz.set(this, void 0), jz.set(this, void 0), Qz.set(this, void 0), Yz.set(this, void 0), Kz.set(this, void 0), qz.set(this, void 0), Xz.set(this, !1), Zz.set(this, void 0), Jz.set(this, !1), $z.set(this, void 0), eO.set(this, void 0), rO(this, qz, i, "f"); const r = document.getElementById("ui"); if (null == r) throw new Error("UI element not found"); rO(this, Wz, r, "f"), rO(this, Vz, n, "f"), rO(this, Zz, t, "f"), rO(this, Hz, document.createElement("div"), "f"), aO(this, Hz, "f").className = "time-bar", aO(this, Wz, "f").appendChild(aO(this, Hz, "f")), rO(this, Gz, document.createElement("button"), "f"), aO(this, Gz, "f").className = "button", aO(this, Gz, "f").addEventListener("click", (() => { e.playUIClick(), aO(this, Xz, "f") ? (aO(this, Vz, "f").call(this, new xp(0)), this.isPaused = !1) : this.isPaused = !this.isPaused })), aO(this, Hz, "f").appendChild(aO(this, Gz, "f")), aO(this, Fz, "m", nO).call(this), rO(this, jz, document.createElement("div"), "f"), aO(this, jz, "f").className = "bar", aO(this, jz, "f").addEventListener("pointerdown", (e => { rO(this, Jz, !0, "f"), aO(this, Fz, "m", tO).call(this, e) })), window.addEventListener("pointermove", rO(this, $z, (e => { aO(this, Jz, "f") && aO(this, Fz, "m", tO).call(this, e) }), "f")), window.addEventListener("pointerup", rO(this, eO, (e => { aO(this, Jz, "f") && (rO(this, Jz, !1, "f"), aO(this, Fz, "m", tO).call(this, e)) }), "f")), aO(this, Hz, "f").appendChild(aO(this, jz, "f")); const a = document.createElement("div"); aO(this, jz, "f").appendChild(a), rO(this, Qz, document.createElement("div"), "f"), aO(this, Qz, "f").className = "unloaded-fill", a.appendChild(aO(this, Qz, "f")), rO(this, Yz, document.createElement("div"), "f"), aO(this, Yz, "f").className = "fill", a.appendChild(aO(this, Yz, "f")), rO(this, Kz, document.createElement("div"), "f"), aO(this, Kz, "f").className = "dash-container", a.appendChild(aO(this, Kz, "f")), aO(this, Fz, "m", iO).call(this) } dispose() { aO(this, Wz, "f").removeChild(aO(this, Hz, "f")), window.removeEventListener("pointermove", aO(this, $z, "f")), window.removeEventListener("pointerup", aO(this, eO, "f")) } get isDragging() { return aO(this, Jz, "f") } get isPaused() { return aO(this, qz, "f") } set isPaused(e) { rO(this, qz, e, "f"), aO(this, Fz, "m", nO).call(this) } set time(e) { const t = e.numberOfFrames >= aO(this, Zz, "f").numberOfFrames; aO(this, Yz, "f").style.width = "calc(8px + " + (e.numberOfFrames / aO(this, Zz, "f").numberOfFrames * 100).toString() + "%)", 0 == e.numberOfFrames ? aO(this, Yz, "f").style.visibility = "hidden" : aO(this, Yz, "f").style.visibility = "visible", aO(this, Xz, "f") != t && (rO(this, Xz, t, "f"), aO(this, Fz, "m", nO).call(this)) } set loadedTime(e) { aO(this, Qz, "f").style.width = "calc(8px + " + (100 * (1 - e.numberOfFrames / aO(this, Zz, "f").numberOfFrames)).toString() + "%)", e.numberOfFrames >= aO(this, Zz, "f").numberOfFrames ? aO(this, Qz, "f").style.visibility = "hidden" : aO(this, Qz, "f").style.visibility = "visible" } set totalTime(e) { aO(this, Zz, "f").equals(e) || (rO(this, Zz, e.clone(), "f"), aO(this, Fz, "m", iO).call(this)) } }; var oO = n(8768), lO = {}; lO.styleTagTransform = u(), lO.setAttributes = l(), lO.insert = s().bind(null, "head"), lO.domAPI = r(), lO.insertStyleElement = h(); t()(oO.A, lO); oO.A && oO.A.locals && oO.A.locals; var cO, hO, dO = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, uO = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; cO = new WeakMap, hO = new WeakMap; const pO = class { constructor(e, t, n, i) { cO.set(this, void 0), hO.set(this, void 0); const r = document.getElementById("ui"); if (null == r) throw new Error("UI element not found"); dO(this, cO, r, "f"), dO(this, hO, document.createElement("div"), "f"), uO(this, hO, "f").className = "preview-toolbar"; const a = document.createElement("button"); if (a.className = "button", a.innerHTML = ' ', a.append(document.createTextNode(t.get("Back"))), a.addEventListener("click", (() => { e.playUIClick(), n() })), uO(this, hO, "f").appendChild(a), null != i) { const n = document.createElement("button"); n.className = "button", n.innerHTML = ' ', n.append(document.createTextNode(t.get("Switch car"))), n.addEventListener("click", (() => { e.playUIClick(), i() })), uO(this, hO, "f").appendChild(n) } uO(this, cO, "f").appendChild(uO(this, hO, "f")) } dispose() { uO(this, cO, "f").removeChild(uO(this, hO, "f")) } }; var fO, mO, gO, vO, wO, yO, AO, bO, xO, kO, EO, SO, MO, TO, _O, CO, PO, IO, RO, LO, DO, NO, BO, UO, zO, OO, FO, WO, VO, HO, GO, jO = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }, QO = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }; mO = new WeakMap, gO = new WeakMap, vO = new WeakMap, wO = new WeakMap, yO = new WeakMap, AO = new WeakMap, bO = new WeakMap, xO = new WeakMap, kO = new WeakMap, EO = new WeakMap, SO = new WeakMap, MO = new WeakMap, TO = new WeakMap, _O = new WeakMap, CO = new WeakMap, PO = new WeakMap, IO = new WeakMap, RO = new WeakMap, LO = new WeakMap, DO = new WeakMap, NO = new WeakMap, BO = new WeakMap, UO = new WeakMap, zO = new WeakMap, OO = new WeakMap, FO = new WeakMap, WO = new WeakMap, VO = new WeakMap, fO = new WeakSet, HO = function(e) { var t, n, i, r, a; if (e) { const e = QO(this, _O, "f")[QO(this, TO, "f")].settings.time; let t; jO(this, DO, new sO(QO(this, kO, "f"), e, (e => { var t, n, i; jO(this, PO, Math.max(0, Math.min(QO(this, IO, "f"), e.time)), "f"); const r = Math.round(1e3 * QO(this, PO, "f")); QO(this, fO, "m", GO).call(this, r); for (const e of QO(this, _O, "f")) e.car.update(0); const a = QO(this, _O, "f")[QO(this, TO, "f")].car; null != QO(this, DO, "f") && (QO(this, DO, "f").time = new xp(r)), null === (t = QO(this, BO, "f")) || void 0 === t || t.update(a.getControls()), null === (n = QO(this, UO, "f")) || void 0 === n || n.update(a), null === (i = QO(this, zO, "f")) || void 0 === i || i.update(a) }), QO(this, CO, "f")), "f"), t = QO(this, _O, "f").length > 1 ? () => { jO(this, TO, (QO(this, TO, "f") + 1) % QO(this, _O, "f").length, "f"); for (let e = 0; e < QO(this, _O, "f").length; e++) QO(this, _O, "f")[e].car.notificationAudioEnabled = e == QO(this, TO, "f"); QO(this, RO, "f").isEnabled || (QO(this, SO, "f").getSettingBoolean($o.DefaultCameraMode) ? QO(this, xO, "f").setCamera(QO(this, _O, "f")[QO(this, TO, "f")].car.cameraCockpit) : QO(this, xO, "f").setCamera(QO(this, _O, "f")[QO(this, TO, "f")].car.cameraOrbit)), null != QO(this, DO, "f") && (QO(this, DO, "f").totalTime = QO(this, _O, "f")[QO(this, TO, "f")].settings.time), null != QO(this, zO, "f") && (QO(this, zO, "f").nickname = QO(this, _O, "f")[QO(this, TO, "f")].settings.name) } : null, jO(this, NO, new pO(QO(this, kO, "f"), QO(this, EO, "f"), (() => { QO(this, MO, "f").call(this, QO(this, vO, "f"), QO(this, wO, "f"), QO(this, yO, "f"), QO(this, _O, "f").map((e => e.settings))) }), t), "f"), jO(this, BO, new Uz, "f"), jO(this, UO, new TT(QO(this, SO, "f")), "f"), QO(this, UO, "f").setOverridePosition(!1), jO(this, zO, new fk(QO(this, EO, "f"), QO(this, SO, "f"), !0), "f"), QO(this, zO, "f").nickname = QO(this, _O, "f")[QO(this, TO, "f")].settings.name, QO(this, zO, "f").setOverridePosition(!1) } else null === (t = QO(this, DO, "f")) || void 0 === t || t.dispose(), jO(this, DO, null, "f"), null === (n = QO(this, NO, "f")) || void 0 === n || n.dispose(), jO(this, NO, null, "f"), null === (i = QO(this, BO, "f")) || void 0 === i || i.dispose(), jO(this, BO, null, "f"), null === (r = QO(this, UO, "f")) || void 0 === r || r.dispose(), jO(this, UO, null, "f"), null === (a = QO(this, zO, "f")) || void 0 === a || a.dispose(), jO(this, zO, null, "f") }, GO = function(e) { for (const t of QO(this, _O, "f")) if (t.car.getTime().numberOfFrames != e) { const n = t.replay.getFrame(e); null != n && t.car.setCarState(n) } }; const YO = class { constructor(e, t, n, i, r, a, s, o, l, c, h, d, u) { fO.add(this), mO.set(this, void 0), gO.set(this, void 0), vO.set(this, void 0), wO.set(this, void 0), yO.set(this, void 0), AO.set(this, void 0), bO.set(this, void 0), xO.set(this, void 0), kO.set(this, void 0), EO.set(this, void 0), SO.set(this, void 0), MO.set(this, void 0), TO.set(this, 0), _O.set(this, void 0), CO.set(this, !1), PO.set(this, 0), IO.set(this, 0), RO.set(this, void 0), LO.set(this, !0), DO.set(this, null), NO.set(this, null), BO.set(this, null), UO.set(this, null), zO.set(this, null), OO.set(this, null), FO.set(this, void 0), WO.set(this, void 0), VO.set(this, 1e4), jO(this, mO, e, "f"), jO(this, gO, t, "f"), jO(this, vO, n, "f"), jO(this, wO, i, "f"), jO(this, yO, r, "f"), jO(this, AO, a, "f"), jO(this, bO, s, "f"), jO(this, xO, o, "f"), jO(this, kO, l, "f"), jO(this, EO, c, "f"), jO(this, SO, h, "f"), jO(this, MO, u, "f"), t.loadTrackData(i), t.generateMeshes(), a.generateMountains(t.getBounds()); const p = t.getStartTransform(); if (null == p) throw new Error("Track has no starting point"); const f = new xp(d.reduce(((e, t) => Math.max(e, t.time.numberOfFrames + QO(this, VO, "f"))), 0)); jO(this, IO, f.time, "f"), jO(this, _O, d.map(((n, i) => { const r = new Aw(null, p, n.recording, null, o, l, a, t, h); r.notificationAudioEnabled = QO(this, TO, "f") == i, r.setColors(n.carColors); const s = { replay: new __, carId: null, car: r, settings: n }, c = e.createCar(p, a.getMountainVertices(), a.getMountainOffset(), t.getTrackData(), n.recording, (t => { s.replay.push(t), null != s.carId && t.frames >= f.numberOfFrames && (e.deleteCar(s.carId), s.carId = null) })); return s.replay.push(c), e.startCar(c.id, f.clone()), s.carId = c.id, s })), "f"), h.getSettingBoolean($o.DefaultCameraMode) ? o.setCamera(QO(this, _O, "f")[QO(this, TO, "f")].car.cameraCockpit) : o.setCamera(QO(this, _O, "f")[QO(this, TO, "f")].car.cameraOrbit), jO(this, RO, new s_(o, h), "f"), QO(this, RO, "f").addToggleListener((e => { e ? o.setCamera(QO(this, RO, "f").camera) : QO(this, SO, "f").getSettingBoolean($o.DefaultCameraMode) ? QO(this, xO, "f").setCamera(QO(this, _O, "f")[QO(this, TO, "f")].car.cameraCockpit) : QO(this, xO, "f").setCamera(QO(this, _O, "f")[QO(this, TO, "f")].car.cameraOrbit) })), QO(this, fO, "m", HO).call(this, !0), window.addEventListener("keydown", jO(this, FO, (e => { if (QO(this, RO, "f").isEnabled) "Escape" == e.code && (QO(this, RO, "f").isEnabled = !1, e.preventDefault()); else if ("Escape" == e.code) u(n, i, r, QO(this, _O, "f").map((e => e.settings))), e.preventDefault(); else if (h.checkKeyBinding(e, Ix.VehicleCheckpointReset) || h.checkKeyBinding(e, Ix.VehicleStartReset)) e.repeat || jO(this, PO, 0, "f"), e.preventDefault(); else if (QO(this, SO, "f").checkKeyBinding(e, Ix.VehicleCockpitCamera)) { if (!e.repeat) { const e = QO(this, _O, "f")[QO(this, TO, "f")].car; e.hasFinished() || (QO(this, SO, "f").getSettingBoolean($o.CockpitCameraToggle) ? QO(this, xO, "f").camera == e.cameraOrbit ? QO(this, xO, "f").setCamera(e.cameraCockpit) : QO(this, xO, "f").setCamera(e.cameraOrbit) : QO(this, SO, "f").getSettingBoolean($o.DefaultCameraMode) ? QO(this, xO, "f").setCamera(e.cameraOrbit) : QO(this, xO, "f").setCamera(e.cameraCockpit)) } e.preventDefault() } if (h.checkKeyBinding(e, Ix.ToggleUI) && (jO(this, LO, !QO(this, LO, "f"), "f"), QO(this, fO, "m", HO).call(this, QO(this, LO, "f")), e.preventDefault()), h.checkKeyBinding(e, Ix.ToggleSpectatorCamera)) { QO(this, RO, "f").camera.position.copy(QO(this, xO, "f").camera.position); const t = new ai(0, 0, 0, "YXZ").setFromQuaternion(QO(this, xO, "f").camera.quaternion); t.z = 0, QO(this, RO, "f").camera.quaternion.setFromEuler(t), QO(this, RO, "f").toggle(), e.preventDefault() } "Space" == e.code && (jO(this, CO, !QO(this, CO, "f"), "f"), null != QO(this, DO, "f") && (QO(this, DO, "f").isPaused = QO(this, CO, "f")), e.preventDefault()) }), "f")), window.addEventListener("keyup", jO(this, WO, (e => { if (!QO(this, RO, "f").isEnabled && QO(this, SO, "f").checkKeyBinding(e, Ix.VehicleCockpitCamera)) { const e = QO(this, _O, "f")[QO(this, TO, "f")].car; e.hasFinished() || QO(this, SO, "f").getSettingBoolean($o.CockpitCameraToggle) || (QO(this, SO, "f").getSettingBoolean($o.DefaultCameraMode) ? QO(this, xO, "f").setCamera(e.cameraCockpit) : QO(this, xO, "f").setCamera(e.cameraOrbit)) } }), "f")) } dispose() { var e; QO(this, gO, "f").clear(), QO(this, AO, "f").clearMountains(); for (const e of QO(this, _O, "f")) null != e.carId && (QO(this, mO, "f").deleteCar(e.carId), e.carId = null), e.car.dispose(); QO(this, RO, "f").dispose(), QO(this, fO, "m", HO).call(this, !1), window.removeEventListener("keydown", QO(this, FO, "f")), window.removeEventListener("keyup", QO(this, WO, "f")), null === (e = QO(this, OO, "f")) || void 0 === e || e.dispose() } update(e) { var t, n, i, r, a, s; null != QO(this, DO, "f") && jO(this, CO, QO(this, DO, "f").isPaused, "f"); let o = 1 / 0; for (const e of QO(this, _O, "f")) o = Math.min(o, e.replay.getLastFrame().numberOfFrames); const l = new xp(o); let c; if (QO(this, CO, "f") || (null === (t = QO(this, DO, "f")) || void 0 === t ? void 0 : t.isDragging)) { c = 0; for (const e of QO(this, _O, "f")) e.car.audioVolume = 0 } else { const t = Math.min(QO(this, IO, "f"), QO(this, PO, "f") + e); if (l.time >= t) { jO(this, PO, t, "f"), QO(this, PO, "f") == QO(this, IO, "f") && (null != QO(this, DO, "f") && (QO(this, DO, "f").isPaused = !0), jO(this, CO, !0, "f")), c = e; for (const e of QO(this, _O, "f")) e.car.audioVolume = 1 } else { c = 0; for (const e of QO(this, _O, "f")) e.car.audioVolume = 0 } } const h = Math.round(1e3 * QO(this, PO, "f")), d = Math.min(h, l.numberOfFrames); if ((null === (n = QO(this, DO, "f")) || void 0 === n ? void 0 : n.isDragging) || d < QO(this, _O, "f")[QO(this, TO, "f")].car.getTime().numberOfFrames || d > QO(this, _O, "f")[QO(this, TO, "f")].car.getTime().numberOfFrames + 1e3) QO(this, fO, "m", GO).call(this, d); else { for (let e = QO(this, _O, "f")[QO(this, TO, "f")].car.getTime().numberOfFrames + 1; e <= d; e++) QO(this, fO, "m", GO).call(this, e) } null != QO(this, DO, "f") && (QO(this, DO, "f").time = QO(this, _O, "f")[QO(this, TO, "f")].car.getTime(), QO(this, DO, "f").loadedTime = l), null === (i = QO(this, BO, "f")) || void 0 === i || i.update(QO(this, _O, "f")[QO(this, TO, "f")].car.getControls()), null === (r = QO(this, UO, "f")) || void 0 === r || r.update(QO(this, _O, "f")[QO(this, TO, "f")].car), null === (a = QO(this, zO, "f")) || void 0 === a || a.update(QO(this, _O, "f")[QO(this, TO, "f")].car); for (const e of QO(this, _O, "f")) e.car.update(c), e.car.updateCameras(c); null === (s = QO(this, OO, "f")) || void 0 === s || s.updateCar(QO(this, _O, "f")[QO(this, TO, "f")].car), QO(this, RO, "f").update(e), QO(this, AO, "f").update(QO(this, gO, "f")), QO(this, bO, "f").update(c, QO(this, xO, "f").camera, QO(this, gO, "f").sunDirection), QO(this, kO, "f").update(e, !1, QO(this, xO, "f"), QO(this, SO, "f")), QO(this, xO, "f").update(QO(this, _O, "f")[QO(this, TO, "f")].car.getPosition(), QO(this, gO, "f").sunDirection) } }; var KO, qO, XO = function(e, t, n, i) { if ("a" === n && !i) throw new TypeError("Private accessor was defined without a getter"); if ("function" == typeof t ? e !== t || !i : !t.has(e)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return "m" === n ? i : "a" === n ? i.call(e) : i ? i.value : t.get(e) }, ZO = function(e, t, n, i, r) { if ("m" === i) throw new TypeError("Private method is not writable"); if ("a" === i && !r) throw new TypeError("Private accessor was defined without a setter"); if ("function" == typeof t ? e !== t || !r : !t.has(e)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return "a" === i ? r.call(e, n) : r ? r.value = n : t.set(e, n), n }; KO = new WeakMap, qO = new WeakMap; const JO = class { constructor() { KO.set(this, !1), qO.set(this, []), window.addEventListener("touchstart", (() => { if (!XO(this, KO, "f")) { ZO(this, KO, !0, "f"); for (const e of XO(this, qO, "f")) e(XO(this, KO, "f")) } })), window.addEventListener("keydown", (() => { if (XO(this, KO, "f")) { ZO(this, KO, !1, "f"); for (const e of XO(this, qO, "f")) e(XO(this, KO, "f")) } })) } get touchEnabled() { return XO(this, KO, "f") } addChangeListener(e) { XO(this, qO, "f").push(e), e(XO(this, KO, "f")) } removeChangeListener(e) { const t = XO(this, qO, "f").indexOf(e); t >= 0 && XO(this, qO, "f").splice(t, 1) } }; /** * @license * Copyright 2025 Kodub.com */ nn.enabled = !1, function() { const e = new oN; e.addResource(), K_().then((() => { e.loadedResource() })).catch((e => { console.error(e) })), e.addCompleteListener((() => { $_() })); const t = n(7780); for (const n of t.keys()) e.preloadImage("images/" + n.substring(2)); const i = new ZN, r = new OB, a = new ul(e); a.load("music", ["audio/music.mp3", "audio/music.flac"]), a.load("click", ["audio/click.flac"]), a.load("engine", ["audio/engine.flac"]), a.load("suspension", ["audio/suspension.flac"]), a.load("tires", ["audio/tires.flac"]), a.load("collision", ["audio/collision.flac"]), a.load("skidding", ["audio/skidding.flac"]), a.load("editor_edit", ["audio/editor_edit.flac"]), a.load("checkpoint", ["audio/checkpoint.flac"]), a.load("finish", ["audio/checkpoint.flac"]), $u.initResources(e); const s = Aw.initResources(); ex.initResources(e); const o = new GN, l = o.init(e), c = new _B; c.migrate(); const h = new cU(!0, o, e), d = new cU(!1, o, e), u = h.testDeterminism(); e.addResource(), e.addResource(), e.addResource(), s.then((t => { e.loadedResource(), l.then((n => { e.loadedResource(), u.then((i => { e.loadedResource(), g.determinismState = i ? n && t ? VI.Ok : VI.AssetsFailed : VI.TestFailed })).catch((e => { console.error(e) })) })).catch((e => { console.error(e) })) })).catch((e => { console.error(e) })); const p = new ZB(c), f = new Mz(p.getSetting($o.Language)), m = new gL(c), g = new HB; m.syncUserProfile(g); const v = new yN(c, g, m), w = document.getElementById("screen"), y = new Au(w, p), A = new rB(y, p, e), b = new VP(y), x = new jb(y, p, o), k = new LN(e, c), E = new SA, S = new eN(a), M = new JO, T = t => { i.trigger((() => { X_(), Z_(), L.dispose(), L = new BD(h, x, b, A, k, f, S, m, v, y, a, c, p, g, e, t, _, C, P, I, R), J_() })) }, _ = () => { i.trigger((() => { X_(), Z_(), L.dispose(), L = new pA(f, x, b, A, y, a, m, p, g, S, (() => { T(!1) })), J_() })) }, C = () => { i.trigger((() => { Z_(), L.dispose(); const t = L = new FM(x, o, c, b, A, f, a, y, p, i, m, v, k, S, M, (() => { X_(), Z_(), L.dispose(), L = new BD(h, x, b, A, k, f, S, m, v, y, a, c, p, g, e, !1, _, C, P, I, R), J_() }), ((e, n, i) => { const s = L = new AP(h, d, x, b, A, f, y, a, m, p, r, S, M, e, n, "custom", [], null, (() => {}), (() => { q_(), s.dispose(!1), L = t, i() }), null) })); return J_(), t.isPaused = !0, eC((() => { a.mute() }), "start-editor").finally((() => { q_(), a.unmute(), t.isPaused = !1 })) })) }, P = (e, t, n, s) => { i.trigger((() => { Z_(), L.dispose(); const i = m.profileSlot, o = v.getRecordTime(i, t.getId()), l = L = new AP(h, d, x, b, A, f, y, a, m, p, r, S, M, e, t, n, s, o, ((e, t, n) => { if (null != e) { const r = v.getRecordTime(i, e); (null == r || n.lessThan(r)) && v.setRecord(i, e, n, t) } }), (() => { T(!0) }), I); return J_(), l.isPaused = !0, eC((() => { a.mute() }), "start-game").finally((() => { a.unmute(), l.isPaused = !1 })) })) }, I = (e, t, n, r) => { i.trigger((() => { Z_(), L.dispose(), L = new YO(d, x, e, t, n, b, A, y, a, f, p, r, P), J_(), q_() })) }, R = t => { i.trigger((() => { Z_(), L.dispose(), L = new iz(a, y, g, k, o, p, e, t, (() => { T(!1) })), J_(), q_() })) }; let L = new BD(h, x, b, A, k, f, S, m, v, y, a, c, p, g, e, !1, _, C, P, I, R), D = 0; y.setAnimationLoop((function(e) { const t = Math.max(e - D, 0) / 1e3; D = e, L.update(t), E.update(t) })), window.addEventListener("keyup", (e => { p.checkKeyBinding(e, Ix.ToggleFpsCounter) && E.toggle() })) }() })() })();