aws-cdk 2.1001.0 → 2.1002.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/README.md +15 -0
- package/THIRD_PARTY_LICENSES +41 -41
- package/build-info.json +2 -2
- package/lib/api/bootstrap/bootstrap-template.yaml +3 -1
- package/lib/api/deployments/deploy-stack.d.ts +0 -20
- package/lib/api/deployments/deploy-stack.js +25 -20
- package/lib/api/deployments/deployments.d.ts +0 -27
- package/lib/api/deployments/deployments.js +13 -13
- package/lib/api/resource-import/importer.d.ts +0 -8
- package/lib/api/resource-import/importer.js +1 -1
- package/lib/api/resource-import/migrator.js +1 -2
- package/lib/api/stack-events/stack-activity-monitor.d.ts +87 -165
- package/lib/api/stack-events/stack-activity-monitor.js +61 -445
- package/lib/api/stack-events/stack-event-poller.d.ts +6 -0
- package/lib/api/stack-events/stack-event-poller.js +1 -1
- package/lib/api/stack-events/stack-progress-monitor.d.ts +61 -0
- package/lib/api/stack-events/stack-progress-monitor.js +94 -0
- package/lib/api/work-graph/work-graph-builder.js +4 -4
- package/lib/cli/activity-printer/base.d.ts +51 -0
- package/lib/cli/activity-printer/base.js +115 -0
- package/lib/cli/activity-printer/current.d.ts +25 -0
- package/lib/cli/activity-printer/current.js +122 -0
- package/lib/cli/activity-printer/history.d.ts +31 -0
- package/lib/cli/activity-printer/history.js +109 -0
- package/lib/cli/activity-printer/index.d.ts +3 -0
- package/lib/cli/activity-printer/index.js +20 -0
- package/lib/cli/cdk-toolkit.d.ts +1 -1
- package/lib/cli/cdk-toolkit.js +10 -9
- package/lib/cli/cli-config.js +5 -4
- package/lib/cli/cli.js +3 -1
- package/lib/cli/convert-to-user-input.js +18 -16
- package/lib/cli/parse-command-line-arguments.js +7 -1
- package/lib/cli/user-input.d.ts +8 -0
- package/lib/cli/user-input.js +1 -1
- package/lib/commands/deploy.d.ts +13 -0
- package/lib/commands/deploy.js +18 -0
- package/lib/context-providers/cc-api-provider.js +2 -2
- package/lib/index.js +18101 -16933
- package/lib/init.d.ts +5 -1
- package/lib/init.js +11 -8
- package/lib/legacy-exports-source.d.ts +1 -1
- package/lib/legacy-exports-source.js +2 -2
- package/lib/notices.js +2 -2
- package/lib/toolkit/cli-io-host.d.ts +28 -0
- package/lib/toolkit/cli-io-host.js +74 -2
- package/lib/toolkit/error.d.ts +1 -44
- package/lib/toolkit/error.js +16 -76
- package/lib/util/cloudformation.d.ts +12 -0
- package/lib/util/cloudformation.js +27 -1
- package/lib/util/string-manipulation.d.ts +5 -1
- package/lib/util/string-manipulation.js +11 -5
- package/package.json +25 -24
- /package/lib/{api/stack-events → cli/activity-printer}/display.d.ts +0 -0
- /package/lib/{api/stack-events → cli/activity-printer}/display.js +0 -0
|
@@ -1,108 +1,83 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.StackActivityMonitor = void 0;
|
|
4
4
|
const util = require("util");
|
|
5
5
|
const cloud_assembly_schema_1 = require("@aws-cdk/cloud-assembly-schema");
|
|
6
|
-
const
|
|
6
|
+
const uuid = require("uuid");
|
|
7
7
|
const stack_event_poller_1 = require("./stack-event-poller");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
/**
|
|
12
|
-
* Supported display modes for stack deployment activity
|
|
13
|
-
*/
|
|
14
|
-
var StackActivityProgress;
|
|
15
|
-
(function (StackActivityProgress) {
|
|
16
|
-
/**
|
|
17
|
-
* Displays a progress bar with only the events for the resource currently being deployed
|
|
18
|
-
*/
|
|
19
|
-
StackActivityProgress["BAR"] = "bar";
|
|
20
|
-
/**
|
|
21
|
-
* Displays complete history with all CloudFormation stack events
|
|
22
|
-
*/
|
|
23
|
-
StackActivityProgress["EVENTS"] = "events";
|
|
24
|
-
})(StackActivityProgress || (exports.StackActivityProgress = StackActivityProgress = {}));
|
|
8
|
+
const messages_1 = require("../../cli/messages");
|
|
9
|
+
const util_1 = require("../../util");
|
|
10
|
+
const stack_progress_monitor_1 = require("./stack-progress-monitor");
|
|
25
11
|
class StackActivityMonitor {
|
|
26
|
-
|
|
27
|
-
* Create a Stack Activity Monitor using a default printer, based on context clues
|
|
28
|
-
*/
|
|
29
|
-
static withDefaultPrinter(cfn, stackName, stackArtifact, options = {}) {
|
|
30
|
-
var _a, _b;
|
|
31
|
-
const stream = options.ci ? process.stdout : process.stderr;
|
|
32
|
-
const props = {
|
|
33
|
-
resourceTypeColumnWidth: calcMaxResourceTypeLength(stackArtifact.template),
|
|
34
|
-
resourcesTotal: options.resourcesTotal,
|
|
35
|
-
stream,
|
|
36
|
-
};
|
|
37
|
-
const isWindows = process.platform === 'win32';
|
|
38
|
-
const verbose = (_a = options.logLevel) !== null && _a !== void 0 ? _a : 'info';
|
|
39
|
-
// On some CI systems (such as CircleCI) output still reports as a TTY so we also
|
|
40
|
-
// need an individual check for whether we're running on CI.
|
|
41
|
-
// see: https://discuss.circleci.com/t/circleci-terminal-is-a-tty-but-term-is-not-set/9965
|
|
42
|
-
const fancyOutputAvailable = !isWindows && stream.isTTY && !options.ci;
|
|
43
|
-
const progress = (_b = options.progress) !== null && _b !== void 0 ? _b : StackActivityProgress.BAR;
|
|
44
|
-
const printer = fancyOutputAvailable && !verbose && progress === StackActivityProgress.BAR
|
|
45
|
-
? new CurrentActivityPrinter(props)
|
|
46
|
-
: new HistoryActivityPrinter(props);
|
|
47
|
-
return new StackActivityMonitor(cfn, stackName, printer, stackArtifact, options.changeSetCreationTime);
|
|
48
|
-
}
|
|
49
|
-
constructor(cfn, stackName, printer, stack, changeSetCreationTime) {
|
|
12
|
+
constructor({ cfn, ioHost, action, stack, stackName, resourcesTotal, changeSetCreationTime, pollingInterval = 2000, }) {
|
|
50
13
|
var _a;
|
|
51
|
-
this.stackName = stackName;
|
|
52
|
-
this.printer = printer;
|
|
53
|
-
this.stack = stack;
|
|
54
14
|
this.errors = [];
|
|
55
|
-
this.
|
|
15
|
+
this.ioHost = ioHost;
|
|
16
|
+
this.action = action;
|
|
17
|
+
this.stack = stack;
|
|
18
|
+
this.stackName = stackName;
|
|
19
|
+
this.progressMonitor = new stack_progress_monitor_1.StackProgressMonitor(resourcesTotal);
|
|
20
|
+
this.pollingInterval = pollingInterval;
|
|
56
21
|
this.poller = new stack_event_poller_1.StackEventPoller(cfn, {
|
|
57
22
|
stackName,
|
|
58
23
|
startTime: (_a = changeSetCreationTime === null || changeSetCreationTime === void 0 ? void 0 : changeSetCreationTime.getTime()) !== null && _a !== void 0 ? _a : Date.now(),
|
|
59
24
|
});
|
|
60
25
|
}
|
|
61
|
-
start() {
|
|
62
|
-
this.
|
|
63
|
-
this.
|
|
26
|
+
async start() {
|
|
27
|
+
this.monitorId = uuid.v4();
|
|
28
|
+
await this.ioHost.notify((0, messages_1.debug)(this.action, `Deploying ${this.stackName}`, 'CDK_TOOLKIT_I5501', {
|
|
29
|
+
deployment: this.monitorId,
|
|
30
|
+
stack: this.stack,
|
|
31
|
+
stackName: this.stackName,
|
|
32
|
+
resourcesTotal: this.progressMonitor.total,
|
|
33
|
+
}));
|
|
64
34
|
this.scheduleNextTick();
|
|
65
35
|
return this;
|
|
66
36
|
}
|
|
67
37
|
async stop() {
|
|
68
|
-
|
|
38
|
+
const oldMonitorId = this.monitorId;
|
|
39
|
+
this.monitorId = undefined;
|
|
69
40
|
if (this.tickTimer) {
|
|
70
41
|
clearTimeout(this.tickTimer);
|
|
71
42
|
}
|
|
72
43
|
// Do a final poll for all events. This is to handle the situation where DescribeStackStatus
|
|
73
44
|
// already returned an error, but the monitor hasn't seen all the events yet and we'd end
|
|
74
45
|
// up not printing the failure reason to users.
|
|
75
|
-
await this.finalPollToEnd();
|
|
76
|
-
this.
|
|
46
|
+
await this.finalPollToEnd(oldMonitorId);
|
|
47
|
+
await this.ioHost.notify((0, messages_1.debug)(this.action, `Completed ${this.stackName}`, 'CDK_TOOLKIT_I5503', {
|
|
48
|
+
deployment: oldMonitorId,
|
|
49
|
+
stack: this.stack,
|
|
50
|
+
stackName: this.stackName,
|
|
51
|
+
resourcesTotal: this.progressMonitor.total,
|
|
52
|
+
}));
|
|
77
53
|
}
|
|
78
54
|
scheduleNextTick() {
|
|
79
|
-
if (!this.
|
|
55
|
+
if (!this.monitorId) {
|
|
80
56
|
return;
|
|
81
57
|
}
|
|
82
|
-
this.tickTimer = setTimeout(() => void this.tick(), this.
|
|
58
|
+
this.tickTimer = setTimeout(() => void this.tick(), this.pollingInterval);
|
|
83
59
|
}
|
|
84
60
|
async tick() {
|
|
85
|
-
if (!this.
|
|
61
|
+
if (!this.monitorId) {
|
|
86
62
|
return;
|
|
87
63
|
}
|
|
88
64
|
try {
|
|
89
|
-
this.readPromise = this.readNewEvents();
|
|
65
|
+
this.readPromise = this.readNewEvents(this.monitorId);
|
|
90
66
|
await this.readPromise;
|
|
91
67
|
this.readPromise = undefined;
|
|
92
68
|
// We might have been stop()ped while the network call was in progress.
|
|
93
|
-
if (!this.
|
|
69
|
+
if (!this.monitorId) {
|
|
94
70
|
return;
|
|
95
71
|
}
|
|
96
|
-
this.printer.print();
|
|
97
72
|
}
|
|
98
73
|
catch (e) {
|
|
99
|
-
(0,
|
|
74
|
+
await this.ioHost.notify((0, messages_1.error)(this.action, util.format('Error occurred while monitoring stack: %s', e), 'CDK_TOOLKIT_E5500', { error: e }));
|
|
100
75
|
}
|
|
101
76
|
this.scheduleNextTick();
|
|
102
77
|
}
|
|
103
78
|
findMetadataFor(logicalId) {
|
|
104
|
-
var _a
|
|
105
|
-
const metadata = (
|
|
79
|
+
var _a;
|
|
80
|
+
const metadata = (_a = this.stack.manifest) === null || _a === void 0 ? void 0 : _a.metadata;
|
|
106
81
|
if (!logicalId || !metadata) {
|
|
107
82
|
return undefined;
|
|
108
83
|
}
|
|
@@ -126,15 +101,18 @@ class StackActivityMonitor {
|
|
|
126
101
|
* see a next page and the last event in the page is new to us (and within the time window).
|
|
127
102
|
* haven't seen the final event
|
|
128
103
|
*/
|
|
129
|
-
async readNewEvents() {
|
|
104
|
+
async readNewEvents(monitorId) {
|
|
130
105
|
const pollEvents = await this.poller.poll();
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
106
|
+
for (const resourceEvent of pollEvents) {
|
|
107
|
+
this.progressMonitor.process(resourceEvent.event);
|
|
108
|
+
const activity = {
|
|
109
|
+
deployment: monitorId,
|
|
110
|
+
event: resourceEvent.event,
|
|
111
|
+
metadata: this.findMetadataFor(resourceEvent.event.LogicalResourceId),
|
|
112
|
+
progress: this.progressMonitor.progress,
|
|
113
|
+
};
|
|
136
114
|
this.checkForErrors(activity);
|
|
137
|
-
this.
|
|
115
|
+
await this.ioHost.notify((0, messages_1.info)(this.action, this.formatActivity(activity, true), 'CDK_TOOLKIT_I5502', activity));
|
|
138
116
|
}
|
|
139
117
|
}
|
|
140
118
|
/**
|
|
@@ -143,7 +121,7 @@ class StackActivityMonitor {
|
|
|
143
121
|
* Finish any poll currently in progress, then do a final one until we've
|
|
144
122
|
* reached the last page.
|
|
145
123
|
*/
|
|
146
|
-
async finalPollToEnd() {
|
|
124
|
+
async finalPollToEnd(monitorId) {
|
|
147
125
|
// If we were doing a poll, finish that first. It was started before
|
|
148
126
|
// the moment we were sure we weren't going to get any new events anymore
|
|
149
127
|
// so we need to do a new one anyway. Need to wait for this one though
|
|
@@ -151,11 +129,21 @@ class StackActivityMonitor {
|
|
|
151
129
|
if (this.readPromise) {
|
|
152
130
|
await this.readPromise;
|
|
153
131
|
}
|
|
154
|
-
await this.readNewEvents();
|
|
132
|
+
await this.readNewEvents(monitorId);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Formats a stack activity into a basic string
|
|
136
|
+
*/
|
|
137
|
+
formatActivity(activity, progress) {
|
|
138
|
+
const event = activity.event;
|
|
139
|
+
const metadata = activity.metadata;
|
|
140
|
+
const resourceName = metadata ? metadata.constructPath : event.LogicalResourceId || '';
|
|
141
|
+
const logicalId = resourceName !== event.LogicalResourceId ? `(${event.LogicalResourceId}) ` : '';
|
|
142
|
+
return util.format('%s | %s%s | %s | %s | %s %s%s%s', event.StackName, progress !== false ? `${activity.progress.formatted} | ` : '', new Date(event.Timestamp).toLocaleTimeString(), event.ResourceStatus || '', event.ResourceType, resourceName, logicalId, event.ResourceStatusReason ? event.ResourceStatusReason : '', (metadata === null || metadata === void 0 ? void 0 : metadata.entry.trace) ? `\n\t${metadata.entry.trace.join('\n\t\\_ ')}` : '');
|
|
155
143
|
}
|
|
156
144
|
checkForErrors(activity) {
|
|
157
145
|
var _a, _b, _c;
|
|
158
|
-
if (
|
|
146
|
+
if ((0, util_1.stackEventHasErrorMessage)((_a = activity.event.ResourceStatus) !== null && _a !== void 0 ? _a : '')) {
|
|
159
147
|
const isCancelled = ((_b = activity.event.ResourceStatusReason) !== null && _b !== void 0 ? _b : '').indexOf('cancelled') > -1;
|
|
160
148
|
// Cancelled is not an interesting failure reason, nor is the stack message (stack
|
|
161
149
|
// message will just say something like "stack failed to update")
|
|
@@ -175,376 +163,4 @@ class StackActivityMonitor {
|
|
|
175
163
|
}
|
|
176
164
|
}
|
|
177
165
|
exports.StackActivityMonitor = StackActivityMonitor;
|
|
178
|
-
function padRight(n, x) {
|
|
179
|
-
return x + ' '.repeat(Math.max(0, n - x.length));
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Infamous padLeft()
|
|
183
|
-
*/
|
|
184
|
-
function padLeft(n, x) {
|
|
185
|
-
return ' '.repeat(Math.max(0, n - x.length)) + x;
|
|
186
|
-
}
|
|
187
|
-
function calcMaxResourceTypeLength(template) {
|
|
188
|
-
const resources = (template && template.Resources) || {};
|
|
189
|
-
let maxWidth = 0;
|
|
190
|
-
for (const id of Object.keys(resources)) {
|
|
191
|
-
const type = resources[id].Type || '';
|
|
192
|
-
if (type.length > maxWidth) {
|
|
193
|
-
maxWidth = type.length;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return maxWidth;
|
|
197
|
-
}
|
|
198
|
-
class ActivityPrinterBase {
|
|
199
|
-
constructor(props) {
|
|
200
|
-
this.props = props;
|
|
201
|
-
/**
|
|
202
|
-
* Fetch new activity every 5 seconds
|
|
203
|
-
*/
|
|
204
|
-
this.updateSleep = 5000;
|
|
205
|
-
/**
|
|
206
|
-
* A list of resource IDs which are currently being processed
|
|
207
|
-
*/
|
|
208
|
-
this.resourcesInProgress = {};
|
|
209
|
-
/**
|
|
210
|
-
* Previous completion state observed by logical ID
|
|
211
|
-
*
|
|
212
|
-
* We use this to detect that if we see a DELETE_COMPLETE after a
|
|
213
|
-
* CREATE_COMPLETE, it's actually a rollback and we should DECREASE
|
|
214
|
-
* resourcesDone instead of increase it
|
|
215
|
-
*/
|
|
216
|
-
this.resourcesPrevCompleteState = {};
|
|
217
|
-
/**
|
|
218
|
-
* Count of resources that have reported a _COMPLETE status
|
|
219
|
-
*/
|
|
220
|
-
this.resourcesDone = 0;
|
|
221
|
-
/**
|
|
222
|
-
* How many digits we need to represent the total count (for lining up the status reporting)
|
|
223
|
-
*/
|
|
224
|
-
this.resourceDigits = 0;
|
|
225
|
-
this.rollingBack = false;
|
|
226
|
-
this.failures = new Array();
|
|
227
|
-
this.hookFailureMap = new Map();
|
|
228
|
-
// +1 because the stack also emits a "COMPLETE" event at the end, and that wasn't
|
|
229
|
-
// counted yet. This makes it line up with the amount of events we expect.
|
|
230
|
-
this.resourcesTotal = props.resourcesTotal ? props.resourcesTotal + 1 : undefined;
|
|
231
|
-
// How many digits does this number take to represent?
|
|
232
|
-
this.resourceDigits = this.resourcesTotal ? Math.ceil(Math.log10(this.resourcesTotal)) : 0;
|
|
233
|
-
}
|
|
234
|
-
failureReason(activity) {
|
|
235
|
-
var _a, _b;
|
|
236
|
-
const resourceStatusReason = (_a = activity.event.ResourceStatusReason) !== null && _a !== void 0 ? _a : '';
|
|
237
|
-
const logicalResourceId = (_b = activity.event.LogicalResourceId) !== null && _b !== void 0 ? _b : '';
|
|
238
|
-
const hookFailureReasonMap = this.hookFailureMap.get(logicalResourceId);
|
|
239
|
-
if (hookFailureReasonMap !== undefined) {
|
|
240
|
-
for (const hookType of hookFailureReasonMap.keys()) {
|
|
241
|
-
if (resourceStatusReason.includes(hookType)) {
|
|
242
|
-
return resourceStatusReason + ' : ' + hookFailureReasonMap.get(hookType);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
return resourceStatusReason;
|
|
247
|
-
}
|
|
248
|
-
addActivity(activity) {
|
|
249
|
-
var _a, _b, _c, _d, _e;
|
|
250
|
-
const status = activity.event.ResourceStatus;
|
|
251
|
-
const hookStatus = activity.event.HookStatus;
|
|
252
|
-
const hookType = activity.event.HookType;
|
|
253
|
-
if (!status || !activity.event.LogicalResourceId) {
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
if (status === 'ROLLBACK_IN_PROGRESS' || status === 'UPDATE_ROLLBACK_IN_PROGRESS') {
|
|
257
|
-
// Only triggered on the stack once we've started doing a rollback
|
|
258
|
-
this.rollingBack = true;
|
|
259
|
-
}
|
|
260
|
-
if (status.endsWith('_IN_PROGRESS')) {
|
|
261
|
-
this.resourcesInProgress[activity.event.LogicalResourceId] = activity;
|
|
262
|
-
}
|
|
263
|
-
if (hasErrorMessage(status)) {
|
|
264
|
-
const isCancelled = ((_a = activity.event.ResourceStatusReason) !== null && _a !== void 0 ? _a : '').indexOf('cancelled') > -1;
|
|
265
|
-
// Cancelled is not an interesting failure reason
|
|
266
|
-
if (!isCancelled) {
|
|
267
|
-
this.failures.push(activity);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
if (status.endsWith('_COMPLETE') || status.endsWith('_FAILED')) {
|
|
271
|
-
delete this.resourcesInProgress[activity.event.LogicalResourceId];
|
|
272
|
-
}
|
|
273
|
-
if (status.endsWith('_COMPLETE_CLEANUP_IN_PROGRESS')) {
|
|
274
|
-
this.resourcesDone++;
|
|
275
|
-
}
|
|
276
|
-
if (status.endsWith('_COMPLETE')) {
|
|
277
|
-
const prevState = this.resourcesPrevCompleteState[activity.event.LogicalResourceId];
|
|
278
|
-
if (!prevState) {
|
|
279
|
-
this.resourcesDone++;
|
|
280
|
-
}
|
|
281
|
-
else {
|
|
282
|
-
// If we completed this before and we're completing it AGAIN, means we're rolling back.
|
|
283
|
-
// Protect against silly underflow.
|
|
284
|
-
this.resourcesDone--;
|
|
285
|
-
if (this.resourcesDone < 0) {
|
|
286
|
-
this.resourcesDone = 0;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
this.resourcesPrevCompleteState[activity.event.LogicalResourceId] = status;
|
|
290
|
-
}
|
|
291
|
-
if (hookStatus !== undefined &&
|
|
292
|
-
hookStatus.endsWith('_COMPLETE_FAILED') &&
|
|
293
|
-
activity.event.LogicalResourceId !== undefined &&
|
|
294
|
-
hookType !== undefined) {
|
|
295
|
-
if (this.hookFailureMap.has(activity.event.LogicalResourceId)) {
|
|
296
|
-
(_b = this.hookFailureMap.get(activity.event.LogicalResourceId)) === null || _b === void 0 ? void 0 : _b.set(hookType, (_c = activity.event.HookStatusReason) !== null && _c !== void 0 ? _c : '');
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
this.hookFailureMap.set(activity.event.LogicalResourceId, new Map());
|
|
300
|
-
(_d = this.hookFailureMap.get(activity.event.LogicalResourceId)) === null || _d === void 0 ? void 0 : _d.set(hookType, (_e = activity.event.HookStatusReason) !== null && _e !== void 0 ? _e : '');
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
start() {
|
|
305
|
-
// Empty on purpose
|
|
306
|
-
}
|
|
307
|
-
stop() {
|
|
308
|
-
// Empty on purpose
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Activity Printer which shows a full log of all CloudFormation events
|
|
313
|
-
*
|
|
314
|
-
* When there hasn't been activity for a while, it will print the resources
|
|
315
|
-
* that are currently in progress, to show what's holding up the deployment.
|
|
316
|
-
*/
|
|
317
|
-
class HistoryActivityPrinter extends ActivityPrinterBase {
|
|
318
|
-
constructor(props) {
|
|
319
|
-
super(props);
|
|
320
|
-
/**
|
|
321
|
-
* Last time we printed something to the console.
|
|
322
|
-
*
|
|
323
|
-
* Used to measure timeout for progress reporting.
|
|
324
|
-
*/
|
|
325
|
-
this.lastPrintTime = Date.now();
|
|
326
|
-
/**
|
|
327
|
-
* Number of ms of change absence before we tell the user about the resources that are currently in progress.
|
|
328
|
-
*/
|
|
329
|
-
this.inProgressDelay = 30000;
|
|
330
|
-
this.printable = new Array();
|
|
331
|
-
}
|
|
332
|
-
addActivity(activity) {
|
|
333
|
-
super.addActivity(activity);
|
|
334
|
-
this.printable.push(activity);
|
|
335
|
-
this.print();
|
|
336
|
-
}
|
|
337
|
-
print() {
|
|
338
|
-
for (const activity of this.printable) {
|
|
339
|
-
this.printOne(activity);
|
|
340
|
-
}
|
|
341
|
-
this.printable.splice(0, this.printable.length);
|
|
342
|
-
this.printInProgress();
|
|
343
|
-
}
|
|
344
|
-
stop() {
|
|
345
|
-
// Print failures at the end
|
|
346
|
-
if (this.failures.length > 0) {
|
|
347
|
-
(0, logging_1.info)('\nFailed resources:');
|
|
348
|
-
for (const failure of this.failures) {
|
|
349
|
-
// Root stack failures are not interesting
|
|
350
|
-
if (failure.isStackEvent) {
|
|
351
|
-
continue;
|
|
352
|
-
}
|
|
353
|
-
this.printOne(failure, false);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
printOne(activity, progress) {
|
|
358
|
-
const event = activity.event;
|
|
359
|
-
const color = colorFromStatusResult(event.ResourceStatus);
|
|
360
|
-
let reasonColor = chalk.cyan;
|
|
361
|
-
let stackTrace = '';
|
|
362
|
-
const metadata = activity.metadata;
|
|
363
|
-
if (event.ResourceStatus && event.ResourceStatus.indexOf('FAILED') !== -1) {
|
|
364
|
-
if (progress == undefined || progress) {
|
|
365
|
-
event.ResourceStatusReason = event.ResourceStatusReason ? this.failureReason(activity) : '';
|
|
366
|
-
}
|
|
367
|
-
if (metadata) {
|
|
368
|
-
stackTrace = metadata.entry.trace ? `\n\t${metadata.entry.trace.join('\n\t\\_ ')}` : '';
|
|
369
|
-
}
|
|
370
|
-
reasonColor = chalk.red;
|
|
371
|
-
}
|
|
372
|
-
const resourceName = metadata ? metadata.constructPath : event.LogicalResourceId || '';
|
|
373
|
-
const logicalId = resourceName !== event.LogicalResourceId ? `(${event.LogicalResourceId}) ` : '';
|
|
374
|
-
(0, logging_1.info)(util.format('%s | %s%s | %s | %s | %s %s%s%s', event.StackName, progress !== false ? `${this.progress()} | ` : '', new Date(event.Timestamp).toLocaleTimeString(), color(padRight(STATUS_WIDTH, (event.ResourceStatus || '').slice(0, STATUS_WIDTH))), // pad left and trim
|
|
375
|
-
padRight(this.props.resourceTypeColumnWidth, event.ResourceType || ''), color(chalk.bold(resourceName)), logicalId, reasonColor(chalk.bold(event.ResourceStatusReason ? event.ResourceStatusReason : '')), reasonColor(stackTrace)));
|
|
376
|
-
this.lastPrintTime = Date.now();
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Report the current progress as a [34/42] string, or just [34] if the total is unknown
|
|
380
|
-
*/
|
|
381
|
-
progress() {
|
|
382
|
-
if (this.resourcesTotal == null) {
|
|
383
|
-
// Don't have total, show simple count and hope the human knows
|
|
384
|
-
return padLeft(3, util.format('%s', this.resourcesDone)); // max 500 resources
|
|
385
|
-
}
|
|
386
|
-
return util.format('%s/%s', padLeft(this.resourceDigits, this.resourcesDone.toString()), padLeft(this.resourceDigits, this.resourcesTotal != null ? this.resourcesTotal.toString() : '?'));
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* If some resources are taking a while to create, notify the user about what's currently in progress
|
|
390
|
-
*/
|
|
391
|
-
printInProgress() {
|
|
392
|
-
if (Date.now() < this.lastPrintTime + this.inProgressDelay) {
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
if (Object.keys(this.resourcesInProgress).length > 0) {
|
|
396
|
-
(0, logging_1.info)(util.format('%s Currently in progress: %s', this.progress(), chalk.bold(Object.keys(this.resourcesInProgress).join(', '))));
|
|
397
|
-
}
|
|
398
|
-
// We cheat a bit here. To prevent printInProgress() from repeatedly triggering,
|
|
399
|
-
// we set the timestamp into the future. It will be reset whenever a regular print
|
|
400
|
-
// occurs, after which we can be triggered again.
|
|
401
|
-
this.lastPrintTime = +Infinity;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
exports.HistoryActivityPrinter = HistoryActivityPrinter;
|
|
405
|
-
/**
|
|
406
|
-
* Activity Printer which shows the resources currently being updated
|
|
407
|
-
*
|
|
408
|
-
* It will continuously reupdate the terminal and show only the resources
|
|
409
|
-
* that are currently being updated, in addition to a progress bar which
|
|
410
|
-
* shows how far along the deployment is.
|
|
411
|
-
*
|
|
412
|
-
* Resources that have failed will always be shown, and will be recapitulated
|
|
413
|
-
* along with their stack trace when the monitoring ends.
|
|
414
|
-
*
|
|
415
|
-
* Resources that failed deployment because they have been cancelled are
|
|
416
|
-
* not included.
|
|
417
|
-
*/
|
|
418
|
-
class CurrentActivityPrinter extends ActivityPrinterBase {
|
|
419
|
-
constructor(props) {
|
|
420
|
-
super(props);
|
|
421
|
-
/**
|
|
422
|
-
* This looks very disorienting sleeping for 5 seconds. Update quicker.
|
|
423
|
-
*/
|
|
424
|
-
this.updateSleep = 2000;
|
|
425
|
-
this.oldLogThreshold = cli_io_host_1.CliIoHost.instance().logLevel;
|
|
426
|
-
this.stream = props.stream;
|
|
427
|
-
this.block = new display_1.RewritableBlock(this.stream);
|
|
428
|
-
}
|
|
429
|
-
print() {
|
|
430
|
-
var _a;
|
|
431
|
-
const lines = [];
|
|
432
|
-
// Add a progress bar at the top
|
|
433
|
-
const progressWidth = Math.max(Math.min(((_a = this.block.width) !== null && _a !== void 0 ? _a : 80) - PROGRESSBAR_EXTRA_SPACE - 1, MAX_PROGRESSBAR_WIDTH), MIN_PROGRESSBAR_WIDTH);
|
|
434
|
-
const prog = this.progressBar(progressWidth);
|
|
435
|
-
if (prog) {
|
|
436
|
-
lines.push(' ' + prog, '');
|
|
437
|
-
}
|
|
438
|
-
// Normally we'd only print "resources in progress", but it's also useful
|
|
439
|
-
// to keep an eye on the failures and know about the specific errors asquickly
|
|
440
|
-
// as possible (while the stack is still rolling back), so add those in.
|
|
441
|
-
const toPrint = [...this.failures, ...Object.values(this.resourcesInProgress)];
|
|
442
|
-
toPrint.sort((a, b) => a.event.Timestamp.getTime() - b.event.Timestamp.getTime());
|
|
443
|
-
lines.push(...toPrint.map((res) => {
|
|
444
|
-
var _a, _b, _c;
|
|
445
|
-
const color = colorFromStatusActivity(res.event.ResourceStatus);
|
|
446
|
-
const resourceName = (_c = (_b = (_a = res.metadata) === null || _a === void 0 ? void 0 : _a.constructPath) !== null && _b !== void 0 ? _b : res.event.LogicalResourceId) !== null && _c !== void 0 ? _c : '';
|
|
447
|
-
return util.format('%s | %s | %s | %s%s', padLeft(TIMESTAMP_WIDTH, new Date(res.event.Timestamp).toLocaleTimeString()), color(padRight(STATUS_WIDTH, (res.event.ResourceStatus || '').slice(0, STATUS_WIDTH))), padRight(this.props.resourceTypeColumnWidth, res.event.ResourceType || ''), color(chalk.bold(shorten(40, resourceName))), this.failureReasonOnNextLine(res));
|
|
448
|
-
}));
|
|
449
|
-
this.block.displayLines(lines);
|
|
450
|
-
}
|
|
451
|
-
start() {
|
|
452
|
-
// Need to prevent the waiter from printing 'stack not stable' every 5 seconds, it messes
|
|
453
|
-
// with the output calculations.
|
|
454
|
-
this.oldLogThreshold = cli_io_host_1.CliIoHost.instance().logLevel;
|
|
455
|
-
cli_io_host_1.CliIoHost.instance().logLevel = 'info';
|
|
456
|
-
}
|
|
457
|
-
stop() {
|
|
458
|
-
var _a, _b, _c;
|
|
459
|
-
cli_io_host_1.CliIoHost.instance().logLevel = this.oldLogThreshold;
|
|
460
|
-
// Print failures at the end
|
|
461
|
-
const lines = new Array();
|
|
462
|
-
for (const failure of this.failures) {
|
|
463
|
-
// Root stack failures are not interesting
|
|
464
|
-
if (failure.isStackEvent) {
|
|
465
|
-
continue;
|
|
466
|
-
}
|
|
467
|
-
lines.push(util.format(chalk.red('%s | %s | %s | %s%s') + '\n', padLeft(TIMESTAMP_WIDTH, new Date(failure.event.Timestamp).toLocaleTimeString()), padRight(STATUS_WIDTH, (failure.event.ResourceStatus || '').slice(0, STATUS_WIDTH)), padRight(this.props.resourceTypeColumnWidth, failure.event.ResourceType || ''), shorten(40, (_a = failure.event.LogicalResourceId) !== null && _a !== void 0 ? _a : ''), this.failureReasonOnNextLine(failure)));
|
|
468
|
-
const trace = (_c = (_b = failure.metadata) === null || _b === void 0 ? void 0 : _b.entry) === null || _c === void 0 ? void 0 : _c.trace;
|
|
469
|
-
if (trace) {
|
|
470
|
-
lines.push(chalk.red(`\t${trace.join('\n\t\\_ ')}\n`));
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
// Display in the same block space, otherwise we're going to have silly empty lines.
|
|
474
|
-
this.block.displayLines(lines);
|
|
475
|
-
this.block.removeEmptyLines();
|
|
476
|
-
}
|
|
477
|
-
progressBar(width) {
|
|
478
|
-
if (!this.resourcesTotal) {
|
|
479
|
-
return '';
|
|
480
|
-
}
|
|
481
|
-
const fraction = Math.min(this.resourcesDone / this.resourcesTotal, 1);
|
|
482
|
-
const innerWidth = Math.max(1, width - 2);
|
|
483
|
-
const chars = innerWidth * fraction;
|
|
484
|
-
const remainder = chars - Math.floor(chars);
|
|
485
|
-
const fullChars = FULL_BLOCK.repeat(Math.floor(chars));
|
|
486
|
-
const partialChar = PARTIAL_BLOCK[Math.floor(remainder * PARTIAL_BLOCK.length)];
|
|
487
|
-
const filler = '·'.repeat(innerWidth - Math.floor(chars) - (partialChar ? 1 : 0));
|
|
488
|
-
const color = this.rollingBack ? chalk.yellow : chalk.green;
|
|
489
|
-
return '[' + color(fullChars + partialChar) + filler + `] (${this.resourcesDone}/${this.resourcesTotal})`;
|
|
490
|
-
}
|
|
491
|
-
failureReasonOnNextLine(activity) {
|
|
492
|
-
var _a, _b;
|
|
493
|
-
return hasErrorMessage((_a = activity.event.ResourceStatus) !== null && _a !== void 0 ? _a : '')
|
|
494
|
-
? `\n${' '.repeat(TIMESTAMP_WIDTH + STATUS_WIDTH + 6)}${chalk.red((_b = this.failureReason(activity)) !== null && _b !== void 0 ? _b : '')}`
|
|
495
|
-
: '';
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
exports.CurrentActivityPrinter = CurrentActivityPrinter;
|
|
499
|
-
const FULL_BLOCK = '█';
|
|
500
|
-
const PARTIAL_BLOCK = ['', '▏', '▎', '▍', '▌', '▋', '▊', '▉'];
|
|
501
|
-
const MAX_PROGRESSBAR_WIDTH = 60;
|
|
502
|
-
const MIN_PROGRESSBAR_WIDTH = 10;
|
|
503
|
-
const PROGRESSBAR_EXTRA_SPACE = 2 /* leading spaces */ + 2 /* brackets */ + 4 /* progress number decoration */ + 6; /* 2 progress numbers up to 999 */
|
|
504
|
-
function hasErrorMessage(status) {
|
|
505
|
-
return status.endsWith('_FAILED') || status === 'ROLLBACK_IN_PROGRESS' || status === 'UPDATE_ROLLBACK_IN_PROGRESS';
|
|
506
|
-
}
|
|
507
|
-
function colorFromStatusResult(status) {
|
|
508
|
-
if (!status) {
|
|
509
|
-
return chalk.reset;
|
|
510
|
-
}
|
|
511
|
-
if (status.indexOf('FAILED') !== -1) {
|
|
512
|
-
return chalk.red;
|
|
513
|
-
}
|
|
514
|
-
if (status.indexOf('ROLLBACK') !== -1) {
|
|
515
|
-
return chalk.yellow;
|
|
516
|
-
}
|
|
517
|
-
if (status.indexOf('COMPLETE') !== -1) {
|
|
518
|
-
return chalk.green;
|
|
519
|
-
}
|
|
520
|
-
return chalk.reset;
|
|
521
|
-
}
|
|
522
|
-
function colorFromStatusActivity(status) {
|
|
523
|
-
if (!status) {
|
|
524
|
-
return chalk.reset;
|
|
525
|
-
}
|
|
526
|
-
if (status.endsWith('_FAILED')) {
|
|
527
|
-
return chalk.red;
|
|
528
|
-
}
|
|
529
|
-
if (status.startsWith('CREATE_') || status.startsWith('UPDATE_') || status.startsWith('IMPORT_')) {
|
|
530
|
-
return chalk.green;
|
|
531
|
-
}
|
|
532
|
-
// For stacks, it may also be 'UPDDATE_ROLLBACK_IN_PROGRESS'
|
|
533
|
-
if (status.indexOf('ROLLBACK_') !== -1) {
|
|
534
|
-
return chalk.yellow;
|
|
535
|
-
}
|
|
536
|
-
if (status.startsWith('DELETE_')) {
|
|
537
|
-
return chalk.yellow;
|
|
538
|
-
}
|
|
539
|
-
return chalk.reset;
|
|
540
|
-
}
|
|
541
|
-
function shorten(maxWidth, p) {
|
|
542
|
-
if (p.length <= maxWidth) {
|
|
543
|
-
return p;
|
|
544
|
-
}
|
|
545
|
-
const half = Math.floor((maxWidth - 3) / 2);
|
|
546
|
-
return p.slice(0, half) + '...' + p.slice(-half);
|
|
547
|
-
}
|
|
548
|
-
const TIMESTAMP_WIDTH = 12;
|
|
549
|
-
const STATUS_WIDTH = 20;
|
|
550
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2stYWN0aXZpdHktbW9uaXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInN0YWNrLWFjdGl2aXR5LW1vbml0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQTZCO0FBQzdCLDBFQUErRjtBQUUvRiwrQkFBK0I7QUFDL0IsNkRBQXVFO0FBQ3ZFLDJDQUE0QztBQUM1QywyREFBc0U7QUFFdEUsdUNBQTRDO0FBVzVDOztHQUVHO0FBQ0gsSUFBWSxxQkFVWDtBQVZELFdBQVkscUJBQXFCO0lBQy9COztPQUVHO0lBQ0gsb0NBQVcsQ0FBQTtJQUVYOztPQUVHO0lBQ0gsMENBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQVZXLHFCQUFxQixxQ0FBckIscUJBQXFCLFFBVWhDO0FBc0RELE1BQWEsb0JBQW9CO0lBQy9COztPQUVHO0lBQ0ksTUFBTSxDQUFDLGtCQUFrQixDQUM5QixHQUEwQixFQUMxQixTQUFpQixFQUNqQixhQUEwQyxFQUMxQyxVQUFtQyxFQUFFOztRQUVyQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBRTVELE1BQU0sS0FBSyxHQUFpQjtZQUMxQix1QkFBdUIsRUFBRSx5QkFBeUIsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDO1lBQzFFLGNBQWMsRUFBRSxPQUFPLENBQUMsY0FBYztZQUN0QyxNQUFNO1NBQ1AsQ0FBQztRQUVGLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxDQUFDO1FBQy9DLE1BQU0sT0FBTyxHQUFHLE1BQUEsT0FBTyxDQUFDLFFBQVEsbUNBQUksTUFBTSxDQUFDO1FBQzNDLGlGQUFpRjtRQUNqRiw0REFBNEQ7UUFDNUQsMEZBQTBGO1FBQzFGLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxTQUFTLElBQUksTUFBTSxDQUFDLEtBQUssSUFBSSxD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QUFVLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUNqRyxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUM7SUFDckIsQ0FBQztJQUNELDREQUE0RDtJQUM1RCxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN2QyxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDdEIsQ0FBQztJQUNELElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ2pDLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQztJQUN0QixDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDO0FBQ3JCLENBQUM7QUFFRCxTQUFTLE9BQU8sQ0FBQyxRQUFnQixFQUFFLENBQVM7SUFDMUMsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQ3pCLE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDNUMsT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFRCxNQUFNLGVBQWUsR0FBRyxFQUFFLENBQUM7QUFDM0IsTUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgdXRpbCBmcm9tICd1dGlsJztcbmltcG9ydCB7IEFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUsIHR5cGUgTWV0YWRhdGFFbnRyeSB9IGZyb20gJ0Bhd3MtY2RrL2Nsb3VkLWFzc2VtYmx5LXNjaGVtYSc7XG5pbXBvcnQgdHlwZSB7IENsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCB9IGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgKiBhcyBjaGFsayBmcm9tICdjaGFsayc7XG5pbXBvcnQgeyBSZXNvdXJjZUV2ZW50LCBTdGFja0V2ZW50UG9sbGVyIH0gZnJvbSAnLi9zdGFjay1ldmVudC1wb2xsZXInO1xuaW1wb3J0IHsgZXJyb3IsIGluZm8gfSBmcm9tICcuLi8uLi9sb2dnaW5nJztcbmltcG9ydCB7IENsaUlvSG9zdCwgSW9NZXNzYWdlTGV2ZWwgfSBmcm9tICcuLi8uLi90b29sa2l0L2NsaS1pby1ob3N0JztcbmltcG9ydCB0eXBlIHsgSUNsb3VkRm9ybWF0aW9uQ2xpZW50IH0gZnJvbSAnLi4vYXdzLWF1dGgnO1xuaW1wb3J0IHsgUmV3cml0YWJsZUJsb2NrIH0gZnJvbSAnLi9kaXNwbGF5JztcblxuZXhwb3J0IGludGVyZmFjZSBTdGFja0FjdGl2aXR5IGV4dGVuZHMgUmVzb3VyY2VFdmVudCB7XG4gIHJlYWRvbmx5IG1ldGFkYXRhPzogUmVzb3VyY2VNZXRhZGF0YTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXNvdXJjZU1ldGFkYXRhIHtcbiAgZW50cnk6IE1ldGFkYXRhRW50cnk7XG4gIGNvbnN0cnVjdFBhdGg6IHN0cmluZztcbn1cblxuLyoqXG4gKiBTdXBwb3J0ZWQgZGlzcGxheSBtb2RlcyBmb3Igc3RhY2sgZGVwbG95bWVudCBhY3Rpdml0eVxuICovXG5leHBvcnQgZW51bSBTdGFja0FjdGl2aXR5UHJvZ3Jlc3Mge1xuICAvKipcbiAgICogRGlzcGxheXMgYSBwcm9ncmVzcyBiYXIgd2l0aCBvbmx5IHRoZSBldmVudHMgZm9yIHRoZSByZXNvdXJjZSBjdXJyZW50bHkgYmVpbmcgZGVwbG95ZWRcbiAgICovXG4gIEJBUiA9ICdiYXInLFxuXG4gIC8qKlxuICAgKiBEaXNwbGF5cyBjb21wbGV0ZSBoaXN0b3J5IHdpdGggYWxsIENsb3VkRm9ybWF0aW9uIHN0YWNrIGV2ZW50c1xuICAgKi9cbiAgRVZFTlRTID0gJ2V2ZW50cycsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2l0aERlZmF1bHRQcmludGVyUHJvcHMge1xuICAvKipcbiAgICogVG90YWwgbnVtYmVyIG9mIHJlc291cmNlcyB0byB1cGRhdGVcbiAgICpcbiAgICogVXNlZCB0byBjYWxjdWxhdGUgYSBwcm9ncmVzcyBiYXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gcHJvZ3Jlc3MgcmVwb3J0aW5nLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVzb3VyY2VzVG90YWw/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBsb2cgbGV2ZWwgdGhhdCB3YXMgcmVxdWVzdGVkIGluIHRoZSBDTElcbiAgICpcbiAgICogSWYgdmVyYm9zZSBvciB0cmFjZSBpcyByZXF1ZXN0ZWQsIHdlJ2xsIGFsd2F5cyB1c2UgdGhlIGZ1bGwgaGlzdG9yeSBwcmludGVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFVzZSB2YWx1ZSBmcm9tIGxvZ2dpbmcubG9nTGV2ZWxcbiAgICovXG4gIHJlYWRvbmx5IGxvZ0xldmVsPzogSW9NZXNzYWdlTGV2ZWw7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gZGlzcGxheSBhbGwgc3RhY2sgZXZlbnRzIG9yIHRvIGRpc3BsYXkgb25seSB0aGUgZXZlbnRzIGZvciB0aGVcbiAgICogcmVzb3VyY2UgY3VycmVudGx5IGJlaW5nIGRlcGxveWVkXG4gICAqXG4gICAqIElmIG5vdCBzZXQsIHRoZSBzdGFjayBoaXN0b3J5IHdpdGggYWxsIHN0YWNrIGV2ZW50cyB3aWxsIGJlIGRpc3BsYXllZFxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcHJvZ3Jlc3M/OiBTdGFja0FjdGl2aXR5UHJvZ3Jlc3M7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgd2UgYXJlIG9uIGEgQ0kgc3lzdGVtXG4gICAqXG4gICAqIElmIHNvLCBkaXNhYmxlIHRoZSBcIm9wdGltaXplZFwiIHN0YWNrIG1vbml0b3IuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBjaT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENyZWF0aW9uIHRpbWUgb2YgdGhlIGNoYW5nZSBzZXRcbiAgICpcbiAgICogVGhpcyB3aWxsIGJlIHVzZWQgdG8gZmlsdGVyIGV2ZW50cywgb25seSBzaG93aW5nIHRob3NlIGZyb20gYWZ0ZXIgdGhlIGNoYW5nZVxuICAgKiBzZXQgY3JlYXRpb24gdGltZS5cbiAgICpcbiAgICogSXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlIHRoaXMsIG90aGVyd2lzZSB0aGUgZmlsdGVyaW5nIHdpbGwgYmUgc3ViamVjdFxuICAgKiB0byBjbG9jayBkcmlmdCBiZXR3ZWVuIGxvY2FsIGFuZCBjbG91ZCBtYWNoaW5lcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBsb2NhbCBtYWNoaW5lJ3MgY3VycmVudCB0aW1lXG4gICAqL1xuICByZWFkb25seSBjaGFuZ2VTZXRDcmVhdGlvblRpbWU/OiBEYXRlO1xufVxuXG5leHBvcnQgY2xhc3MgU3RhY2tBY3Rpdml0eU1vbml0b3Ige1xuICAvKipcbiAgICogQ3JlYXRlIGEgU3RhY2sgQWN0aXZpdHkgTW9uaXRvciB1c2luZyBhIGRlZmF1bHQgcHJpbnRlciwgYmFzZWQgb24gY29udGV4dCBjbHVlc1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyB3aXRoRGVmYXVsdFByaW50ZXIoXG4gICAgY2ZuOiBJQ2xvdWRGb3JtYXRpb25DbGllbnQsXG4gICAgc3RhY2tOYW1lOiBzdHJpbmcsXG4gICAgc3RhY2tBcnRpZmFjdDogQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0LFxuICAgIG9wdGlvbnM6IFdpdGhEZWZhdWx0UHJpbnRlclByb3BzID0ge30sXG4gICkge1xuICAgIGNvbnN0IHN0cmVhbSA9IG9wdGlvbnMuY2kgPyBwcm9jZXNzLnN0ZG91dCA6IHByb2Nlc3Muc3RkZXJyO1xuXG4gICAgY29uc3QgcHJvcHM6IFByaW50ZXJQcm9wcyA9IHtcbiAgICAgIHJlc291cmNlVHlwZUNvbHVtbldpZHRoOiBjYWxjTWF4UmVzb3VyY2VUeXBlTGVuZ3RoKHN0YWNrQXJ0aWZhY3QudGVtcGxhdGUpLFxuICAgICAgcmVzb3VyY2VzVG90YWw6IG9wdGlvbnMucmVzb3VyY2VzVG90YWwsXG4gICAgICBzdHJlYW0sXG4gICAgfTtcblxuICAgIGNvbnN0IGlzV2luZG93cyA9IHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMic7XG4gICAgY29uc3QgdmVyYm9zZSA9IG9wdGlvbnMubG9nTGV2ZWwgPz8gJ2luZm8nO1xuICAgIC8vIE9uIHNvbWUgQ0kgc3lzdGVtcyAoc3VjaCBhcyBDaXJjbGVDSSkgb3V0cHV0IHN0aWxsIHJlcG9ydHMgYXMgYSBUVFkgc28gd2UgYWxzb1xuICAgIC8vIG5lZWQgYW4gaW5kaXZpZHVhbCBjaGVjayBmb3Igd2hldGhlciB3ZSdyZSBydW5uaW5nIG9uIENJLlxuICAgIC8vIHNlZTogaHR0cHM6Ly9kaXNjdXNzLmNpcmNsZWNpLmNvbS90L2NpcmNsZWNpLXRlcm1pbmFsLWlzLWEtdHR5LWJ1dC10ZXJtLWlzLW5vdC1zZXQvOTk2NVxuICAgIGNvbnN0IGZhbmN5T3V0cHV0QXZhaWxhYmxlID0gIWlzV2luZG93cyAmJiBzdHJlYW0uaXNUVFkgJiYgIW9wdGlvbnMuY2k7XG4gICAgY29uc3QgcHJvZ3Jlc3MgPSBvcHRpb25zLnByb2dyZXNzID8/IFN0YWNrQWN0aXZpdHlQcm9ncmVzcy5CQVI7XG5cbiAgICBjb25zdCBwcmludGVyID1cbiAgICAgIGZhbmN5T3V0cHV0QXZhaWxhYmxlICYmICF2ZXJib3NlICYmIHByb2dyZXNzID09PSBTdGFja0FjdGl2aXR5UHJvZ3Jlc3MuQkFSXG4gICAgICAgID8gbmV3IEN1cnJlbnRBY3Rpdml0eVByaW50ZXIocHJvcHMpXG4gICAgICAgIDogbmV3IEhpc3RvcnlBY3Rpdml0eVByaW50ZXIocHJvcHMpO1xuXG4gICAgcmV0dXJuIG5ldyBTdGFja0FjdGl2aXR5TW9uaXRvcihjZm4sIHN0YWNrTmFtZSwgcHJpbnRlciwgc3RhY2tBcnRpZmFjdCwgb3B0aW9ucy5jaGFuZ2VTZXRDcmVhdGlvblRpbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBwb2xsZXIgdXNlZCB0byByZWFkIHN0YWNrIGV2ZW50c1xuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHBvbGxlcjogU3RhY2tFdmVudFBvbGxlcjtcblxuICBwdWJsaWMgcmVhZG9ubHkgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIHByaXZhdGUgYWN0aXZlID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEN1cnJlbnQgdGljayB0aW1lclxuICAgKi9cbiAgcHJpdmF0ZSB0aWNrVGltZXI/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcblxuICAvKipcbiAgICogU2V0IHRvIHRoZSBhY3Rpdml0eSBvZiByZWFkaW5nIHRoZSBjdXJyZW50IGV2ZW50c1xuICAgKi9cbiAgcHJpdmF0ZSByZWFkUHJvbWlzZT86IFByb21pc2U8YW55PjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBjZm46IElDbG91ZEZvcm1hdGlvbkNsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0YWNrTmFtZTogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcHJpbnRlcjogSUFjdGl2aXR5UHJpbnRlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0YWNrPzogQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0LFxuICAgIGNoYW5nZVNldENyZWF0aW9uVGltZT86IERhdGUsXG4gICkge1xuICAgIHRoaXMucG9sbGVyID0gbmV3IFN0YWNrRXZlbnRQb2xsZXIoY2ZuLCB7XG4gICAgICBzdGFja05hbWUsXG4gICAgICBzdGFydFRpbWU6IGNoYW5nZVNldENyZWF0aW9uVGltZT8uZ2V0VGltZSgpID8/IERhdGUubm93KCksXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc3RhcnQoKSB7XG4gICAgdGhpcy5hY3RpdmUgPSB0cnVlO1xuICAgIHRoaXMucHJpbnRlci5zdGFydCgpO1xuICAgIHRoaXMuc2NoZWR1bGVOZXh0VGljaygpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHN0b3AoKSB7XG4gICAgdGhpcy5hY3RpdmUgPSBmYWxzZTtcbiAgICBpZiAodGhpcy50aWNrVGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpY2tUaW1lcik7XG4gICAgfVxuXG4gICAgLy8gRG8gYSBmaW5hbCBwb2xsIGZvciBhbGwgZXZlbnRzLiBUaGlzIGlzIHRvIGhhbmRsZSB0aGUgc2l0dWF0aW9uIHdoZXJlIERlc2NyaWJlU3RhY2tTdGF0dXNcbiAgICAvLyBhbHJlYWR5IHJldHVybmVkIGFuIGVycm9yLCBidXQgdGhlIG1vbml0b3IgaGFzbid0IHNlZW4gYWxsIHRoZSBldmVudHMgeWV0IGFuZCB3ZSdkIGVuZFxuICAgIC8vIHVwIG5vdCBwcmludGluZyB0aGUgZmFpbHVyZSByZWFzb24gdG8gdXNlcnMuXG4gICAgYXdhaXQgdGhpcy5maW5hbFBvbGxUb0VuZCgpO1xuXG4gICAgdGhpcy5wcmludGVyLnN0b3AoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2NoZWR1bGVOZXh0VGljaygpIHtcbiAgICBpZiAoIXRoaXMuYWN0aXZlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy50aWNrVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHZvaWQgdGhpcy50aWNrKCksIHRoaXMucHJpbnRlci51cGRhdGVTbGVlcCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHRpY2soKSB7XG4gICAgaWYgKCF0aGlzLmFjdGl2ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICB0aGlzLnJlYWRQcm9taXNlID0gdGhpcy5yZWFkTmV3RXZlbnRzKCk7XG4gICAgICBhd2FpdCB0aGlzLnJlYWRQcm9taXNlO1xuICAgICAgdGhpcy5yZWFkUHJvbWlzZSA9IHVuZGVmaW5lZDtcblxuICAgICAgLy8gV2UgbWlnaHQgaGF2ZSBiZWVuIHN0b3AoKXBlZCB3aGlsZSB0aGUgbmV0d29yayBjYWxsIHdhcyBpbiBwcm9ncmVzcy5cbiAgICAgIGlmICghdGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnByaW50ZXIucHJpbnQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBlcnJvcignRXJyb3Igb2NjdXJyZWQgd2hpbGUgbW9uaXRvcmluZyBzdGFjazogJXMnLCBlKTtcbiAgICB9XG4gICAgdGhpcy5zY2hlZHVsZU5leHRUaWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGZpbmRNZXRhZGF0YUZvcihsb2dpY2FsSWQ6IHN0cmluZyB8IHVuZGVmaW5lZCk6IFJlc291cmNlTWV0YWRhdGEgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5zdGFjaz8ubWFuaWZlc3Q/Lm1ldGFkYXRhO1xuICAgIGlmICghbG9naWNhbElkIHx8ICFtZXRhZGF0YSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZm9yIChjb25zdCBwYXRoIG9mIE9iamVjdC5rZXlzKG1ldGFkYXRhKSkge1xuICAgICAgY29uc3QgZW50cnkgPSBtZXRhZGF0YVtwYXRoXVxuICAgICAgICAuZmlsdGVyKChlKSA9PiBlLnR5cGUgPT09IEFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUuTE9HSUNBTF9JRClcbiAgICAgICAgLmZpbmQoKGUpID0+IGUuZGF0YSA9PT0gbG9naWNhbElkKTtcbiAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVudHJ5LFxuICAgICAgICAgIGNvbnN0cnVjdFBhdGg6IHRoaXMuc2ltcGxpZnlDb25zdHJ1Y3RQYXRoKHBhdGgpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWRzIGFsbCBuZXcgZXZlbnRzIGZyb20gdGhlIHN0YWNrIGhpc3RvcnlcbiAgICpcbiAgICogVGhlIGV2ZW50cyBhcmUgcmV0dXJuZWQgaW4gcmV2ZXJzZSBjaHJvbm9sb2dpY2FsIG9yZGVyOyB3ZSBjb250aW51ZSB0byB0aGUgbmV4dCBwYWdlIGlmIHdlXG4gICAqIHNlZSBhIG5leHQgcGFnZSBhbmQgdGhlIGxhc3QgZXZlbnQgaW4gdGhlIHBhZ2UgaXMgbmV3IHRvIHVzIChhbmQgd2l0aGluIHRoZSB0aW1lIHdpbmRvdykuXG4gICAqIGhhdmVuJ3Qgc2VlbiB0aGUgZmluYWwgZXZlbnRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVhZE5ld0V2ZW50cygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBwb2xsRXZlbnRzID0gYXdhaXQgdGhpcy5wb2xsZXIucG9sbCgpO1xuXG4gICAgY29uc3QgYWN0aXZpdGllczogU3RhY2tBY3Rpdml0eVtdID0gcG9sbEV2ZW50cy5tYXAoKGV2ZW50KSA9PiAoe1xuICAgICAgLi4uZXZlbnQsXG4gICAgICBtZXRhZGF0YTogdGhpcy5maW5kTWV0YWRhdGFGb3IoZXZlbnQuZXZlbnQuTG9naWNhbFJlc291cmNlSWQpLFxuICAgIH0pKTtcblxuICAgIGZvciAoY29uc3QgYWN0aXZpdHkgb2YgYWN0aXZpdGllcykge1xuICAgICAgdGhpcy5jaGVja0ZvckVycm9ycyhhY3Rpdml0eSk7XG4gICAgICB0aGlzLnByaW50ZXIuYWRkQWN0aXZpdHkoYWN0aXZpdHkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIGEgZmluYWwgcG9sbCB0byB0aGUgZW5kIGFuZCBmbHVzaCBvdXQgYWxsIGV2ZW50cyB0byB0aGUgcHJpbnRlclxuICAgKlxuICAgKiBGaW5pc2ggYW55IHBvbGwgY3VycmVudGx5IGluIHByb2dyZXNzLCB0aGVuIGRvIGEgZmluYWwgb25lIHVudGlsIHdlJ3ZlXG4gICAqIHJlYWNoZWQgdGhlIGxhc3QgcGFnZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmluYWxQb2xsVG9FbmQoKSB7XG4gICAgLy8gSWYgd2Ugd2VyZSBkb2luZyBhIHBvbGwsIGZpbmlzaCB0aGF0IGZpcnN0LiBJdCB3YXMgc3RhcnRlZCBiZWZvcmVcbiAgICAvLyB0aGUgbW9tZW50IHdlIHdlcmUgc3VyZSB3ZSB3ZXJlbid0IGdvaW5nIHRvIGdldCBhbnkgbmV3IGV2ZW50cyBhbnltb3JlXG4gICAgLy8gc28gd2UgbmVlZCB0byBkbyBhIG5ldyBvbmUgYW55d2F5LiBOZWVkIHRvIHdhaXQgZm9yIHRoaXMgb25lIHRob3VnaFxuICAgIC8vIGJlY2F1c2Ugb3VyIHN0YXRlIGlzIHNpbmdsZS10aHJlYWRlZC5cbiAgICBpZiAodGhpcy5yZWFkUHJvbWlzZSkge1xuICAgICAgYXdhaXQgdGhpcy5yZWFkUHJvbWlzZTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnJlYWROZXdFdmVudHMoKTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tGb3JFcnJvcnMoYWN0aXZpdHk6IFN0YWNrQWN0aXZpdHkpIHtcbiAgICBpZiAoaGFzRXJyb3JNZXNzYWdlKGFjdGl2aXR5LmV2ZW50LlJlc291cmNlU3RhdHVzID8/ICcnKSkge1xuICAgICAgY29uc3QgaXNDYW5jZWxsZWQgPSAoYWN0aXZpdHkuZXZlbnQuUmVzb3VyY2VTdGF0dXNSZWFzb24gPz8gJycpLmluZGV4T2YoJ2NhbmNlbGxlZCcpID4gLTE7XG5cbiAgICAgIC8vIENhbmNlbGxlZCBpcyBub3QgYW4gaW50ZXJlc3RpbmcgZmFpbHVyZSByZWFzb24sIG5vciBpcyB0aGUgc3RhY2sgbWVzc2FnZSAoc3RhY2tcbiAgICAgIC8vIG1lc3NhZ2Ugd2lsbCBqdXN0IHNheSBzb21ldGhpbmcgbGlrZSBcInN0YWNrIGZhaWxlZCB0byB1cGRhdGVcIilcbiAgICAgIGlmICghaXNDYW5jZWxsZWQgJiYgYWN0aXZpdHkuZXZlbnQuU3RhY2tOYW1lICE9PSBhY3Rpdml0eS5ldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCkge1xuICAgICAgICB0aGlzLmVycm9ycy5wdXNoKGFjdGl2aXR5LmV2ZW50LlJlc291cmNlU3RhdHVzUmVhc29uID8/ICcnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNpbXBsaWZ5Q29uc3RydWN0UGF0aChwYXRoOiBzdHJpbmcpIHtcbiAgICBwYXRoID0gcGF0aC5yZXBsYWNlKC9cXC9SZXNvdXJjZSQvLCAnJyk7XG4gICAgcGF0aCA9IHBhdGgucmVwbGFjZSgvXlxcLy8sICcnKTsgLy8gcmVtb3ZlIFwiL1wiIHByZWZpeFxuXG4gICAgLy8gcmVtb3ZlIFwiPHN0YWNrLW5hbWU+L1wiIHByZWZpeFxuICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgodGhpcy5zdGFja05hbWUgKyAnLycpKSB7XG4gICAgICBwYXRoID0gcGF0aC5zbGljZSh0aGlzLnN0YWNrTmFtZS5sZW5ndGggKyAxKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhdGg7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGFkUmlnaHQobjogbnVtYmVyLCB4OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4geCArICcgJy5yZXBlYXQoTWF0aC5tYXgoMCwgbiAtIHgubGVuZ3RoKSk7XG59XG5cbi8qKlxuICogSW5mYW1vdXMgcGFkTGVmdCgpXG4gKi9cbmZ1bmN0aW9uIHBhZExlZnQobjogbnVtYmVyLCB4OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gJyAnLnJlcGVhdChNYXRoLm1heCgwLCBuIC0geC5sZW5ndGgpKSArIHg7XG59XG5cbmZ1bmN0aW9uIGNhbGNNYXhSZXNvdXJjZVR5cGVMZW5ndGgodGVtcGxhdGU6IGFueSkge1xuICBjb25zdCByZXNvdXJjZXMgPSAodGVtcGxhdGUgJiYgdGVtcGxhdGUuUmVzb3VyY2VzKSB8fCB7fTtcbiAgbGV0IG1heFdpZHRoID0gMDtcbiAgZm9yIChjb25zdCBpZCBvZiBPYmplY3Qua2V5cyhyZXNvdXJjZXMpKSB7XG4gICAgY29uc3QgdHlwZSA9IHJlc291cmNlc1tpZF0uVHlwZSB8fCAnJztcbiAgICBpZiAodHlwZS5sZW5ndGggPiBtYXhXaWR0aCkge1xuICAgICAgbWF4V2lkdGggPSB0eXBlLmxlbmd0aDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1heFdpZHRoO1xufVxuXG5pbnRlcmZhY2UgUHJpbnRlclByb3BzIHtcbiAgLyoqXG4gICAqIFRvdGFsIHJlc291cmNlcyB0byBkZXBsb3lcbiAgICovXG4gIHJlYWRvbmx5IHJlc291cmNlc1RvdGFsPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgd2l0aCBvZiB0aGUgXCJyZXNvdXJjZSB0eXBlXCIgY29sdW1uLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVzb3VyY2VUeXBlQ29sdW1uV2lkdGg6IG51bWJlcjtcblxuICAvKipcbiAgICogU3RyZWFtIHRvIHdyaXRlIHRvXG4gICAqL1xuICByZWFkb25seSBzdHJlYW06IE5vZGVKUy5Xcml0ZVN0cmVhbTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJQWN0aXZpdHlQcmludGVyIHtcbiAgcmVhZG9ubHkgdXBkYXRlU2xlZXA6IG51bWJlcjtcblxuICBhZGRBY3Rpdml0eShhY3Rpdml0eTogU3RhY2tBY3Rpdml0eSk6IHZvaWQ7XG4gIHByaW50KCk6IHZvaWQ7XG4gIHN0YXJ0KCk6IHZvaWQ7XG4gIHN0b3AoKTogdm9pZDtcbn1cblxuYWJzdHJhY3QgY2xhc3MgQWN0aXZpdHlQcmludGVyQmFzZSBpbXBsZW1lbnRzIElBY3Rpdml0eVByaW50ZXIge1xuICAvKipcbiAgICogRmV0Y2ggbmV3IGFjdGl2aXR5IGV2ZXJ5IDUgc2Vjb25kc1xuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHVwZGF0ZVNsZWVwOiBudW1iZXIgPSA1XzAwMDtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIHJlc291cmNlIElEcyB3aGljaCBhcmUgY3VycmVudGx5IGJlaW5nIHByb2Nlc3NlZFxuICAgKi9cbiAgcHJvdGVjdGVkIHJlc291cmNlc0luUHJvZ3Jlc3M6IFJlY29yZDxzdHJpbmcsIFN0YWNrQWN0aXZpdHk+ID0ge307XG5cbiAgLyoqXG4gICAqIFByZXZpb3VzIGNvbXBsZXRpb24gc3RhdGUgb2JzZXJ2ZWQgYnkgbG9naWNhbCBJRFxuICAgKlxuICAgKiBXZSB1c2UgdGhpcyB0byBkZXRlY3QgdGhhdCBpZiB3ZSBzZWUgYSBERUxFVEVfQ09NUExFVEUgYWZ0ZXIgYVxuICAgKiBDUkVBVEVfQ09NUExFVEUsIGl0J3MgYWN0dWFsbHkgYSByb2xsYmFjayBhbmQgd2Ugc2hvdWxkIERFQ1JFQVNFXG4gICAqIHJlc291cmNlc0RvbmUgaW5zdGVhZCBvZiBpbmNyZWFzZSBpdFxuICAgKi9cbiAgcHJvdGVjdGVkIHJlc291cmNlc1ByZXZDb21wbGV0ZVN0YXRlOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgLyoqXG4gICAqIENvdW50IG9mIHJlc291cmNlcyB0aGF0IGhhdmUgcmVwb3J0ZWQgYSBfQ09NUExFVEUgc3RhdHVzXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVzb3VyY2VzRG9uZTogbnVtYmVyID0gMDtcblxuICAvKipcbiAgICogSG93IG1hbnkgZGlnaXRzIHdlIG5lZWQgdG8gcmVwcmVzZW50IHRoZSB0b3RhbCBjb3VudCAoZm9yIGxpbmluZyB1cCB0aGUgc3RhdHVzIHJlcG9ydGluZylcbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSByZXNvdXJjZURpZ2l0czogbnVtYmVyID0gMDtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVzb3VyY2VzVG90YWw/OiBudW1iZXI7XG5cbiAgcHJvdGVjdGVkIHJvbGxpbmdCYWNrID0gZmFsc2U7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGZhaWx1cmVzID0gbmV3IEFycmF5PFN0YWNrQWN0aXZpdHk+KCk7XG5cbiAgcHJvdGVjdGVkIGhvb2tGYWlsdXJlTWFwID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIHN0cmluZz4+KCk7XG5cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIHJlYWRvbmx5IHByb3BzOiBQcmludGVyUHJvcHMpIHtcbiAgICAvLyArMSBiZWNhdXNlIHRoZSBzdGFjayBhbHNvIGVtaXRzIGEgXCJDT01QTEVURVwiIGV2ZW50IGF0IHRoZSBlbmQsIGFuZCB0aGF0IHdhc24ndFxuICAgIC8vIGNvdW50ZWQgeWV0LiBUaGlzIG1ha2VzIGl0IGxpbmUgdXAgd2l0aCB0aGUgYW1vdW50IG9mIGV2ZW50cyB3ZSBleHBlY3QuXG4gICAgdGhpcy5yZXNvdXJjZXNUb3RhbCA9IHByb3BzLnJlc291cmNlc1RvdGFsID8gcHJvcHMucmVzb3VyY2VzVG90YWwgKyAxIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gSG93IG1hbnkgZGlnaXRzIGRvZXMgdGhpcyBudW1iZXIgdGFrZSB0byByZXByZXNlbnQ/XG4gICAgdGhpcy5yZXNvdXJjZURpZ2l0cyA9IHRoaXMucmVzb3VyY2VzVG90YWwgPyBNYXRoLmNlaWwoTWF0aC5sb2cxMCh0aGlzLnJlc291cmNlc1RvdGFsKSkgOiAwO1xuICB9XG5cbiAgcHVibGljIGZhaWx1cmVSZWFzb24oYWN0aXZpdHk6IFN0YWNrQWN0aXZpdHkpIHtcbiAgICBjb25zdCByZXNvdXJjZVN0YXR1c1JlYXNvbiA9IGFjdGl2aXR5LmV2ZW50LlJlc291cmNlU3RhdHVzUmVhc29uID8/ICcnO1xuICAgIGNvbnN0IGxvZ2ljYWxSZXNvdXJjZUlkID0gYWN0aXZpdHkuZXZlbnQuTG9naWNhbFJlc291cmNlSWQgPz8gJyc7XG4gICAgY29uc3QgaG9va0ZhaWx1cmVSZWFzb25NYXAgPSB0aGlzLmhvb2tGYWlsdXJlTWFwLmdldChsb2dpY2FsUmVzb3VyY2VJZCk7XG5cbiAgICBpZiAoaG9va0ZhaWx1cmVSZWFzb25NYXAgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZm9yIChjb25zdCBob29rVHlwZSBvZiBob29rRmFpbHVyZVJlYXNvbk1hcC5rZXlzKCkpIHtcbiAgICAgICAgaWYgKHJlc291cmNlU3RhdHVzUmVhc29uLmluY2x1ZGVzKGhvb2tUeXBlKSkge1xuICAgICAgICAgIHJldHVybiByZXNvdXJjZVN0YXR1c1JlYXNvbiArICcgOiAnICsgaG9va0ZhaWx1cmVSZWFzb25NYXAuZ2V0KGhvb2tUeXBlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzb3VyY2VTdGF0dXNSZWFzb247XG4gIH1cblxuICBwdWJsaWMgYWRkQWN0aXZpdHkoYWN0aXZpdHk6IFN0YWNrQWN0aXZpdHkpIHtcbiAgICBjb25zdCBzdGF0dXMgPSBhY3Rpdml0eS5ldmVudC5SZXNvdXJjZVN0YXR1cztcbiAgICBjb25zdCBob29rU3RhdHVzID0gYWN0aXZpdHkuZXZlbnQuSG9va1N0YXR1cztcbiAgICBjb25zdCBob29rVHlwZSA9IGFjdGl2aXR5LmV2ZW50Lkhvb2tUeXBlO1xuICAgIGlmICghc3RhdHVzIHx8ICFhY3Rpdml0eS5ldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzdGF0dXMgPT09ICdST0xMQkFDS19JTl9QUk9HUkVTUycgfHwgc3RhdHVzID09PSAnVVBEQVRFX1JPTExCQUNLX0lOX1BST0dSRVNTJykge1xuICAgICAgLy8gT25seSB0cmlnZ2VyZWQgb24gdGhlIHN0YWNrIG9uY2Ugd2UndmUgc3RhcnRlZCBkb2luZyBhIHJvbGxiYWNrXG4gICAgICB0aGlzLnJvbGxpbmdCYWNrID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdHVzLmVuZHNXaXRoKCdfSU5fUFJPR1JFU1MnKSkge1xuICAgICAgdGhpcy5yZXNvdXJjZXNJblByb2dyZXNzW2FjdGl2aXR5LmV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkXSA9IGFjdGl2aXR5O1xuICAgIH1cblxuICAgIGlmIChoYXNFcnJvck1lc3NhZ2Uoc3RhdHVzKSkge1xuICAgICAgY29uc3QgaXNDYW5jZWxsZWQgPSAoYWN0aXZpdHkuZXZlbnQuUmVzb3VyY2VTdGF0dXNSZWFzb24gPz8gJycpLmluZGV4T2YoJ2NhbmNlbGxlZCcpID4gLTE7XG5cbiAgICAgIC8vIENhbmNlbGxlZCBpcyBub3QgYW4gaW50ZXJlc3RpbmcgZmFpbHVyZSByZWFzb25cbiAgICAgIGlmICghaXNDYW5jZWxsZWQpIHtcbiAgICAgICAgdGhpcy5mYWlsdXJlcy5wdXNoKGFjdGl2aXR5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3RhdHVzLmVuZHNXaXRoKCdfQ09NUExFVEUnKSB8fCBzdGF0dXMuZW5kc1dpdGgoJ19GQUlMRUQnKSkge1xuICAgICAgZGVsZXRlIHRoaXMucmVzb3VyY2VzSW5Qcm9ncmVzc1thY3Rpdml0eS5ldmVudC5Mb2dpY2FsUmVzb3VyY2VJZF07XG4gICAgfVxuXG4gICAgaWYgKHN0YXR1cy5lbmRzV2l0aCgnX0NPTVBMRVRFX0NMRUFOVVBfSU5fUFJPR1JFU1MnKSkge1xuICAgICAgdGhpcy5yZXNvdXJjZXNEb25lKys7XG4gICAgfVxuXG4gICAgaWYgKHN0YXR1cy5lbmRzV2l0aCgnX0NPTVBMRVRFJykpIHtcbiAgICAgIGNvbnN0IHByZXZTdGF0ZSA9IHRoaXMucmVzb3VyY2VzUHJldkNvbXBsZXRlU3RhdGVbYWN0aXZpdHkuZXZlbnQuTG9naWNhbFJlc291cmNlSWRdO1xuICAgICAgaWYgKCFwcmV2U3RhdGUpIHtcbiAgICAgICAgdGhpcy5yZXNvdXJjZXNEb25lKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiB3ZSBjb21wbGV0ZWQgdGhpcyBiZWZvcmUgYW5kIHdlJ3JlIGNvbXBsZXRpbmcgaXQgQUdBSU4sIG1lYW5zIHdlJ3JlIHJvbGxpbmcgYmFjay5cbiAgICAgICAgLy8gUHJvdGVjdCBhZ2FpbnN0IHNpbGx5IHVuZGVyZmxvdy5cbiAgICAgICAgdGhpcy5yZXNvdXJjZXNEb25lLS07XG4gICAgICAgIGlmICh0aGlzLnJlc291cmNlc0RvbmUgPCAwKSB7XG4gICAgICAgICAgdGhpcy5yZXNvdXJjZXNEb25lID0gMDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5yZXNvdXJjZXNQcmV2Q29tcGxldGVTdGF0ZVthY3Rpdml0eS5ldmVudC5Mb2dpY2FsUmVzb3VyY2VJZF0gPSBzdGF0dXM7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgaG9va1N0YXR1cyAhPT0gdW5kZWZpbmVkICYmXG4gICAgICBob29rU3RhdHVzLmVuZHNXaXRoKCdfQ09NUExFVEVfRkFJTEVEJykgJiZcbiAgICAgIGFjdGl2aXR5LmV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIGhvb2tUeXBlICE9PSB1bmRlZmluZWRcbiAgICApIHtcbiAgICAgIGlmICh0aGlzLmhvb2tGYWlsdXJlTWFwLmhhcyhhY3Rpdml0eS5ldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCkpIHtcbiAgICAgICAgdGhpcy5ob29rRmFpbHVyZU1hcC5nZXQoYWN0aXZpdHkuZXZlbnQuTG9naWNhbFJlc291cmNlSWQpPy5zZXQoaG9va1R5cGUsIGFjdGl2aXR5LmV2ZW50Lkhvb2tTdGF0dXNSZWFzb24gPz8gJycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ob29rRmFpbHVyZU1hcC5zZXQoYWN0aXZpdHkuZXZlbnQuTG9naWNhbFJlc291cmNlSWQsIG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCkpO1xuICAgICAgICB0aGlzLmhvb2tGYWlsdXJlTWFwLmdldChhY3Rpdml0eS5ldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCk/LnNldChob29rVHlwZSwgYWN0aXZpdHkuZXZlbnQuSG9va1N0YXR1c1JlYXNvbiA/PyAnJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFic3RyYWN0IHByaW50KCk6IHZvaWQ7XG5cbiAgcHVibGljIHN0YXJ0KCkge1xuICAgIC8vIEVtcHR5IG9uIHB1cnBvc2VcbiAgfVxuXG4gIHB1YmxpYyBzdG9wKCkge1xuICAgIC8vIEVtcHR5IG9uIHB1cnBvc2VcbiAgfVxufVxuXG4vKipcbiAqIEFjdGl2aXR5IFByaW50ZXIgd2hpY2ggc2hvd3MgYSBmdWxsIGxvZyBvZiBhbGwgQ2xvdWRGb3JtYXRpb24gZXZlbnRzXG4gKlxuICogV2hlbiB0aGVyZSBoYXNuJ3QgYmVlbiBhY3Rpdml0eSBmb3IgYSB3aGlsZSwgaXQgd2lsbCBwcmludCB0aGUgcmVzb3VyY2VzXG4gKiB0aGF0IGFyZSBjdXJyZW50bHkgaW4gcHJvZ3Jlc3MsIHRvIHNob3cgd2hhdCdzIGhvbGRpbmcgdXAgdGhlIGRlcGxveW1lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBIaXN0b3J5QWN0aXZpdHlQcmludGVyIGV4dGVuZHMgQWN0aXZpdHlQcmludGVyQmFzZSB7XG4gIC8qKlxuICAgKiBMYXN0IHRpbWUgd2UgcHJpbnRlZCBzb21ldGhpbmcgdG8gdGhlIGNvbnNvbGUuXG4gICAqXG4gICAqIFVzZWQgdG8gbWVhc3VyZSB0aW1lb3V0IGZvciBwcm9ncmVzcyByZXBvcnRpbmcuXG4gICAqL1xuICBwcml2YXRlIGxhc3RQcmludFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgbXMgb2YgY2hhbmdlIGFic2VuY2UgYmVmb3JlIHdlIHRlbGwgdGhlIHVzZXIgYWJvdXQgdGhlIHJlc291cmNlcyB0aGF0IGFyZSBjdXJyZW50bHkgaW4gcHJvZ3Jlc3MuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGluUHJvZ3Jlc3NEZWxheSA9IDMwXzAwMDtcblxuICBwcml2YXRlIHJlYWRvbmx5IHByaW50YWJsZSA9IG5ldyBBcnJheTxTdGFja0FjdGl2aXR5PigpO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBQcmludGVyUHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gIH1cblxuICBwdWJsaWMgYWRkQWN0aXZpdHkoYWN0aXZpdHk6IFN0YWNrQWN0aXZpdHkpIHtcbiAgICBzdXBlci5hZGRBY3Rpdml0eShhY3Rpdml0eSk7XG4gICAgdGhpcy5wcmludGFibGUucHVzaChhY3Rpdml0eSk7XG4gICAgdGhpcy5wcmludCgpO1xuICB9XG5cbiAgcHVibGljIHByaW50KCkge1xuICAgIGZvciAoY29uc3QgYWN0aXZpdHkgb2YgdGhpcy5wcmludGFibGUpIHtcbiAgICAgIHRoaXMucHJpbnRPbmUoYWN0aXZpdHkpO1xuICAgIH1cbiAgICB0aGlzLnByaW50YWJsZS5zcGxpY2UoMCwgdGhpcy5wcmludGFibGUubGVuZ3RoKTtcbiAgICB0aGlzLnByaW50SW5Qcm9ncmVzcygpO1xuICB9XG5cbiAgcHVibGljIHN0b3AoKSB7XG4gICAgLy8gUHJpbnQgZmFpbHVyZXMgYXQgdGhlIGVuZFxuICAgIGlmICh0aGlzLmZhaWx1cmVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGluZm8oJ1xcbkZhaWxlZCByZXNvdXJjZXM6Jyk7XG4gICAgICBmb3IgKGNvbnN0IGZhaWx1cmUgb2YgdGhpcy5mYWlsdXJlcykge1xuICAgICAgICAvLyBSb290IHN0YWNrIGZhaWx1cmVzIGFyZSBub3QgaW50ZXJlc3RpbmdcbiAgICAgICAgaWYgKGZhaWx1cmUuaXNTdGFja0V2ZW50KSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnByaW50T25lKGZhaWx1cmUsIGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHByaW50T25lKGFjdGl2aXR5OiBTdGFja0FjdGl2aXR5LCBwcm9ncmVzcz86IGJvb2xlYW4pIHtcbiAgICBjb25zdCBldmVudCA9IGFjdGl2aXR5LmV2ZW50O1xuICAgIGNvbnN0IGNvbG9yID0gY29sb3JGcm9tU3RhdHVzUmVzdWx0KGV2ZW50LlJlc291cmNlU3RhdHVzKTtcbiAgICBsZXQgcmVhc29uQ29sb3IgPSBjaGFsay5jeWFuO1xuXG4gICAgbGV0IHN0YWNrVHJhY2UgPSAnJztcbiAgICBjb25zdCBtZXRhZGF0YSA9IGFjdGl2aXR5Lm1ldGFkYXRhO1xuXG4gICAgaWYgKGV2ZW50LlJlc291cmNlU3RhdHVzICYmIGV2ZW50LlJlc291cmNlU3RhdHVzLmluZGV4T2YoJ0ZBSUxFRCcpICE9PSAtMSkge1xuICAgICAgaWYgKHByb2dyZXNzID09IHVuZGVmaW5lZCB8fCBwcm9ncmVzcykge1xuICAgICAgICBldmVudC5SZXNvdXJjZVN0YXR1c1JlYXNvbiA9IGV2ZW50LlJlc291cmNlU3RhdHVzUmVhc29uID8gdGhpcy5mYWlsdXJlUmVhc29uKGFjdGl2aXR5KSA6ICcnO1xuICAgICAgfVxuICAgICAgaWYgKG1ldGFkYXRhKSB7XG4gICAgICAgIHN0YWNrVHJhY2UgPSBtZXRhZGF0YS5lbnRyeS50cmFjZSA/IGBcXG5cXHQke21ldGFkYXRhLmVudHJ5LnRyYWNlLmpvaW4oJ1xcblxcdFxcXFxfICcpfWAgOiAnJztcbiAgICAgIH1cbiAgICAgIHJlYXNvbkNvbG9yID0gY2hhbGsucmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc291cmNlTmFtZSA9IG1ldGFkYXRhID8gbWV0YWRhdGEuY29uc3RydWN0UGF0aCA6IGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkIHx8ICcnO1xuXG4gICAgY29uc3QgbG9naWNhbElkID0gcmVzb3VyY2VOYW1lICE9PSBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCA/IGAoJHtldmVudC5Mb2dpY2FsUmVzb3VyY2VJZH0pIGAgOiAnJztcblxuICAgIGluZm8oXG4gICAgICB1dGlsLmZvcm1hdChcbiAgICAgICAgJyVzIHwgJXMlcyB8ICVzIHwgJXMgfCAlcyAlcyVzJXMnLFxuICAgICAgICBldmVudC5TdGFja05hbWUsXG4gICAgICAgIHByb2dyZXNzICE9PSBmYWxzZSA/IGAke3RoaXMucHJvZ3Jlc3MoKX0gfCBgIDogJycsXG4gICAgICAgIG5ldyBEYXRlKGV2ZW50LlRpbWVzdGFtcCEpLnRvTG9jYWxlVGltZVN0cmluZygpLFxuICAgICAgICBjb2xvcihwYWRSaWdodChTVEFUVVNfV0lEVEgsIChldmVudC5SZXNvdXJjZVN0YXR1cyB8fCAnJykuc2xpY2UoMCwgU1RBVFVTX1dJRFRIKSkpLCAvLyBwYWQgbGVmdCBhbmQgdHJpbVxuICAgICAgICBwYWRSaWdodCh0aGlzLnByb3BzLnJlc291cmNlVHlwZUNvbHVtbldpZHRoLCBldmVudC5SZXNvdXJjZVR5cGUgfHwgJycpLFxuICAgICAgICBjb2xvcihjaGFsay5ib2xkKHJlc291cmNlTmFtZSkpLFxuICAgICAgICBsb2dpY2FsSWQsXG4gICAgICAgIHJlYXNvbkNvbG9yKGNoYWxrLmJvbGQoZXZlbnQuUmVzb3VyY2VTdGF0dXNSZWFzb24gPyBldmVudC5SZXNvdXJjZVN0YXR1c1JlYXNvbiA6ICcnKSksXG4gICAgICAgIHJlYXNvbkNvbG9yKHN0YWNrVHJhY2UpLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgdGhpcy5sYXN0UHJpbnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBvcnQgdGhlIGN1cnJlbnQgcHJvZ3Jlc3MgYXMgYSBbMzQvNDJdIHN0cmluZywgb3IganVzdCBbMzRdIGlmIHRoZSB0b3RhbCBpcyB1bmtub3duXG4gICAqL1xuICBwcml2YXRlIHByb2dyZXNzKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMucmVzb3VyY2VzVG90YWwgPT0gbnVsbCkge1xuICAgICAgLy8gRG9uJ3QgaGF2ZSB0b3RhbCwgc2hvdyBzaW1wbGUgY291bnQgYW5kIGhvcGUgdGhlIGh1bWFuIGtub3dzXG4gICAgICByZXR1cm4gcGFkTGVmdCgzLCB1dGlsLmZvcm1hdCgnJXMnLCB0aGlzLnJlc291cmNlc0RvbmUpKTsgLy8gbWF4IDUwMCByZXNvdXJjZXNcbiAgICB9XG5cbiAgICByZXR1cm4gdXRpbC5mb3JtYXQoXG4gICAgICAnJXMvJXMnLFxuICAgICAgcGFkTGVmdCh0aGlzLnJlc291cmNlRGlnaXRzLCB0aGlzLnJlc291cmNlc0RvbmUudG9TdHJpbmcoKSksXG4gICAgICBwYWRMZWZ0KHRoaXMucmVzb3VyY2VEaWdpdHMsIHRoaXMucmVzb3VyY2VzVG90YWwgIT0gbnVsbCA/IHRoaXMucmVzb3VyY2VzVG90YWwudG9TdHJpbmcoKSA6ICc/JyksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiBzb21lIHJlc291cmNlcyBhcmUgdGFraW5nIGEgd2hpbGUgdG8gY3JlYXRlLCBub3RpZnkgdGhlIHVzZXIgYWJvdXQgd2hhdCdzIGN1cnJlbnRseSBpbiBwcm9ncmVzc1xuICAgKi9cbiAgcHJpdmF0ZSBwcmludEluUHJvZ3Jlc3MoKSB7XG4gICAgaWYgKERhdGUubm93KCkgPCB0aGlzLmxhc3RQcmludFRpbWUgKyB0aGlzLmluUHJvZ3Jlc3NEZWxheSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLnJlc291cmNlc0luUHJvZ3Jlc3MpLmxlbmd0aCA+IDApIHtcbiAgICAgIGluZm8oXG4gICAgICAgIHV0aWwuZm9ybWF0KFxuICAgICAgICAgICclcyBDdXJyZW50bHkgaW4gcHJvZ3Jlc3M6ICVzJyxcbiAgICAgICAgICB0aGlzLnByb2dyZXNzKCksXG4gICAgICAgICAgY2hhbGsuYm9sZChPYmplY3Qua2V5cyh0aGlzLnJlc291cmNlc0luUHJvZ3Jlc3MpLmpvaW4oJywgJykpLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBXZSBjaGVhdCBhIGJpdCBoZXJlLiBUbyBwcmV2ZW50IHByaW50SW5Qcm9ncmVzcygpIGZyb20gcmVwZWF0ZWRseSB0cmlnZ2VyaW5nLFxuICAgIC8vIHdlIHNldCB0aGUgdGltZXN0YW1wIGludG8gdGhlIGZ1dHVyZS4gSXQgd2lsbCBiZSByZXNldCB3aGVuZXZlciBhIHJlZ3VsYXIgcHJpbnRcbiAgICAvLyBvY2N1cnMsIGFmdGVyIHdoaWNoIHdlIGNhbiBiZSB0cmlnZ2VyZWQgYWdhaW4uXG4gICAgdGhpcy5sYXN0UHJpbnRUaW1lID0gK0luZmluaXR5O1xuICB9XG59XG5cbi8qKlxuICogQWN0aXZpdHkgUHJpbnRlciB3aGljaCBzaG93cyB0aGUgcmVzb3VyY2VzIGN1cnJlbnRseSBiZWluZyB1cGRhdGVkXG4gKlxuICogSXQgd2lsbCBjb250aW51b3VzbHkgcmV1cGRhdGUgdGhlIHRlcm1pbmFsIGFuZCBzaG93IG9ubHkgdGhlIHJlc291cmNlc1xuICogdGhhdCBhcmUgY3VycmVudGx5IGJlaW5nIHVwZGF0ZWQsIGluIGFkZGl0aW9uIHRvIGEgcHJvZ3Jlc3MgYmFyIHdoaWNoXG4gKiBzaG93cyBob3cgZmFyIGFsb25nIHRoZSBkZXBsb3ltZW50IGlzLlxuICpcbiAqIFJlc291cmNlcyB0aGF0IGhhdmUgZmFpbGVkIHdpbGwgYWx3YXlzIGJlIHNob3duLCBhbmQgd2lsbCBiZSByZWNhcGl0dWxhdGVkXG4gKiBhbG9uZyB3aXRoIHRoZWlyIHN0YWNrIHRyYWNlIHdoZW4gdGhlIG1vbml0b3JpbmcgZW5kcy5cbiAqXG4gKiBSZXNvdXJjZXMgdGhhdCBmYWlsZWQgZGVwbG95bWVudCBiZWNhdXNlIHRoZXkgaGF2ZSBiZWVuIGNhbmNlbGxlZCBhcmVcbiAqIG5vdCBpbmNsdWRlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIEN1cnJlbnRBY3Rpdml0eVByaW50ZXIgZXh0ZW5kcyBBY3Rpdml0eVByaW50ZXJCYXNlIHtcbiAgLyoqXG4gICAqIFRoaXMgbG9va3MgdmVyeSBkaXNvcmllbnRpbmcgc2xlZXBpbmcgZm9yIDUgc2Vjb25kcy4gVXBkYXRlIHF1aWNrZXIuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdXBkYXRlU2xlZXA6IG51bWJlciA9IDJfMDAwO1xuXG4gIHByaXZhdGUgb2xkTG9nVGhyZXNob2xkOiBJb01lc3NhZ2VMZXZlbDtcbiAgcHJpdmF0ZSByZWFkb25seSBzdHJlYW06IE5vZGVKUy5Xcml0ZVN0cmVhbTtcbiAgcHJpdmF0ZSBibG9jazogUmV3cml0YWJsZUJsb2NrO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBQcmludGVyUHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5vbGRMb2dUaHJlc2hvbGQgPSBDbGlJb0hvc3QuaW5zdGFuY2UoKS5sb2dMZXZlbDtcbiAgICB0aGlzLnN0cmVhbSA9IHByb3BzLnN0cmVhbTtcbiAgICB0aGlzLmJsb2NrID0gbmV3IFJld3JpdGFibGVCbG9jayh0aGlzLnN0cmVhbSk7XG4gIH1cblxuICBwdWJsaWMgcHJpbnQoKTogdm9pZCB7XG4gICAgY29uc3QgbGluZXMgPSBbXTtcblxuICAgIC8vIEFkZCBhIHByb2dyZXNzIGJhciBhdCB0aGUgdG9wXG4gICAgY29uc3QgcHJvZ3Jlc3NXaWR0aCA9IE1hdGgubWF4KFxuICAgICAgTWF0aC5taW4oKHRoaXMuYmxvY2sud2lkdGggPz8gODApIC0gUFJPR1JFU1NCQVJfRVhUUkFfU1BBQ0UgLSAxLCBNQVhfUFJPR1JFU1NCQVJfV0lEVEgpLFxuICAgICAgTUlOX1BST0dSRVNTQkFSX1dJRFRILFxuICAgICk7XG4gICAgY29uc3QgcHJvZyA9IHRoaXMucHJvZ3Jlc3NCYXIocHJvZ3Jlc3NXaWR0aCk7XG4gICAgaWYgKHByb2cpIHtcbiAgICAgIGxpbmVzLnB1c2goJyAgJyArIHByb2csICcnKTtcbiAgICB9XG5cbiAgICAvLyBOb3JtYWxseSB3ZSdkIG9ubHkgcHJpbnQgXCJyZXNvdXJjZXMgaW4gcHJvZ3Jlc3NcIiwgYnV0IGl0J3MgYWxzbyB1c2VmdWxcbiAgICAvLyB0byBrZWVwIGFuIGV5ZSBvbiB0aGUgZmFpbHVyZXMgYW5kIGtub3cgYWJvdXQgdGhlIHNwZWNpZmljIGVycm9ycyBhc3F1aWNrbHlcbiAgICAvLyBhcyBwb3NzaWJsZSAod2hpbGUgdGhlIHN0YWNrIGlzIHN0aWxsIHJvbGxpbmcgYmFjayksIHNvIGFkZCB0aG9zZSBpbi5cbiAgICBjb25zdCB0b1ByaW50OiBTdGFja0FjdGl2aXR5W10gPSBbLi4udGhpcy5mYWlsdXJlcywgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLnJlc291cmNlc0luUHJvZ3Jlc3MpXTtcbiAgICB0b1ByaW50LnNvcnQoKGEsIGIpID0+IGEuZXZlbnQuVGltZXN0YW1wIS5nZXRUaW1lKCkgLSBiLmV2ZW50LlRpbWVzdGFtcCEuZ2V0VGltZSgpKTtcblxuICAgIGxpbmVzLnB1c2goXG4gICAgICAuLi50b1ByaW50Lm1hcCgocmVzKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbG9yID0gY29sb3JGcm9tU3RhdHVzQWN0aXZpdHkocmVzLmV2ZW50LlJlc291cmNlU3RhdHVzKTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VOYW1lID0gcmVzLm1ldGFkYXRhPy5jb25zdHJ1Y3RQYXRoID8/IHJlcy5ldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCA/PyAnJztcblxuICAgICAgICByZXR1cm4gdXRpbC5mb3JtYXQoXG4gICAgICAgICAgJyVzIHwgJXMgfCAlcyB8ICVzJXMnLFxuICAgICAgICAgIHBhZExlZnQoVElNRVNUQU1QX1dJRFRILCBuZXcgRGF0ZShyZXMuZXZlbnQuVGltZXN0YW1wISkudG9Mb2NhbGVUaW1lU3RyaW5nKCkpLFxuICAgICAgICAgIGNvbG9yKHBhZFJpZ2h0KFNUQVRVU19XSURUSCwgKHJlcy5ldmVudC5SZXNvdXJjZVN0YXR1cyB8fCAnJykuc2xpY2UoMCwgU1RBVFVTX1dJRFRIKSkpLFxuICAgICAgICAgIHBhZFJpZ2h0KHRoaXMucHJvcHMucmVzb3VyY2VUeXBlQ29sdW1uV2lkdGgsIHJlcy5ldmVudC5SZXNvdXJjZVR5cGUgfHwgJycpLFxuICAgICAgICAgIGNvbG9yKGNoYWxrLmJvbGQoc2hvcnRlbig0MCwgcmVzb3VyY2VOYW1lKSkpLFxuICAgICAgICAgIHRoaXMuZmFpbHVyZVJlYXNvbk9uTmV4dExpbmUocmVzKSxcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICB0aGlzLmJsb2NrLmRpc3BsYXlMaW5lcyhsaW5lcyk7XG4gIH1cblxuICBwdWJsaWMgc3RhcnQoKSB7XG4gICAgLy8gTmVlZCB0byBwcmV2ZW50IHRoZSB3YWl0ZXIgZnJvbSBwcmludGluZyAnc3RhY2sgbm90IHN0YWJsZScgZXZlcnkgNSBzZWNvbmRzLCBpdCBtZXNzZXNcbiAgICAvLyB3aXRoIHRoZSBvdXRwdXQgY2FsY3VsYXRpb25zLlxuICAgIHRoaXMub2xkTG9nVGhyZXNob2xkID0gQ2xpSW9Ib3N0Lmluc3RhbmNlKCkubG9nTGV2ZWw7XG4gICAgQ2xpSW9Ib3N0Lmluc3RhbmNlKCkubG9nTGV2ZWwgPSAnaW5mbyc7XG4gIH1cblxuICBwdWJsaWMgc3RvcCgpIHtcbiAgICBDbGlJb0hvc3QuaW5zdGFuY2UoKS5sb2dMZXZlbCA9IHRoaXMub2xkTG9nVGhyZXNob2xkO1xuXG4gICAgLy8gUHJpbnQgZmFpbHVyZXMgYXQgdGhlIGVuZFxuICAgIGNvbnN0IGxpbmVzID0gbmV3IEFycmF5PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IGZhaWx1cmUgb2YgdGhpcy5mYWlsdXJlcykge1xuICAgICAgLy8gUm9vdCBzdGFjayBmYWlsdXJlcyBhcmUgbm90IGludGVyZXN0aW5nXG4gICAgICBpZiAoZmFpbHVyZS5pc1N0YWNrRXZlbnQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGxpbmVzLnB1c2goXG4gICAgICAgIHV0aWwuZm9ybWF0KFxuICAgICAgICAgIGNoYWxrLnJlZCgnJXMgfCAlcyB8ICVzIHwgJXMlcycpICsgJ1xcbicsXG4gICAgICAgICAgcGFkTGVmdChUSU1FU1RBTVBfV0lEVEgsIG5ldyBEYXRlKGZhaWx1cmUuZXZlbnQuVGltZXN0YW1wISkudG9Mb2NhbGVUaW1lU3RyaW5nKCkpLFxuICAgICAgICAgIHBhZFJpZ2h0KFNUQVRVU19XSURUSCwgKGZhaWx1cmUuZXZlbnQuUmVzb3VyY2VTdGF0dXMgfHwgJycpLnNsaWNlKDAsIFNUQVRVU19XSURUSCkpLFxuICAgICAgICAgIHBhZFJpZ2h0KHRoaXMucHJvcHMucmVzb3VyY2VUeXBlQ29sdW1uV2lkdGgsIGZhaWx1cmUuZXZlbnQuUmVzb3VyY2VUeXBlIHx8ICcnKSxcbiAgICAgICAgICBzaG9ydGVuKDQwLCBmYWlsdXJlLmV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkID8/ICcnKSxcbiAgICAgICAgICB0aGlzLmZhaWx1cmVSZWFzb25Pbk5leHRMaW5lKGZhaWx1cmUpLFxuICAgICAgICApLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgdHJhY2UgPSBmYWlsdXJlLm1ldGFkYXRhPy5lbnRyeT8udHJhY2U7XG4gICAgICBpZiAodHJhY2UpIHtcbiAgICAgICAgbGluZXMucHVzaChjaGFsay5yZWQoYFxcdCR7dHJhY2Uuam9pbignXFxuXFx0XFxcXF8gJyl9XFxuYCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIERpc3BsYXkgaW4gdGhlIHNhbWUgYmxvY2sgc3BhY2UsIG90aGVyd2lzZSB3ZSdyZSBnb2luZyB0byBoYXZlIHNpbGx5IGVtcHR5IGxpbmVzLlxuICAgIHRoaXMuYmxvY2suZGlzcGxheUxpbmVzKGxpbmVzKTtcbiAgICB0aGlzLmJsb2NrLnJlbW92ZUVtcHR5TGluZXMoKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJvZ3Jlc3NCYXIod2lkdGg6IG51bWJlcikge1xuICAgIGlmICghdGhpcy5yZXNvdXJjZXNUb3RhbCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBjb25zdCBmcmFjdGlvbiA9IE1hdGgubWluKHRoaXMucmVzb3VyY2VzRG9uZSAvIHRoaXMucmVzb3VyY2VzVG90YWwsIDEpO1xuICAgIGNvbnN0IGlubmVyV2lkdGggPSBNYXRoLm1heCgxLCB3aWR0aCAtIDIpO1xuICAgIGNvbnN0IGNoYXJzID0gaW5uZXJXaWR0aCAqIGZyYWN0aW9uO1xuICAgIGNvbnN0IHJlbWFpbmRlciA9IGNoYXJzIC0gTWF0aC5mbG9vcihjaGFycyk7XG5cbiAgICBjb25zdCBmdWxsQ2hhcnMgPSBGVUxMX0JMT0NLLnJlcGVhdChNYXRoLmZsb29yKGNoYXJzKSk7XG4gICAgY29uc3QgcGFydGlhbENoYXIgPSBQQVJUSUFMX0JMT0NLW01hdGguZmxvb3IocmVtYWluZGVyICogUEFSVElBTF9CTE9DSy5sZW5ndGgpXTtcbiAgICBjb25zdCBmaWxsZXIgPSAnwrcnLnJlcGVhdChpbm5lcldpZHRoIC0gTWF0aC5mbG9vcihjaGFycykgLSAocGFydGlhbENoYXIgPyAxIDogMCkpO1xuXG4gICAgY29uc3QgY29sb3IgPSB0aGlzLnJvbGxpbmdCYWNrID8gY2hhbGsueWVsbG93IDogY2hhbGsuZ3JlZW47XG5cbiAgICByZXR1cm4gJ1snICsgY29sb3IoZnVsbENoYXJzICsgcGFydGlhbENoYXIpICsgZmlsbGVyICsgYF0gKCR7dGhpcy5yZXNvdXJjZXNEb25lfS8ke3RoaXMucmVzb3VyY2VzVG90YWx9KWA7XG4gIH1cblxuICBwcml2YXRlIGZhaWx1cmVSZWFzb25Pbk5leHRMaW5lKGFjdGl2aXR5OiBTdGFja0FjdGl2aXR5KSB7XG4gICAgcmV0dXJuIGhhc0Vycm9yTWVzc2FnZShhY3Rpdml0eS5ldmVudC5SZXNvdXJjZVN0YXR1cyA/PyAnJylcbiAgICAgID8gYFxcbiR7JyAnLnJlcGVhdChUSU1FU1RBTVBfV0lEVEggKyBTVEFUVVNfV0lEVEggKyA2KX0ke2NoYWxrLnJlZCh0aGlzLmZhaWx1cmVSZWFzb24oYWN0aXZpdHkpID8/ICcnKX1gXG4gICAgICA6ICcnO1xuICB9XG59XG5cbmNvbnN0IEZVTExfQkxPQ0sgPSAn4paIJztcbmNvbnN0IFBBUlRJQUxfQkxPQ0sgPSBbJycsICfilo8nLCAn4paOJywgJ+KWjScsICfilownLCAn4paLJywgJ+KWiicsICfiloknXTtcbmNvbnN0IE1BWF9QUk9HUkVTU0JBUl9XSURUSCA9IDYwO1xuY29uc3QgTUlOX1BST0dSRVNTQkFSX1dJRFRIID0gMTA7XG5jb25zdCBQUk9HUkVTU0JBUl9FWFRSQV9TUEFDRSA9XG4gIDIgLyogbGVhZGluZyBzcGFjZXMgKi8gKyAyIC8qIGJyYWNrZXRzICovICsgNCAvKiBwcm9ncmVzcyBudW1iZXIgZGVjb3JhdGlvbiAqLyArIDY7IC8qIDIgcHJvZ3Jlc3MgbnVtYmVycyB1cCB0byA5OTkgKi9cblxuZnVuY3Rpb24gaGFzRXJyb3JNZXNzYWdlKHN0YXR1czogc3RyaW5nKSB7XG4gIHJldHVybiBzdGF0dXMuZW5kc1dpdGgoJ19GQUlMRUQnKSB8fCBzdGF0dXMgPT09ICdST0xMQkFDS19JTl9QUk9HUkVTUycgfHwgc3RhdHVzID09PSAnVVBEQVRFX1JPTExCQUNLX0lOX1BST0dSRVNTJztcbn1cblxuZnVuY3Rpb24gY29sb3JGcm9tU3RhdHVzUmVzdWx0KHN0YXR1cz86IHN0cmluZykge1xuICBpZiAoIXN0YXR1cykge1xuICAgIHJldHVybiBjaGFsay5yZXNldDtcbiAgfVxuXG4gIGlmIChzdGF0dXMuaW5kZXhPZignRkFJTEVEJykgIT09IC0xKSB7XG4gICAgcmV0dXJuIGNoYWxrLnJlZDtcbiAgfVxuICBpZiAoc3RhdHVzLmluZGV4T2YoJ1JPTExCQUNLJykgIT09IC0xKSB7XG4gICAgcmV0dXJuIGNoYWxrLnllbGxvdztcbiAgfVxuICBpZiAoc3RhdHVzLmluZGV4T2YoJ0NPTVBMRVRFJykgIT09IC0xKSB7XG4gICAgcmV0dXJuIGNoYWxrLmdyZWVuO1xuICB9XG5cbiAgcmV0dXJuIGNoYWxrLnJlc2V0O1xufVxuXG5mdW5jdGlvbiBjb2xvckZyb21TdGF0dXNBY3Rpdml0eShzdGF0dXM/OiBzdHJpbmcpIHtcbiAgaWYgKCFzdGF0dXMpIHtcbiAgICByZXR1cm4gY2hhbGsucmVzZXQ7XG4gIH1cblxuICBpZiAoc3RhdHVzLmVuZHNXaXRoKCdfRkFJTEVEJykpIHtcbiAgICByZXR1cm4gY2hhbGsucmVkO1xuICB9XG5cbiAgaWYgKHN0YXR1cy5zdGFydHNXaXRoKCdDUkVBVEVfJykgfHwgc3RhdHVzLnN0YXJ0c1dpdGgoJ1VQREFURV8nKSB8fCBzdGF0dXMuc3RhcnRzV2l0aCgnSU1QT1JUXycpKSB7XG4gICAgcmV0dXJuIGNoYWxrLmdyZWVuO1xuICB9XG4gIC8vIEZvciBzdGFja3MsIGl0IG1heSBhbHNvIGJlICdVUEREQVRFX1JPTExCQUNLX0lOX1BST0dSRVNTJ1xuICBpZiAoc3RhdHVzLmluZGV4T2YoJ1JPTExCQUNLXycpICE9PSAtMSkge1xuICAgIHJldHVybiBjaGFsay55ZWxsb3c7XG4gIH1cbiAgaWYgKHN0YXR1cy5zdGFydHNXaXRoKCdERUxFVEVfJykpIHtcbiAgICByZXR1cm4gY2hhbGsueWVsbG93O1xuICB9XG5cbiAgcmV0dXJuIGNoYWxrLnJlc2V0O1xufVxuXG5mdW5jdGlvbiBzaG9ydGVuKG1heFdpZHRoOiBudW1iZXIsIHA6IHN0cmluZykge1xuICBpZiAocC5sZW5ndGggPD0gbWF4V2lkdGgpIHtcbiAgICByZXR1cm4gcDtcbiAgfVxuICBjb25zdCBoYWxmID0gTWF0aC5mbG9vcigobWF4V2lkdGggLSAzKSAvIDIpO1xuICByZXR1cm4gcC5zbGljZSgwLCBoYWxmKSArICcuLi4nICsgcC5zbGljZSgtaGFsZik7XG59XG5cbmNvbnN0IFRJTUVTVEFNUF9XSURUSCA9IDEyO1xuY29uc3QgU1RBVFVTX1dJRFRIID0gMjA7XG4iXX0=
|
|
166
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2stYWN0aXZpdHktbW9uaXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInN0YWNrLWFjdGl2aXR5LW1vbml0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsNkJBQTZCO0FBQzdCLDBFQUErRjtBQUcvRiw2QkFBNkI7QUFDN0IsNkRBQXdEO0FBQ3hELGlEQUF3RDtBQUV4RCxxQ0FBdUQ7QUFFdkQscUVBQStFO0FBdUgvRSxNQUFhLG9CQUFvQjtJQWlDL0IsWUFBWSxFQUNWLEdBQUcsRUFDSCxNQUFNLEVBQ04sTUFBTSxFQUNOLEtBQUssRUFDTCxTQUFTLEVBQ1QsY0FBYyxFQUNkLHFCQUFxQixFQUNyQixlQUFlLEdBQUcsSUFBSyxHQUNHOztRQTlCWixXQUFNLEdBQWEsRUFBRSxDQUFDO1FBK0JwQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUUzQixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksNkNBQW9CLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLGVBQWUsR0FBRyxlQUFlLENBQUM7UUFDdkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLHFDQUFnQixDQUFDLEdBQUcsRUFBRTtZQUN0QyxTQUFTO1lBQ1QsU0FBUyxFQUFFLE1BQUEscUJBQXFCLGFBQXJCLHFCQUFxQix1QkFBckIscUJBQXFCLENBQUUsT0FBTyxFQUFFLG1DQUFJLElBQUksQ0FBQyxHQUFHLEVBQUU7U0FDMUQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLEtBQUssQ0FBQyxLQUFLO1FBQ2hCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQzNCLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FB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LENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjtRQUVwRCxnQ0FBZ0M7UUFDaEMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUMxQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMvQyxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0NBQ0Y7QUFyT0Qsb0RBcU9DIiwic291cmNlc0NvbnRlbnQiOlsiXG5pbXBvcnQgKiBhcyB1dGlsIGZyb20gJ3V0aWwnO1xuaW1wb3J0IHsgQXJ0aWZhY3RNZXRhZGF0YUVudHJ5VHlwZSwgdHlwZSBNZXRhZGF0YUVudHJ5IH0gZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCB0eXBlIHsgQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0IH0gZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCB7IFN0YWNrRXZlbnQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtY2xvdWRmb3JtYXRpb24nO1xuaW1wb3J0ICogYXMgdXVpZCBmcm9tICd1dWlkJztcbmltcG9ydCB7IFN0YWNrRXZlbnRQb2xsZXIgfSBmcm9tICcuL3N0YWNrLWV2ZW50LXBvbGxlcic7XG5pbXBvcnQgeyBkZWJ1ZywgZXJyb3IsIGluZm8gfSBmcm9tICcuLi8uLi9jbGkvbWVzc2FnZXMnO1xuaW1wb3J0IHsgSW9NZXNzYWdpbmcgfSBmcm9tICcuLi8uLi90b29sa2l0L2NsaS1pby1ob3N0JztcbmltcG9ydCB7IHN0YWNrRXZlbnRIYXNFcnJvck1lc3NhZ2UgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB0eXBlIHsgSUNsb3VkRm9ybWF0aW9uQ2xpZW50IH0gZnJvbSAnLi4vYXdzLWF1dGgnO1xuaW1wb3J0IHsgU3RhY2tQcm9ncmVzcywgU3RhY2tQcm9ncmVzc01vbml0b3IgfSBmcm9tICcuL3N0YWNrLXByb2dyZXNzLW1vbml0b3InO1xuXG4vKipcbiAqIFBheWxvYWQgd2hlbiBzdGFjayBtb25pdG9yaW5nIGlzIHN0YXJ0aW5nIG9yIHN0b3BwaW5nIGZvciBhIGdpdmVuIHN0YWNrIGRlcGxveW1lbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RhY2tNb25pdG9yaW5nQ29udHJvbEV2ZW50IHtcbiAgLyoqXG4gICAqIEEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIGEgc3BlY2lmaWMgc3RhY2sgZGVwbG95bWVudC5cbiAgICpcbiAgICogVXNlIHRoaXMgdmFsdWUgdG8gYXR0cmlidXRlIHN0YWNrIGFjdGl2aXRpZXMgcmVjZWl2ZWQgZm9yIGNvbmN1cnJlbnQgZGVwbG95bWVudHMuXG4gICAqL1xuICByZWFkb25seSBkZXBsb3ltZW50OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBzdGFjayBhcnRpZmFjdCB0aGF0IGlzIGdldHRpbmcgZGVwbG95ZWRcbiAgICovXG4gIHJlYWRvbmx5IHN0YWNrOiBDbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Q7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBTdGFjayB0aGF0IGlzIGdldHRpbmcgZGVwbG95ZWRcbiAgICovXG4gIHJlYWRvbmx5IHN0YWNrTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUb3RhbCBudW1iZXIgb2YgcmVzb3VyY2VzIHRha2luZyBwYXJ0IGluIHRoaXMgZGVwbG95bWVudFxuICAgKlxuICAgKiBUaGUgbnVtYmVyIG1pZ2h0IG5vdCBhbHdheXMgYmUga25vd24gb3IgYWNjdXJhdGUuXG4gICAqIE9ubHkgdXNlIGZvciBpbmZvcm1hdGlvbmFsIHB1cnBvc2VzIGFuZCBoYW5kbGUgdGhlIGNhc2Ugd2hlbiBpdCdzIHVuYXZhaWxhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVzb3VyY2VzVG90YWw/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhY2tBY3Rpdml0eSB7XG4gIC8qKlxuICAgKiBBIHVuaXF1ZSBpZGVudGlmaWVyIGZvciBhIHNwZWNpZmljIHN0YWNrIGRlcGxveW1lbnQuXG4gICAqXG4gICAqIFVzZSB0aGlzIHZhbHVlIHRvIGF0dHJpYnV0ZSBzdGFjayBhY3Rpdml0aWVzIHJlY2VpdmVkIGZvciBjb25jdXJyZW50IGRlcGxveW1lbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVwbG95bWVudDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgU3RhY2sgRXZlbnQgYXMgcmVjZWl2ZWQgZnJvbSBDbG91ZEZvcm1hdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgZXZlbnQ6IFN0YWNrRXZlbnQ7XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgcmVzb3VyY2UgbWV0YWRhdGFcbiAgICovXG4gIHJlYWRvbmx5IG1ldGFkYXRhPzogUmVzb3VyY2VNZXRhZGF0YTtcblxuICAvKipcbiAgICogVGhlIHN0YWNrIHByb2dyZXNzXG4gICAqL1xuICByZWFkb25seSBwcm9ncmVzczogU3RhY2tQcm9ncmVzcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXNvdXJjZU1ldGFkYXRhIHtcbiAgZW50cnk6IE1ldGFkYXRhRW50cnk7XG4gIGNvbnN0cnVjdFBhdGg6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTdGFja0FjdGl2aXR5TW9uaXRvclByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBDbG91ZEZvcm1hdGlvbiBjbGllbnRcbiAgICovXG4gIHJlYWRvbmx5IGNmbjogSUNsb3VkRm9ybWF0aW9uQ2xpZW50O1xuXG4gIC8qKlxuICAgKiBUaGUgSW9Ib3N0IHVzZWQgZm9yIG1lc3NhZ2luZ1xuICAgKi9cbiAgcmVhZG9ubHkgaW9Ib3N0OiBJb01lc3NhZ2luZ1snaW9Ib3N0J107XG5cbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IFRvb2xraXRBY3Rpb25cbiAgICovXG4gIHJlYWRvbmx5IGFjdGlvbjogSW9NZXNzYWdpbmdbJ2FjdGlvbiddO1xuXG4gIC8qKlxuICAgKiBUaGUgc3RhY2sgYXJ0aWZhY3QgdGhhdCBpcyBnZXR0aW5nIGRlcGxveWVkXG4gICAqL1xuICByZWFkb25seSBzdGFjazogQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0O1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgU3RhY2sgdGhhdCBpcyBnZXR0aW5nIGRlcGxveWVkXG4gICAqL1xuICByZWFkb25seSBzdGFja05hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVG90YWwgbnVtYmVyIG9mIHJlc291cmNlcyB0byB1cGRhdGVcbiAgICpcbiAgICogVXNlZCB0byBjYWxjdWxhdGUgYSBwcm9ncmVzcyBiYXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gcHJvZ3Jlc3MgcmVwb3J0aW5nLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVzb3VyY2VzVG90YWw/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIENyZWF0aW9uIHRpbWUgb2YgdGhlIGNoYW5nZSBzZXRcbiAgICpcbiAgICogVGhpcyB3aWxsIGJlIHVzZWQgdG8gZmlsdGVyIGV2ZW50cywgb25seSBzaG93aW5nIHRob3NlIGZyb20gYWZ0ZXIgdGhlIGNoYW5nZVxuICAgKiBzZXQgY3JlYXRpb24gdGltZS5cbiAgICpcbiAgICogSXQgaXMgcmVjb21tZW5kZWQgdG8gdXNlIHRoaXMsIG90aGVyd2lzZSB0aGUgZmlsdGVyaW5nIHdpbGwgYmUgc3ViamVjdFxuICAgKiB0byBjbG9jayBkcmlmdCBiZXR3ZWVuIGxvY2FsIGFuZCBjbG91ZCBtYWNoaW5lcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBsb2NhbCBtYWNoaW5lJ3MgY3VycmVudCB0aW1lXG4gICAqL1xuICByZWFkb25seSBjaGFuZ2VTZXRDcmVhdGlvblRpbWU/OiBEYXRlO1xuXG4gIC8qKlxuICAgKiBUaW1lIHRvIHdhaXQgYmV0d2VlbiBmZXRjaGluZyBuZXcgYWN0aXZpdGllcy5cbiAgICpcbiAgICogTXVzdCB3YWl0IGEgcmVhc29uYWJsZSBhbW91bnQgb2YgdGltZSBiZXR3ZWVuIHBvbGxzLCBzaW5jZSB3ZSBuZWVkIHRvIGNvbnNpZGVyIENsb3VkRm9ybWF0aW9uIEFQSSBsaW1pdHNcbiAgICpcbiAgICogQGRlZmF1bHQgMl8wMDBcbiAgICovXG4gIHJlYWRvbmx5IHBvbGxpbmdJbnRlcnZhbD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNsYXNzIFN0YWNrQWN0aXZpdHlNb25pdG9yIHtcbiAgLyoqXG4gICAqIFRoZSBwb2xsZXIgdXNlZCB0byByZWFkIHN0YWNrIGV2ZW50c1xuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBwb2xsZXI6IFN0YWNrRXZlbnRQb2xsZXI7XG5cbiAgLyoqXG4gICAqIEZldGNoIG5ldyBhY3Rpdml0eSBldmVyeSAxIHNlY29uZFxuICAgKiBQcmludGVycyBjYW4gZGVjaWRlIHRvIHVwZGF0ZSBhIHZpZXcgbGVzcyBmcmVxdWVudGx5IGlmIGRlc2lyZWRcbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcG9sbGluZ0ludGVydmFsOiBudW1iZXI7XG5cbiAgcHVibGljIHJlYWRvbmx5IGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICBwcml2YXRlIG1vbml0b3JJZD86IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IHByb2dyZXNzTW9uaXRvcjogU3RhY2tQcm9ncmVzc01vbml0b3I7XG5cbiAgLyoqXG4gICAqIEN1cnJlbnQgdGljayB0aW1lclxuICAgKi9cbiAgcHJpdmF0ZSB0aWNrVGltZXI/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcblxuICAvKipcbiAgICogU2V0IHRvIHRoZSBhY3Rpdml0eSBvZiByZWFkaW5nIHRoZSBjdXJyZW50IGV2ZW50c1xuICAgKi9cbiAgcHJpdmF0ZSByZWFkUHJvbWlzZT86IFByb21pc2U8YW55PjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGlvSG9zdDogSW9NZXNzYWdpbmdbJ2lvSG9zdCddO1xuICBwcml2YXRlIHJlYWRvbmx5IGFjdGlvbjogSW9NZXNzYWdpbmdbJ2FjdGlvbiddO1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YWNrTmFtZTogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YWNrOiBDbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Q7XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIGNmbixcbiAgICBpb0hvc3QsXG4gICAgYWN0aW9uLFxuICAgIHN0YWNrLFxuICAgIHN0YWNrTmFtZSxcbiAgICByZXNvdXJjZXNUb3RhbCxcbiAgICBjaGFuZ2VTZXRDcmVhdGlvblRpbWUsXG4gICAgcG9sbGluZ0ludGVydmFsID0gMl8wMDAsXG4gIH06IFN0YWNrQWN0aXZpdHlNb25pdG9yUHJvcHMpIHtcbiAgICB0aGlzLmlvSG9zdCA9IGlvSG9zdDtcbiAgICB0aGlzLmFjdGlvbiA9IGFjdGlvbjtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5zdGFja05hbWUgPSBzdGFja05hbWU7XG5cbiAgICB0aGlzLnByb2dyZXNzTW9uaXRvciA9IG5ldyBTdGFja1Byb2dyZXNzTW9uaXRvcihyZXNvdXJjZXNUb3RhbCk7XG4gICAgdGhpcy5wb2xsaW5nSW50ZXJ2YWwgPSBwb2xsaW5nSW50ZXJ2YWw7XG4gICAgdGhpcy5wb2xsZXIgPSBuZXcgU3RhY2tFdmVudFBvbGxlcihjZm4sIHtcbiAgICAgIHN0YWNrTmFtZSxcbiAgICAgIHN0YXJ0VGltZTogY2hhbmdlU2V0Q3JlYXRpb25UaW1lPy5nZXRUaW1lKCkgPz8gRGF0ZS5ub3coKSxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzdGFydCgpIHtcbiAgICB0aGlzLm1vbml0b3JJZCA9IHV1aWQudjQoKTtcbiAgICBhd2FpdCB0aGlzLmlvSG9zdC5ub3RpZnkoZGVidWcodGhpcy5hY3Rpb24sIGBEZXBsb3lpbmcgJHt0aGlzLnN0YWNrTmFtZX1gLCAnQ0RLX1RPT0xLSVRfSTU1MDEnLCB7XG4gICAgICBkZXBsb3ltZW50OiB0aGlzLm1vbml0b3JJZCxcbiAgICAgIHN0YWNrOiB0aGlzLnN0YWNrLFxuICAgICAgc3RhY2tOYW1lOiB0aGlzLnN0YWNrTmFtZSxcbiAgICAgIHJlc291cmNlc1RvdGFsOiB0aGlzLnByb2dyZXNzTW9uaXRvci50b3RhbCxcbiAgICB9IGFzIFN0YWNrTW9uaXRvcmluZ0NvbnRyb2xFdmVudCkpO1xuICAgIHRoaXMuc2NoZWR1bGVOZXh0VGljaygpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHN0b3AoKSB7XG4gICAgY29uc3Qgb2xkTW9uaXRvcklkID0gdGhpcy5tb25pdG9ySWQhO1xuICAgIHRoaXMubW9uaXRvcklkID0gdW5kZWZpbmVkO1xuICAgIGlmICh0aGlzLnRpY2tUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGlja1RpbWVyKTtcbiAgICB9XG5cbiAgICAvLyBEbyBhIGZpbmFsIHBvbGwgZm9yIGFsbCBldmVudHMuIFRoaXMgaXMgdG8gaGFuZGxlIHRoZSBzaXR1YXRpb24gd2hlcmUgRGVzY3JpYmVTdGFja1N0YXR1c1xuICAgIC8vIGFscmVhZHkgcmV0dXJuZWQgYW4gZXJyb3IsIGJ1dCB0aGUgbW9uaXRvciBoYXNuJ3Qgc2VlbiBhbGwgdGhlIGV2ZW50cyB5ZXQgYW5kIHdlJ2QgZW5kXG4gICAgLy8gdXAgbm90IHByaW50aW5nIHRoZSBmYWlsdXJlIHJlYXNvbiB0byB1c2Vycy5cbiAgICBhd2FpdCB0aGlzLmZpbmFsUG9sbFRvRW5kKG9sZE1vbml0b3JJZCk7XG5cbiAgICBhd2FpdCB0aGlzLmlvSG9zdC5ub3RpZnkoZGVidWcodGhpcy5hY3Rpb24sIGBDb21wbGV0ZWQgJHt0aGlzLnN0YWNrTmFtZX1gLCAnQ0RLX1RPT0xLSVRfSTU1MDMnLCB7XG4gICAgICBkZXBsb3ltZW50OiBvbGRNb25pdG9ySWQsXG4gICAgICBzdGFjazogdGhpcy5zdGFjayxcbiAgICAgIHN0YWNrTmFtZTogdGhpcy5zdGFja05hbWUsXG4gICAgICByZXNvdXJjZXNUb3RhbDogdGhpcy5wcm9ncmVzc01vbml0b3IudG90YWwsXG4gICAgfSBhcyBTdGFja01vbml0b3JpbmdDb250cm9sRXZlbnQpKTtcbiAgfVxuXG4gIHByaXZhdGUgc2NoZWR1bGVOZXh0VGljaygpIHtcbiAgICBpZiAoIXRoaXMubW9uaXRvcklkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy50aWNrVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHZvaWQgdGhpcy50aWNrKCksIHRoaXMucG9sbGluZ0ludGVydmFsKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdGljaygpIHtcbiAgICBpZiAoIXRoaXMubW9uaXRvcklkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMucmVhZFByb21pc2UgPSB0aGlzLnJlYWROZXdFdmVudHModGhpcy5tb25pdG9ySWQpO1xuICAgICAgYXdhaXQgdGhpcy5yZWFkUHJvbWlzZTtcbiAgICAgIHRoaXMucmVhZFByb21pc2UgPSB1bmRlZmluZWQ7XG5cbiAgICAgIC8vIFdlIG1pZ2h0IGhhdmUgYmVlbiBzdG9wKClwZWQgd2hpbGUgdGhlIG5ldHdvcmsgY2FsbCB3YXMgaW4gcHJvZ3Jlc3MuXG4gICAgICBpZiAoIXRoaXMubW9uaXRvcklkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBhd2FpdCB0aGlzLmlvSG9zdC5ub3RpZnkoZXJyb3IoXG4gICAgICAgIHRoaXMuYWN0aW9uLFxuICAgICAgICB1dGlsLmZvcm1hdCgnRXJyb3Igb2NjdXJyZWQgd2hpbGUgbW9uaXRvcmluZyBzdGFjazogJXMnLCBlKSxcbiAgICAgICAgJ0NES19UT09MS0lUX0U1NTAwJyxcbiAgICAgICAgeyBlcnJvcjogZSB9LFxuICAgICAgKSk7XG4gICAgfVxuICAgIHRoaXMuc2NoZWR1bGVOZXh0VGljaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kTWV0YWRhdGFGb3IobG9naWNhbElkOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBSZXNvdXJjZU1ldGFkYXRhIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuc3RhY2subWFuaWZlc3Q/Lm1ldGFkYXRhO1xuICAgIGlmICghbG9naWNhbElkIHx8ICFtZXRhZGF0YSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZm9yIChjb25zdCBwYXRoIG9mIE9iamVjdC5rZXlzKG1ldGFkYXRhKSkge1xuICAgICAgY29uc3QgZW50cnkgPSBtZXRhZGF0YVtwYXRoXVxuICAgICAgICAuZmlsdGVyKChlKSA9PiBlLnR5cGUgPT09IEFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUuTE9HSUNBTF9JRClcbiAgICAgICAgLmZpbmQoKGUpID0+IGUuZGF0YSA9PT0gbG9naWNhbElkKTtcbiAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVudHJ5LFxuICAgICAgICAgIGNvbnN0cnVjdFBhdGg6IHRoaXMuc2ltcGxpZnlDb25zdHJ1Y3RQYXRoKHBhdGgpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWRzIGFsbCBuZXcgZXZlbnRzIGZyb20gdGhlIHN0YWNrIGhpc3RvcnlcbiAgICpcbiAgICogVGhlIGV2ZW50cyBhcmUgcmV0dXJuZWQgaW4gcmV2ZXJzZSBjaHJvbm9sb2dpY2FsIG9yZGVyOyB3ZSBjb250aW51ZSB0byB0aGUgbmV4dCBwYWdlIGlmIHdlXG4gICAqIHNlZSBhIG5leHQgcGFnZSBhbmQgdGhlIGxhc3QgZXZlbnQgaW4gdGhlIHBhZ2UgaXMgbmV3IHRvIHVzIChhbmQgd2l0aGluIHRoZSB0aW1lIHdpbmRvdykuXG4gICAqIGhhdmVuJ3Qgc2VlbiB0aGUgZmluYWwgZXZlbnRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVhZE5ld0V2ZW50cyhtb25pdG9ySWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBvbGxFdmVudHMgPSBhd2FpdCB0aGlzLnBvbGxlci5wb2xsKCk7XG5cbiAgICBmb3IgKGNvbnN0IHJlc291cmNlRXZlbnQgb2YgcG9sbEV2ZW50cykge1xuICAgICAgdGhpcy5wcm9ncmVzc01vbml0b3IucHJvY2VzcyhyZXNvdXJjZUV2ZW50LmV2ZW50KTtcblxuICAgICAgY29uc3QgYWN0aXZpdHk6IFN0YWNrQWN0aXZpdHkgPSB7XG4gICAgICAgIGRlcGxveW1lbnQ6IG1vbml0b3JJZCxcbiAgICAgICAgZXZlbnQ6IHJlc291cmNlRXZlbnQuZXZlbnQsXG4gICAgICAgIG1ldGFkYXRhOiB0aGlzLmZpbmRNZXRhZGF0YUZvcihyZXNvdXJjZUV2ZW50LmV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkKSxcbiAgICAgICAgcHJvZ3Jlc3M6IHRoaXMucHJvZ3Jlc3NNb25pdG9yLnByb2dyZXNzLFxuICAgICAgfTtcblxuICAgICAgdGhpcy5jaGVja0ZvckVycm9ycyhhY3Rpdml0eSk7XG4gICAgICBhd2FpdCB0aGlzLmlvSG9zdC5ub3RpZnkoaW5mbyh0aGlzLmFjdGlvbiwgdGhpcy5mb3JtYXRBY3Rpdml0eShhY3Rpdml0eSwgdHJ1ZSksICdDREtfVE9PTEtJVF9JNTUwMicsIGFjdGl2aXR5KSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gYSBmaW5hbCBwb2xsIHRvIHRoZSBlbmQgYW5kIGZsdXNoIG91dCBhbGwgZXZlbnRzIHRvIHRoZSBwcmludGVyXG4gICAqXG4gICAqIEZpbmlzaCBhbnkgcG9sbCBjdXJyZW50bHkgaW4gcHJvZ3Jlc3MsIHRoZW4gZG8gYSBmaW5hbCBvbmUgdW50aWwgd2UndmVcbiAgICogcmVhY2hlZCB0aGUgbGFzdCBwYWdlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBmaW5hbFBvbGxUb0VuZChtb25pdG9ySWQ6IHN0cmluZykge1xuICAgIC8vIElmIHdlIHdlcmUgZG9pbmcgYSBwb2xsLCBmaW5pc2ggdGhhdCBmaXJzdC4gSXQgd2FzIHN0YXJ0ZWQgYmVmb3JlXG4gICAgLy8gdGhlIG1vbWVudCB3ZSB3ZXJlIHN1cmUgd2Ugd2VyZW4ndCBnb2luZyB0byBnZXQgYW55IG5ldyBldmVudHMgYW55bW9yZVxuICAgIC8vIHNvIHdlIG5lZWQgdG8gZG8gYSBuZXcgb25lIGFueXdheS4gTmVlZCB0byB3YWl0IGZvciB0aGlzIG9uZSB0aG91Z2hcbiAgICAvLyBiZWNhdXNlIG91ciBzdGF0ZSBpcyBzaW5nbGUtdGhyZWFkZWQuXG4gICAgaWYgKHRoaXMucmVhZFByb21pc2UpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVhZFByb21pc2U7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZWFkTmV3RXZlbnRzKG1vbml0b3JJZCk7XG4gIH1cblxuICAvKipcbiAgICogRm9ybWF0cyBhIHN0YWNrIGFjdGl2aXR5IGludG8gYSBiYXNpYyBzdHJpbmdcbiAgICovXG4gIHByaXZhdGUgZm9ybWF0QWN0aXZpdHkoYWN0aXZpdHk6IFN0YWNrQWN0aXZpdHksIHByb2dyZXNzOiBib29sZWFuKTogc3RyaW5nIHtcbiAgICBjb25zdCBldmVudCA9IGFjdGl2aXR5LmV2ZW50O1xuICAgIGNvbnN0IG1ldGFkYXRhID0gYWN0aXZpdHkubWV0YWRhdGE7XG5cbiAgICBjb25zdCByZXNvdXJjZU5hbWUgPSBtZXRhZGF0YSA/IG1ldGFkYXRhLmNvbnN0cnVjdFBhdGggOiBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCB8fCAnJztcbiAgICBjb25zdCBsb2dpY2FsSWQgPSByZXNvdXJjZU5hbWUgIT09IGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkID8gYCgke2V2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkfSkgYCA6ICcnO1xuXG4gICAgcmV0dXJuIHV0aWwuZm9ybWF0KFxuICAgICAgJyVzIHwgJXMlcyB8ICVzIHwgJXMgfCAlcyAlcyVzJXMnLFxuICAgICAgZXZlbnQuU3RhY2tOYW1lLFxuICAgICAgcHJvZ3Jlc3MgIT09IGZhbHNlID8gYCR7YWN0aXZpdHkucHJvZ3Jlc3MuZm9ybWF0dGVkfSB8IGAgOiAnJyxcbiAgICAgIG5ldyBEYXRlKGV2ZW50LlRpbWVzdGFtcCEpLnRvTG9jYWxlVGltZVN0cmluZygpLFxuICAgICAgZXZlbnQuUmVzb3VyY2VTdGF0dXMgfHwgJycsXG4gICAgICBldmVudC5SZXNvdXJjZVR5cGUsXG4gICAgICByZXNvdXJjZU5hbWUsXG4gICAgICBsb2dpY2FsSWQsXG4gICAgICBldmVudC5SZXNvdXJjZVN0YXR1c1JlYXNvbiA/IGV2ZW50LlJlc291cmNlU3RhdHVzUmVhc29uIDogJycsXG4gICAgICBtZXRhZGF0YT8uZW50cnkudHJhY2UgPyBgXFxuXFx0JHttZXRhZGF0YS5lbnRyeS50cmFjZS5qb2luKCdcXG5cXHRcXFxcXyAnKX1gIDogJycsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tGb3JFcnJvcnMoYWN0aXZpdHk6IFN0YWNrQWN0aXZpdHkpIHtcbiAgICBpZiAoc3RhY2tFdmVudEhhc0Vycm9yTWVzc2FnZShhY3Rpdml0eS5ldmVudC5SZXNvdXJjZVN0YXR1cyA/PyAnJykpIHtcbiAgICAgIGNvbnN0IGlzQ2FuY2VsbGVkID0gKGFjdGl2aXR5LmV2ZW50LlJlc291cmNlU3RhdHVzUmVhc29uID8/ICcnKS5pbmRleE9mKCdjYW5jZWxsZWQnKSA+IC0xO1xuXG4gICAgICAvLyBDYW5jZWxsZWQgaXMgbm90IGFuIGludGVyZXN0aW5nIGZhaWx1cmUgcmVhc29uLCBub3IgaXMgdGhlIHN0YWNrIG1lc3NhZ2UgKHN0YWNrXG4gICAgICAvLyBtZXNzYWdlIHdpbGwganVzdCBzYXkgc29tZXRoaW5nIGxpa2UgXCJzdGFjayBmYWlsZWQgdG8gdXBkYXRlXCIpXG4gICAgICBpZiAoIWlzQ2FuY2VsbGVkICYmIGFjdGl2aXR5LmV2ZW50LlN0YWNrTmFtZSAhPT0gYWN0aXZpdHkuZXZlbnQuTG9naWNhbFJlc291cmNlSWQpIHtcbiAgICAgICAgdGhpcy5lcnJvcnMucHVzaChhY3Rpdml0eS5ldmVudC5SZXNvdXJjZVN0YXR1c1JlYXNvbiA/PyAnJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzaW1wbGlmeUNvbnN0cnVjdFBhdGgocGF0aDogc3RyaW5nKSB7XG4gICAgcGF0aCA9IHBhdGgucmVwbGFjZSgvXFwvUmVzb3VyY2UkLywgJycpO1xuICAgIHBhdGggPSBwYXRoLnJlcGxhY2UoL15cXC8vLCAnJyk7IC8vIHJlbW92ZSBcIi9cIiBwcmVmaXhcblxuICAgIC8vIHJlbW92ZSBcIjxzdGFjay1uYW1lPi9cIiBwcmVmaXhcbiAgICBpZiAocGF0aC5zdGFydHNXaXRoKHRoaXMuc3RhY2tOYW1lICsgJy8nKSkge1xuICAgICAgcGF0aCA9IHBhdGguc2xpY2UodGhpcy5zdGFja05hbWUubGVuZ3RoICsgMSk7XG4gICAgfVxuICAgIHJldHVybiBwYXRoO1xuICB9XG59XG4iXX0=
|