UNPKG

@haelp/teto

Version:

A typescript-based controllable TETR.IO client.

1 lines 147 kB
{"version":3,"sources":["../../../../src/classes/ribbon/codecs/codec-candor.ts"],"sourcesContent":["// @ts-nocheck\nimport { Bits as n } from \"./utils/bits\";\nimport r from \"./utils/msgpackr-943ed70\";\nimport {\n OptionsList,\n spinbonuses_rules,\n kicksets,\n tetrominoes,\n minocolors\n} from \"./utils/shared\";\n\nimport { strictShallowEqual } from \"fast-equals\";\n\nconst e = Buffer;\n\nlet cached = {};\nfunction itdo(e: any) {\n const t = Object.prototype.toString.call(e);\n if (cached[t]) {\n return cached[t];\n } else {\n return (cached[t] = t.substring(8, t.length - 1).toLowerCase());\n }\n}\nfunction initOptions() {\n let OptionsTemplate = {};\n for (const [e, t] of Object.entries(OptionsList)) {\n OptionsTemplate[e] = t.default;\n const n = itdo(t.default);\n switch (n) {\n case \"boolean\":\n case \"number\":\n case \"array\":\n case \"object\":\n // @ts-ignore\n t.type = n;\n break;\n case \"string\":\n // @ts-ignore\n t.type = t.allowed || t.possibles ? \"table\" : \"string\";\n break;\n default:\n throw new TypeError(\n `Error while templating ${e}: typeof ${n} is not supported as default values`\n );\n }\n }\n}\ninitOptions();\nconst ve = {\n int64AsType: \"number\",\n bundleStrings: false,\n sequential: false\n};\nconst ke = new r.Packr(ve);\nconst we = new r.Unpackr(ve);\nconst Be = {\n F_ALLOC: 1,\n F_HOOK: 2,\n F_ID: 128\n};\nconst Le = new (class {\n _commands = new Map();\n _codes = new Map();\n _PACK = null;\n _UNPACK = null;\n SymCmd = Symbol(\"cmd\");\n FLAG = Be;\n SetMsgpackr(e, t) {\n this._PACK = e.pack.bind(e);\n this._UNPACK = t.unpack.bind(t);\n }\n GetHandlers() {\n const c = [];\n for (const t of this._commands.values()) {\n if (t.flags & this.FLAG.F_HOOK) {\n c.push(t.name);\n }\n }\n const h = this._commands.get(\"__pack__\")?.table;\n if (h) {\n c.push.apply(c, Object.keys(h));\n }\n return c;\n }\n Add(t, n) {\n this._commands.set(t, n);\n this._codes.set(n.code, n);\n n.name = t;\n if (n.flags & this.FLAG.F_ALLOC) {\n n.buffer = e.from([n.code]);\n }\n if (n.table) {\n n._kv = new Map();\n n._vk = new Map();\n n.getkv = (e) => n._kv.get(e);\n n.getvk = (e) => n._vk.get(e);\n for (const [e, t] of Object.entries(n.table)) {\n n._kv.set(e, t);\n n._vk.set(t, e);\n }\n }\n }\n Encode(t, n, i = {}) {\n const s = this._commands.get(t) ?? this._commands.get(\"__pack__\");\n let o = s.code;\n let r = 1;\n if (s.flags & this.FLAG.F_ALLOC) {\n return s.buffer;\n }\n if (!i.batched && (s.flags & this.FLAG.F_ID || i.id)) {\n r += 3;\n o |= this.FLAG.F_ID;\n }\n const a = s.encode(n, this._PACK, t);\n const l = e.allocUnsafe(r + a.byteLength);\n l.writeUInt8(o, 0);\n l.set(a, r);\n return l;\n }\n Decode(e) {\n const t = new n(e);\n const i = t.peek(6, 2);\n const s = this._codes.get(i);\n const o = {\n command: s?.name\n };\n let r = 1;\n if (!s) {\n throw new ReferenceError(\n `received an unknown code [0x${i.toString(16).padStart(2, \"0\")}]`\n );\n }\n if (s.flags & this.FLAG.F_ALLOC) {\n return o;\n }\n if (e[0] & this.FLAG.F_ID) {\n o.id = t.peek(24, 8);\n r += 3;\n }\n e = e.subarray(r);\n try {\n o.data = s.decode(e, this._UNPACK);\n } catch (t) {\n console.error(`Failed to decode command ${s.name}: ${e.toString()}`);\n throw t;\n }\n if (this.SymCmd in o.data) {\n o.command = o.data[this.SymCmd];\n o.data = o.data.data;\n }\n return o;\n }\n})();\n{\n const { F_ALLOC: t, F_HOOK: n, F_ID: i } = Le.FLAG;\n const s = {\n code: 25,\n flags: t\n };\n Le.Add(\"new\", s);\n const o = {\n code: 63,\n flags: t\n };\n Le.Add(\"die\", o);\n const r = {\n code: 19,\n flags: n | t\n };\n Le.Add(\"rejected\", r);\n const a = {\n code: 33,\n flags: n | t\n };\n Le.Add(\"reload\", a);\n Le.Add(\"ping\", {\n code: 9,\n flags: n,\n encode({ recvid: t }) {\n const n = e.allocUnsafe(4);\n n.writeUInt32BE(t, 0);\n return n;\n },\n decode(e) {\n return {\n recvid: e.readUInt32BE(0)\n };\n }\n });\n Le.Add(\"session\", {\n code: 44,\n encode({ ribbonid: t, tokenid: n }) {\n const i = e.allocUnsafe(16);\n i.write(t, 0, 8, \"hex\");\n i.write(n, 8, 8, \"hex\");\n return i;\n },\n decode: (e) => ({\n ribbonid: e.toString(\"hex\", 0, 8),\n tokenid: e.toString(\"hex\", 8, 16)\n })\n });\n Le.Add(\"packets\", {\n code: 7,\n encode({ packets: t }) {\n const n = t.reduce((e, t) => e + t.length, 0);\n const i = e.allocUnsafe(n + t.length * 4);\n for (let e = 0, n = 0; e < t.length; e++) {\n const s = t[e];\n i.writeUInt32BE(s.length, n);\n i.set(s, n + 4);\n n += s.length + 4;\n }\n return i;\n },\n decode(e) {\n const t = [];\n for (let n = 0; n < e.length; ) {\n const i = e.readUInt32BE(n);\n n += 4;\n const s = e.subarray(n, n + i);\n t.push(s);\n n += i;\n }\n return {\n packets: t\n };\n }\n });\n Le.Add(\"kick\", {\n table: {\n outdated: 1,\n kick: 2,\n restrict: 3,\n block: 4,\n anticheat: 5,\n manual: 6,\n rename: 7\n },\n flags: n,\n code: 4,\n encode({ reason: t }) {\n let n = e.allocUnsafe(1);\n const i = this.getkv(t);\n n.writeUInt8(i, 0);\n if (!i) {\n n = e.concat([n, e.from(t)]);\n }\n return n;\n },\n decode(e) {\n const t = e.readUInt8(0);\n let n = this.getvk(t);\n n ||= e.toString(\"utf8\", 1);\n return {\n reason: n\n };\n }\n });\n Le.Add(\"nope\", {\n table: {\n \"protocol violation\": 0,\n \"ribbon expired\": 1\n },\n code: 42,\n encode({ reason: t }) {\n return e.from([this.getkv(t)]);\n },\n decode(e) {\n const t = e.readUInt8(0);\n return {\n reason: this.getvk(t)\n };\n }\n });\n Le.Add(\"pni\", {\n table: {\n background: 0,\n split: 1,\n load: 2\n },\n code: 51,\n flags: n,\n encode({ type: t, timeout: n }) {\n const i = e.allocUnsafe(3);\n i.writeUInt8(this.getkv(t), 0);\n i.writeUInt16BE(n, 1);\n return i;\n },\n decode(e) {\n return {\n type: this.getvk(e.readUInt8(0)),\n timeout: e.readUInt16BE(1)\n };\n }\n });\n Le.Add(\"notify\", {\n table: {\n deny: 1,\n warm: 2,\n ok: 3,\n error: 4,\n announce: 5\n },\n code: 49,\n flags: n | i,\n encode(t, n) {\n const i = this.getkv(t.type);\n const s = e.from([i]);\n switch (i) {\n case 1: {\n const n = e.allocUnsafe(2 + t.msg.length);\n n.writeUInt16BE(t.timeout);\n n.write(t.msg, 2);\n return e.concat([s, n]);\n }\n case 2:\n case 3:\n case 4:\n case 5:\n return e.concat([s, e.from(t.msg)]);\n default:\n return e.concat([s, n(t)]);\n }\n },\n decode(e, t) {\n const n = e.readUInt8(0);\n const i = this.getvk(n);\n switch (n) {\n case 1:\n return {\n type: i,\n timeout: e.readUInt16BE(1),\n msg: e.toString(\"utf8\", 3)\n };\n case 2:\n case 3:\n case 4:\n case 5:\n return {\n type: i,\n msg: e.toString(\"utf8\", 1)\n };\n default:\n return t(e.subarray(1));\n }\n }\n });\n Le.Add(\"__pack__\", {\n table: {\n \"config.handling\": 1,\n \"channel.subscribe\": 2,\n \"channel.unsubscribe\": 3,\n \"social.presence\": 16,\n \"social.invite\": 17,\n \"social.link\": 18,\n \"social.online\": 19,\n \"social.notification\": 20,\n \"social.notification.ack\": 21,\n \"social.dm\": 22,\n \"social.dm.fail\": 23,\n \"social.relation.ack\": 24,\n \"social.relation.add\": 25,\n \"social.relation.remove\": 26,\n \"social.relation.update\": 27,\n \"social.relation.clear\": 28,\n \"social.party.invite\": 29,\n \"social.party.invite.accept\": 30,\n \"game.enter\": 48,\n \"game.replace\": 49,\n \"game.forfeit\": 50,\n \"game.ready\": 51,\n \"game.start\": 52,\n \"game.spectate\": 53,\n \"game.submit\": 54,\n \"game.advance\": 55,\n \"game.abort\": 56,\n \"game.end\": 57,\n \"game.score\": 58,\n \"game.waitstate\": 59,\n \"game.match\": 60,\n \"game.match.score\": 61,\n \"game.replay\": 62,\n \"game.replay.enter\": 63,\n \"game.replay.ige\": 64,\n \"game.replay.state\": 65,\n \"game.replay.board\": 66,\n \"game.replay.end\": 67,\n \"game.scope.start\": 68,\n \"game.scope.end\": 69,\n \"game.setspec\": 70,\n \"game.records.revolved\": 71,\n \"party.ready\": 80,\n \"party.leave\": 81,\n \"party.members\": 83,\n \"party.sync\": 82,\n \"staff.chat\": 96,\n \"staff.spam\": 97,\n \"staff.warn\": 98,\n \"staff.silence\": 99,\n \"staff.lift\": 100,\n \"staff.kickfail\": 101,\n \"staff.shout\": 102,\n \"staff.waterfall\": 103,\n \"staff.game.event\": 104,\n \"staff.xrc\": 105,\n \"room.create\": 128,\n \"room.join\": 129,\n \"room.leave\": 130,\n \"room.abort\": 131,\n \"room.start\": 132,\n \"room.kick\": 133,\n \"room.unban\": 134,\n \"room.banlist\": 135,\n \"room.setid\": 136,\n \"room.setconfig\": 137,\n \"room.update\": 138,\n \"room.update.bracket\": 139,\n \"room.update.host\": 140,\n \"room.update.auto\": 141,\n \"room.update.supporter\": 142,\n \"room.player.add\": 143,\n \"room.player.remove\": 144,\n \"room.bracket.switch\": 145,\n \"room.bracket.move\": 146,\n \"room.owner.transfer\": 147,\n \"room.owner.revoke\": 148,\n \"room.chat\": 149,\n \"room.chat.send\": 150,\n \"room.chat.clear\": 151,\n \"room.chat.delete\": 152,\n \"room.chat.gift\": 153,\n \"room.chat.game\": 154,\n \"room.call\": 155,\n \"league.enter\": 177,\n \"league.leave\": 178,\n \"league.match\": 179,\n \"league.counts\": 180,\n \"league.ready\": 181,\n \"server.maintenance\": 208,\n \"server.announcement\": 209,\n \"server.authorize\": 210,\n \"server.migrate\": 211,\n \"server.migrated\": 212,\n \"xrc.relog\": 255\n },\n flags: i,\n code: 43,\n encode(t, n, i) {\n const s = n(t);\n const o = e.allocUnsafe(1 + s.length);\n const r = this.getkv(i);\n o.writeUInt8(r, 0);\n o.set(s, 1);\n return o;\n },\n decode(e, t) {\n const n = e.readUInt8(0);\n const i = this.getvk(n);\n const s = t(e.subarray(1));\n return {\n [Le.SymCmd]: i,\n data: s\n };\n }\n });\n}\nconst Se = {\n Table: 0,\n Array: 1,\n Struct: 2,\n String: 3,\n Buffer: 4,\n Boolean: 5,\n Int: 6,\n UInt: 7,\n DInt: 8,\n Float: 9,\n UFloat: 10,\n Double: 11,\n Number: 12,\n Any: 13\n};\nconst Te = {\n NaN: 0,\n Infinity: 1,\n UInt: 2,\n Int: 3,\n Double: 4\n};\nconst Me = {\n BUFFER: 1,\n DOUBLE: 2,\n QWORD: 3,\n HEX: 4\n};\nclass Ee {\n static TYPES = Se;\n static TYPES_INDEX = Array.from(Object.keys(this.TYPES));\n static SUPPORTED_TYPES = new Set([\n \"undefined\",\n \"null\",\n \"boolean\",\n \"number\",\n \"string\",\n \"array\"\n ]);\n static cla32(e) {\n if (e >>> 0 === e) {\n return Math.max(32 - Math.clz32(e), 1);\n } else {\n return Math.max(32 - Math.clz32(~e) + 1, 2);\n }\n }\n static GetIntSize(e) {\n return Math.ceil(this.cla32(e) / 4);\n }\n static DInt = class {\n constructor({ min: e, max: t }) {\n this._minBits = e;\n this._maxBits = t;\n this._minSize = Math.pow(2, e);\n this._maxSize = Math.pow(2, t);\n }\n get minSize() {\n return this._minSize;\n }\n get maxSize() {\n return this._maxSize;\n }\n readSize(e) {\n if (e) {\n return this._maxBits;\n } else {\n return this._minBits;\n }\n }\n writeSize(e) {\n let t;\n switch (e) {\n case e >>> 0:\n t = this._minSize <= e;\n break;\n case e | 0:\n t = -this._minSize / 2 > e;\n break;\n default:\n throw new RangeError(\n `Float/Double is not supported for DInt: got ${e}`\n );\n }\n return {\n bit: t,\n size: t ? this._maxBits : this._minBits\n };\n }\n };\n static Number = new (class {\n TYPES = Te;\n encode(e, t) {\n const { TYPES: n } = this;\n if (typeof t != \"number\") {\n throw new TypeError(`Attempted to encode ${typeof t} as a number`);\n }\n if (Number.isNaN(t)) {\n return e.writeUInt(n.NaN, 3);\n }\n if (!Number.isFinite(t)) {\n e.writeUInt(n.Infinity, 3);\n return e.writeBoolean(t === Number.POSITIVE_INFINITY);\n }\n switch (t) {\n case t >>> 0: {\n const i = Ee.GetIntSize(t);\n e.writeUInt(n.UInt, 3);\n e.writeUInt(i - 1, 3);\n e.writeUInt(t, i * 4);\n break;\n }\n case t | 0: {\n const i = Ee.GetIntSize(t);\n e.writeUInt(n.Int, 3);\n e.writeUInt(i - 1, 3);\n e.writeInt(t, i * 4);\n break;\n }\n default:\n e.writeUInt(n.Double, 3);\n e.writeDouble(t);\n }\n }\n decode(e) {\n switch (e.readUInt(3)) {\n case 0:\n return NaN;\n case 1:\n if (e.readBoolean()) {\n return Number.POSITIVE_INFINITY;\n } else {\n return Number.NEGATIVE_INFINITY;\n }\n case 2: {\n const t = e.readUInt(3) + 1;\n return e.readUInt(t * 4);\n }\n case 3: {\n const t = e.readUInt(3) + 1;\n return e.readInt(t * 4);\n }\n case 4:\n return e.readDouble();\n }\n }\n })();\n static Table = class {\n constructor(e, t = \"strict\") {\n this._kv = new Map();\n this._vk = new Map();\n for (const [t, a] of e.entries()) {\n this._kv.set(a, t + 1);\n this._vk.set(t + 1, a);\n }\n this._mode = t;\n this._size = Math.floor(Math.log2(this._kv.size)) + 1;\n this.has = this._kv.has.bind(this._kv);\n }\n get mode() {\n return this._mode;\n }\n get size() {\n return this._size;\n }\n get struct() {\n const a = {};\n for (const [t, l] of this._kv.entries()) {\n a[t] = \"0x\" + l.toString(16).padStart(2, \"0\");\n }\n return a;\n }\n getkv(e) {\n return this._kv.get(e);\n }\n getvk(e) {\n return this._vk.get(e);\n }\n };\n static Array = class {\n constructor(e = \"default\", { list: t, min: n, max: i } = {}) {\n this._mode = e;\n switch (e) {\n case \"strict\":\n this._table = new Ee.Table(t);\n break;\n case \"flexible\":\n throw new Error(\"Flexible mode is not implemented yet\");\n case \"default\":\n }\n n = n ?? 7;\n i = i ?? 15;\n const h = {\n min: n,\n max: i\n };\n this._prop = new Ee.DInt(h);\n }\n get mode() {\n return this._mode;\n }\n encode(e, t) {\n e.writeDInt(t.length, this._prop);\n switch (this._mode) {\n case \"strict\":\n for (const n of t) {\n e.writeTable(n, this._table);\n }\n break;\n case \"flexible\":\n throw new Error(\"Flexible mode is not implemented yet\");\n default:\n for (const n of t) {\n e.writeAny(n, this);\n }\n }\n }\n decode(e) {\n const t = e.readDInt(this._prop);\n const n = [];\n if (this._mode === \"strict\") {\n for (let i = 0; i < t; i++) {\n n.push(e.readTable(this._table));\n }\n } else {\n for (let i = 0; i < t; i++) {\n n.push(e.readAny(this));\n }\n }\n return n;\n }\n };\n static init() {\n this.SUPPORTED_TYPES_TABLE = new this.Table(\n Array.from(this.SUPPORTED_TYPES.keys())\n );\n this.DEFAULT_ARRAY = new this.Array();\n this.DEFAULT_PROP = new this.DInt({\n min: 8,\n max: 32\n });\n }\n constructor() {\n this.ref = new Map();\n this.refid = 0;\n }\n static Encoder = class t extends this {\n static TYPES = Me;\n constructor(e = null, t = null) {\n super();\n this._buffer = [];\n this._size = 0;\n this._packr = e;\n this._packBuffer = t;\n }\n get buffer() {\n return this._buffer;\n }\n get size() {\n return this._size;\n }\n get byteLength() {\n return Math.ceil(this._size / 8);\n }\n realign() {\n return (this._size += (8 - (this._size % 8)) % 8);\n }\n _insert(e, t, n = null) {\n if (n) {\n this.realign();\n }\n this._size += t;\n return this._buffer.push({\n val: e,\n size: t,\n type: n\n });\n }\n writeTable(e, t) {\n if (t.mode === \"strict\") {\n return this._insert(t.getkv(e), t.size);\n }\n const n = t.getkv(e);\n if (n === undefined) {\n this._insert(null, t.size);\n return this.writeAny(e);\n } else {\n return this._insert(n, t.size);\n }\n }\n writeArray(e, t = Ee.DEFAULT_ARRAY) {\n if (t.mode === \"strict\") {\n return t.encode(this, e);\n } else if (this.ref.has(e)) {\n this._insert(true, 1);\n return this.writeDInt(this.ref.get(e), Ee.DEFAULT_PROP);\n } else {\n this._insert(false, 1);\n this.ref.set(e, this.refid++);\n return t.encode(this, e);\n }\n }\n writeStruct(e, t) {\n return t.encode(this, e);\n }\n writeString(n, i = true) {\n n = e.from(i ? `${n}\\0` : n);\n return this._insert(n, n.byteLength * 8, t.TYPES.BUFFER);\n }\n writeBuffer(e) {\n return this._insert(e, e.byteLength * 8, t.TYPES.BUFFER);\n }\n writeBoolean(e) {\n return this._insert(!!e, 1);\n }\n writeInt(e, t) {\n return this._insert(e, t);\n }\n writeUInt(e, t) {\n return this._insert(e, t);\n }\n writeUInt64(e) {\n return this._insert(e, 64, t.TYPES.QWORD);\n }\n writeDInt(e, t) {\n const n = t.writeSize(e);\n this._insert(n.bit, 1);\n return this._insert(e, n.size);\n }\n writeFloat(e, t, n) {\n this._insert(e < 0, 1);\n return this._insert(Math.round(e * n), t);\n }\n writeUFloat(e, t, n) {\n return this._insert(Math.round(e * n), t);\n }\n writeDouble(e) {\n return this._insert(e, 64, t.TYPES.DOUBLE);\n }\n writeNumber(e) {\n return Ee.Number.encode(this, e);\n }\n writeHex(e, n) {\n return this._insert(e, n * 8, t.TYPES.HEX);\n }\n writeAny(e, t) {\n const n = b(e);\n if (!Ee.SUPPORTED_TYPES.has(n)) {\n throw new TypeError(\n `Type ${n} is not implemented for NetCodec.TYPES.Any`\n );\n }\n this.writeTable(n, Ee.SUPPORTED_TYPES_TABLE);\n switch (n) {\n case \"boolean\":\n this.writeBoolean(e);\n break;\n case \"null\":\n case \"undefined\":\n break;\n case \"number\":\n Ee.Number.encode(this, e);\n break;\n case \"string\":\n this.writeString(e);\n break;\n case \"array\":\n this.writeArray(e, t);\n }\n }\n writeByType(e, t, ...n) {\n return this[`write${Ee.TYPES_INDEX[e]}`](t, ...n);\n }\n pack(e) {\n this._packr.useBuffer(this._packBuffer);\n const n = this._packr.pack(e);\n return this._insert(n, n.byteLength * 8, t.TYPES.BUFFER);\n }\n finalize(i = null) {\n const s = i ?? e.allocUnsafe(this.byteLength);\n const o = new n(s);\n for (const { val: e, size: n, type: i } of this._buffer) {\n switch (i) {\n case t.TYPES.BUFFER:\n o.offset += (8 - (o.offset % 8)) % 8;\n s.set(e, o.offset / 8);\n o.seek(e.byteLength * 8, 2);\n break;\n case t.TYPES.DOUBLE:\n o.offset += (8 - (o.offset % 8)) % 8;\n s.writeDoubleBE(e, o.offset / 8);\n o.seek(64, 2);\n break;\n case t.TYPES.QWORD:\n o.offset += (8 - (o.offset % 8)) % 8;\n s.writeBigUInt64BE(e, o.offset / 8);\n o.seek(64, 2);\n break;\n case t.TYPES.HEX:\n o.offset += (8 - (o.offset % 8)) % 8;\n s.write(e, o.offset / 8, \"hex\");\n o.seek(n, 2);\n break;\n default:\n o.write(e, n);\n }\n }\n return s;\n }\n };\n static Decoder = class e extends this {\n static _MAX_BITS = Math.log2(Number.MAX_SAFE_INTEGER);\n static _MAX_BITS_SIGNED = 32;\n constructor(e, t = null) {\n super();\n this._bits = new n(e);\n this._unpack = t;\n }\n get length() {\n return this._bits.length;\n }\n get offset() {\n return this._bits.offset;\n }\n set offset(e) {\n this._bits.offset = e;\n }\n get buffer() {\n return this._bits.buffer;\n }\n get byteOffset() {\n return Math.ceil(this.offset / 8);\n }\n realign() {\n this.offset = this.byteOffset * 8;\n }\n _read_signed(t) {\n const n = e._MAX_BITS_SIGNED - t;\n return (this._read(t) << n) >> n;\n }\n _read(e) {\n return this._bits.read(e);\n }\n readTable(e) {\n const t = e.size;\n if (this.peek(t) !== 0) {\n return e.getvk(this._read(t));\n } else {\n this.seek(t, 2);\n return this.readAny();\n }\n }\n readArray(e = Ee.DEFAULT_ARRAY) {\n if (e.mode === \"strict\") {\n return e.decode(this);\n }\n if (this._read(1)) {\n return this.ref.get(this.readDInt(Ee.DEFAULT_PROP));\n }\n const t = [];\n this.ref.set(this.refid++, t);\n t.push.apply(t, e.decode(this));\n return t;\n }\n readStruct(e) {\n return e.decode(this);\n }\n readString(e) {\n const t = this.byteOffset;\n let n;\n if (typeof e == \"number\") {\n n = t + e;\n this.seek(n * 8);\n } else {\n n = this.buffer.indexOf(0, t);\n this.seek((n + 1) * 8);\n }\n return this.buffer.toString(\"utf8\", t, n);\n }\n readBuffer(e) {\n const t = this.byteOffset;\n const n = t + e;\n this.seek(n * 8);\n return this.buffer.subarray(t, n);\n }\n readBoolean() {\n return !!this._read(1);\n }\n readInt(t) {\n if (t > e._MAX_BITS_SIGNED) {\n throw new RangeError(\n `${t} of bits is not supported for signed values, max is ${e._MAX_BITS_SIGNED}`\n );\n }\n return this._read_signed(t);\n }\n readUInt(t) {\n if (t > e._MAX_BITS) {\n throw new RangeError(\n `${t} of bits is not supported, max is ${e._MAX_BITS}`\n );\n }\n return this._read(t);\n }\n readUInt64() {\n const e = this.byteOffset;\n this.seek(e * 8 + 64);\n return this.buffer.readBigUInt64BE(e);\n }\n readDInt(e, t = false) {\n const n = e.readSize(this._read(1));\n if (t) {\n return this._read_signed(n);\n } else {\n return this._read(n);\n }\n }\n readFloat(e, t) {\n if (this.peek(1)) {\n return this._read_signed(e + 1) / t;\n } else {\n this.seek(1, 2);\n return this._read(e) / t;\n }\n }\n readUFloat(e, t) {\n return this._read(e) / t;\n }\n readDouble() {\n const e = this.byteOffset;\n this.seek(e * 8 + 64);\n return this.buffer.readDoubleBE(e);\n }\n readNumber() {\n return Ee.Number.decode(this);\n }\n readHex(e) {\n const t = this.byteOffset;\n const n = t + e;\n this.seek(n * 8);\n return this.buffer.toString(\"hex\", t, n);\n }\n readAny(e) {\n switch (this.readTable(Ee.SUPPORTED_TYPES_TABLE)) {\n case \"boolean\":\n return this.readBoolean();\n case \"null\":\n return null;\n case \"undefined\":\n return;\n case \"number\":\n return Ee.Number.decode(this);\n case \"string\":\n return this.readString();\n case \"array\":\n return this.readArray(e);\n }\n }\n readByType(e, ...t) {\n return this[`read${Ee.TYPES_INDEX[e]}`](...t);\n }\n peek(e, t) {\n return this._bits.peek(e, t);\n }\n peekTable(e, t = this.offset) {\n return e.getvk(this.peek(e.size, t));\n }\n peekDInt(e, t = this.offset) {\n return this.peek(e.readSize(this.peek(1, t)), t + 1);\n }\n seek(e, t) {\n this._bits.seek(e, t);\n }\n unpack() {\n this.realign();\n return this._unpack(this.byteOffset);\n }\n };\n}\nclass De {\n static _MAX_BUFFER = 65536;\n static BUFFER = e.alloc(this._MAX_BUFFER);\n static _LIST = {};\n static get LIST() {\n return this._LIST;\n }\n static AddExtension(t, n = {}) {\n this._LIST[t.name] = t;\n if (\"ownBuffer\" in n) {\n t.BUFFER = e.alloc(this._MAX_BUFFER);\n }\n }\n static AddTable(e, t, n) {\n this[\"$$\" + e] = new Ee.Table(t, n);\n }\n static AddProperty(e, t) {\n this[\"$\" + e] = new Ee.DInt(t);\n }\n static LoadExtensions(e) {\n let a = 10;\n function l(e) {\n return e.encode.call(e, new Ee.Encoder(this, e.constructor.BUFFER));\n }\n function h(e, t, n, i) {\n return e.decode(new Ee.Decoder(t, (e) => n(i + e)));\n }\n for (const n of Object.values(this._LIST)) {\n n.ext_code = a++;\n e.addExtension({\n Class: n,\n type: n.ext_code,\n pack: l,\n unpack: h.bind(null, n)\n });\n }\n }\n}\nclass Oe extends De {\n static AddStructure(e) {\n this._cstFields = new Map();\n this._fixFields = new Map();\n this._optFields = new Map();\n for (const [t, { mode: n, type: c, size: h, value: u }] of Object.entries(\n e\n )) {\n switch (n) {\n case \"static\":\n this._cstFields.set(t, u);\n break;\n case \"fixed\":\n const e = {\n type: c,\n size: h\n };\n this._fixFields.set(t, e);\n break;\n case \"optional\":\n const n = {\n type: c,\n size: h\n };\n this._optFields.set(t, n);\n }\n }\n super.AddTable(\"prop\", Array.from(this._optFields.keys()));\n }\n static encode(e, t) {\n for (const [n, { type: i, size: s }] of this._fixFields.entries()) {\n e.writeByType(i, t[n], s);\n }\n for (const [n, { type: i, size: s }] of this._optFields.entries()) {\n if (t[n] !== undefined) {\n if (i !== Ee.TYPES.DInt || t[n] !== null) {\n e.writeTable(n, this.$$prop);\n e.writeByType(i, t[n], s);\n }\n }\n }\n e.writeUInt(null, this.$$prop.size);\n }\n static decode(e) {\n const t = {};\n const n = this.$$prop.size;\n for (const [n, { type: i, size: s }] of this._fixFields.entries()) {\n t[n] = e.readByType(i, s);\n }\n for (let i = e.peek(n); i !== 0; i = e.peek(n)) {\n const n = e.readTable(this.$$prop);\n const { type: i, size: s } = this._optFields.get(n);\n const o = e.readByType(i, s);\n t[n] = o;\n }\n for (const [e, n] of this._cstFields.entries()) {\n t[e] = n;\n }\n return t;\n }\n}\nclass Pe extends De {\n static init() {\n super.AddExtension(this);\n super.AddProperty(\"prov\", {\n min: 18,\n max: 26\n });\n }\n static decode(e) {\n return new this(e.readUInt(13), e.readDInt(this.$prov), e.unpack());\n }\n constructor(e, t, n) {\n super();\n this.gameid = e;\n this.provisioned = t;\n this.frames = n.map((e) => new Re(e));\n }\n encode(e) {\n const t = this.constructor;\n const n = this.provisioned;\n e.writeUInt(this.gameid, 13);\n e.writeDInt(n, t.$prov);\n e.pack(this.frames);\n return e.finalize();\n }\n}\nclass We extends De {\n static init() {\n super.AddExtension(this);\n super.AddProperty(\"long\", {\n min: 16,\n max: 32\n });\n }\n static decode(e) {\n const t = [];\n const n = e.readUInt(13);\n for (let i = 0; i < n; i++) {\n const n = {\n board: {}\n };\n n.gameid = e.readUInt(13);\n n.board.f = e.readUInt(10);\n n.board.g = e.readDInt(this.$long);\n n.board.w = e.readUInt(Ue.MAX_WIDTH);\n n.board.h = e.readUInt(Ue.MAX_HEIGHT);\n n.board.b = e.readStruct(Ue);\n t[i] = n;\n }\n return new this(t);\n }\n constructor(e) {\n super();\n this.boards = e;\n }\n encode(e) {\n const t = this.constructor;\n e.writeUInt(this.boards.length, 13);\n for (const {\n gameid: n,\n board: { b: i, f: s, g: o, w: r, h: a }\n } of this.boards) {\n e.writeUInt(n, 13);\n e.writeUInt(s, 10);\n e.writeDInt(o, t.$long);\n e.writeUInt(r, Ue.MAX_WIDTH);\n e.writeUInt(a, Ue.MAX_HEIGHT);\n e.writeStruct(i, Ue);\n }\n return e.finalize();\n }\n}\nclass He extends De {\n static init() {\n super.AddExtension(this);\n super.AddTable(\"extraStat\", [\n \"none\",\n \"revives\",\n \"escapeartist\",\n \"blockrationing_app\",\n \"blockrationing_final\",\n \"talentless\"\n ]);\n }\n static decode(e) {\n const t = [];\n const n = e.readUInt(13);\n for (let i = 0; i < n; i++) {\n const n = {\n stats: {},\n allies: []\n };\n t[i] = n;\n n.gameid = e.readUInt(13);\n n.stats.rank = e.readUInt(6);\n n.stats.altitude = e.readFloat(18, 10);\n n.stats.btb = e.readUInt(13);\n n.specCount = e.readUInt(10);\n n.speedrun = e.readBoolean();\n n.nearWR = e.readBoolean();\n const s = e.readUInt(3);\n for (let t = 0; t < s; t++) {\n n.allies.push(e.readUInt(13));\n }\n n.stats.revives = 0;\n n.stats.escapeartist = 0;\n n.stats.blockrationing_app = 0;\n n.stats.blockrationing_final = 0;\n switch (e.readTable(this.$$extraStat)) {\n case \"none\":\n break;\n case \"revives\":\n n.stats.revives = e.readUInt(8);\n break;\n case \"escapeartist\":\n n.stats.escapeartist = e.readUInt(9);\n break;\n case \"blockrationing_app\":\n n.stats.blockrationing_app = e.readFloat(10, 100);\n break;\n case \"blockrationing_final\":\n n.stats.blockrationing_final = e.readUInt(11);\n break;\n case \"talentless\":\n n.talentless = true;\n }\n }\n return new this(t);\n }\n constructor(e) {\n super();\n this.sb = e;\n }\n encode(e) {\n const t = this.constructor;\n e.writeUInt(this.sb.length, 13);\n for (const {\n gameid: n,\n stats: i,\n allies: s,\n specCount: o,\n speedrun: r,\n nearWR: a,\n talentless: l\n } of this.sb) {\n e.writeUInt(n, 13);\n e.writeUInt(Math.floor(i.rank), 6);\n e.writeFloat(i.altitude.toFixed(2), 18, 10);\n e.writeUInt(i.btb, 13);\n e.writeUInt(o, 10);\n e.writeBoolean(r);\n e.writeBoolean(a);\n if (s) {\n e.writeUInt(s.length, 3);\n for (const t of s) {\n e.writeUInt(t, 13);\n }\n } else {\n e.writeUInt(0, 3);\n }\n let c = \"none\";\n if (i.revives) {\n c = \"revives\";\n }\n if (i.escapeartist) {\n c = \"escapeartist\";\n }\n if (i.blockrationing_app) {\n c = \"blockrationing_app\";\n }\n if (i.blockrationing_final) {\n c = \"blockrationing_final\";\n }\n if (l) {\n c = \"talentless\";\n }\n e.writeTable(c, t.$$extraStat);\n switch (c) {\n case \"none\":\n case \"talentless\":\n break;\n case \"revives\":\n e.writeUInt(i.revives, 8);\n break;\n case \"escapeartist\":\n e.writeUInt(i.escapeartist, 9);\n break;\n case \"blockrationing_app\":\n e.writeFloat(i.blockrationing_app.toFixed(3), 10, 100);\n break;\n case \"blockrationing_final\":\n e.writeUInt(i.blockrationing_final, 11);\n }\n }\n return e.finalize();\n }\n}\nclass Re extends De {\n static init() {\n super.AddExtension(this, {\n ownBuffer: true\n });\n super.AddProperty(\"frame\", {\n min: 18,\n max: 26\n });\n super.AddTable(\"type\", [\n \"keydown\",\n \"keyup\",\n \"start\",\n \"full\",\n \"end\",\n \"ige\",\n \"strategy\",\n \"manual_target\"\n ]);\n super.AddTable(\"key\", [\n \"moveLeft\",\n \"moveRight\",\n \"rotate180\",\n \"rotateCCW\",\n \"rotateCW\",\n \"softDrop\",\n \"hardDrop\",\n \"undo\",\n \"redo\",\n \"hold\",\n \"retry\",\n \"exit\"\n ]);\n }\n static decode(e) {\n const t = {};\n t.type = e.readTable(this.$$type);\n t.frame = e.readDInt(this.$frame);\n switch (t.type) {\n case \"keydown\":\n case \"keyup\": {\n const n = e.readTable(this.$$key);\n const i = e.readBoolean();\n const s = {\n key: n,\n subframe: e.readFloat(4, 10)\n };\n if (i) {\n s.hoisted = true;\n }\n t.data = s;\n break;\n }\n case \"start\":\n t.data = {};\n break;\n case \"full\":\n t.data = e.readStruct($e);\n break;\n case \"end\":\n t.data = e.readStruct(nt);\n break;\n case \"ige\":\n t.data = e.readStruct(je);\n break;\n case \"strategy\":\n t.data = e.readUInt(3);\n break;\n case \"manual_target\":\n t.data = e.readUInt(13);\n break;\n default:\n t.data = e.unpack();\n }\n return new this(t);\n }\n constructor(e) {\n super();\n this.type = e.type;\n this.frame = e.frame;\n this.data = e.data;\n }\n encode(e) {\n const t = this.constructor;\n e.writeTable(this.type, t.$$type);\n e.writeDInt(this.frame, t.$frame);\n switch (this.type) {\n case \"keydown\":\n case \"keyup\": {\n const n = this.data.hoisted;\n const i = this.data.subframe;\n e.writeTable(this.data.key, t.$$key);\n e.writeBoolean(n);\n e.writeFloat(i, 4, 10);\n return e.finalize();\n }\n case \"start\":\n return e.finalize();\n case \"full\":\n e.writeStruct(this.data, $e);\n return e.finalize();\n case \"end\":\n e.writeStruct(this.data, nt);\n return e.finalize();\n case \"ige\":\n e.writeStruct(this.data, je);\n return e.finalize();\n case \"strategy\":\n e.writeUInt(this.data, 3);\n return e.finalize();\n case \"manual_target\":\n e.writeUInt(this.data, 13);\n return e.finalize();\n default:\n console.warn(\n `Fallback to packer ${this.type} -> ${JSON.stringify(this.data)}`\n );\n e.pack(this.data);\n return e.finalize();\n }\n }\n}\nclass Ne extends De {\n static init() {\n super.AddExtension(this);\n }\n static decode(e) {\n const t = [];\n const n = e.readUInt(13);\n for (let i = 0; i < n; i++) {\n const n = {};\n n.userid = e.readHex(12);\n n.gameid = e.readUInt(13);\n n.alive = e.readBoolean();\n n.naturalorder = e.readUInt(13);\n n.options = e.readStruct(et);\n t.push(n);\n }\n return t;\n }\n constructor(e) {\n super();\n this.players = e;\n }\n encode(e) {\n e.writeUInt(this.players.length, 13);\n for (const {\n gameid: t,\n userid: n,\n alive: i,\n naturalorder: s,\n options: o\n } of this.players) {\n e.writeHex(n, 12);\n e.writeUInt(t, 13);\n e.writeBoolean(i);\n e.writeUInt(s, 13);\n e.writeStruct(o, et);\n }\n return e.finalize();\n }\n}\nclass $e extends De {\n static init() {\n super.AddTable(\"piece\", [null, ...Object.keys(tetrominoes)], \"flexible\");\n super.AddTable(\"ixs\", [\"off\", \"hold\", \"tap\"]);\n }\n static encode(e, t) {\n const n = t.game.board;\n const i = t.game.bag;\n const s = t.game.hold;\n const o = t.game.g;\n const r = t.game.controlling;\n const a = t.game.falling;\n const l = t.game.handling;\n e.writeUInt(i.length, 12);\n for (const t of i) {\n e.writeTable(t, this.$$piece);\n }\n e.writeStruct(n, Ue);\n e.writeBoolean(s.locked);\n e.writeTable(s.piece, this.$$piece);\n e.writeDouble(o);\n e.writeBoolean(r.inputSoftdrop);\n e.writeBoolean(r.lastshift === -1);\n e.writeBoolean(r.lShift.held);\n e.writeBoolean(r.rShift.held);\n e.writeUInt(t.diyusi, 4);\n e.writeDouble(r.lShift.arr);\n e.writeDouble(r.rShift.arr);\n e.writeDouble(r.lShift.das);\n e.writeDouble(r.rShift.das);\n e.writeStruct(a, Xe);\n e.writeFloat(l.arr, 6, 10);\n e.writeUInt(l.sdf, 6);\n e.writeBoolean(l.safelock);\n e.writeBoolean(l.cancel);\n e.writeBoolean(l.may20g);\n e.writeBoolean(t.game.playing);\n e.writeFloat(l.das, 8, 10);\n e.writeFloat(l.dcd, 8, 10);\n e.writeTable(l.irs, this.$$ixs);\n e.writeTable(l.ihs, this.$$ixs);\n e.writeStruct(t.stats, qe);\n }\n static decode(e) {\n const t = {};\n const n = {\n bag: [],\n controlling: {\n lShift: {\n dir: -1\n },\n rShift: {\n dir: 1\n }\n },\n handling: {}\n };\n const i = n.controlling;\n const s = n.handling;\n const o = e.readUInt(12);\n for (let t = 0; t < o; t++) {\n n.bag.push(e.readTable(this.$$piece));\n }\n n.board = e.readStruct(Ue);\n n.hold = {\n locked: e.readBoolean(),\n piece: e.readTable(this.$$piece)\n };\n n.g = e.readDouble();\n i.inputSoftdrop = e.readBoolean();\n i.lastshift = e.readBoolean() ? -1 : 1;\n i.lShift.held = e.readBoolean();\n i.rShift.held = e.readBoolean();\n t.diyusi = e.readUInt(4);\n i.lShift.arr = e.readDouble();\n i.rShift.arr = e.readDouble();\n i.lShift.das = e.readDouble();\n i.rShift.das = e.readDouble();\n n.falling = e.readStruct(Xe);\n s.arr = e.readFloat(6, 10);\n s.sdf = e.readUInt(6);\n s.safelock = e.readBoolean();\n s.cancel = e.readBoolean();\n s.may20g = e.readBoolean();\n n.playing = e.readBoolean();\n s.das = e.readFloat(8, 10);\n s.dcd = e.readFloat(8, 10);\n s.irs = e.readTable(this.$$ixs);\n s.ihs = e.readTable(this.$$ixs);\n t.stats = e.readStruct(qe);\n t.game = n;\n return t;\n }\n}\nclass Ue extends De {\n static MAX_WIDTH = Math.log2(512);\n static MAX_HEIGHT = Math.log2(512);\n static init() {\n super.AddTable(\"blk\", [false, null, ...minocolors]);\n }\n static encode(e, t) {\n const n = t[0]?.length ?? 0;\n const i = t.length;\n if (!n) {\n return e.writeUInt(0, this.MAX_WIDTH);\n }\n e.writeUInt(n, this.MAX_WIDTH);\n e.writeUInt(i, this.MAX_HEIGHT);\n for (const n of t) {\n if (n.some((e) => e !== null)) {\n for (const t of n) {\n e.writeTable(t, this.$$blk);\n }\n } else {\n e.writeTable(false, this.$$blk);\n }\n }\n }\n static decode(e) {\n const t = [];\n const n = e.readUInt(this.MAX_WIDTH);\n if (!n) {\n return t;\n }\n const i = e.readUInt(this.MAX_HEIGHT);\n for (let s = 0; s < i; s++) {\n if (e.peekTable(this.$$blk) !== false) {\n t[s] = [];\n for (let i = 0; i < n; i++) {\n t[s][i] = e.readTable(this.$$blk);\n }\n } else {\n e.seek(4, 2);\n t[s] = new Array(n).fill(null);\n }\n }\n return t;\n }\n}\nclass Xe extends De {\n static init() {\n super.AddTable(\"piece\", [null, ...Object.keys(tetrominoes)], \"flexible\");\n }\n static encode(e, t) {\n e.writeTable(t.type, this.$$piece);\n e.writeInt(t.x, Ue.MAX_WIDTH);\n e.writeUInt(t.r, 2);\n e.writeUInt(t.hy, Ue.MAX_HEIGHT);\n e.writeUInt(t.irs, 2);\n e.writeUInt(t.kick, 5);\n e.writeUInt(t.keys, 16);\n e.writeUInt(t.flags, 15);\n e.writeUInt(t.safelock, 3);\n e.writeUInt(t.lockresets, 5);\n e.writeUInt(t.rotresets, 6);\n e.writeBoolean(t.skip.length);\n if (t.skip.length) {\n for (const n of t.skip) {\n e.writeUInt(n + 1, 7);\n }\n e.writeUInt(0, 7);\n }\n e.writeDouble(t.y);\n e.writeDouble(t.locking);\n }\n static decode(e) {\n const t = {};\n t.type = e.readTable(this.$$piece);\n t.x = e.readInt(Ue.MAX_WIDTH);\n t.r = e.readUInt(2);\n t.hy = e.readUInt(Ue.MAX_HEIGHT);\n t.irs = e.readUInt(2);\n t.kick = e.readUInt(5);\n t.keys = e.readUInt(16);\n t.flags = e.readUInt(15);\n t.safelock = e.readUInt(3);\n t.lockresets = e.readUInt(5);\n t.rotresets = e.readUInt(6);\n t.skip = [];\n if (e.readBoolean()) {\n const n = 7;\n for (let i = e.peek(n); i !== 0; i = e.peek(n)) {\n t.skip.push(e.readUInt(n) - 1);\n }\n e.seek(n, 2);\n }\n t.y = e.readDouble();\n t.locking = e.readDouble();\n return t;\n }\n}\nclass qe extends De {\n static init() {\n super.AddTable(\"piece\", [...Object.keys(tetrominoes)], \"flexible\");\n super.AddProperty(\"short\", {\n min: 8,\n max: 16\n });\n super.AddProperty(\"long\", {\n min: 16,\n max: 32\n });\n this._clears = [\n \"singles\",\n \"doubles\",\n \"triples\",\n \"quads\",\n \"pentas\",\n \"realtspins\",\n \"minitspins\",\n \"minitspinsingles\",\n \"tspinsingles\",\n \"minitspindoubles\",\n \"tspindoubles\",\n \"minitspintriples\",\n \"tspintriples\",\n \"minitspinquads\",\n \"tspinquads\",\n \"tspinpentas\",\n \"allclear\"\n ];\n }\n static encode(e, t) {\n const n = t.garbage;\n const i = t.clears;\n const s = t.finesse;\n e.writeDInt(t.lines, this.$short);\n e.writeDInt(t.level_lines, this.$short);\n e.writeDInt(t.level_lines_needed, this.$short);\n e.writeDInt(t.inputs, this.$long);\n e.writeDInt(t.holds, this.$long);\n e.writeDInt(t.score, this.$long);\n e.writeUInt(t.level, 8);\n e.writeDInt(t.combo, this.$long);\n e.writeDInt(t.topcombo, this.$long);\n e.writeUInt(t.combopower, 3);\n e.writeDInt(t.btb, this.$short);\n e.writeDInt(t.topbtb, this.$short);\n e.writeUInt(t.btbpower, 8);\n e.writeDInt(t.tspins, this.$long);\n e.writeDInt(t.piecesplaced, this.$long);\n for (const t of this._clears) {\n e.writeDInt(i[t], this.$short);\n }\n e.writeDInt(n.sent, this.$long);\n e.writeDInt(n.sent_nomult, this.$long);\n e.writeDInt(n.maxspike, this.$long);\n e.writeDInt(n.maxspike_nomult, this.$long);\n e.writeDInt(n.received, this.$long);\n e.writeDInt(n.attack, this.$long);\n e.writeDInt(n.cleared, this.$long);\n e.writeDInt(t.kills, this.$short);\n e.writeDInt(s.combo, this.$long);\n e.writeDInt(s.faults, this.$long);\n e.writeDInt(s.perfectpieces, this.$long);\n e.writeStruct(t.zenith, Ke);\n }\n static decode(e) {\n const t = {\n zenlevel: 1,\n zenprogress: 0,\n clears: {},\n garbage: {},\n finesse: {}\n };\n t.lines = e.readDInt(this.$short);\n t.level_lines = e.readDInt(this.$short);\n t.level_lines_needed = e.readDInt(this.$short);\n t.inputs = e.readDInt(this.$long);\n t.holds = e.readDInt(this.$long);\n t.score = e.readDInt(this.$long);\n t.level = e.readUInt(8);\n t.combo = e.readDInt(this.$long);\n t.topcombo = e.readDInt(this.$long);\n t.combopower = e.readUInt(3);\n t.btb = e.readDInt(this.$short);\n t.topbtb = e.readDInt(this.$short);\n t.btbpower = e.readUInt(8);\n t.tspins = e.readDInt(this.$long);\n t.piecesplaced = e.readDInt(this.$long);\n for (const n of this._clears) {\n t.clears[n] = e.readDInt(this.$short);\n }\n t.garbage.sent = e.readDInt(this.$long);\n t.garbage.sent_nomult = e.readDInt(this.$long);\n t.garbage.maxspike = e.readDInt(this.$long);\n t.garbage.maxspike_nomult = e.readDInt(this.$long);\n t.garbage.received = e.readDInt(this.$long);\n t.garbage.attack = e.readDInt(this.$long);\n t.garbage.cleared = e.readDInt(this.$long);\n t.kills = e.readDInt(this.$short);\n t.finesse.combo = e.readDInt(this.$long);\n t.finesse.faults = e.readDInt(this.$long);\n t.finesse.perfectpieces = e.readDInt(this.$long);\n t.zenith = e.readStruct(Ke);\n return t;\n }\n}\nclass Ke extends De {\n static init() {\n super.AddProperty(\"long\", {\n min: 16,\n max: 32\n });\n }\n static encode(e, t) {\n e.writeDouble(t.altitude);\n e.writeDouble(t.rank);\n e.writeDouble(t.peakrank);\n e.writeDouble(t.avgrankpts);\n e.writeDouble(t.totalbonus);\n e.writeFloat(t.targetingfactor, 16, 100);\n e.writeFloat(t.targetinggrace, 16, 100);\n e.writeUInt(t.floor, 4);\n e.writeUInt(t.revives, 8);\n e.writeUInt(t.revivesTotal, 8);\n e.writeBoolean(t.speedrun);\n e.writeBoolean(t.speedrun_seen);\n for (let n = 0; n < 9; n++) {\n e.writeDInt(t.splits[n], this.$long);\n }\n }\n static decode(e) {\n const t = {};\n t.altitude = e.readDouble();\n t.rank = e.readDouble();\n t.peakrank = e.readDouble();\n t.avgrankpts = e.readDouble();\n t.totalbonus = e.readDouble();\n t.targetingfactor = e.readFloat(16, 100);\n t.targetinggrace = e.readFloat(16, 100);\n t.floor = e.readUInt(4);\n t.revives = e.readUInt(8);\n t.revivesTotal = e.readUInt(8);\n t.revivesMaxOfBoth = Math.max(t.revives, t.revivesTotal - t.revives);\n t.speedrun = e.readBoolean();\n t.speedrun_seen = e.readBoolean();\n t.splits = [];\n for (let n = 0; n < 9; n++) {\n t.splits[n] = e.readDInt(this.$long);\n }\n return t;\n }\n}\nclass je extends De {\n static init() {\n super.AddProperty(\"byte\", {\n min: 8,\n max: 24\n });\n super.AddTable(\"type\", [\n \"interaction\",\n \"interaction_confirm\",\n \"target\",\n \"targeted\",\n \"allow_targeting\",\n \"kev\",\n \"custom\"\n ]);\n super.AddTable(\"int_type\", [\n \"garbage\",\n \"zenith.climb_pts\",\n \"zenith.bonus\",\n \"zenith.incapacitated\",\n \"zenith.revive\"\n ]);\n }\n static encode(e, t) {\n const n = t.frame;\n const i = t.type;\n const s = t.data;\n e.writeDInt(t.id, this.$byte);\n e.writeDInt(n, this.$byte);\n e.writeTable(i, this.$$type);\n switch (i) {\n case \"interaction\":\n return e.writeStruct(s, Ve);\n case \"interaction_confirm\":\n e.writeTable(s.type, this.$$int_type);\n switch (s.type) {\n case \"garbage\":\n return e.writeStruct(s, Ve);\n case \"zenith.climb_pts\":\n case \"zenith.bonus\":\n e.writeUInt(s.gameid, 13);\n e.writeDInt(s.frame, this.$byte);\n return e.writeDouble(s.amt);\n case \"zenith.incapacitated\":\n case \"zenith.revive\":\n e.writeUInt(s.gameid, 13);\n return e.writeDInt(s.frame, this.$byte);\n default:\n throw new Error(`Unknown interaction type received: ${s.type}`);\n }\n case \"target\":\n e.writeUInt(s.targets.length, 13);\n for (const t of s.targets) {\n e.writeUInt(t, 13);\n }\n break;\n case \"targeted\":\n e.writeBoolean(s.value);\n e.writeUInt(s.gameid, 13);\n e.writeDInt(s.frame, this.$byte);\n break;\n case \"allow_targeting\":\n e.writeBoolean(s.value);\n break;\n case \"kev\":\n e.writeUInt(s.victim.gameid, 13);\n e.writeUInt(s.killer.gameid, 13);\n e.writeDInt(s.frame, this.$byte);\n e.writeUInt(s.fire, 10);\n break;\n case \"custom\":\n return e.writeStruct(s, Qe);\n }\n }\n static decode(e) {\n const t = {};\n t.id = e.readDInt(this.$byte);\n t.frame = e.readDInt(this.$byte);\n t.type = e.readTable(this.$$type);\n e: switch (t.type) {\n case \"interaction\":\n t.data = e.readStruct(Ve);\n break;\n case \"interaction_confirm\": {\n const n = e.readTable(this.$$int_type);\n switch (n) {\n case \"garbage\":\n t.data = e.readStruct(Ve);\n break e;\n case \"zenith.climb_pts\":\n case \"zenith.bonus\":\n t.data = {\n type: n,\n gameid: e.readUInt(13),\n frame: e.readDInt(this.$byte),\n