UNPKG

23.1 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.TYPE = exports.Packet = exports.OFFSET = exports.HEADER_LENGTH = void 0;
7exports.isPacketComplete = isPacketComplete;
8exports.packetLength = packetLength;
9var _sprintfJs = require("sprintf-js");
10const HEADER_LENGTH = exports.HEADER_LENGTH = 8;
11const TYPE = exports.TYPE = {
12 SQL_BATCH: 0x01,
13 RPC_REQUEST: 0x03,
14 TABULAR_RESULT: 0x04,
15 ATTENTION: 0x06,
16 BULK_LOAD: 0x07,
17 TRANSACTION_MANAGER: 0x0E,
18 LOGIN7: 0x10,
19 NTLMAUTH_PKT: 0x11,
20 PRELOGIN: 0x12,
21 FEDAUTH_TOKEN: 0x08
22};
23const typeByValue = {};
24for (const name in TYPE) {
25 typeByValue[TYPE[name]] = name;
26}
27const STATUS = {
28 NORMAL: 0x00,
29 EOM: 0x01,
30 IGNORE: 0x02,
31 RESETCONNECTION: 0x08,
32 RESETCONNECTIONSKIPTRAN: 0x10
33};
34const OFFSET = exports.OFFSET = {
35 Type: 0,
36 Status: 1,
37 Length: 2,
38 SPID: 4,
39 PacketID: 6,
40 Window: 7
41};
42const DEFAULT_SPID = 0;
43const DEFAULT_PACKETID = 1;
44const DEFAULT_WINDOW = 0;
45const NL = '\n';
46class Packet {
47 constructor(typeOrBuffer) {
48 if (typeOrBuffer instanceof Buffer) {
49 this.buffer = typeOrBuffer;
50 } else {
51 const type = typeOrBuffer;
52 this.buffer = Buffer.alloc(HEADER_LENGTH, 0);
53 this.buffer.writeUInt8(type, OFFSET.Type);
54 this.buffer.writeUInt8(STATUS.NORMAL, OFFSET.Status);
55 this.buffer.writeUInt16BE(DEFAULT_SPID, OFFSET.SPID);
56 this.buffer.writeUInt8(DEFAULT_PACKETID, OFFSET.PacketID);
57 this.buffer.writeUInt8(DEFAULT_WINDOW, OFFSET.Window);
58 this.setLength();
59 }
60 }
61 setLength() {
62 this.buffer.writeUInt16BE(this.buffer.length, OFFSET.Length);
63 }
64 length() {
65 return this.buffer.readUInt16BE(OFFSET.Length);
66 }
67 resetConnection(reset) {
68 let status = this.buffer.readUInt8(OFFSET.Status);
69 if (reset) {
70 status |= STATUS.RESETCONNECTION;
71 } else {
72 status &= 0xFF - STATUS.RESETCONNECTION;
73 }
74 this.buffer.writeUInt8(status, OFFSET.Status);
75 }
76 last(last) {
77 let status = this.buffer.readUInt8(OFFSET.Status);
78 if (arguments.length > 0) {
79 if (last) {
80 status |= STATUS.EOM;
81 } else {
82 status &= 0xFF - STATUS.EOM;
83 }
84 this.buffer.writeUInt8(status, OFFSET.Status);
85 }
86 return this.isLast();
87 }
88 ignore(last) {
89 let status = this.buffer.readUInt8(OFFSET.Status);
90 if (last) {
91 status |= STATUS.IGNORE;
92 } else {
93 status &= 0xFF - STATUS.IGNORE;
94 }
95 this.buffer.writeUInt8(status, OFFSET.Status);
96 }
97 isLast() {
98 return !!(this.buffer.readUInt8(OFFSET.Status) & STATUS.EOM);
99 }
100 packetId(packetId) {
101 if (packetId) {
102 this.buffer.writeUInt8(packetId % 256, OFFSET.PacketID);
103 }
104 return this.buffer.readUInt8(OFFSET.PacketID);
105 }
106 addData(data) {
107 this.buffer = Buffer.concat([this.buffer, data]);
108 this.setLength();
109 return this;
110 }
111 data() {
112 return this.buffer.slice(HEADER_LENGTH);
113 }
114 type() {
115 return this.buffer.readUInt8(OFFSET.Type);
116 }
117 statusAsString() {
118 const status = this.buffer.readUInt8(OFFSET.Status);
119 const statuses = [];
120 for (const name in STATUS) {
121 const value = STATUS[name];
122 if (status & value) {
123 statuses.push(name);
124 } else {
125 statuses.push(undefined);
126 }
127 }
128 return statuses.join(' ').trim();
129 }
130 headerToString(indent = '') {
131 const text = (0, _sprintfJs.sprintf)('type:0x%02X(%s), status:0x%02X(%s), length:0x%04X, spid:0x%04X, packetId:0x%02X, window:0x%02X', this.buffer.readUInt8(OFFSET.Type), typeByValue[this.buffer.readUInt8(OFFSET.Type)], this.buffer.readUInt8(OFFSET.Status), this.statusAsString(), this.buffer.readUInt16BE(OFFSET.Length), this.buffer.readUInt16BE(OFFSET.SPID), this.buffer.readUInt8(OFFSET.PacketID), this.buffer.readUInt8(OFFSET.Window));
132 return indent + text;
133 }
134 dataToString(indent = '') {
135 const BYTES_PER_GROUP = 0x04;
136 const CHARS_PER_GROUP = 0x08;
137 const BYTES_PER_LINE = 0x20;
138 const data = this.data();
139 let dataDump = '';
140 let chars = '';
141 for (let offset = 0; offset < data.length; offset++) {
142 if (offset % BYTES_PER_LINE === 0) {
143 dataDump += indent;
144 dataDump += (0, _sprintfJs.sprintf)('%04X ', offset);
145 }
146 if (data[offset] < 0x20 || data[offset] > 0x7E) {
147 chars += '.';
148 if ((offset + 1) % CHARS_PER_GROUP === 0 && !((offset + 1) % BYTES_PER_LINE === 0)) {
149 chars += ' ';
150 }
151 } else {
152 chars += String.fromCharCode(data[offset]);
153 }
154 if (data[offset] != null) {
155 dataDump += (0, _sprintfJs.sprintf)('%02X', data[offset]);
156 }
157 if ((offset + 1) % BYTES_PER_GROUP === 0 && !((offset + 1) % BYTES_PER_LINE === 0)) {
158 dataDump += ' ';
159 }
160 if ((offset + 1) % BYTES_PER_LINE === 0) {
161 dataDump += ' ' + chars;
162 chars = '';
163 if (offset < data.length - 1) {
164 dataDump += NL;
165 }
166 }
167 }
168 if (chars.length) {
169 dataDump += ' ' + chars;
170 }
171 return dataDump;
172 }
173 toString(indent = '') {
174 return this.headerToString(indent) + '\n' + this.dataToString(indent + indent);
175 }
176 payloadString() {
177 return '';
178 }
179}
180exports.Packet = Packet;
181function isPacketComplete(potentialPacketBuffer) {
182 if (potentialPacketBuffer.length < HEADER_LENGTH) {
183 return false;
184 } else {
185 return potentialPacketBuffer.length >= potentialPacketBuffer.readUInt16BE(OFFSET.Length);
186 }
187}
188function packetLength(potentialPacketBuffer) {
189 return potentialPacketBuffer.readUInt16BE(OFFSET.Length);
190}
191//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfc3ByaW50ZkpzIiwicmVxdWlyZSIsIkhFQURFUl9MRU5HVEgiLCJleHBvcnRzIiwiVFlQRSIsIlNRTF9CQVRDSCIsIlJQQ19SRVFVRVNUIiwiVEFCVUxBUl9SRVNVTFQiLCJBVFRFTlRJT04iLCJCVUxLX0xPQUQiLCJUUkFOU0FDVElPTl9NQU5BR0VSIiwiTE9HSU43IiwiTlRMTUFVVEhfUEtUIiwiUFJFTE9HSU4iLCJGRURBVVRIX1RPS0VOIiwidHlwZUJ5VmFsdWUiLCJuYW1lIiwiU1RBVFVTIiwiTk9STUFMIiwiRU9NIiwiSUdOT1JFIiwiUkVTRVRDT05ORUNUSU9OIiwiUkVTRVRDT05ORUNUSU9OU0tJUFRSQU4iLCJPRkZTRVQiLCJUeXBlIiwiU3RhdHVzIiwiTGVuZ3RoIiwiU1BJRCIsIlBhY2tldElEIiwiV2luZG93IiwiREVGQVVMVF9TUElEIiwiREVGQVVMVF9QQUNLRVRJRCIsIkRFRkFVTFRfV0lORE9XIiwiTkwiLCJQYWNrZXQiLCJjb25zdHJ1Y3RvciIsInR5cGVPckJ1ZmZlciIsIkJ1ZmZlciIsImJ1ZmZlciIsInR5cGUiLCJhbGxvYyIsIndyaXRlVUludDgiLCJ3cml0ZVVJbnQxNkJFIiwic2V0TGVuZ3RoIiwibGVuZ3RoIiwicmVhZFVJbnQxNkJFIiwicmVzZXRDb25uZWN0aW9uIiwicmVzZXQiLCJzdGF0dXMiLCJyZWFkVUludDgiLCJsYXN0IiwiYXJndW1lbnRzIiwiaXNMYXN0IiwiaWdub3JlIiwicGFja2V0SWQiLCJhZGREYXRhIiwiZGF0YSIsImNvbmNhdCIsInNsaWNlIiwic3RhdHVzQXNTdHJpbmciLCJzdGF0dXNlcyIsInZhbHVlIiwicHVzaCIsInVuZGVmaW5lZCIsImpvaW4iLCJ0cmltIiwiaGVhZGVyVG9TdHJpbmciLCJpbmRlbnQiLCJ0ZXh0Iiwic3ByaW50ZiIsImRhdGFUb1N0cmluZyIsIkJZVEVTX1BFUl9HUk9VUCIsIkNIQVJTX1BFUl9HUk9VUCIsIkJZVEVTX1BFUl9MSU5FIiwiZGF0YUR1bXAiLCJjaGFycyIsIm9mZnNldCIsIlN0cmluZyIsImZyb21DaGFyQ29kZSIsInRvU3RyaW5nIiwicGF5bG9hZFN0cmluZyIsImlzUGFja2V0Q29tcGxldGUiLCJwb3RlbnRpYWxQYWNrZXRCdWZmZXIiLCJwYWNrZXRMZW5ndGgiXSwic291cmNlcyI6WyIuLi9zcmMvcGFja2V0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNwcmludGYgfSBmcm9tICdzcHJpbnRmLWpzJztcblxuZXhwb3J0IGNvbnN0IEhFQURFUl9MRU5HVEggPSA4O1xuXG5leHBvcnQgY29uc3QgVFlQRTogeyBba2V5OiBzdHJpbmddOiBudW1iZXIgfSA9IHtcbiAgU1FMX0JBVENIOiAweDAxLFxuICBSUENfUkVRVUVTVDogMHgwMyxcbiAgVEFCVUxBUl9SRVNVTFQ6IDB4MDQsXG4gIEFUVEVOVElPTjogMHgwNixcbiAgQlVMS19MT0FEOiAweDA3LFxuICBUUkFOU0FDVElPTl9NQU5BR0VSOiAweDBFLFxuICBMT0dJTjc6IDB4MTAsXG4gIE5UTE1BVVRIX1BLVDogMHgxMSxcbiAgUFJFTE9HSU46IDB4MTIsXG4gIEZFREFVVEhfVE9LRU46IDB4MDhcbn07XG5cbmNvbnN0IHR5cGVCeVZhbHVlOiB7IFtrZXk6IG51bWJlcl06IHN0cmluZyB9ID0ge307XG5cbmZvciAoY29uc3QgbmFtZSBpbiBUWVBFKSB7XG4gIHR5cGVCeVZhbHVlW1RZUEVbbmFtZV1dID0gbmFtZTtcbn1cblxuY29uc3QgU1RBVFVTOiB7IFtrZXk6IHN0cmluZ106IG51bWJlciB9ID0ge1xuICBOT1JNQUw6IDB4MDAsXG4gIEVPTTogMHgwMSxcbiAgSUdOT1JFOiAweDAyLFxuICBSRVNFVENPTk5FQ1RJT046IDB4MDgsXG4gIFJFU0VUQ09OTkVDVElPTlNLSVBUUkFOOiAweDEwXG59O1xuXG5leHBvcnQgY29uc3QgT0ZGU0VUID0ge1xuICBUeXBlOiAwLFxuICBTdGF0dXM6IDEsXG4gIExlbmd0aDogMixcbiAgU1BJRDogNCxcbiAgUGFja2V0SUQ6IDYsXG4gIFdpbmRvdzogN1xufTtcblxuY29uc3QgREVGQVVMVF9TUElEID0gMDtcblxuY29uc3QgREVGQVVMVF9QQUNLRVRJRCA9IDE7XG5cbmNvbnN0IERFRkFVTFRfV0lORE9XID0gMDtcblxuY29uc3QgTkwgPSAnXFxuJztcblxuZXhwb3J0IGNsYXNzIFBhY2tldCB7XG4gIGRlY2xhcmUgYnVmZmVyOiBCdWZmZXI7XG5cbiAgY29uc3RydWN0b3IodHlwZU9yQnVmZmVyOiBCdWZmZXIgfCBudW1iZXIpIHtcbiAgICBpZiAodHlwZU9yQnVmZmVyIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICB0aGlzLmJ1ZmZlciA9IHR5cGVPckJ1ZmZlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdHlwZSA9IHR5cGVPckJ1ZmZlcjtcbiAgICAgIHRoaXMuYnVmZmVyID0gQnVmZmVyLmFsbG9jKEhFQURFUl9MRU5HVEgsIDApO1xuICAgICAgdGhpcy5idWZmZXIud3JpdGVVSW50OCh0eXBlLCBPRkZTRVQuVHlwZSk7XG4gICAgICB0aGlzLmJ1ZmZlci53cml0ZVVJbnQ4KFNUQVRVUy5OT1JNQUwsIE9GRlNFVC5TdGF0dXMpO1xuICAgICAgdGhpcy5idWZmZXIud3JpdGVVSW50MTZCRShERUZBVUxUX1NQSUQsIE9GRlNFVC5TUElEKTtcbiAgICAgIHRoaXMuYnVmZmVyLndyaXRlVUludDgoREVGQVVMVF9QQUNLRVRJRCwgT0ZGU0VULlBhY2tldElEKTtcbiAgICAgIHRoaXMuYnVmZmVyLndyaXRlVUludDgoREVGQVVMVF9XSU5ET1csIE9GRlNFVC5XaW5kb3cpO1xuICAgICAgdGhpcy5zZXRMZW5ndGgoKTtcbiAgICB9XG4gIH1cblxuICBzZXRMZW5ndGgoKSB7XG4gICAgdGhpcy5idWZmZXIud3JpdGVVSW50MTZCRSh0aGlzLmJ1ZmZlci5sZW5ndGgsIE9GRlNFVC5MZW5ndGgpO1xuICB9XG5cbiAgbGVuZ3RoKCkge1xuICAgIHJldHVybiB0aGlzLmJ1ZmZlci5yZWFkVUludDE2QkUoT0ZGU0VULkxlbmd0aCk7XG4gIH1cblxuICByZXNldENvbm5lY3Rpb24ocmVzZXQ6IGJvb2xlYW4pIHtcbiAgICBsZXQgc3RhdHVzID0gdGhpcy5idWZmZXIucmVhZFVJbnQ4KE9GRlNFVC5TdGF0dXMpO1xuICAgIGlmIChyZXNldCkge1xuICAgICAgc3RhdHVzIHw9IFNUQVRVUy5SRVNFVENPTk5FQ1RJT047XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXR1cyAmPSAweEZGIC0gU1RBVFVTLlJFU0VUQ09OTkVDVElPTjtcbiAgICB9XG4gICAgdGhpcy5idWZmZXIud3JpdGVVSW50OChzdGF0dXMsIE9GRlNFVC5TdGF0dXMpO1xuICB9XG5cbiAgbGFzdChsYXN0PzogYm9vbGVhbikge1xuICAgIGxldCBzdGF0dXMgPSB0aGlzLmJ1ZmZlci5yZWFkVUludDgoT0ZGU0VULlN0YXR1cyk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAobGFzdCkge1xuICAgICAgICBzdGF0dXMgfD0gU1RBVFVTLkVPTTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXR1cyAmPSAweEZGIC0gU1RBVFVTLkVPTTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYnVmZmVyLndyaXRlVUludDgoc3RhdHVzLCBPRkZTRVQuU3RhdHVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaXNMYXN0KCk7XG4gIH1cblxuICBpZ25vcmUobGFzdDogYm9vbGVhbikge1xuICAgIGxldCBzdGF0dXMgPSB0aGlzLmJ1ZmZlci5yZWFkVUludDgoT0ZGU0VULlN0YXR1cyk7XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIHN0YXR1cyB8PSBTVEFUVVMuSUdOT1JFO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0dXMgJj0gMHhGRiAtIFNUQVRVUy5JR05PUkU7XG4gICAgfVxuICAgIHRoaXMuYnVmZmVyLndyaXRlVUludDgoc3RhdHVzLCBPRkZTRVQuU3RhdHVzKTtcbiAgfVxuXG4gIGlzTGFzdCgpIHtcbiAgICByZXR1cm4gISEodGhpcy5idWZmZXIucmVhZFVJbnQ4KE9GRlNFVC5TdGF0dXMpICYgU1RBVFVTLkVPTSk7XG4gIH1cblxuICBwYWNrZXRJZChwYWNrZXRJZD86IG51bWJlcikge1xuICAgIGlmIChwYWNrZXRJZCkge1xuICAgICAgdGhpcy5idWZmZXIud3JpdGVVSW50OChwYWNrZXRJZCAlIDI1NiwgT0ZGU0VULlBhY2tldElEKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYnVmZmVyLnJlYWRVSW50OChPRkZTRVQuUGFja2V0SUQpO1xuICB9XG5cbiAgYWRkRGF0YShkYXRhOiBCdWZmZXIpIHtcbiAgICB0aGlzLmJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuYnVmZmVyLCBkYXRhXSk7XG4gICAgdGhpcy5zZXRMZW5ndGgoKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGRhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMuYnVmZmVyLnNsaWNlKEhFQURFUl9MRU5HVEgpO1xuICB9XG5cbiAgdHlwZSgpIHtcbiAgICByZXR1cm4gdGhpcy5idWZmZXIucmVhZFVJbnQ4KE9GRlNFVC5UeXBlKTtcbiAgfVxuXG4gIHN0YXR1c0FzU3RyaW5nKCkge1xuICAgIGNvbnN0IHN0YXR1cyA9IHRoaXMuYnVmZmVyLnJlYWRVSW50OChPRkZTRVQuU3RhdHVzKTtcbiAgICBjb25zdCBzdGF0dXNlcyA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBuYW1lIGluIFNUQVRVUykge1xuICAgICAgY29uc3QgdmFsdWUgPSBTVEFUVVNbbmFtZV07XG5cbiAgICAgIGlmIChzdGF0dXMgJiB2YWx1ZSkge1xuICAgICAgICBzdGF0dXNlcy5wdXNoKG5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdHVzZXMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzdGF0dXNlcy5qb2luKCcgJykudHJpbSgpO1xuICB9XG5cbiAgaGVhZGVyVG9TdHJpbmcoaW5kZW50ID0gJycpIHtcbiAgICBjb25zdCB0ZXh0ID0gc3ByaW50ZigndHlwZToweCUwMlgoJXMpLCBzdGF0dXM6MHglMDJYKCVzKSwgbGVuZ3RoOjB4JTA0WCwgc3BpZDoweCUwNFgsIHBhY2tldElkOjB4JTAyWCwgd2luZG93OjB4JTAyWCcsIHRoaXMuYnVmZmVyLnJlYWRVSW50OChPRkZTRVQuVHlwZSksIHR5cGVCeVZhbHVlW3RoaXMuYnVmZmVyLnJlYWRVSW50OChPRkZTRVQuVHlwZSldLCB0aGlzLmJ1ZmZlci5yZWFkVUludDgoT0ZGU0VULlN0YXR1cyksIHRoaXMuc3RhdHVzQXNTdHJpbmcoKSwgdGhpcy5idWZmZXIucmVhZFVJbnQxNkJFKE9GRlNFVC5MZW5ndGgpLCB0aGlzLmJ1ZmZlci5yZWFkVUludDE2QkUoT0ZGU0VULlNQSUQpLCB0aGlzLmJ1ZmZlci5yZWFkVUludDgoT0ZGU0VULlBhY2tldElEKSwgdGhpcy5idWZmZXIucmVhZFVJbnQ4KE9GRlNFVC5XaW5kb3cpKTtcbiAgICByZXR1cm4gaW5kZW50ICsgdGV4dDtcbiAgfVxuXG4gIGRhdGFUb1N0cmluZyhpbmRlbnQgPSAnJykge1xuICAgIGNvbnN0IEJZVEVTX1BFUl9HUk9VUCA9IDB4MDQ7XG4gICAgY29uc3QgQ0hBUlNfUEVSX0dST1VQID0gMHgwODtcbiAgICBjb25zdCBCWVRFU19QRVJfTElORSA9IDB4MjA7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZGF0YSgpO1xuXG4gICAgbGV0IGRhdGFEdW1wID0gJyc7XG4gICAgbGV0IGNoYXJzID0gJyc7XG5cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGRhdGEubGVuZ3RoOyBvZmZzZXQrKykge1xuICAgICAgaWYgKG9mZnNldCAlIEJZVEVTX1BFUl9MSU5FID09PSAwKSB7XG4gICAgICAgIGRhdGFEdW1wICs9IGluZGVudDtcbiAgICAgICAgZGF0YUR1bXAgKz0gc3ByaW50ZignJTA0WCAgJywgb2Zmc2V0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRhdGFbb2Zmc2V0XSA8IDB4MjAgfHwgZGF0YVtvZmZzZXRdID4gMHg3RSkge1xuICAgICAgICBjaGFycyArPSAnLic7XG4gICAgICAgIGlmICgoKG9mZnNldCArIDEpICUgQ0hBUlNfUEVSX0dST1VQID09PSAwKSAmJiAhKChvZmZzZXQgKyAxKSAlIEJZVEVTX1BFUl9MSU5FID09PSAwKSkge1xuICAgICAgICAgIGNoYXJzICs9ICcgJztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2hhcnMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShkYXRhW29mZnNldF0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YVtvZmZzZXRdICE9IG51bGwpIHtcbiAgICAgICAgZGF0YUR1bXAgKz0gc3ByaW50ZignJTAyWCcsIGRhdGFbb2Zmc2V0XSk7XG4gICAgICB9XG5cbiAgICAgIGlmICgoKG9mZnNldCArIDEpICUgQllURVNfUEVSX0dST1VQID09PSAwKSAmJiAhKChvZmZzZXQgKyAxKSAlIEJZVEVTX1BFUl9MSU5FID09PSAwKSkge1xuICAgICAgICBkYXRhRHVtcCArPSAnICc7XG4gICAgICB9XG5cbiAgICAgIGlmICgob2Zmc2V0ICsgMSkgJSBCWVRFU19QRVJfTElORSA9PT0gMCkge1xuICAgICAgICBkYXRhRHVtcCArPSAnICAnICsgY2hhcnM7XG4gICAgICAgIGNoYXJzID0gJyc7XG4gICAgICAgIGlmIChvZmZzZXQgPCBkYXRhLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICBkYXRhRHVtcCArPSBOTDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjaGFycy5sZW5ndGgpIHtcbiAgICAgIGRhdGFEdW1wICs9ICcgICcgKyBjaGFycztcbiAgICB9XG5cbiAgICByZXR1cm4gZGF0YUR1bXA7XG4gIH1cblxuICB0b1N0cmluZyhpbmRlbnQgPSAnJykge1xuICAgIHJldHVybiB0aGlzLmhlYWRlclRvU3RyaW5nKGluZGVudCkgKyAnXFxuJyArIHRoaXMuZGF0YVRvU3RyaW5nKGluZGVudCArIGluZGVudCk7XG4gIH1cblxuICBwYXlsb2FkU3RyaW5nKCkge1xuICAgIHJldHVybiAnJztcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQYWNrZXRDb21wbGV0ZShwb3RlbnRpYWxQYWNrZXRCdWZmZXI6IEJ1ZmZlcikge1xuICBpZiAocG90ZW50aWFsUGFja2V0QnVmZmVyLmxlbmd0aCA8IEhFQURFUl9MRU5HVEgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHBvdGVudGlhbFBhY2tldEJ1ZmZlci5sZW5ndGggPj0gcG90ZW50aWFsUGFja2V0QnVmZmVyLnJlYWRVSW50MTZCRShPRkZTRVQuTGVuZ3RoKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFja2V0TGVuZ3RoKHBvdGVudGlhbFBhY2tldEJ1ZmZlcjogQnVmZmVyKSB7XG4gIHJldHVybiBwb3RlbnRpYWxQYWNrZXRCdWZmZXIucmVhZFVJbnQxNkJFKE9GRlNFVC5MZW5ndGgpO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBLElBQUFBLFVBQUEsR0FBQUMsT0FBQTtBQUVPLE1BQU1DLGFBQWEsR0FBQUMsT0FBQSxDQUFBRCxhQUFBLEdBQUcsQ0FBQztBQUV2QixNQUFNRSxJQUErQixHQUFBRCxPQUFBLENBQUFDLElBQUEsR0FBRztFQUM3Q0MsU0FBUyxFQUFFLElBQUk7RUFDZkMsV0FBVyxFQUFFLElBQUk7RUFDakJDLGNBQWMsRUFBRSxJQUFJO0VBQ3BCQyxTQUFTLEVBQUUsSUFBSTtFQUNmQyxTQUFTLEVBQUUsSUFBSTtFQUNmQyxtQkFBbUIsRUFBRSxJQUFJO0VBQ3pCQyxNQUFNLEVBQUUsSUFBSTtFQUNaQyxZQUFZLEVBQUUsSUFBSTtFQUNsQkMsUUFBUSxFQUFFLElBQUk7RUFDZEMsYUFBYSxFQUFFO0FBQ2pCLENBQUM7QUFFRCxNQUFNQyxXQUFzQyxHQUFHLENBQUMsQ0FBQztBQUVqRCxLQUFLLE1BQU1DLElBQUksSUFBSVosSUFBSSxFQUFFO0VBQ3ZCVyxXQUFXLENBQUNYLElBQUksQ0FBQ1ksSUFBSSxDQUFDLENBQUMs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
\No newline at end of file