UNPKG

91 kBJavaScriptView Raw
1"use strict";
2var _a, _b;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.Protocol = exports.ContainerDependencyCondition = exports.UlimitName = exports.ContainerDefinition = exports.Secret = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7const cdk = require("@aws-cdk/core");
8const task_definition_1 = require("./base/task-definition");
9// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
10// eslint-disable-next-line no-duplicate-imports, import/order
11const core_1 = require("@aws-cdk/core");
12/**
13 * A secret environment variable.
14 */
15class Secret {
16 /**
17 * Creates an environment variable value from a parameter stored in AWS
18 * Systems Manager Parameter Store.
19 */
20 static fromSsmParameter(parameter) {
21 return {
22 arn: parameter.parameterArn,
23 grantRead: grantee => parameter.grantRead(grantee),
24 };
25 }
26 /**
27 * Creates a environment variable value from a secret stored in AWS Secrets
28 * Manager.
29 *
30 * @param secret the secret stored in AWS Secrets Manager
31 * @param field the name of the field with the value that you want to set as
32 * the environment variable value. Only values in JSON format are supported.
33 * If you do not specify a JSON field, then the full content of the secret is
34 * used.
35 */
36 static fromSecretsManager(secret, field) {
37 return {
38 arn: field ? `${secret.secretArn}:${field}::` : secret.secretArn,
39 hasField: !!field,
40 grantRead: grantee => secret.grantRead(grantee),
41 };
42 }
43 /**
44 * Creates a environment variable value from a secret stored in AWS Secrets
45 * Manager.
46 *
47 * @param secret the secret stored in AWS Secrets Manager
48 * @param versionInfo the version information to reference the secret
49 * @param field the name of the field with the value that you want to set as
50 * the environment variable value. Only values in JSON format are supported.
51 * If you do not specify a JSON field, then the full content of the secret is
52 * used.
53 */
54 static fromSecretsManagerVersion(secret, versionInfo, field) {
55 var _c, _d;
56 try {
57 jsiiDeprecationWarnings._aws_cdk_aws_ecs_SecretVersionInfo(versionInfo);
58 }
59 catch (error) {
60 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
61 Error.captureStackTrace(error, this.fromSecretsManagerVersion);
62 }
63 throw error;
64 }
65 return {
66 arn: `${secret.secretArn}:${field !== null && field !== void 0 ? field : ''}:${(_c = versionInfo.versionStage) !== null && _c !== void 0 ? _c : ''}:${(_d = versionInfo.versionId) !== null && _d !== void 0 ? _d : ''}`,
67 hasField: !!field,
68 grantRead: grantee => secret.grantRead(grantee),
69 };
70 }
71}
72exports.Secret = Secret;
73_a = JSII_RTTI_SYMBOL_1;
74Secret[_a] = { fqn: "@aws-cdk/aws-ecs.Secret", version: "1.156.1" };
75/**
76 * A container definition is used in a task definition to describe the containers that are launched as part of a task.
77 */
78class ContainerDefinition extends core_1.Construct {
79 /**
80 * Constructs a new instance of the ContainerDefinition class.
81 */
82 constructor(scope, id, props) {
83 var _c, _d;
84 super(scope, id);
85 this.props = props;
86 /**
87 * The mount points for data volumes in your container.
88 */
89 this.mountPoints = new Array();
90 /**
91 * The list of port mappings for the container. Port mappings allow containers to access ports
92 * on the host container instance to send or receive traffic.
93 */
94 this.portMappings = new Array();
95 /**
96 * The data volumes to mount from another container in the same task definition.
97 */
98 this.volumesFrom = new Array();
99 /**
100 * An array of ulimits to set in the container.
101 */
102 this.ulimits = new Array();
103 /**
104 * An array dependencies defined for container startup and shutdown.
105 */
106 this.containerDependencies = new Array();
107 /**
108 * The inference accelerators referenced by this container.
109 */
110 this.inferenceAcceleratorResources = [];
111 /**
112 * The configured container links
113 */
114 this.links = new Array();
115 try {
116 jsiiDeprecationWarnings._aws_cdk_aws_ecs_ContainerDefinitionProps(props);
117 }
118 catch (error) {
119 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
120 Error.captureStackTrace(error, this.constructor);
121 }
122 throw error;
123 }
124 if (props.memoryLimitMiB !== undefined && props.memoryReservationMiB !== undefined) {
125 if (props.memoryLimitMiB < props.memoryReservationMiB) {
126 throw new Error('MemoryLimitMiB should not be less than MemoryReservationMiB.');
127 }
128 }
129 this.essential = (_c = props.essential) !== null && _c !== void 0 ? _c : true;
130 this.taskDefinition = props.taskDefinition;
131 this.memoryLimitSpecified = props.memoryLimitMiB !== undefined || props.memoryReservationMiB !== undefined;
132 this.linuxParameters = props.linuxParameters;
133 this.containerName = (_d = props.containerName) !== null && _d !== void 0 ? _d : this.node.id;
134 this.imageConfig = props.image.bind(this, this);
135 this.imageName = this.imageConfig.imageName;
136 if (props.logging) {
137 this.logDriverConfig = props.logging.bind(this, this);
138 }
139 if (props.secrets) {
140 this.secrets = [];
141 for (const [name, secret] of Object.entries(props.secrets)) {
142 if (secret.hasField) {
143 this.referencesSecretJsonField = true;
144 }
145 secret.grantRead(this.taskDefinition.obtainExecutionRole());
146 this.secrets.push({
147 name,
148 valueFrom: secret.arn,
149 });
150 }
151 }
152 if (props.environment) {
153 this.environment = { ...props.environment };
154 }
155 else {
156 this.environment = {};
157 }
158 if (props.environmentFiles) {
159 this.environmentFiles = [];
160 for (const environmentFile of props.environmentFiles) {
161 this.environmentFiles.push(environmentFile.bind(this));
162 }
163 }
164 props.taskDefinition._linkContainer(this);
165 if (props.portMappings) {
166 this.addPortMappings(...props.portMappings);
167 }
168 if (props.inferenceAcceleratorResources) {
169 this.addInferenceAcceleratorResource(...props.inferenceAcceleratorResources);
170 }
171 }
172 /**
173 * This method adds a link which allows containers to communicate with each other without the need for port mappings.
174 *
175 * This parameter is only supported if the task definition is using the bridge network mode.
176 * Warning: The --link flag is a legacy feature of Docker. It may eventually be removed.
177 */
178 addLink(container, alias) {
179 try {
180 jsiiDeprecationWarnings._aws_cdk_aws_ecs_ContainerDefinition(container);
181 }
182 catch (error) {
183 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
184 Error.captureStackTrace(error, this.addLink);
185 }
186 throw error;
187 }
188 if (this.taskDefinition.networkMode !== task_definition_1.NetworkMode.BRIDGE) {
189 throw new Error('You must use network mode Bridge to add container links.');
190 }
191 if (alias !== undefined) {
192 this.links.push(`${container.containerName}:${alias}`);
193 }
194 else {
195 this.links.push(`${container.containerName}`);
196 }
197 }
198 /**
199 * This method adds one or more mount points for data volumes to the container.
200 */
201 addMountPoints(...mountPoints) {
202 try {
203 jsiiDeprecationWarnings._aws_cdk_aws_ecs_MountPoint(mountPoints);
204 }
205 catch (error) {
206 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
207 Error.captureStackTrace(error, this.addMountPoints);
208 }
209 throw error;
210 }
211 this.mountPoints.push(...mountPoints);
212 }
213 /**
214 * This method mounts temporary disk space to the container.
215 *
216 * This adds the correct container mountPoint and task definition volume.
217 */
218 addScratch(scratch) {
219 try {
220 jsiiDeprecationWarnings._aws_cdk_aws_ecs_ScratchSpace(scratch);
221 }
222 catch (error) {
223 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
224 Error.captureStackTrace(error, this.addScratch);
225 }
226 throw error;
227 }
228 const mountPoint = {
229 containerPath: scratch.containerPath,
230 readOnly: scratch.readOnly,
231 sourceVolume: scratch.name,
232 };
233 const volume = {
234 host: {
235 sourcePath: scratch.sourcePath,
236 },
237 name: scratch.name,
238 };
239 this.taskDefinition.addVolume(volume);
240 this.addMountPoints(mountPoint);
241 }
242 /**
243 * This method adds one or more port mappings to the container.
244 */
245 addPortMappings(...portMappings) {
246 try {
247 jsiiDeprecationWarnings._aws_cdk_aws_ecs_PortMapping(portMappings);
248 }
249 catch (error) {
250 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
251 Error.captureStackTrace(error, this.addPortMappings);
252 }
253 throw error;
254 }
255 this.portMappings.push(...portMappings.map(pm => {
256 if (this.taskDefinition.networkMode === task_definition_1.NetworkMode.AWS_VPC || this.taskDefinition.networkMode === task_definition_1.NetworkMode.HOST) {
257 if (pm.containerPort !== pm.hostPort && pm.hostPort !== undefined) {
258 throw new Error(`Host port (${pm.hostPort}) must be left out or equal to container port ${pm.containerPort} for network mode ${this.taskDefinition.networkMode}`);
259 }
260 }
261 if (this.taskDefinition.networkMode === task_definition_1.NetworkMode.BRIDGE) {
262 if (pm.hostPort === undefined) {
263 pm = {
264 ...pm,
265 hostPort: 0,
266 };
267 }
268 }
269 return pm;
270 }));
271 }
272 /**
273 * This method adds an environment variable to the container.
274 */
275 addEnvironment(name, value) {
276 this.environment[name] = value;
277 }
278 /**
279 * This method adds one or more resources to the container.
280 */
281 addInferenceAcceleratorResource(...inferenceAcceleratorResources) {
282 this.inferenceAcceleratorResources.push(...inferenceAcceleratorResources.map(resource => {
283 for (const inferenceAccelerator of this.taskDefinition.inferenceAccelerators) {
284 if (resource === inferenceAccelerator.deviceName) {
285 return resource;
286 }
287 }
288 throw new Error(`Resource value ${resource} in container definition doesn't match any inference accelerator device name in the task definition.`);
289 }));
290 }
291 /**
292 * This method adds one or more ulimits to the container.
293 */
294 addUlimits(...ulimits) {
295 try {
296 jsiiDeprecationWarnings._aws_cdk_aws_ecs_Ulimit(ulimits);
297 }
298 catch (error) {
299 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
300 Error.captureStackTrace(error, this.addUlimits);
301 }
302 throw error;
303 }
304 this.ulimits.push(...ulimits);
305 }
306 /**
307 * This method adds one or more container dependencies to the container.
308 */
309 addContainerDependencies(...containerDependencies) {
310 try {
311 jsiiDeprecationWarnings._aws_cdk_aws_ecs_ContainerDependency(containerDependencies);
312 }
313 catch (error) {
314 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
315 Error.captureStackTrace(error, this.addContainerDependencies);
316 }
317 throw error;
318 }
319 this.containerDependencies.push(...containerDependencies);
320 }
321 /**
322 * This method adds one or more volumes to the container.
323 */
324 addVolumesFrom(...volumesFrom) {
325 try {
326 jsiiDeprecationWarnings._aws_cdk_aws_ecs_VolumeFrom(volumesFrom);
327 }
328 catch (error) {
329 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
330 Error.captureStackTrace(error, this.addVolumesFrom);
331 }
332 throw error;
333 }
334 this.volumesFrom.push(...volumesFrom);
335 }
336 /**
337 * This method adds the specified statement to the IAM task execution policy in the task definition.
338 */
339 addToExecutionPolicy(statement) {
340 this.taskDefinition.addToExecutionRolePolicy(statement);
341 }
342 /**
343 * Returns the host port for the requested container port if it exists
344 */
345 findPortMapping(containerPort, protocol) {
346 try {
347 jsiiDeprecationWarnings._aws_cdk_aws_ecs_Protocol(protocol);
348 }
349 catch (error) {
350 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
351 Error.captureStackTrace(error, this.findPortMapping);
352 }
353 throw error;
354 }
355 for (const portMapping of this.portMappings) {
356 const p = portMapping.protocol || Protocol.TCP;
357 const c = portMapping.containerPort;
358 if (c === containerPort && p === protocol) {
359 return portMapping;
360 }
361 }
362 return undefined;
363 }
364 /**
365 * The inbound rules associated with the security group the task or service will use.
366 *
367 * This property is only used for tasks that use the awsvpc network mode.
368 */
369 get ingressPort() {
370 if (this.portMappings.length === 0) {
371 throw new Error(`Container ${this.containerName} hasn't defined any ports. Call addPortMappings().`);
372 }
373 const defaultPortMapping = this.portMappings[0];
374 if (defaultPortMapping.hostPort !== undefined && defaultPortMapping.hostPort !== 0) {
375 return defaultPortMapping.hostPort;
376 }
377 if (this.taskDefinition.networkMode === task_definition_1.NetworkMode.BRIDGE) {
378 return 0;
379 }
380 return defaultPortMapping.containerPort;
381 }
382 /**
383 * The port the container will listen on.
384 */
385 get containerPort() {
386 if (this.portMappings.length === 0) {
387 throw new Error(`Container ${this.containerName} hasn't defined any ports. Call addPortMappings().`);
388 }
389 const defaultPortMapping = this.portMappings[0];
390 return defaultPortMapping.containerPort;
391 }
392 /**
393 * Render this container definition to a CloudFormation object
394 *
395 * @param _taskDefinition [disable-awslint:ref-via-interface] (unused but kept to avoid breaking change)
396 */
397 renderContainerDefinition(_taskDefinition) {
398 try {
399 jsiiDeprecationWarnings._aws_cdk_aws_ecs_TaskDefinition(_taskDefinition);
400 }
401 catch (error) {
402 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
403 Error.captureStackTrace(error, this.renderContainerDefinition);
404 }
405 throw error;
406 }
407 return {
408 command: this.props.command,
409 cpu: this.props.cpu,
410 disableNetworking: this.props.disableNetworking,
411 dependsOn: cdk.Lazy.any({ produce: () => this.containerDependencies.map(renderContainerDependency) }, { omitEmptyArray: true }),
412 dnsSearchDomains: this.props.dnsSearchDomains,
413 dnsServers: this.props.dnsServers,
414 dockerLabels: this.props.dockerLabels,
415 dockerSecurityOptions: this.props.dockerSecurityOptions,
416 entryPoint: this.props.entryPoint,
417 essential: this.essential,
418 hostname: this.props.hostname,
419 image: this.imageConfig.imageName,
420 memory: this.props.memoryLimitMiB,
421 memoryReservation: this.props.memoryReservationMiB,
422 mountPoints: cdk.Lazy.any({ produce: () => this.mountPoints.map(renderMountPoint) }, { omitEmptyArray: true }),
423 name: this.containerName,
424 portMappings: cdk.Lazy.any({ produce: () => this.portMappings.map(renderPortMapping) }, { omitEmptyArray: true }),
425 privileged: this.props.privileged,
426 readonlyRootFilesystem: this.props.readonlyRootFilesystem,
427 repositoryCredentials: this.imageConfig.repositoryCredentials,
428 startTimeout: this.props.startTimeout && this.props.startTimeout.toSeconds(),
429 stopTimeout: this.props.stopTimeout && this.props.stopTimeout.toSeconds(),
430 ulimits: cdk.Lazy.any({ produce: () => this.ulimits.map(renderUlimit) }, { omitEmptyArray: true }),
431 user: this.props.user,
432 volumesFrom: cdk.Lazy.any({ produce: () => this.volumesFrom.map(renderVolumeFrom) }, { omitEmptyArray: true }),
433 workingDirectory: this.props.workingDirectory,
434 logConfiguration: this.logDriverConfig,
435 environment: this.environment && Object.keys(this.environment).length ? renderKV(this.environment, 'name', 'value') : undefined,
436 environmentFiles: this.environmentFiles && renderEnvironmentFiles(cdk.Stack.of(this).partition, this.environmentFiles),
437 secrets: this.secrets,
438 extraHosts: this.props.extraHosts && renderKV(this.props.extraHosts, 'hostname', 'ipAddress'),
439 healthCheck: this.props.healthCheck && renderHealthCheck(this.props.healthCheck),
440 links: cdk.Lazy.list({ produce: () => this.links }, { omitEmpty: true }),
441 linuxParameters: this.linuxParameters && this.linuxParameters.renderLinuxParameters(),
442 resourceRequirements: (!this.props.gpuCount && this.inferenceAcceleratorResources.length == 0) ? undefined :
443 renderResourceRequirements(this.props.gpuCount, this.inferenceAcceleratorResources),
444 systemControls: this.props.systemControls && renderSystemControls(this.props.systemControls),
445 };
446 }
447}
448exports.ContainerDefinition = ContainerDefinition;
449_b = JSII_RTTI_SYMBOL_1;
450ContainerDefinition[_b] = { fqn: "@aws-cdk/aws-ecs.ContainerDefinition", version: "1.156.1" };
451function renderKV(env, keyName, valueName) {
452 const ret = [];
453 for (const [key, value] of Object.entries(env)) {
454 ret.push({ [keyName]: key, [valueName]: value });
455 }
456 return ret;
457}
458function renderEnvironmentFiles(partition, environmentFiles) {
459 const ret = [];
460 for (const environmentFile of environmentFiles) {
461 const s3Location = environmentFile.s3Location;
462 if (!s3Location) {
463 throw Error('Environment file must specify an S3 location');
464 }
465 ret.push({
466 type: environmentFile.fileType,
467 value: `arn:${partition}:s3:::${s3Location.bucketName}/${s3Location.objectKey}`,
468 });
469 }
470 return ret;
471}
472function renderHealthCheck(hc) {
473 var _c, _d, _e, _f, _g, _h;
474 return {
475 command: getHealthCheckCommand(hc),
476 interval: (_d = (_c = hc.interval) === null || _c === void 0 ? void 0 : _c.toSeconds()) !== null && _d !== void 0 ? _d : 30,
477 retries: (_e = hc.retries) !== null && _e !== void 0 ? _e : 3,
478 startPeriod: (_f = hc.startPeriod) === null || _f === void 0 ? void 0 : _f.toSeconds(),
479 timeout: (_h = (_g = hc.timeout) === null || _g === void 0 ? void 0 : _g.toSeconds()) !== null && _h !== void 0 ? _h : 5,
480 };
481}
482function getHealthCheckCommand(hc) {
483 const cmd = hc.command;
484 const hcCommand = new Array();
485 if (cmd.length === 0) {
486 throw new Error('At least one argument must be supplied for health check command.');
487 }
488 if (cmd.length === 1) {
489 hcCommand.push('CMD-SHELL', cmd[0]);
490 return hcCommand;
491 }
492 if (cmd[0] !== 'CMD' && cmd[0] !== 'CMD-SHELL') {
493 hcCommand.push('CMD');
494 }
495 return hcCommand.concat(cmd);
496}
497function renderResourceRequirements(gpuCount = 0, inferenceAcceleratorResources = []) {
498 const ret = [];
499 for (const resource of inferenceAcceleratorResources) {
500 ret.push({
501 type: 'InferenceAccelerator',
502 value: resource,
503 });
504 }
505 if (gpuCount > 0) {
506 ret.push({
507 type: 'GPU',
508 value: gpuCount.toString(),
509 });
510 }
511 return ret;
512}
513/**
514 * Type of resource to set a limit on
515 */
516var UlimitName;
517(function (UlimitName) {
518 UlimitName["CORE"] = "core";
519 UlimitName["CPU"] = "cpu";
520 UlimitName["DATA"] = "data";
521 UlimitName["FSIZE"] = "fsize";
522 UlimitName["LOCKS"] = "locks";
523 UlimitName["MEMLOCK"] = "memlock";
524 UlimitName["MSGQUEUE"] = "msgqueue";
525 UlimitName["NICE"] = "nice";
526 UlimitName["NOFILE"] = "nofile";
527 UlimitName["NPROC"] = "nproc";
528 UlimitName["RSS"] = "rss";
529 UlimitName["RTPRIO"] = "rtprio";
530 UlimitName["RTTIME"] = "rttime";
531 UlimitName["SIGPENDING"] = "sigpending";
532 UlimitName["STACK"] = "stack";
533})(UlimitName = exports.UlimitName || (exports.UlimitName = {}));
534function renderUlimit(ulimit) {
535 return {
536 name: ulimit.name,
537 softLimit: ulimit.softLimit,
538 hardLimit: ulimit.hardLimit,
539 };
540}
541var ContainerDependencyCondition;
542(function (ContainerDependencyCondition) {
543 /**
544 * This condition emulates the behavior of links and volumes today.
545 * It validates that a dependent container is started before permitting other containers to start.
546 */
547 ContainerDependencyCondition["START"] = "START";
548 /**
549 * This condition validates that a dependent container runs to completion (exits) before permitting other containers to start.
550 * This can be useful for nonessential containers that run a script and then exit.
551 */
552 ContainerDependencyCondition["COMPLETE"] = "COMPLETE";
553 /**
554 * This condition is the same as COMPLETE, but it also requires that the container exits with a zero status.
555 */
556 ContainerDependencyCondition["SUCCESS"] = "SUCCESS";
557 /**
558 * This condition validates that the dependent container passes its Docker health check before permitting other containers to start.
559 * This requires that the dependent container has health checks configured. This condition is confirmed only at task startup.
560 */
561 ContainerDependencyCondition["HEALTHY"] = "HEALTHY";
562})(ContainerDependencyCondition = exports.ContainerDependencyCondition || (exports.ContainerDependencyCondition = {}));
563function renderContainerDependency(containerDependency) {
564 return {
565 containerName: containerDependency.container.containerName,
566 condition: containerDependency.condition || ContainerDependencyCondition.HEALTHY,
567 };
568}
569/**
570 * Network protocol
571 */
572var Protocol;
573(function (Protocol) {
574 /**
575 * TCP
576 */
577 Protocol["TCP"] = "tcp";
578 /**
579 * UDP
580 */
581 Protocol["UDP"] = "udp";
582})(Protocol = exports.Protocol || (exports.Protocol = {}));
583function renderPortMapping(pm) {
584 return {
585 containerPort: pm.containerPort,
586 hostPort: pm.hostPort,
587 protocol: pm.protocol || Protocol.TCP,
588 };
589}
590function renderMountPoint(mp) {
591 return {
592 containerPath: mp.containerPath,
593 readOnly: mp.readOnly,
594 sourceVolume: mp.sourceVolume,
595 };
596}
597function renderVolumeFrom(vf) {
598 return {
599 sourceContainer: vf.sourceContainer,
600 readOnly: vf.readOnly,
601 };
602}
603function renderSystemControls(systemControls) {
604 return systemControls.map(sc => ({
605 namespace: sc.namespace,
606 value: sc.value,
607 }));
608}
609//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGFpbmVyLWRlZmluaXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjb250YWluZXItZGVmaW5pdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFHQSxxQ0FBcUM7QUFFckMsNERBQXFFO0FBT3JFLGlHQUFpRztBQUNqRyw4REFBOEQ7QUFDOUQsd0NBQTJEO0FBb0IzRDs7R0FFRztBQUNILE1BQXNCLE1BQU07SUFDMUI7OztPQUdHO0lBQ0ksTUFBTSxDQUFDLGdCQUFnQixDQUFDLFNBQXlCO1FBQ3RELE9BQU87WUFDTCxHQUFHLEVBQUUsU0FBUyxDQUFDLFlBQVk7WUFDM0IsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUM7U0FDbkQsQ0FBQztLQUNIO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksTUFBTSxDQUFDLGtCQUFrQixDQUFDLE1BQThCLEVBQUUsS0FBYztRQUM3RSxPQUFPO1lBQ0wsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUztZQUNoRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLEtBQUs7WUFDakIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUM7U0FDaEQsQ0FBQztLQUNIO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLE1BQU0sQ0FBQyx5QkFBeUIsQ0FBQyxNQUE4QixFQUFFLFdBQThCLEVBQUUsS0FBYzs7Ozs7Ozs7Ozs7UUFDcEgsT0FBTztZQUNMLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxTQUFTLElBQUksS0FBSyxhQUFMLEtBQUssY0FBTCxLQUFLLEdBQUksRUFBRSxJQUFJLE1BQUEsV0FBVyxDQUFDLFlBQVksbUNBQUksRUFBRSxJQUFJLE1BQUEsV0FBVyxDQUFD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QyxHQUFHO0tBQ3RDLENBQUM7QUFDSixDQUFDO0FBK0NELFNBQVMsZ0JBQWdCLENBQUMsRUFBYztJQUN0QyxPQUFPO1FBQ0wsYUFBYSxFQUFFLEVBQUUsQ0FBQyxhQUFhO1FBQy9CLFFBQVEsRUFBRSxFQUFFLENBQUMsUUFBUTtRQUNyQixZQUFZLEVBQUUsRUFBRSxDQUFDLFlBQVk7S0FDOUIsQ0FBQztBQUNKLENBQUM7QUFvQkQsU0FBUyxnQkFBZ0IsQ0FBQyxFQUFjO0lBQ3RDLE9BQU87UUFDTCxlQUFlLEVBQUUsRUFBRSxDQUFDLGVBQWU7UUFDbkMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxRQUFRO0tBQ3RCLENBQUM7QUFDSixDQUFDO0FBaUJELFNBQVMsb0JBQW9CLENBQUMsY0FBK0I7SUFDM0QsT0FBTyxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMvQixTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVM7UUFDdkIsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLO0tBQ2hCLENBQUMsQ0FBQyxDQUFDO0FBQ04sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGlhbSBmcm9tICdAYXdzLWNkay9hd3MtaWFtJztcbmltcG9ydCAqIGFzIHNlY3JldHNtYW5hZ2VyIGZyb20gJ0Bhd3MtY2RrL2F3cy1zZWNyZXRzbWFuYWdlcic7XG5pbXBvcnQgKiBhcyBzc20gZnJvbSAnQGF3cy1jZGsvYXdzLXNzbSc7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IE5ldHdvcmtNb2RlLCBUYXNrRGVmaW5pdGlvbiB9IGZyb20gJy4vYmFzZS90YXNrLWRlZmluaXRpb24nO1xuaW1wb3J0IHsgQ29udGFpbmVySW1hZ2UsIENvbnRhaW5lckltYWdlQ29uZmlnIH0gZnJvbSAnLi9jb250YWluZXItaW1hZ2UnO1xuaW1wb3J0IHsgQ2ZuVGFza0RlZmluaXRpb24gfSBmcm9tICcuL2Vjcy5nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgRW52aXJvbm1lbnRGaWxlLCBFbnZpcm9ubWVudEZpbGVDb25maWcgfSBmcm9tICcuL2Vudmlyb25tZW50LWZpbGUnO1xuaW1wb3J0IHsgTGludXhQYXJhbWV0ZXJzIH0gZnJvbSAnLi9saW51eC1wYXJhbWV0ZXJzJztcbmltcG9ydCB7IExvZ0RyaXZlciwgTG9nRHJpdmVyQ29uZmlnIH0gZnJvbSAnLi9sb2ctZHJpdmVycy9sb2ctZHJpdmVyJztcblxuLy8ga2VlcCB0aGlzIGltcG9ydCBzZXBhcmF0ZSBmcm9tIG90aGVyIGltcG9ydHMgdG8gcmVkdWNlIGNoYW5jZSBmb3IgbWVyZ2UgY29uZmxpY3RzIHdpdGggdjItbWFpblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWR1cGxpY2F0ZS1pbXBvcnRzLCBpbXBvcnQvb3JkZXJcbmltcG9ydCB7IENvbnN0cnVjdCBhcyBDb3JlQ29uc3RydWN0IH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5cbi8qKlxuICogU3BlY2lmeSB0aGUgc2VjcmV0J3MgdmVyc2lvbiBpZCBvciB2ZXJzaW9uIHN0YWdlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VjcmV0VmVyc2lvbkluZm8ge1xuICAvKipcbiAgICogdmVyc2lvbiBpZCBvZiB0aGUgc2VjcmV0XG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdXNlIGRlZmF1bHQgdmVyc2lvbiBpZFxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbklkPzogc3RyaW5nO1xuICAvKipcbiAgICogdmVyc2lvbiBzdGFnZSBvZiB0aGUgc2VjcmV0XG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdXNlIGRlZmF1bHQgdmVyc2lvbiBzdGFnZVxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvblN0YWdlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgc2VjcmV0IGVudmlyb25tZW50IHZhcmlhYmxlLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgU2VjcmV0IHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gZW52aXJvbm1lbnQgdmFyaWFibGUgdmFsdWUgZnJvbSBhIHBhcmFtZXRlciBzdG9yZWQgaW4gQVdTXG4gICAqIFN5c3RlbXMgTWFuYWdlciBQYXJhbWV0ZXIgU3RvcmUuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21Tc21QYXJhbWV0ZXIocGFyYW1ldGVyOiBzc20uSVBhcmFtZXRlcik6IFNlY3JldCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGFybjogcGFyYW1ldGVyLnBhcmFtZXRlckFybixcbiAgICAgIGdyYW50UmVhZDogZ3JhbnRlZSA9PiBwYXJhbWV0ZXIuZ3JhbnRSZWFkKGdyYW50ZWUpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIGVudmlyb25tZW50IHZhcmlhYmxlIHZhbHVlIGZyb20gYSBzZWNyZXQgc3RvcmVkIGluIEFXUyBTZWNyZXRzXG4gICAqIE1hbmFnZXIuXG4gICAqXG4gICAqIEBwYXJhbSBzZWNyZXQgdGhlIHNlY3JldCBzdG9yZWQgaW4gQVdTIFNlY3JldHMgTWFuYWdlclxuICAgKiBAcGFyYW0gZmllbGQgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHdpdGggdGhlIHZhbHVlIHRoYXQgeW91IHdhbnQgdG8gc2V0IGFzXG4gICAqIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZSB2YWx1ZS4gT25seSB2YWx1ZXMgaW4gSlNPTiBmb3JtYXQgYXJlIHN1cHBvcnRlZC5cbiAgICogSWYgeW91IGRvIG5vdCBzcGVjaWZ5IGEgSlNPTiBmaWVsZCwgdGhlbiB0aGUgZnVsbCBjb250ZW50IG9mIHRoZSBzZWNyZXQgaXNcbiAgICogdXNlZC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVNlY3JldHNNYW5hZ2VyKHNlY3JldDogc2VjcmV0c21hbmFnZXIuSVNlY3JldCwgZmllbGQ/OiBzdHJpbmcpOiBTZWNyZXQge1xuICAgIHJldHVybiB7XG4gICAgICBhcm46IGZpZWxkID8gYCR7c2VjcmV0LnNlY3JldEFybn06JHtmaWVsZH06OmAgOiBzZWNyZXQuc2VjcmV0QXJuLFxuICAgICAgaGFzRmllbGQ6ICEhZmllbGQsXG4gICAgICBncmFudFJlYWQ6IGdyYW50ZWUgPT4gc2VjcmV0LmdyYW50UmVhZChncmFudGVlKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBlbnZpcm9ubWVudCB2YXJpYWJsZSB2YWx1ZSBmcm9tIGEgc2VjcmV0IHN0b3JlZCBpbiBBV1MgU2VjcmV0c1xuICAgKiBNYW5hZ2VyLlxuICAgKlxuICAgKiBAcGFyYW0gc2VjcmV0IHRoZSBzZWNyZXQgc3RvcmVkIGluIEFXUyBTZWNyZXRzIE1hbmFnZXJcbiAgICogQHBhcmFtIHZlcnNpb25JbmZvIHRoZSB2ZXJzaW9uIGluZm9ybWF0aW9uIHRvIHJlZmVyZW5jZSB0aGUgc2VjcmV0XG4gICAqIEBwYXJhbSBmaWVsZCB0aGUgbmFtZSBvZiB0aGUgZmllbGQgd2l0aCB0aGUgdmFsdWUgdGhhdCB5b3Ugd2FudCB0byBzZXQgYXNcbiAgICogdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIHZhbHVlLiBPbmx5IHZhbHVlcyBpbiBKU09OIGZvcm1hdCBhcmUgc3VwcG9ydGVkLlxuICAgKiBJZiB5b3UgZG8gbm90IHNwZWNpZnkgYSBKU09OIGZpZWxkLCB0aGVuIHRoZSBmdWxsIGNvbnRlbnQgb2YgdGhlIHNlY3JldCBpc1xuICAgKiB1c2VkLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tU2VjcmV0c01hbmFnZXJWZXJzaW9uKHNlY3JldDogc2VjcmV0c21hbmFnZXIuSVNlY3JldCwgdmVyc2lvbkluZm86IFNlY3JldFZlcnNpb25JbmZvLCBmaWVsZD86IHN0cmluZyk6IFNlY3JldCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGFybjogYCR7c2VjcmV0LnNlY3JldEFybn06JHtmaWVsZCA/PyAnJ306JHt2ZXJzaW9uSW5mby52ZXJzaW9uU3RhZ2UgPz8gJyd9OiR7dmVyc2lvbkluZm8udmVyc2lvbklkID8/ICcnfWAsXG4gICAgICBoYXNGaWVsZDogISFmaWVsZCxcbiAgICAgIGdyYW50UmVhZDogZ3JhbnRlZSA9PiBzZWNyZXQuZ3JhbnRSZWFkKGdyYW50ZWUpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGUgc2VjcmV0XG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgYXJuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBzZWNyZXQgdXNlcyBhIHNwZWNpZmljIEpTT04gZmllbGRcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBoYXNGaWVsZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEdyYW50cyByZWFkaW5nIHRoZSBzZWNyZXQgdG8gYSBwcmluY2lwYWxcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCBncmFudFJlYWQoZ3JhbnRlZTogaWFtLklHcmFudGFibGUpOiBpYW0uR3JhbnQ7XG59XG5cbi8qXG4gKiBUaGUgb3B0aW9ucyBmb3IgY3JlYXRpbmcgYSBjb250YWluZXIgZGVmaW5pdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb250YWluZXJEZWZpbml0aW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgaW1hZ2UgdXNlZCB0byBzdGFydCBhIGNvbnRhaW5lci5cbiAgICpcbiAgICogVGhpcyBzdHJpbmcgaXMgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSBEb2NrZXIgZGFlbW9uLlxuICAgKiBJbWFnZXMgaW4gdGhlIERvY2tlciBIdWIgcmVnaXN0cnkgYXJlIGF2YWlsYWJsZSBieSBkZWZhdWx0LlxuICAgKiBPdGhlciByZXBvc2l0b3JpZXMgYXJlIHNwZWNpZmllZCB3aXRoIGVpdGhlciByZXBvc2l0b3J5LXVybC9pbWFnZTp0YWcgb3IgcmVwb3NpdG9yeS11cmwvaW1hZ2VAZGlnZXN0LlxuICAgKiBUT0RPOiBVcGRhdGUgdGhlc2UgdG8gc3BlY2lmeSB1c2luZyBjbGFzc2VzIG9mIElDb250YWluZXJJbWFnZVxuICAgKi9cbiAgcmVhZG9ubHkgaW1hZ2U6IENvbnRhaW5lckltYWdlO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGlkIG9mIG5vZGUgYXNzb2NpYXRlZCB3aXRoIENvbnRhaW5lckRlZmluaXRpb24uXG4gICAqL1xuICByZWFkb25seSBjb250YWluZXJOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgY29tbWFuZCB0aGF0IGlzIHBhc3NlZCB0byB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBJZiB5b3UgcHJvdmlkZSBhIHNoZWxsIGNvbW1hbmQgYXMgYSBzaW5nbGUgc3RyaW5nLCB5b3UgaGF2ZSB0byBxdW90ZSBjb21tYW5kLWxpbmUgYXJndW1lbnRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIENNRCB2YWx1ZSBidWlsdCBpbnRvIGNvbnRhaW5lciBpbWFnZS5cbiAgICovXG4gIHJlYWRvbmx5IGNvbW1hbmQ/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIG1pbmltdW0gbnVtYmVyIG9mIENQVSB1bml0cyB0byByZXNlcnZlIGZvciB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIG1pbmltdW0gQ1BVIHVuaXRzIHJlc2VydmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgY3B1PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgd2hldGhlciBuZXR3b3JraW5nIGlzIGRpc2FibGVkIHdpdGhpbiB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBXaGVuIHRoaXMgcGFyYW1ldGVyIGlzIHRydWUsIG5ldHdvcmtpbmcgaXMgZGlzYWJsZWQgd2l0aGluIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBkaXNhYmxlTmV0d29ya2luZz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBETlMgc2VhcmNoIGRvbWFpbnMgdGhhdCBhcmUgcHJlc2VudGVkIHRvIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gc2VhcmNoIGRvbWFpbnMuXG4gICAqL1xuICByZWFkb25seSBkbnNTZWFyY2hEb21haW5zPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBETlMgc2VydmVycyB0aGF0IGFyZSBwcmVzZW50ZWQgdG8gdGhlIGNvbnRhaW5lci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBEZWZhdWx0IEROUyBzZXJ2ZXJzLlxuICAgKi9cbiAgcmVhZG9ubHkgZG5zU2VydmVycz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBBIGtleS92YWx1ZSBtYXAgb2YgbGFiZWxzIHRvIGFkZCB0byB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIGxhYmVscy5cbiAgICovXG4gIHJlYWRvbmx5IGRvY2tlckxhYmVscz86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBzdHJpbmdzIHRvIHByb3ZpZGUgY3VzdG9tIGxhYmVscyBmb3IgU0VMaW51eCBhbmQgQXBwQXJtb3IgbXVsdGktbGV2ZWwgc2VjdXJpdHkgc3lzdGVtcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBzZWN1cml0eSBsYWJlbHMuXG4gICAqL1xuICByZWFkb25seSBkb2NrZXJTZWN1cml0eU9wdGlvbnM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIEVOVFJZUE9JTlQgdmFsdWUgdG8gcGFzcyB0byB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvYnVpbGRlci8jZW50cnlwb2ludFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEVudHJ5IHBvaW50IGNvbmZpZ3VyZWQgaW4gY29udGFpbmVyLlxuICAgKi9cbiAgcmVhZG9ubHkgZW50cnlQb2ludD86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgZW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIHBhc3MgdG8gdGhlIGNvbnRhaW5lci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBlbnZpcm9ubWVudCB2YXJpYWJsZXMuXG4gICAqL1xuICByZWFkb25seSBlbnZpcm9ubWVudD86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG5cbiAgLyoqXG4gICAqIFRoZSBlbnZpcm9ubWVudCBmaWxlcyB0byBwYXNzIHRvIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvdGFza2RlZi1lbnZmaWxlcy5odG1sXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZW52aXJvbm1lbnQgZmlsZXMuXG4gICAqL1xuICByZWFkb25seSBlbnZpcm9ubWVudEZpbGVzPzogRW52aXJvbm1lbnRGaWxlW107XG5cbiAgLyoqXG4gICAqIFRoZSBzZWNyZXQgZW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIHBhc3MgdG8gdGhlIGNvbnRhaW5lci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBzZWNyZXQgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgc2VjcmV0cz86IHsgW2tleTogc3RyaW5nXTogU2VjcmV0IH07XG5cbiAgLyoqXG4gICAqIFRpbWUgZHVyYXRpb24gKGluIHNlY29uZHMpIHRvIHdhaXQgYmVmb3JlIGdpdmluZyB1cCBvbiByZXNvbHZpbmcgZGVwZW5kZW5jaWVzIGZvciBhIGNvbnRhaW5lci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICByZWFkb25seSBzdGFydFRpbWVvdXQ/OiBjZGsuRHVyYXRpb247XG5cbiAgLyoqXG4gICAqIFRpbWUgZHVyYXRpb24gKGluIHNlY29uZHMpIHRvIHdhaXQgYmVmb3JlIHRoZSBjb250YWluZXIgaXMgZm9yY2VmdWxseSBraWxsZWQgaWYgaXQgZG9lc24ndCBleGl0IG5vcm1hbGx5IG9uIGl0cyBvd24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgc3RvcFRpbWVvdXQ/OiBjZGsuRHVyYXRpb247XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB3aGV0aGVyIHRoZSBjb250YWluZXIgaXMgbWFya2VkIGVzc2VudGlhbC5cbiAgICpcbiAgICogSWYgdGhlIGVzc2VudGlhbCBwYXJhbWV0ZXIgb2YgYSBjb250YWluZXIgaXMgbWFya2VkIGFzIHRydWUsIGFuZCB0aGF0IGNvbnRhaW5lciBmYWlsc1xuICAgKiBvciBzdG9wcyBmb3IgYW55IHJlYXNvbiwgYWxsIG90aGVyIGNvbnRhaW5lcnMgdGhhdCBhcmUgcGFydCBvZiB0aGUgdGFzayBhcmUgc3RvcHBlZC5cbiAgICogSWYgdGhlIGVzc2VudGlhbCBwYXJhbWV0ZXIgb2YgYSBjb250YWluZXIgaXMgbWFya2VkIGFzIGZhbHNlLCB0aGVuIGl0cyBmYWlsdXJlIGRvZXMgbm90XG4gICAqIGFmZmVjdCB0aGUgcmVzdCBvZiB0aGUgY29udGFpbmVycyBpbiBhIHRhc2suIEFsbCB0YXNrcyBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGVzc2VudGlhbCBjb250YWluZXIuXG4gICAqXG4gICAqIElmIHRoaXMgcGFyYW1ldGVyIGlzIG9taXR0ZWQsIGEgY29udGFpbmVyIGlzIGFzc3VtZWQgdG8gYmUgZXNzZW50aWFsLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBlc3NlbnRpYWw/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgaG9zdG5hbWVzIGFuZCBJUCBhZGRyZXNzIG1hcHBpbmdzIHRvIGFwcGVuZCB0byB0aGUgL2V0Yy9ob3N0cyBmaWxlIG9uIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZXh0cmEgaG9zdHMuXG4gICAqL1xuICByZWFkb25seSBleHRyYUhvc3RzPzogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH07XG5cbiAgLyoqXG4gICAqIFRoZSBoZWFsdGggY2hlY2sgY29tbWFuZCBhbmQgYXNzb2NpYXRlZCBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMgZm9yIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gSGVhbHRoIGNoZWNrIGNvbmZpZ3VyYXRpb24gZnJvbSBjb250YWluZXIuXG4gICAqL1xuICByZWFkb25seSBoZWFsdGhDaGVjaz86IEhlYWx0aENoZWNrO1xuXG4gIC8qKlxuICAgKiBUaGUgaG9zdG5hbWUgdG8gdXNlIGZvciB5b3VyIGNvbnRhaW5lci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBBdXRvbWF0aWMgaG9zdG5hbWUuXG4gICAqL1xuICByZWFkb25seSBob3N0bmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGFtb3VudCAoaW4gTWlCKSBvZiBtZW1vcnkgdG8gcHJlc2VudCB0byB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBJZiB5b3VyIGNvbnRhaW5lciBhdHRlbXB0cyB0byBleGNlZWQgdGhlIGFsbG9jYXRlZCBtZW1vcnksIHRoZSBjb250YWluZXJcbiAgICogaXMgdGVybWluYXRlZC5cbiAgICpcbiAgICogQXQgbGVhc3Qgb25lIG9mIG1lbW9yeUxpbWl0TWlCIGFuZCBtZW1vcnlSZXNlcnZhdGlvbk1pQiBpcyByZXF1aXJlZCBmb3Igbm9uLUZhcmdhdGUgc2VydmljZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gbWVtb3J5IGxpbWl0LlxuICAgKi9cbiAgcmVhZG9ubHkgbWVtb3J5TGltaXRNaUI/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBzb2Z0IGxpbWl0IChpbiBNaUIpIG9mIG1lbW9yeSB0byByZXNlcnZlIGZvciB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBXaGVuIHN5c3RlbSBtZW1vcnkgaXMgdW5kZXIgaGVhdnkgY29udGVudGlvbiwgRG9ja2VyIGF0dGVtcHRzIHRvIGtlZXAgdGhlXG4gICAqIGNvbnRhaW5lciBtZW1vcnkgdG8gdGhpcyBzb2Z0IGxpbWl0LiBIb3dldmVyLCB5b3VyIGNvbnRhaW5lciBjYW4gY29uc3VtZSBtb3JlXG4gICAqIG1lbW9yeSB3aGVuIGl0IG5lZWRzIHRvLCB1cCB0byBlaXRoZXIgdGhlIGhhcmQgbGltaXQgc3BlY2lmaWVkIHdpdGggdGhlIG1lbW9yeVxuICAgKiBwYXJhbWV0ZXIgKGlmIGFwcGxpY2FibGUpLCBvciBhbGwgb2YgdGhlIGF2YWlsYWJsZSBtZW1vcnkgb24gdGhlIGNvbnRhaW5lclxuICAgKiBpbnN0YW5jZSwgd2hpY2hldmVyIGNvbWVzIGZpcnN0LlxuICAgKlxuICAgKiBBdCBsZWFzdCBvbmUgb2YgbWVtb3J5TGltaXRNaUIgYW5kIG1lbW9yeVJlc2VydmF0aW9uTWlCIGlzIHJlcXVpcmVkIGZvciBub24tRmFyZ2F0ZSBzZXJ2aWNlcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBtZW1vcnkgcmVzZXJ2ZWQuXG4gICAqL1xuICByZWFkb25seSBtZW1vcnlSZXNlcnZhdGlvbk1pQj86IG51bWJlcjtcblxuICAvKipcbiAgICogU3BlY2lmaWVzIHdoZXRoZXIgdGhlIGNvbnRhaW5lciBpcyBtYXJrZWQgYXMgcHJpdmlsZWdlZC5cbiAgICogV2hlbiB0aGlzIHBhcmFtZXRlciBpcyB0cnVlLCB0aGUgY29udGFpbmVyIGlzIGdpdmVuIGVsZXZhdGVkIHByaXZpbGVnZXMgb24gdGhlIGhvc3QgY29udGFpbmVyIGluc3RhbmNlIChzaW1pbGFyIHRvIHRoZSByb290IHVzZXIpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgcHJpdmlsZWdlZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZW4gdGhpcyBwYXJhbWV0ZXIgaXMgdHJ1ZSwgdGhlIGNvbnRhaW5lciBpcyBnaXZlbiByZWFkLW9ubHkgYWNjZXNzIHRvIGl0cyByb290IGZpbGUgc3lzdGVtLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVhZG9ubHlSb290RmlsZXN5c3RlbT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSB1c2VyIG5hbWUgdG8gdXNlIGluc2lkZSB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCByb290XG4gICAqL1xuICByZWFkb25seSB1c2VyPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgd29ya2luZyBkaXJlY3RvcnkgaW4gd2hpY2ggdG8gcnVuIGNvbW1hbmRzIGluc2lkZSB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAvXG4gICAqL1xuICByZWFkb25seSB3b3JraW5nRGlyZWN0b3J5Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbG9nIGNvbmZpZ3VyYXRpb24gc3BlY2lmaWNhdGlvbiBmb3IgdGhlIGNvbnRhaW5lci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBDb250YWluZXJzIHVzZSB0aGUgc2FtZSBsb2dnaW5nIGRyaXZlciB0aGF0IHRoZSBEb2NrZXIgZGFlbW9uIHVzZXMuXG4gICAqL1xuICByZWFkb25seSBsb2dnaW5nPzogTG9nRHJpdmVyO1xuXG4gIC8qKlxuICAgKiBMaW51eC1zcGVjaWZpYyBtb2RpZmljYXRpb25zIHRoYXQgYXJlIGFwcGxpZWQgdG8gdGhlIGNvbnRhaW5lciwgc3VjaCBhcyBMaW51eCBrZXJuZWwgY2FwYWJpbGl0aWVzLlxuICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBzZWUgW0tlcm5lbENhcGFiaWxpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVDUy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9LZXJuZWxDYXBhYmlsaXRpZXMuaHRtbCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gTGludXggcGFyYW1ldGVycy5cbiAgICovXG4gIHJlYWRvbmx5IGxpbnV4UGFyYW1ldGVycz86IExpbnV4UGFyYW1ldGVycztcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBHUFVzIGFzc2lnbmVkIHRvIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gR1BVcyBhc3NpZ25lZC5cbiAgICovXG4gIHJlYWRvbmx5IGdwdUNvdW50PzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgcG9ydCBtYXBwaW5ncyB0byBhZGQgdG8gdGhlIGNvbnRhaW5lciBkZWZpbml0aW9uLlxuICAgKiBAZGVmYXVsdCAtIE5vIHBvcnRzIGFyZSBtYXBwZWQuXG4gICAqL1xuICByZWFkb25seSBwb3J0TWFwcGluZ3M/OiBQb3J0TWFwcGluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgaW5mZXJlbmNlIGFjY2VsZXJhdG9ycyByZWZlcmVuY2VkIGJ5IHRoZSBjb250YWluZXIuXG4gICAqIEBkZWZhdWx0IC0gTm8gaW5mZXJlbmNlIGFjY2VsZXJhdG9ycyBhc3NpZ25lZC5cbiAgICovXG4gIHJlYWRvbmx5IGluZmVyZW5jZUFjY2VsZXJhdG9yUmVzb3VyY2VzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBuYW1lc3BhY2VkIGtlcm5lbCBwYXJhbWV0ZXJzIHRvIHNldCBpbiB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIHN5c3RlbSBjb250cm9scyBhcmUgc2V0LlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjcy10YXNrZGVmaW5pdGlvbi1zeXN0ZW1jb250cm9sLmh0bWxcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNTL2xhdGVzdC9kZXZlbG9wZXJndWlkZS90YXNrX2RlZmluaXRpb25fcGFyYW1ldGVycy5odG1sI2NvbnRhaW5lcl9kZWZpbml0aW9uX3N5c3RlbWNvbnRyb2xzXG4gICAqL1xuICByZWFkb25seSBzeXN0ZW1Db250cm9scz86IFN5c3RlbUNvbnRyb2xbXTtcbn1cblxuLyoqXG4gKiBUaGUgcHJvcGVydGllcyBpbiBhIGNvbnRhaW5lciBkZWZpbml0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbnRhaW5lckRlZmluaXRpb25Qcm9wcyBleHRlbmRzIENvbnRhaW5lckRlZmluaXRpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSB0YXNrIGRlZmluaXRpb24gdGhhdCBpbmNsdWRlcyB0aGlzIGNvbnRhaW5lciBkZWZpbml0aW9uLlxuICAgKlxuICAgKiBbZGlzYWJsZS1hd3NsaW50OnJlZi12aWEtaW50ZXJmYWNlXVxuICAgKi9cbiAgcmVhZG9ubHkgdGFza0RlZmluaXRpb246IFRhc2tEZWZpbml0aW9uO1xufVxuXG4vKipcbiAqIEEgY29udGFpbmVyIGRlZmluaXRpb24gaXMgdXNlZCBpbiBhIHRhc2sgZGVmaW5pdGlvbiB0byBkZXNjcmliZSB0aGUgY29udGFpbmVycyB0aGF0IGFyZSBsYXVuY2hlZCBhcyBwYXJ0IG9mIGEgdGFzay5cbiAqL1xuZXhwb3J0IGNsYXNzIENvbnRhaW5lckRlZmluaXRpb24gZXh0ZW5kcyBDb3JlQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFRoZSBMaW51eC1zcGVjaWZpYyBtb2RpZmljYXRpb25zIHRoYXQgYXJlIGFwcGxpZWQgdG8gdGhlIGNvbnRhaW5lciwgc3VjaCBhcyBMaW51eCBrZXJuZWwgY2FwYWJpbGl0aWVzLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGxpbnV4UGFyYW1ldGVycz86IExpbnV4UGFyYW1ldGVycztcblxuICAvKipcbiAgICogVGhlIG1vdW50IHBvaW50cyBmb3IgZGF0YSB2b2x1bWVzIGluIHlvdXIgY29udGFpbmVyLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1vdW50UG9pbnRzID0gbmV3IEFycmF5PE1vdW50UG9pbnQ+KCk7XG5cbiAgLyoqXG4gICAqIFRoZSBsaXN0IG9mIHBvcnQgbWFwcGluZ3MgZm9yIHRoZSBjb250YWluZXIuIFBvcnQgbWFwcGluZ3MgYWxsb3cgY29udGFpbmVycyB0byBhY2Nlc3MgcG9ydHNcbiAgICogb24gdGhlIGhvc3QgY29udGFpbmVyIGluc3RhbmNlIHRvIHNlbmQgb3IgcmVjZWl2ZSB0cmFmZmljLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHBvcnRNYXBwaW5ncyA9IG5ldyBBcnJheTxQb3J0TWFwcGluZz4oKTtcblxuICAvKipcbiAgICogVGhlIGRhdGEgdm9sdW1lcyB0byBtb3VudCBmcm9tIGFub3RoZXIgY29udGFpbmVyIGluIHRoZSBzYW1lIHRhc2sgZGVmaW5pdGlvbi5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB2b2x1bWVzRnJvbSA9IG5ldyBBcnJheTxWb2x1bWVGcm9tPigpO1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiB1bGltaXRzIHRvIHNldCBpbiB0aGUgY29udGFpbmVyLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHVsaW1pdHMgPSBuZXcgQXJyYXk8VWxpbWl0PigpO1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBkZXBlbmRlbmNpZXMgZGVmaW5lZCBmb3IgY29udGFpbmVyIHN0YXJ0dXAgYW5kIHNodXRkb3duLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNvbnRhaW5lckRlcGVuZGVuY2llcyA9IG5ldyBBcnJheTxDb250YWluZXJEZXBlbmRlbmN5PigpO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgY29udGFpbmVyIHdpbGwgYmUgbWFya2VkIGVzc2VudGlhbC5cbiAgICpcbiAgICogSWYgdGhlIGVzc2VudGlhbCBwYXJhbWV0ZXIgb2YgYSBjb250YWluZXIgaXMgbWFya2VkIGFzIHRydWUsIGFuZCB0aGF0IGNvbnRhaW5lclxuICAgKiBmYWlscyBvciBzdG9wcyBmb3IgYW55IHJlYXNvbiwgYWxsIG90aGVyIGNvbnRhaW5lcnMgdGhhdCBhcmUgcGFydCBvZiB0aGUgdGFzayBhcmVcbiAgICogc3RvcHBlZC4gSWYgdGhlIGVzc2VudGlhbCBwYXJhbWV0ZXIgb2YgYSBjb250YWluZXIgaXMgbWFya2VkIGFzIGZhbHNlLCB0aGVuIGl0c1xuICAgKiBmYWlsdXJlIGRvZXMgbm90IGFmZmVjdCB0aGUgcmVzdCBvZiB0aGUgY29udGFpbmVycyBpbiBhIHRhc2suXG4gICAqXG4gICAqIElmIHRoaXMgcGFyYW1ldGVyIGlzIG9taXR0ZWQsIGEgY29udGFpbmVyIGlzIGFzc3VtZWQgdG8gYmUgZXNzZW50aWFsLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGVzc2VudGlhbDogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhpcyBjb250YWluZXJcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjb250YWluZXJOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlcmUgd2FzIGF0IGxlYXN0IG9uZSBtZW1vcnkgbGltaXQgc3BlY2lmaWVkIGluIHRoaXMgZGVmaW5pdGlvblxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1lbW9yeUxpbWl0U3BlY2lmaWVkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgdGFzayBkZWZpbml0aW9uIHRoYXQgaW5jbHVkZXMgdGhpcyBjb250YWluZXIgZGVmaW5pdGlvbi5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB0YXNrRGVmaW5pdGlvbjogVGFza0RlZmluaXRpb247XG5cbiAgLyoqXG4gICAqIFRoZSBlbnZpcm9ubWVudCBmaWxlcyBmb3IgdGhpcyBjb250YWluZXJcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBlbnZpcm9ubWVudEZpbGVzPzogRW52aXJvbm1lbnRGaWxlQ29uZmlnW107XG5cbiAgLyoqXG4gICAqIFRoZSBsb2cgY29uZmlndXJhdGlvbiBzcGVjaWZpY2F0aW9uIGZvciB0aGUgY29udGFpbmVyLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGxvZ0RyaXZlckNvbmZpZz86IExvZ0RyaXZlckNvbmZpZztcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIGNvbnRhaW5lciBkZWZpbml0aW9uIHJlZmVyZW5jZXMgYSBzcGVjaWZpYyBKU09OIGZpZWxkIG9mIGEgc2VjcmV0XG4gICAqIHN0b3JlZCBpbiBTZWNyZXRzIE1hbmFnZXIuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcmVmZXJlbmNlc1NlY3JldEpzb25GaWVsZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBpbWFnZSByZWZlcmVuY2VkIGJ5IHRoaXMgY29udGFpbmVyLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGltYWdlTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgaW5mZXJlbmNlIGFjY2VsZXJhdG9ycyByZWZlcmVuY2VkIGJ5IHRoaXMgY29udGFpbmVyLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBpbmZlcmVuY2VBY2NlbGVyYXRvclJlc291cmNlczogc3RyaW5nW10gPSBbXTtcblxuICAvKipcbiAgICogVGhlIGNvbmZpZ3VyZWQgY29udGFpbmVyIGxpbmtzXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGxpbmtzID0gbmV3IEFycmF5PHN0cmluZz4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGltYWdlQ29uZmlnOiBDb250YWluZXJJbWFnZUNvbmZpZztcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlY3JldHM/OiBDZm5UYXNrRGVmaW5pdGlvbi5TZWNyZXRQcm9wZXJ0eVtdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZW52aXJvbm1lbnQ6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIENvbnRhaW5lckRlZmluaXRpb24gY2xhc3MuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBDb250YWluZXJEZWZpbml0aW9uUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIGlmIChwcm9wcy5tZW1vcnlMaW1pdE1pQiAhPT0gdW5kZWZpbmVkICYmIHByb3BzLm1lbW9yeVJlc2VydmF0aW9uTWlCICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChwcm9wcy5tZW1vcnlMaW1pdE1pQiA8IHByb3BzLm1lbW9yeVJlc2VydmF0aW9uTWlCKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWVtb3J5TGltaXRNaUIgc2hvdWxkIG5vdCBiZSBsZXNzIHRoYW4gTWVtb3J5UmVzZXJ2YXRpb25NaUIuJyk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuZXNzZW50aWFsID0gcHJvcHMuZXNzZW50aWFsID8/IHRydWU7XG4gICAgdGhpcy50YXNrRGVmaW5pdGlvbiA9IHByb3BzLnRhc2tEZWZpbml0aW9uO1xuICAgIHRoaXMubWVtb3J5TGltaXRTcGVjaWZpZWQgPSBwcm9wcy5tZW1vcnlMaW1pdE1pQiAhPT0gdW5kZWZpbmVkIHx8IHByb3BzLm1lbW9yeVJlc2VydmF0aW9uTWlCICE9PSB1bmRlZmluZWQ7XG4gICAgdGhpcy5saW51eFBhcmFtZXRlcnMgPSBwcm9wcy5saW51eFBhcmFtZXRlcnM7XG4gICAgdGhpcy5jb250YWluZXJOYW1lID0gcHJvcHMuY29udGFpbmVyTmFtZSA/PyB0aGlzLm5vZGUuaWQ7XG5cbiAgICB0aGlzLmltYWdlQ29uZmlnID0gcHJvcHMuaW1hZ2UuYmluZCh0aGlzLCB0aGlzKTtcbiAgICB0aGlzLmltYWdlTmFtZSA9IHRoaXMuaW1hZ2VDb25maWcuaW1hZ2VOYW1lO1xuXG4gICAgaWYgKHByb3BzLmxvZ2dpbmcpIHtcbiAgICAgIHRoaXMubG9nRHJpdmVyQ29uZmlnID0gcHJvcHMubG9nZ2luZy5iaW5kKHRoaXMsIHRoaXMpO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy5zZWNyZXRzKSB7XG4gICAgICB0aGlzLnNlY3JldHMgPSBbXTtcbiAgICAgIGZvciAoY29uc3QgW25hbWUsIHNlY3JldF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHMuc2VjcmV0cykpIHtcbiAgICAgICAgaWYgKHNlY3JldC5oYXNGaWVsZCkge1xuICAgICAgICAgIHRoaXMucmVmZXJlbmNlc1NlY3JldEpzb25GaWVsZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgc2VjcmV0LmdyYW50UmVhZCh0aGlzLnRhc2tEZWZpbml0aW9uLm9idGFpbkV4ZWN1dGlvblJvbGUoKSk7XG4gICAgICAgIHRoaXMuc2VjcmV0cy5wdXNoKHtcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIHZhbHVlRnJvbTogc2VjcmV0LmFybixcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmVudmlyb25tZW50KSB7XG4gICAgICB0aGlzLmVudmlyb25tZW50ID0geyAuLi5wcm9wcy5lbnZpcm9ubWVudCB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVudmlyb25tZW50ID0ge307XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmVudmlyb25tZW50RmlsZXMpIHtcbiAgICAgIHRoaXMuZW52aXJvbm1lbnRGaWxlcyA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGVudmlyb25tZW50RmlsZSBvZiBwcm9wcy5lbnZpcm9ubWVudEZpbGVzKSB7XG4gICAgICAgIHRoaXMuZW52aXJvbm1lbnRGaWxlcy5wdXNoKGVudmlyb25tZW50RmlsZS5iaW5kKHRoaXMpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcm9wcy50YXNrRGVmaW5pdGlvbi5fbGlua0NvbnRhaW5lcih0aGlzKTtcblxuICAgIGlmIChwcm9wcy5wb3J0TWFwcGluZ3MpIHtcbiAgICAgIHRoaXMuYWRkUG9ydE1hcHBpbmdzKC4uLnByb3BzLnBvcnRNYXBwaW5ncyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmluZmVyZW5jZUFjY2VsZXJhdG9yUmVzb3VyY2VzKSB7XG4gICAgICB0aGlzLmFkZEluZmVyZW5jZUFjY2VsZXJhdG9yUmVzb3VyY2UoLi4ucHJvcHMuaW5mZXJlbmNlQWNjZWxlcmF0b3JSZXNvdXJjZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBhZGRzIGEgbGluayB3aGljaCBhbGxvd3MgY29udGFpbmVycyB0byBjb21tdW5pY2F0ZSB3aXRoIGVhY2ggb3RoZXIgd2l0aG91dCB0aGUgbmVlZCBmb3IgcG9ydCBtYXBwaW5ncy5cbiAgICpcbiAgICogVGhpcyBwYXJhbWV0ZXIgaXMgb25seSBzdXBwb3J0ZWQgaWYgdGhlIHRhc2sgZGVmaW5pdGlvbiBpcyB1c2luZyB0aGUgYnJpZGdlIG5ldHdvcmsgbW9kZS5cbiAgICogV2FybmluZzogVGhlIC0tbGluayBmbGFnIGlzIGEgbGVnYWN5IGZlYXR1cmUgb2YgRG9ja2VyLiBJdCBtYXkgZXZlbnR1YWxseSBiZSByZW1vdmVkLlxuICAgKi9cbiAgcHVibGljIGFkZExpbmsoY29udGFpbmVyOiBDb250YWluZXJEZWZpbml0aW9uLCBhbGlhcz86IHN0cmluZykge1xuICAgIGlmICh0aGlzLnRhc2tEZWZpbml0aW9uLm5ldHdvcmtNb2RlICE9PSBOZXR3b3JrTW9kZS5CUklER0UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG11c3QgdXNlIG5ldHdvcmsgbW9kZSBCcmlkZ2UgdG8gYWRkIGNvbnRhaW5lciBsaW5rcy4nKTtcbiAgICB9XG4gICAgaWYgKGFsaWFzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubGlua3MucHVzaChgJHtjb250YWluZXIuY29udGFpbmVyTmFtZX06JHthbGlhc31gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5saW5rcy5wdXNoKGAke2NvbnRhaW5lci5jb250YWluZXJOYW1lfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBhZGRzIG9uZSBvciBtb3JlIG1vdW50IHBvaW50cyBmb3IgZGF0YSB2b2x1bWVzIHRvIHRoZSBjb250YWluZXIuXG4gICAqL1xuICBwdWJsaWMgYWRkTW91bnRQb2ludHMoLi4ubW91bnRQb2ludHM6IE1vdW50UG9pbnRbXSkge1xuICAgIHRoaXMubW91bnRQb2ludHMucHVzaCguLi5tb3VudFBvaW50cyk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgbW91bnRzIHRlbXBvcmFyeSBkaXNrIHNwYWNlIHRvIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIFRoaXMgYWRkcyB0aGUgY29ycmVjdCBjb250YWluZXIgbW91bnRQb2ludCBhbmQgdGFzayBkZWZpbml0aW9uIHZvbHVtZS5cbiAgICovXG4gIHB1YmxpYyBhZGRTY3JhdGNoKHNjcmF0Y2g6IFNjcmF0Y2hTcGFjZSkge1xuICAgIGNvbnN0IG1vdW50UG9pbnQgPSB7XG4gICAgICBjb250YWluZXJQYXRoOiBzY3JhdGNoLmNvbnRhaW5lclBhdGgsXG4gICAgICByZWFkT25seTogc2NyYXRjaC5yZWFkT25seSxcbiAgICAgIHNvdXJjZVZvbHVtZTogc2NyYXRjaC5uYW1lLFxuICAgIH07XG5cbiAgICBjb25zdCB2b2x1bWUgPSB7XG4gICAgICBob3N0OiB7XG4gICAgICAgIHNvdXJjZVBhdGg6IHNjcmF0Y2guc291cmNlUGF0aCxcbiAgICAgIH0sXG4gICAgICBuYW1lOiBzY3JhdGNoLm5hbWUsXG4gICAgfTtcblxuICAgIHRoaXMudGFza0RlZmluaXRpb24uYWRkVm9sdW1lKHZvbHVtZSk7XG4gICAgdGhpcy5hZGRNb3VudFBvaW50cyhtb3VudFBvaW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBhZGRzIG9uZSBvciBtb3JlIHBvcnQgbWFwcGluZ3MgdG8gdGhlIGNvbnRhaW5lci5cbiAgICovXG4gIHB1YmxpYyBhZGRQb3J0TWFwcGluZ3MoLi4ucG9ydE1hcHBpbmdzOiBQb3J0TWFwcGluZ1tdKSB7XG4gICAgdGhpcy5wb3J0TWFwcGluZ3MucHVzaCguLi5wb3J0TWFwcGluZ3MubWFwKHBtID0+IHtcbiAgICAgIGlmICh0aGlzLnRhc2tEZWZpbml0aW9uLm5ldHdvcmtNb2RlID09PSBOZXR3b3JrTW9kZS5BV1NfVlBDIHx8IHRoaXMudGFza0RlZmluaXRpb24ubmV0d29ya01vZGUgPT09IE5ldHdvcmtNb2RlLkhPU1QpIHtcbiAgICAgICAgaWYgKHBtLmNvbnRhaW5lclBvcnQgIT09IHBtLmhvc3RQb3J0ICYmIHBtLmhvc3RQb3J0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEhvc3QgcG9ydCAoJHtwbS5ob3N0UG9ydH0pIG11c3QgYmUgbGVmdCBvdXQgb3IgZXF1YWwgdG8gY29udGFpbmVyIHBvcnQgJHtwbS5jb250YWluZXJQb3J0fSBmb3IgbmV0d29yayBtb2RlICR7dGhpcy50YXNrRGVmaW5pdGlvbi5uZXR3b3JrTW9kZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy50YXNrRGVmaW5pdGlvbi5uZXR3b3JrTW9kZSA9PT0gTmV0d29ya01vZGUuQlJJREdFKSB7XG4gICAgICAgIGlmIChwbS5ob3N0UG9ydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcG0gPSB7XG4gICAgICAgICAgICAuLi5wbSxcbiAgICAgICAgICAgIGhvc3RQb3J0OiAwLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBtO1xuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBhZGRzIGFuIGVudmlyb25tZW50IHZhcmlhYmxlIHRvIHRoZSBjb250YWluZXIuXG4gICAqL1xuICBwdWJsaWMgYWRkRW52aXJvbm1lbnQobmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5lbnZpcm9ubWVudFtuYW1lXSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGFkZHMgb25lIG9yIG1vcmUgcmVzb3VyY2VzIHRvIHRoZSBjb250YWluZXIuXG4gICAqL1xuICBwdWJsaWMgYWRkSW5mZXJlbmNlQWNjZWxlcmF0b3JSZXNvdXJjZSguLi5pbmZlcmVuY2VBY2NlbGVyYXRvclJlc291cmNlczogc3RyaW5nW10pIHtcbiAgICB0aGlzLmluZmVyZW5jZUFjY2VsZXJhdG9yUmVzb3VyY2VzLnB1c2goLi4uaW5mZXJlbmNlQWNjZWxlcmF0b3JSZXNvdXJjZXMubWFwKHJlc291cmNlID0+IHtcbiAgICAgIGZvciAoY29uc3QgaW5mZXJlbmNlQWNjZWxlcmF0b3Igb2YgdGhpcy50YXNrRGVmaW5pdGlvbi5pbmZlcmVuY2VBY2NlbGVyYXRvcnMpIHtcbiAgICAgICAgaWYgKHJlc291cmNlID09PSBpbmZlcmVuY2VBY2NlbGVyYXRvci5kZXZpY2VOYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc291cmNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlc291cmNlIHZhbHVlICR7cmVzb3VyY2V9IGluIGNvbnRhaW5lciBkZWZpbml0aW9uIGRvZXNuJ3QgbWF0Y2ggYW55IGluZmVyZW5jZSBhY2NlbGVyYXRvciBkZXZpY2UgbmFtZSBpbiB0aGUgdGFzayBkZWZpbml0aW9uLmApO1xuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBhZGRzIG9uZSBvciBtb3JlIHVsaW1pdHMgdG8gdGhlIGNvbnRhaW5lci5cbiAgICovXG4gIHB1YmxpYyBhZGRVbGltaXRzKC4uLnVsaW1pdHM6IFVsaW1pdFtdKSB7XG4gICAgdGhpcy51bGltaXRzLnB1c2goLi4udWxpbWl0cyk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgYWRkcyBvbmUgb3IgbW9yZSBjb250YWluZXIgZGVwZW5kZW5jaWVzIHRvIHRoZSBjb250YWluZXIuXG4gICAqL1xuICBwdWJsaWMgYWRkQ29udGFpbmVyRGVwZW5kZW5jaWVzKC4uLmNvbnRhaW5lckRlcGVuZGVuY2llczogQ29udGFpbmVyRGVwZW5kZW5jeVtdKSB7XG4gICAgdGhpcy5jb250YWluZXJEZXBlbmRlbmNpZXMucHVzaCguLi5jb250YWluZXJEZXBlbmRlbmNpZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGFkZHMgb25lIG9yIG1vcmUgdm9sdW1lcyB0byB0aGUgY29udGFpbmVyLlxuICAgKi9cbiAgcHVibGljIGFkZFZvbHVtZXNGcm9tKC4uLnZvbHVtZXNGcm9tOiBWb2x1bWVGcm9tW10pIHtcbiAgICB0aGlzLnZvbHVtZXNGcm9tLnB1c2goLi4udm9sdW1lc0Zyb20pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGFkZHMgdGhlIHNwZWNpZmllZCBzdGF0ZW1lbnQgdG8gdGhlIElBTSB0YXNrIGV4ZWN1dGlvbiBwb2xpY3kgaW4gdGhlIHRhc2sgZGVmaW5pdGlvbi5cbiAgICovXG4gIHB1YmxpYyBhZGRUb0V4ZWN1dGlvblBvbGljeShzdGF0ZW1lbnQ6IGlhbS5Qb2xpY3lTdGF0ZW1lbnQpIHtcbiAgICB0aGlzLnRhc2tEZWZpbml0aW9uLmFkZFRvRXhlY3V0aW9uUm9sZVBvbGljeShzdGF0ZW1lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGhvc3QgcG9ydCBmb3IgdGhlIHJlcXVlc3RlZCBjb250YWluZXIgcG9ydCBpZiBpdCBleGlzdHNcbiAgICovXG4gIHB1YmxpYyBmaW5kUG9ydE1hcHBpbmcoY29udGFpbmVyUG9ydDogbnVtYmVyLCBwcm90b2NvbDogUHJvdG9jb2wpOiBQb3J0TWFwcGluZyB8IHVuZGVmaW5lZCB7XG4gICAgZm9yIChjb25zdCBwb3J0TWFwcGluZyBvZiB0aGlzLnBvcnRNYXBwaW5ncykge1xuICAgICAgY29uc3QgcCA9IHBvcnRNYXBwaW5nLnByb3RvY29sIHx8IFByb3RvY29sLlRDUDtcbiAgICAgIGNvbnN0IGMgPSBwb3J0TWFwcGluZy5jb250YWluZXJQb3J0O1xuICAgICAgaWYgKGMgPT09IGNvbnRhaW5lclBvcnQgJiYgcCA9PT0gcHJvdG9jb2wpIHtcbiAgICAgICAgcmV0dXJuIHBvcnRNYXBwaW5nO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBpbmJvdW5kIHJ1bGVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2VjdXJpdHkgZ3JvdXAgdGhlIHRhc2sgb3Igc2VydmljZSB3aWxsIHVzZS5cbiAgICpcbiAgICogVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IHVzZWQgZm9yIHRhc2tzIHRoYXQgdXNlIHRoZSBhd3N2cGMgbmV0d29yayBtb2RlLlxuICAgKi9cbiAgcHVibGljIGdldCBpbmdyZXNzUG9ydCgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLnBvcnRNYXBwaW5ncy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ29udGFpbmVyICR7dGhpcy5jb250YWluZXJOYW1lfSBoYXNuJ3QgZGVmaW5lZCBhbnkgcG9ydHMuIENhbGwgYWRkUG9ydE1hcHBpbmdzKCkuYCk7XG4gICAgfVxuICAgIGNvbnN0IGRlZmF1bHRQb3J0TWFwcGluZyA9IHRoaXMucG9ydE1hcHBpbmdzWzBdO1xuXG4gICAgaWYgKGRlZmF1bHRQb3J0TWFwcGluZy5ob3N0UG9ydCAhPT0gdW5kZWZpbmVkICYmIGRlZmF1bHRQb3J0TWFwcGluZy5ob3N0UG9ydCAhPT0gMCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRQb3J0TWFwcGluZy5ob3N0UG9ydDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy50YXNrRGVmaW5pdGlvbi5uZXR3b3JrTW9kZSA9PT0gTmV0d29ya01vZGUuQlJJREdFKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmF1bHRQb3J0TWFwcGluZy5jb250YWluZXJQb3J0O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBwb3J0IHRoZSBjb250YWluZXIgd2lsbCBsaXN0ZW4gb24uXG4gICAqL1xuICBwdWJsaWMgZ2V0IGNvbnRhaW5lclBvcnQoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5wb3J0TWFwcGluZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbnRhaW5lciAke3RoaXMuY29udGFpbmVyTmFtZX0gaGFzbid0IGRlZmluZWQgYW55IHBvcnRzLiBDYWxsIGFkZFBvcnRNYXBwaW5ncygpLmApO1xuICAgIH1cbiAgICBjb25zdCBkZWZhdWx0UG9ydE1hcHBpbmcgPSB0aGlzLnBvcnRNYXBwaW5nc1swXTtcbiAgICByZXR1cm4gZGVmYXVsdFBvcnRNYXBwaW5nLmNvbnRhaW5lclBvcnQ7XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVyIHRoaXMgY29udGFpbmVyIGRlZmluaXRpb24gdG8gYSBDbG91ZEZvcm1hdGlvbiBvYmplY3RcbiAgICpcbiAgICogQHBhcmFtIF90YXNrRGVmaW5pdGlvbiBbZGlzYWJsZS1hd3NsaW50OnJlZi12aWEtaW50ZXJmYWNlXSAodW51c2VkIGJ1dCBrZXB0IHRvIGF2b2lkIGJyZWFraW5nIGNoYW5nZSlcbiAgICovXG4gIHB1YmxpYyByZW5kZXJDb250YWluZXJEZWZpbml0aW9uKF90YXNrRGVmaW5pdGlvbj86IFRhc2tEZWZpbml0aW9uKTogQ2ZuVGFza0RlZmluaXRpb24uQ29udGFpbmVyRGVmaW5pdGlvblByb3BlcnR5IHtcbiAgICByZXR1cm4ge1xuICAgICAgY29tbWFuZDogdGhpcy5wcm9wcy5jb21tYW5kLFxuICAgICAgY3B1OiB0aGlzLnByb3BzLmNwdSxcbiAgICAgIGRpc2FibGVOZXR3b3JraW5nOiB0aGlzLnByb3BzLmRpc2FibGVOZXR3b3JraW5nLFxuICAgICAgZGVwZW5kc09uOiBjZGsuTGF6eS5hbnkoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLmNvbnRhaW5lckRlcGVuZGVuY2llcy5tYXAocmVuZGVyQ29udGFpbmVyRGVwZW5kZW5jeSkgfSwgeyBvbWl0RW1wdHlBcnJheTogdHJ1ZSB9KSxcbiAgICAgIGRuc1NlYXJjaERvbWFpbnM6IHRoaXMucHJvcHMuZG5zU2VhcmNoRG9tYWlucyxcbiAgICAgIGRuc1NlcnZlcnM6IHRoaXMucHJvcHMuZG5zU2VydmVycyxcbiAgICAgIGRvY2tlckxhYmVsczogdGhpcy5wcm9wcy5kb2NrZXJMYWJlbHMsXG4gICAgICBkb2NrZXJTZWN1cml0eU9wdGlvbnM6IHRoaXMucHJvcHMuZG9ja2VyU2VjdXJpdHlPcHRpb25zLFxuICAgICAgZW50cnlQb2ludDogdGhpcy5wcm9wcy5lbnRyeVBvaW50LFxuICAgICAgZXNzZW50aWFsOiB0aGlzLmVzc2VudGlhbCxcbiAgICAgIGhvc3RuYW1lOiB0aGlzLnByb3BzLmhvc3RuYW1lLFxuICAgICAgaW1hZ2U6IHRoaXMuaW1hZ2VDb25maWcuaW1hZ2VOYW1lLFxuICAgICAgbWVtb3J5OiB0aGlzLnByb3BzLm1lbW9yeUxpbWl0TWlCLFxuICAgICAgbWVtb3J5UmVzZXJ2YXRpb246IHRoaXMucHJvcHMubWVtb3J5UmVzZXJ2YXRpb25NaUIsXG4gICAgICBtb3VudFBvaW50czogY2RrLkxhenkuYW55KHsgcHJvZHVjZTogKCkgPT4gdGhpcy5tb3VudFBvaW50cy5tYXAocmVuZGVyTW91bnRQb2ludCkgfSwgeyBvbWl0RW1wdHlBcnJheTogdHJ1ZSB9KSxcbiAgICAgIG5hbWU6IHRoaXMuY29udGFpbmVyTmFtZSxcbiAgICAgIHBvcnRNYXBwaW5nczogY2RrLkxhenkuYW55KHsgcHJvZHVjZTogKCkgPT4gdGhpcy5wb3J0TWFwcGluZ3MubWFwKHJlbmRlclBvcnRNYXBwaW5nKSB9LCB7IG9taXRFbXB0eUFycmF5OiB0cnVlIH0pLFxuICAgICAgcHJpdmlsZWdlZDogdGhpcy5wcm9wcy5wcml2aWxlZ2VkLFxuICAgICAgcmVhZG9ubHlSb290RmlsZXN5c3RlbTogdGhpcy5wcm9wcy5yZWFkb25seVJvb3RGaWxlc3lzdGVtLFxuICAgICAgcmVwb3NpdG9yeUNyZWRlbnRpYWxzOiB0aGlzLmltYWdlQ29uZmlnLnJlcG9zaXRvcnlDcmVkZW50aWFscyxcbiAgICAgIHN0YXJ0VGltZW91dDogdGhpcy5wcm9wcy5zdGFydFRpbWVvdXQgJiYgdGhpcy5wcm9wcy5zdGFydFRpbWVvdXQudG9TZWNvbmRzKCksXG4gICAgICBzdG9wVGltZW91dDogdGhpcy5wcm9wcy5zdG9wVGltZW91dCAmJiB0aGlzLnByb3BzLnN0b3BUaW1lb3V0LnRvU2Vjb25kcygpLFxuICAgICAgdWxpbWl0czogY2RrLkxhenkuYW55KHsgcHJvZHVjZTogKCkgPT4gdGhpcy51bGltaXRzLm1hcChyZW5kZXJVbGltaXQpIH0sIHsgb21pdEVtcHR5QXJyYXk6IHRydWUgfSksXG4gICAgICB1c2VyOiB0aGlzLnByb3BzLnVzZXIsXG4gICAgICB2b2x1bWVzRnJvbTogY2RrLkxhenkuYW55KHsgcHJvZHVjZTogKCkgPT4gdGhpcy52b2x1bWVzRnJvbS5tYXAocmVuZGVyVm9sdW1lRnJvbSkgfSwgeyBvbWl0RW1wdHlBcnJheTogdHJ1ZSB9KSxcbiAgICAgIHdvcmtpbmdEaXJlY3Rvcnk6IHRoaXMucHJvcHMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIGxvZ0NvbmZpZ3VyYXRpb246IHRoaXMubG9nRHJpdmVyQ29uZmlnLFxuICAgICAgZW52aXJvbm1lbnQ6IHRoaXMuZW52aXJvbm1lbnQgJiYgT2JqZWN0LmtleXModGhpcy5lbnZpcm9ubWVudCkubGVuZ3RoID8gcmVuZGVyS1YodGhpcy5lbnZpcm9ubWVudCwgJ25hbWUnLCAndmFsdWUnKSA6IHVuZGVmaW5lZCxcbiAgICAgIGVudmlyb25tZW50RmlsZXM6IHRoaXMuZW52aXJvbm1lbnRGaWxlcyAmJiByZW5kZXJFbnZpcm9ubWVudEZpbGVzKGNkay5TdGFjay5vZih0aGlzKS5wYXJ0aXRpb24sIHRoaXMuZW52aXJvbm1lbnRGaWxlcyksXG4gICAgICBzZWNyZXRzOiB0aGlzLnNlY3JldHMsXG4gICAgICBleHRyYUhvc3RzOiB0aGlzLnByb3BzLmV4dHJhSG9zdHMgJiYgcmVuZGVyS1YodGhpcy5wcm9wcy5leHRyYUhvc3RzLCAnaG9zdG5hbWUnLCAnaXBBZGRyZXNzJyksXG4gICAgICBoZWFsdGhDaGVjazogdGhpcy5wcm9wcy5oZWFsdGhDaGVjayAmJiByZW5kZXJIZWFsdGhDaGVjayh0aGlzLnByb3BzLmhlYWx0aENoZWNrKSxcbiAgICAgIGxpbmtzOiBjZGsuTGF6eS5saXN0KHsgcHJvZHVjZTogKCkgPT4gdGhpcy5saW5rcyB9LCB7IG9taXRFbXB0eTogdHJ1ZSB9KSxcbiAgICAgIGxpbnV4UGFyYW1ldGVyczogdGhpcy5saW51eFBhcmFtZXRlcnMgJiYgdGhpcy5saW51eFBhcmFtZXRlcnMucmVuZGVyTGludXhQYXJhbWV0ZXJzKCksXG4gICAgICByZXNvdXJjZVJlcXVpcmVtZW50czogKCF0aGlzLnByb3BzLmdwdUNvdW50ICYmIHRoaXMuaW5mZXJlbmNlQWNjZWxlcmF0b3JSZXNvdXJjZXMubGVuZ3RoID09IDAgKSA/IHVuZGVmaW5lZCA6XG4gICAgICAgIHJlbmRlclJlc291cmNlUmVxdWlyZW1lbnRzKHRoaXMucHJvcHMuZ3B1Q291bnQsIHRoaXMuaW5mZXJlbmNlQWNjZWxlcmF0b3JSZXNvdXJjZXMpLFxuICAgICAgc3lzdGVtQ29udHJvbHM6IHRoaXMucHJvcHMuc3lzdGVtQ29udHJvbHMgJiYgcmVuZGVyU3lzdGVtQ29udHJvbHModGhpcy5wcm9wcy5zeXN0ZW1Db250cm9scyksXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIFRoZSBoZWFsdGggY2hlY2sgY29tbWFuZCBhbmQgYXNzb2NpYXRlZCBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMgZm9yIHRoZSBjb250YWluZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSGVhbHRoQ2hlY2sge1xuICAvKipcbiAgICogQSBzdHJpbmcgYXJyYXkgcmVwcmVzZW50aW5nIHRoZSBjb21tYW5kIHRoYXQgdGhlIGNvbnRhaW5lciBydW5zIHRvIGRldGVybWluZSBpZiBpdCBpcyBoZWFsdGh5LlxuICAgKiBUaGUgc3RyaW5nIGFycmF5IG11c3Qgc3RhcnQgd2l0aCBDTUQgdG8gZXhlY3V0ZSB0aGUgY29tbWFuZCBhcmd1bWVudHMgZGlyZWN0bHksIG9yXG4gICAqIENNRC1TSEVMTCB0byBydW4gdGhlIGNvbW1hbmQgd2l0aCB0aGUgY29udGFpbmVyJ3MgZGVmYXVsdCBzaGVsbC5cbiAgICpcbiAgICogRm9yIGV4YW1wbGU6IFsgXCJDTUQtU0hFTExcIiwgXCJjdXJsIC1mIGh0dHA6Ly9sb2NhbGhvc3QvIHx8IGV4aXQgMVwiIF1cbiAgICovXG4gIHJlYWRvbmx5IGNvbW1hbmQ6IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgdGltZSBwZXJpb2QgaW4gc2Vjb25kcyBiZXR3ZWVuIGVhY2ggaGVhbHRoIGNoZWNrIGV4ZWN1dGlvbi5cbiAgICpcbiAgICogWW91IG1heSBzcGVjaWZ5IGJldHdlZW4gNSBhbmQgMzAwIHNlY29uZHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IER1cmF0aW9uLnNlY29uZHMoMzApXG4gICAqL1xuICByZWFkb25seSBpbnRlcnZhbD86IGNkay5EdXJhdGlvbjtcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiB0aW1lcyB0byByZXRyeSBhIGZhaWxlZCBoZWFsdGggY2hlY2sgYmVmb3JlIHRoZSBjb250YWluZXIgaXMgY29uc2lkZXJlZCB1bmhlYWx0aHkuXG4gICAqXG4gICAqIFlvdSBtYXkgc3BlY2lmeSBiZXR3ZWVuIDEgYW5kIDEwIHJldHJpZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IDNcbiAgICovXG4gIHJlYWRvbmx5IHJldHJpZXM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBvcHRpb25hbCBncmFjZSBwZXJpb2Qgd2l0aGluIHdoaWNoIHRvIHByb3ZpZGUgY29udGFpbmVycyB0aW1lIHRvIGJvb3RzdHJhcCBiZWZvcmVcbiAgICogZmFpbGVkIGhlYWx0aCBjaGVja3MgY291bnQgdG93YXJkcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgcmV0cmllcy5cbiAgICpcbiAgICogWW91IG1heSBzcGVjaWZ5IGJldHdlZW4gMCBhbmQgMzAwIHNlY29uZHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IE5vIHN0YXJ0IHBlcmlvZFxuICAgKi9cbiAgcmVhZG9ubHkgc3RhcnRQZXJpb2Q/OiBjZGsuRHVyYXRpb247XG5cbiAgLyoqXG4gICAqIFRoZSB0aW1lIHBlcmlvZCBpbiBzZWNvbmRzIHRvIHdhaXQgZm9yIGEgaGVhbHRoIGNoZWNrIHRvIHN1Y2NlZWQgYmVmb3JlIGl0IGlzIGNvbnNpZGVyZWQgYSBmYWlsdXJlLlxuICAgKlxuICAgKiBZb3UgbWF5IHNwZWNpZnkgYmV0d2VlbiAyIGFuZCA2MCBzZWNvbmRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBEdXJhdGlvbi5zZWNvbmRzKDUpXG4gICAqL1xuICByZWFkb25seSB0aW1lb3V0PzogY2RrLkR1cmF0aW9uO1xufVxuXG5mdW5jdGlvbiByZW5kZXJLVihlbnY6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0sIGtleU5hbWU6IHN0cmluZywgdmFsdWVOYW1lOiBzdHJpbmcpOiBhbnlbXSB7XG4gIGNvbnN0IHJldCA9IFtdO1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnYpKSB7XG4gICAgcmV0LnB1c2goeyBba2V5TmFtZV06IGtleSwgW3ZhbHVlTmFtZV06IHZhbHVlIH0pO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIHJlbmRlckVudmlyb25tZW50RmlsZXMocGFydGl0aW9uOiBzdHJpbmcsIGVudmlyb25tZW50RmlsZXM6IEVudmlyb25tZW50RmlsZUNvbmZpZ1tdKTogYW55W10ge1xuICBjb25zdCByZXQgPSBbXTtcbiAgZm9yIChjb25zdCBlbnZpcm9ubWVudEZpbGUgb2YgZW52aXJvbm1lbnRGaWxlcykge1xuICAgIGNvbnN0IHMzTG9jYXRpb24gPSBlbnZpcm9ubWVudEZpbGUuczNMb2NhdGlvbjtcblxuICAgIGlmICghczNMb2NhdGlvbikge1xuICAgICAgdGhyb3cgRXJyb3IoJ0Vudmlyb25tZW50IGZpbGUgbXVzdCBzcGVjaWZ5IGFuIFMzIGxvY2F0aW9uJyk7XG4gICAgfVxuXG4gICAgcmV0LnB1c2goe1xuICAgICAgdHlwZTogZW52aXJvbm1lbnRGaWxlLmZpbGVUeXBlLFxuICAgICAgdmFsdWU6IGBhcm46JHtwYXJ0aXRpb259OnMzOjo6JHtzM0xvY2F0aW9uLmJ1Y2tldE5hbWV9LyR7czNMb2NhdGlvbi5vYmplY3RLZXl9YCxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiByZW5kZXJIZWFsdGhDaGVjayhoYzogSGVhbHRoQ2hlY2spOiBDZm5UYXNrRGVmaW5pdGlvbi5IZWFsdGhDaGVja1Byb3BlcnR5IHtcbiAgcmV0dXJuIHtcbiAgICBjb21tYW5kOiBnZXRIZWFsdGhDaGVja0NvbW1hbmQoaGMpLFxuICAgIGludGVydmFsOiBoYy5pbnRlcnZhbD8udG9TZWNvbmRzKCkgPz8gMzAsXG4gICAgcmV0cmllczogaGMucmV0cmllcyA/PyAzLFxuICAgIHN0YXJ0UGVyaW9kOiBoYy5zdGFydFBlcmlvZD8udG9TZWNvbmRzKCksXG4gICAgdGltZW91dDogaGMudGltZW91dD8udG9TZWNvbmRzKCkgPz8gNSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0SGVhbHRoQ2hlY2tDb21tYW5kKGhjOiBIZWFsdGhDaGVjayk6IHN0cmluZ1tdIHtcbiAgY29uc3QgY21kID0gaGMuY29tbWFuZDtcbiAgY29uc3QgaGNDb21tYW5kID0gbmV3IEFycmF5PHN0cmluZz4oKTtcblxuICBpZiAoY21kLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQXQgbGVhc3Qgb25lIGFyZ3VtZW50IG11c3QgYmUgc3VwcGxpZWQgZm9yIGhlYWx0aCBjaGVjayBjb21tYW5kLicpO1xuICB9XG5cbiAgaWYgKGNtZC5sZW5ndGggPT09IDEpIHtcbiAgICBoY0NvbW1hbmQucHVzaCgnQ01ELVNIRUxMJywgY21kWzBdKTtcbiAgICByZXR1cm4gaGNDb21tYW5kO1xuICB9XG5cbiAgaWYgKGNtZFswXSAhPT0gJ0NNRCcgJiYgY21kWzBdICE9PSAnQ01ELVNIRUxMJykge1xuICAgIGhjQ29tbWFuZC5wdXNoKCdDTUQnKTtcbiAgfVxuXG4gIHJldHVybiBoY0NvbW1hbmQuY29uY2F0KGNtZCk7XG59XG5cbmZ1bmN0aW9uIHJlbmRlclJlc291cmNlUmVxdWlyZW1lbnRzKGdwdUNvdW50OiBudW1iZXIgPSAwLCBpbmZlcmVuY2VBY2NlbGVyYXRvclJlc291cmNlczogc3RyaW5nW10gPSBbXSk6XG5DZm5UYXNrRGVmaW5pdGlvbi5SZXNvdXJjZVJlcXVpcmVtZW50UHJvcGVydHlbXSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHJldCA9IFtdO1xuICBmb3IgKGNvbnN0IHJlc291cmNlIG9mIGluZmVyZW5jZUFjY2VsZXJhdG9yUmVzb3VyY2VzKSB7XG4gICAgcmV0LnB1c2goe1xuICAgICAgdHlwZTogJ0luZmVyZW5jZUFjY2VsZXJhdG9yJyxcbiAgICAgIHZhbHVlOiByZXNvdXJjZSxcbiAgICB9KTtcbiAgfVxuICBpZiAoZ3B1Q291bnQgPiAwKSB7XG4gICAgcmV0LnB1c2goe1xuICAgICAgdHlwZTogJ0dQVScsXG4gICAgICB2YWx1ZTogZ3B1Q291bnQudG9TdHJpbmcoKSxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIFRoZSB1bGltaXQgc2V0dGluZ3MgdG8gcGFzcyB0byB0aGUgY29udGFpbmVyLlxuICpcbiAqIE5PVEU6IERvZXMgbm90IHdvcmsgZm9yIFdpbmRvd3MgY29udGFpbmVycy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbGltaXQge1xuICAvKipcbiAgICogVGhlIHR5cGUgb2YgdGhlIHVsaW1pdC5cbiAgICpcbiAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbVWxpbWl0TmFtZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nkay9hcGkvbGF0ZXN0L3R5cGVzY3JpcHQvYXBpL2F3cy1lY3MvdWxpbWl0bmFtZS5odG1sI2F3c19lY3NfVWxpbWl0TmFtZSkuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBVbGltaXROYW1lLFxuXG4gIC8qKlxuICAgKiBUaGUgc29mdCBsaW1pdCBmb3IgdGhlIHVsaW1pdCB0eXBlLlxuICAgKi9cbiAgcmVhZG9ubHkgc29mdExpbWl0OiBudW1iZXIsXG5cbiAgLyoqXG4gICAqIFRoZSBoYXJkIGxpbWl0IGZvciB0aGUgdWxpbWl0IHR5cGUuXG4gICAqL1xuICByZWFkb25seSBoYXJkTGltaXQ6IG51bWJlcixcbn1cblxuLyoqXG4gKiBUeXBlIG9mIHJlc291cmNlIHRvIHNldCBhIGxpbWl0IG9uXG4gKi9cbmV4cG9ydCBlbnVtIFVsaW1pdE5hbWUge1xuICBDT1JFID0gJ2NvcmUnLFxuICBDUFUgPSAnY3B1JyxcbiAgREFUQSA9ICdkYXRhJyxcbiAgRlNJWkUgPSAnZnNpemUnLFxuICBMT0NLUyA9ICdsb2NrcycsXG4gIE1FTUxPQ0sgPSAnbWVtbG9jaycsXG4gIE1TR1FVRVVFID0gJ21zZ3F1ZXVlJyxcbiAgTklDRSA9ICduaWNlJyxcbiAgTk9GSUxFID0gJ25vZmlsZScsXG4gIE5QUk9DID0gJ25wcm9jJyxcbiAgUlNTID0gJ3JzcycsXG4gIFJUUFJJTyA9ICdydHByaW8nLFxuICBSVFRJTUUgPSAncnR0aW1lJyxcbiAgU0lHUEVORElORyA9ICdzaWdwZW5kaW5nJyxcbiAgU1RBQ0sgPSAnc3RhY2snXG59XG5cbmZ1bmN0aW9uIHJlbmRlclVsaW1pdCh1bGltaXQ6IFVsaW1pdCk6IENmblRhc2tEZWZpbml0aW9uLlVsaW1pdFByb3BlcnR5IHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiB1bGltaXQubmFtZSxcbiAgICBzb2Z0TGltaXQ6IHVsaW1pdC5zb2Z0TGltaXQsXG4gICAgaGFyZExpbWl0OiB1bGltaXQuaGFyZExpbWl0LFxuICB9O1xufVxuLyoqXG4gKiBUaGUgZGV0YWlscyBvZiBhIGRlcGVuZGVuY3kgb24gYW5vdGhlciBjb250YWluZXIgaW4gdGhlIHRhc2sgZGVmaW5pdGlvbi5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ29udGFpbmVyRGVwZW5kZW5jeS5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29udGFpbmVyRGVwZW5kZW5jeSB7XG4gIC8qKlxuICAgKiBUaGUgY29udGFpbmVyIHRvIGRlcGVuZCBvbi5cbiAgICovXG4gIHJlYWRvbmx5IGNvbnRhaW5lcjogQ29udGFpbmVyRGVmaW5pdGlvbjtcblxuICAvKipcbiAgICogVGhlIHN0YXRlIHRoZSBjb250YWluZXIgbmVlZHMgdG8gYmUgaW4gdG8gc2F0aXNmeSB0aGUgZGVwZW5kZW5jeSBhbmQgcHJvY2VlZCB3aXRoIHN0YXJ0dXAuXG4gICAqIFZhbGlkIHZhbHVlcyBhcmUgQ29udGFpbmVyRGVwZW5kZW5jeUNvbmRpdGlvbi5TVEFSVCwgQ29udGFpbmVyRGVwZW5kZW5jeUNvbmRpdGlvbi5DT01QTEVURSxcbiAgICogQ29udGFpbmVyRGVwZW5kZW5jeUNvbmRpdGlvbi5TVUNDRVNTIGFuZCBDb250YWluZXJEZXBlbmRlbmN5Q29uZGl0aW9uLkhFQUxUSFkuXG4gICAqXG4gICAqIEBkZWZhdWx0IENvbnRhaW5lckRlcGVuZGVuY3lDb25kaXRpb24uSEVBTFRIWVxuICAgKi9cbiAgcmVhZG9ubHkgY29uZGl0aW9uPzogQ29udGFpbmVyRGVwZW5kZW5jeUNvbmRpdGlvbjtcbn1cblxuZXhwb3J0IGVudW0gQ29udGFpbmVyRGVwZW5kZW5jeUNvbmRpdGlvbiB7XG4gIC8qKlxuICAgKiBUaGlzIGNvbmRpdGlvbiBlbXVsYXRlcyB0aGUgYmVoYXZpb3Igb2YgbGlua3MgYW5kIHZvbHVtZXMgdG9kYXkuXG4gICAqIEl0IHZhbGlkYXRlcyB0aGF0IGEgZGVwZW5kZW50IGNvbnRhaW5lciBpcyBzdGFydGVkIGJlZm9yZSBwZXJtaXR0aW5nIG90aGVyIGNvbnRhaW5lcnMgdG8gc3RhcnQuXG4gICAqL1xuICBTVEFSVCA9ICdTVEFSVCcsXG5cbiAgLyoqXG4gICAqIFRoaXMgY29uZGl0aW9uIHZhbGlkYXRlcyB0aGF0IGEgZGVwZW5kZW50IGNvbnRhaW5lciBydW5zIHRvIGNvbXBsZXRpb24gKGV4aXRzKSBiZWZvcmUgcGVybWl0dGluZyBvdGhlciBjb250YWluZXJzIHRvIHN0YXJ0LlxuICAgKiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIG5vbmVzc2VudGlhbCBjb250YWluZXJzIHRoYXQgcnVuIGEgc2NyaXB0IGFuZCB0aGVuIGV4aXQuXG4gICAqL1xuICBDT01QTEVURSA9ICdDT01QTEVURScsXG5cbiAgLyoqXG4gICAqIFRoaXMgY29uZGl0aW9uIGlzIHRoZSBzYW1lIGFzIENPTVBMRVRFLCBidXQgaXQgYWxzbyByZXF1aXJlcyB0aGF0IHRoZSBjb250YWluZXIgZXhpdHMgd2l0aCBhIHplcm8gc3RhdHVzLlxuICAgKi9cbiAgU1VDQ0VTUyA9ICdTVUNDRVNTJyxcblxuICAvKipcbiAgICogVGhpcyBjb25kaXRpb24gdmFsaWRhdGVzIHRoYXQgdGhlIGRlcGVuZGVudCBjb250YWluZXIgcGFzc2VzIGl0cyBEb2NrZXIgaGVhbHRoIGNoZWNrIGJlZm9yZSBwZXJtaXR0aW5nIG90aGVyIGNvbnRhaW5lcnMgdG8gc3RhcnQuXG4gICAqIFRoaXMgcmVxdWlyZXMgdGhhdCB0aGUgZGVwZW5kZW50IGNvbnRhaW5lciBoYXMgaGVhbHRoIGNoZWNrcyBjb25maWd1cmVkLiBUaGlzIGNvbmRpdGlvbiBpcyBjb25maXJtZWQgb25seSBhdCB0YXNrIHN0YXJ0dXAuXG4gICAqL1xuICBIRUFMVEhZID0gJ0hFQUxUSFknLFxufVxuXG5mdW5jdGlvbiByZW5kZXJDb250YWluZXJEZXBlbmRlbmN5KGNvbnRhaW5lckRlcGVuZGVuY3k6IENvbnRhaW5lckRlcGVuZGVuY3kpOiBDZm5UYXNrRGVmaW5pdGlvbi5Db250YWluZXJEZXBlbmRlbmN5UHJvcGVydHkge1xuICByZXR1cm4ge1xuICAgIGNvbnRhaW5lck5hbWU6IGNvbnRhaW5lckRlcGVuZGVuY3kuY29udGFpbmVyLmNvbnRhaW5lck5hbWUsXG4gICAgY29uZGl0aW9uOiBjb250YWluZXJEZXBlbmRlbmN5LmNvbmRpdGlvbiB8fCBDb250YWluZXJEZXBlbmRlbmN5Q29uZGl0aW9uLkhFQUxUSFksXG4gIH07XG59XG5cbi8qKlxuICogUG9ydCBtYXBwaW5ncyBhbGxvdyBjb250YWluZXJzIHRvIGFjY2VzcyBwb3J0cyBvbiB0aGUgaG9zdCBjb250YWluZXIgaW5zdGFuY2UgdG8gc2VuZCBvciByZWNlaXZlIHRyYWZmaWMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUG9ydE1hcHBpbmcge1xuICAvKipcbiAgICogVGhlIHBvcnQgbnVtYmVyIG9uIHRoZSBjb250YWluZXIgdGhhdCBpcyBib3VuZCB0byB0aGUgdXNlci1zcGVjaWZpZWQgb3IgYXV0b21hdGljYWxseSBhc3NpZ25lZCBob3N0IHBvcnQuXG4gICAqXG4gICAqIElmIHlvdSBhcmUgdXNpbmcgY29udGFpbmVycyBpbiBhIHRhc2sgd2l0aCB0aGUgYXdzdnBjIG9yIGhvc3QgbmV0d29yayBtb2RlLCBleHBvc2VkIHBvcnRzIHNob3VsZCBiZSBzcGVjaWZpZWQgdXNpbmcgY29udGFpbmVyUG9ydC5cbiAgICogSWYgeW91IGFyZSB1c2luZyBjb250YWluZXJzIGluIGEgdGFzayB3aXRoIHRoZSBicmlkZ2UgbmV0d29yayBtb2RlIGFuZCB5b3Ugc3BlY2lmeSBhIGNvbnRhaW5lciBwb3J0IGFuZCBub3QgYSBob3N0IHBvcnQsXG4gICAqIHlvdXIgY29udGFpbmVyIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZXMgYSBob3N0IHBvcnQgaW4gdGhlIGVwaGVtZXJhbCBwb3J0IHJhbmdlLlxuICAgKlxuICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIGhvc3RQb3J0LlxuICAgKiBQb3J0IG1hcHBpbmdzIHRoYXQgYXJlIGF1dG9tYXRpY2FsbHkgYXNzaWduZWQgaW4gdGhpcyB3YXkgZG8gbm90IGNvdW50IHRvd2FyZCB0aGUgMTAwIHJlc2VydmVkIHBvcnRzIGxpbWl0IG9mIGEgY29udGFpbmVyIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgY29udGFpbmVyUG9ydDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgcG9ydCBudW1iZXIgb24gdGhlIGNvbnRhaW5lciBpbnN0YW5jZSB0byByZXNlcnZlIGZvciB5b3VyIGNvbnRhaW5lci5cbiAgICpcbiAgICogSWYgeW91IGFyZSB1c2luZyBjb250YWluZXJzIGluIGEgdGFzayB3aXRoIHRoZSBhd3N2cGMgb3IgaG9zdCBuZXR3b3JrIG1vZGUsXG4gICAqIHRoZSBob3N0UG9ydCBjYW4gZWl0aGVyIGJlIGxlZnQgYmxhbmsgb3Igc2V0IHRvIHRoZSBzYW1lIHZhbHVlIGFzIHRoZSBjb250YWluZXJQb3J0LlxuICAgKlxuICAgKiBJZiB5b3UgYXJlIHVzaW5nIGNvbnRhaW5lcnMgaW4gYSB0YXNrIHdpdGggdGhlIGJyaWRnZSBuZXR3b3JrIG1vZGUsXG4gICAqIHlvdSBjYW4gc3BlY2lmeSBhIG5vbi1yZXNlcnZlZCBob3N0IHBvcnQgZm9yIHlvdXIgY29udGFpbmVyIHBvcnQgbWFwcGluZywgb3JcbiAgICogeW91IGNhbiBvbWl0IHRoZSBob3N0UG9ydCAob3Igc2V0IGl0IHRvIDApIHdoaWxlIHNwZWNpZnlpbmcgYSBjb250YWluZXJQb3J0IGFuZFxuICAgKiB5b3VyIGNvbnRhaW5lciBhdXRvbWF0aWNhbGx5IHJlY2VpdmVzIGEgcG9ydCBpbiB0aGUgZXBoZW1lcmFsIHBvcnQgcmFuZ2UgZm9yXG4gICAqIHlvdXIgY29udGFpbmVyIGluc3RhbmNlIG9wZXJhdGluZyBzeXN0ZW0gYW5kIERvY2tlciB2ZXJzaW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgaG9zdFBvcnQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBwcm90b2NvbCB1c2VkIGZvciB0aGUgcG9ydCBtYXBwaW5nLiBWYWxpZCB2YWx1ZXMgYXJlIFByb3RvY29sLlRDUCBhbmQgUHJvdG9jb2wuVURQLlxuICAgKlxuICAgKiBAZGVmYXVsdCBUQ1BcbiAgICovXG4gIHJlYWRvbmx5IHByb3RvY29sPzogUHJvdG9jb2xcbn1cblxuLyoqXG4gKiBOZXR3b3JrIHByb3RvY29sXG4gKi9cbmV4cG9ydCBlbnVtIFByb3RvY29sIHtcbiAgLyoqXG4gICAqIFRDUFxuICAgKi9cbiAgVENQID0gJ3RjcCcsXG5cbiAgLyoqXG4gICAqIFVEUFxuICAgKi9cbiAgVURQID0gJ3VkcCcsXG59XG5cbmZ1bmN0aW9uIHJlbmRlclBvcnRNYXBwaW5nKHBtOiBQb3J0TWFwcGluZyk6IENmblRhc2tEZWZpbml0aW9uLlBvcnRNYXBwaW5nUHJvcGVydHkge1xuICByZXR1cm4ge1xuICAgIGNvbnRhaW5lclBvcnQ6IHBtLmNvbnRhaW5lclBvcnQsXG4gICAgaG9zdFBvcnQ6IHBtLmhvc3RQb3J0LFxuICAgIHByb3RvY29sOiBwbS5wcm90b2NvbCB8fCBQcm90b2NvbC5UQ1AsXG4gIH07XG59XG5cbi8qKlxuICogVGhlIHRlbXBvcmFyeSBkaXNrIHNwYWNlIG1vdW50ZWQgdG8gdGhlIGNvbnRhaW5lci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTY3JhdGNoU3BhY2Uge1xuICAvKipcbiAgICogVGhlIHBhdGggb24gdGhlIGNvbnRhaW5lciB0byBtb3VudCB0aGUgc2NyYXRjaCB2b2x1bWUgYXQuXG4gICAqL1xuICByZWFkb25seSBjb250YWluZXJQYXRoOiBzdHJpbmcsXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgd2hldGhlciB0byBnaXZlIHRoZSBjb250YWluZXIgcmVhZC1vbmx5IGFjY2VzcyB0byB0aGUgc2NyYXRjaCB2b2x1bWUuXG4gICAqXG4gICAqIElmIHRoaXMgdmFsdWUgaXMgdHJ1ZSwgdGhlIGNvbnRhaW5lciBoYXMgcmVhZC1vbmx5IGFjY2VzcyB0byB0aGUgc2NyYXRjaCB2b2x1bWUuXG4gICAqIElmIHRoaXMgdmFsdWUgaXMgZmFsc2UsIHRoZW4gdGhlIGNvbnRhaW5lciBjYW4gd3JpdGUgdG8gdGhlIHNjcmF0Y2ggdm9sdW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVhZE9ubHk6IGJvb2xlYW4sXG4gIHJlYWRvbmx5IHNvdXJjZVBhdGg6IHN0cmluZyxcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBzY3JhdGNoIHZvbHVtZSB0byBtb3VudC4gTXVzdCBiZSBhIHZvbHVtZSBuYW1lIHJlZmVyZW5jZWQgaW4gdGhlIG5hbWUgcGFyYW1ldGVyIG9mIHRhc2sgZGVmaW5pdGlvbiB2b2x1bWUuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmcsXG59XG5cbi8qKlxuICogVGhlIGRldGFpbHMgb2YgZGF0YSB2b2x1bWUgbW91bnQgcG9pbnRzIGZvciBhIGNvbnRhaW5lci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb3VudFBvaW50IHtcbiAgLyoqXG4gICAqIFRoZSBwYXRoIG9uIHRoZSBjb250YWluZXIgdG8gbW91bnQgdGhlIGhvc3Qgdm9sdW1lIGF0LlxuICAgKi9cbiAgcmVhZG9ubHkgY29udGFpbmVyUGF0aDogc3RyaW5nLFxuICAvKipcbiAgICogU3BlY2lmaWVzIHdoZXRoZXIgdG8gZ2l2ZSB0aGUgY29udGFpbmVyIHJlYWQtb25seSBhY2Nlc3MgdG8gdGhlIHZvbHVtZS5cbiAgICpcbiAgICogSWYgdGhpcyB2YWx1ZSBpcyB0cnVlLCB0aGUgY29udGFpbmVyIGhhcyByZWFkLW9ubHkgYWNjZXNzIHRvIHRoZSB2b2x1bWUuXG4gICAqIElmIHRoaXMgdmFsdWUgaXMgZmFsc2UsIHRoZW4gdGhlIGNvbnRhaW5lciBjYW4gd3JpdGUgdG8gdGhlIHZvbHVtZS5cbiAgICovXG4gIHJlYWRvbmx5IHJlYWRPbmx5OiBib29sZWFuLFxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIHZvbHVtZSB0byBtb3VudC5cbiAgICpcbiAgICogTXVzdCBiZSBhIHZvbHVtZSBuYW1lIHJlZmVyZW5jZWQgaW4gdGhlIG5hbWUgcGFyYW1ldGVyIG9mIHRhc2sgZGVmaW5pdGlvbiB2b2x1bWUuXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VWb2x1bWU6IHN0cmluZyxcbn1cblxuZnVuY3Rpb24gcmVuZGVyTW91bnRQb2ludChtcDogTW91bnRQb2ludCk6IENmblRhc2tEZWZpbml0aW9uLk1vdW50UG9pbnRQcm9wZXJ0eSB7XG4gIHJldHVybiB7XG4gICAgY29udGFpbmVyUGF0aDogbXAuY29udGFpbmVyUGF0aCxcbiAgICByZWFkT25seTogbXAucmVhZE9ubHksXG4gICAgc291cmNlVm9sdW1lOiBtcC5zb3VyY2VWb2x1bWUsXG4gIH07XG59XG5cbi8qKlxuICogVGhlIGRldGFpbHMgb24gYSBkYXRhIHZvbHVtZSBmcm9tIGFub3RoZXIgY29udGFpbmVyIGluIHRoZSBzYW1lIHRhc2sgZGVmaW5pdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWb2x1bWVGcm9tIHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIGFub3RoZXIgY29udGFpbmVyIHdpdGhpbiB0aGUgc2FtZSB0YXNrIGRlZmluaXRpb24gZnJvbSB3aGljaCB0byBtb3VudCB2b2x1bWVzLlxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlQ29udGFpbmVyOiBzdHJpbmcsXG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB3aGV0aGVyIHRoZSBjb250YWluZXIgaGFzIHJlYWQtb25seSBhY2Nlc3MgdG8gdGhlIHZvbHVtZS5cbiAgICpcbiAgICogSWYgdGhpcyB2YWx1ZSBpcyB0cnVlLCB0aGUgY29udGFpbmVyIGhhcyByZWFkLW9ubHkgYWNjZXNzIHRvIHRoZSB2b2x1bWUuXG4gICAqIElmIHRoaXMgdmFsdWUgaXMgZmFsc2UsIHRoZW4gdGhlIGNvbnRhaW5lciBjYW4gd3JpdGUgdG8gdGhlIHZvbHVtZS5cbiAgICovXG4gIHJlYWRvbmx5IHJlYWRPbmx5OiBib29sZWFuLFxufVxuXG5mdW5jdGlvbiByZW5kZXJWb2x1bWVGcm9tKHZmOiBWb2x1bWVGcm9tKTogQ2ZuVGFza0RlZmluaXRpb24uVm9sdW1lRnJvbVByb3BlcnR5IHtcbiAgcmV0dXJuIHtcbiAgICBzb3VyY2VDb250YWluZXI6IHZmLnNvdXJjZUNvbnRhaW5lcixcbiAgICByZWFkT25seTogdmYucmVhZE9ubHksXG4gIH07XG59XG5cbi8qKlxuICogS2VybmVsIHBhcmFtZXRlcnMgdG8gc2V0IGluIHRoZSBjb250YWluZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTeXN0ZW1Db250cm9sIHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lc3BhY2VkIGtlcm5lbCBwYXJhbWV0ZXIgZm9yIHdoaWNoIHRvIHNldCBhIHZhbHVlLlxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZXNwYWNlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSBmb3IgdGhlIG5hbWVzcGFjZWQga2VybmVsIHBhcmFtZXRlciBzcGVjaWZpZWQgaW4gbmFtZXNwYWNlLlxuICAgKi9cbiAgcmVhZG9ubHkgdmFsdWU6IHN0cmluZztcbn1cblxuZnVuY3Rpb24gcmVuZGVyU3lzdGVtQ29udHJvbHMoc3lzdGVtQ29udHJvbHM6IFN5c3RlbUNvbnRyb2xbXSk6IENmblRhc2tEZWZpbml0aW9uLlN5c3RlbUNvbnRyb2xQcm9wZXJ0eVtdIHtcbiAgcmV0dXJuIHN5c3RlbUNvbnRyb2xzLm1hcChzYyA9PiAoe1xuICAgIG5hbWVzcGFjZTogc2MubmFtZXNwYWNlLFxuICAgIHZhbHVlOiBzYy52YWx1ZSxcbiAgfSkpO1xufVxuIl19
\No newline at end of file