oxygen-cli 1.33.5 → 1.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/build/ox_modules/module-http/ntlm-util.js +32 -0
- package/build/ox_modules/module-http/ntlm.js +514 -0
- package/build/ox_modules/module-http.js +120 -5
- package/build/ox_modules/module-mob.js +4 -2
- package/build/ox_modules/module-utils.js +4 -2
- package/build/ox_modules/module-web.js +4 -2
- package/build/ox_modules/module-win.js +4 -2
- package/package.json +3 -1
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("source-map-support/register");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Copyright (c) 2013 Sam Decrock https://github.com/SamDecrock/
|
|
7
|
+
* All rights reserved.
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the MIT license found in the
|
|
10
|
+
* LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/* eslint-disable */
|
|
14
|
+
var crypto = require('crypto');
|
|
15
|
+
|
|
16
|
+
var jsmd4 = require("js-md4");
|
|
17
|
+
|
|
18
|
+
var desjs = require("des.js");
|
|
19
|
+
|
|
20
|
+
var flags = {
|
|
21
|
+
NTLM_NegotiateUnicode: 0x00000001,
|
|
22
|
+
NTLM_NegotiateOEM: 0x00000002,
|
|
23
|
+
NTLM_RequestTarget: 0x00000004,
|
|
24
|
+
NTLM_Unknown9: 0x00000008,
|
|
25
|
+
NTLM_NegotiateSign: 0x00000010,
|
|
26
|
+
NTLM_NegotiateSeal: 0x00000020,
|
|
27
|
+
NTLM_NegotiateDatagram: 0x00000040,
|
|
28
|
+
NTLM_NegotiateLanManagerKey: 0x00000080,
|
|
29
|
+
NTLM_Unknown8: 0x00000100,
|
|
30
|
+
NTLM_NegotiateNTLM: 0x00000200,
|
|
31
|
+
NTLM_NegotiateNTOnly: 0x00000400,
|
|
32
|
+
NTLM_Anonymous: 0x00000800,
|
|
33
|
+
NTLM_NegotiateOemDomainSupplied: 0x00001000,
|
|
34
|
+
NTLM_NegotiateOemWorkstationSupplied: 0x00002000,
|
|
35
|
+
NTLM_Unknown6: 0x00004000,
|
|
36
|
+
NTLM_NegotiateAlwaysSign: 0x00008000,
|
|
37
|
+
NTLM_TargetTypeDomain: 0x00010000,
|
|
38
|
+
NTLM_TargetTypeServer: 0x00020000,
|
|
39
|
+
NTLM_TargetTypeShare: 0x00040000,
|
|
40
|
+
NTLM_NegotiateExtendedSecurity: 0x00080000,
|
|
41
|
+
NTLM_NegotiateIdentify: 0x00100000,
|
|
42
|
+
NTLM_Unknown5: 0x00200000,
|
|
43
|
+
NTLM_RequestNonNTSessionKey: 0x00400000,
|
|
44
|
+
NTLM_NegotiateTargetInfo: 0x00800000,
|
|
45
|
+
NTLM_Unknown4: 0x01000000,
|
|
46
|
+
NTLM_NegotiateVersion: 0x02000000,
|
|
47
|
+
NTLM_Unknown3: 0x04000000,
|
|
48
|
+
NTLM_Unknown2: 0x08000000,
|
|
49
|
+
NTLM_Unknown1: 0x10000000,
|
|
50
|
+
NTLM_Negotiate128: 0x20000000,
|
|
51
|
+
NTLM_NegotiateKeyExchange: 0x40000000,
|
|
52
|
+
NTLM_Negotiate56: 0x80000000
|
|
53
|
+
};
|
|
54
|
+
var typeflags = {
|
|
55
|
+
NTLM_TYPE1_FLAGS: flags.NTLM_NegotiateUnicode + flags.NTLM_NegotiateOEM + flags.NTLM_RequestTarget + flags.NTLM_NegotiateNTLM + flags.NTLM_NegotiateOemDomainSupplied + flags.NTLM_NegotiateOemWorkstationSupplied + flags.NTLM_NegotiateAlwaysSign + flags.NTLM_NegotiateExtendedSecurity + flags.NTLM_NegotiateVersion + flags.NTLM_Negotiate128 + flags.NTLM_Negotiate56,
|
|
56
|
+
NTLM_TYPE2_FLAGS: flags.NTLM_NegotiateUnicode + flags.NTLM_RequestTarget + flags.NTLM_NegotiateNTLM + flags.NTLM_NegotiateAlwaysSign + flags.NTLM_NegotiateExtendedSecurity + flags.NTLM_NegotiateTargetInfo + flags.NTLM_NegotiateVersion + flags.NTLM_Negotiate128 + flags.NTLM_Negotiate56
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
function createType1Message(options) {
|
|
60
|
+
if (!options.domain) options.domain = '';
|
|
61
|
+
if (!options.workstation) options.workstation = '';
|
|
62
|
+
var domain = escape(options.domain.toUpperCase());
|
|
63
|
+
var workstation = escape(options.workstation.toUpperCase());
|
|
64
|
+
var protocol = 'NTLMSSP\0';
|
|
65
|
+
var BODY_LENGTH = 40;
|
|
66
|
+
var type1flags = typeflags.NTLM_TYPE1_FLAGS;
|
|
67
|
+
if (!domain || domain === '') type1flags = type1flags - flags.NTLM_NegotiateOemDomainSupplied;
|
|
68
|
+
var pos = 0;
|
|
69
|
+
var buf = Buffer.alloc(BODY_LENGTH + domain.length + workstation.length);
|
|
70
|
+
buf.write(protocol, pos, protocol.length);
|
|
71
|
+
pos += protocol.length; // protocol
|
|
72
|
+
|
|
73
|
+
buf.writeUInt32LE(1, pos);
|
|
74
|
+
pos += 4; // type 1
|
|
75
|
+
|
|
76
|
+
buf.writeUInt32LE(type1flags, pos);
|
|
77
|
+
pos += 4; // TYPE1 flag
|
|
78
|
+
|
|
79
|
+
buf.writeUInt16LE(domain.length, pos);
|
|
80
|
+
pos += 2; // domain length
|
|
81
|
+
|
|
82
|
+
buf.writeUInt16LE(domain.length, pos);
|
|
83
|
+
pos += 2; // domain max length
|
|
84
|
+
|
|
85
|
+
buf.writeUInt32LE(BODY_LENGTH + workstation.length, pos);
|
|
86
|
+
pos += 4; // domain buffer offset
|
|
87
|
+
|
|
88
|
+
buf.writeUInt16LE(workstation.length, pos);
|
|
89
|
+
pos += 2; // workstation length
|
|
90
|
+
|
|
91
|
+
buf.writeUInt16LE(workstation.length, pos);
|
|
92
|
+
pos += 2; // workstation max length
|
|
93
|
+
|
|
94
|
+
buf.writeUInt32LE(BODY_LENGTH, pos);
|
|
95
|
+
pos += 4; // workstation buffer offset
|
|
96
|
+
|
|
97
|
+
buf.writeUInt8(5, pos);
|
|
98
|
+
pos += 1; //ProductMajorVersion
|
|
99
|
+
|
|
100
|
+
buf.writeUInt8(1, pos);
|
|
101
|
+
pos += 1; //ProductMinorVersion
|
|
102
|
+
|
|
103
|
+
buf.writeUInt16LE(2600, pos);
|
|
104
|
+
pos += 2; //ProductBuild
|
|
105
|
+
|
|
106
|
+
buf.writeUInt8(0, pos);
|
|
107
|
+
pos += 1; //VersionReserved1
|
|
108
|
+
|
|
109
|
+
buf.writeUInt8(0, pos);
|
|
110
|
+
pos += 1; //VersionReserved2
|
|
111
|
+
|
|
112
|
+
buf.writeUInt8(0, pos);
|
|
113
|
+
pos += 1; //VersionReserved3
|
|
114
|
+
|
|
115
|
+
buf.writeUInt8(15, pos);
|
|
116
|
+
pos += 1; //NTLMRevisionCurrent
|
|
117
|
+
// length checks is to fix issue #46 and possibly #57
|
|
118
|
+
|
|
119
|
+
if (workstation.length != 0) buf.write(workstation, pos, workstation.length, 'ascii');
|
|
120
|
+
pos += workstation.length; // workstation string
|
|
121
|
+
|
|
122
|
+
if (domain.length != 0) buf.write(domain, pos, domain.length, 'ascii');
|
|
123
|
+
pos += domain.length; // domain string
|
|
124
|
+
|
|
125
|
+
return 'NTLM ' + buf.toString('base64');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function parseType2Message(rawmsg) {
|
|
129
|
+
var match = rawmsg.match(/NTLM (.+)?/);
|
|
130
|
+
|
|
131
|
+
if (!match || !match[1]) {
|
|
132
|
+
throw new Error("Couldn't find NTLM in the message type2 coming from the server");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var buf = Buffer.from(match[1], 'base64');
|
|
136
|
+
var msg = {};
|
|
137
|
+
msg.signature = buf.slice(0, 8);
|
|
138
|
+
msg.type = buf.readInt16LE(8);
|
|
139
|
+
|
|
140
|
+
if (msg.type != 2) {
|
|
141
|
+
throw new Error("Server didn't return a type 2 message");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
msg.targetNameLen = buf.readInt16LE(12);
|
|
145
|
+
msg.targetNameMaxLen = buf.readInt16LE(14);
|
|
146
|
+
msg.targetNameOffset = buf.readInt32LE(16);
|
|
147
|
+
msg.targetName = buf.slice(msg.targetNameOffset, msg.targetNameOffset + msg.targetNameMaxLen);
|
|
148
|
+
msg.negotiateFlags = buf.readInt32LE(20);
|
|
149
|
+
msg.serverChallenge = buf.slice(24, 32);
|
|
150
|
+
msg.reserved = buf.slice(32, 40);
|
|
151
|
+
|
|
152
|
+
if (msg.negotiateFlags & flags.NTLM_NegotiateTargetInfo) {
|
|
153
|
+
msg.targetInfoLen = buf.readInt16LE(40);
|
|
154
|
+
msg.targetInfoMaxLen = buf.readInt16LE(42);
|
|
155
|
+
msg.targetInfoOffset = buf.readInt32LE(44);
|
|
156
|
+
msg.targetInfo = buf.slice(msg.targetInfoOffset, msg.targetInfoOffset + msg.targetInfoLen);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return msg;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function createType3Message(msg2, options) {
|
|
163
|
+
if (!options.domain) options.domain = '';
|
|
164
|
+
if (!options.workstation) options.workstation = '';
|
|
165
|
+
if (!options.username) options.username = '';
|
|
166
|
+
if (!options.password) options.password = '';
|
|
167
|
+
var nonce = msg2.serverChallenge;
|
|
168
|
+
var username = options.username;
|
|
169
|
+
var password = options.password;
|
|
170
|
+
var lm_password = options.lm_password;
|
|
171
|
+
var nt_password = options.nt_password;
|
|
172
|
+
var negotiateFlags = msg2.negotiateFlags;
|
|
173
|
+
var isUnicode = negotiateFlags & flags.NTLM_NegotiateUnicode;
|
|
174
|
+
var isNegotiateExtendedSecurity = negotiateFlags & flags.NTLM_NegotiateExtendedSecurity;
|
|
175
|
+
var BODY_LENGTH = 72;
|
|
176
|
+
var domainName = escape(options.domain.toUpperCase());
|
|
177
|
+
var workstation = escape(options.workstation.toUpperCase());
|
|
178
|
+
var workstationBytes, domainNameBytes, usernameBytes, encryptedRandomSessionKeyBytes;
|
|
179
|
+
var encryptedRandomSessionKey = "";
|
|
180
|
+
|
|
181
|
+
if (isUnicode) {
|
|
182
|
+
workstationBytes = Buffer.from(workstation, 'utf16le');
|
|
183
|
+
domainNameBytes = Buffer.from(domainName, 'utf16le');
|
|
184
|
+
usernameBytes = Buffer.from(username, 'utf16le');
|
|
185
|
+
encryptedRandomSessionKeyBytes = Buffer.from(encryptedRandomSessionKey, 'utf16le');
|
|
186
|
+
} else {
|
|
187
|
+
workstationBytes = Buffer.from(workstation, 'ascii');
|
|
188
|
+
domainNameBytes = Buffer.from(domainName, 'ascii');
|
|
189
|
+
usernameBytes = Buffer.from(username, 'ascii');
|
|
190
|
+
encryptedRandomSessionKeyBytes = Buffer.from(encryptedRandomSessionKey, 'ascii');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
var lmChallengeResponse = calc_resp(lm_password != null ? lm_password : create_LM_hashed_password_v1(password), nonce);
|
|
194
|
+
var ntChallengeResponse = calc_resp(nt_password != null ? nt_password : create_NT_hashed_password_v1(password), nonce);
|
|
195
|
+
|
|
196
|
+
if (isNegotiateExtendedSecurity) {
|
|
197
|
+
/*
|
|
198
|
+
* NTLMv2 extended security is enabled. While this technically can mean NTLMv2 extended security with NTLMv1 protocol,
|
|
199
|
+
* servers that support extended security likely also support NTLMv2, so use NTLMv2.
|
|
200
|
+
* This is also how curl implements NTLMv2 "detection".
|
|
201
|
+
* By using NTLMv2, this supports communication with servers that forbid the use of NTLMv1 (e.g. via windows policies)
|
|
202
|
+
*
|
|
203
|
+
* However, the target info is needed to construct the NTLMv2 response so if it can't be negotiated,
|
|
204
|
+
* fall back to NTLMv1 with NTLMv2 extended security.
|
|
205
|
+
*/
|
|
206
|
+
var pwhash = nt_password != null ? nt_password : create_NT_hashed_password_v1(password);
|
|
207
|
+
var clientChallenge = "";
|
|
208
|
+
|
|
209
|
+
for (var i = 0; i < 8; i++) {
|
|
210
|
+
clientChallenge += String.fromCharCode(Math.floor(Math.random() * 256));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
var clientChallengeBytes = Buffer.from(clientChallenge, 'ascii');
|
|
214
|
+
var challenges = msg2.targetInfo ? calc_ntlmv2_resp(pwhash, username, domainName, msg2.targetInfo, nonce, clientChallengeBytes) : ntlm2sr_calc_resp(pwhash, nonce, clientChallengeBytes);
|
|
215
|
+
lmChallengeResponse = challenges.lmChallengeResponse;
|
|
216
|
+
ntChallengeResponse = challenges.ntChallengeResponse;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
var signature = 'NTLMSSP\0';
|
|
220
|
+
var pos = 0;
|
|
221
|
+
var buf = Buffer.alloc(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length + encryptedRandomSessionKeyBytes.length);
|
|
222
|
+
buf.write(signature, pos, signature.length);
|
|
223
|
+
pos += signature.length;
|
|
224
|
+
buf.writeUInt32LE(3, pos);
|
|
225
|
+
pos += 4; // type 1
|
|
226
|
+
|
|
227
|
+
buf.writeUInt16LE(lmChallengeResponse.length, pos);
|
|
228
|
+
pos += 2; // LmChallengeResponseLen
|
|
229
|
+
|
|
230
|
+
buf.writeUInt16LE(lmChallengeResponse.length, pos);
|
|
231
|
+
pos += 2; // LmChallengeResponseMaxLen
|
|
232
|
+
|
|
233
|
+
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length, pos);
|
|
234
|
+
pos += 4; // LmChallengeResponseOffset
|
|
235
|
+
|
|
236
|
+
buf.writeUInt16LE(ntChallengeResponse.length, pos);
|
|
237
|
+
pos += 2; // NtChallengeResponseLen
|
|
238
|
+
|
|
239
|
+
buf.writeUInt16LE(ntChallengeResponse.length, pos);
|
|
240
|
+
pos += 2; // NtChallengeResponseMaxLen
|
|
241
|
+
|
|
242
|
+
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length, pos);
|
|
243
|
+
pos += 4; // NtChallengeResponseOffset
|
|
244
|
+
|
|
245
|
+
buf.writeUInt16LE(domainNameBytes.length, pos);
|
|
246
|
+
pos += 2; // DomainNameLen
|
|
247
|
+
|
|
248
|
+
buf.writeUInt16LE(domainNameBytes.length, pos);
|
|
249
|
+
pos += 2; // DomainNameMaxLen
|
|
250
|
+
|
|
251
|
+
buf.writeUInt32LE(BODY_LENGTH, pos);
|
|
252
|
+
pos += 4; // DomainNameOffset
|
|
253
|
+
|
|
254
|
+
buf.writeUInt16LE(usernameBytes.length, pos);
|
|
255
|
+
pos += 2; // UserNameLen
|
|
256
|
+
|
|
257
|
+
buf.writeUInt16LE(usernameBytes.length, pos);
|
|
258
|
+
pos += 2; // UserNameMaxLen
|
|
259
|
+
|
|
260
|
+
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length, pos);
|
|
261
|
+
pos += 4; // UserNameOffset
|
|
262
|
+
|
|
263
|
+
buf.writeUInt16LE(workstationBytes.length, pos);
|
|
264
|
+
pos += 2; // WorkstationLen
|
|
265
|
+
|
|
266
|
+
buf.writeUInt16LE(workstationBytes.length, pos);
|
|
267
|
+
pos += 2; // WorkstationMaxLen
|
|
268
|
+
|
|
269
|
+
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length, pos);
|
|
270
|
+
pos += 4; // WorkstationOffset
|
|
271
|
+
|
|
272
|
+
buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos);
|
|
273
|
+
pos += 2; // EncryptedRandomSessionKeyLen
|
|
274
|
+
|
|
275
|
+
buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos);
|
|
276
|
+
pos += 2; // EncryptedRandomSessionKeyMaxLen
|
|
277
|
+
|
|
278
|
+
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length, pos);
|
|
279
|
+
pos += 4; // EncryptedRandomSessionKeyOffset
|
|
280
|
+
// Fix #98
|
|
281
|
+
|
|
282
|
+
var flagsToWrite = isUnicode ? typeflags.NTLM_TYPE2_FLAGS : typeflags.NTLM_TYPE2_FLAGS - flags.NTLM_NegotiateUnicode;
|
|
283
|
+
buf.writeUInt32LE(flagsToWrite, pos);
|
|
284
|
+
pos += 4; // NegotiateFlags
|
|
285
|
+
|
|
286
|
+
buf.writeUInt8(5, pos);
|
|
287
|
+
pos++; // ProductMajorVersion
|
|
288
|
+
|
|
289
|
+
buf.writeUInt8(1, pos);
|
|
290
|
+
pos++; // ProductMinorVersion
|
|
291
|
+
|
|
292
|
+
buf.writeUInt16LE(2600, pos);
|
|
293
|
+
pos += 2; // ProductBuild
|
|
294
|
+
|
|
295
|
+
buf.writeUInt8(0, pos);
|
|
296
|
+
pos++; // VersionReserved1
|
|
297
|
+
|
|
298
|
+
buf.writeUInt8(0, pos);
|
|
299
|
+
pos++; // VersionReserved2
|
|
300
|
+
|
|
301
|
+
buf.writeUInt8(0, pos);
|
|
302
|
+
pos++; // VersionReserved3
|
|
303
|
+
|
|
304
|
+
buf.writeUInt8(15, pos);
|
|
305
|
+
pos++; // NTLMRevisionCurrent
|
|
306
|
+
|
|
307
|
+
domainNameBytes.copy(buf, pos);
|
|
308
|
+
pos += domainNameBytes.length;
|
|
309
|
+
usernameBytes.copy(buf, pos);
|
|
310
|
+
pos += usernameBytes.length;
|
|
311
|
+
workstationBytes.copy(buf, pos);
|
|
312
|
+
pos += workstationBytes.length;
|
|
313
|
+
lmChallengeResponse.copy(buf, pos);
|
|
314
|
+
pos += lmChallengeResponse.length;
|
|
315
|
+
ntChallengeResponse.copy(buf, pos);
|
|
316
|
+
pos += ntChallengeResponse.length;
|
|
317
|
+
encryptedRandomSessionKeyBytes.copy(buf, pos);
|
|
318
|
+
pos += encryptedRandomSessionKeyBytes.length;
|
|
319
|
+
return 'NTLM ' + buf.toString('base64');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function create_LM_hashed_password_v1(password) {
|
|
323
|
+
// fix the password length to 14 bytes
|
|
324
|
+
password = password.toUpperCase();
|
|
325
|
+
var passwordBytes = Buffer.from(password, 'ascii');
|
|
326
|
+
var passwordBytesPadded = Buffer.alloc(14);
|
|
327
|
+
passwordBytesPadded.fill("\0");
|
|
328
|
+
var sourceEnd = 14;
|
|
329
|
+
if (passwordBytes.length < 14) sourceEnd = passwordBytes.length;
|
|
330
|
+
passwordBytes.copy(passwordBytesPadded, 0, 0, sourceEnd); // split into 2 parts of 7 bytes:
|
|
331
|
+
|
|
332
|
+
var firstPart = passwordBytesPadded.slice(0, 7);
|
|
333
|
+
var secondPart = passwordBytesPadded.slice(7);
|
|
334
|
+
|
|
335
|
+
function encrypt(buf) {
|
|
336
|
+
var key = insertZerosEvery7Bits(buf);
|
|
337
|
+
var des = desjs.DES.create({
|
|
338
|
+
type: 'encrypt',
|
|
339
|
+
key: key
|
|
340
|
+
});
|
|
341
|
+
var magicKey = Buffer.from('KGS!@#$%', 'ascii'); // page 57 in [MS-NLMP]
|
|
342
|
+
|
|
343
|
+
var encrypted = des.update(magicKey);
|
|
344
|
+
return Buffer.from(encrypted);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
var firstPartEncrypted = encrypt(firstPart);
|
|
348
|
+
var secondPartEncrypted = encrypt(secondPart);
|
|
349
|
+
return Buffer.concat([firstPartEncrypted, secondPartEncrypted]);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function insertZerosEvery7Bits(buf) {
|
|
353
|
+
var binaryArray = bytes2binaryArray(buf);
|
|
354
|
+
var newBinaryArray = [];
|
|
355
|
+
|
|
356
|
+
for (var i = 0; i < binaryArray.length; i++) {
|
|
357
|
+
newBinaryArray.push(binaryArray[i]);
|
|
358
|
+
|
|
359
|
+
if ((i + 1) % 7 === 0) {
|
|
360
|
+
newBinaryArray.push(0);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return binaryArray2bytes(newBinaryArray);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function bytes2binaryArray(buf) {
|
|
368
|
+
var hex2binary = {
|
|
369
|
+
0: [0, 0, 0, 0],
|
|
370
|
+
1: [0, 0, 0, 1],
|
|
371
|
+
2: [0, 0, 1, 0],
|
|
372
|
+
3: [0, 0, 1, 1],
|
|
373
|
+
4: [0, 1, 0, 0],
|
|
374
|
+
5: [0, 1, 0, 1],
|
|
375
|
+
6: [0, 1, 1, 0],
|
|
376
|
+
7: [0, 1, 1, 1],
|
|
377
|
+
8: [1, 0, 0, 0],
|
|
378
|
+
9: [1, 0, 0, 1],
|
|
379
|
+
A: [1, 0, 1, 0],
|
|
380
|
+
B: [1, 0, 1, 1],
|
|
381
|
+
C: [1, 1, 0, 0],
|
|
382
|
+
D: [1, 1, 0, 1],
|
|
383
|
+
E: [1, 1, 1, 0],
|
|
384
|
+
F: [1, 1, 1, 1]
|
|
385
|
+
};
|
|
386
|
+
var hexString = buf.toString('hex').toUpperCase();
|
|
387
|
+
var array = [];
|
|
388
|
+
|
|
389
|
+
for (var i = 0; i < hexString.length; i++) {
|
|
390
|
+
var hexchar = hexString.charAt(i);
|
|
391
|
+
array = array.concat(hex2binary[hexchar]);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return array;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function binaryArray2bytes(array) {
|
|
398
|
+
var binary2hex = {
|
|
399
|
+
'0000': 0,
|
|
400
|
+
'0001': 1,
|
|
401
|
+
'0010': 2,
|
|
402
|
+
'0011': 3,
|
|
403
|
+
'0100': 4,
|
|
404
|
+
'0101': 5,
|
|
405
|
+
'0110': 6,
|
|
406
|
+
'0111': 7,
|
|
407
|
+
'1000': 8,
|
|
408
|
+
'1001': 9,
|
|
409
|
+
'1010': 'A',
|
|
410
|
+
'1011': 'B',
|
|
411
|
+
'1100': 'C',
|
|
412
|
+
'1101': 'D',
|
|
413
|
+
'1110': 'E',
|
|
414
|
+
'1111': 'F'
|
|
415
|
+
};
|
|
416
|
+
var bufArray = [];
|
|
417
|
+
|
|
418
|
+
for (var i = 0; i < array.length; i += 8) {
|
|
419
|
+
if (i + 7 > array.length) break;
|
|
420
|
+
var binString1 = '' + array[i] + '' + array[i + 1] + '' + array[i + 2] + '' + array[i + 3];
|
|
421
|
+
var binString2 = '' + array[i + 4] + '' + array[i + 5] + '' + array[i + 6] + '' + array[i + 7];
|
|
422
|
+
var hexchar1 = binary2hex[binString1];
|
|
423
|
+
var hexchar2 = binary2hex[binString2];
|
|
424
|
+
var buf = Buffer.from(hexchar1 + '' + hexchar2, 'hex');
|
|
425
|
+
bufArray.push(buf);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return Buffer.concat(bufArray);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function create_NT_hashed_password_v1(password) {
|
|
432
|
+
var buf = Buffer.from(password, 'utf16le');
|
|
433
|
+
var md4 = jsmd4.create();
|
|
434
|
+
md4.update(buf);
|
|
435
|
+
return Buffer.from(md4.digest());
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
function calc_resp(password_hash, server_challenge) {
|
|
439
|
+
// padding with zeros to make the hash 21 bytes long
|
|
440
|
+
var passHashPadded = Buffer.alloc(21);
|
|
441
|
+
passHashPadded.fill("\0");
|
|
442
|
+
password_hash.copy(passHashPadded, 0, 0, password_hash.length);
|
|
443
|
+
var resArray = [];
|
|
444
|
+
var des = desjs.DES.create({
|
|
445
|
+
type: 'encrypt',
|
|
446
|
+
key: insertZerosEvery7Bits(passHashPadded.slice(0, 7))
|
|
447
|
+
});
|
|
448
|
+
resArray.push(Buffer.from(des.update(server_challenge.slice(0, 8))));
|
|
449
|
+
des = desjs.DES.create({
|
|
450
|
+
type: 'encrypt',
|
|
451
|
+
key: insertZerosEvery7Bits(passHashPadded.slice(7, 14))
|
|
452
|
+
});
|
|
453
|
+
resArray.push(Buffer.from(des.update(server_challenge.slice(0, 8))));
|
|
454
|
+
des = desjs.DES.create({
|
|
455
|
+
type: 'encrypt',
|
|
456
|
+
key: insertZerosEvery7Bits(passHashPadded.slice(14, 21))
|
|
457
|
+
});
|
|
458
|
+
resArray.push(Buffer.from(des.update(server_challenge.slice(0, 8))));
|
|
459
|
+
return Buffer.concat(resArray);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function hmac_md5(key, data) {
|
|
463
|
+
var hmac = crypto.createHmac('md5', key);
|
|
464
|
+
hmac.update(data);
|
|
465
|
+
return hmac.digest();
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function ntlm2sr_calc_resp(responseKeyNT, serverChallenge, clientChallenge) {
|
|
469
|
+
// padding with zeros to make the hash 16 bytes longer
|
|
470
|
+
var lmChallengeResponse = Buffer.alloc(clientChallenge.length + 16);
|
|
471
|
+
lmChallengeResponse.fill("\0");
|
|
472
|
+
clientChallenge.copy(lmChallengeResponse, 0, 0, clientChallenge.length);
|
|
473
|
+
var buf = Buffer.concat([serverChallenge, clientChallenge]);
|
|
474
|
+
var md5 = crypto.createHash('md5');
|
|
475
|
+
md5.update(buf);
|
|
476
|
+
var sess = md5.digest();
|
|
477
|
+
var ntChallengeResponse = calc_resp(responseKeyNT, sess.slice(0, 8));
|
|
478
|
+
return {
|
|
479
|
+
lmChallengeResponse: lmChallengeResponse,
|
|
480
|
+
ntChallengeResponse: ntChallengeResponse
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function calc_ntlmv2_resp(pwhash, username, domain, targetInfo, serverChallenge, clientChallenge) {
|
|
485
|
+
var responseKeyNTLM = NTOWFv2(pwhash, username, domain);
|
|
486
|
+
var lmV2ChallengeResponse = Buffer.concat([hmac_md5(responseKeyNTLM, Buffer.concat([serverChallenge, clientChallenge])), clientChallenge]); // 11644473600000 = diff between 1970 and 1601
|
|
487
|
+
|
|
488
|
+
var now = Date.now();
|
|
489
|
+
var timestamp = (BigInt(now) + BigInt(11644473600000)) * BigInt(10000); // we need BigInt to be able to write it to a buffer
|
|
490
|
+
|
|
491
|
+
var timestampBuffer = Buffer.alloc(8);
|
|
492
|
+
timestampBuffer.writeBigUInt64LE(timestamp);
|
|
493
|
+
var zero32Bit = Buffer.alloc(4, 0);
|
|
494
|
+
var temp = Buffer.concat([// Version
|
|
495
|
+
Buffer.from([0x01, 0x01, 0x00, 0x00]), zero32Bit, timestampBuffer, clientChallenge, zero32Bit, targetInfo, zero32Bit]);
|
|
496
|
+
var proofString = hmac_md5(responseKeyNTLM, Buffer.concat([serverChallenge, temp]));
|
|
497
|
+
var ntV2ChallengeResponse = Buffer.concat([proofString, temp]);
|
|
498
|
+
return {
|
|
499
|
+
lmChallengeResponse: lmV2ChallengeResponse,
|
|
500
|
+
ntChallengeResponse: ntV2ChallengeResponse
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function NTOWFv2(pwhash, user, domain) {
|
|
505
|
+
return hmac_md5(pwhash, Buffer.from(user.toUpperCase() + domain, 'utf16le'));
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
exports.createType1Message = createType1Message;
|
|
509
|
+
exports.parseType2Message = parseType2Message;
|
|
510
|
+
exports.createType3Message = createType3Message;
|
|
511
|
+
exports.create_NT_hashed_password = create_NT_hashed_password_v1;
|
|
512
|
+
exports.create_LM_hashed_password = create_LM_hashed_password_v1;
|
|
513
|
+
/* eslint-enable */
|
|
514
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9veF9tb2R1bGVzL21vZHVsZS1odHRwL250bG0uanMiXSwibmFtZXMiOlsiY3J5cHRvIiwicmVxdWlyZSIsImpzbWQ0IiwiZGVzanMiLCJmbGFncyIsIk5UTE1fTmVnb3RpYXRlVW5pY29kZSIsIk5UTE1fTmVnb3RpYXRlT0VNIiwiTlRMTV9SZXF1ZXN0VGFyZ2V0IiwiTlRMTV9Vbmtub3duOSIsIk5UTE1fTmVnb3RpYXRlU2lnbiIsIk5UTE1fTmVnb3RpYXRlU2VhbCIsIk5UTE1fTmVnb3RpYXRlRGF0YWdyYW0iLCJOVExNX05lZ290aWF0ZUxhbk1hbmFnZXJLZXkiLCJOVExNX1Vua25vd244IiwiTlRMTV9OZWdvdGlhdGVOVExNIiwiTlRMTV9OZWdvdGlhdGVOVE9ubHkiLCJOVExNX0Fub255bW91cyIsIk5UTE1fTmVnb3RpYXRlT2VtRG9tYWluU3VwcGxpZWQiLCJOVExNX05lZ290aWF0ZU9lbVdvcmtzdGF0aW9uU3VwcGxpZWQiLCJOVExNX1Vua25vd242IiwiTlRMTV9OZWdvdGlhdGVBbHdheXNTaWduIiwiTlRMTV9UYXJnZXRUeXBlRG9tYWluIiwiTlRMTV9UYXJnZXRUeXBlU2VydmVyIiwiTlRMTV9UYXJnZXRUeXBlU2hhcmUiLCJOVExNX05lZ290aWF0ZUV4dGVuZGVkU2VjdXJpdHkiLCJOVExNX05lZ290aWF0ZUlkZW50aWZ5IiwiTlRMTV9Vbmtub3duNSIsIk5UTE1fUmVxdWVzdE5vbk5UU2Vzc2lvbktleSIsIk5UTE1fTmVnb3RpYXRlVGFyZ2V0SW5mbyIsIk5UTE1fVW5rbm93bjQiLCJOVExNX05lZ290aWF0ZVZlcnNpb24iLCJOVExNX1Vua25vd24zIiwiTlRMTV9Vbmtub3duMiIsIk5UTE1fVW5rbm93bjEiLCJOVExNX05lZ290aWF0ZTEyOCIsIk5UTE1fTmVnb3RpYXRlS2V5RXhjaGFuZ2UiLCJOVExNX05lZ290aWF0ZTU2IiwidHlwZWZsYWdzIiwiTlRMTV9UWVBFMV9GTEFHUyIsIk5UTE1fVFlQRTJfRkxBR1MiLCJjcmVhdGVUeXBlMU1lc3NhZ2UiLCJvcHRpb25zIiwiZG9tYWluIiwid29ya3N0YXRpb24iLCJlc2NhcGUiLCJ0b1VwcGVyQ2FzZSIsInByb3RvY29sIiwiQk9EWV9MRU5HVEgiLCJ0eXBlMWZsYWdzIiwicG9zIiwiYnVmIiwiQnVmZmVyIiwiYWxsb2MiLCJsZW5ndGgiLCJ3cml0ZSIsIndyaXRlVUludDMyTEUiLCJ3cml0ZVVJbnQxNkxFIiwid3JpdGVVSW50OCIsInRvU3RyaW5nIiwicGFyc2VUeXBlMk1lc3NhZ2UiLCJyYXdtc2ciLCJtYXRjaCIsIkVycm9yIiwiZnJvbSIsIm1zZyIsInNpZ25hdHVyZSIsInNsaWNlIiwidHlwZSIsInJlYWRJbnQxNkxFIiwidGFyZ2V0TmFtZUxlbiIsInRhcmdldE5hbWVNYXhMZW4iLCJ0YXJnZXROYW1lT2Zmc2V0IiwicmVhZEludDMyTEUiLCJ0YXJnZXROYW1lIiwibmVnb3RpYXRlRmxhZ3MiLCJzZXJ2ZXJDaGFsbGVuZ2UiLCJyZXNlcnZlZCIsInRhcmdldEluZm9MZW4iLCJ0YXJnZXRJbmZvTWF4TGVuIiwidGFyZ2V0SW5mb09mZnNldCIsInRhcmdldEluZm8iLCJjcmVhdGVUeXBlM01lc3NhZ2UiLCJtc2cyIiwidXNlcm5hbWUiLCJwYXNzd29yZCIsIm5vbmNlIiwibG1fcGFzc3dvcmQiLCJudF9wYXNzd29yZCIsImlzVW5pY29kZSIsImlzTmVnb3RpYXRlRXh0ZW5kZWRTZWN1cml0eSIsImRvbWFpbk5hbWUiLCJ3b3Jrc3RhdGlvbkJ5dGVzIiwiZG9tYWluTmFtZUJ5dGVzIiwidXNlcm5hbWVCeXRlcyIsImVuY3J5cHRlZFJhbmRvbVNlc3Npb25LZXlCeXRlcyIsImVuY3J5cHRlZFJhbmRvbVNlc3Npb25LZXkiLCJsbUNoYWxsZW5nZVJlc3BvbnNlIiwiY2FsY19yZXNwIiwiY3JlYXRlX0xNX2hhc2hlZF9wYXNzd29yZF92MSIsIm50Q2hhbGxlbmdlUmVzcG9uc2UiLCJjcmVhdGVfTlRfaGFzaGVkX3Bhc3N3b3JkX3YxIiwicHdoYXNoIiwiY2xpZW50Q2hhbGxlbmdlIiwiaSIsIlN0cmluZyIsImZyb21DaGFyQ29kZSIsIk1hdGgiLCJmbG9vciIsInJhbmRvbSIsImNsaWVudENoYWxsZW5nZUJ5dGVzIiwiY2hhbGxlbmdlcyIsImNhbGNfbnRsbXYyX3Jlc3AiLCJudGxtMnNyX2NhbGNfcmVzcCIsImZsYWdzVG9Xcml0ZSIsImNvcHkiLCJwYXNzd29yZEJ5dGVzIiwicGFzc3dvcmRCeXRlc1BhZGRlZCIsImZpbGwiLCJzb3VyY2VFbmQiLCJmaXJzdFBhcnQiLCJzZWNvbmRQYXJ0IiwiZW5jcnlwdCIsImtleSIsImluc2VydFplcm9zRXZlcnk3Qml0cyIsImRlcyIsIkRFUyIsImNyZWF0ZSIsIm1hZ2ljS2V5IiwiZW5jcnlwdGVkIiwidXBkYXRlIiwiZmlyc3RQYXJ0RW5jcnlwdGVkIiwic2Vjb25kUGFydEVuY3J5cHRlZCIsImNvbmNhdCIsImJpbmFyeUFycmF5IiwiYnl0ZXMyYmluYXJ5QXJyYXkiLCJuZXdCaW5hcnlBcnJheSIsInB1c2giLCJiaW5hcnlBcnJheTJieXRlcyIsImhleDJiaW5hcnkiLCJBIiwiQiIsIkMiLCJEIiwiRSIsIkYiLCJoZXhTdHJpbmciLCJhcnJheSIsImhleGNoYXIiLCJjaGFyQXQiLCJiaW5hcnkyaGV4IiwiYnVmQXJyYXkiLCJiaW5TdHJpbmcxIiwiYmluU3RyaW5nMiIsImhleGNoYXIxIiwiaGV4Y2hhcjIiLCJtZDQiLCJkaWdlc3QiLCJwYXNzd29yZF9oYXNoIiwic2VydmVyX2NoYWxsZW5nZSIsInBhc3NIYXNoUGFkZGVkIiwicmVzQXJyYXkiLCJobWFjX21kNSIsImRhdGEiLCJobWFjIiwiY3JlYXRlSG1hYyIsInJlc3BvbnNlS2V5TlQiLCJtZDUiLCJjcmVhdGVIYXNoIiwic2VzcyIsInJlc3BvbnNlS2V5TlRMTSIsIk5UT1dGdjIiLCJsbVYyQ2hhbGxlbmdlUmVzcG9uc2UiLCJub3ciLCJEYXRlIiwidGltZXN0YW1wIiwiQmlnSW50IiwidGltZXN0YW1wQnVmZmVyIiwid3JpdGVCaWdVSW50NjRMRSIsInplcm8zMkJpdCIsInRlbXAiLCJwcm9vZlN0cmluZyIsIm50VjJDaGFsbGVuZ2VSZXNwb25zZSIsInVzZXIiLCJleHBvcnRzIiwiY3JlYXRlX05UX2hhc2hlZF9wYXNzd29yZCIsImNyZWF0ZV9MTV9oYXNoZWRfcGFzc3dvcmQiXSwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBLElBQUlBLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFFBQUQsQ0FBcEI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsUUFBRCxDQUFuQjs7QUFDQSxJQUFJRSxLQUFLLEdBQUdGLE9BQU8sQ0FBQyxRQUFELENBQW5COztBQUVBLElBQUlHLEtBQUssR0FBRztBQUNYQyxFQUFBQSxxQkFBcUIsRUFBbUIsVUFEN0I7QUFFWEMsRUFBQUEsaUJBQWlCLEVBQXVCLFVBRjdCO0FBR1hDLEVBQUFBLGtCQUFrQixFQUFzQixVQUg3QjtBQUlYQyxFQUFBQSxhQUFhLEVBQTJCLFVBSjdCO0FBS1hDLEVBQUFBLGtCQUFrQixFQUFzQixVQUw3QjtBQU1YQyxFQUFBQSxrQkFBa0IsRUFBc0IsVUFON0I7QUFPWEMsRUFBQUEsc0JBQXNCLEVBQWtCLFVBUDdCO0FBUVhDLEVBQUFBLDJCQUEyQixFQUFhLFVBUjdCO0FBU1hDLEVBQUFBLGFBQWEsRUFBMkIsVUFUN0I7QUFVWEMsRUFBQUEsa0JBQWtCLEVBQXNCLFVBVjdCO0FBV1hDLEVBQUFBLG9CQUFvQixFQUFvQixVQVg3QjtBQVlYQyxFQUFBQSxjQUFjLEVBQTBCLFVBWjdCO0FBYVhDLEVBQUFBLCtCQUErQixFQUFTLFVBYjdCO0FBY1hDLEVBQUFBLG9DQUFvQyxFQUFJLFVBZDdCO0FBZVhDLEVBQUFBLGFBQWEsRUFBMkIsVUFmN0I7QUFnQlhDLEVBQUFBLHdCQUF3QixFQUFnQixVQWhCN0I7QUFpQlhDLEVBQUFBLHFCQUFxQixFQUFtQixVQWpCN0I7QUFrQlhDLEVBQUFBLHFCQUFxQixFQUFtQixVQWxCN0I7QUFtQlhDLEVBQUFB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bUJBQW1CLEVBQUUyRSxxQkFEZjtBQUVOeEUsSUFBQUEsbUJBQW1CLEVBQUVrRjtBQUZmLEdBQVA7QUFJSDs7QUFFRCxTQUFTWCxPQUFULENBQWlCckUsTUFBakIsRUFBeUJpRixJQUF6QixFQUErQjVJLE1BQS9CLEVBQXNDO0FBQ3JDLFNBQU91SCxRQUFRLENBQUM1RCxNQUFELEVBQVNsRCxNQUFNLENBQUNZLElBQVAsQ0FBWXVILElBQUksQ0FBQ3pJLFdBQUwsS0FBcUJILE1BQWpDLEVBQXlDLFNBQXpDLENBQVQsQ0FBZjtBQUNBOztBQUVENkksT0FBTyxDQUFDL0ksa0JBQVIsR0FBNkJBLGtCQUE3QjtBQUNBK0ksT0FBTyxDQUFDNUgsaUJBQVIsR0FBNEJBLGlCQUE1QjtBQUNBNEgsT0FBTyxDQUFDdEcsa0JBQVIsR0FBNkJBLGtCQUE3QjtBQUNBc0csT0FBTyxDQUFDQyx5QkFBUixHQUFvQ3BGLDRCQUFwQztBQUNBbUYsT0FBTyxDQUFDRSx5QkFBUixHQUFvQ3ZGLDRCQUFwQztBQUNBIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIENvcHlyaWdodCAoYykgMjAxMyBTYW0gRGVjcm9jayBodHRwczovL2dpdGh1Yi5jb20vU2FtRGVjcm9jay9cclxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuICpcclxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXHJcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cclxuICovXHJcbi8qIGVzbGludC1kaXNhYmxlICovXHJcbnZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcclxudmFyIGpzbWQ0ID0gcmVxdWlyZShcImpzLW1kNFwiKTtcclxudmFyIGRlc2pzID0gcmVxdWlyZShcImRlcy5qc1wiKTtcclxuXHJcbnZhciBmbGFncyA9IHtcclxuXHROVExNX05lZ290aWF0ZVVuaWNvZGUgICAgICAgICAgICAgICAgOiAgMHgwMDAwMDAwMSxcclxuXHROVExNX05lZ290aWF0ZU9FTSAgICAgICAgICAgICAgICAgICAgOiAgMHgwMDAwMDAwMixcclxuXHROVExNX1JlcXVlc3RUYXJnZXQgICAgICAgICAgICAgICAgICAgOiAgMHgwMDAwMDAwNCxcclxuXHROVExNX1Vua25vd245ICAgICAgICAgICAgICAgICAgICAgICAgOiAgMHgwMDAwMDAwOCxcclxuXHROVExNX05lZ290aWF0ZVNpZ24gICAgICAgICAgICAgICAgICAgOiAgMHgwMDAwMDAxMCxcclxuXHROVExNX05lZ290aWF0ZVNlYWwgICAgICAgICAgICAgICAgICAgOiAgMHgwMDAwMDAyMCxcclxuXHROVExNX05lZ290aWF0ZURhdGFncmFtICAgICAgICAgICAgICAgOiAgMHgwMDAwMDA0MCxcclxuXHROVExNX05lZ290aWF0ZUxhbk1hbmFnZXJLZXkgICAgICAgICAgOiAgMHgwMDAwMDA4MCxcclxuXHROVExNX1Vua25vd244ICAgICAgICAgICAgICAgICAgICAgICAgOiAgMHgwMDAwMDEwMCxcclxuXHROVExNX05lZ290aWF0ZU5UTE0gICAgICAgICAgICAgICAgICAgOiAgMHgwMDAwMDIwMCxcclxuXHROVExNX05lZ290aWF0ZU5UT25seSAgICAgICAgICAgICAgICAgOiAgMHgwMDAwMDQwMCxcclxuXHROVExNX0Fub255bW91cyAgICAgICAgICAgICAgICAgICAgICAgOiAgMHgwMDAwMDgwMCxcclxuXHROVExNX05lZ290aWF0ZU9lbURvbWFpblN1cHBsaWVkICAgICAgOiAgMHgwMDAwMTAwMCxcclxuXHROVExNX05lZ290aWF0ZU9lbVdvcmtzdGF0aW9uU3VwcGxpZWQgOiAgMHgwMDAwMjAwMCxcclxuXHROVExNX1Vua25vd242ICAgICAgICAgICAgICAgICAgICAgICAgOiAgMHgwMDAwNDAwMCxcclxuXHROVExNX05lZ290aWF0ZUFsd2F5c1NpZ24gICAgICAgICAgICAgOiAgMHgwMDAwODAwMCxcclxuXHROVExNX1RhcmdldFR5cGVEb21haW4gICAgICAgICAgICAgICAgOiAgMHgwMDAxMDAwMCxcclxuXHROVExNX1RhcmdldFR5cGVTZXJ2ZXIgICAgICAgICAgICAgICAgOiAgMHgwMDAyMDAwMCxcclxuXHROVExNX1RhcmdldFR5cGVTaGFyZSAgICAgICAgICAgICAgICAgOiAgMHgwMDA0MDAwMCxcclxuXHROVExNX05lZ290aWF0ZUV4dGVuZGVkU2VjdXJpdHkgICAgICAgOiAgMHgwMDA4MDAwMCxcclxuXHROVExNX05lZ290aWF0ZUlkZW50aWZ5ICAgICAgICAgICAgICAgOiAgMHgwMDEwMDAwMCxcclxuXHROVExNX1Vua25vd241ICAgICAgICAgICAgICAgICAgICAgICAgOiAgMHgwMDIwMDAwMCxcclxuXHROVExNX1JlcXVlc3ROb25OVFNlc3Npb25LZXkgICAgICAgICAgOiAgMHgwMDQwMDAwMCxcclxuXHROVExNX05lZ290aWF0ZVRhcmdldEluZm8gICAgICAgICAgICAgOiAgMHgwMDgwMDAwMCxcclxuXHROVExNX1Vua25vd240ICAgICAgICAgICAgICAgICAgICAgICAgOiAgMHgwMTAwMDAwMCxcclxuXHROVExNX05lZ290aWF0ZVZlcnNpb24gICAgICAgICAgICAgICAgOiAgMHgwMjAwMDAwMCxcclxuXHROVExNX1Vua25vd24zICAgICAgICAgICAgICAgICAgICAgICAgOiAgMHgwNDAwMDAwMCxcclxuXHROVExNX1Vua25vd24yICAgICAgICAgICAgICAgICAgICAgICAgOiAgMHgwODAwMDAwMCxcclxuXHROVExNX1Vua25vd24xICAgICAgICAgICAgICAgICAgICAgICAgOiAgMHgxMDAwMDAwMCxcclxuXHROVExNX05lZ290aWF0ZTEyOCAgICAgICAgICAgICAgICAgICAgOiAgMHgyMDAwMDAwMCxcclxuXHROVExNX05lZ290aWF0ZUtleUV4Y2hhbmdlICAgICAgICAgICAgOiAgMHg0MDAwMDAwMCxcclxuXHROVExNX05lZ290aWF0ZTU2ICAgICAgICAgICAgICAgICAgICAgOiAgMHg4MDAwMDAwMFxyXG59O1xyXG52YXIgdHlwZWZsYWdzID0ge1xyXG5cdE5UTE1fVFlQRTFfRkxBR1MgOiBcdCAgZmxhZ3MuTlRMTV9OZWdvdGlhdGVVbmljb2RlXHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGVPRU1cclxuXHRcdFx0XHRcdFx0KyBmbGFncy5OVExNX1JlcXVlc3RUYXJnZXRcclxuXHRcdFx0XHRcdFx0KyBmbGFncy5OVExNX05lZ290aWF0ZU5UTE1cclxuXHRcdFx0XHRcdFx0KyBmbGFncy5OVExNX05lZ290aWF0ZU9lbURvbWFpblN1cHBsaWVkXHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGVPZW1Xb3Jrc3RhdGlvblN1cHBsaWVkXHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGVBbHdheXNTaWduXHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGVFeHRlbmRlZFNlY3VyaXR5XHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGVWZXJzaW9uXHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGUxMjhcclxuXHRcdFx0XHRcdFx0KyBmbGFncy5OVExNX05lZ290aWF0ZTU2LFxyXG5cclxuXHROVExNX1RZUEUyX0ZMQUdTIDogICAgZmxhZ3MuTlRMTV9OZWdvdGlhdGVVbmljb2RlXHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9SZXF1ZXN0VGFyZ2V0XHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGVOVExNXHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGVBbHdheXNTaWduXHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGVFeHRlbmRlZFNlY3VyaXR5XHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGVUYXJnZXRJbmZvXHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGVWZXJzaW9uXHJcblx0XHRcdFx0XHRcdCsgZmxhZ3MuTlRMTV9OZWdvdGlhdGUxMjhcclxuXHRcdFx0XHRcdFx0KyBmbGFncy5OVExNX05lZ290aWF0ZTU2XHJcbn07XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVUeXBlMU1lc3NhZ2Uob3B0aW9ucyl7XHJcblx0aWYoIW9wdGlvbnMuZG9tYWluKSBvcHRpb25zLmRvbWFpbiA9ICcnO1xyXG5cdGlmKCFvcHRpb25zLndvcmtzdGF0aW9uKSBvcHRpb25zLndvcmtzdGF0aW9uID0gJyc7XHJcblxyXG5cdHZhciBkb21haW4gPSBlc2NhcGUob3B0aW9ucy5kb21haW4udG9VcHBlckNhc2UoKSk7XHJcblx0dmFyIHdvcmtzdGF0aW9uID0gZXNjYXBlKG9wdGlvbnMud29ya3N0YXRpb24udG9VcHBlckNhc2UoKSk7XHJcblx0dmFyIHByb3RvY29sID0gJ05UTE1TU1BcXDAnO1xyXG5cclxuXHR2YXIgQk9EWV9MRU5HVEggPSA0MDtcclxuXHJcblx0dmFyIHR5cGUxZmxhZ3MgPSB0eXBlZmxhZ3MuTlRMTV9UWVBFMV9GTEFHUztcclxuXHRpZighZG9tYWluIHx8IGRvbWFpbiA9PT0gJycpXHJcblx0XHR0eXBlMWZsYWdzID0gdHlwZTFmbGFncyAtIGZsYWdzLk5UTE1fTmVnb3RpYXRlT2VtRG9tYWluU3VwcGxpZWQ7XHJcblxyXG5cdHZhciBwb3MgPSAwO1xyXG5cdHZhciBidWYgPSBCdWZmZXIuYWxsb2MoQk9EWV9MRU5HVEggKyBkb21haW4ubGVuZ3RoICsgd29ya3N0YXRpb24ubGVuZ3RoKTtcclxuXHJcblxyXG5cdGJ1Zi53cml0ZShwcm90b2NvbCwgcG9zLCBwcm90b2NvbC5sZW5ndGgpOyBwb3MgKz0gcHJvdG9jb2wubGVuZ3RoOyAvLyBwcm90b2NvbFxyXG5cdGJ1Zi53cml0ZVVJbnQzMkxFKDEsIHBvcyk7IHBvcyArPSA0OyAgICAgICAgICAvLyB0eXBlIDFcclxuXHRidWYud3JpdGVVSW50MzJMRSh0eXBlMWZsYWdzLCBwb3MpOyBwb3MgKz0gNDsgLy8gVFlQRTEgZmxhZ1xyXG5cclxuXHRidWYud3JpdGVVSW50MTZMRShkb21haW4ubGVuZ3RoLCBwb3MpOyBwb3MgKz0gMjsgLy8gZG9tYWluIGxlbmd0aFxyXG5cdGJ1Zi53cml0ZVVJbnQxNkxFKGRvbWFpbi5sZW5ndGgsIHBvcyk7IHBvcyArPSAyOyAvLyBkb21haW4gbWF4IGxlbmd0aFxyXG5cdGJ1Zi53cml0ZVVJbnQzMkxFKEJPRFlfTEVOR1RIICsgd29ya3N0YXRpb24ubGVuZ3RoLCBwb3MpOyBwb3MgKz0gNDsgLy8gZG9tYWluIGJ1ZmZlciBvZmZzZXRcclxuXHJcblx0YnVmLndyaXRlVUludDE2TEUod29ya3N0YXRpb24ubGVuZ3RoLCBwb3MpOyBwb3MgKz0gMjsgLy8gd29ya3N0YXRpb24gbGVuZ3RoXHJcblx0YnVmLndyaXRlVUludDE2TEUod29ya3N0YXRpb24ubGVuZ3RoLCBwb3MpOyBwb3MgKz0gMjsgLy8gd29ya3N0YXRpb24gbWF4IGxlbmd0aFxyXG5cdGJ1Zi53cml0ZVVJbnQzMkxFKEJPRFlfTEVOR1RILCBwb3MpOyBwb3MgKz0gNDsgLy8gd29ya3N0YXRpb24gYnVmZmVyIG9mZnNldFxyXG5cclxuXHRidWYud3JpdGVVSW50OCg1LCBwb3MpOyBwb3MgKz0gMTsgICAgICAvL1Byb2R1Y3RNYWpvclZlcnNpb25cclxuXHRidWYud3JpdGVVSW50OCgxLCBwb3MpOyBwb3MgKz0gMTsgICAgICAvL1Byb2R1Y3RNaW5vclZlcnNpb25cclxuXHRidWYud3JpdGVVSW50MTZMRSgyNjAwLCBwb3MpOyBwb3MgKz0gMjsgLy9Qcm9kdWN0QnVpbGRcclxuXHJcblx0YnVmLndyaXRlVUludDgoMCAsIHBvcyk7IHBvcyArPSAxOyAvL1ZlcnNpb25SZXNlcnZlZDFcclxuXHRidWYud3JpdGVVSW50OCgwICwgcG9zKTsgcG9zICs9IDE7IC8vVmVyc2lvblJlc2VydmVkMlxyXG5cdGJ1Zi53cml0ZVVJbnQ4KDAgLCBwb3MpOyBwb3MgKz0gMTsgLy9WZXJzaW9uUmVzZXJ2ZWQzXHJcblx0YnVmLndyaXRlVUludDgoMTUsIHBvcyk7IHBvcyArPSAxOyAvL05UTE1SZXZpc2lvbkN1cnJlbnRcclxuXHJcblxyXG5cdC8vIGxlbmd0aCBjaGVja3MgaXMgdG8gZml4IGlzc3VlICM0NiBhbmQgcG9zc2libHkgIzU3XHJcblx0aWYod29ya3N0YXRpb24ubGVuZ3RoICE9MCkgYnVmLndyaXRlKHdvcmtzdGF0aW9uLCBwb3MsIHdvcmtzdGF0aW9uLmxlbmd0aCwgJ2FzY2lpJyk7IHBvcyArPSB3b3Jrc3RhdGlvbi5sZW5ndGg7IC8vIHdvcmtzdGF0aW9uIHN0cmluZ1xyXG5cdGlmKGRvbWFpbi5sZW5ndGggIT0wKSAgICAgIGJ1Zi53cml0ZShkb21haW4gICAgICwgcG9zLCBkb21haW4ubGVuZ3RoICAgICAsICdhc2NpaScpOyBwb3MgKz0gZG9tYWluLmxlbmd0aDsgLy8gZG9tYWluIHN0cmluZ1xyXG5cclxuXHRyZXR1cm4gJ05UTE0gJyArIGJ1Zi50b1N0cmluZygnYmFzZTY0Jyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHBhcnNlVHlwZTJNZXNzYWdlKHJhd21zZyl7XHJcblx0dmFyIG1hdGNoID0gcmF3bXNnLm1hdGNoKC9OVExNICguKyk/Lyk7XHJcblx0aWYoIW1hdGNoIHx8ICFtYXRjaFsxXSkge1xyXG5cdFx0dGhyb3cgbmV3IEVycm9yKFwiQ291bGRuJ3QgZmluZCBOVExNIGluIHRoZSBtZXNzYWdlIHR5cGUyIGNvbWluZyBmcm9tIHRoZSBzZXJ2ZXJcIik7XHJcblx0fVxyXG5cclxuXHR2YXIgYnVmID0gQnVmZmVyLmZyb20obWF0Y2hbMV0sICdiYXNlNjQnKTtcclxuXHJcblx0dmFyIG1zZyA9IHt9O1xyXG5cclxuXHRtc2cuc2lnbmF0dXJlID0gYnVmLnNsaWNlKDAsIDgpO1xyXG5cdG1zZy50eXBlID0gYnVmLnJlYWRJbnQxNkxFKDgpO1xyXG5cclxuXHRpZihtc2cudHlwZSAhPSAyKSB7XHJcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJTZXJ2ZXIgZGlkbid0IHJldHVybiBhIHR5cGUgMiBtZXNzYWdlXCIpO1xyXG5cdH1cclxuXHJcblx0bXNnLnRhcmdldE5hbWVMZW4gPSBidWYucmVhZEludDE2TEUoMTIpO1xyXG5cdG1zZy50YXJnZXROYW1lTWF4TGVuID0gYnVmLnJlYWRJbnQxNkxFKDE0KTtcclxuXHRtc2cudGFyZ2V0TmFtZU9mZnNldCA9IGJ1Zi5yZWFkSW50MzJMRSgxNik7XHJcblx0bXNnLnRhcmdldE5hbWUgID0gYnVmLnNsaWNlKG1zZy50YXJnZXROYW1lT2Zmc2V0LCBtc2cudGFyZ2V0TmFtZU9mZnNldCArIG1zZy50YXJnZXROYW1lTWF4TGVuKTtcclxuXHJcbiAgICBtc2cubmVnb3RpYXRlRmxhZ3MgPSBidWYucmVhZEludDMyTEUoMjApO1xyXG4gICAgbXNnLnNlcnZlckNoYWxsZW5nZSA9IGJ1Zi5zbGljZSgyNCwgMzIpO1xyXG4gICAgbXNnLnJlc2VydmVkID0gYnVmLnNsaWNlKDMyLCA0MCk7XHJcblxyXG4gICAgaWYobXNnLm5lZ290aWF0ZUZsYWdzICYgZmxhZ3MuTlRMTV9OZWdvdGlhdGVUYXJnZXRJbmZvKXtcclxuICAgIFx0bXNnLnRhcmdldEluZm9MZW4gPSBidWYucmVhZEludDE2TEUoNDApO1xyXG4gICAgXHRtc2cudGFyZ2V0SW5mb01heExlbiA9IGJ1Zi5yZWFkSW50MTZMRSg0Mik7XHJcbiAgICBcdG1zZy50YXJnZXRJbmZvT2Zmc2V0ID0gYnVmLnJlYWRJbnQzMkxFKDQ0KTtcclxuICAgIFx0bXNnLnRhcmdldEluZm8gPSBidWYuc2xpY2UobXNnLnRhcmdldEluZm9PZmZzZXQsIG1zZy50YXJnZXRJbmZvT2Zmc2V0ICsgbXNnLnRhcmdldEluZm9MZW4pO1xyXG4gICAgfVxyXG5cdHJldHVybiBtc2c7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVR5cGUzTWVzc2FnZShtc2cyLCBvcHRpb25zKXtcclxuXHRpZighb3B0aW9ucy5kb21haW4pIG9wdGlvbnMuZG9tYWluID0gJyc7XHJcblx0aWYoIW9wdGlvbnMud29ya3N0YXRpb24pIG9wdGlvbnMud29ya3N0YXRpb24gPSAnJztcclxuXHRpZighb3B0aW9ucy51c2VybmFtZSkgb3B0aW9ucy51c2VybmFtZSA9ICcnO1xyXG5cdGlmKCFvcHRpb25zLnBhc3N3b3JkKSBvcHRpb25zLnBhc3N3b3JkID0gJyc7XHJcblxyXG5cdHZhciBub25jZSA9IG1zZzIuc2VydmVyQ2hhbGxlbmdlO1xyXG5cdHZhciB1c2VybmFtZSA9IG9wdGlvbnMudXNlcm5hbWU7XHJcblx0dmFyIHBhc3N3b3JkID0gb3B0aW9ucy5wYXNzd29yZDtcclxuXHR2YXIgbG1fcGFzc3dvcmQgPSBvcHRpb25zLmxtX3Bhc3N3b3JkO1xyXG5cdHZhciBudF9wYXNzd29yZCA9IG9wdGlvbnMubnRfcGFzc3dvcmQ7XHJcblx0dmFyIG5lZ290aWF0ZUZsYWdzID0gbXNnMi5uZWdvdGlhdGVGbGFncztcclxuXHJcblx0dmFyIGlzVW5pY29kZSA9IG5lZ290aWF0ZUZsYWdzICYgZmxhZ3MuTlRMTV9OZWdvdGlhdGVVbmljb2RlO1xyXG5cdHZhciBpc05lZ290aWF0ZUV4dGVuZGVkU2VjdXJpdHkgPSBuZWdvdGlhdGVGbGFncyAmIGZsYWdzLk5UTE1fTmVnb3RpYXRlRXh0ZW5kZWRTZWN1cml0eTtcclxuXHJcblx0dmFyIEJPRFlfTEVOR1RIID0gNzI7XHJcblxyXG5cdHZhciBkb21haW5OYW1lID0gZXNjYXBlKG9wdGlvbnMuZG9tYWluLnRvVXBwZXJDYXNlKCkpO1xyXG5cdHZhciB3b3Jrc3RhdGlvbiA9IGVzY2FwZShvcHRpb25zLndvcmtzdGF0aW9uLnRvVXBwZXJDYXNlKCkpO1xyXG5cclxuXHR2YXIgd29ya3N0YXRpb25CeXRlcywgZG9tYWluTmFtZUJ5dGVzLCB1c2VybmFtZUJ5dGVzLCBlbmNyeXB0ZWRSYW5kb21TZXNzaW9uS2V5Qnl0ZXM7XHJcblxyXG5cdHZhciBlbmNyeXB0ZWRSYW5kb21TZXNzaW9uS2V5ID0gXCJcIjtcclxuXHRpZihpc1VuaWNvZGUpe1xyXG5cdFx0d29ya3N0YXRpb25CeXRlcyA9IEJ1ZmZlci5mcm9tKHdvcmtzdGF0aW9uLCAndXRmMTZsZScpO1xyXG5cdFx0ZG9tYWluTmFtZUJ5dGVzID0gQnVmZmVyLmZyb20oZG9tYWluTmFtZSwgJ3V0ZjE2bGUnKTtcclxuXHRcdHVzZXJuYW1lQnl0ZXMgPSBCdWZmZXIuZnJvbSh1c2VybmFtZSwgJ3V0ZjE2bGUnKTtcclxuXHRcdGVuY3J5cHRlZFJhbmRvbVNlc3Npb25LZXlCeXRlcyA9IEJ1ZmZlci5mcm9tKGVuY3J5cHRlZFJhbmRvbVNlc3Npb25LZXksICd1dGYxNmxlJyk7XHJcblx0fWVsc2V7XHJcblx0XHR3b3Jrc3RhdGlvbkJ5dGVzID0gQnVmZmVyLmZyb20od29ya3N0YXRpb24sICdhc2NpaScpO1xyXG5cdFx0ZG9tYWluTmFtZUJ5dGVzID0gQnVmZmVyLmZyb20oZG9tYWluTmFtZSwgJ2FzY2lpJyk7XHJcblx0XHR1c2VybmFtZUJ5dGVzID0gQnVmZmVyLmZyb20odXNlcm5hbWUsICdhc2NpaScpO1xyXG5cdFx0ZW5jcnlwdGVkUmFuZG9tU2Vzc2lvbktleUJ5dGVzID0gQnVmZmVyLmZyb20oZW5jcnlwdGVkUmFuZG9tU2Vzc2lvbktleSwgJ2FzY2lpJyk7XHJcblx0fVxyXG5cclxuXHR2YXIgbG1DaGFsbGVuZ2VSZXNwb25zZSA9IGNhbGNfcmVzcCgobG1fcGFzc3dvcmQhPW51bGwpP2xtX3Bhc3N3b3JkOmNyZWF0ZV9MTV9oYXNoZWRfcGFzc3dvcmRfdjEocGFzc3dvcmQpLCBub25jZSk7XHJcblx0dmFyIG50Q2hhbGxlbmdlUmVzcG9uc2UgPSBjYWxjX3Jlc3AoKG50X3Bhc3N3b3JkIT1udWxsKT9udF9wYXNzd29yZDpjcmVhdGVfTlRfaGFzaGVkX3Bhc3N3b3JkX3YxKHBhc3N3b3JkKSwgbm9uY2UpO1xyXG5cclxuXHRpZihpc05lZ290aWF0ZUV4dGVuZGVkU2VjdXJpdHkpe1xyXG5cdFx0LypcclxuXHRcdCAqIE5UTE12MiBleHRlbmRlZCBzZWN1cml0eSBpcyBlbmFibGVkLiBXaGlsZSB0aGlzIHRlY2huaWNhbGx5IGNhbiBtZWFuIE5UTE12MiBleHRlbmRlZCBzZWN1cml0eSB3aXRoIE5UTE12MSBwcm90b2NvbCxcclxuXHRcdCAqIHNlcnZlcnMgdGhhdCBzdXBwb3J0IGV4dGVuZGVkIHNlY3VyaXR5IGxpa2VseSBhbHNvIHN1cHBvcnQgTlRMTXYyLCBzbyB1c2UgTlRMTXYyLlxyXG5cdFx0ICogVGhpcyBpcyBhbHNvIGhvdyBjdXJsIGltcGxlbWVudHMgTlRMTXYyIFwiZGV0ZWN0aW9uXCIuXHJcblx0XHQgKiBCeSB1c2luZyBOVExNdjIsIHRoaXMgc3VwcG9ydHMgY29tbXVuaWNhdGlvbiB3aXRoIHNlcnZlcnMgdGhhdCBmb3JiaWQgdGhlIHVzZSBvZiBOVExNdjEgKGUuZy4gdmlhIHdpbmRvd3MgcG9saWNpZXMpXHJcblx0XHQgKlxyXG5cdFx0ICogSG93ZXZlciwgdGhlIHRhcmdldCBpbmZvIGlzIG5lZWRlZCB0byBjb25zdHJ1Y3QgdGhlIE5UTE12MiByZXNwb25zZSBzbyBpZiBpdCBjYW4ndCBiZSBuZWdvdGlhdGVkLFxyXG5cdFx0ICogZmFsbCBiYWNrIHRvIE5UTE12MSB3aXRoIE5UTE12MiBleHRlbmRlZCBzZWN1cml0eS5cclxuXHRcdCAqL1xyXG5cdFx0dmFyIHB3aGFzaCA9IChudF9wYXNzd29yZCE9bnVsbCk/bnRfcGFzc3dvcmQ6Y3JlYXRlX05UX2hhc2hlZF9wYXNzd29yZF92MShwYXNzd29yZCk7XHJcblx0XHR2YXIgY2xpZW50Q2hhbGxlbmdlID0gXCJcIjtcclxuXHQgXHRmb3IodmFyIGk9MDsgaSA8IDg7IGkrKyl7XHJcblx0IFx0XHRjbGllbnRDaGFsbGVuZ2UgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSggTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKjI1NikgKTtcclxuXHQgICBcdH1cclxuXHQgICBcdHZhciBjbGllbnRDaGFsbGVuZ2VCeXRlcyA9IEJ1ZmZlci5mcm9tKGNsaWVudENoYWxsZW5nZSwgJ2FzY2lpJyk7XHJcblx0XHR2YXIgY2hhbGxlbmdlcyA9IG1zZzIudGFyZ2V0SW5mb1xyXG5cdFx0XHQ/IGNhbGNfbnRsbXYyX3Jlc3AocHdoYXNoLCB1c2VybmFtZSwgZG9tYWluTmFtZSwgbXNnMi50YXJnZXRJbmZvLCBub25jZSwgY2xpZW50Q2hhbGxlbmdlQnl0ZXMpXHJcblx0XHRcdDogbnRsbTJzcl9jYWxjX3Jlc3AocHdoYXNoLCBub25jZSwgY2xpZW50Q2hhbGxlbmdlQnl0ZXMpO1xyXG5cdCAgICBsbUNoYWxsZW5nZVJlc3BvbnNlID0gY2hhbGxlbmdlcy5sbUNoYWxsZW5nZVJlc3BvbnNlO1xyXG5cdCAgICBudENoYWxsZW5nZVJlc3BvbnNlID0gY2hhbGxlbmdlcy5udENoYWxsZW5nZVJlc3BvbnNlO1xyXG5cdH1cclxuXHJcblx0dmFyIHNpZ25hdHVyZSA9ICdOVExNU1NQXFwwJztcclxuXHJcblx0dmFyIHBvcyA9IDA7XHJcblx0dmFyIGJ1ZiA9IEJ1ZmZlci5hbGxvYyhCT0RZX0xFTkdUSCArIGRvbWFpbk5hbWVCeXRlcy5sZW5ndGggKyB1c2VybmFtZUJ5dGVzLmxlbmd0aCArIHdvcmtzdGF0aW9uQnl0ZXMubGVuZ3RoICsgbG1DaGFsbGVuZ2VSZXNwb25zZS5sZW5ndGggKyBudENoYWxsZW5nZVJlc3BvbnNlLmxlbmd0aCArIGVuY3J5cHRlZFJhbmRvbVNlc3Npb25LZXlCeXRlcy5sZW5ndGgpO1xyXG5cclxuXHRidWYud3JpdGUoc2lnbmF0dXJlLCBwb3MsIHNpZ25hdHVyZS5sZW5ndGgpOyBwb3MgKz0gc2lnbmF0dXJlLmxlbmd0aDtcclxuXHRidWYud3JpdGVVSW50MzJMRSgzLCBwb3MpOyBwb3MgKz0gNDsgICAgICAgICAgLy8gdHlwZSAxXHJcblxyXG5cdGJ1Zi53cml0ZVVJbnQxNkxFKGxtQ2hhbGxlbmdlUmVzcG9uc2UubGVuZ3RoLCBwb3MpOyBwb3MgKz0gMjsgLy8gTG1DaGFsbGVuZ2VSZXNwb25zZUxlblxyXG5cdGJ1Zi53cml0ZVVJbnQxNkxFKGxtQ2hhbGxlbmdlUmVzcG9uc2UubGVuZ3RoLCBwb3MpOyBwb3MgKz0gMjsgLy8gTG1DaGFsbGVuZ2VSZXNwb25zZU1heExlblxyXG5cdGJ1Zi53cml0ZVVJbnQzMkxFKEJPRFlfTEVOR1RIICsgZG9tYWluTmFtZUJ5dGVzLmxlbmd0aCArIHVzZXJuYW1lQnl0ZXMubGVuZ3RoICsgd29ya3N0YXRpb25CeXRlcy5sZW5ndGgsIHBvcyk7IHBvcyArPSA0OyAvLyBMbUNoYWxsZW5nZVJlc3BvbnNlT2Zmc2V0XHJcblxyXG5cdGJ1Zi53cml0ZVVJbnQxNkxFKG50Q2hhbGxlbmdlUmVzcG9uc2UubGVuZ3RoLCBwb3MpOyBwb3MgKz0gMjsgLy8gTnRDaGFsbGVuZ2VSZXNwb25zZUxlblxyXG5cdGJ1Zi53cml0ZVVJbnQxNkxFKG50Q2hhbGxlbmdlUmVzcG9uc2UubGVuZ3RoLCBwb3MpOyBwb3MgKz0gMjsgLy8gTnRDaGFsbGVuZ2VSZXNwb25zZU1heExlblxyXG5cdGJ1Zi53cml0ZVVJbnQzMkxFKEJPRFlfTEVOR1RIICsgZG9tYWluTmFtZUJ5dGVzLmxlbmd0aCArIHVzZXJuYW1lQnl0ZXMubGVuZ3RoICsgd29ya3N0YXRpb25CeXRlcy5sZW5ndGggKyBsbUNoYWxsZW5nZVJlc3BvbnNlLmxlbmd0aCwgcG9zKTsgcG9zICs9IDQ7IC8vIE50Q2hhbGxlbmdlUmVzcG9uc2VPZmZzZXRcclxuXHJcblx0YnVmLndyaXRlVUludDE2TEUoZG9tYWluTmFtZUJ5dGVzLmxlbmd0aCwgcG9zKTsgcG9zICs9IDI7IC8vIERvbWFpbk5hbWVMZW5cclxuXHRidWYud3JpdGVVSW50MTZMRShkb21haW5OYW1lQnl0ZXMubGVuZ3RoLCBwb3MpOyBwb3MgKz0gMjsgLy8gRG9tYWluTmFtZU1heExlblxyXG5cdGJ1Zi53cml0ZVVJbnQzMkxFKEJPRFlfTEVOR1RILCBwb3MpOyBwb3MgKz0gNDsgXHRcdFx0ICAvLyBEb21haW5OYW1lT2Zmc2V0XHJcblxyXG5cdGJ1Zi53cml0ZVVJbnQxNkxFKHVzZXJuYW1lQnl0ZXMubGVuZ3RoLCBwb3MpOyBwb3MgKz0gMjsgLy8gVXNlck5hbWVMZW5cclxuXHRidWYud3JpdGVVSW50MTZMRSh1c2VybmFtZUJ5dGVzLmxlbmd0aCwgcG9zKTsgcG9zICs9IDI7IC8vIFVzZXJOYW1lTWF4TGVuXHJcblx0YnVmLndyaXRlVUludDMyTEUoQk9EWV9MRU5HVEggKyBkb21haW5OYW1lQnl0ZXMubGVuZ3RoLCBwb3MpOyBwb3MgKz0gNDsgLy8gVXNlck5hbWVPZmZzZXRcclxuXHJcblx0YnVmLndyaXRlVUludDE2TEUod29ya3N0YXRpb25CeXRlcy5sZW5ndGgsIHBvcyk7IHBvcyArPSAyOyAvLyBXb3Jrc3RhdGlvbkxlblxyXG5cdGJ1Zi53cml0ZVVJbnQxNkxFKHdvcmtzdGF0aW9uQnl0ZXMubGVuZ3RoLCBwb3MpOyBwb3MgKz0gMjsgLy8gV29ya3N0YXRpb25NYXhMZW5cclxuXHRidWYud3JpdGVVSW50MzJMRShCT0RZX0xFTkdUSCArIGRvbWFpbk5hbWVCeXRlcy5sZW5ndGggKyB1c2VybmFtZUJ5dGVzLmxlbmd0aCwgcG9zKTsgcG9zICs9IDQ7IC8vIFdvcmtzdGF0aW9uT2Zmc2V0XHJcblxyXG5cdGJ1Zi53cml0ZVVJbnQxNkxFKGVuY3J5cHRlZFJhbmRvbVNlc3Npb25LZXlCeXRlcy5sZW5ndGgsIHBvcyk7IHBvcyArPSAyOyAvLyBFbmNyeXB0ZWRSYW5kb21TZXNzaW9uS2V5TGVuXHJcblx0YnVmLndyaXRlVUludDE2TEUoZW5jcnlwdGVkUmFuZG9tU2Vzc2lvbktleUJ5dGVzLmxlbmd0aCwgcG9zKTsgcG9zICs9IDI7IC8vIEVuY3J5cHRlZFJhbmRvbVNlc3Npb25LZXlNYXhMZW5cclxuXHRidWYud3JpdGVVSW50MzJMRShCT0RZX0xFTkdUSCArIGRvbWFpbk5hbWVCeXRlcy5sZW5ndGggKyB1c2VybmFtZUJ5dGVzLmxlbmd0aCArIHdvcmtzdGF0aW9uQnl0ZXMubGVuZ3RoICsgbG1DaGFsbGVuZ2VSZXNwb25zZS5sZW5ndGggKyBudENoYWxsZW5nZVJlc3BvbnNlLmxlbmd0aCwgcG9zKTsgcG9zICs9IDQ7IC8vIEVuY3J5cHRlZFJhbmRvbVNlc3Npb25LZXlPZmZzZXRcclxuXHJcblx0Ly8gRml4ICM5OFxyXG5cdHZhciBmbGFnc1RvV3JpdGUgPSBpc1VuaWNvZGVcclxuXHQgICAgPyB0eXBlZmxhZ3MuTlRMTV9UWVBFMl9GTEFHU1xyXG5cdCAgICA6IHR5cGVmbGFncy5OVExNX1RZUEUyX0ZMQUdTIC0gZmxhZ3MuTlRMTV9OZWdvdGlhdGVVbmljb2RlO1xyXG5cdGJ1Zi53cml0ZVVJbnQzMkxFKGZsYWdzVG9Xcml0ZSAsIHBvcyk7IHBvcyArPSA0OyAvLyBOZWdvdGlhdGVGbGFnc1xyXG5cclxuXHRidWYud3JpdGVVSW50OCg1LCBwb3MpOyBwb3MrKzsgLy8gUHJvZHVjdE1ham9yVmVyc2lvblxyXG5cdGJ1Zi53cml0ZVVJbnQ4KDEsIHBvcyk7IHBvcysrOyAvLyBQcm9kdWN0TWlub3JWZXJzaW9uXHJcblx0YnVmLndyaXRlVUludDE2TEUoMjYwMCwgcG9zKTsgcG9zICs9IDI7IC8vIFByb2R1Y3RCdWlsZFxyXG5cdGJ1Zi53cml0ZVVJbnQ4KDAsIHBvcyk7IHBvcysrOyAvLyBWZXJzaW9uUmVzZXJ2ZWQxXHJcblx0YnVmLndyaXRlVUludDgoMCwgcG9zKTsgcG9zKys7IC8vIFZlcnNpb25SZXNlcnZlZDJcclxuXHRidWYud3JpdGVVSW50OCgwLCBwb3MpOyBwb3MrKzsgLy8gVmVyc2lvblJlc2VydmVkM1xyXG5cdGJ1Zi53cml0ZVVJbnQ4KDE1LCBwb3MpOyBwb3MrKzsgLy8gTlRMTVJldmlzaW9uQ3VycmVudFxyXG5cclxuXHRkb21haW5OYW1lQnl0ZXMuY29weShidWYsIHBvcyk7IHBvcyArPSBkb21haW5OYW1lQnl0ZXMubGVuZ3RoO1xyXG5cdHVzZXJuYW1lQnl0ZXMuY29weShidWYsIHBvcyk7IHBvcyArPSB1c2VybmFtZUJ5dGVzLmxlbmd0aDtcclxuXHR3b3Jrc3RhdGlvbkJ5dGVzLmNvcHkoYnVmLCBwb3MpOyBwb3MgKz0gd29ya3N0YXRpb25CeXRlcy5sZW5ndGg7XHJcblx0bG1DaGFsbGVuZ2VSZXNwb25zZS5jb3B5KGJ1ZiwgcG9zKTsgcG9zICs9IGxtQ2hhbGxlbmdlUmVzcG9uc2UubGVuZ3RoO1xyXG5cdG50Q2hhbGxlbmdlUmVzcG9uc2UuY29weShidWYsIHBvcyk7IHBvcyArPSBudENoYWxsZW5nZVJlc3BvbnNlLmxlbmd0aDtcclxuXHRlbmNyeXB0ZWRSYW5kb21TZXNzaW9uS2V5Qnl0ZXMuY29weShidWYsIHBvcyk7IHBvcyArPSBlbmNyeXB0ZWRSYW5kb21TZXNzaW9uS2V5Qnl0ZXMubGVuZ3RoO1xyXG5cclxuXHRyZXR1cm4gJ05UTE0gJyArIGJ1Zi50b1N0cmluZygnYmFzZTY0Jyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZV9MTV9oYXNoZWRfcGFzc3dvcmRfdjEocGFzc3dvcmQpe1xyXG5cdC8vIGZpeCB0aGUgcGFzc3dvcmQgbGVuZ3RoIHRvIDE0IGJ5dGVzXHJcblx0cGFzc3dvcmQgPSBwYXNzd29yZC50b1VwcGVyQ2FzZSgpO1xyXG5cdHZhciBwYXNzd29yZEJ5dGVzID0gQnVmZmVyLmZyb20ocGFzc3dvcmQsICdhc2NpaScpO1xyXG5cclxuXHR2YXIgcGFzc3dvcmRCeXRlc1BhZGRlZCA9IEJ1ZmZlci5hbGxvYygxNCk7XHJcblx0cGFzc3dvcmRCeXRlc1BhZGRlZC5maWxsKFwiXFwwXCIpO1xyXG5cdHZhciBzb3VyY2VFbmQgPSAxNDtcclxuXHRpZihwYXNzd29yZEJ5dGVzLmxlbmd0aCA8IDE0KSBzb3VyY2VFbmQgPSBwYXNzd29yZEJ5dGVzLmxlbmd0aDtcclxuXHRwYXNzd29yZEJ5dGVzLmNvcHkocGFzc3dvcmRCeXRlc1BhZGRlZCwgMCwgMCwgc291cmNlRW5kKTtcclxuXHJcblx0Ly8gc3BsaXQgaW50byAyIHBhcnRzIG9mIDcgYnl0ZXM6XHJcblx0dmFyIGZpcnN0UGFydCA9IHBhc3N3b3JkQnl0ZXNQYWRkZWQuc2xpY2UoMCw3KTtcclxuXHR2YXIgc2Vjb25kUGFydCA9IHBhc3N3b3JkQnl0ZXNQYWRkZWQuc2xpY2UoNyk7XHJcblxyXG5cdGZ1bmN0aW9uIGVuY3J5cHQoYnVmKXtcclxuXHRcdHZhciBrZXkgPSBpbnNlcnRaZXJvc0V2ZXJ5N0JpdHMoYnVmKTtcclxuXHRcdHZhciBkZXMgPSBkZXNqcy5ERVMuY3JlYXRlKHt0eXBlOiAnZW5jcnlwdCcsIGtleToga2V5fSk7XHJcblx0XHR2YXIgbWFnaWNLZXkgPSBCdWZmZXIuZnJvbSgnS0dTIUAjJCUnLCAnYXNjaWknKTsgLy8gcGFnZSA1NyBpbiBbTVMtTkxNUF1cclxuXHRcdHZhciBlbmNyeXB0ZWQgPSBkZXMudXBkYXRlKG1hZ2ljS2V5KTtcclxuXHRcdHJldHVybiBCdWZmZXIuZnJvbShlbmNyeXB0ZWQpO1xyXG5cdH1cclxuXHJcblx0dmFyIGZpcnN0UGFydEVuY3J5cHRlZCA9IGVuY3J5cHQoZmlyc3RQYXJ0KTtcclxuXHR2YXIgc2Vjb25kUGFydEVuY3J5cHRlZCA9IGVuY3J5cHQoc2Vjb25kUGFydCk7XHJcblxyXG5cdHJldHVybiBCdWZmZXIuY29uY2F0KFtmaXJzdFBhcnRFbmNyeXB0ZWQsIHNlY29uZFBhcnRFbmNyeXB0ZWRdKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaW5zZXJ0WmVyb3NFdmVyeTdCaXRzKGJ1Zil7XHJcblx0dmFyIGJpbmFyeUFycmF5ID0gYnl0ZXMyYmluYXJ5QXJyYXkoYnVmKTtcclxuXHR2YXIgbmV3QmluYXJ5QXJyYXkgPSBbXTtcclxuXHRmb3IodmFyIGk9MDsgaTxiaW5hcnlBcnJheS5sZW5ndGg7IGkrKyl7XHJcblx0XHRuZXdCaW5hcnlBcnJheS5wdXNoKGJpbmFyeUFycmF5W2ldKTtcclxuXHJcblx0XHRpZigoaSsxKSU3ID09PSAwKXtcclxuXHRcdFx0bmV3QmluYXJ5QXJyYXkucHVzaCgwKTtcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIGJpbmFyeUFycmF5MmJ5dGVzKG5ld0JpbmFyeUFycmF5KTtcclxufVxyXG5cclxuZnVuY3Rpb24gYnl0ZXMyYmluYXJ5QXJyYXkoYnVmKXtcclxuXHR2YXIgaGV4MmJpbmFyeSA9IHtcclxuXHRcdDA6IFswLDAsMCwwXSxcclxuXHRcdDE6IFswLDAsMCwxXSxcclxuXHRcdDI6IFswLDAsMSwwXSxcclxuXHRcdDM6IFswLDAsMSwxXSxcclxuXHRcdDQ6IFswLDEsMCwwXSxcclxuXHRcdDU6IFswLDEsMCwxXSxcclxuXHRcdDY6IFswLDEsMSwwXSxcclxuXHRcdDc6IFswLDEsMSwxXSxcclxuXHRcdDg6IFsxLDAsMCwwXSxcclxuXHRcdDk6IFsxLDAsMCwxXSxcclxuXHRcdEE6IFsxLDAsMSwwXSxcclxuXHRcdEI6IFsxLDAsMSwxXSxcclxuXHRcdEM6IFsxLDEsMCwwXSxcclxuXHRcdEQ6IFsxLDEsMCwxXSxcclxuXHRcdEU6IFsxLDEsMSwwXSxcclxuXHRcdEY6IFsxLDEsMSwxXVxyXG5cdH07XHJcblxyXG5cdHZhciBoZXhTdHJpbmcgPSBidWYudG9TdHJpbmcoJ2hleCcpLnRvVXBwZXJDYXNlKCk7XHJcblx0dmFyIGFycmF5ID0gW107XHJcblx0Zm9yKHZhciBpPTA7IGk8aGV4U3RyaW5nLmxlbmd0aDsgaSsrKXtcclxuICAgXHRcdHZhciBoZXhjaGFyID0gaGV4U3RyaW5nLmNoYXJBdChpKTtcclxuICAgXHRcdGFycmF5ID0gYXJyYXkuY29uY2F0KGhleDJiaW5hcnlbaGV4Y2hhcl0pO1xyXG4gICBcdH1cclxuICAgXHRyZXR1cm4gYXJyYXk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGJpbmFyeUFycmF5MmJ5dGVzKGFycmF5KXtcclxuXHR2YXIgYmluYXJ5MmhleCA9IHtcclxuXHRcdCcwMDAwJzogMCxcclxuXHRcdCcwMDAxJzogMSxcclxuXHRcdCcwMDEwJzogMixcclxuXHRcdCcwMDExJzogMyxcclxuXHRcdCcwMTAwJzogNCxcclxuXHRcdCcwMTAxJzogNSxcclxuXHRcdCcwMTEwJzogNixcclxuXHRcdCcwMTExJzogNyxcclxuXHRcdCcxMDAwJzogOCxcclxuXHRcdCcxMDAxJzogOSxcclxuXHRcdCcxMDEwJzogJ0EnLFxyXG5cdFx0JzEwMTEnOiAnQicsXHJcblx0XHQnMTEwMCc6ICdDJyxcclxuXHRcdCcxMTAxJzogJ0QnLFxyXG5cdFx0JzExMTAnOiAnRScsXHJcblx0XHQnMTExMSc6ICdGJ1xyXG5cdH07XHJcblxyXG4gXHR2YXIgYnVmQXJyYXkgPSBbXTtcclxuXHJcblx0Zm9yKHZhciBpPTA7IGk8YXJyYXkubGVuZ3RoOyBpICs9OCApe1xyXG5cdFx0aWYoKGkrNykgPiBhcnJheS5sZW5ndGgpXHJcblx0XHRcdGJyZWFrO1xyXG5cclxuXHRcdHZhciBiaW5TdHJpbmcxID0gJycgKyBhcnJheVtpXSArICcnICsgYXJyYXlbaSsxXSArICcnICsgYXJyYXlbaSsyXSArICcnICsgYXJyYXlbaSszXTtcclxuXHRcdHZhciBiaW5TdHJpbmcyID0gJycgKyBhcnJheVtpKzRdICsgJycgKyBhcnJheVtpKzVdICsgJycgKyBhcnJheVtpKzZdICsgJycgKyBhcnJheVtpKzddO1xyXG4gICBcdFx0dmFyIGhleGNoYXIxID0gYmluYXJ5MmhleFtiaW5TdHJpbmcxXTtcclxuICAgXHRcdHZhciBoZXhjaGFyMiA9IGJpbmFyeTJoZXhbYmluU3RyaW5nMl07XHJcblxyXG4gICBcdFx0dmFyIGJ1ZiA9IEJ1ZmZlci5mcm9tKGhleGNoYXIxICsgJycgKyBoZXhjaGFyMiwgJ2hleCcpO1xyXG4gICBcdFx0YnVmQXJyYXkucHVzaChidWYpO1xyXG4gICBcdH1cclxuXHJcbiAgIFx0cmV0dXJuIEJ1ZmZlci5jb25jYXQoYnVmQXJyYXkpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVfTlRfaGFzaGVkX3Bhc3N3b3JkX3YxKHBhc3N3b3JkKXtcclxuXHR2YXIgYnVmID0gQnVmZmVyLmZyb20ocGFzc3dvcmQsICd1dGYxNmxlJyk7XHJcblx0dmFyIG1kNCA9IGpzbWQ0LmNyZWF0ZSgpO1xyXG5cdG1kNC51cGRhdGUoYnVmKTtcclxuXHRyZXR1cm4gQnVmZmVyLmZyb20obWQ0LmRpZ2VzdCgpKTtcclxufVxyXG5cclxuZnVuY3Rpb24gY2FsY19yZXNwKHBhc3N3b3JkX2hhc2gsIHNlcnZlcl9jaGFsbGVuZ2Upe1xyXG4gICAgLy8gcGFkZGluZyB3aXRoIHplcm9zIHRvIG1ha2UgdGhlIGhhc2ggMjEgYnl0ZXMgbG9uZ1xyXG4gICAgdmFyIHBhc3NIYXNoUGFkZGVkID0gQnVmZmVyLmFsbG9jKDIxKTtcclxuICAgIHBhc3NIYXNoUGFkZGVkLmZpbGwoXCJcXDBcIik7XHJcbiAgICBwYXNzd29yZF9oYXNoLmNvcHkocGFzc0hhc2hQYWRkZWQsIDAsIDAsIHBhc3N3b3JkX2hhc2gubGVuZ3RoKTtcclxuXHJcbiAgICB2YXIgcmVzQXJyYXkgPSBbXTtcclxuXHJcblx0dmFyIGRlcyA9IGRlc2pzLkRFUy5jcmVhdGUoe3R5cGU6ICdlbmNyeXB0Jywga2V5OiBpbnNlcnRaZXJvc0V2ZXJ5N0JpdHMocGFzc0hhc2hQYWRkZWQuc2xpY2UoMCw3KSl9KTtcclxuXHRyZXNBcnJheS5wdXNoKCBCdWZmZXIuZnJvbShkZXMudXBkYXRlKHNlcnZlcl9jaGFsbGVuZ2Uuc2xpY2UoMCw4KSkpICk7XHJcblxyXG5cdGRlcyA9IGRlc2pzLkRFUy5jcmVhdGUoe3R5cGU6ICdlbmNyeXB0Jywga2V5OiBpbnNlcnRaZXJvc0V2ZXJ5N0JpdHMocGFzc0hhc2hQYWRkZWQuc2xpY2UoNywxNCkpfSk7XHJcblx0cmVzQXJyYXkucHVzaCggQnVmZmVyLmZyb20oZGVzLnVwZGF0ZShzZXJ2ZXJfY2hhbGxlbmdlLnNsaWNlKDAsOCkpKSApO1xyXG5cclxuXHRkZXMgPSBkZXNqcy5ERVMuY3JlYXRlKHt0eXBlOiAnZW5jcnlwdCcsIGtleTogaW5zZXJ0WmVyb3NFdmVyeTdCaXRzKHBhc3NIYXNoUGFkZGVkLnNsaWNlKDE0LDIxKSl9KTtcclxuXHRyZXNBcnJheS5wdXNoKCBCdWZmZXIuZnJvbShkZXMudXBkYXRlKHNlcnZlcl9jaGFsbGVuZ2Uuc2xpY2UoMCw4KSkpICk7XHJcblxyXG4gICBcdHJldHVybiBCdWZmZXIuY29uY2F0KHJlc0FycmF5KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaG1hY19tZDUoa2V5LCBkYXRhKXtcclxuXHR2YXIgaG1hYyA9IGNyeXB0by5jcmVhdGVIbWFjKCdtZDUnLCBrZXkpO1xyXG5cdGhtYWMudXBkYXRlKGRhdGEpO1xyXG5cdHJldHVybiBobWFjLmRpZ2VzdCgpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBudGxtMnNyX2NhbGNfcmVzcChyZXNwb25zZUtleU5ULCBzZXJ2ZXJDaGFsbGVuZ2UsIGNsaWVudENoYWxsZW5nZSl7XHJcblx0Ly8gcGFkZGluZyB3aXRoIHplcm9zIHRvIG1ha2UgdGhlIGhhc2ggMTYgYnl0ZXMgbG9uZ2VyXHJcbiAgICB2YXIgbG1DaGFsbGVuZ2VSZXNwb25zZSA9IEJ1ZmZlci5hbGxvYyhjbGllbnRDaGFsbGVuZ2UubGVuZ3RoICsgMTYpO1xyXG4gICAgbG1DaGFsbGVuZ2VSZXNwb25zZS5maWxsKFwiXFwwXCIpO1xyXG4gICAgY2xpZW50Q2hhbGxlbmdlLmNvcHkobG1DaGFsbGVuZ2VSZXNwb25zZSwgMCwgMCwgY2xpZW50Q2hhbGxlbmdlLmxlbmd0aCk7XHJcblxyXG4gICAgdmFyIGJ1ZiA9IEJ1ZmZlci5jb25jYXQoW3NlcnZlckNoYWxsZW5nZSwgY2xpZW50Q2hhbGxlbmdlXSk7XHJcbiAgICB2YXIgbWQ1ID0gY3J5cHRvLmNyZWF0ZUhhc2goJ21kNScpO1xyXG4gICAgbWQ1LnVwZGF0ZShidWYpO1xyXG4gICAgdmFyIHNlc3MgPSBtZDUuZGlnZXN0KCk7XHJcbiAgICB2YXIgbnRDaGFsbGVuZ2VSZXNwb25zZSA9IGNhbGNfcmVzcChyZXNwb25zZUtleU5ULCBzZXNzLnNsaWNlKDAsOCkpO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICBcdGxtQ2hhbGxlbmdlUmVzcG9uc2U6IGxtQ2hhbGxlbmdlUmVzcG9uc2UsXHJcbiAgICBcdG50Q2hhbGxlbmdlUmVzcG9uc2U6IG50Q2hhbGxlbmdlUmVzcG9uc2VcclxuICAgIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNhbGNfbnRsbXYyX3Jlc3AocHdoYXNoLCB1c2VybmFtZSwgZG9tYWluLCB0YXJnZXRJbmZvLCBzZXJ2ZXJDaGFsbGVuZ2UsIGNsaWVudENoYWxsZW5nZSl7XHJcblx0dmFyIHJlc3BvbnNlS2V5TlRMTSA9IE5UT1dGdjIocHdoYXNoLCB1c2VybmFtZSwgZG9tYWluKTtcclxuXHJcblx0dmFyIGxtVjJDaGFsbGVuZ2VSZXNwb25zZSA9IEJ1ZmZlci5jb25jYXQoW1xyXG5cdFx0aG1hY19tZDUocmVzcG9uc2VLZXlOVExNLCBCdWZmZXIuY29uY2F0KFtzZXJ2ZXJDaGFsbGVuZ2UsIGNsaWVudENoYWxsZW5nZV0pKSxcclxuXHRcdGNsaWVudENoYWxsZW5nZVxyXG5cdF0pO1xyXG5cclxuXHQvLyAxMTY0NDQ3MzYwMDAwMCA9IGRpZmYgYmV0d2VlbiAxOTcwIGFuZCAxNjAxXHJcblx0dmFyIG5vdyA9IERhdGUubm93KCk7XHJcblx0dmFyIHRpbWVzdGFtcCA9ICgoQmlnSW50KG5vdykgKyBCaWdJbnQoMTE2NDQ0NzM2MDAwMDApKSAqIEJpZ0ludCgxMDAwMCkpOyAgLy8gd2UgbmVlZCBCaWdJbnQgdG8gYmUgYWJsZSB0byB3cml0ZSBpdCB0byBhIGJ1ZmZlclxyXG5cdHZhciB0aW1lc3RhbXBCdWZmZXIgPSBCdWZmZXIuYWxsb2MoOCk7XHJcblx0dGltZXN0YW1wQnVmZmVyLndyaXRlQmlnVUludDY0TEUodGltZXN0YW1wKTtcclxuXHJcblx0dmFyIHplcm8zMkJpdCA9IEJ1ZmZlci5hbGxvYyg0LCAwKVxyXG5cdHZhciB0ZW1wID0gQnVmZmVyLmNvbmNhdChbXHJcblx0XHQvLyBWZXJzaW9uXHJcblx0XHRCdWZmZXIuZnJvbShbMHgwMSwgMHgwMSwgMHgwMCwgMHgwMF0pLFxyXG5cdFx0emVybzMyQml0LFxyXG5cdFx0dGltZXN0YW1wQnVmZmVyLFxyXG5cdFx0Y2xpZW50Q2hhbGxlbmdlLFxyXG5cdFx0emVybzMyQml0LFxyXG5cdFx0dGFyZ2V0SW5mbyxcclxuXHRcdHplcm8zMkJpdFxyXG5cdF0pO1xyXG5cdHZhciBwcm9vZlN0cmluZyA9IGhtYWNfbWQ1KHJlc3BvbnNlS2V5TlRMTSwgQnVmZmVyLmNvbmNhdChbc2VydmVyQ2hhbGxlbmdlLCB0ZW1wXSkpO1xyXG5cdHZhciBudFYyQ2hhbGxlbmdlUmVzcG9uc2UgPSBCdWZmZXIuY29uY2F0KFtwcm9vZlN0cmluZywgdGVtcF0pO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICBcdGxtQ2hhbGxlbmdlUmVzcG9uc2U6IGxtVjJDaGFsbGVuZ2VSZXNwb25zZSxcclxuICAgIFx0bnRDaGFsbGVuZ2VSZXNwb25zZTogbnRWMkNoYWxsZW5nZVJlc3BvbnNlXHJcbiAgICB9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBOVE9XRnYyKHB3aGFzaCwgdXNlciwgZG9tYWluKXtcclxuXHRyZXR1cm4gaG1hY19tZDUocHdoYXNoLCBCdWZmZXIuZnJvbSh1c2VyLnRvVXBwZXJDYXNlKCkgKyBkb21haW4sICd1dGYxNmxlJykpO1xyXG59XHJcblxyXG5leHBvcnRzLmNyZWF0ZVR5cGUxTWVzc2FnZSA9IGNyZWF0ZVR5cGUxTWVzc2FnZTtcclxuZXhwb3J0cy5wYXJzZVR5cGUyTWVzc2FnZSA9IHBhcnNlVHlwZTJNZXNzYWdlO1xyXG5leHBvcnRzLmNyZWF0ZVR5cGUzTWVzc2FnZSA9IGNyZWF0ZVR5cGUzTWVzc2FnZTtcclxuZXhwb3J0cy5jcmVhdGVfTlRfaGFzaGVkX3Bhc3N3b3JkID0gY3JlYXRlX05UX2hhc2hlZF9wYXNzd29yZF92MTtcclxuZXhwb3J0cy5jcmVhdGVfTE1faGFzaGVkX3Bhc3N3b3JkID0gY3JlYXRlX0xNX2hhc2hlZF9wYXNzd29yZF92MTtcclxuLyogZXNsaW50LWVuYWJsZSAqL1xyXG4iXX0=
|