@jsprismarine/raknet
Version:
Basic RakNet implementation written in TypeScript
104 lines (103 loc) • 13.3 kB
JavaScript
"use strict";
Object.defineProperties(exports, {
__esModule: { value: true },
[Symbol.toStringTag]: { value: "Module" }
});
const require_runtime = require("../_virtual/_rolldown/runtime.cjs.cjs");
const require_protocol_BitFlags = require("./BitFlags.cjs.cjs");
const require_protocol_FrameReliability = require("./FrameReliability.cjs.cjs");
let _jsprismarine_jsbinaryutils = require("@jsprismarine/jsbinaryutils");
_jsprismarine_jsbinaryutils = require_runtime.__toESM(_jsprismarine_jsbinaryutils, 1);
let assert = require("assert");
assert = require_runtime.__toESM(assert, 1);
//#region src/protocol/Frame.ts
var MAX_FRAME_BYTE_LENGTH = 23;
var Frame = class {
reliability = require_protocol_FrameReliability.FrameReliability.UNRELIABLE;
reliableIndex = null;
sequenceIndex = null;
orderIndex = null;
orderChannel;
fragmentSize = 0;
fragmentId;
fragmentIndex;
content;
fromBinary(stream) {
const header = stream.readByte();
this.reliability = (header & 224) >> 5;
const length = Math.ceil(stream.readShort() / 8);
if (this.isReliable()) this.reliableIndex = stream.readTriadLE();
if (this.isSequenced()) this.sequenceIndex = stream.readTriadLE();
if (this.isOrdered()) {
this.orderIndex = stream.readTriadLE();
this.orderChannel = stream.readByte();
}
if ((header & require_protocol_BitFlags.BitFlags.SPLIT) > 0) {
this.fragmentSize = stream.readInt();
this.fragmentId = stream.readShort();
this.fragmentIndex = stream.readInt();
}
this.content = stream.read(length);
return this;
}
toBinary() {
const stream = new _jsprismarine_jsbinaryutils.default();
const fragmented = this.isFragmented();
stream.writeByte(this.reliability << 5 | (fragmented ? require_protocol_BitFlags.BitFlags.SPLIT : 0));
stream.writeUnsignedShort(this.content.byteLength << 3);
if (this.isReliable()) {
(0, assert.default)(typeof this.reliableIndex === "number", "Invalid ReliableIndex for reliable Frame");
stream.writeUnsignedTriadLE(this.reliableIndex);
}
if (this.isSequenced()) {
(0, assert.default)(typeof this.sequenceIndex === "number", "Invalid SequenceIndex for sequenced Frame");
stream.writeUnsignedTriadLE(this.sequenceIndex);
}
if (this.isOrdered()) {
(0, assert.default)(typeof this.orderIndex === "number", "Invalid OrderIndex for ordered Frame");
stream.writeUnsignedTriadLE(this.orderIndex);
(0, assert.default)(typeof this.orderChannel === "number", "Invalid OrderChannel for ordered FrameSet");
stream.writeByte(this.orderChannel);
}
if (fragmented) {
stream.writeUnsignedInt(this.fragmentSize);
stream.writeUnsignedShort(this.fragmentId);
stream.writeUnsignedInt(this.fragmentIndex);
}
stream.write(this.content);
return stream;
}
getByteLength() {
return 3 + this.content.byteLength + (this.isReliable() ? 3 : 0) + (this.isSequenced() ? 3 : 0) + (this.isOrdered() ? 4 : 0) + (this.isFragmented() ? 10 : 0);
}
isReliable() {
return [
require_protocol_FrameReliability.FrameReliability.RELIABLE,
require_protocol_FrameReliability.FrameReliability.RELIABLE_ORDERED,
require_protocol_FrameReliability.FrameReliability.RELIABLE_SEQUENCED,
require_protocol_FrameReliability.FrameReliability.RELIABLE_WITH_ACK_RECEIPT,
require_protocol_FrameReliability.FrameReliability.RELIABLE_ORDERED_WITH_ACK_RECEIPT
].includes(this.reliability);
}
isSequenced() {
return [require_protocol_FrameReliability.FrameReliability.RELIABLE_SEQUENCED, require_protocol_FrameReliability.FrameReliability.UNRELIABLE_SEQUENCED].includes(this.reliability);
}
isOrdered() {
return [
require_protocol_FrameReliability.FrameReliability.UNRELIABLE_SEQUENCED,
require_protocol_FrameReliability.FrameReliability.RELIABLE_ORDERED,
require_protocol_FrameReliability.FrameReliability.RELIABLE_SEQUENCED,
require_protocol_FrameReliability.FrameReliability.RELIABLE_ORDERED_WITH_ACK_RECEIPT
].includes(this.reliability);
}
isOrderedExclusive() {
return [require_protocol_FrameReliability.FrameReliability.RELIABLE_ORDERED, require_protocol_FrameReliability.FrameReliability.RELIABLE_ORDERED_WITH_ACK_RECEIPT].includes(this.reliability);
}
isFragmented() {
return this.fragmentSize > 0;
}
};
//#endregion
exports.MAX_FRAME_BYTE_LENGTH = MAX_FRAME_BYTE_LENGTH;
exports.default = Frame;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRnJhbWUuY2pzLmNqcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJvdG9jb2wvRnJhbWUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJpbmFyeVN0cmVhbSBmcm9tICdAanNwcmlzbWFyaW5lL2pzYmluYXJ5dXRpbHMnO1xuaW1wb3J0IEJpdEZsYWdzIGZyb20gJy4vQml0RmxhZ3MnO1xuaW1wb3J0IEZyYW1lUmVsaWFiaWxpdHkgZnJvbSAnLi9GcmFtZVJlbGlhYmlsaXR5JztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rYXJjaGl2ZS9SYWtOZXQvYmxvYi8xYTE2OTg5NWE5MDBjOWZjNDg0MWM1NTZlMTY1MTQxODJiNzVmYWY4L1NvdXJjZS9SZWxpYWJpbGl0eUxheWVyLmNwcCNMMTMzXG4vLyBJdCdzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBieXRlcyBhIGZyYW1lc2V0IGNhbiB0YWtlLiAoc3BsaXR0ZWQgcmVsaWFibGUgc2VxdWVuY2VkKS5cbmV4cG9ydCBjb25zdCBNQVhfRlJBTUVfQllURV9MRU5HVEggPSAyMztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRnJhbWUge1xuICAgIHB1YmxpYyByZWxpYWJpbGl0eSA9IEZyYW1lUmVsaWFiaWxpdHkuVU5SRUxJQUJMRTtcblxuICAgIHB1YmxpYyByZWxpYWJsZUluZGV4OiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICAgIHB1YmxpYyBzZXF1ZW5jZUluZGV4OiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICAgIHB1YmxpYyBvcmRlckluZGV4OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgICBwdWJsaWMgb3JkZXJDaGFubmVsITogTm9uTnVsbGFibGU8bnVtYmVyPjtcblxuICAgIHB1YmxpYyBmcmFnbWVudFNpemUgPSAwO1xuICAgIHB1YmxpYyBmcmFnbWVudElkITogbnVtYmVyO1xuICAgIHB1YmxpYyBmcmFnbWVudEluZGV4ITogbnVtYmVyO1xuXG4gICAgcHVibGljIGNvbnRlbnQhOiBCdWZmZXI7XG5cbiAgICBwdWJsaWMgZnJvbUJpbmFyeShzdHJlYW06IEJpbmFyeVN0cmVhbSk6IEZyYW1lIHtcbiAgICAgICAgY29uc3QgaGVhZGVyID0gc3RyZWFtLnJlYWRCeXRlKCk7XG4gICAgICAgIHRoaXMucmVsaWFiaWxpdHkgPSAoaGVhZGVyICYgMHhlMCkgPj4gNTtcblxuICAgICAgICAvLyBMZW5ndGggZnJvbSBiaXRzIHRvIGJ5dGVzXG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGguY2VpbChzdHJlYW0ucmVhZFNob3J0KCkgLyA4KTtcblxuICAgICAgICBpZiAodGhpcy5pc1JlbGlhYmxlKCkpIHtcbiAgICAgICAgICAgIHRoaXMucmVsaWFibGVJbmRleCA9IHN0cmVhbS5yZWFkVHJpYWRMRSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaXNTZXF1ZW5jZWQoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXF1ZW5jZUluZGV4ID0gc3RyZWFtLnJlYWRUcmlhZExFKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5pc09yZGVyZWQoKSkge1xuICAgICAgICAgICAgdGhpcy5vcmRlckluZGV4ID0gc3RyZWFtLnJlYWRUcmlhZExFKCk7XG4gICAgICAgICAgICB0aGlzLm9yZGVyQ2hhbm5lbCA9IHN0cmVhbS5yZWFkQnl0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKChoZWFkZXIgJiBCaXRGbGFncy5TUExJVCkgPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmZyYWdtZW50U2l6ZSA9IHN0cmVhbS5yZWFkSW50KCk7XG4gICAgICAgICAgICB0aGlzLmZyYWdtZW50SWQgPSBzdHJlYW0ucmVhZFNob3J0KCk7XG4gICAgICAgICAgICB0aGlzLmZyYWdtZW50SW5kZXggPSBzdHJlYW0ucmVhZEludCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb250ZW50ID0gc3RyZWFtLnJlYWQobGVuZ3RoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcHVibGljIHRvQmluYXJ5KCk6IEJpbmFyeVN0cmVhbSB7XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IG5ldyBCaW5hcnlTdHJlYW0oKTtcbiAgICAgICAgY29uc3QgZnJhZ21lbnRlZCA9IHRoaXMuaXNGcmFnbWVudGVkKCk7XG5cbiAgICAgICAgc3RyZWFtLndyaXRlQnl0ZSgodGhpcy5yZWxpYWJpbGl0eSA8PCA1KSB8IChmcmFnbWVudGVkID8gQml0RmxhZ3MuU1BMSVQgOiAwKSk7XG4gICAgICAgIHN0cmVhbS53cml0ZVVuc2lnbmVkU2hvcnQodGhpcy5jb250ZW50LmJ5dGVMZW5ndGggPDwgMyk7XG5cbiAgICAgICAgaWYgKHRoaXMuaXNSZWxpYWJsZSgpKSB7XG4gICAgICAgICAgICBhc3NlcnQodHlwZW9mIHRoaXMucmVsaWFibGVJbmRleCA9PT0gJ251bWJlcicsICdJbnZhbGlkIFJlbGlhYmxlSW5kZXggZm9yIHJlbGlhYmxlIEZyYW1lJyk7XG4gICAgICAgICAgICBzdHJlYW0ud3JpdGVVbnNpZ25lZFRyaWFkTEUodGhpcy5yZWxpYWJsZUluZGV4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmlzU2VxdWVuY2VkKCkpIHtcbiAgICAgICAgICAgIGFzc2VydCh0eXBlb2YgdGhpcy5zZXF1ZW5jZUluZGV4ID09PSAnbnVtYmVyJywgJ0ludmFsaWQgU2VxdWVuY2VJbmRleCBmb3Igc2VxdWVuY2VkIEZyYW1lJyk7XG4gICAgICAgICAgICBzdHJlYW0ud3JpdGVVbnNpZ25lZFRyaWFkTEUodGhpcy5zZXF1ZW5jZUluZGV4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmlzT3JkZXJlZCgpKSB7XG4gICAgICAgICAgICBhc3NlcnQodHlwZW9mIHRoaXMub3JkZXJJbmRleCA9PT0gJ251bWJlcicsICdJbnZhbGlkIE9yZGVySW5kZXggZm9yIG9yZGVyZWQgRnJhbWUnKTtcbiAgICAgICAgICAgIHN0cmVhbS53cml0ZVVuc2lnbmVkVHJpYWRMRSh0aGlzLm9yZGVySW5kZXgpO1xuICAgICAgICAgICAgYXNzZXJ0KHR5cGVvZiB0aGlzLm9yZGVyQ2hhbm5lbCA9PT0gJ251bWJlcicsICdJbnZhbGlkIE9yZGVyQ2hhbm5lbCBmb3Igb3JkZXJlZCBGcmFtZVNldCcpO1xuICAgICAgICAgICAgc3RyZWFtLndyaXRlQnl0ZSh0aGlzLm9yZGVyQ2hhbm5lbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZnJhZ21lbnRlZCkge1xuICAgICAgICAgICAgc3RyZWFtLndyaXRlVW5zaWduZWRJbnQodGhpcy5mcmFnbWVudFNpemUpO1xuICAgICAgICAgICAgc3RyZWFtLndyaXRlVW5zaWduZWRTaG9ydCh0aGlzLmZyYWdtZW50SWQpO1xuICAgICAgICAgICAgc3RyZWFtLndyaXRlVW5zaWduZWRJbnQodGhpcy5mcmFnbWVudEluZGV4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0cmVhbS53cml0ZSh0aGlzLmNvbnRlbnQpO1xuICAgICAgICByZXR1cm4gc3RyZWFtO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRCeXRlTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAzICtcbiAgICAgICAgICAgIHRoaXMuY29udGVudC5ieXRlTGVuZ3RoICtcbiAgICAgICAgICAgICh0aGlzLmlzUmVsaWFibGUoKSA/IDMgOiAwKSArXG4gICAgICAgICAgICAodGhpcy5pc1NlcXVlbmNlZCgpID8gMyA6IDApICtcbiAgICAgICAgICAgICh0aGlzLmlzT3JkZXJlZCgpID8gNCA6IDApICtcbiAgICAgICAgICAgICh0aGlzLmlzRnJhZ21lbnRlZCgpID8gMTAgOiAwKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc1JlbGlhYmxlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgRnJhbWVSZWxpYWJpbGl0eS5SRUxJQUJMRSxcbiAgICAgICAgICAgIEZyYW1lUmVsaWFiaWxpdHkuUkVMSUFCTEVfT1JERVJFRCxcbiAgICAgICAgICAgIEZyYW1lUmVsaWFiaWxpdHkuUkVMSUFCTEVfU0VRVUVOQ0VELFxuICAgICAgICAgICAgRnJhbWVSZWxpYWJpbGl0eS5SRUxJQUJMRV9XSVRIX0FDS19SRUNFSVBULFxuICAgICAgICAgICAgRnJhbWVSZWxpYWJpbGl0eS5SRUxJQUJMRV9PUkRFUkVEX1dJVEhfQUNLX1JFQ0VJUFRcbiAgICAgICAgXS5pbmNsdWRlcyh0aGlzLnJlbGlhYmlsaXR5KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNTZXF1ZW5jZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBbRnJhbWVSZWxpYWJpbGl0eS5SRUxJQUJMRV9TRVFVRU5DRUQsIEZyYW1lUmVsaWFiaWxpdHkuVU5SRUxJQUJMRV9TRVFVRU5DRURdLmluY2x1ZGVzKHRoaXMucmVsaWFiaWxpdHkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc09yZGVyZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBGcmFtZVJlbGlhYmlsaXR5LlVOUkVMSUFCTEVfU0VRVUVOQ0VELFxuICAgICAgICAgICAgRnJhbWVSZWxpYWJpbGl0eS5SRUxJQUJMRV9PUkRFUkVELFxuICAgICAgICAgICAgRnJhbWVSZWxpYWJpbGl0eS5SRUxJQUJMRV9TRVFVRU5DRUQsXG4gICAgICAgICAgICBGcmFtZVJlbGlhYmlsaXR5LlJFTElBQkxFX09SREVSRURfV0lUSF9BQ0tfUkVDRUlQVFxuICAgICAgICBdLmluY2x1ZGVzKHRoaXMucmVsaWFiaWxpdHkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc09yZGVyZWRFeGNsdXNpdmUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBbRnJhbWVSZWxpYWJpbGl0eS5SRUxJQUJMRV9PUkRFUkVELCBGcmFtZVJlbGlhYmlsaXR5LlJFTElBQkxFX09SREVSRURfV0lUSF9BQ0tfUkVDRUlQVF0uaW5jbHVkZXMoXG4gICAgICAgICAgICB0aGlzLnJlbGlhYmlsaXR5XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIGlzRnJhZ21lbnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJhZ21lbnRTaXplID4gMDtcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFPQSxJQUFhLHdCQUF3QjtBQUVyQyxJQUFxQixRQUFyQixNQUEyQjtDQUN2QixjQUFxQixrQ0FBQSxpQkFBaUI7Q0FFdEMsZ0JBQXNDO0NBRXRDLGdCQUFzQztDQUV0QyxhQUFtQztDQUNuQztDQUVBLGVBQXNCO0NBQ3RCO0NBQ0E7Q0FFQTtDQUVBLFdBQWtCLFFBQTZCO0VBQzNDLE1BQU0sU0FBUyxPQUFPLFNBQVM7RUFDL0IsS0FBSyxlQUFlLFNBQVMsUUFBUztFQUd0QyxNQUFNLFNBQVMsS0FBSyxLQUFLLE9BQU8sVUFBVSxJQUFJLENBQUM7RUFFL0MsSUFBSSxLQUFLLFdBQVcsR0FDaEIsS0FBSyxnQkFBZ0IsT0FBTyxZQUFZO0VBRzVDLElBQUksS0FBSyxZQUFZLEdBQ2pCLEtBQUssZ0JBQWdCLE9BQU8sWUFBWTtFQUc1QyxJQUFJLEtBQUssVUFBVSxHQUFHO0dBQ2xCLEtBQUssYUFBYSxPQUFPLFlBQVk7R0FDckMsS0FBSyxlQUFlLE9BQU8sU0FBUztFQUN4QztFQUVBLEtBQUssU0FBUywwQkFBQSxTQUFTLFNBQVMsR0FBRztHQUMvQixLQUFLLGVBQWUsT0FBTyxRQUFRO0dBQ25DLEtBQUssYUFBYSxPQUFPLFVBQVU7R0FDbkMsS0FBSyxnQkFBZ0IsT0FBTyxRQUFRO0VBQ3hDO0VBRUEsS0FBSyxVQUFVLE9BQU8sS0FBSyxNQUFNO0VBQ2pDLE9BQU87Q0FDWDtDQUVBLFdBQWdDO0VBQzVCLE1BQU0sU0FBUyxJQUFJLDRCQUFBLFFBQWE7RUFDaEMsTUFBTSxhQUFhLEtBQUssYUFBYTtFQUVyQyxPQUFPLFVBQVcsS0FBSyxlQUFlLEtBQU0sYUFBYSwwQkFBQSxTQUFTLFFBQVEsRUFBRTtFQUM1RSxPQUFPLG1CQUFtQixLQUFLLFFBQVEsY0FBYyxDQUFDO0VBRXRELElBQUksS0FBSyxXQUFXLEdBQUc7R0FDbkIsQ0FBQSxHQUFBLE9BQUEsU0FBTyxPQUFPLEtBQUssa0JBQWtCLFVBQVUsMENBQTBDO0dBQ3pGLE9BQU8scUJBQXFCLEtBQUssYUFBYTtFQUNsRDtFQUVBLElBQUksS0FBSyxZQUFZLEdBQUc7R0FDcEIsQ0FBQSxHQUFBLE9BQUEsU0FBTyxPQUFPLEtBQUssa0JBQWtCLFVBQVUsMkNBQTJDO0dBQzFGLE9BQU8scUJBQXFCLEtBQUssYUFBYTtFQUNsRDtFQUVBLElBQUksS0FBSyxVQUFVLEdBQUc7R0FDbEIsQ0FBQSxHQUFBLE9BQUEsU0FBTyxPQUFPLEtBQUssZUFBZSxVQUFVLHNDQUFzQztHQUNsRixPQUFPLHFCQUFxQixLQUFLLFVBQVU7R0FDM0MsQ0FBQSxHQUFBLE9BQUEsU0FBTyxPQUFPLEtBQUssaUJBQWlCLFVBQVUsMkNBQTJDO0dBQ3pGLE9BQU8sVUFBVSxLQUFLLFlBQVk7RUFDdEM7RUFFQSxJQUFJLFlBQVk7R0FDWixPQUFPLGlCQUFpQixLQUFLLFlBQVk7R0FDekMsT0FBTyxtQkFBbUIsS0FBSyxVQUFVO0dBQ3pDLE9BQU8saUJBQWlCLEtBQUssYUFBYTtFQUM5QztFQUVBLE9BQU8sTUFBTSxLQUFLLE9BQU87RUFDekIsT0FBTztDQUNYO0NBRUEsZ0JBQStCO0VBQzNCLE9BQ0ksSUFDQSxLQUFLLFFBQVEsY0FDWixLQUFLLFdBQVcsSUFBSSxJQUFJLE1BQ3hCLEtBQUssWUFBWSxJQUFJLElBQUksTUFDekIsS0FBSyxVQUFVLElBQUksSUFBSSxNQUN2QixLQUFLLGFBQWEsSUFBSSxLQUFLO0NBRXBDO0NBRUEsYUFBNkI7RUFDekIsT0FBTztHQUNILGtDQUFBLGlCQUFpQjtHQUNqQixrQ0FBQSxpQkFBaUI7R0FDakIsa0NBQUEsaUJBQWlCO0dBQ2pCLGtDQUFBLGlCQUFpQjtHQUNqQixrQ0FBQSxpQkFBaUI7RUFDckIsRUFBRSxTQUFTLEtBQUssV0FBVztDQUMvQjtDQUVBLGNBQThCO0VBQzFCLE9BQU8sQ0FBQyxrQ0FBQSxpQkFBaUIsb0JBQW9CLGtDQUFBLGlCQUFpQixvQkFBb0IsRUFBRSxTQUFTLEtBQUssV0FBVztDQUNqSDtDQUVBLFlBQTRCO0VBQ3hCLE9BQU87R0FDSCxrQ0FBQSxpQkFBaUI7R0FDakIsa0NBQUEsaUJBQWlCO0dBQ2pCLGtDQUFBLGlCQUFpQjtHQUNqQixrQ0FBQSxpQkFBaUI7RUFDckIsRUFBRSxTQUFTLEtBQUssV0FBVztDQUMvQjtDQUVBLHFCQUFxQztFQUNqQyxPQUFPLENBQUMsa0NBQUEsaUJBQWlCLGtCQUFrQixrQ0FBQSxpQkFBaUIsaUNBQWlDLEVBQUUsU0FDM0YsS0FBSyxXQUNUO0NBQ0o7Q0FFQSxlQUErQjtFQUMzQixPQUFPLEtBQUssZUFBZTtDQUMvQjtBQUNKIn0=