jderobot-ide-interface 0.3.17 → 0.3.18

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.
@@ -0,0 +1,626 @@
1
+ "use strict";
2
+ (this["webpackChunkjderobot_ide_interface"] = this["webpackChunkjderobot_ide_interface"] || []).push([["vendors-node_modules_vscode_diff_dist_index_js"],{
3
+
4
+ /***/ "./node_modules/@vscode/diff/dist/index.js"
5
+ /*!*************************************************!*\
6
+ !*** ./node_modules/@vscode/diff/dist/index.js ***!
7
+ \*************************************************/
8
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
9
+
10
+ __webpack_require__.r(__webpack_exports__);
11
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
12
+ /* harmony export */ AnnotatedStringEdit: () => (/* binding */ AnnotatedStringEdit),
13
+ /* harmony export */ AnnotatedStringReplacement: () => (/* binding */ AnnotatedStringReplacement),
14
+ /* harmony export */ DiffAnnotation: () => (/* binding */ DiffAnnotation),
15
+ /* harmony export */ DiffResult: () => (/* binding */ DiffResult),
16
+ /* harmony export */ Move: () => (/* binding */ Move),
17
+ /* harmony export */ OffsetRange: () => (/* reexport safe */ _wire_js__WEBPACK_IMPORTED_MODULE_0__.O),
18
+ /* harmony export */ OffsetRangeMapping: () => (/* binding */ OffsetRangeMapping),
19
+ /* harmony export */ StringEdit: () => (/* binding */ StringEdit),
20
+ /* harmony export */ StringReplacement: () => (/* binding */ StringReplacement),
21
+ /* harmony export */ _DefaultLinesDiffComputer: () => (/* reexport safe */ _wire_js__WEBPACK_IMPORTED_MODULE_0__.D),
22
+ /* harmony export */ _DetailedLineRangeMapping: () => (/* reexport safe */ _wire_js__WEBPACK_IMPORTED_MODULE_0__.b),
23
+ /* harmony export */ _LineRange: () => (/* reexport safe */ _wire_js__WEBPACK_IMPORTED_MODULE_0__.L),
24
+ /* harmony export */ _LineRangeMapping: () => (/* reexport safe */ _wire_js__WEBPACK_IMPORTED_MODULE_0__.d),
25
+ /* harmony export */ _LinesDiff: () => (/* reexport safe */ _wire_js__WEBPACK_IMPORTED_MODULE_0__.c),
26
+ /* harmony export */ _RangeMapping: () => (/* reexport safe */ _wire_js__WEBPACK_IMPORTED_MODULE_0__.R),
27
+ /* harmony export */ _getWasm: () => (/* reexport safe */ _wire_js__WEBPACK_IMPORTED_MODULE_0__.g),
28
+ /* harmony export */ _initWasm: () => (/* reexport safe */ _wire_js__WEBPACK_IMPORTED_MODULE_0__.i),
29
+ /* harmony export */ createDiffComputer: () => (/* binding */ createDiffComputer),
30
+ /* harmony export */ createWorkerDiffComputer: () => (/* binding */ createWorkerDiffComputer)
31
+ /* harmony export */ });
32
+ /* harmony import */ var _wire_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./wire.js */ "./node_modules/@vscode/diff/dist/wire.js");
33
+ /*---------------------------------------------------------------------------------------------
34
+ * Copyright (c) Microsoft Corporation. All rights reserved.
35
+ * Licensed under the MIT License. See License.txt in the project root for license information.
36
+ *--------------------------------------------------------------------------------------------*/
37
+
38
+
39
+
40
+ /**
41
+ * A pair of ranges, one in `original`, one in `modified`.
42
+ */
43
+ class OffsetRangeMapping {
44
+ original;
45
+ modified;
46
+ constructor(original, modified) {
47
+ this.original = original;
48
+ this.modified = modified;
49
+ }
50
+ toString() {
51
+ return `${this.original} <-> ${this.modified}`;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * A single atomic replacement: replace `range` in the input with `newText`.
57
+ */
58
+ class StringReplacement {
59
+ range;
60
+ newText;
61
+ constructor(range, newText) {
62
+ this.range = range;
63
+ this.newText = newText;
64
+ }
65
+ get isEmpty() {
66
+ return this.range.isEmpty && this.newText.length === 0;
67
+ }
68
+ toString() {
69
+ return `${this.range}->${JSON.stringify(this.newText)}`;
70
+ }
71
+ }
72
+ /**
73
+ * A set of replacements applied in parallel to one input string.
74
+ *
75
+ * Invariants:
76
+ * - replacements are sorted by `range.start`
77
+ * - replacements do not overlap (touching is allowed)
78
+ * - all ranges live in the same coordinate space (the input passed to `apply`)
79
+ */
80
+ class StringEdit {
81
+ replacements;
82
+ static empty = new StringEdit([]);
83
+ static single(replacement) {
84
+ return new StringEdit([replacement]);
85
+ }
86
+ /**
87
+ * Validates that replacements are sorted and non-overlapping.
88
+ */
89
+ static of(replacements) {
90
+ for (let i = 1; i < replacements.length; i++) {
91
+ const prev = replacements[i - 1];
92
+ const cur = replacements[i];
93
+ if (prev.range.endExclusive > cur.range.start) {
94
+ throw new Error(`StringEdit.of: replacements must be sorted and non-overlapping (` +
95
+ `${prev.range} vs ${cur.range})`);
96
+ }
97
+ }
98
+ return new StringEdit(replacements);
99
+ }
100
+ constructor(replacements) {
101
+ this.replacements = replacements;
102
+ }
103
+ get isEmpty() {
104
+ return this.replacements.length === 0;
105
+ }
106
+ apply(text) {
107
+ if (this.replacements.length === 0) {
108
+ return text;
109
+ }
110
+ const parts = [];
111
+ let cursor = 0;
112
+ for (const r of this.replacements) {
113
+ parts.push(text.substring(cursor, r.range.start));
114
+ parts.push(r.newText);
115
+ cursor = r.range.endExclusive;
116
+ }
117
+ parts.push(text.substring(cursor));
118
+ return parts.join('');
119
+ }
120
+ /**
121
+ * Returns an edit `E` such that `E.apply(this.apply(input)) === input`.
122
+ */
123
+ inverse(input) {
124
+ const out = [];
125
+ let delta = 0;
126
+ for (const r of this.replacements) {
127
+ const newStart = r.range.start + delta;
128
+ const newEnd = newStart + r.newText.length;
129
+ const oldText = input.substring(r.range.start, r.range.endExclusive);
130
+ out.push(new StringReplacement(new _wire_js__WEBPACK_IMPORTED_MODULE_0__.O(newStart, newEnd), oldText));
131
+ delta += r.newText.length - r.range.length;
132
+ }
133
+ return new StringEdit(out);
134
+ }
135
+ /**
136
+ * Joins touching replacements and drops no-ops.
137
+ */
138
+ normalize() {
139
+ const out = [];
140
+ for (const r of this.replacements) {
141
+ if (r.isEmpty) {
142
+ continue;
143
+ }
144
+ const prev = out[out.length - 1];
145
+ if (prev && prev.range.endExclusive === r.range.start) {
146
+ out[out.length - 1] = new StringReplacement(new _wire_js__WEBPACK_IMPORTED_MODULE_0__.O(prev.range.start, r.range.endExclusive), prev.newText + r.newText);
147
+ }
148
+ else {
149
+ out.push(r);
150
+ }
151
+ }
152
+ return new StringEdit(out);
153
+ }
154
+ toString() {
155
+ return `StringEdit[${this.replacements.map(r => r.toString()).join(', ')}]`;
156
+ }
157
+ }
158
+
159
+ /**
160
+ * An atomic replacement carrying user-defined metadata.
161
+ */
162
+ class AnnotatedStringReplacement {
163
+ range;
164
+ newText;
165
+ data;
166
+ constructor(range, newText, data) {
167
+ this.range = range;
168
+ this.newText = newText;
169
+ this.data = data;
170
+ }
171
+ get isEmpty() {
172
+ return this.range.isEmpty && this.newText.length === 0;
173
+ }
174
+ toString() {
175
+ return `${this.range}->${JSON.stringify(this.newText)}#${this.data}`;
176
+ }
177
+ }
178
+ /**
179
+ * A set of annotated replacements applied in parallel.
180
+ *
181
+ * Invariants: same as `StringEdit` (sorted by `range.start`, non-overlapping,
182
+ * shared coordinate space).
183
+ */
184
+ class AnnotatedStringEdit {
185
+ replacements;
186
+ static empty() {
187
+ return new AnnotatedStringEdit([]);
188
+ }
189
+ static single(replacement) {
190
+ return new AnnotatedStringEdit([replacement]);
191
+ }
192
+ static of(replacements) {
193
+ for (let i = 1; i < replacements.length; i++) {
194
+ const prev = replacements[i - 1];
195
+ const cur = replacements[i];
196
+ if (prev.range.endExclusive > cur.range.start) {
197
+ throw new Error(`AnnotatedStringEdit.of: replacements must be sorted and non-overlapping (` +
198
+ `${prev.range} vs ${cur.range})`);
199
+ }
200
+ }
201
+ return new AnnotatedStringEdit(replacements);
202
+ }
203
+ constructor(replacements) {
204
+ this.replacements = replacements;
205
+ }
206
+ get isEmpty() {
207
+ return this.replacements.length === 0;
208
+ }
209
+ apply(text) {
210
+ if (this.replacements.length === 0) {
211
+ return text;
212
+ }
213
+ const parts = [];
214
+ let cursor = 0;
215
+ for (const r of this.replacements) {
216
+ parts.push(text.substring(cursor, r.range.start));
217
+ parts.push(r.newText);
218
+ cursor = r.range.endExclusive;
219
+ }
220
+ parts.push(text.substring(cursor));
221
+ return parts.join('');
222
+ }
223
+ inverse(input, invertData) {
224
+ const out = [];
225
+ let delta = 0;
226
+ for (const r of this.replacements) {
227
+ const newStart = r.range.start + delta;
228
+ const newEnd = newStart + r.newText.length;
229
+ const oldText = input.substring(r.range.start, r.range.endExclusive);
230
+ out.push(new AnnotatedStringReplacement(new _wire_js__WEBPACK_IMPORTED_MODULE_0__.O(newStart, newEnd), oldText, invertData(r.data)));
231
+ delta += r.newText.length - r.range.length;
232
+ }
233
+ return new AnnotatedStringEdit(out);
234
+ }
235
+ /**
236
+ * Joins touching replacements when their annotations join. Drops no-ops.
237
+ */
238
+ normalize() {
239
+ const out = [];
240
+ for (const r of this.replacements) {
241
+ if (r.isEmpty) {
242
+ continue;
243
+ }
244
+ const prev = out[out.length - 1];
245
+ if (prev && prev.range.endExclusive === r.range.start) {
246
+ const joined = prev.data.join(r.data);
247
+ if (joined !== undefined) {
248
+ out[out.length - 1] = new AnnotatedStringReplacement(new _wire_js__WEBPACK_IMPORTED_MODULE_0__.O(prev.range.start, r.range.endExclusive), prev.newText + r.newText, joined);
249
+ continue;
250
+ }
251
+ }
252
+ out.push(r);
253
+ }
254
+ return new AnnotatedStringEdit(out);
255
+ }
256
+ mapData(f) {
257
+ return new AnnotatedStringEdit(this.replacements.map(r => new AnnotatedStringReplacement(r.range, r.newText, f(r.data))));
258
+ }
259
+ stripData() {
260
+ return StringEdit.of(this.replacements.map(r => new StringReplacement(r.range, r.newText)));
261
+ }
262
+ toString() {
263
+ return `AnnotatedStringEdit[${this.replacements.map(r => r.toString()).join(', ')}]`;
264
+ }
265
+ }
266
+ /**
267
+ * Diff result annotation.
268
+ *
269
+ * Carries flags describing the nature of the replacement. For now only
270
+ * `isFormattingChange` is exposed; more flags (e.g. move source/target,
271
+ * semantic category) can be added later.
272
+ */
273
+ class DiffAnnotation {
274
+ isFormattingChange;
275
+ static change = new DiffAnnotation(false);
276
+ static formatting = new DiffAnnotation(true);
277
+ constructor(
278
+ /** Whether the replacement is purely a formatting change (whitespace, indentation, etc.). */
279
+ isFormattingChange) {
280
+ this.isFormattingChange = isFormattingChange;
281
+ }
282
+ join(other) {
283
+ if (this.isFormattingChange !== other.isFormattingChange) {
284
+ return undefined;
285
+ }
286
+ return this;
287
+ }
288
+ toString() {
289
+ return this.isFormattingChange ? 'formatting' : 'change';
290
+ }
291
+ }
292
+
293
+ /**
294
+ * A block of text that was moved between two locations.
295
+ *
296
+ * `range` locates the block in `original` and in `modified` (offsets in the
297
+ * respective full texts). `innerEdit` describes the changes inside the moved
298
+ * block, with offsets local to the slice (i.e. `0` is the start of the slice).
299
+ */
300
+ class Move {
301
+ range;
302
+ innerEdit;
303
+ constructor(range, innerEdit) {
304
+ this.range = range;
305
+ this.innerEdit = innerEdit;
306
+ }
307
+ toString() {
308
+ return `Move ${this.range}` + (this.innerEdit.isEmpty ? '' : ` (${this.innerEdit})`);
309
+ }
310
+ }
311
+
312
+ /**
313
+ * Output of a diff computation.
314
+ */
315
+ class DiffResult {
316
+ edits;
317
+ moves;
318
+ hitTimeout;
319
+ constructor(
320
+ /**
321
+ * Parallel set of replacements transforming `original` into `modified`,
322
+ * excluding any replacements that are part of a `Move`.
323
+ *
324
+ * When no moves are computed: `edits.apply(original) === modified`.
325
+ */
326
+ edits,
327
+ /**
328
+ * Detected text moves. Empty unless `DiffOptions.computeMoves` is set.
329
+ */
330
+ moves,
331
+ /**
332
+ * `true` if the algorithm aborted because of `maxComputationTimeMs`.
333
+ * The result is still valid but may be coarser than ideal.
334
+ */
335
+ hitTimeout) {
336
+ this.edits = edits;
337
+ this.moves = moves;
338
+ this.hitTimeout = hitTimeout;
339
+ }
340
+ }
341
+
342
+ async function createDiffComputer(options = {}) {
343
+ if (options.useWasm) {
344
+ await (0,_wire_js__WEBPACK_IMPORTED_MODULE_0__.i)();
345
+ return new _WasmDiffComputer(options.algorithm);
346
+ }
347
+ return new _TsDiffComputer(options.algorithm);
348
+ }
349
+ // ============================================================================
350
+ // TS-backed computer
351
+ // ============================================================================
352
+ class _TsDiffComputer {
353
+ _algorithm;
354
+ _impl = new _wire_js__WEBPACK_IMPORTED_MODULE_0__.D();
355
+ constructor(_algorithm) {
356
+ this._algorithm = _algorithm;
357
+ }
358
+ computeDiff(original, modified, options) {
359
+ const originalLines = original.split('\n');
360
+ const modifiedLines = modified.split('\n');
361
+ const internal = {
362
+ maxComputationTimeMs: options?.maxComputationTimeMs ?? 0,
363
+ ignoreTrimWhitespace: options?.ignoreTrimWhitespace ?? false,
364
+ computeMoves: options?.computeMoves ?? false,
365
+ extendToSubwords: options?.extendToSubwords ?? false,
366
+ };
367
+ const linesDiff = this._impl.computeDiff(originalLines, modifiedLines, internal);
368
+ void this._algorithm; // currently a hint; auto-selection lives inside DefaultLinesDiffComputer
369
+ return _adaptLinesDiff(linesDiff, original, modified, originalLines, modifiedLines);
370
+ }
371
+ }
372
+ // ============================================================================
373
+ // WASM-backed computer
374
+ // ============================================================================
375
+ class _WasmDiffComputer {
376
+ _algorithm;
377
+ constructor(_algorithm) {
378
+ this._algorithm = _algorithm;
379
+ }
380
+ computeDiff(original, modified, options) {
381
+ const originalLines = original.split('\n');
382
+ const modifiedLines = modified.split('\n');
383
+ const wasmOptions = {};
384
+ if (options?.maxComputationTimeMs !== undefined)
385
+ wasmOptions.maxComputationTimeMs = options.maxComputationTimeMs;
386
+ if (options?.ignoreTrimWhitespace !== undefined)
387
+ wasmOptions.ignoreTrimWhitespace = options.ignoreTrimWhitespace;
388
+ if (options?.computeMoves !== undefined)
389
+ wasmOptions.computeMoves = options.computeMoves;
390
+ if (options?.extendToSubwords !== undefined)
391
+ wasmOptions.extendToSubwords = options.extendToSubwords;
392
+ const wasm = (0,_wire_js__WEBPACK_IMPORTED_MODULE_0__.g)();
393
+ const wasmResult = wasm.computeDiffLines(originalLines, modifiedLines, wasmOptions);
394
+ void this._algorithm;
395
+ const linesDiff = _wasmToLinesDiff(wasmResult);
396
+ return _adaptLinesDiff(linesDiff, original, modified, originalLines, modifiedLines);
397
+ }
398
+ }
399
+ function _wasmToLinesDiff(wasmResult) {
400
+ const changes = wasmResult.changes.map((c) => {
401
+ const inner = c.innerChanges?.map((ic) => new _wire_js__WEBPACK_IMPORTED_MODULE_0__.R(new _wire_js__WEBPACK_IMPORTED_MODULE_0__.a(ic.originalStartLine, ic.originalStartColumn, ic.originalEndLine, ic.originalEndColumn), new _wire_js__WEBPACK_IMPORTED_MODULE_0__.a(ic.modifiedStartLine, ic.modifiedStartColumn, ic.modifiedEndLine, ic.modifiedEndColumn)));
402
+ return new _wire_js__WEBPACK_IMPORTED_MODULE_0__.b(new _wire_js__WEBPACK_IMPORTED_MODULE_0__.L(c.original.startLineNumber, c.original.endLineNumberExclusive), new _wire_js__WEBPACK_IMPORTED_MODULE_0__.L(c.modified.startLineNumber, c.modified.endLineNumberExclusive), inner);
403
+ });
404
+ return new _wire_js__WEBPACK_IMPORTED_MODULE_0__.c(changes, [], wasmResult.hitTimeout);
405
+ }
406
+ // ============================================================================
407
+ // LinesDiff -> DiffResult adapter
408
+ // ============================================================================
409
+ /** @internal — exported for the worker-side client. */
410
+ function _adaptLinesDiff(linesDiff, original, modified, originalLines, modifiedLines) {
411
+ const originalLineStarts = _computeLineStarts(originalLines);
412
+ const modifiedLineStarts = _computeLineStarts(modifiedLines);
413
+ const replacements = [];
414
+ for (const change of linesDiff.changes) {
415
+ _appendChangeReplacements(change, original, modified, originalLines, modifiedLines, originalLineStarts, modifiedLineStarts, replacements);
416
+ }
417
+ const edits = AnnotatedStringEdit.of(replacements);
418
+ const moves = linesDiff.moves.map(m => _adaptMove(m, original, modified, originalLines, modifiedLines, originalLineStarts, modifiedLineStarts));
419
+ return new DiffResult(edits, moves, linesDiff.hitTimeout);
420
+ }
421
+ function _appendChangeReplacements(change, original, modified, originalLines, modifiedLines, originalLineStarts, modifiedLineStarts, out) {
422
+ if (change.innerChanges && change.innerChanges.length > 0) {
423
+ for (const ic of change.innerChanges) {
424
+ const origRange = _rangeToOffsetRange(ic.originalRange, original, originalLines, originalLineStarts);
425
+ const modRange = _rangeToOffsetRange(ic.modifiedRange, modified, modifiedLines, modifiedLineStarts);
426
+ const newText = modified.substring(modRange.start, modRange.endExclusive);
427
+ out.push(new AnnotatedStringReplacement(origRange, newText, DiffAnnotation.change));
428
+ }
429
+ return;
430
+ }
431
+ // Fallback: no inner detail — replace the whole line range.
432
+ const origRange = _lineRangeToOffsetRange(change.original.startLineNumber, change.original.endLineNumberExclusive, original, originalLineStarts);
433
+ const modRange = _lineRangeToOffsetRange(change.modified.startLineNumber, change.modified.endLineNumberExclusive, modified, modifiedLineStarts);
434
+ const newText = modified.substring(modRange.start, modRange.endExclusive);
435
+ out.push(new AnnotatedStringReplacement(origRange, newText, DiffAnnotation.change));
436
+ }
437
+ function _adaptMove(move, original, modified, originalLines, modifiedLines, originalLineStarts, modifiedLineStarts) {
438
+ const origRange = _lineRangeToOffsetRange(move.lineRangeMapping.original.startLineNumber, move.lineRangeMapping.original.endLineNumberExclusive, original, originalLineStarts);
439
+ const modRange = _lineRangeToOffsetRange(move.lineRangeMapping.modified.startLineNumber, move.lineRangeMapping.modified.endLineNumberExclusive, modified, modifiedLineStarts);
440
+ // Build inner edit with offsets local to the moved slices.
441
+ const inner = [];
442
+ for (const change of move.changes) {
443
+ if (change.innerChanges && change.innerChanges.length > 0) {
444
+ for (const ic of change.innerChanges) {
445
+ const globalOrig = _rangeToOffsetRange(ic.originalRange, original, originalLines, originalLineStarts);
446
+ const globalMod = _rangeToOffsetRange(ic.modifiedRange, modified, modifiedLines, modifiedLineStarts);
447
+ inner.push(new StringReplacement(new _wire_js__WEBPACK_IMPORTED_MODULE_0__.O(globalOrig.start - origRange.start, globalOrig.endExclusive - origRange.start), modified.substring(globalMod.start, globalMod.endExclusive)));
448
+ }
449
+ }
450
+ else {
451
+ const globalOrig = _lineRangeToOffsetRange(change.original.startLineNumber, change.original.endLineNumberExclusive, original, originalLineStarts);
452
+ const globalMod = _lineRangeToOffsetRange(change.modified.startLineNumber, change.modified.endLineNumberExclusive, modified, modifiedLineStarts);
453
+ inner.push(new StringReplacement(new _wire_js__WEBPACK_IMPORTED_MODULE_0__.O(globalOrig.start - origRange.start, globalOrig.endExclusive - origRange.start), modified.substring(globalMod.start, globalMod.endExclusive)));
454
+ }
455
+ }
456
+ return new Move(new OffsetRangeMapping(origRange, modRange), StringEdit.of(inner));
457
+ }
458
+ // ----- offset/line helpers -----
459
+ function _computeLineStarts(lines) {
460
+ // Offsets correspond to `lines.join('\n')`, which equals the input string
461
+ // when the input was split by `\n`.
462
+ const starts = new Array(lines.length + 1);
463
+ starts[0] = 0;
464
+ for (let i = 0; i < lines.length; i++) {
465
+ starts[i + 1] = starts[i] + lines[i].length + 1; // +1 for the '\n'
466
+ }
467
+ // `starts[lines.length]` is one past the synthetic trailing newline; the
468
+ // real text ends one earlier when there is no trailing newline (which is
469
+ // what `split('\n')` produces for non-newline-terminated input).
470
+ return starts;
471
+ }
472
+ function _lineRangeToOffsetRange(startLineNumber, endLineNumberExclusive, text, lineStarts) {
473
+ const start = _lineColToOffset(startLineNumber, 1, text, lineStarts);
474
+ const end = _lineColToOffset(endLineNumberExclusive, 1, text, lineStarts);
475
+ return new _wire_js__WEBPACK_IMPORTED_MODULE_0__.O(start, end);
476
+ }
477
+ function _rangeToOffsetRange(range, text, lines, lineStarts) {
478
+ const start = _lineColToOffset(range.startLineNumber, range.startColumn, text, lineStarts);
479
+ const end = _lineColToOffset(range.endLineNumber, range.endColumn, text, lineStarts);
480
+ return new _wire_js__WEBPACK_IMPORTED_MODULE_0__.O(start, end);
481
+ }
482
+ function _lineColToOffset(lineNumber, column, text, lineStarts) {
483
+ // `lineNumber` and `column` are 1-based; `endLineNumberExclusive` can be
484
+ // `lines.length + 1` (one past the last line).
485
+ if (lineNumber <= 0) {
486
+ return 0;
487
+ }
488
+ if (lineNumber > lineStarts.length) {
489
+ return text.length;
490
+ }
491
+ const base = lineStarts[lineNumber - 1];
492
+ const offset = base + (column - 1);
493
+ return Math.min(Math.max(offset, 0), text.length);
494
+ }
495
+
496
+ /**
497
+ * Main-thread client for the diff worker. Exposes an async `IAsyncDiffComputer`.
498
+ *
499
+ * Inputs travel as `string[]` via structured-clone postMessage. The response
500
+ * is a small JSON-friendly `WireLinesDiff`; the main thread reconstructs the
501
+ * full `LinesDiff` and runs `_adaptLinesDiff` locally (it already has the
502
+ * input strings).
503
+ */
504
+ async function createWorkerDiffComputer(opts = {}) {
505
+ const worker = opts.workerFactory ? opts.workerFactory() : defaultWorkerFactory();
506
+ const backend = opts.useWasm ? 'wasm' : 'ts';
507
+ const computer = new _WorkerDiffComputer(worker, backend);
508
+ await computer.init();
509
+ return computer;
510
+ }
511
+ function defaultWorkerFactory() {
512
+ // The `?esm` marker is auto-discovered by `@vscode/*-plugin-esm-url`
513
+ // bundler plugins; they emit `worker.ts` as a sibling `worker.js` bundle
514
+ // and rewrite this URL accordingly.
515
+ return new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("node_modules_vscode_diff_dist_worker_js_esm"), __webpack_require__.b), { type: undefined });
516
+ }
517
+ class _WorkerDiffComputer {
518
+ _worker;
519
+ _backend;
520
+ _nextId = 1;
521
+ _pending = new Map();
522
+ _pendingInit = null;
523
+ _disposed = false;
524
+ constructor(_worker, _backend) {
525
+ this._worker = _worker;
526
+ this._backend = _backend;
527
+ this._worker.addEventListener('message', (ev) => {
528
+ this._onMessage(ev.data);
529
+ });
530
+ this._worker.addEventListener('error', (ev) => {
531
+ this._failAll(new Error(`Worker error: ${ev.message ?? 'unknown'}`));
532
+ });
533
+ }
534
+ init() {
535
+ const id = this._nextId++;
536
+ const req = { kind: 'init', id, backend: this._backend };
537
+ return new Promise((resolve, reject) => {
538
+ this._pendingInit = { resolve, reject };
539
+ this._worker.postMessage(req);
540
+ });
541
+ }
542
+ computeDiff(original, modified, options = {}) {
543
+ if (this._disposed) {
544
+ return Promise.reject(new Error('Worker computer disposed'));
545
+ }
546
+ const id = this._nextId++;
547
+ const originalLines = original.split('\n');
548
+ const modifiedLines = modified.split('\n');
549
+ const msg = {
550
+ kind: 'computeDiff',
551
+ id,
552
+ backend: this._backend,
553
+ originalLines,
554
+ modifiedLines,
555
+ options,
556
+ };
557
+ return new Promise((resolve, reject) => {
558
+ this._pending.set(id, {
559
+ resolve,
560
+ reject,
561
+ original,
562
+ modified,
563
+ originalLines,
564
+ modifiedLines,
565
+ });
566
+ this._worker.postMessage(msg);
567
+ });
568
+ }
569
+ dispose() {
570
+ if (this._disposed)
571
+ return;
572
+ this._disposed = true;
573
+ this._failAll(new Error('Worker computer disposed'));
574
+ this._worker.terminate();
575
+ }
576
+ _onMessage(msg) {
577
+ if (msg.kind === 'init') {
578
+ const pending = this._pendingInit;
579
+ this._pendingInit = null;
580
+ pending?.resolve();
581
+ return;
582
+ }
583
+ const entry = this._pending.get(msg.id);
584
+ if (!entry) {
585
+ // Init failure is reported on the init id with `kind === 'computeDiff'`
586
+ // and `ok === false`; route to the init promise if it's still pending.
587
+ if (!msg.ok && this._pendingInit) {
588
+ const p = this._pendingInit;
589
+ this._pendingInit = null;
590
+ p.reject(new Error(msg.error));
591
+ }
592
+ return;
593
+ }
594
+ this._pending.delete(msg.id);
595
+ if (!msg.ok) {
596
+ entry.reject(new Error(msg.error));
597
+ return;
598
+ }
599
+ try {
600
+ const linesDiff = (0,_wire_js__WEBPACK_IMPORTED_MODULE_0__.w)(msg.result);
601
+ const result = _adaptLinesDiff(linesDiff, entry.original, entry.modified, entry.originalLines, entry.modifiedLines);
602
+ entry.resolve(result);
603
+ }
604
+ catch (err) {
605
+ entry.reject(err instanceof Error ? err : new Error(String(err)));
606
+ }
607
+ }
608
+ _failAll(err) {
609
+ for (const p of this._pending.values())
610
+ p.reject(err);
611
+ this._pending.clear();
612
+ if (this._pendingInit) {
613
+ this._pendingInit.reject(err);
614
+ this._pendingInit = null;
615
+ }
616
+ }
617
+ }
618
+
619
+
620
+ //# sourceMappingURL=index.js.map
621
+
622
+
623
+ /***/ }
624
+
625
+ }]);
626
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVuZG9ycy1ub2RlX21vZHVsZXNfdnNjb2RlX2RpZmZfZGlzdF9pbmRleF9qcy5tYWluLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDNk47QUFDMUs7O0FBRW5EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsZUFBZSxNQUFNLGNBQWM7QUFDckQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLFdBQVcsSUFBSSw2QkFBNkI7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3Qix5QkFBeUI7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsWUFBWSxLQUFLLFVBQVU7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0MsdUNBQVc7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLHVDQUFXO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsb0RBQW9EO0FBQ2pGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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LDJDQUFlO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRXNiO0FBQ3RiIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vamRlcm9ib3QtaWRlLWludGVyZmFjZS8uL25vZGVfbW9kdWxlcy9AdnNjb2RlL2RpZmYvZGlzdC9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbmltcG9ydCB7IE8gYXMgT2Zmc2V0UmFuZ2UsIGkgYXMgaW5pdFdhc20sIGcgYXMgZ2V0V2FzbSwgRCBhcyBEZWZhdWx0TGluZXNEaWZmQ29tcHV0ZXIsIFIgYXMgUmFuZ2VNYXBwaW5nLCBhIGFzIFJhbmdlLCBiIGFzIERldGFpbGVkTGluZVJhbmdlTWFwcGluZywgTCBhcyBMaW5lUmFuZ2UsIGMgYXMgTGluZXNEaWZmLCB3IGFzIHdpcmVUb0xpbmVzRGlmZiB9IGZyb20gJy4vd2lyZS5qcyc7XG5leHBvcnQgeyBkIGFzIF9MaW5lUmFuZ2VNYXBwaW5nIH0gZnJvbSAnLi93aXJlLmpzJztcblxuLyoqXG4gKiBBIHBhaXIgb2YgcmFuZ2VzLCBvbmUgaW4gYG9yaWdpbmFsYCwgb25lIGluIGBtb2RpZmllZGAuXG4gKi9cbmNsYXNzIE9mZnNldFJhbmdlTWFwcGluZyB7XG4gICAgb3JpZ2luYWw7XG4gICAgbW9kaWZpZWQ7XG4gICAgY29uc3RydWN0b3Iob3JpZ2luYWwsIG1vZGlmaWVkKSB7XG4gICAgICAgIHRoaXMub3JpZ2luYWwgPSBvcmlnaW5hbDtcbiAgICAgICAgdGhpcy5tb2RpZmllZCA9IG1vZGlmaWVkO1xuICAgIH1cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIGAke3RoaXMub3JpZ2luYWx9IDwtPiAke3RoaXMubW9kaWZpZWR9YDtcbiAgICB9XG59XG5cbi8qKlxuICogQSBzaW5nbGUgYXRvbWljIHJlcGxhY2VtZW50OiByZXBsYWNlIGByYW5nZWAgaW4gdGhlIGlucHV0IHdpdGggYG5ld1RleHRgLlxuICovXG5jbGFzcyBTdHJpbmdSZXBsYWNlbWVudCB7XG4gICAgcmFuZ2U7XG4gICAgbmV3VGV4dDtcbiAgICBjb25zdHJ1Y3RvcihyYW5nZSwgbmV3VGV4dCkge1xuICAgICAgICB0aGlzLnJhbmdlID0gcmFuZ2U7XG4gICAgICAgIHRoaXMubmV3VGV4dCA9IG5ld1RleHQ7XG4gICAgfVxuICAgIGdldCBpc0VtcHR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yYW5nZS5pc0VtcHR5ICYmIHRoaXMubmV3VGV4dC5sZW5ndGggPT09IDA7XG4gICAgfVxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gYCR7dGhpcy5yYW5nZX0tPiR7SlNPTi5zdHJpbmdpZnkodGhpcy5uZXdUZXh0KX1gO1xuICAgIH1cbn1cbi8qKlxuICogQSBzZXQgb2YgcmVwbGFjZW1lbnRzIGFwcGxpZWQgaW4gcGFyYWxsZWwgdG8gb25lIGlucHV0IHN0cmluZy5cbiAqXG4gKiBJbnZhcmlhbnRzOlxuICogIC0gcmVwbGFjZW1lbnRzIGFyZSBzb3J0ZWQgYnkgYHJhbmdlLnN0YXJ0YFxuICogIC0gcmVwbGFjZW1lbnRzIGRvIG5vdCBvdmVybGFwICh0b3VjaGluZyBpcyBhbGxvd2VkKVxuICogIC0gYWxsIHJhbmdlcyBsaXZlIGluIHRoZSBzYW1lIGNvb3JkaW5hdGUgc3BhY2UgKHRoZSBpbnB1dCBwYXNzZWQgdG8gYGFwcGx5YClcbiAqL1xuY2xhc3MgU3RyaW5nRWRpdCB7XG4gICAgcmVwbGFjZW1lbnRzO1xuICAgIHN0YXRpYyBlbXB0eSA9IG5ldyBTdHJpbmdFZGl0KFtdKTtcbiAgICBzdGF0aWMgc2luZ2xlKHJlcGxhY2VtZW50KSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RyaW5nRWRpdChbcmVwbGFjZW1lbnRdKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVmFsaWRhdGVzIHRoYXQgcmVwbGFjZW1lbnRzIGFyZSBzb3J0ZWQgYW5kIG5vbi1vdmVybGFwcGluZy5cbiAgICAgKi9cbiAgICBzdGF0aWMgb2YocmVwbGFjZW1lbnRzKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmVwbGFjZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2ID0gcmVwbGFjZW1lbnRzW2kgLSAxXTtcbiAgICAgICAgICAgIGNvbnN0IGN1ciA9IHJlcGxhY2VtZW50c1tpXTtcbiAgICAgICAgICAgIGlmIChwcmV2LnJhbmdlLmVuZEV4Y2x1c2l2ZSA+IGN1ci5yYW5nZS5zdGFydCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU3RyaW5nRWRpdC5vZjogcmVwbGFjZW1lbnRzIG11c3QgYmUgc29ydGVkIGFuZCBub24tb3ZlcmxhcHBpbmcgKGAgK1xuICAgICAgICAgICAgICAgICAgICBgJHtwcmV2LnJhbmdlfSB2cyAke2N1ci5yYW5nZX0pYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdFZGl0KHJlcGxhY2VtZW50cyk7XG4gICAgfVxuICAgIGNvbnN0cnVjdG9yKHJlcGxhY2VtZW50cykge1xuICAgICAgICB0aGlzLnJlcGxhY2VtZW50cyA9IHJlcGxhY2VtZW50cztcbiAgICB9XG4gICAgZ2V0IGlzRW1wdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VtZW50cy5sZW5ndGggPT09IDA7XG4gICAgfVxuICAgIGFwcGx5KHRleHQpIHtcbiAgICAgICAgaWYgKHRoaXMucmVwbGFjZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFydHMgPSBbXTtcbiAgICAgICAgbGV0IGN1cnNvciA9IDA7XG4gICAgICAgIGZvciAoY29uc3QgciBvZiB0aGlzLnJlcGxhY2VtZW50cykge1xuICAgICAgICAgICAgcGFydHMucHVzaCh0ZXh0LnN1YnN0cmluZyhjdXJzb3IsIHIucmFuZ2Uuc3RhcnQpKTtcbiAgICAgICAgICAgIHBhcnRzLnB1c2goci5uZXdUZXh0KTtcbiAgICAgICAgICAgIGN1cnNvciA9IHIucmFuZ2UuZW5kRXhjbHVzaXZlO1xuICAgICAgICB9XG4gICAgICAgIHBhcnRzLnB1c2godGV4dC5zdWJzdHJpbmcoY3Vyc29yKSk7XG4gICAgICAgIHJldHVybiBwYXJ0cy5qb2luKCcnKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBlZGl0IGBFYCBzdWNoIHRoYXQgYEUuYXBwbHkodGhpcy5hcHBseShpbnB1dCkpID09PSBpbnB1dGAuXG4gICAgICovXG4gICAgaW52ZXJzZShpbnB1dCkge1xuICAgICAgICBjb25zdCBvdXQgPSBbXTtcbiAgICAgICAgbGV0IGRlbHRhID0gMDtcbiAgICAgICAgZm9yIChjb25zdCByIG9mIHRoaXMucmVwbGFjZW1lbnRzKSB7XG4gICAgICAgICAgICBjb25zdCBuZXdTdGFydCA9IHIucmFuZ2Uuc3RhcnQgKyBkZWx0YTtcbiAgICAgICAgICAgIGNvbnN0IG5ld0VuZCA9IG5ld1N0YXJ0ICsgci5uZXdUZXh0Lmxlbmd0aDtcbiAgICAgICAgICAgIGNvbnN0IG9sZFRleHQgPSBpbnB1dC5zdWJzdHJpbmcoci5yYW5nZS5zdGFydCwgci5yYW5nZS5lbmRFeGNsdXNpdmUpO1xuICAgICAgICAgICAgb3V0LnB1c2gobmV3IFN0cmluZ1JlcGxhY2VtZW50KG5ldyBPZmZzZXRSYW5nZShuZXdTdGFydCwgbmV3RW5kKSwgb2xkVGV4dCkpO1xuICAgICAgICAgICAgZGVsdGEgKz0gci5uZXdUZXh0Lmxlbmd0aCAtIHIucmFuZ2UubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgU3RyaW5nRWRpdChvdXQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBKb2lucyB0b3VjaGluZyByZXBsYWNlbWVudHMgYW5kIGRyb3BzIG5vLW9wcy5cbiAgICAgKi9cbiAgICBub3JtYWxpemUoKSB7XG4gICAgICAgIGNvbnN0IG91dCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHIgb2YgdGhpcy5yZXBsYWNlbWVudHMpIHtcbiAgICAgICAgICAgIGlmIChyLmlzRW1wdHkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHByZXYgPSBvdXRbb3V0Lmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgaWYgKHByZXYgJiYgcHJldi5yYW5nZS5lbmRFeGNsdXNpdmUgPT09IHIucmFuZ2Uuc3RhcnQpIHtcbiAgICAgICAgICAgICAgICBvdXRbb3V0Lmxlbmd0aCAtIDFdID0gbmV3IFN0cmluZ1JlcGxhY2VtZW50KG5ldyBPZmZzZXRSYW5nZShwcmV2LnJhbmdlLnN0YXJ0LCByLnJhbmdlLmVuZEV4Y2x1c2l2ZSksIHByZXYubmV3VGV4dCArIHIubmV3VGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBvdXQucHVzaChyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFN0cmluZ0VkaXQob3V0KTtcbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiBgU3RyaW5nRWRpdFske3RoaXMucmVwbGFjZW1lbnRzLm1hcChyID0+IHIudG9TdHJpbmcoKSkuam9pbignLCAnKX1dYDtcbiAgICB9XG59XG5cbi8qKlxuICogQW4gYXRvbWljIHJlcGxhY2VtZW50IGNhcnJ5aW5nIHVzZXItZGVmaW5lZCBtZXRhZGF0YS5cbiAqL1xuY2xhc3MgQW5ub3RhdGVkU3RyaW5nUmVwbGFjZW1lbnQge1xuICAgIHJhbmdlO1xuICAgIG5ld1RleHQ7XG4gICAgZGF0YTtcbiAgICBjb25zdHJ1Y3RvcihyYW5nZSwgbmV3VGV4dCwgZGF0YSkge1xuICAgICAgICB0aGlzLnJhbmdlID0gcmFuZ2U7XG4gICAgICAgIHRoaXMubmV3VGV4dCA9IG5ld1RleHQ7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuICAgIGdldCBpc0VtcHR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yYW5nZS5pc0VtcHR5ICYmIHRoaXMubmV3VGV4dC5sZW5ndGggPT09IDA7XG4gICAgfVxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gYCR7dGhpcy5yYW5nZX0tPiR7SlNPTi5zdHJpbmdpZnkodGhpcy5uZXdUZXh0KX0jJHt0aGlzLmRhdGF9YDtcbiAgICB9XG59XG4vKipcbiAqIEEgc2V0IG9mIGFubm90YXRlZCByZXBsYWNlbWVudHMgYXBwbGllZCBpbiBwYXJhbGxlbC5cbiAqXG4gKiBJbnZhcmlhbnRzOiBzYW1lIGFzIGBTdHJpbmdFZGl0YCAoc29ydGVkIGJ5IGByYW5nZS5zdGFydGAsIG5vbi1vdmVybGFwcGluZyxcbiAqIHNoYXJlZCBjb29yZGluYXRlIHNwYWNlKS5cbiAqL1xuY2xhc3MgQW5ub3RhdGVkU3RyaW5nRWRpdCB7XG4gICAgcmVwbGFjZW1lbnRzO1xuICAgIHN0YXRpYyBlbXB0eSgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBbm5vdGF0ZWRTdHJpbmdFZGl0KFtdKTtcbiAgICB9XG4gICAgc3RhdGljIHNpbmdsZShyZXBsYWNlbWVudCkge1xuICAgICAgICByZXR1cm4gbmV3IEFubm90YXRlZFN0cmluZ0VkaXQoW3JlcGxhY2VtZW50XSk7XG4gICAgfVxuICAgIHN0YXRpYyBvZihyZXBsYWNlbWVudHMpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCByZXBsYWNlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXYgPSByZXBsYWNlbWVudHNbaSAtIDFdO1xuICAgICAgICAgICAgY29uc3QgY3VyID0gcmVwbGFjZW1lbnRzW2ldO1xuICAgICAgICAgICAgaWYgKHByZXYucmFuZ2UuZW5kRXhjbHVzaXZlID4gY3VyLnJhbmdlLnN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBbm5vdGF0ZWRTdHJpbmdFZGl0Lm9mOiByZXBsYWNlbWVudHMgbXVzdCBiZSBzb3J0ZWQgYW5kIG5vbi1vdmVybGFwcGluZyAoYCArXG4gICAgICAgICAgICAgICAgICAgIGAke3ByZXYucmFuZ2V9IHZzICR7Y3VyLnJhbmdlfSlgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IEFubm90YXRlZFN0cmluZ0VkaXQocmVwbGFjZW1lbnRzKTtcbiAgICB9XG4gICAgY29uc3RydWN0b3IocmVwbGFjZW1lbnRzKSB7XG4gICAgICAgIHRoaXMucmVwbGFjZW1lbnRzID0gcmVwbGFjZW1lbnRzO1xuICAgIH1cbiAgICBnZXQgaXNFbXB0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZW1lbnRzLmxlbmd0aCA9PT0gMDtcbiAgICB9XG4gICAgYXBwbHkodGV4dCkge1xuICAgICAgICBpZiAodGhpcy5yZXBsYWNlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGV4dDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXJ0cyA9IFtdO1xuICAgICAgICBsZXQgY3Vyc29yID0gMDtcbiAgICAgICAgZm9yIChjb25zdCByIG9mIHRoaXMucmVwbGFjZW1lbnRzKSB7XG4gICAgICAgICAgICBwYXJ0cy5wdXNoKHRleHQuc3Vic3RyaW5nKGN1cnNvciwgci5yYW5nZS5zdGFydCkpO1xuICAgICAgICAgICAgcGFydHMucHVzaChyLm5ld1RleHQpO1xuICAgICAgICAgICAgY3Vyc29yID0gci5yYW5nZS5lbmRFeGNsdXNpdmU7XG4gICAgICAgIH1cbiAgICAgICAgcGFydHMucHVzaCh0ZXh0LnN1YnN0cmluZyhjdXJzb3IpKTtcbiAgICAgICAgcmV0dXJuIHBhcnRzLmpvaW4oJycpO1xuICAgIH1cbiAgICBpbnZlcnNlKGlucHV0LCBpbnZlcnREYXRhKSB7XG4gICAgICAgIGNvbnN0IG91dCA9IFtdO1xuICAgICAgICBsZXQgZGVsdGEgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IHIgb2YgdGhpcy5yZXBsYWNlbWVudHMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld1N0YXJ0ID0gci5yYW5nZS5zdGFydCArIGRlbHRhO1xuICAgICAgICAgICAgY29uc3QgbmV3RW5kID0gbmV3U3RhcnQgKyByLm5ld1RleHQubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3Qgb2xkVGV4dCA9IGlucHV0LnN1YnN0cmluZyhyLnJhbmdlLnN0YXJ0LCByLnJhbmdlLmVuZEV4Y2x1c2l2ZSk7XG4gICAgICAgICAgICBvdXQucHVzaChuZXcgQW5ub3RhdGVkU3RyaW5nUmVwbGFjZW1lbnQobmV3IE9mZnNldFJhbmdlKG5ld1N0YXJ0LCBuZXdFbmQpLCBvbGRUZXh0LCBpbnZlcnREYXRhKHIuZGF0YSkpKTtcbiAgICAgICAgICAgIGRlbHRhICs9IHIubmV3VGV4dC5sZW5ndGggLSByLnJhbmdlLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IEFubm90YXRlZFN0cmluZ0VkaXQob3V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSm9pbnMgdG91Y2hpbmcgcmVwbGFjZW1lbnRzIHdoZW4gdGhlaXIgYW5ub3RhdGlvbnMgam9pbi4gRHJvcHMgbm8tb3BzLlxuICAgICAqL1xuICAgIG5vcm1hbGl6ZSgpIHtcbiAgICAgICAgY29uc3Qgb3V0ID0gW107XG4gICAgICAgIGZvciAoY29uc3QgciBvZiB0aGlzLnJlcGxhY2VtZW50cykge1xuICAgICAgICAgICAgaWYgKHIuaXNFbXB0eSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcHJldiA9IG91dFtvdXQubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICBpZiAocHJldiAmJiBwcmV2LnJhbmdlLmVuZEV4Y2x1c2l2ZSA9PT0gci5yYW5nZS5zdGFydCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5lZCA9IHByZXYuZGF0YS5qb2luKHIuZGF0YSk7XG4gICAgICAgICAgICAgICAgaWYgKGpvaW5lZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dFtvdXQubGVuZ3RoIC0gMV0gPSBuZXcgQW5ub3RhdGVkU3RyaW5nUmVwbGFjZW1lbnQobmV3IE9mZnNldFJhbmdlKHByZXYucmFuZ2Uuc3RhcnQsIHIucmFuZ2UuZW5kRXhjbHVzaXZlKSwgcHJldi5uZXdUZXh0ICsgci5uZXdUZXh0LCBqb2luZWQpO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvdXQucHVzaChyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IEFubm90YXRlZFN0cmluZ0VkaXQob3V0KTtcbiAgICB9XG4gICAgbWFwRGF0YShmKSB7XG4gICAgICAgIHJldHVybiBuZXcgQW5ub3RhdGVkU3RyaW5nRWRpdCh0aGlzLnJlcGxhY2VtZW50cy5tYXAociA9PiBuZXcgQW5ub3RhdGVkU3RyaW5nUmVwbGFjZW1lbnQoci5yYW5nZSwgci5uZXdUZXh0LCBmKHIuZGF0YSkpKSk7XG4gICAgfVxuICAgIHN0cmlwRGF0YSgpIHtcbiAgICAgICAgcmV0dXJuIFN0cmluZ0VkaXQub2YodGhpcy5yZXBsYWNlbWVudHMubWFwKHIgPT4gbmV3IFN0cmluZ1JlcGxhY2VtZW50KHIucmFuZ2UsIHIubmV3VGV4dCkpKTtcbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiBgQW5ub3RhdGVkU3RyaW5nRWRpdFske3RoaXMucmVwbGFjZW1lbnRzLm1hcChyID0+IHIudG9TdHJpbmcoKSkuam9pbignLCAnKX1dYDtcbiAgICB9XG59XG4vKipcbiAqIERpZmYgcmVzdWx0IGFubm90YXRpb24uXG4gKlxuICogQ2FycmllcyBmbGFncyBkZXNjcmliaW5nIHRoZSBuYXR1cmUgb2YgdGhlIHJlcGxhY2VtZW50LiBGb3Igbm93IG9ubHlcbiAqIGBpc0Zvcm1hdHRpbmdDaGFuZ2VgIGlzIGV4cG9zZWQ7IG1vcmUgZmxhZ3MgKGUuZy4gbW92ZSBzb3VyY2UvdGFyZ2V0LFxuICogc2VtYW50aWMgY2F0ZWdvcnkpIGNhbiBiZSBhZGRlZCBsYXRlci5cbiAqL1xuY2xhc3MgRGlmZkFubm90YXRpb24ge1xuICAgIGlzRm9ybWF0dGluZ0NoYW5nZTtcbiAgICBzdGF0aWMgY2hhbmdlID0gbmV3IERpZmZBbm5vdGF0aW9uKGZhbHNlKTtcbiAgICBzdGF0aWMgZm9ybWF0dGluZyA9IG5ldyBEaWZmQW5ub3RhdGlvbih0cnVlKTtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKiogV2hldGhlciB0aGUgcmVwbGFjZW1lbnQgaXMgcHVyZWx5IGEgZm9ybWF0dGluZyBjaGFuZ2UgKHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBldGMuKS4gKi9cbiAgICBpc0Zvcm1hdHRpbmdDaGFuZ2UpIHtcbiAgICAgICAgdGhpcy5pc0Zvcm1hdHRpbmdDaGFuZ2UgPSBpc0Zvcm1hdHRpbmdDaGFuZ2U7XG4gICAgfVxuICAgIGpvaW4ob3RoZXIpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNGb3JtYXR0aW5nQ2hhbmdlICE9PSBvdGhlci5pc0Zvcm1hdHRpbmdDaGFuZ2UpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc0Zvcm1hdHRpbmdDaGFuZ2UgPyAnZm9ybWF0dGluZycgOiAnY2hhbmdlJztcbiAgICB9XG59XG5cbi8qKlxuICogQSBibG9jayBvZiB0ZXh0IHRoYXQgd2FzIG1vdmVkIGJldHdlZW4gdHdvIGxvY2F0aW9ucy5cbiAqXG4gKiBgcmFuZ2VgIGxvY2F0ZXMgdGhlIGJsb2NrIGluIGBvcmlnaW5hbGAgYW5kIGluIGBtb2RpZmllZGAgKG9mZnNldHMgaW4gdGhlXG4gKiByZXNwZWN0aXZlIGZ1bGwgdGV4dHMpLiBgaW5uZXJFZGl0YCBkZXNjcmliZXMgdGhlIGNoYW5nZXMgaW5zaWRlIHRoZSBtb3ZlZFxuICogYmxvY2ssIHdpdGggb2Zmc2V0cyBsb2NhbCB0byB0aGUgc2xpY2UgKGkuZS4gYDBgIGlzIHRoZSBzdGFydCBvZiB0aGUgc2xpY2UpLlxuICovXG5jbGFzcyBNb3ZlIHtcbiAgICByYW5nZTtcbiAgICBpbm5lckVkaXQ7XG4gICAgY29uc3RydWN0b3IocmFuZ2UsIGlubmVyRWRpdCkge1xuICAgICAgICB0aGlzLnJhbmdlID0gcmFuZ2U7XG4gICAgICAgIHRoaXMuaW5uZXJFZGl0ID0gaW5uZXJFZGl0O1xuICAgIH1cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIGBNb3ZlICR7dGhpcy5yYW5nZX1gICsgKHRoaXMuaW5uZXJFZGl0LmlzRW1wdHkgPyAnJyA6IGAgKCR7dGhpcy5pbm5lckVkaXR9KWApO1xuICAgIH1cbn1cblxuLyoqXG4gKiBPdXRwdXQgb2YgYSBkaWZmIGNvbXB1dGF0aW9uLlxuICovXG5jbGFzcyBEaWZmUmVzdWx0IHtcbiAgICBlZGl0cztcbiAgICBtb3ZlcztcbiAgICBoaXRUaW1lb3V0O1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgICAqIFBhcmFsbGVsIHNldCBvZiByZXBsYWNlbWVudHMgdHJhbnNmb3JtaW5nIGBvcmlnaW5hbGAgaW50byBgbW9kaWZpZWRgLFxuICAgICAqIGV4Y2x1ZGluZyBhbnkgcmVwbGFjZW1lbnRzIHRoYXQgYXJlIHBhcnQgb2YgYSBgTW92ZWAuXG4gICAgICpcbiAgICAgKiBXaGVuIG5vIG1vdmVzIGFyZSBjb21wdXRlZDogYGVkaXRzLmFwcGx5KG9yaWdpbmFsKSA9PT0gbW9kaWZpZWRgLlxuICAgICAqL1xuICAgIGVkaXRzLCBcbiAgICAvKipcbiAgICAgKiBEZXRlY3RlZCB0ZXh0IG1vdmVzLiBFbXB0eSB1bmxlc3MgYERpZmZPcHRpb25zLmNvbXB1dGVNb3Zlc2AgaXMgc2V0LlxuICAgICAqL1xuICAgIG1vdmVzLCBcbiAgICAvKipcbiAgICAgKiBgdHJ1ZWAgaWYgdGhlIGFsZ29yaXRobSBhYm9ydGVkIGJlY2F1c2Ugb2YgYG1heENvbXB1dGF0aW9uVGltZU1zYC5cbiAgICAgKiBUaGUgcmVzdWx0IGlzIHN0aWxsIHZhbGlkIGJ1dCBtYXkgYmUgY29hcnNlciB0aGFuIGlkZWFsLlxuICAgICAqL1xuICAgIGhpdFRpbWVvdXQpIHtcbiAgICAgICAgdGhpcy5lZGl0cyA9IGVkaXRzO1xuICAgICAgICB0aGlzLm1vdmVzID0gbW92ZXM7XG4gICAgICAgIHRoaXMuaGl0VGltZW91dCA9IGhpdFRpbWVvdXQ7XG4gICAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVEaWZmQ29tcHV0ZXIob3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKG9wdGlvbnMudXNlV2FzbSkge1xuICAgICAgICBhd2FpdCBpbml0V2FzbSgpO1xuICAgICAgICByZXR1cm4gbmV3IF9XYXNtRGlmZkNvbXB1dGVyKG9wdGlvbnMuYWxnb3JpdGhtKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBfVHNEaWZmQ29tcHV0ZXIob3B0aW9ucy5hbGdvcml0aG0pO1xufVxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVFMtYmFja2VkIGNvbXB1dGVyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5jbGFzcyBfVHNEaWZmQ29tcHV0ZXIge1xuICAgIF9hbGdvcml0aG07XG4gICAgX2ltcGwgPSBuZXcgRGVmYXVsdExpbmVzRGlmZkNvbXB1dGVyKCk7XG4gICAgY29uc3RydWN0b3IoX2FsZ29yaXRobSkge1xuICAgICAgICB0aGlzLl9hbGdvcml0aG0gPSBfYWxnb3JpdGhtO1xuICAgIH1cbiAgICBjb21wdXRlRGlmZihvcmlnaW5hbCwgbW9kaWZpZWQsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxMaW5lcyA9IG9yaWdpbmFsLnNwbGl0KCdcXG4nKTtcbiAgICAgICAgY29uc3QgbW9kaWZpZWRMaW5lcyA9IG1vZGlmaWVkLnNwbGl0KCdcXG4nKTtcbiAgICAgICAgY29uc3QgaW50ZXJuYWwgPSB7XG4gICAgICAgICAgICBtYXhDb21wdXRhdGlvblRpbWVNczogb3B0aW9ucz8ubWF4Q29tcHV0YXRpb25UaW1lTXMgPz8gMCxcbiAgICAgICAgICAgIGlnbm9yZVRyaW1XaGl0ZXNwYWNlOiBvcHRpb25zPy5pZ25vcmVUcmltV2hpdGVzcGFjZSA/PyBmYWxzZSxcbiAgICAgICAgICAgIGNvbXB1dGVNb3Zlczogb3B0aW9ucz8uY29tcHV0ZU1vdmVzID8/IGZhbHNlLFxuICAgICAgICAgICAgZXh0ZW5kVG9TdWJ3b3Jkczogb3B0aW9ucz8uZXh0ZW5kVG9TdWJ3b3JkcyA/PyBmYWxzZSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgbGluZXNEaWZmID0gdGhpcy5faW1wbC5jb21wdXRlRGlmZihvcmlnaW5hbExpbmVzLCBtb2RpZmllZExpbmVzLCBpbnRlcm5hbCk7XG4gICAgICAgIHZvaWQgdGhpcy5fYWxnb3JpdGhtOyAvLyBjdXJyZW50bHkgYSBoaW50OyBhdXRvLXNlbGVjdGlvbiBsaXZlcyBpbnNpZGUgRGVmYXVsdExpbmVzRGlmZkNvbXB1dGVyXG4gICAgICAgIHJldHVybiBfYWRhcHRMaW5lc0RpZmYobGluZXNEaWZmLCBvcmlnaW5hbCwgbW9kaWZpZWQsIG9yaWdpbmFsTGluZXMsIG1vZGlmaWVkTGluZXMpO1xuICAgIH1cbn1cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFdBU00tYmFja2VkIGNvbXB1dGVyXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5jbGFzcyBfV2FzbURpZmZDb21wdXRlciB7XG4gICAgX2FsZ29yaXRobTtcbiAgICBjb25zdHJ1Y3RvcihfYWxnb3JpdGhtKSB7XG4gICAgICAgIHRoaXMuX2FsZ29yaXRobSA9IF9hbGdvcml0aG07XG4gICAgfVxuICAgIGNvbXB1dGVEaWZmKG9yaWdpbmFsLCBtb2RpZmllZCwgb3B0aW9ucykge1xuICAgICAgICBjb25zdCBvcmlnaW5hbExpbmVzID0gb3JpZ2luYWwuc3BsaXQoJ1xcbicpO1xuICAgICAgICBjb25zdCBtb2RpZmllZExpbmVzID0gbW9kaWZpZWQuc3BsaXQoJ1xcbicpO1xuICAgICAgICBjb25zdCB3YXNtT3B0aW9ucyA9IHt9O1xuICAgICAgICBpZiAob3B0aW9ucz8ubWF4Q29tcHV0YXRpb25UaW1lTXMgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgIHdhc21PcHRpb25zLm1heENvbXB1dGF0aW9uVGltZU1zID0gb3B0aW9ucy5tYXhDb21wdXRhdGlvblRpbWVNcztcbiAgICAgICAgaWYgKG9wdGlvbnM/Lmlnbm9yZVRyaW1XaGl0ZXNwYWNlICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICB3YXNtT3B0aW9ucy5pZ25vcmVUcmltV2hpdGVzcGFjZSA9IG9wdGlvbnMuaWdub3JlVHJpbVdoaXRlc3BhY2U7XG4gICAgICAgIGlmIChvcHRpb25zPy5jb21wdXRlTW92ZXMgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAgIHdhc21PcHRpb25zLmNvbXB1dGVNb3ZlcyA9IG9wdGlvbnMuY29tcHV0ZU1vdmVzO1xuICAgICAgICBpZiAob3B0aW9ucz8uZXh0ZW5kVG9TdWJ3b3JkcyAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgd2FzbU9wdGlvbnMuZXh0ZW5kVG9TdWJ3b3JkcyA9IG9wdGlvbnMuZXh0ZW5kVG9TdWJ3b3JkcztcbiAgICAgICAgY29uc3Qgd2FzbSA9IGdldFdhc20oKTtcbiAgICAgICAgY29uc3Qgd2FzbVJlc3VsdCA9IHdhc20uY29tcHV0ZURpZmZMaW5lcyhvcmlnaW5hbExpbmVzLCBtb2RpZmllZExpbmVzLCB3YXNtT3B0aW9ucyk7XG4gICAgICAgIHZvaWQgdGhpcy5fYWxnb3JpdGhtO1xuICAgICAgICBjb25zdCBsaW5lc0RpZmYgPSBfd2FzbVRvTGluZXNEaWZmKHdhc21SZXN1bHQpO1xuICAgICAgICByZXR1cm4gX2FkYXB0TGluZXNEaWZmKGxpbmVzRGlmZiwgb3JpZ2luYWwsIG1vZGlmaWVkLCBvcmlnaW5hbExpbmVzLCBtb2RpZmllZExpbmVzKTtcbiAgICB9XG59XG5mdW5jdGlvbiBfd2FzbVRvTGluZXNEaWZmKHdhc21SZXN1bHQpIHtcbiAgICBjb25zdCBjaGFuZ2VzID0gd2FzbVJlc3VsdC5jaGFuZ2VzLm1hcCgoYykgPT4ge1xuICAgICAgICBjb25zdCBpbm5lciA9IGMuaW5uZXJDaGFuZ2VzPy5tYXAoKGljKSA9PiBuZXcgUmFuZ2VNYXBwaW5nKG5ldyBSYW5nZShpYy5vcmlnaW5hbFN0YXJ0TGluZSwgaWMub3JpZ2luYWxTdGFydENvbHVtbiwgaWMub3JpZ2luYWxFbmRMaW5lLCBpYy5vcmlnaW5hbEVuZENvbHVtbiksIG5ldyBSYW5nZShpYy5tb2RpZmllZFN0YXJ0TGluZSwgaWMubW9kaWZpZWRTdGFydENvbHVtbiwgaWMubW9kaWZpZWRFbmRMaW5lLCBpYy5tb2RpZmllZEVuZENvbHVtbikpKTtcbiAgICAgICAgcmV0dXJuIG5ldyBEZXRhaWxlZExpbmVSYW5nZU1hcHBpbmcobmV3IExpbmVSYW5nZShjLm9yaWdpbmFsLnN0YXJ0TGluZU51bWJlciwgYy5vcmlnaW5hbC5lbmRMaW5lTnVtYmVyRXhjbHVzaXZlKSwgbmV3IExpbmVSYW5nZShjLm1vZGlmaWVkLnN0YXJ0TGluZU51bWJlciwgYy5tb2RpZmllZC5lbmRMaW5lTnVtYmVyRXhjbHVzaXZlKSwgaW5uZXIpO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXcgTGluZXNEaWZmKGNoYW5nZXMsIFtdLCB3YXNtUmVzdWx0LmhpdFRpbWVvdXQpO1xufVxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gTGluZXNEaWZmIC0+IERpZmZSZXN1bHQgYWRhcHRlclxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLyoqIEBpbnRlcm5hbCDigJQgZXhwb3J0ZWQgZm9yIHRoZSB3b3JrZXItc2lkZSBjbGllbnQuICovXG5mdW5jdGlvbiBfYWRhcHRMaW5lc0RpZmYobGluZXNEaWZmLCBvcmlnaW5hbCwgbW9kaWZpZWQsIG9yaWdpbmFsTGluZXMsIG1vZGlmaWVkTGluZXMpIHtcbiAgICBjb25zdCBvcmlnaW5hbExpbmVTdGFydHMgPSBfY29tcHV0ZUxpbmVTdGFydHMob3JpZ2luYWxMaW5lcyk7XG4gICAgY29uc3QgbW9kaWZpZWRMaW5lU3RhcnRzID0gX2NvbXB1dGVMaW5lU3RhcnRzKG1vZGlmaWVkTGluZXMpO1xuICAgIGNvbnN0IHJlcGxhY2VtZW50cyA9IFtdO1xuICAgIGZvciAoY29uc3QgY2hhbmdlIG9mIGxpbmVzRGlmZi5jaGFuZ2VzKSB7XG4gICAgICAgIF9hcHBlbmRDaGFuZ2VSZXBsYWNlbWVudHMoY2hhbmdlLCBvcmlnaW5hbCwgbW9kaWZpZWQsIG9yaWdpbmFsTGluZXMsIG1vZGlmaWVkTGluZXMsIG9yaWdpbmFsTGluZVN0YXJ0cywgbW9kaWZpZWRMaW5lU3RhcnRzLCByZXBsYWNlbWVudHMpO1xuICAgIH1cbiAgICBjb25zdCBlZGl0cyA9IEFubm90YXRlZFN0cmluZ0VkaXQub2YocmVwbGFjZW1lbnRzKTtcbiAgICBjb25zdCBtb3ZlcyA9IGxpbmVzRGlmZi5tb3Zlcy5tYXAobSA9PiBfYWRhcHRNb3ZlKG0sIG9yaWdpbmFsLCBtb2RpZmllZCwgb3JpZ2luYWxMaW5lcywgbW9kaWZpZWRMaW5lcywgb3JpZ2luYWxMaW5lU3RhcnRzLCBtb2RpZmllZExpbmVTdGFydHMpKTtcbiAgICByZXR1cm4gbmV3IERpZmZSZXN1bHQoZWRpdHMsIG1vdmVzLCBsaW5lc0RpZmYuaGl0VGltZW91dCk7XG59XG5mdW5jdGlvbiBfYXBwZW5kQ2hhbmdlUmVwbGFjZW1lbnRzKGNoYW5nZSwgb3JpZ2luYWwsIG1vZGlmaWVkLCBvcmlnaW5hbExpbmVzLCBtb2RpZmllZExpbmVzLCBvcmlnaW5hbExpbmVTdGFydHMsIG1vZGlmaWVkTGluZVN0YXJ0cywgb3V0KSB7XG4gICAgaWYgKGNoYW5nZS5pbm5lckNoYW5nZXMgJiYgY2hhbmdlLmlubmVyQ2hhbmdlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvciAoY29uc3QgaWMgb2YgY2hhbmdlLmlubmVyQ2hhbmdlcykge1xuICAgICAgICAgICAgY29uc3Qgb3JpZ1JhbmdlID0gX3JhbmdlVG9PZmZzZXRSYW5nZShpYy5vcmlnaW5hbFJhbmdlLCBvcmlnaW5hbCwgb3JpZ2luYWxMaW5lcywgb3JpZ2luYWxMaW5lU3RhcnRzKTtcbiAgICAgICAgICAgIGNvbnN0IG1vZFJhbmdlID0gX3JhbmdlVG9PZmZzZXRSYW5nZShpYy5tb2RpZmllZFJhbmdlLCBtb2RpZmllZCwgbW9kaWZpZWRMaW5lcywgbW9kaWZpZWRMaW5lU3RhcnRzKTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1RleHQgPSBtb2RpZmllZC5zdWJzdHJpbmcobW9kUmFuZ2Uuc3RhcnQsIG1vZFJhbmdlLmVuZEV4Y2x1c2l2ZSk7XG4gICAgICAgICAgICBvdXQucHVzaChuZXcgQW5ub3RhdGVkU3RyaW5nUmVwbGFjZW1lbnQob3JpZ1JhbmdlLCBuZXdUZXh0LCBEaWZmQW5ub3RhdGlvbi5jaGFuZ2UpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIEZhbGxiYWNrOiBubyBpbm5lciBkZXRhaWwg4oCUIHJlcGxhY2UgdGhlIHdob2xlIGxpbmUgcmFuZ2UuXG4gICAgY29uc3Qgb3JpZ1JhbmdlID0gX2xpbmVSYW5nZVRvT2Zmc2V0UmFuZ2UoY2hhbmdlLm9yaWdpbmFsLnN0YXJ0TGluZU51bWJlciwgY2hhbmdlLm9yaWdpbmFsLmVuZExpbmVOdW1iZXJFeGNsdXNpdmUsIG9yaWdpbmFsLCBvcmlnaW5hbExpbmVTdGFydHMpO1xuICAgIGNvbnN0IG1vZFJhbmdlID0gX2xpbmVSYW5nZVRvT2Zmc2V0UmFuZ2UoY2hhbmdlLm1vZGlmaWVkLnN0YXJ0TGluZU51bWJlciwgY2hhbmdlLm1vZGlmaWVkLmVuZExpbmVOdW1iZXJFeGNsdXNpdmUsIG1vZGlmaWVkLCBtb2RpZmllZExpbmVTdGFydHMpO1xuICAgIGNvbnN0IG5ld1RleHQgPSBtb2RpZmllZC5zdWJzdHJpbmcobW9kUmFuZ2Uuc3RhcnQsIG1vZFJhbmdlLmVuZEV4Y2x1c2l2ZSk7XG4gICAgb3V0LnB1c2gobmV3IEFubm90YXRlZFN0cmluZ1JlcGxhY2VtZW50KG9yaWdSYW5nZSwgbmV3VGV4dCwgRGlmZkFubm90YXRpb24uY2hhbmdlKSk7XG59XG5mdW5jdGlvbiBfYWRhcHRNb3ZlKG1vdmUsIG9yaWdpbmFsLCBtb2RpZmllZCwgb3JpZ2luYWxMaW5lcywgbW9kaWZpZWRMaW5lcywgb3JpZ2luYWxMaW5lU3RhcnRzLCBtb2RpZmllZExpbmVTdGFydHMpIHtcbiAgICBjb25zdCBvcmlnUmFuZ2UgPSBfbGluZVJhbmdlVG9PZmZzZXRSYW5nZShtb3ZlLmxpbmVSYW5nZU1hcHBpbmcub3JpZ2luYWwuc3RhcnRMaW5lTnVtYmVyLCBtb3ZlLmxpbmVSYW5nZU1hcHBpbmcub3JpZ2luYWwuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSwgb3JpZ2luYWwsIG9yaWdpbmFsTGluZVN0YXJ0cyk7XG4gICAgY29uc3QgbW9kUmFuZ2UgPSBfbGluZVJhbmdlVG9PZmZzZXRSYW5nZShtb3ZlLmxpbmVSYW5nZU1hcHBpbmcubW9kaWZpZWQuc3RhcnRMaW5lTnVtYmVyLCBtb3ZlLmxpbmVSYW5nZU1hcHBpbmcubW9kaWZpZWQuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSwgbW9kaWZpZWQsIG1vZGlmaWVkTGluZVN0YXJ0cyk7XG4gICAgLy8gQnVpbGQgaW5uZXIgZWRpdCB3aXRoIG9mZnNldHMgbG9jYWwgdG8gdGhlIG1vdmVkIHNsaWNlcy5cbiAgICBjb25zdCBpbm5lciA9IFtdO1xuICAgIGZvciAoY29uc3QgY2hhbmdlIG9mIG1vdmUuY2hhbmdlcykge1xuICAgICAgICBpZiAoY2hhbmdlLmlubmVyQ2hhbmdlcyAmJiBjaGFuZ2UuaW5uZXJDaGFuZ2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaWMgb2YgY2hhbmdlLmlubmVyQ2hhbmdlcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGdsb2JhbE9yaWcgPSBfcmFuZ2VUb09mZnNldFJhbmdlKGljLm9yaWdpbmFsUmFuZ2UsIG9yaWdpbmFsLCBvcmlnaW5hbExpbmVzLCBvcmlnaW5hbExpbmVTdGFydHMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGdsb2JhbE1vZCA9IF9yYW5nZVRvT2Zmc2V0UmFuZ2UoaWMubW9kaWZpZWRSYW5nZSwgbW9kaWZpZWQsIG1vZGlmaWVkTGluZXMsIG1vZGlmaWVkTGluZVN0YXJ0cyk7XG4gICAgICAgICAgICAgICAgaW5uZXIucHVzaChuZXcgU3RyaW5nUmVwbGFjZW1lbnQobmV3IE9mZnNldFJhbmdlKGdsb2JhbE9yaWcuc3RhcnQgLSBvcmlnUmFuZ2Uuc3RhcnQsIGdsb2JhbE9yaWcuZW5kRXhjbHVzaXZlIC0gb3JpZ1JhbmdlLnN0YXJ0KSwgbW9kaWZpZWQuc3Vic3RyaW5nKGdsb2JhbE1vZC5zdGFydCwgZ2xvYmFsTW9kLmVuZEV4Y2x1c2l2ZSkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGdsb2JhbE9yaWcgPSBfbGluZVJhbmdlVG9PZmZzZXRSYW5nZShjaGFuZ2Uub3JpZ2luYWwuc3RhcnRMaW5lTnVtYmVyLCBjaGFuZ2Uub3JpZ2luYWwuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSwgb3JpZ2luYWwsIG9yaWdpbmFsTGluZVN0YXJ0cyk7XG4gICAgICAgICAgICBjb25zdCBnbG9iYWxNb2QgPSBfbGluZVJhbmdlVG9PZmZzZXRSYW5nZShjaGFuZ2UubW9kaWZpZWQuc3RhcnRMaW5lTnVtYmVyLCBjaGFuZ2UubW9kaWZpZWQuZW5kTGluZU51bWJlckV4Y2x1c2l2ZSwgbW9kaWZpZWQsIG1vZGlmaWVkTGluZVN0YXJ0cyk7XG4gICAgICAgICAgICBpbm5lci5wdXNoKG5ldyBTdHJpbmdSZXBsYWNlbWVudChuZXcgT2Zmc2V0UmFuZ2UoZ2xvYmFsT3JpZy5zdGFydCAtIG9yaWdSYW5nZS5zdGFydCwgZ2xvYmFsT3JpZy5lbmRFeGNsdXNpdmUgLSBvcmlnUmFuZ2Uuc3RhcnQpLCBtb2RpZmllZC5zdWJzdHJpbmcoZ2xvYmFsTW9kLnN0YXJ0LCBnbG9iYWxNb2QuZW5kRXhjbHVzaXZlKSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgTW92ZShuZXcgT2Zmc2V0UmFuZ2VNYXBwaW5nKG9yaWdSYW5nZSwgbW9kUmFuZ2UpLCBTdHJpbmdFZGl0Lm9mKGlubmVyKSk7XG59XG4vLyAtLS0tLSBvZmZzZXQvbGluZSBoZWxwZXJzIC0tLS0tXG5mdW5jdGlvbiBfY29tcHV0ZUxpbmVTdGFydHMobGluZXMpIHtcbiAgICAvLyBPZmZzZXRzIGNvcnJlc3BvbmQgdG8gYGxpbmVzLmpvaW4oJ1xcbicpYCwgd2hpY2ggZXF1YWxzIHRoZSBpbnB1dCBzdHJpbmdcbiAgICAvLyB3aGVuIHRoZSBpbnB1dCB3YXMgc3BsaXQgYnkgYFxcbmAuXG4gICAgY29uc3Qgc3RhcnRzID0gbmV3IEFycmF5KGxpbmVzLmxlbmd0aCArIDEpO1xuICAgIHN0YXJ0c1swXSA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBzdGFydHNbaSArIDFdID0gc3RhcnRzW2ldICsgbGluZXNbaV0ubGVuZ3RoICsgMTsgLy8gKzEgZm9yIHRoZSAnXFxuJ1xuICAgIH1cbiAgICAvLyBgc3RhcnRzW2xpbmVzLmxlbmd0aF1gIGlzIG9uZSBwYXN0IHRoZSBzeW50aGV0aWMgdHJhaWxpbmcgbmV3bGluZTsgdGhlXG4gICAgLy8gcmVhbCB0ZXh0IGVuZHMgb25lIGVhcmxpZXIgd2hlbiB0aGVyZSBpcyBubyB0cmFpbGluZyBuZXdsaW5lICh3aGljaCBpc1xuICAgIC8vIHdoYXQgYHNwbGl0KCdcXG4nKWAgcHJvZHVjZXMgZm9yIG5vbi1uZXdsaW5lLXRlcm1pbmF0ZWQgaW5wdXQpLlxuICAgIHJldHVybiBzdGFydHM7XG59XG5mdW5jdGlvbiBfbGluZVJhbmdlVG9PZmZzZXRSYW5nZShzdGFydExpbmVOdW1iZXIsIGVuZExpbmVOdW1iZXJFeGNsdXNpdmUsIHRleHQsIGxpbmVTdGFydHMpIHtcbiAgICBjb25zdCBzdGFydCA9IF9saW5lQ29sVG9PZmZzZXQoc3RhcnRMaW5lTnVtYmVyLCAxLCB0ZXh0LCBsaW5lU3RhcnRzKTtcbiAgICBjb25zdCBlbmQgPSBfbGluZUNvbFRvT2Zmc2V0KGVuZExpbmVOdW1iZXJFeGNsdXNpdmUsIDEsIHRleHQsIGxpbmVTdGFydHMpO1xuICAgIHJldHVybiBuZXcgT2Zmc2V0UmFuZ2Uoc3RhcnQsIGVuZCk7XG59XG5mdW5jdGlvbiBfcmFuZ2VUb09mZnNldFJhbmdlKHJhbmdlLCB0ZXh0LCBsaW5lcywgbGluZVN0YXJ0cykge1xuICAgIGNvbnN0IHN0YXJ0ID0gX2xpbmVDb2xUb09mZnNldChyYW5nZS5zdGFydExpbmVOdW1iZXIsIHJhbmdlLnN0YXJ0Q29sdW1uLCB0ZXh0LCBsaW5lU3RhcnRzKTtcbiAgICBjb25zdCBlbmQgPSBfbGluZUNvbFRvT2Zmc2V0KHJhbmdlLmVuZExpbmVOdW1iZXIsIHJhbmdlLmVuZENvbHVtbiwgdGV4dCwgbGluZVN0YXJ0cyk7XG4gICAgcmV0dXJuIG5ldyBPZmZzZXRSYW5nZShzdGFydCwgZW5kKTtcbn1cbmZ1bmN0aW9uIF9saW5lQ29sVG9PZmZzZXQobGluZU51bWJlciwgY29sdW1uLCB0ZXh0LCBsaW5lU3RhcnRzKSB7XG4gICAgLy8gYGxpbmVOdW1iZXJgIGFuZCBgY29sdW1uYCBhcmUgMS1iYXNlZDsgYGVuZExpbmVOdW1iZXJFeGNsdXNpdmVgIGNhbiBiZVxuICAgIC8vIGBsaW5lcy5sZW5ndGggKyAxYCAob25lIHBhc3QgdGhlIGxhc3QgbGluZSkuXG4gICAgaWYgKGxpbmVOdW1iZXIgPD0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgaWYgKGxpbmVOdW1iZXIgPiBsaW5lU3RhcnRzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdGV4dC5sZW5ndGg7XG4gICAgfVxuICAgIGNvbnN0IGJhc2UgPSBsaW5lU3RhcnRzW2xpbmVOdW1iZXIgLSAxXTtcbiAgICBjb25zdCBvZmZzZXQgPSBiYXNlICsgKGNvbHVtbiAtIDEpO1xuICAgIHJldHVybiBNYXRoLm1pbihNYXRoLm1heChvZmZzZXQsIDApLCB0ZXh0Lmxlbmd0aCk7XG59XG5cbi8qKlxuICogTWFpbi10aHJlYWQgY2xpZW50IGZvciB0aGUgZGlmZiB3b3JrZXIuIEV4cG9zZXMgYW4gYXN5bmMgYElBc3luY0RpZmZDb21wdXRlcmAuXG4gKlxuICogSW5wdXRzIHRyYXZlbCBhcyBgc3RyaW5nW11gIHZpYSBzdHJ1Y3R1cmVkLWNsb25lIHBvc3RNZXNzYWdlLiBUaGUgcmVzcG9uc2VcbiAqIGlzIGEgc21hbGwgSlNPTi1mcmllbmRseSBgV2lyZUxpbmVzRGlmZmA7IHRoZSBtYWluIHRocmVhZCByZWNvbnN0cnVjdHMgdGhlXG4gKiBmdWxsIGBMaW5lc0RpZmZgIGFuZCBydW5zIGBfYWRhcHRMaW5lc0RpZmZgIGxvY2FsbHkgKGl0IGFscmVhZHkgaGFzIHRoZVxuICogaW5wdXQgc3RyaW5ncykuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdvcmtlckRpZmZDb21wdXRlcihvcHRzID0ge30pIHtcbiAgICBjb25zdCB3b3JrZXIgPSBvcHRzLndvcmtlckZhY3RvcnkgPyBvcHRzLndvcmtlckZhY3RvcnkoKSA6IGRlZmF1bHRXb3JrZXJGYWN0b3J5KCk7XG4gICAgY29uc3QgYmFja2VuZCA9IG9wdHMudXNlV2FzbSA/ICd3YXNtJyA6ICd0cyc7XG4gICAgY29uc3QgY29tcHV0ZXIgPSBuZXcgX1dvcmtlckRpZmZDb21wdXRlcih3b3JrZXIsIGJhY2tlbmQpO1xuICAgIGF3YWl0IGNvbXB1dGVyLmluaXQoKTtcbiAgICByZXR1cm4gY29tcHV0ZXI7XG59XG5mdW5jdGlvbiBkZWZhdWx0V29ya2VyRmFjdG9yeSgpIHtcbiAgICAvLyBUaGUgYD9lc21gIG1hcmtlciBpcyBhdXRvLWRpc2NvdmVyZWQgYnkgYEB2c2NvZGUvKi1wbHVnaW4tZXNtLXVybGBcbiAgICAvLyBidW5kbGVyIHBsdWdpbnM7IHRoZXkgZW1pdCBgd29ya2VyLnRzYCBhcyBhIHNpYmxpbmcgYHdvcmtlci5qc2AgYnVuZGxlXG4gICAgLy8gYW5kIHJld3JpdGUgdGhpcyBVUkwgYWNjb3JkaW5nbHkuXG4gICAgcmV0dXJuIG5ldyBXb3JrZXIobmV3IFVSTCgnd29ya2VyLmpzP2VzbScsIGltcG9ydC5tZXRhLnVybCksIHsgdHlwZTogJ21vZHVsZScgfSk7XG59XG5jbGFzcyBfV29ya2VyRGlmZkNvbXB1dGVyIHtcbiAgICBfd29ya2VyO1xuICAgIF9iYWNrZW5kO1xuICAgIF9uZXh0SWQgPSAxO1xuICAgIF9wZW5kaW5nID0gbmV3IE1hcCgpO1xuICAgIF9wZW5kaW5nSW5pdCA9IG51bGw7XG4gICAgX2Rpc3Bvc2VkID0gZmFsc2U7XG4gICAgY29uc3RydWN0b3IoX3dvcmtlciwgX2JhY2tlbmQpIHtcbiAgICAgICAgdGhpcy5fd29ya2VyID0gX3dvcmtlcjtcbiAgICAgICAgdGhpcy5fYmFja2VuZCA9IF9iYWNrZW5kO1xuICAgICAgICB0aGlzLl93b3JrZXIuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIChldikgPT4ge1xuICAgICAgICAgICAgdGhpcy5fb25NZXNzYWdlKGV2LmRhdGEpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fd29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgKGV2KSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9mYWlsQWxsKG5ldyBFcnJvcihgV29ya2VyIGVycm9yOiAke2V2Lm1lc3NhZ2UgPz8gJ3Vua25vd24nfWApKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGluaXQoKSB7XG4gICAgICAgIGNvbnN0IGlkID0gdGhpcy5fbmV4dElkKys7XG4gICAgICAgIGNvbnN0IHJlcSA9IHsga2luZDogJ2luaXQnLCBpZCwgYmFja2VuZDogdGhpcy5fYmFja2VuZCB9O1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcGVuZGluZ0luaXQgPSB7IHJlc29sdmUsIHJlamVjdCB9O1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLnBvc3RNZXNzYWdlKHJlcSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBjb21wdXRlRGlmZihvcmlnaW5hbCwgbW9kaWZpZWQsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBpZiAodGhpcy5fZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ1dvcmtlciBjb21wdXRlciBkaXNwb3NlZCcpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpZCA9IHRoaXMuX25leHRJZCsrO1xuICAgICAgICBjb25zdCBvcmlnaW5hbExpbmVzID0gb3JpZ2luYWwuc3BsaXQoJ1xcbicpO1xuICAgICAgICBjb25zdCBtb2RpZmllZExpbmVzID0gbW9kaWZpZWQuc3BsaXQoJ1xcbicpO1xuICAgICAgICBjb25zdCBtc2cgPSB7XG4gICAgICAgICAgICBraW5kOiAnY29tcHV0ZURpZmYnLFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBiYWNrZW5kOiB0aGlzLl9iYWNrZW5kLFxuICAgICAgICAgICAgb3JpZ2luYWxMaW5lcyxcbiAgICAgICAgICAgIG1vZGlmaWVkTGluZXMsXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcGVuZGluZy5zZXQoaWQsIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlLFxuICAgICAgICAgICAgICAgIHJlamVjdCxcbiAgICAgICAgICAgICAgICBvcmlnaW5hbCxcbiAgICAgICAgICAgICAgICBtb2RpZmllZCxcbiAgICAgICAgICAgICAgICBvcmlnaW5hbExpbmVzLFxuICAgICAgICAgICAgICAgIG1vZGlmaWVkTGluZXMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtlci5wb3N0TWVzc2FnZShtc2cpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2Rpc3Bvc2VkKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB0aGlzLl9kaXNwb3NlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuX2ZhaWxBbGwobmV3IEVycm9yKCdXb3JrZXIgY29tcHV0ZXIgZGlzcG9zZWQnKSk7XG4gICAgICAgIHRoaXMuX3dvcmtlci50ZXJtaW5hdGUoKTtcbiAgICB9XG4gICAgX29uTWVzc2FnZShtc2cpIHtcbiAgICAgICAgaWYgKG1zZy5raW5kID09PSAnaW5pdCcpIHtcbiAgICAgICAgICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLl9wZW5kaW5nSW5pdDtcbiAgICAgICAgICAgIHRoaXMuX3BlbmRpbmdJbml0ID0gbnVsbDtcbiAgICAgICAgICAgIHBlbmRpbmc/LnJlc29sdmUoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBlbnRyeSA9IHRoaXMuX3BlbmRpbmcuZ2V0KG1zZy5pZCk7XG4gICAgICAgIGlmICghZW50cnkpIHtcbiAgICAgICAgICAgIC8vIEluaXQgZmFpbHVyZSBpcyByZXBvcnRlZCBvbiB0aGUgaW5pdCBpZCB3aXRoIGBraW5kID09PSAnY29tcHV0ZURpZmYnYFxuICAgICAgICAgICAgLy8gYW5kIGBvayA9PT0gZmFsc2VgOyByb3V0ZSB0byB0aGUgaW5pdCBwcm9taXNlIGlmIGl0J3Mgc3RpbGwgcGVuZGluZy5cbiAgICAgICAgICAgIGlmICghbXNnLm9rICYmIHRoaXMuX3BlbmRpbmdJbml0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcCA9IHRoaXMuX3BlbmRpbmdJbml0O1xuICAgICAgICAgICAgICAgIHRoaXMuX3BlbmRpbmdJbml0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICBwLnJlamVjdChuZXcgRXJyb3IobXNnLmVycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcGVuZGluZy5kZWxldGUobXNnLmlkKTtcbiAgICAgICAgaWYgKCFtc2cub2spIHtcbiAgICAgICAgICAgIGVudHJ5LnJlamVjdChuZXcgRXJyb3IobXNnLmVycm9yKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGxpbmVzRGlmZiA9IHdpcmVUb0xpbmVzRGlmZihtc2cucmVzdWx0KTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IF9hZGFwdExpbmVzRGlmZihsaW5lc0RpZmYsIGVudHJ5Lm9yaWdpbmFsLCBlbnRyeS5tb2RpZmllZCwgZW50cnkub3JpZ2luYWxMaW5lcywgZW50cnkubW9kaWZpZWRMaW5lcyk7XG4gICAgICAgICAgICBlbnRyeS5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgZW50cnkucmVqZWN0KGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyIDogbmV3IEVycm9yKFN0cmluZyhlcnIpKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX2ZhaWxBbGwoZXJyKSB7XG4gICAgICAgIGZvciAoY29uc3QgcCBvZiB0aGlzLl9wZW5kaW5nLnZhbHVlcygpKVxuICAgICAgICAgICAgcC5yZWplY3QoZXJyKTtcbiAgICAgICAgdGhpcy5fcGVuZGluZy5jbGVhcigpO1xuICAgICAgICBpZiAodGhpcy5fcGVuZGluZ0luaXQpIHtcbiAgICAgICAgICAgIHRoaXMuX3BlbmRpbmdJbml0LnJlamVjdChlcnIpO1xuICAgICAgICAgICAgdGhpcy5fcGVuZGluZ0luaXQgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgeyBBbm5vdGF0ZWRTdHJpbmdFZGl0LCBBbm5vdGF0ZWRTdHJpbmdSZXBsYWNlbWVudCwgRGlmZkFubm90YXRpb24sIERpZmZSZXN1bHQsIE1vdmUsIE9mZnNldFJhbmdlLCBPZmZzZXRSYW5nZU1hcHBpbmcsIFN0cmluZ0VkaXQsIFN0cmluZ1JlcGxhY2VtZW50LCBEZWZhdWx0TGluZXNEaWZmQ29tcHV0ZXIgYXMgX0RlZmF1bHRMaW5lc0RpZmZDb21wdXRlciwgRGV0YWlsZWRMaW5lUmFuZ2VNYXBwaW5nIGFzIF9EZXRhaWxlZExpbmVSYW5nZU1hcHBpbmcsIExpbmVSYW5nZSBhcyBfTGluZVJhbmdlLCBMaW5lc0RpZmYgYXMgX0xpbmVzRGlmZiwgUmFuZ2VNYXBwaW5nIGFzIF9SYW5nZU1hcHBpbmcsIGdldFdhc20gYXMgX2dldFdhc20sIGluaXRXYXNtIGFzIF9pbml0V2FzbSwgY3JlYXRlRGlmZkNvbXB1dGVyLCBjcmVhdGVXb3JrZXJEaWZmQ29tcHV0ZXIgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcFxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9