@aws-cdk/aws-glue-alpha 2.176.0-alpha.0 → 2.178.0-alpha.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/.jsii +6187 -3907
- package/.jsii.tabl.json.gz +0 -0
- package/.warnings.jsii.js +525 -235
- package/README.md +422 -159
- package/awslint.json +5 -5
- package/lib/code.js +4 -5
- package/lib/connection.js +15 -3
- package/lib/constants.d.ts +261 -0
- package/lib/constants.js +281 -0
- package/lib/data-format.js +5 -5
- package/lib/data-quality-ruleset.js +6 -3
- package/lib/database.js +5 -2
- package/lib/external-table.js +20 -2
- package/lib/index.d.ts +13 -2
- package/lib/index.js +14 -3
- package/lib/jobs/job.d.ts +393 -0
- package/lib/jobs/job.js +298 -0
- package/lib/jobs/pyspark-etl-job.d.ts +81 -0
- package/lib/jobs/pyspark-etl-job.js +130 -0
- package/lib/jobs/pyspark-flex-etl-job.d.ts +83 -0
- package/lib/jobs/pyspark-flex-etl-job.js +137 -0
- package/lib/jobs/pyspark-streaming-job.d.ts +81 -0
- package/lib/jobs/pyspark-streaming-job.js +130 -0
- package/lib/jobs/python-shell-job.d.ts +55 -0
- package/lib/jobs/python-shell-job.js +99 -0
- package/lib/jobs/ray-job.d.ts +44 -0
- package/lib/jobs/ray-job.js +89 -0
- package/lib/jobs/scala-spark-etl-job.d.ts +78 -0
- package/lib/jobs/scala-spark-etl-job.js +134 -0
- package/lib/jobs/scala-spark-flex-etl-job.d.ts +109 -0
- package/lib/jobs/scala-spark-flex-etl-job.js +143 -0
- package/lib/jobs/scala-spark-streaming-job.d.ts +77 -0
- package/lib/jobs/scala-spark-streaming-job.js +131 -0
- package/lib/jobs/spark-ui-utils.d.ts +53 -0
- package/lib/jobs/spark-ui-utils.js +26 -0
- package/lib/s3-table.d.ts +4 -4
- package/lib/s3-table.js +20 -2
- package/lib/schema.d.ts +1 -1
- package/lib/schema.js +2 -2
- package/lib/security-configuration.js +5 -2
- package/lib/storage-parameter.js +1 -1
- package/lib/table-base.d.ts +1 -1
- package/lib/table-base.js +2 -2
- package/lib/table-deprecated.js +1 -1
- package/lib/triggers/trigger-options.d.ts +205 -0
- package/lib/triggers/trigger-options.js +39 -0
- package/lib/triggers/workflow.d.ts +203 -0
- package/lib/triggers/workflow.js +371 -0
- package/package.json +8 -8
- package/rosetta/default.ts-fixture +1 -1
- package/lib/job-executable.d.ts +0 -384
- package/lib/job-executable.js +0 -348
- package/lib/job.d.ts +0 -574
- package/lib/job.js +0 -531
package/lib/jobs/job.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a, _b;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Job = exports.JobBase = void 0;
|
|
5
|
+
const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
|
|
6
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
7
|
+
const cloudwatch = require("aws-cdk-lib/aws-cloudwatch");
|
|
8
|
+
const events = require("aws-cdk-lib/aws-events");
|
|
9
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
10
|
+
const cdk = require("aws-cdk-lib/core");
|
|
11
|
+
const constants_1 = require("../constants");
|
|
12
|
+
/**
|
|
13
|
+
* A base class is needed to be able to import existing Jobs into a CDK app to
|
|
14
|
+
* reference as part of a larger stack or construct. JobBase has the subset
|
|
15
|
+
* of attribtues required to idenitfy and reference an existing Glue Job,
|
|
16
|
+
* as well as some CloudWatch metric conveneince functions to configure an
|
|
17
|
+
* event-driven flow using the job.
|
|
18
|
+
*/
|
|
19
|
+
class JobBase extends cdk.Resource {
|
|
20
|
+
/**
|
|
21
|
+
* Create a CloudWatch Event Rule for this Glue Job when it's in a given state
|
|
22
|
+
*
|
|
23
|
+
* @param id construct id
|
|
24
|
+
* @param options event options. Note that some values are overridden if provided, these are
|
|
25
|
+
* - eventPattern.source = ['aws.glue']
|
|
26
|
+
* - eventPattern.detailType = ['Glue Job State Change', 'Glue Job Run Status']
|
|
27
|
+
* - eventPattern.detail.jobName = [this.jobName]
|
|
28
|
+
*
|
|
29
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html#glue-event-types
|
|
30
|
+
*/
|
|
31
|
+
onEvent(id, options = {}) {
|
|
32
|
+
const rule = new events.Rule(this, id, options);
|
|
33
|
+
rule.addTarget(options.target);
|
|
34
|
+
rule.addEventPattern({
|
|
35
|
+
source: ['aws.glue'],
|
|
36
|
+
detailType: ['Glue Job State Change', 'Glue Job Run Status'],
|
|
37
|
+
detail: {
|
|
38
|
+
jobName: [this.jobName],
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
return rule;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a CloudWatch Event Rule for the transition into the input jobState.
|
|
45
|
+
*
|
|
46
|
+
* @param id construct id.
|
|
47
|
+
* @param jobState the job state.
|
|
48
|
+
* @param options optional event options.
|
|
49
|
+
*/
|
|
50
|
+
onStateChange(id, jobState, options = {}) {
|
|
51
|
+
try {
|
|
52
|
+
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_JobState(jobState);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
56
|
+
Error.captureStackTrace(error, this.onStateChange);
|
|
57
|
+
}
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
const rule = this.onEvent(id, {
|
|
61
|
+
description: `Rule triggered when Glue job ${this.jobName} is in ${jobState} state`,
|
|
62
|
+
...options,
|
|
63
|
+
});
|
|
64
|
+
rule.addEventPattern({
|
|
65
|
+
detail: {
|
|
66
|
+
state: [jobState],
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
return rule;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create a CloudWatch Event Rule matching JobState.SUCCEEDED.
|
|
73
|
+
*
|
|
74
|
+
* @param id construct id.
|
|
75
|
+
* @param options optional event options. default is {}.
|
|
76
|
+
*/
|
|
77
|
+
onSuccess(id, options = {}) {
|
|
78
|
+
return this.onStateChange(id, constants_1.JobState.SUCCEEDED, options);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Return a CloudWatch Event Rule matching FAILED state.
|
|
82
|
+
*
|
|
83
|
+
* @param id construct id.
|
|
84
|
+
* @param options optional event options. default is {}.
|
|
85
|
+
*/
|
|
86
|
+
onFailure(id, options = {}) {
|
|
87
|
+
return this.onStateChange(id, constants_1.JobState.FAILED, options);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Return a CloudWatch Event Rule matching TIMEOUT state.
|
|
91
|
+
*
|
|
92
|
+
* @param id construct id.
|
|
93
|
+
* @param options optional event options. default is {}.
|
|
94
|
+
*/
|
|
95
|
+
onTimeout(id, options = {}) {
|
|
96
|
+
return this.onStateChange(id, constants_1.JobState.TIMEOUT, options);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Create a CloudWatch metric.
|
|
100
|
+
*
|
|
101
|
+
* @param metricName name of the metric typically prefixed with `glue.driver.`, `glue.<executorId>.` or `glue.ALL.`.
|
|
102
|
+
* @param type the metric type.
|
|
103
|
+
* @param props metric options.
|
|
104
|
+
*
|
|
105
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/monitoring-awsglue-with-cloudwatch-metrics.html
|
|
106
|
+
*/
|
|
107
|
+
metric(metricName, type, props) {
|
|
108
|
+
try {
|
|
109
|
+
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_MetricType(type);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
113
|
+
Error.captureStackTrace(error, this.metric);
|
|
114
|
+
}
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
return new cloudwatch.Metric({
|
|
118
|
+
metricName,
|
|
119
|
+
namespace: 'Glue',
|
|
120
|
+
dimensionsMap: {
|
|
121
|
+
JobName: this.jobName,
|
|
122
|
+
JobRunId: 'ALL',
|
|
123
|
+
Type: type,
|
|
124
|
+
},
|
|
125
|
+
...props,
|
|
126
|
+
}).attachTo(this);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Return a CloudWatch Metric indicating job success.
|
|
130
|
+
*
|
|
131
|
+
* This metric is based on the Rule returned by no-args onSuccess() call.
|
|
132
|
+
*/
|
|
133
|
+
metricSuccess(props) {
|
|
134
|
+
return metricRule(this.metricJobStateRule('SuccessMetricRule', constants_1.JobState.SUCCEEDED), props);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Return a CloudWatch Metric indicating job failure.
|
|
138
|
+
*
|
|
139
|
+
* This metric is based on the Rule returned by no-args onFailure() call.
|
|
140
|
+
*/
|
|
141
|
+
metricFailure(props) {
|
|
142
|
+
return metricRule(this.metricJobStateRule('FailureMetricRule', constants_1.JobState.FAILED), props);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Return a CloudWatch Metric indicating job timeout.
|
|
146
|
+
*
|
|
147
|
+
* This metric is based on the Rule returned by no-args onTimeout() call.
|
|
148
|
+
*/
|
|
149
|
+
metricTimeout(props) {
|
|
150
|
+
return metricRule(this.metricJobStateRule('TimeoutMetricRule', constants_1.JobState.TIMEOUT), props);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Creates or retrieves a singleton event rule for the input job state for use with the metric JobState methods.
|
|
154
|
+
*
|
|
155
|
+
* @param id construct id.
|
|
156
|
+
* @param jobState the job state.
|
|
157
|
+
*/
|
|
158
|
+
metricJobStateRule(id, jobState) {
|
|
159
|
+
return this.node.tryFindChild(id) ?? this.onStateChange(id, jobState);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Returns the job arn
|
|
163
|
+
*/
|
|
164
|
+
buildJobArn(scope, jobName) {
|
|
165
|
+
return cdk.Stack.of(scope).formatArn({
|
|
166
|
+
service: 'glue',
|
|
167
|
+
resource: 'job',
|
|
168
|
+
resourceName: jobName,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
exports.JobBase = JobBase;
|
|
173
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
174
|
+
JobBase[_a] = { fqn: "@aws-cdk/aws-glue-alpha.JobBase", version: "2.178.0-alpha.0" };
|
|
175
|
+
/**
|
|
176
|
+
* A Glue Job.
|
|
177
|
+
* @resource AWS::Glue::Job
|
|
178
|
+
*/
|
|
179
|
+
class Job extends JobBase {
|
|
180
|
+
/**
|
|
181
|
+
* Identifies an existing Glue Job from a subset of attributes that can
|
|
182
|
+
* be referenced from within another Stack or Construct.
|
|
183
|
+
*
|
|
184
|
+
* @param scope The scope creating construct (usually `this`)
|
|
185
|
+
* @param id The construct's id.
|
|
186
|
+
* @param attrs Attributes for the Glue Job we want to import
|
|
187
|
+
*/
|
|
188
|
+
static fromJobAttributes(scope, id, attrs) {
|
|
189
|
+
try {
|
|
190
|
+
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_JobImportAttributes(attrs);
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
194
|
+
Error.captureStackTrace(error, this.fromJobAttributes);
|
|
195
|
+
}
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
class Import extends JobBase {
|
|
199
|
+
constructor() {
|
|
200
|
+
super(...arguments);
|
|
201
|
+
this.jobName = attrs.jobName;
|
|
202
|
+
this.jobArn = this.buildJobArn(scope, attrs.jobName);
|
|
203
|
+
this.grantPrincipal = attrs.role ?? new iam.UnknownPrincipal({ resource: this });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return new Import(scope, id);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Check no usage of reserved arguments.
|
|
210
|
+
*
|
|
211
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
212
|
+
*/
|
|
213
|
+
checkNoReservedArgs(defaultArguments) {
|
|
214
|
+
if (defaultArguments) {
|
|
215
|
+
const reservedArgs = new Set(['--debug', '--mode', '--JOB_NAME']);
|
|
216
|
+
Object.keys(defaultArguments).forEach((arg) => {
|
|
217
|
+
if (reservedArgs.has(arg)) {
|
|
218
|
+
throw new Error(`The ${arg} argument is reserved by Glue. Don't set it`);
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return defaultArguments;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Setup Continuous Loggiung Properties
|
|
226
|
+
* @param role The IAM role to use for continuous logging
|
|
227
|
+
* @param props The properties for continuous logging configuration
|
|
228
|
+
* @returns String containing the args for the continuous logging command
|
|
229
|
+
*/
|
|
230
|
+
setupContinuousLogging(role, props) {
|
|
231
|
+
try {
|
|
232
|
+
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_ContinuousLoggingProps(props);
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
236
|
+
Error.captureStackTrace(error, this.setupContinuousLogging);
|
|
237
|
+
}
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
// If the developer has explicitly disabled continuous logging return no args
|
|
241
|
+
if (props && !props.enabled) {
|
|
242
|
+
return {};
|
|
243
|
+
}
|
|
244
|
+
// Else we turn on continuous logging by default. Determine what log group to use.
|
|
245
|
+
const args = {
|
|
246
|
+
'--enable-continuous-cloudwatch-log': 'true',
|
|
247
|
+
};
|
|
248
|
+
if (props?.quiet) {
|
|
249
|
+
args['--enable-continuous-log-filter'] = 'true';
|
|
250
|
+
}
|
|
251
|
+
// If the developer provided a log group, add its name to the args and update the role.
|
|
252
|
+
if (props?.logGroup) {
|
|
253
|
+
args['--continuous-log-logGroup'] = props.logGroup.logGroupName;
|
|
254
|
+
props.logGroup.grantWrite(role);
|
|
255
|
+
}
|
|
256
|
+
if (props?.logStreamPrefix) {
|
|
257
|
+
args['--continuous-log-logStreamPrefix'] = props.logStreamPrefix;
|
|
258
|
+
}
|
|
259
|
+
if (props?.conversionPattern) {
|
|
260
|
+
args['--continuous-log-conversionPattern'] = props.conversionPattern;
|
|
261
|
+
}
|
|
262
|
+
return args;
|
|
263
|
+
}
|
|
264
|
+
codeS3ObjectUrl(code) {
|
|
265
|
+
try {
|
|
266
|
+
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_Code(code);
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
270
|
+
Error.captureStackTrace(error, this.codeS3ObjectUrl);
|
|
271
|
+
}
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
const s3Location = code.bind(this, this.role).s3Location;
|
|
275
|
+
return `s3://${s3Location.bucketName}/${s3Location.objectKey}`;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
exports.Job = Job;
|
|
279
|
+
_b = JSII_RTTI_SYMBOL_1;
|
|
280
|
+
Job[_b] = { fqn: "@aws-cdk/aws-glue-alpha.Job", version: "2.178.0-alpha.0" };
|
|
281
|
+
/**
|
|
282
|
+
* Create a CloudWatch Metric that's based on Glue Job events
|
|
283
|
+
* {@see https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html#glue-event-types}
|
|
284
|
+
* The metric has namespace = 'AWS/Events', metricName = 'TriggeredRules' and RuleName = rule.ruleName dimension.
|
|
285
|
+
*
|
|
286
|
+
* @param rule for use in setting RuleName dimension value
|
|
287
|
+
* @param props metric properties
|
|
288
|
+
*/
|
|
289
|
+
function metricRule(rule, props) {
|
|
290
|
+
return new cloudwatch.Metric({
|
|
291
|
+
namespace: 'AWS/Events',
|
|
292
|
+
metricName: 'TriggeredRules',
|
|
293
|
+
dimensionsMap: { RuleName: rule.ruleName },
|
|
294
|
+
statistic: cloudwatch.Statistic.SUM,
|
|
295
|
+
...props,
|
|
296
|
+
}).attachTo(rule);
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam9iLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiam9iLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHlEQUF5RDtBQUN6RCxpREFBaUQ7QUFDakQsMkNBQTJDO0FBRTNDLHdDQUF3QztBQUd4Qyw0Q0FBNkU7QUFzSDdFOzs7Ozs7R0FNRztBQUNILE1BQXNCLE9BQVEsU0FBUSxHQUFHLENBQUMsUUFBUTtJQUtoRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksT0FBTyxDQUFDLEVBQVUsRUFBRSxVQUFpQyxFQUFFO1FBQzVELE1BQU0sSUFBSSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxlQUFlLENBQUM7WUFDbkIsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDO1lBQ3BCLFVBQVUsRUFBRSxDQUFDLHVCQUF1QixFQUFFLHFCQUFxQixDQUFDO1lBQzVELE1BQU0sRUFBRTtnQkFDTixPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2FBQ3hCO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxJQUFJLENBQUM7S0FDYjtJQUVEOzs7Ozs7T0FNRztJQUNPLGFBQWEsQ0FBQyxFQUFVLEVBQUUsUUFBa0IsRUFBRSxVQUFpQyxFQUFFOzs7Ozs7Ozs7O1FBQ3pGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFO1lBQzVCLFdBQVcsRUFBRSxnQ0FBZ0MsSUFBSSxDQUFDLE9BQU8sVUFBVSxRQUFRLFFBQVE7WUFDbkYsR0FBRyxPQUFPO1NBQ1gsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUNuQixNQUFNLEVBQUU7Z0JBQ04sS0FBSyxFQUFFLENBQUMsUUFBUSxDQUFDO2FBQ2xCO1NBQ0YsQ0FBQyxD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LEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUM7WUFDaEUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsQ0FBQztRQUVELElBQUksS0FBSyxFQUFFLGVBQWUsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxrQ0FBa0MsQ0FBQyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUM7UUFDbkUsQ0FBQztRQUVELElBQUksS0FBSyxFQUFFLGlCQUFpQixFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLG9DQUFvQyxDQUFDLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixDQUFDO1FBQ3ZFLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztLQUNiO0lBRVMsZUFBZSxDQUFDLElBQVU7Ozs7Ozs7Ozs7UUFDbEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQztRQUN6RCxPQUFPLFFBQVEsVUFBVSxDQUFDLFVBQVUsSUFBSSxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUM7S0FDaEU7O0FBbEZILGtCQW1GQzs7O0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMsVUFBVSxDQUFDLElBQWtCLEVBQUUsS0FBZ0M7SUFDdEUsT0FBTyxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUM7UUFDM0IsU0FBUyxFQUFFLFlBQVk7UUFDdkIsVUFBVSxFQUFFLGdCQUFnQjtRQUM1QixhQUFhLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRTtRQUMxQyxTQUFTLEVBQUUsVUFBVSxDQUFDLFNBQVMsQ0FBQyxHQUFHO1FBQ25DLEdBQUcsS0FBSztLQUNULENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDcEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2gnO1xuaW1wb3J0ICogYXMgZXZlbnRzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1ldmVudHMnO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgbG9ncyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSAnYXdzLWNkay1saWIvY29yZSc7XG5pbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQ29kZSB9IGZyb20gJy4uJztcbmltcG9ydCB7IE1ldHJpY1R5cGUsIEpvYlN0YXRlLCBXb3JrZXJUeXBlLCBHbHVlVmVyc2lvbiB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBJQ29ubmVjdGlvbiB9IGZyb20gJy4uL2Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgSVNlY3VyaXR5Q29uZmlndXJhdGlvbiB9IGZyb20gJy4uL3NlY3VyaXR5LWNvbmZpZ3VyYXRpb24nO1xuXG4vKipcbiAqIEludGVyZmFjZSByZXByZXNlbnRpbmcgYSBuZXcgb3IgYW4gaW1wb3J0ZWQgR2x1ZSBKb2JcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJSm9iIGV4dGVuZHMgY2RrLklSZXNvdXJjZSwgaWFtLklHcmFudGFibGUge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGpvYi5cbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgam9iTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBqb2IuXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGpvYkFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGEgQ2xvdWRXYXRjaCBldmVudCBydWxlIHRyaWdnZXJlZCB3aGVuIHNvbWV0aGluZyBoYXBwZW5zIHdpdGggdGhpcyBqb2IuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L2V2ZW50cy9FdmVudFR5cGVzLmh0bWwjZ2x1ZS1ldmVudC10eXBlc1xuICAgKi9cbiAgb25FdmVudChpZDogc3RyaW5nLCBvcHRpb25zPzogZXZlbnRzLk9uRXZlbnRPcHRpb25zKTogZXZlbnRzLlJ1bGU7XG5cbiAgLyoqXG4gICAqIERlZmluZXMgYSBDbG91ZFdhdGNoIGV2ZW50IHJ1bGUgdHJpZ2dlcmVkIHdoZW4gdGhpcyBqb2IgbW92ZXMgdG8gdGhlIFNVQ0NFRURFRCBzdGF0ZS5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvZXZlbnRzL0V2ZW50VHlwZXMuaHRtbCNnbHVlLWV2ZW50LXR5cGVzXG4gICAqL1xuICBvblN1Y2Nlc3MoaWQ6IHN0cmluZywgb3B0aW9ucz86IGV2ZW50cy5PbkV2ZW50T3B0aW9ucyk6IGV2ZW50cy5SdWxlO1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGEgQ2xvdWRXYXRjaCBldmVudCBydWxlIHRyaWdnZXJlZCB3aGVuIHRoaXMgam9iIG1vdmVzIHRvIHRoZSBGQUlMRUQgc3RhdGUuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L2V2ZW50cy9FdmVudFR5cGVzLmh0bWwjZ2x1ZS1ldmVudC10eXBlc1xuICAgKi9cbiAgb25GYWlsdXJlKGlkOiBzdHJpbmcsIG9wdGlvbnM/OiBldmVudHMuT25FdmVudE9wdGlvbnMpOiBldmVudHMuUnVsZTtcblxuICAvKipcbiAgICogRGVmaW5lcyBhIENsb3VkV2F0Y2ggZXZlbnQgcnVsZSB0cmlnZ2VyZWQgd2hlbiB0aGlzIGpvYiBtb3ZlcyB0byB0aGUgVElNRU9VVCBzdGF0ZS5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvZXZlbnRzL0V2ZW50VHlwZXMuaHRtbCNnbHVlLWV2ZW50LXR5cGVzXG4gICAqL1xuICBvblRpbWVvdXQoaWQ6IHN0cmluZywgb3B0aW9ucz86IGV2ZW50cy5PbkV2ZW50T3B0aW9ucyk6IGV2ZW50cy5SdWxlO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBDbG91ZFdhdGNoIG1ldHJpYy5cbiAgICpcbiAgICogQHBhcmFtIG1ldHJpY05hbWUgbmFtZSBvZiB0aGUgbWV0cmljIHR5cGljYWxseSBwcmVmaXhlZCB3aXRoIGBnbHVlLmRyaXZlci5gLCBgZ2x1ZS48ZXhlY3V0b3JJZD4uYCBvciBgZ2x1ZS5BTEwuYC5cbiAgICogQHBhcmFtIHR5cGUgdGhlIG1ldHJpYyB0eXBlLlxuICAgKiBAcGFyYW0gcHJvcHMgbWV0cmljIG9wdGlvbnMuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL21vbml0b3JpbmctYXdzZ2x1ZS13aXRoLWNsb3Vkd2F0Y2gtbWV0cmljcy5odG1sXG4gICAqL1xuICBtZXRyaWMobWV0cmljTmFtZTogc3RyaW5nLCB0eXBlOiBNZXRyaWNUeXBlLCBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBDbG91ZFdhdGNoIE1ldHJpYyBpbmRpY2F0aW5nIGpvYiBzdWNjZXNzLlxuICAgKi9cbiAgbWV0cmljU3VjY2Vzcyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBDbG91ZFdhdGNoIE1ldHJpYyBpbmRpY2F0aW5nIGpvYiBmYWlsdXJlLlxuICAgKi9cbiAgbWV0cmljRmFpbHVyZShwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBDbG91ZFdhdGNoIE1ldHJpYyBpbmRpY2F0aW5nIGpvYiB0aW1lb3V0LlxuICAgKi9cbiAgbWV0cmljVGltZW91dChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGVuYWJsaW5nIENvbnRpbnVvdXMgTG9nZ2luZyBmb3IgR2x1ZSBKb2JzLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL21vbml0b3ItY29udGludW91cy1sb2dnaW5nLWVuYWJsZS5odG1sXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nbHVlL2xhdGVzdC9kZy9hd3MtZ2x1ZS1wcm9ncmFtbWluZy1ldGwtZ2x1ZS1hcmd1bWVudHMuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbnRpbnVvdXNMb2dnaW5nUHJvcHMge1xuICAvKipcbiAgICogRW5hYmxlIGNvbnRpbm91b3VzIGxvZ2dpbmcuXG4gICAqL1xuICByZWFkb25seSBlbmFibGVkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZ5IGEgY3VzdG9tIENsb3VkV2F0Y2ggbG9nIGdyb3VwIG5hbWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYSBsb2cgZ3JvdXAgaXMgY3JlYXRlZCB3aXRoIG5hbWUgYC9hd3MtZ2x1ZS9qb2JzL2xvZ3MtdjIvYC5cbiAgICovXG4gIHJlYWRvbmx5IGxvZ0dyb3VwPzogbG9ncy5JTG9nR3JvdXA7XG5cbiAgLyoqXG4gICAqIFNwZWNpZnkgYSBjdXN0b20gQ2xvdWRXYXRjaCBsb2cgc3RyZWFtIHByZWZpeC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0aGUgam9iIHJ1biBJRC5cbiAgICovXG4gIHJlYWRvbmx5IGxvZ1N0cmVhbVByZWZpeD86IHN0cmluZztcblxuICAvKipcbiAgICogRmlsdGVyIG91dCBub24tdXNlZnVsIEFwYWNoZSBTcGFyayBkcml2ZXIvZXhlY3V0b3IgYW5kIEFwYWNoZSBIYWRvb3AgWUFSTiBoZWFydGJlYXQgbG9nIG1lc3NhZ2VzLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBxdWlldD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEFwcGx5IHRoZSBwcm92aWRlZCBjb252ZXJzaW9uIHBhdHRlcm4uXG4gICAqXG4gICAqIFRoaXMgaXMgYSBMb2c0aiBDb252ZXJzaW9uIFBhdHRlcm4gdG8gY3VzdG9taXplIGRyaXZlciBhbmQgZXhlY3V0b3IgbG9ncy5cbiAgICpcbiAgICogQGRlZmF1bHQgYCVke3l5L01NL2RkIEhIOm1tOnNzfSAlcCAlY3sxfTogJW0lbmBcbiAgICovXG4gIHJlYWRvbmx5IGNvbnZlcnNpb25QYXR0ZXJuPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgYmFzZSBjbGFzcyBpcyBuZWVkZWQgdG8gYmUgYWJsZSB0byBpbXBvcnQgZXhpc3RpbmcgSm9icyBpbnRvIGEgQ0RLIGFwcCB0b1xuICogcmVmZXJlbmNlIGFzIHBhcnQgb2YgYSBsYXJnZXIgc3RhY2sgb3IgY29uc3RydWN0LiBKb2JCYXNlIGhhcyB0aGUgc3Vic2V0XG4gKiBvZiBhdHRyaWJ0dWVzIHJlcXVpcmVkIHRvIGlkZW5pdGZ5IGFuZCByZWZlcmVuY2UgYW4gZXhpc3RpbmcgR2x1ZSBKb2IsXG4gKiBhcyB3ZWxsIGFzIHNvbWUgQ2xvdWRXYXRjaCBtZXRyaWMgY29udmVuZWluY2UgZnVuY3Rpb25zIHRvIGNvbmZpZ3VyZSBhblxuICogZXZlbnQtZHJpdmVuIGZsb3cgdXNpbmcgdGhlIGpvYi5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEpvYkJhc2UgZXh0ZW5kcyBjZGsuUmVzb3VyY2UgaW1wbGVtZW50cyBJSm9iIHtcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IGpvYkFybjogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgam9iTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgZ3JhbnRQcmluY2lwYWw6IGlhbS5JUHJpbmNpcGFsO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBDbG91ZFdhdGNoIEV2ZW50IFJ1bGUgZm9yIHRoaXMgR2x1ZSBKb2Igd2hlbiBpdCdzIGluIGEgZ2l2ZW4gc3RhdGVcbiAgICpcbiAgICogQHBhcmFtIGlkIGNvbnN0cnVjdCBpZFxuICAgKiBAcGFyYW0gb3B0aW9ucyBldmVudCBvcHRpb25zLiBOb3RlIHRoYXQgc29tZSB2YWx1ZXMgYXJlIG92ZXJyaWRkZW4gaWYgcHJvdmlkZWQsIHRoZXNlIGFyZVxuICAgKiAgLSBldmVudFBhdHRlcm4uc291cmNlID0gWydhd3MuZ2x1ZSddXG4gICAqICAtIGV2ZW50UGF0dGVybi5kZXRhaWxUeXBlID0gWydHbHVlIEpvYiBTdGF0ZSBDaGFuZ2UnLCAnR2x1ZSBKb2IgUnVuIFN0YXR1cyddXG4gICAqICAtIGV2ZW50UGF0dGVybi5kZXRhaWwuam9iTmFtZSA9IFt0aGlzLmpvYk5hbWVdXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L2V2ZW50cy9FdmVudFR5cGVzLmh0bWwjZ2x1ZS1ldmVudC10eXBlc1xuICAgKi9cbiAgcHVibGljIG9uRXZlbnQoaWQ6IHN0cmluZywgb3B0aW9uczogZXZlbnRzLk9uRXZlbnRPcHRpb25zID0ge30pOiBldmVudHMuUnVsZSB7XG4gICAgY29uc3QgcnVsZSA9IG5ldyBldmVudHMuUnVsZSh0aGlzLCBpZCwgb3B0aW9ucyk7XG4gICAgcnVsZS5hZGRUYXJnZXQob3B0aW9ucy50YXJnZXQpO1xuICAgIHJ1bGUuYWRkRXZlbnRQYXR0ZXJuKHtcbiAgICAgIHNvdXJjZTogWydhd3MuZ2x1ZSddLFxuICAgICAgZGV0YWlsVHlwZTogWydHbHVlIEpvYiBTdGF0ZSBDaGFuZ2UnLCAnR2x1ZSBKb2IgUnVuIFN0YXR1cyddLFxuICAgICAgZGV0YWlsOiB7XG4gICAgICAgIGpvYk5hbWU6IFt0aGlzLmpvYk5hbWVdLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gcnVsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBDbG91ZFdhdGNoIEV2ZW50IFJ1bGUgZm9yIHRoZSB0cmFuc2l0aW9uIGludG8gdGhlIGlucHV0IGpvYlN0YXRlLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgY29uc3RydWN0IGlkLlxuICAgKiBAcGFyYW0gam9iU3RhdGUgdGhlIGpvYiBzdGF0ZS5cbiAgICogQHBhcmFtIG9wdGlvbnMgb3B0aW9uYWwgZXZlbnQgb3B0aW9ucy5cbiAgICovXG4gIHByb3RlY3RlZCBvblN0YXRlQ2hhbmdlKGlkOiBzdHJpbmcsIGpvYlN0YXRlOiBKb2JTdGF0ZSwgb3B0aW9uczogZXZlbnRzLk9uRXZlbnRPcHRpb25zID0ge30pOiBldmVudHMuUnVsZSB7XG4gICAgY29uc3QgcnVsZSA9IHRoaXMub25FdmVudChpZCwge1xuICAgICAgZGVzY3JpcHRpb246IGBSdWxlIHRyaWdnZXJlZCB3aGVuIEdsdWUgam9iICR7dGhpcy5qb2JOYW1lfSBpcyBpbiAke2pvYlN0YXRlfSBzdGF0ZWAsXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH0pO1xuICAgIHJ1bGUuYWRkRXZlbnRQYXR0ZXJuKHtcbiAgICAgIGRldGFpbDoge1xuICAgICAgICBzdGF0ZTogW2pvYlN0YXRlXSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHJ1bGU7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgQ2xvdWRXYXRjaCBFdmVudCBSdWxlIG1hdGNoaW5nIEpvYlN0YXRlLlNVQ0NFRURFRC5cbiAgICpcbiAgICogQHBhcmFtIGlkIGNvbnN0cnVjdCBpZC5cbiAgICogQHBhcmFtIG9wdGlvbnMgb3B0aW9uYWwgZXZlbnQgb3B0aW9ucy4gZGVmYXVsdCBpcyB7fS5cbiAgICovXG4gIHB1YmxpYyBvblN1Y2Nlc3MoaWQ6IHN0cmluZywgb3B0aW9uczogZXZlbnRzLk9uRXZlbnRPcHRpb25zID0ge30pOiBldmVudHMuUnVsZSB7XG4gICAgcmV0dXJuIHRoaXMub25TdGF0ZUNoYW5nZShpZCwgSm9iU3RhdGUuU1VDQ0VFREVELCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBDbG91ZFdhdGNoIEV2ZW50IFJ1bGUgbWF0Y2hpbmcgRkFJTEVEIHN0YXRlLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgY29uc3RydWN0IGlkLlxuICAgKiBAcGFyYW0gb3B0aW9ucyBvcHRpb25hbCBldmVudCBvcHRpb25zLiBkZWZhdWx0IGlzIHt9LlxuICAgKi9cbiAgcHVibGljIG9uRmFpbHVyZShpZDogc3RyaW5nLCBvcHRpb25zOiBldmVudHMuT25FdmVudE9wdGlvbnMgPSB7fSk6IGV2ZW50cy5SdWxlIHtcbiAgICByZXR1cm4gdGhpcy5vblN0YXRlQ2hhbmdlKGlkLCBKb2JTdGF0ZS5GQUlMRUQsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIENsb3VkV2F0Y2ggRXZlbnQgUnVsZSBtYXRjaGluZyBUSU1FT1VUIHN0YXRlLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgY29uc3RydWN0IGlkLlxuICAgKiBAcGFyYW0gb3B0aW9ucyBvcHRpb25hbCBldmVudCBvcHRpb25zLiBkZWZhdWx0IGlzIHt9LlxuICAgKi9cbiAgcHVibGljIG9uVGltZW91dChpZDogc3RyaW5nLCBvcHRpb25zOiBldmVudHMuT25FdmVudE9wdGlvbnMgPSB7fSk6IGV2ZW50cy5SdWxlIHtcbiAgICByZXR1cm4gdGhpcy5vblN0YXRlQ2hhbmdlKGlkLCBKb2JTdGF0ZS5USU1FT1VULCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBDbG91ZFdhdGNoIG1ldHJpYy5cbiAgICpcbiAgICogQHBhcmFtIG1ldHJpY05hbWUgbmFtZSBvZiB0aGUgbWV0cmljIHR5cGljYWxseSBwcmVmaXhlZCB3aXRoIGBnbHVlLmRyaXZlci5gLCBgZ2x1ZS48ZXhlY3V0b3JJZD4uYCBvciBgZ2x1ZS5BTEwuYC5cbiAgICogQHBhcmFtIHR5cGUgdGhlIG1ldHJpYyB0eXBlLlxuICAgKiBAcGFyYW0gcHJvcHMgbWV0cmljIG9wdGlvbnMuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL21vbml0b3JpbmctYXdzZ2x1ZS13aXRoLWNsb3Vkd2F0Y2gtbWV0cmljcy5odG1sXG4gICAqL1xuICBwdWJsaWMgbWV0cmljKG1ldHJpY05hbWU6IHN0cmluZywgdHlwZTogTWV0cmljVHlwZSwgcHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICBtZXRyaWNOYW1lLFxuICAgICAgbmFtZXNwYWNlOiAnR2x1ZScsXG4gICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgIEpvYk5hbWU6IHRoaXMuam9iTmFtZSxcbiAgICAgICAgSm9iUnVuSWQ6ICdBTEwnLFxuICAgICAgICBUeXBlOiB0eXBlLFxuICAgICAgfSxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pLmF0dGFjaFRvKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIENsb3VkV2F0Y2ggTWV0cmljIGluZGljYXRpbmcgam9iIHN1Y2Nlc3MuXG4gICAqXG4gICAqIFRoaXMgbWV0cmljIGlzIGJhc2VkIG9uIHRoZSBSdWxlIHJldHVybmVkIGJ5IG5vLWFyZ3Mgb25TdWNjZXNzKCkgY2FsbC5cbiAgICovXG4gIHB1YmxpYyBtZXRyaWNTdWNjZXNzKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiBtZXRyaWNSdWxlKHRoaXMubWV0cmljSm9iU3RhdGVSdWxlKCdTdWNjZXNzTWV0cmljUnVsZScsIEpvYlN0YXRlLlNVQ0NFRURFRCksIHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBDbG91ZFdhdGNoIE1ldHJpYyBpbmRpY2F0aW5nIGpvYiBmYWlsdXJlLlxuICAgKlxuICAgKiBUaGlzIG1ldHJpYyBpcyBiYXNlZCBvbiB0aGUgUnVsZSByZXR1cm5lZCBieSBuby1hcmdzIG9uRmFpbHVyZSgpIGNhbGwuXG4gICAqL1xuICBwdWJsaWMgbWV0cmljRmFpbHVyZShwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gbWV0cmljUnVsZSh0aGlzLm1ldHJpY0pvYlN0YXRlUnVsZSgnRmFpbHVyZU1ldHJpY1J1bGUnLCBKb2JTdGF0ZS5GQUlMRUQpLCBwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgQ2xvdWRXYXRjaCBNZXRyaWMgaW5kaWNhdGluZyBqb2IgdGltZW91dC5cbiAgICpcbiAgICogVGhpcyBtZXRyaWMgaXMgYmFzZWQgb24gdGhlIFJ1bGUgcmV0dXJuZWQgYnkgbm8tYXJncyBvblRpbWVvdXQoKSBjYWxsLlxuICAgKi9cbiAgcHVibGljIG1ldHJpY1RpbWVvdXQocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgcmV0dXJuIG1ldHJpY1J1bGUodGhpcy5tZXRyaWNKb2JTdGF0ZVJ1bGUoJ1RpbWVvdXRNZXRyaWNSdWxlJywgSm9iU3RhdGUuVElNRU9VVCksIHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIG9yIHJldHJpZXZlcyBhIHNpbmdsZXRvbiBldmVudCBydWxlIGZvciB0aGUgaW5wdXQgam9iIHN0YXRlIGZvciB1c2Ugd2l0aCB0aGUgbWV0cmljIEpvYlN0YXRlIG1ldGhvZHMuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBjb25zdHJ1Y3QgaWQuXG4gICAqIEBwYXJhbSBqb2JTdGF0ZSB0aGUgam9iIHN0YXRlLlxuICAgKi9cbiAgcHJpdmF0ZSBtZXRyaWNKb2JTdGF0ZVJ1bGUoaWQ6IHN0cmluZywgam9iU3RhdGU6IEpvYlN0YXRlKTogZXZlbnRzLlJ1bGUge1xuICAgIHJldHVybiB0aGlzLm5vZGUudHJ5RmluZENoaWxkKGlkKSBhcyBldmVudHMuUnVsZSA/PyB0aGlzLm9uU3RhdGVDaGFuZ2UoaWQsIGpvYlN0YXRlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBqb2IgYXJuXG4gICAqL1xuICBwcm90ZWN0ZWQgYnVpbGRKb2JBcm4oc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LCBqb2JOYW1lOiBzdHJpbmcpIDogc3RyaW5nIHtcbiAgICByZXR1cm4gY2RrLlN0YWNrLm9mKHNjb3BlKS5mb3JtYXRBcm4oe1xuICAgICAgc2VydmljZTogJ2dsdWUnLFxuICAgICAgcmVzb3VyY2U6ICdqb2InLFxuICAgICAgcmVzb3VyY2VOYW1lOiBqb2JOYW1lLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogQSBzdWJzZXQgb2YgSm9iIGF0dHJpYnV0ZXMgYXJlIHJlcXVpcmVkIGZvciBpbXBvcnRpbmcgYW4gZXhpc3Rpbmcgam9iXG4gKiBpbnRvIGEgQ0RLIHByb2plY3QuIFRoaXMgaXMgaW9ubHkgdXNlZCB3aGVuIHVzaW5nIGZyb21Kb2JBdHRyaWJ1dGVzXG4gKiB0byBpZGVudGlmeSBhbmQgcmVmZXJlbmNlIHRoZSBleGlzdGluZyBqb2IuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSm9iSW1wb3J0QXR0cmlidXRlcyB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgam9iLlxuICAgKi9cbiAgcmVhZG9ubHkgam9iTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgSUFNIHJvbGUgYXNzdW1lZCBieSBHbHVlIHRvIHJ1biB0aGlzIGpvYi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB1bmRlZmluZWRcbiAgICovXG4gIHJlYWRvbmx5IHJvbGU/OiBpYW0uSVJvbGU7XG5cbn1cblxuLyoqXG4gKiBKb2JQcm9wZXJ0aWVzIHdpbGwgYmUgdXNlZCB0byBjcmVhdGUgbmV3IEdsdWUgSm9icyB1c2luZyB0aGlzIEwyIENvbnN0cnVjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBKb2JQcm9wZXJ0aWVzIHtcbiAgLyoqXG4gICAqIFNjcmlwdCBDb2RlIExvY2F0aW9uIChyZXF1aXJlZClcbiAgICogU2NyaXB0IHRvIHJ1biB3aGVuIHRoZSBHbHVlIGpvYiBleGVjdXRlcy4gQ2FuIGJlIHVwbG9hZGVkXG4gICAqIGZyb20gdGhlIGxvY2FsIGRpcmVjdG9yeSBzdHJ1Y3R1cmUgdXNpbmcgZnJvbUFzc2V0XG4gICAqIG9yIHJlZmVyZW5jZWQgdmlhIFMzIGxvY2F0aW9uIHVzaW5nIGZyb21CdWNrZXRcbiAgICovXG4gIHJlYWRvbmx5IHNjcmlwdDogQ29kZTtcblxuICAvKipcbiAgICogSUFNIFJvbGUgKHJlcXVpcmVkKVxuICAgKiBJQU0gUm9sZSB0byB1c2UgZm9yIEdsdWUgam9iIGV4ZWN1dGlvblxuICAgKiBNdXN0IGJlIHNwZWNpZmllZCBieSB0aGUgZGV2ZWxvcGVyIGJlY2F1c2UgdGhlIEwyIGRvZXNuJ3QgaGF2ZSB2aXNpYmlsaXR5XG4gICAqIGludG8gdGhlIGFjdGlvbnMgdGhlIHNjcmlwdChzKSB0YWtlcyBkdXJpbmcgdGhlIGpvYiBleGVjdXRpb25cbiAgICogVGhlIHJvbGUgbXVzdCB0cnVzdCB0aGUgR2x1ZSBzZXJ2aWNlIHByaW5jaXBhbCAoZ2x1ZS5hbWF6b25hd3MuY29tKVxuICAgKiBhbmQgYmUgZ3JhbnRlZCBzdWZmaWNpZW50IHBlcm1pc3Npb25zLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nbHVlL2xhdGVzdC9kZy9nZXR0aW5nLXN0YXJ0ZWQtYWNjZXNzLmh0bWxcbiAgICovXG4gIHJlYWRvbmx5IHJvbGU6IGlhbS5JUm9sZTtcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgR2x1ZSBqb2IgKG9wdGlvbmFsKVxuICAgKiBEZXZlbG9wZXItc3BlY2lmaWVkIG5hbWUgb2YgdGhlIEdsdWUgam9iXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYSBuYW1lIGlzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkXG4gICAqL1xuICByZWFkb25seSBqb2JOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEZXNjcmlwdGlvbiAob3B0aW9uYWwpXG4gICAqIERldmVsb3Blci1zcGVjaWZpZWQgZGVzY3JpcHRpb24gb2YgdGhlIEdsdWUgam9iXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gdmFsdWVcbiAgICovXG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgV29ya2VycyAob3B0aW9uYWwpXG4gICAqIE51bWJlciBvZiB3b3JrZXJzIGZvciBHbHVlIHRvIHVzZSBkdXJpbmcgam9iIGV4ZWN1dGlvblxuICAgKlxuICAgKiBAZGVmYXVsdCAxMFxuICAgKi9cbiAgcmVhZG9ubHkgbnVtYmVyT2ZXb3JrZXJzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXb3JrZXIgVHlwZSAob3B0aW9uYWwpXG4gICAqIFR5cGUgb2YgV29ya2VyIGZvciBHbHVlIHRvIHVzZSBkdXJpbmcgam9iIGV4ZWN1dGlvblxuICAgKiBFbnVtIG9wdGlvbnM6IFN0YW5kYXJkLCBHXzFYLCBHXzJYLCBHXzAyNVguIEdfNFgsIEdfOFgsIFpfMlhcbiAgICpcbiAgICogQGRlZmF1bHQgV29ya2VyVHlwZS5HXzFYXG4gICAqL1xuICByZWFkb25seSB3b3JrZXJUeXBlPzogV29ya2VyVHlwZTtcblxuICAvKipcbiAgICogTWF4IENvbmN1cnJlbnQgUnVucyAob3B0aW9uYWwpXG4gICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBydW5zIHRoaXMgR2x1ZSBqb2IgY2FuIGNvbmN1cnJlbnRseSBydW5cbiAgICpcbiAgICogQW4gZXJyb3IgaXMgcmV0dXJuZWQgd2hlbiB0aGlzIHRocmVzaG9sZCBpcyByZWFjaGVkLiBUaGUgbWF4aW11bSB2YWx1ZVxuICAgKiB5b3UgY2FuIHNwZWNpZnkgaXMgY29udHJvbGxlZCBieSBhIHNlcnZpY2UgbGltaXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IDFcbiAgICovXG4gIHJlYWRvbmx5IG1heENvbmN1cnJlbnRSdW5zPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IEFyZ3VtZW50cyAob3B0aW9uYWwpXG4gICAqIFRoZSBkZWZhdWx0IGFyZ3VtZW50cyBmb3IgZXZlcnkgcnVuIG9mIHRoaXMgR2x1ZSBqb2IsXG4gICAqIHNwZWNpZmllZCBhcyBuYW1lLXZhbHVlIHBhaXJzLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nbHVlL2xhdGVzdC9kZy9hd3MtZ2x1ZS1wcm9ncmFtbWluZy1ldGwtZ2x1ZS1hcmd1bWVudHMuaHRtbFxuICAgKiBmb3IgYSBsaXN0IG9mIHJlc2VydmVkIHBhcmFtZXRlcnNcbiAgICogQGRlZmF1bHQgLSBubyBhcmd1bWVudHNcbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRBcmd1bWVudHM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gIC8qKlxuICAgKiBDb25uZWN0aW9ucyAob3B0aW9uYWwpXG4gICAqIExpc3Qgb2YgY29ubmVjdGlvbnMgdG8gdXNlIGZvciB0aGlzIEdsdWUgam9iXG4gICAqIENvbm5lY3Rpb25zIGFyZSB1c2VkIHRvIGNvbm5lY3QgdG8gb3RoZXIgQVdTIFNlcnZpY2Ugb3IgcmVzb3VyY2VzIHdpdGhpbiBhIFZQQy5cbiAgICpcbiAgICogQGRlZmF1bHQgW10gLSBubyBjb25uZWN0aW9ucyBhcmUgYWRkZWQgdG8gdGhlIGpvYlxuICAgKi9cbiAgcmVhZG9ubHkgY29ubmVjdGlvbnM/OiBJQ29ubmVjdGlvbltdO1xuXG4gIC8qKlxuICAgKiBNYXggUmV0cmllcyAob3B0aW9uYWwpXG4gICAqIE1heGltdW0gbnVtYmVyIG9mIHJldHJ5IGF0dGVtcHRzIEdsdWUgcGVyZm9ybXMgaWYgdGhlIGpvYiBmYWlsc1xuICAgKlxuICAgKiBAZGVmYXVsdCAwXG4gICAqL1xuICByZWFkb25seSBtYXhSZXRyaWVzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaW1lb3V0IChvcHRpb25hbClcbiAgICogVGhlIG1heGltdW0gdGltZSB0aGF0IGEgam9iIHJ1biBjYW4gY29uc3VtZSByZXNvdXJjZXMgYmVmb3JlIGl0IGlzXG4gICAqIHRlcm1pbmF0ZWQgYW5kIGVudGVycyBUSU1FT1VUIHN0YXR1cy4gU3BlY2lmaWVkIGluIG1pbnV0ZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IDI4ODAgKDIgZGF5cyBmb3Igbm9uLXN0cmVhbWluZylcbiAgICpcbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBjZGsuRHVyYXRpb247XG5cbiAgLyoqXG4gICAqIFNlY3VyaXR5IENvbmZpZ3VyYXRpb24gKG9wdGlvbmFsKVxuICAgKiBEZWZpbmVzIHRoZSBlbmNyeXB0aW9uIG9wdGlvbnMgZm9yIHRoZSBHbHVlIGpvYlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHNlY3VyaXR5IGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUNvbmZpZ3VyYXRpb24/OiBJU2VjdXJpdHlDb25maWd1cmF0aW9uO1xuXG4gIC8qKlxuICAgKiBUYWdzIChvcHRpb25hbClcbiAgICogQSBsaXN0IG9mIGtleTp2YWx1ZSBwYWlycyBvZiB0YWdzIHRvIGFwcGx5IHRvIHRoaXMgR2x1ZSBqb2IgcmVzb3VyY2VzXG4gICAqXG4gICAqIEBkZWZhdWx0IHt9IC0gbm8gdGFnc1xuICAgKi9cbiAgcmVhZG9ubHkgdGFncz86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG5cbiAgLyoqXG4gICAqIEdsdWUgVmVyc2lvblxuICAgKiBUaGUgdmVyc2lvbiBvZiBHbHVlIHRvIHVzZSB0byBleGVjdXRlIHRoaXMgam9iXG4gICAqXG4gICAqIEBkZWZhdWx0IDMuMCBmb3IgRVRMXG4gICAqL1xuICByZWFkb25seSBnbHVlVmVyc2lvbj86IEdsdWVWZXJzaW9uO1xuXG4gIC8qKlxuICAgKiBFbmFibGVzIHRoZSBjb2xsZWN0aW9uIG9mIG1ldHJpY3MgZm9yIGpvYiBwcm9maWxpbmcuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gcHJvZmlsaW5nIG1ldHJpY3MgZW1pdHRlZC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2x1ZS9sYXRlc3QvZGcvYXdzLWdsdWUtcHJvZ3JhbW1pbmctZXRsLWdsdWUtYXJndW1lbnRzLmh0bWxcbiAgICovXG4gIHJlYWRvbmx5IGVuYWJsZVByb2ZpbGluZ01ldHJpY3M/IDpib29sZWFuO1xuXG4gIC8qKlxuICAgKiBFbmFibGVzIGNvbnRpbnVvdXMgbG9nZ2luZyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJvcHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gY29udGludW91cyBsb2dnaW5nIGlzIGVuYWJsZWQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL21vbml0b3ItY29udGludW91cy1sb2dnaW5nLWVuYWJsZS5odG1sXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL2F3cy1nbHVlLXByb2dyYW1taW5nLWV0bC1nbHVlLWFyZ3VtZW50cy5odG1sXG4gICAqKi9cbiAgcmVhZG9ubHkgY29udGludW91c0xvZ2dpbmc/OiBDb250aW51b3VzTG9nZ2luZ1Byb3BzO1xufVxuXG4vKipcbiAqIEEgR2x1ZSBKb2IuXG4gKiBAcmVzb3VyY2UgQVdTOjpHbHVlOjpKb2JcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEpvYiBleHRlbmRzIEpvYkJhc2Uge1xuICAvKipcbiAgICogSWRlbnRpZmllcyBhbiBleGlzdGluZyBHbHVlIEpvYiBmcm9tIGEgc3Vic2V0IG9mIGF0dHJpYnV0ZXMgdGhhdCBjYW5cbiAgICogYmUgcmVmZXJlbmNlZCBmcm9tIHdpdGhpbiBhbm90aGVyIFN0YWNrIG9yIENvbnN0cnVjdC5cbiAgICpcbiAgICogQHBhcmFtIHNjb3BlIFRoZSBzY29wZSBjcmVhdGluZyBjb25zdHJ1Y3QgKHVzdWFsbHkgYHRoaXNgKVxuICAgKiBAcGFyYW0gaWQgVGhlIGNvbnN0cnVjdCdzIGlkLlxuICAgKiBAcGFyYW0gYXR0cnMgQXR0cmlidXRlcyBmb3IgdGhlIEdsdWUgSm9iIHdlIHdhbnQgdG8gaW1wb3J0XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21Kb2JBdHRyaWJ1dGVzKHNjb3BlOiBjb25zdHJ1Y3RzLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgYXR0cnM6IEpvYkltcG9ydEF0dHJpYnV0ZXMpOiBJSm9iIHtcbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBKb2JCYXNlIHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBqb2JOYW1lID0gYXR0cnMuam9iTmFtZTtcbiAgICAgIHB1YmxpYyByZWFkb25seSBqb2JBcm4gPSB0aGlzLmJ1aWxkSm9iQXJuKHNjb3BlLCBhdHRycy5qb2JOYW1lKTtcbiAgICAgIHB1YmxpYyByZWFkb25seSBncmFudFByaW5jaXBhbCA9IGF0dHJzLnJvbGUgPz8gbmV3IGlhbS5Vbmtub3duUHJpbmNpcGFsKHsgcmVzb3VyY2U6IHRoaXMgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgSUFNIHJvbGUgR2x1ZSBhc3N1bWVzIHRvIHJ1biB0aGlzIGpvYi5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhYnN0cmFjdCByb2xlOiBpYW0uSVJvbGU7XG5cbiAgLyoqXG4gICAqIENoZWNrIG5vIHVzYWdlIG9mIHJlc2VydmVkIGFyZ3VtZW50cy5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2x1ZS9sYXRlc3QvZGcvYXdzLWdsdWUtcHJvZ3JhbW1pbmctZXRsLWdsdWUtYXJndW1lbnRzLmh0bWxcbiAgICovXG4gIHByb3RlY3RlZCBjaGVja05vUmVzZXJ2ZWRBcmdzKGRlZmF1bHRBcmd1bWVudHM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KSB7XG4gICAgaWYgKGRlZmF1bHRBcmd1bWVudHMpIHtcbiAgICAgIGNvbnN0IHJlc2VydmVkQXJncyA9IG5ldyBTZXQoWyctLWRlYnVnJywgJy0tbW9kZScsICctLUpPQl9OQU1FJ10pO1xuICAgICAgT2JqZWN0LmtleXMoZGVmYXVsdEFyZ3VtZW50cykuZm9yRWFjaCgoYXJnKSA9PiB7XG4gICAgICAgIGlmIChyZXNlcnZlZEFyZ3MuaGFzKGFyZykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSAke2FyZ30gYXJndW1lbnQgaXMgcmVzZXJ2ZWQgYnkgR2x1ZS4gRG9uJ3Qgc2V0IGl0YCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmYXVsdEFyZ3VtZW50cztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXR1cCBDb250aW51b3VzIExvZ2dpdW5nIFByb3BlcnRpZXNcbiAgICogQHBhcmFtIHJvbGUgVGhlIElBTSByb2xlIHRvIHVzZSBmb3IgY29udGludW91cyBsb2dnaW5nXG4gICAqIEBwYXJhbSBwcm9wcyBUaGUgcHJvcGVydGllcyBmb3IgY29udGludW91cyBsb2dnaW5nIGNvbmZpZ3VyYXRpb25cbiAgICogQHJldHVybnMgU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGFyZ3MgZm9yIHRoZSBjb250aW51b3VzIGxvZ2dpbmcgY29tbWFuZFxuICAgKi9cbiAgcHVibGljIHNldHVwQ29udGludW91c0xvZ2dpbmcocm9sZTogaWFtLklSb2xlLCBwcm9wczogQ29udGludW91c0xvZ2dpbmdQcm9wcyB8IHVuZGVmaW5lZCkgOiBhbnkge1xuICAgIC8vIElmIHRoZSBkZXZlbG9wZXIgaGFzIGV4cGxpY2l0bHkgZGlzYWJsZWQgY29udGludW91cyBsb2dnaW5nIHJldHVybiBubyBhcmdzXG4gICAgaWYgKHByb3BzICYmICFwcm9wcy5lbmFibGVkKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgLy8gRWxzZSB3ZSB0dXJuIG9uIGNvbnRpbnVvdXMgbG9nZ2luZyBieSBkZWZhdWx0LiBEZXRlcm1pbmUgd2hhdCBsb2cgZ3JvdXAgdG8gdXNlLlxuICAgIGNvbnN0IGFyZ3M6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9ID0ge1xuICAgICAgJy0tZW5hYmxlLWNvbnRpbnVvdXMtY2xvdWR3YXRjaC1sb2cnOiAndHJ1ZScsXG4gICAgfTtcblxuICAgIGlmIChwcm9wcz8ucXVpZXQpIHtcbiAgICAgIGFyZ3NbJy0tZW5hYmxlLWNvbnRpbnVvdXMtbG9nLWZpbHRlciddID0gJ3RydWUnO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSBkZXZlbG9wZXIgcHJvdmlkZWQgYSBsb2cgZ3JvdXAsIGFkZCBpdHMgbmFtZSB0byB0aGUgYXJncyBhbmQgdXBkYXRlIHRoZSByb2xlLlxuICAgIGlmIChwcm9wcz8ubG9nR3JvdXApIHtcbiAgICAgIGFyZ3NbJy0tY29udGludW91cy1sb2ctbG9nR3JvdXAnXSA9IHByb3BzLmxvZ0dyb3VwLmxvZ0dyb3VwTmFtZTtcbiAgICAgIHByb3BzLmxvZ0dyb3VwLmdyYW50V3JpdGUocm9sZSk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzPy5sb2dTdHJlYW1QcmVmaXgpIHtcbiAgICAgIGFyZ3NbJy0tY29udGludW91cy1sb2ctbG9nU3RyZWFtUHJlZml4J10gPSBwcm9wcy5sb2dTdHJlYW1QcmVmaXg7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzPy5jb252ZXJzaW9uUGF0dGVybikge1xuICAgICAgYXJnc1snLS1jb250aW51b3VzLWxvZy1jb252ZXJzaW9uUGF0dGVybiddID0gcHJvcHMuY29udmVyc2lvblBhdHRlcm47XG4gICAgfVxuXG4gICAgcmV0dXJuIGFyZ3M7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29kZVMzT2JqZWN0VXJsKGNvZGU6IENvZGUpIHtcbiAgICBjb25zdCBzM0xvY2F0aW9uID0gY29kZS5iaW5kKHRoaXMsIHRoaXMucm9sZSkuczNMb2NhdGlvbjtcbiAgICByZXR1cm4gYHMzOi8vJHtzM0xvY2F0aW9uLmJ1Y2tldE5hbWV9LyR7czNMb2NhdGlvbi5vYmplY3RLZXl9YDtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZSBhIENsb3VkV2F0Y2ggTWV0cmljIHRoYXQncyBiYXNlZCBvbiBHbHVlIEpvYiBldmVudHNcbiAqIHtAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZFdhdGNoL2xhdGVzdC9ldmVudHMvRXZlbnRUeXBlcy5odG1sI2dsdWUtZXZlbnQtdHlwZXN9XG4gKiBUaGUgbWV0cmljIGhhcyBuYW1lc3BhY2UgPSAnQVdTL0V2ZW50cycsIG1ldHJpY05hbWUgPSAnVHJpZ2dlcmVkUnVsZXMnIGFuZCBSdWxlTmFtZSA9IHJ1bGUucnVsZU5hbWUgZGltZW5zaW9uLlxuICpcbiAqIEBwYXJhbSBydWxlIGZvciB1c2UgaW4gc2V0dGluZyBSdWxlTmFtZSBkaW1lbnNpb24gdmFsdWVcbiAqIEBwYXJhbSBwcm9wcyBtZXRyaWMgcHJvcGVydGllc1xuICovXG5mdW5jdGlvbiBtZXRyaWNSdWxlKHJ1bGU6IGV2ZW50cy5JUnVsZSwgcHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gIHJldHVybiBuZXcgY2xvdWR3YXRjaC5NZXRyaWMoe1xuICAgIG5hbWVzcGFjZTogJ0FXUy9FdmVudHMnLFxuICAgIG1ldHJpY05hbWU6ICdUcmlnZ2VyZWRSdWxlcycsXG4gICAgZGltZW5zaW9uc01hcDogeyBSdWxlTmFtZTogcnVsZS5ydWxlTmFtZSB9LFxuICAgIHN0YXRpc3RpYzogY2xvdWR3YXRjaC5TdGF0aXN0aWMuU1VNLFxuICAgIC4uLnByb3BzLFxuICB9KS5hdHRhY2hUbyhydWxlKTtcbn1cblxuIl19
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
2
|
+
import { Job, JobProperties } from './job';
|
|
3
|
+
import { Construct } from 'constructs';
|
|
4
|
+
import { SparkUIProps, SparkUILoggingLocation } from './spark-ui-utils';
|
|
5
|
+
import { Code } from '../code';
|
|
6
|
+
/**
|
|
7
|
+
* Properties for creating a Python Spark ETL job
|
|
8
|
+
*/
|
|
9
|
+
export interface PySparkEtlJobProps extends JobProperties {
|
|
10
|
+
/**
|
|
11
|
+
* Enables the Spark UI debugging and monitoring with the specified props.
|
|
12
|
+
*
|
|
13
|
+
* @default - Spark UI debugging and monitoring is disabled.
|
|
14
|
+
*
|
|
15
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html
|
|
16
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
17
|
+
*/
|
|
18
|
+
readonly sparkUI?: SparkUIProps;
|
|
19
|
+
/**
|
|
20
|
+
* Extra Python Files S3 URL (optional)
|
|
21
|
+
* S3 URL where additional python dependencies are located
|
|
22
|
+
*
|
|
23
|
+
* @default - no extra files
|
|
24
|
+
*/
|
|
25
|
+
readonly extraPythonFiles?: Code[];
|
|
26
|
+
/**
|
|
27
|
+
* Additional files, such as configuration files that AWS Glue copies to the working directory of your script before executing it.
|
|
28
|
+
*
|
|
29
|
+
* @default - no extra files specified.
|
|
30
|
+
*
|
|
31
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
32
|
+
*/
|
|
33
|
+
readonly extraFiles?: Code[];
|
|
34
|
+
/**
|
|
35
|
+
* Specifies whether job run queuing is enabled for the job runs for this job.
|
|
36
|
+
* A value of true means job run queuing is enabled for the job runs.
|
|
37
|
+
* If false or not populated, the job runs will not be considered for queueing.
|
|
38
|
+
* If this field does not match the value set in the job run, then the value from
|
|
39
|
+
* the job run field will be used. This property must be set to false for flex jobs.
|
|
40
|
+
* If this property is enabled, maxRetries must be set to zero.
|
|
41
|
+
*
|
|
42
|
+
* @default false
|
|
43
|
+
*/
|
|
44
|
+
readonly jobRunQueuingEnabled?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* PySpark ETL Jobs class
|
|
48
|
+
*
|
|
49
|
+
* ETL jobs support pySpark and Scala languages, for which there are separate
|
|
50
|
+
* but similar constructors. ETL jobs default to the G2 worker type, but you
|
|
51
|
+
* can override this default with other supported worker type values
|
|
52
|
+
* (G1, G2, G4 and G8). ETL jobs defaults to Glue version 4.0, which you can
|
|
53
|
+
* override to 3.0. The following ETL features are enabled by default:
|
|
54
|
+
* —enable-metrics, —enable-spark-ui, —enable-continuous-cloudwatch-log.
|
|
55
|
+
* You can find more details about version, worker type and other features
|
|
56
|
+
* in Glue's public documentation.
|
|
57
|
+
*/
|
|
58
|
+
export declare class PySparkEtlJob extends Job {
|
|
59
|
+
readonly jobArn: string;
|
|
60
|
+
readonly jobName: string;
|
|
61
|
+
readonly role: iam.IRole;
|
|
62
|
+
readonly grantPrincipal: iam.IPrincipal;
|
|
63
|
+
/**
|
|
64
|
+
* The Spark UI logs location if Spark UI monitoring and debugging is enabled.
|
|
65
|
+
*
|
|
66
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html
|
|
67
|
+
* @see https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
|
|
68
|
+
*/
|
|
69
|
+
readonly sparkUILoggingLocation?: SparkUILoggingLocation;
|
|
70
|
+
/**
|
|
71
|
+
* PySparkEtlJob constructor
|
|
72
|
+
*/
|
|
73
|
+
constructor(scope: Construct, id: string, props: PySparkEtlJobProps);
|
|
74
|
+
/**
|
|
75
|
+
* Set the executable arguments with best practices enabled by default
|
|
76
|
+
*
|
|
77
|
+
* @returns An array of arguments for Glue to use on execution
|
|
78
|
+
*/
|
|
79
|
+
private executableArguments;
|
|
80
|
+
private setupSparkUI;
|
|
81
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.PySparkEtlJob = void 0;
|
|
5
|
+
const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
|
|
6
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
7
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
8
|
+
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
|
9
|
+
const aws_glue_1 = require("aws-cdk-lib/aws-glue");
|
|
10
|
+
const job_1 = require("./job");
|
|
11
|
+
const constants_1 = require("../constants");
|
|
12
|
+
const spark_ui_utils_1 = require("./spark-ui-utils");
|
|
13
|
+
const metadata_resource_1 = require("aws-cdk-lib/core/lib/metadata-resource");
|
|
14
|
+
/**
|
|
15
|
+
* PySpark ETL Jobs class
|
|
16
|
+
*
|
|
17
|
+
* ETL jobs support pySpark and Scala languages, for which there are separate
|
|
18
|
+
* but similar constructors. ETL jobs default to the G2 worker type, but you
|
|
19
|
+
* can override this default with other supported worker type values
|
|
20
|
+
* (G1, G2, G4 and G8). ETL jobs defaults to Glue version 4.0, which you can
|
|
21
|
+
* override to 3.0. The following ETL features are enabled by default:
|
|
22
|
+
* —enable-metrics, —enable-spark-ui, —enable-continuous-cloudwatch-log.
|
|
23
|
+
* You can find more details about version, worker type and other features
|
|
24
|
+
* in Glue's public documentation.
|
|
25
|
+
*/
|
|
26
|
+
class PySparkEtlJob extends job_1.Job {
|
|
27
|
+
/**
|
|
28
|
+
* PySparkEtlJob constructor
|
|
29
|
+
*/
|
|
30
|
+
constructor(scope, id, props) {
|
|
31
|
+
super(scope, id, {
|
|
32
|
+
physicalName: props.jobName,
|
|
33
|
+
});
|
|
34
|
+
try {
|
|
35
|
+
jsiiDeprecationWarnings._aws_cdk_aws_glue_alpha_PySparkEtlJobProps(props);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
39
|
+
Error.captureStackTrace(error, PySparkEtlJob);
|
|
40
|
+
}
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
// Enhanced CDK Analytics Telemetry
|
|
44
|
+
(0, metadata_resource_1.addConstructMetadata)(this, props);
|
|
45
|
+
// Set up role and permissions for principal
|
|
46
|
+
this.role = props.role, {
|
|
47
|
+
assumedBy: new iam.ServicePrincipal('glue.amazonaws.com'),
|
|
48
|
+
managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSGlueServiceRole')],
|
|
49
|
+
};
|
|
50
|
+
this.grantPrincipal = this.role;
|
|
51
|
+
// Enable SparkUI by default as a best practice
|
|
52
|
+
const sparkUIArgs = props.sparkUI?.bucket ? this.setupSparkUI(this.role, props.sparkUI) : undefined;
|
|
53
|
+
this.sparkUILoggingLocation = sparkUIArgs?.location;
|
|
54
|
+
// Enable CloudWatch metrics and continuous logging by default as a best practice
|
|
55
|
+
const continuousLoggingArgs = this.setupContinuousLogging(this.role, props.continuousLogging);
|
|
56
|
+
const profilingMetricsArgs = { '--enable-metrics': '' };
|
|
57
|
+
const observabilityMetricsArgs = { '--enable-observability-metrics': 'true' };
|
|
58
|
+
// Gather executable arguments
|
|
59
|
+
const execuatbleArgs = this.executableArguments(props);
|
|
60
|
+
// Conbine command line arguments into a single line item
|
|
61
|
+
const defaultArguments = {
|
|
62
|
+
...execuatbleArgs,
|
|
63
|
+
...continuousLoggingArgs,
|
|
64
|
+
...profilingMetricsArgs,
|
|
65
|
+
...observabilityMetricsArgs,
|
|
66
|
+
...sparkUIArgs?.args,
|
|
67
|
+
...this.checkNoReservedArgs(props.defaultArguments),
|
|
68
|
+
};
|
|
69
|
+
const jobResource = new aws_glue_1.CfnJob(this, 'Resource', {
|
|
70
|
+
name: props.jobName,
|
|
71
|
+
description: props.description,
|
|
72
|
+
role: this.role.roleArn,
|
|
73
|
+
command: {
|
|
74
|
+
name: constants_1.JobType.ETL,
|
|
75
|
+
scriptLocation: this.codeS3ObjectUrl(props.script),
|
|
76
|
+
pythonVersion: constants_1.PythonVersion.THREE,
|
|
77
|
+
},
|
|
78
|
+
glueVersion: props.glueVersion ?? constants_1.GlueVersion.V4_0,
|
|
79
|
+
workerType: props.workerType ?? constants_1.WorkerType.G_1X,
|
|
80
|
+
numberOfWorkers: props.numberOfWorkers ? props.numberOfWorkers : 10,
|
|
81
|
+
maxRetries: props.jobRunQueuingEnabled ? 0 : props.maxRetries,
|
|
82
|
+
jobRunQueuingEnabled: props.jobRunQueuingEnabled ? props.jobRunQueuingEnabled : false,
|
|
83
|
+
executionProperty: props.maxConcurrentRuns ? { maxConcurrentRuns: props.maxConcurrentRuns } : undefined,
|
|
84
|
+
timeout: props.timeout?.toMinutes(),
|
|
85
|
+
connections: props.connections ? { connections: props.connections.map((connection) => connection.connectionName) } : undefined,
|
|
86
|
+
securityConfiguration: props.securityConfiguration?.securityConfigurationName,
|
|
87
|
+
tags: props.tags,
|
|
88
|
+
defaultArguments,
|
|
89
|
+
});
|
|
90
|
+
const resourceName = this.getResourceNameAttribute(jobResource.ref);
|
|
91
|
+
this.jobArn = this.buildJobArn(this, resourceName);
|
|
92
|
+
this.jobName = resourceName;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Set the executable arguments with best practices enabled by default
|
|
96
|
+
*
|
|
97
|
+
* @returns An array of arguments for Glue to use on execution
|
|
98
|
+
*/
|
|
99
|
+
executableArguments(props) {
|
|
100
|
+
const args = {};
|
|
101
|
+
args['--job-language'] = constants_1.JobLanguage.PYTHON;
|
|
102
|
+
if (props.extraPythonFiles && props.extraPythonFiles.length > 0) {
|
|
103
|
+
args['--extra-py-files'] = props.extraPythonFiles.map(code => this.codeS3ObjectUrl(code)).join(',');
|
|
104
|
+
}
|
|
105
|
+
if (props.extraFiles && props.extraFiles.length > 0) {
|
|
106
|
+
args['--extra-files'] = props.extraFiles.map(code => this.codeS3ObjectUrl(code)).join(',');
|
|
107
|
+
}
|
|
108
|
+
return args;
|
|
109
|
+
}
|
|
110
|
+
setupSparkUI(role, sparkUiProps) {
|
|
111
|
+
(0, spark_ui_utils_1.validateSparkUiPrefix)(sparkUiProps.prefix);
|
|
112
|
+
const bucket = sparkUiProps.bucket ?? new aws_s3_1.Bucket(this, 'SparkUIBucket', { enforceSSL: true, encryption: aws_s3_1.BucketEncryption.S3_MANAGED });
|
|
113
|
+
bucket.grantReadWrite(role, (0, spark_ui_utils_1.cleanSparkUiPrefixForGrant)(sparkUiProps.prefix));
|
|
114
|
+
const args = {
|
|
115
|
+
'--enable-spark-ui': 'true',
|
|
116
|
+
'--spark-event-logs-path': bucket.s3UrlForObject(sparkUiProps.prefix).replace(/\/?$/, '/'), // path will always end with a slash
|
|
117
|
+
};
|
|
118
|
+
return {
|
|
119
|
+
location: {
|
|
120
|
+
prefix: sparkUiProps.prefix,
|
|
121
|
+
bucket,
|
|
122
|
+
},
|
|
123
|
+
args,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.PySparkEtlJob = PySparkEtlJob;
|
|
128
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
129
|
+
PySparkEtlJob[_a] = { fqn: "@aws-cdk/aws-glue-alpha.PySparkEtlJob", version: "2.178.0-alpha.0" };
|
|
130
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHlzcGFyay1ldGwtam9iLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicHlzcGFyay1ldGwtam9iLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDJDQUEyQztBQUMzQywrQ0FBOEQ7QUFDOUQsbURBQThDO0FBQzlDLCtCQUEyQztBQUUzQyw0Q0FBNEY7QUFDNUYscURBQTJIO0FBRTNILDhFQUE4RTtBQThDOUU7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFhLGFBQWMsU0FBUSxTQUFHO0lBY3BDOztPQUVHO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF5QjtRQUNqRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNmLFlBQVksRUFBRSxLQUFLLENBQUMsT0FBTztTQUM1QixDQUFDLENBQUM7Ozs7OzsrQ0FwQk0sYUFBYTs7OztRQXFCdEIsbUNBQW1DO1FBQ25DLElBQUEsd0NBQW9CLEVBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRWxDLDRDQUE0QztRQUM1QyxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUU7WUFDdEIsU0FBUyxFQUFFLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLG9CQUFvQixDQUFDO1lBQ3pELGVBQWUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsd0JBQXdCLENBQUMsaUNBQWlDLENBQUMsQ0FBQztTQUNqRyxDQUFDO1FBQ0YsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBRWhDLCtDQUErQztRQUMvQyxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ3BHLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxXQUFX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LEdBQUc7WUFDWCxtQkFBbUIsRUFBRSxNQUFNO1lBQzNCLHlCQUF5QixFQUFFLE1BQU0sQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLEVBQUUsb0NBQW9DO1NBQ2pJLENBQUM7UUFFRixPQUFPO1lBQ0wsUUFBUSxFQUFFO2dCQUNSLE1BQU0sRUFBRSxZQUFZLENBQUMsTUFBTTtnQkFDM0IsTUFBTTthQUNQO1lBQ0QsSUFBSTtTQUNMLENBQUM7S0FDSDs7QUFuSEgsc0NBb0hDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHsgQnVja2V0LCBCdWNrZXRFbmNyeXB0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzJztcbmltcG9ydCB7IENmbkpvYiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1nbHVlJztcbmltcG9ydCB7IEpvYiwgSm9iUHJvcGVydGllcyB9IGZyb20gJy4vam9iJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgSm9iVHlwZSwgR2x1ZVZlcnNpb24sIEpvYkxhbmd1YWdlLCBQeXRob25WZXJzaW9uLCBXb3JrZXJUeXBlIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IFNwYXJrVUlQcm9wcywgU3BhcmtVSUxvZ2dpbmdMb2NhdGlvbiwgdmFsaWRhdGVTcGFya1VpUHJlZml4LCBjbGVhblNwYXJrVWlQcmVmaXhGb3JHcmFudCB9IGZyb20gJy4vc3BhcmstdWktdXRpbHMnO1xuaW1wb3J0IHsgQ29kZSB9IGZyb20gJy4uL2NvZGUnO1xuaW1wb3J0IHsgYWRkQ29uc3RydWN0TWV0YWRhdGEgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9tZXRhZGF0YS1yZXNvdXJjZSc7XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgY3JlYXRpbmcgYSBQeXRob24gU3BhcmsgRVRMIGpvYlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFB5U3BhcmtFdGxKb2JQcm9wcyBleHRlbmRzIEpvYlByb3BlcnRpZXMge1xuICAvKipcbiAgICogRW5hYmxlcyB0aGUgU3BhcmsgVUkgZGVidWdnaW5nIGFuZCBtb25pdG9yaW5nIHdpdGggdGhlIHNwZWNpZmllZCBwcm9wcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBTcGFyayBVSSBkZWJ1Z2dpbmcgYW5kIG1vbml0b3JpbmcgaXMgZGlzYWJsZWQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL21vbml0b3Itc3BhcmstdWktam9icy5odG1sXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL2F3cy1nbHVlLXByb2dyYW1taW5nLWV0bC1nbHVlLWFyZ3VtZW50cy5odG1sXG4gICAqL1xuICByZWFkb25seSBzcGFya1VJPzogU3BhcmtVSVByb3BzO1xuXG4gIC8qKlxuICAgKiBFeHRyYSBQeXRob24gRmlsZXMgUzMgVVJMIChvcHRpb25hbClcbiAgICogUzMgVVJMIHdoZXJlIGFkZGl0aW9uYWwgcHl0aG9uIGRlcGVuZGVuY2llcyBhcmUgbG9jYXRlZFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGV4dHJhIGZpbGVzXG4gICAqL1xuICByZWFkb25seSBleHRyYVB5dGhvbkZpbGVzPzogQ29kZVtdO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIGZpbGVzLCBzdWNoIGFzIGNvbmZpZ3VyYXRpb24gZmlsZXMgdGhhdCBBV1MgR2x1ZSBjb3BpZXMgdG8gdGhlIHdvcmtpbmcgZGlyZWN0b3J5IG9mIHlvdXIgc2NyaXB0IGJlZm9yZSBleGVjdXRpbmcgaXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gZXh0cmEgZmlsZXMgc3BlY2lmaWVkLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nbHVlL2xhdGVzdC9kZy9hd3MtZ2x1ZS1wcm9ncmFtbWluZy1ldGwtZ2x1ZS1hcmd1bWVudHMuaHRtbFxuICAgKi9cbiAgcmVhZG9ubHkgZXh0cmFGaWxlcz86IENvZGVbXTtcblxuICAvKipcbiAgICogU3BlY2lmaWVzIHdoZXRoZXIgam9iIHJ1biBxdWV1aW5nIGlzIGVuYWJsZWQgZm9yIHRoZSBqb2IgcnVucyBmb3IgdGhpcyBqb2IuXG4gICAqIEEgdmFsdWUgb2YgdHJ1ZSBtZWFucyBqb2IgcnVuIHF1ZXVpbmcgaXMgZW5hYmxlZCBmb3IgdGhlIGpvYiBydW5zLlxuICAgKiBJZiBmYWxzZSBvciBub3QgcG9wdWxhdGVkLCB0aGUgam9iIHJ1bnMgd2lsbCBub3QgYmUgY29uc2lkZXJlZCBmb3IgcXVldWVpbmcuXG4gICAqIElmIHRoaXMgZmllbGQgZG9lcyBub3QgbWF0Y2ggdGhlIHZhbHVlIHNldCBpbiB0aGUgam9iIHJ1biwgdGhlbiB0aGUgdmFsdWUgZnJvbVxuICAgKiB0aGUgam9iIHJ1biBmaWVsZCB3aWxsIGJlIHVzZWQuIFRoaXMgcHJvcGVydHkgbXVzdCBiZSBzZXQgdG8gZmFsc2UgZm9yIGZsZXggam9icy5cbiAgICogSWYgdGhpcyBwcm9wZXJ0eSBpcyBlbmFibGVkLCBtYXhSZXRyaWVzIG11c3QgYmUgc2V0IHRvIHplcm8uXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBqb2JSdW5RdWV1aW5nRW5hYmxlZD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUHlTcGFyayBFVEwgSm9icyBjbGFzc1xuICpcbiAqIEVUTCBqb2JzIHN1cHBvcnQgcHlTcGFyayBhbmQgU2NhbGEgbGFuZ3VhZ2VzLCBmb3Igd2hpY2ggdGhlcmUgYXJlIHNlcGFyYXRlXG4gKiBidXQgc2ltaWxhciBjb25zdHJ1Y3RvcnMuIEVUTCBqb2JzIGRlZmF1bHQgdG8gdGhlIEcyIHdvcmtlciB0eXBlLCBidXQgeW91XG4gKiBjYW4gb3ZlcnJpZGUgdGhpcyBkZWZhdWx0IHdpdGggb3RoZXIgc3VwcG9ydGVkIHdvcmtlciB0eXBlIHZhbHVlc1xuICogKEcxLCBHMiwgRzQgYW5kIEc4KS4gRVRMIGpvYnMgZGVmYXVsdHMgdG8gR2x1ZSB2ZXJzaW9uIDQuMCwgd2hpY2ggeW91IGNhblxuICogb3ZlcnJpZGUgdG8gMy4wLiBUaGUgZm9sbG93aW5nIEVUTCBmZWF0dXJlcyBhcmUgZW5hYmxlZCBieSBkZWZhdWx0OlxuICog4oCUZW5hYmxlLW1ldHJpY3MsIOKAlGVuYWJsZS1zcGFyay11aSwg4oCUZW5hYmxlLWNvbnRpbnVvdXMtY2xvdWR3YXRjaC1sb2cuXG4gKiBZb3UgY2FuIGZpbmQgbW9yZSBkZXRhaWxzIGFib3V0IHZlcnNpb24sIHdvcmtlciB0eXBlIGFuZCBvdGhlciBmZWF0dXJlc1xuICogaW4gR2x1ZSdzIHB1YmxpYyBkb2N1bWVudGF0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgUHlTcGFya0V0bEpvYiBleHRlbmRzIEpvYiB7XG4gIHB1YmxpYyByZWFkb25seSBqb2JBcm46IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGpvYk5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHJvbGU6IGlhbS5JUm9sZTtcbiAgcHVibGljIHJlYWRvbmx5IGdyYW50UHJpbmNpcGFsOiBpYW0uSVByaW5jaXBhbDtcblxuICAvKipcbiAgICogVGhlIFNwYXJrIFVJIGxvZ3MgbG9jYXRpb24gaWYgU3BhcmsgVUkgbW9uaXRvcmluZyBhbmQgZGVidWdnaW5nIGlzIGVuYWJsZWQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL21vbml0b3Itc3BhcmstdWktam9icy5odG1sXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsdWUvbGF0ZXN0L2RnL2F3cy1nbHVlLXByb2dyYW1taW5nLWV0bC1nbHVlLWFyZ3VtZW50cy5odG1sXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3BhcmtVSUxvZ2dpbmdMb2NhdGlvbj86IFNwYXJrVUlMb2dnaW5nTG9jYXRpb247XG5cbiAgLyoqXG4gICAqIFB5U3BhcmtFdGxKb2IgY29uc3RydWN0b3JcbiAgICovXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBQeVNwYXJrRXRsSm9iUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHBoeXNpY2FsTmFtZTogcHJvcHMuam9iTmFtZSxcbiAgICB9KTtcbiAgICAvLyBFbmhhbmNlZCBDREsgQW5hbHl0aWNzIFRlbGVtZXRyeVxuICAgIGFkZENvbnN0cnVjdE1ldGFkYXRhKHRoaXMsIHByb3BzKTtcblxuICAgIC8vIFNldCB1cCByb2xlIGFuZCBwZXJtaXNzaW9ucyBmb3IgcHJpbmNpcGFsXG4gICAgdGhpcy5yb2xlID0gcHJvcHMucm9sZSwge1xuICAgICAgYXNzdW1lZEJ5OiBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2dsdWUuYW1hem9uYXdzLmNvbScpLFxuICAgICAgbWFuYWdlZFBvbGljaWVzOiBbaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdzZXJ2aWNlLXJvbGUvQVdTR2x1ZVNlcnZpY2VSb2xlJyldLFxuICAgIH07XG4gICAgdGhpcy5ncmFudFByaW5jaXBhbCA9IHRoaXMucm9sZTtcblxuICAgIC8vIEVuYWJsZSBTcGFya1VJIGJ5IGRlZmF1bHQgYXMgYSBiZXN0IHByYWN0aWNlXG4gICAgY29uc3Qgc3BhcmtVSUFyZ3MgPSBwcm9wcy5zcGFya1VJPy5idWNrZXQgPyB0aGlzLnNldHVwU3BhcmtVSSh0aGlzLnJvbGUsIHByb3BzLnNwYXJrVUkpIDogdW5kZWZpbmVkO1xuICAgIHRoaXMuc3BhcmtVSUxvZ2dpbmdMb2NhdGlvbiA9IHNwYXJrVUlBcmdzPy5sb2NhdGlvbjtcblxuICAgIC8vIEVuYWJsZSBDbG91ZFdhdGNoIG1ldHJpY3MgYW5kIGNvbnRpbnVvdXMgbG9nZ2luZyBieSBkZWZhdWx0IGFzIGEgYmVzdCBwcmFjdGljZVxuICAgIGNvbnN0IGNvbnRpbnVvdXNMb2dnaW5nQXJncyA9IHRoaXMuc2V0dXBDb250aW51b3VzTG9nZ2luZyh0aGlzLnJvbGUsIHByb3BzLmNvbnRpbnVvdXNMb2dnaW5nKTtcbiAgICBjb25zdCBwcm9maWxpbmdNZXRyaWNzQXJncyA9IHsgJy0tZW5hYmxlLW1ldHJpY3MnOiAnJyB9O1xuICAgIGNvbnN0IG9ic2VydmFiaWxpdHlNZXRyaWNzQXJncyA9IHsgJy0tZW5hYmxlLW9ic2VydmFiaWxpdHktbWV0cmljcyc6ICd0cnVlJyB9O1xuXG4gICAgLy8gR2F0aGVyIGV4ZWN1dGFibGUgYXJndW1lbnRzXG4gICAgY29uc3QgZXhlY3VhdGJsZUFyZ3MgPSB0aGlzLmV4ZWN1dGFibGVBcmd1bWVudHMocHJvcHMpO1xuXG4gICAgLy8gQ29uYmluZSBjb21tYW5kIGxpbmUgYXJndW1lbnRzIGludG8gYSBzaW5nbGUgbGluZSBpdGVtXG4gICAgY29uc3QgZGVmYXVsdEFyZ3VtZW50cyA9IHtcbiAgICAgIC4uLmV4ZWN1YXRibGVBcmdzLFxuICAgICAgLi4uY29udGludW91c0xvZ2dpbmdBcmdzLFxuICAgICAgLi4ucHJvZmlsaW5nTWV0cmljc0FyZ3MsXG4gICAgICAuLi5vYnNlcnZhYmlsaXR5TWV0cmljc0FyZ3MsXG4gICAgICAuLi5zcGFya1VJQXJncz8uYXJncyxcbiAgICAgIC4uLnRoaXMuY2hlY2tOb1Jlc2VydmVkQXJncyhwcm9wcy5kZWZhdWx0QXJndW1lbnRzKSxcbiAgICB9O1xuXG4gICAgY29uc3Qgam9iUmVzb3VyY2UgPSBuZXcgQ2ZuSm9iKHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIG5hbWU6IHByb3BzLmpvYk5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24sXG4gICAgICByb2xlOiB0aGlzLnJvbGUucm9sZUFybixcbiAgICAgIGNvbW1hbmQ6IHtcbiAgICAgICAgbmFtZTogSm9iVHlwZS5FVEwsXG4gICAgICAgIHNjcmlwdExvY2F0aW9uOiB0aGlzLmNvZGVTM09iamVjdFVybChwcm9wcy5zY3JpcHQpLFxuICAgICAgICBweXRob25WZXJzaW9uOiBQeXRob25WZXJzaW9uLlRIUkVFLFxuICAgICAgfSxcbiAgICAgIGdsdWVWZXJzaW9uOiBwcm9wcy5nbHVlVmVyc2lvbiA/PyBHbHVlVmVyc2lvbi5WNF8wLFxuICAgICAgd29ya2VyVHlwZTogcHJvcHMud29ya2VyVHlwZSA/PyBXb3JrZXJUeXBlLkdfMVgsXG4gICAgICBudW1iZXJPZldvcmtlcnM6IHByb3BzLm51bWJlck9mV29ya2VycyA/IHByb3BzLm51bWJlck9mV29ya2VycyA6IDEwLFxuICAgICAgbWF4UmV0cmllczogcHJvcHMuam9iUnVuUXVldWluZ0VuYWJsZWQgPyAwIDogcHJvcHMubWF4UmV0cmllcyxcbiAgICAgIGpvYlJ1blF1ZXVpbmdFbmFibGVkOiBwcm9wcy5qb2JSdW5RdWV1aW5nRW5hYmxlZCA/IHByb3BzLmpvYlJ1blF1ZXVpbmdFbmFibGVkIDogZmFsc2UsXG4gICAgICBleGVjdXRpb25Qcm9wZXJ0eTogcHJvcHMubWF4Q29uY3VycmVudFJ1bnMgPyB7IG1heENvbmN1cnJlbnRSdW5zOiBwcm9wcy5tYXhDb25jdXJyZW50UnVucyB9IDogdW5kZWZpbmVkLFxuICAgICAgdGltZW91dDogcHJvcHMudGltZW91dD8udG9NaW51dGVzKCksXG4gICAgICBjb25uZWN0aW9uczogcHJvcHMuY29ubmVjdGlvbnMgPyB7IGNvbm5lY3Rpb25zOiBwcm9wcy5jb25uZWN0aW9ucy5tYXAoKGNvbm5lY3Rpb24pID0+IGNvbm5lY3Rpb24uY29ubmVjdGlvbk5hbWUpIH0gOiB1bmRlZmluZWQsXG4gICAgICBzZWN1cml0eUNvbmZpZ3VyYXRpb246IHByb3BzLnNlY3VyaXR5Q29uZmlndXJhdGlvbj8uc2VjdXJpdHlDb25maWd1cmF0aW9uTmFtZSxcbiAgICAgIHRhZ3M6IHByb3BzLnRhZ3MsXG4gICAgICBkZWZhdWx0QXJndW1lbnRzLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzb3VyY2VOYW1lID0gdGhpcy5nZXRSZXNvdXJjZU5hbWVBdHRyaWJ1dGUoam9iUmVzb3VyY2UucmVmKTtcbiAgICB0aGlzLmpvYkFybiA9IHRoaXMuYnVpbGRKb2JBcm4odGhpcywgcmVzb3VyY2VOYW1lKTtcbiAgICB0aGlzLmpvYk5hbWUgPSByZXNvdXJjZU5hbWU7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBleGVjdXRhYmxlIGFyZ3VtZW50cyB3aXRoIGJlc3QgcHJhY3RpY2VzIGVuYWJsZWQgYnkgZGVmYXVsdFxuICAgKlxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBhcmd1bWVudHMgZm9yIEdsdWUgdG8gdXNlIG9uIGV4ZWN1dGlvblxuICAgKi9cbiAgcHJpdmF0ZSBleGVjdXRhYmxlQXJndW1lbnRzKHByb3BzOiBQeVNwYXJrRXRsSm9iUHJvcHMpIHtcbiAgICBjb25zdCBhcmdzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgYXJnc1snLS1qb2ItbGFuZ3VhZ2UnXSA9IEpvYkxhbmd1YWdlLlBZVEhPTjtcblxuICAgIGlmIChwcm9wcy5leHRyYVB5dGhvbkZpbGVzICYmIHByb3BzLmV4dHJhUHl0aG9uRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgYXJnc1snLS1leHRyYS1weS1maWxlcyddID0gcHJvcHMuZXh0cmFQeXRob25GaWxlcy5tYXAoY29kZSA9PiB0aGlzLmNvZGVTM09iamVjdFVybChjb2RlKSkuam9pbignLCcpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuZXh0cmFGaWxlcyAmJiBwcm9wcy5leHRyYUZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGFyZ3NbJy0tZXh0cmEtZmlsZXMnXSA9IHByb3BzLmV4dHJhRmlsZXMubWFwKGNvZGUgPT4gdGhpcy5jb2RlUzNPYmplY3RVcmwoY29kZSkpLmpvaW4oJywnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXJncztcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXBTcGFya1VJKHJvbGU6IGlhbS5JUm9sZSwgc3BhcmtVaVByb3BzOiBTcGFya1VJUHJvcHMpIHtcbiAgICB2YWxpZGF0ZVNwYXJrVWlQcmVmaXgoc3BhcmtVaVByb3BzLnByZWZpeCk7XG4gICAgY29uc3QgYnVja2V0ID0gc3BhcmtVaVByb3BzLmJ1Y2tldCA/PyBuZXcgQnVja2V0KHRoaXMsICdTcGFya1VJQnVja2V0JywgeyBlbmZvcmNlU1NMOiB0cnVlLCBlbmNyeXB0aW9uOiBCdWNrZXRFbmNyeXB0aW9uLlMzX01BTkFHRUQgfSk7XG4gICAgYnVja2V0LmdyYW50UmVhZFdyaXRlKHJvbGUsIGNsZWFuU3BhcmtVaVByZWZpeEZvckdyYW50KHNwYXJrVWlQcm9wcy5wcmVmaXgpKTtcbiAgICBjb25zdCBhcmdzID0ge1xuICAgICAgJy0tZW5hYmxlLXNwYXJrLXVpJzogJ3RydWUnLFxuICAgICAgJy0tc3BhcmstZXZlbnQtbG9ncy1wYXRoJzogYnVja2V0LnMzVXJsRm9yT2JqZWN0KHNwYXJrVWlQcm9wcy5wcmVmaXgpLnJlcGxhY2UoL1xcLz8kLywgJy8nKSwgLy8gcGF0aCB3aWxsIGFsd2F5cyBlbmQgd2l0aCBhIHNsYXNoXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBsb2NhdGlvbjoge1xuICAgICAgICBwcmVmaXg6IHNwYXJrVWlQcm9wcy5wcmVmaXgsXG4gICAgICAgIGJ1Y2tldCxcbiAgICAgIH0sXG4gICAgICBhcmdzLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==
|