@aws-cdk/aws-logs
Version:
The CDK Construct Library for AWS::Logs
314 lines • 37.1 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LogGroup = exports.RetentionDays = void 0;
const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const cloudwatch = require("@aws-cdk/aws-cloudwatch");
const iam = require("@aws-cdk/aws-iam");
const core_1 = require("@aws-cdk/core");
const log_stream_1 = require("./log-stream");
const logs_generated_1 = require("./logs.generated");
const metric_filter_1 = require("./metric-filter");
const pattern_1 = require("./pattern");
const policy_1 = require("./policy");
const subscription_filter_1 = require("./subscription-filter");
/**
* An CloudWatch Log Group
*/
class LogGroupBase extends core_1.Resource {
/**
* Create a new Log Stream for this Log Group
*
* @param id Unique identifier for the construct in its parent
* @param props Properties for creating the LogStream
*/
addStream(id, props = {}) {
return new log_stream_1.LogStream(this, id, {
logGroup: this,
...props,
});
}
/**
* Create a new Subscription Filter on this Log Group
*
* @param id Unique identifier for the construct in its parent
* @param props Properties for creating the SubscriptionFilter
*/
addSubscriptionFilter(id, props) {
return new subscription_filter_1.SubscriptionFilter(this, id, {
logGroup: this,
...props,
});
}
/**
* Create a new Metric Filter on this Log Group
*
* @param id Unique identifier for the construct in its parent
* @param props Properties for creating the MetricFilter
*/
addMetricFilter(id, props) {
return new metric_filter_1.MetricFilter(this, id, {
logGroup: this,
...props,
});
}
/**
* Extract a metric from structured log events in the LogGroup
*
* Creates a MetricFilter on this LogGroup that will extract the value
* of the indicated JSON field in all records where it occurs.
*
* The metric will be available in CloudWatch Metrics under the
* indicated namespace and name.
*
* @param jsonField JSON field to extract (example: '$.myfield')
* @param metricNamespace Namespace to emit the metric under
* @param metricName Name to emit the metric under
* @returns A Metric object representing the extracted metric
*/
extractMetric(jsonField, metricNamespace, metricName) {
new metric_filter_1.MetricFilter(this, `${metricNamespace}_${metricName}`, {
logGroup: this,
metricNamespace,
metricName,
filterPattern: pattern_1.FilterPattern.exists(jsonField),
metricValue: jsonField,
});
return new cloudwatch.Metric({ metricName, namespace: metricNamespace }).attachTo(this);
}
/**
* Give permissions to create and write to streams in this log group
*/
grantWrite(grantee) {
return this.grant(grantee, 'logs:CreateLogStream', 'logs:PutLogEvents');
}
/**
* Give the indicated permissions on this log group and all streams
*/
grant(grantee, ...actions) {
return iam.Grant.addToPrincipalOrResource({
grantee,
actions,
// A LogGroup ARN out of CloudFormation already includes a ':*' at the end to include the log streams under the group.
// See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-loggroup.html#w2ab1c21c10c63c43c11
resourceArns: [this.logGroupArn],
resource: this,
});
}
/**
* Public method to get the physical name of this log group
* @returns Physical name of log group
*/
logGroupPhysicalName() {
return this.physicalName;
}
/**
* Adds a statement to the resource policy associated with this log group.
* A resource policy will be automatically created upon the first call to `addToResourcePolicy`.
*
* Any ARN Principals inside of the statement will be converted into AWS Account ID strings
* because CloudWatch Logs Resource Policies do not accept ARN principals.
*
* @param statement The policy statement to add
*/
addToResourcePolicy(statement) {
if (!this.policy) {
this.policy = new policy_1.ResourcePolicy(this, 'Policy');
}
this.policy.document.addStatements(statement.copy({
principals: statement.principals.map(p => this.convertArnPrincpalToAccountId(p)),
}));
return { statementAdded: true, policyDependable: this.policy };
}
convertArnPrincpalToAccountId(principal) {
if (principal.principalAccount) {
// we use ArnPrincipal here because the constructor inserts the argument
// into the template without mutating it, which means that there is no
// ARN created by this call.
return new iam.ArnPrincipal(principal.principalAccount);
}
if (principal instanceof iam.ArnPrincipal) {
const parsedArn = core_1.Arn.split(principal.arn, core_1.ArnFormat.SLASH_RESOURCE_NAME);
if (parsedArn.account) {
return new iam.ArnPrincipal(parsedArn.account);
}
}
return principal;
}
}
/**
* How long, in days, the log contents will be retained.
*/
var RetentionDays;
(function (RetentionDays) {
/**
* 1 day
*/
RetentionDays[RetentionDays["ONE_DAY"] = 1] = "ONE_DAY";
/**
* 3 days
*/
RetentionDays[RetentionDays["THREE_DAYS"] = 3] = "THREE_DAYS";
/**
* 5 days
*/
RetentionDays[RetentionDays["FIVE_DAYS"] = 5] = "FIVE_DAYS";
/**
* 1 week
*/
RetentionDays[RetentionDays["ONE_WEEK"] = 7] = "ONE_WEEK";
/**
* 2 weeks
*/
RetentionDays[RetentionDays["TWO_WEEKS"] = 14] = "TWO_WEEKS";
/**
* 1 month
*/
RetentionDays[RetentionDays["ONE_MONTH"] = 30] = "ONE_MONTH";
/**
* 2 months
*/
RetentionDays[RetentionDays["TWO_MONTHS"] = 60] = "TWO_MONTHS";
/**
* 3 months
*/
RetentionDays[RetentionDays["THREE_MONTHS"] = 90] = "THREE_MONTHS";
/**
* 4 months
*/
RetentionDays[RetentionDays["FOUR_MONTHS"] = 120] = "FOUR_MONTHS";
/**
* 5 months
*/
RetentionDays[RetentionDays["FIVE_MONTHS"] = 150] = "FIVE_MONTHS";
/**
* 6 months
*/
RetentionDays[RetentionDays["SIX_MONTHS"] = 180] = "SIX_MONTHS";
/**
* 1 year
*/
RetentionDays[RetentionDays["ONE_YEAR"] = 365] = "ONE_YEAR";
/**
* 13 months
*/
RetentionDays[RetentionDays["THIRTEEN_MONTHS"] = 400] = "THIRTEEN_MONTHS";
/**
* 18 months
*/
RetentionDays[RetentionDays["EIGHTEEN_MONTHS"] = 545] = "EIGHTEEN_MONTHS";
/**
* 2 years
*/
RetentionDays[RetentionDays["TWO_YEARS"] = 731] = "TWO_YEARS";
/**
* 5 years
*/
RetentionDays[RetentionDays["FIVE_YEARS"] = 1827] = "FIVE_YEARS";
/**
* 6 years
*/
RetentionDays[RetentionDays["SIX_YEARS"] = 2192] = "SIX_YEARS";
/**
* 7 years
*/
RetentionDays[RetentionDays["SEVEN_YEARS"] = 2557] = "SEVEN_YEARS";
/**
* 8 years
*/
RetentionDays[RetentionDays["EIGHT_YEARS"] = 2922] = "EIGHT_YEARS";
/**
* 9 years
*/
RetentionDays[RetentionDays["NINE_YEARS"] = 3288] = "NINE_YEARS";
/**
* 10 years
*/
RetentionDays[RetentionDays["TEN_YEARS"] = 3653] = "TEN_YEARS";
/**
* Retain logs forever
*/
RetentionDays[RetentionDays["INFINITE"] = 9999] = "INFINITE";
})(RetentionDays = exports.RetentionDays || (exports.RetentionDays = {}));
/**
* Define a CloudWatch Log Group
*/
class LogGroup extends LogGroupBase {
constructor(scope, id, props = {}) {
super(scope, id, {
physicalName: props.logGroupName,
});
try {
jsiiDeprecationWarnings._aws_cdk_aws_logs_LogGroupProps(props);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, LogGroup);
}
throw error;
}
let retentionInDays = props.retention;
if (retentionInDays === undefined) {
retentionInDays = RetentionDays.TWO_YEARS;
}
if (retentionInDays === Infinity || retentionInDays === RetentionDays.INFINITE) {
retentionInDays = undefined;
}
if (retentionInDays !== undefined && !core_1.Token.isUnresolved(retentionInDays) && retentionInDays <= 0) {
throw new Error(`retentionInDays must be positive, got ${retentionInDays}`);
}
const resource = new logs_generated_1.CfnLogGroup(this, 'Resource', {
kmsKeyId: props.encryptionKey?.keyArn,
logGroupName: this.physicalName,
retentionInDays,
});
resource.applyRemovalPolicy(props.removalPolicy);
this.logGroupArn = this.getResourceArnAttribute(resource.attrArn, {
service: 'logs',
resource: 'log-group',
resourceName: this.physicalName,
arnFormat: core_1.ArnFormat.COLON_RESOURCE_NAME,
});
this.logGroupName = this.getResourceNameAttribute(resource.ref);
}
/**
* Import an existing LogGroup given its ARN
*/
static fromLogGroupArn(scope, id, logGroupArn) {
const baseLogGroupArn = logGroupArn.replace(/:\*$/, '');
class Import extends LogGroupBase {
constructor() {
super(...arguments);
this.logGroupArn = `${baseLogGroupArn}:*`;
this.logGroupName = core_1.Stack.of(scope).splitArn(baseLogGroupArn, core_1.ArnFormat.COLON_RESOURCE_NAME).resourceName;
}
}
return new Import(scope, id, {
environmentFromArn: baseLogGroupArn,
});
}
/**
* Import an existing LogGroup given its name
*/
static fromLogGroupName(scope, id, logGroupName) {
const baseLogGroupName = logGroupName.replace(/:\*$/, '');
class Import extends LogGroupBase {
constructor() {
super(...arguments);
this.logGroupName = baseLogGroupName;
this.logGroupArn = core_1.Stack.of(scope).formatArn({
service: 'logs',
resource: 'log-group',
arnFormat: core_1.ArnFormat.COLON_RESOURCE_NAME,
resourceName: baseLogGroupName + ':*',
});
}
}
return new Import(scope, id);
}
}
exports.LogGroup = LogGroup;
_a = JSII_RTTI_SYMBOL_1;
LogGroup[_a] = { fqn: "@aws-cdk/aws-logs.LogGroup", version: "1.204.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nLWdyb3VwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibG9nLWdyb3VwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHNEQUFzRDtBQUN0RCx3Q0FBd0M7QUFFeEMsd0NBQXNGO0FBRXRGLDZDQUF5QztBQUN6QyxxREFBK0M7QUFDL0MsbURBQStDO0FBQy9DLHVDQUEwRDtBQUMxRCxxQ0FBMEM7QUFDMUMsK0RBQXdGO0FBd0V4Rjs7R0FFRztBQUNILE1BQWUsWUFBYSxTQUFRLGVBQVE7SUFjMUM7Ozs7O09BS0c7SUFDSSxTQUFTLENBQUMsRUFBVSxFQUFFLFFBQXVCLEVBQUU7UUFDcEQsT0FBTyxJQUFJLHNCQUFTLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRTtZQUM3QixRQUFRLEVBQUUsSUFBSTtZQUNkLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztLQUNKO0lBRUQ7Ozs7O09BS0c7SUFDSSxxQkFBcUIsQ0FBQyxFQUFVLEVBQUUsS0FBZ0M7UUFDdkUsT0FBTyxJQUFJLHdDQUFrQixDQUFDLElBQUksRUFBRSxFQUFFLEVBQUU7WUFDdEMsUUFBUSxFQUFFLElBQUk7WUFDZCxHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUM7S0FDSjtJQUVEOzs7OztPQUtHO0lBQ0ksZUFBZSxDQUFDLEVBQVUsRUFBRSxLQUEwQjtRQUMzRCxPQUFPLElBQUksNEJBQVksQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFO1lBQ2hDLFFBQVEsRUFBRSxJQUFJO1lBQ2QsR0FBRyxLQUFLO1NBQ1QsQ0FBQyxDQUFDO0tBQ0o7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0ksYUFBYSxDQUFDLFNBQWlCLEVBQUUsZUFBdUIsRUFBRSxVQUFrQjtRQUNqRixJQUFJLDRCQUFZLENBQUMsSUFBSSxFQUFFLEdBQUcsZUFBZSxJQUFJLFVBQVUsRUFBRSxFQUFFO1lBQ3pELFFBQVEsRUFBRSxJQUFJO1lBQ2QsZUFBZTtZQUNmLFVBQVU7WUFDVixhQUFhLEVBQUUsdUJB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QUFVLEVBQUUsWUFBb0I7UUFDL0UsTUFBTSxnQkFBZ0IsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztRQUUxRCxNQUFNLE1BQU8sU0FBUSxZQUFZO1lBQWpDOztnQkFDa0IsaUJBQVksR0FBRyxnQkFBZ0IsQ0FBQztnQkFDaEMsZ0JBQVcsR0FBRyxZQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLFNBQVMsQ0FBQztvQkFDdEQsT0FBTyxFQUFFLE1BQU07b0JBQ2YsUUFBUSxFQUFFLFdBQVc7b0JBQ3JCLFNBQVMsRUFBRSxnQkFBUyxDQUFDLG1CQUFtQjtvQkFDeEMsWUFBWSxFQUFFLGdCQUFnQixHQUFHLElBQUk7aUJBQ3RDLENBQUMsQ0FBQztZQUNMLENBQUM7U0FBQTtRQUVELE9BQU8sSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0tBQzlCOztBQWxDSCw0QkEyRUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjbG91ZHdhdGNoIGZyb20gJ0Bhd3MtY2RrL2F3cy1jbG91ZHdhdGNoJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdAYXdzLWNkay9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGttcyBmcm9tICdAYXdzLWNkay9hd3Mta21zJztcbmltcG9ydCB7IEFybiwgQXJuRm9ybWF0LCBSZW1vdmFsUG9saWN5LCBSZXNvdXJjZSwgU3RhY2ssIFRva2VuIH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IExvZ1N0cmVhbSB9IGZyb20gJy4vbG9nLXN0cmVhbSc7XG5pbXBvcnQgeyBDZm5Mb2dHcm91cCB9IGZyb20gJy4vbG9ncy5nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgTWV0cmljRmlsdGVyIH0gZnJvbSAnLi9tZXRyaWMtZmlsdGVyJztcbmltcG9ydCB7IEZpbHRlclBhdHRlcm4sIElGaWx0ZXJQYXR0ZXJuIH0gZnJvbSAnLi9wYXR0ZXJuJztcbmltcG9ydCB7IFJlc291cmNlUG9saWN5IH0gZnJvbSAnLi9wb2xpY3knO1xuaW1wb3J0IHsgSUxvZ1N1YnNjcmlwdGlvbkRlc3RpbmF0aW9uLCBTdWJzY3JpcHRpb25GaWx0ZXIgfSBmcm9tICcuL3N1YnNjcmlwdGlvbi1maWx0ZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIElMb2dHcm91cCBleHRlbmRzIGlhbS5JUmVzb3VyY2VXaXRoUG9saWN5IHtcbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhpcyBsb2cgZ3JvdXAsIHdpdGggJzoqJyBhcHBlbmRlZFxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBsb2dHcm91cEFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGlzIGxvZyBncm91cFxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBsb2dHcm91cE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IExvZyBTdHJlYW0gZm9yIHRoaXMgTG9nIEdyb3VwXG4gICAqXG4gICAqIEBwYXJhbSBpZCBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNvbnN0cnVjdCBpbiBpdHMgcGFyZW50XG4gICAqIEBwYXJhbSBwcm9wcyBQcm9wZXJ0aWVzIGZvciBjcmVhdGluZyB0aGUgTG9nU3RyZWFtXG4gICAqL1xuICBhZGRTdHJlYW0oaWQ6IHN0cmluZywgcHJvcHM/OiBTdHJlYW1PcHRpb25zKTogTG9nU3RyZWFtO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgU3Vic2NyaXB0aW9uIEZpbHRlciBvbiB0aGlzIExvZyBHcm91cFxuICAgKlxuICAgKiBAcGFyYW0gaWQgVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBjb25zdHJ1Y3QgaW4gaXRzIHBhcmVudFxuICAgKiBAcGFyYW0gcHJvcHMgUHJvcGVydGllcyBmb3IgY3JlYXRpbmcgdGhlIFN1YnNjcmlwdGlvbkZpbHRlclxuICAgKi9cbiAgYWRkU3Vic2NyaXB0aW9uRmlsdGVyKGlkOiBzdHJpbmcsIHByb3BzOiBTdWJzY3JpcHRpb25GaWx0ZXJPcHRpb25zKTogU3Vic2NyaXB0aW9uRmlsdGVyO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgTWV0cmljIEZpbHRlciBvbiB0aGlzIExvZyBHcm91cFxuICAgKlxuICAgKiBAcGFyYW0gaWQgVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBjb25zdHJ1Y3QgaW4gaXRzIHBhcmVudFxuICAgKiBAcGFyYW0gcHJvcHMgUHJvcGVydGllcyBmb3IgY3JlYXRpbmcgdGhlIE1ldHJpY0ZpbHRlclxuICAgKi9cbiAgYWRkTWV0cmljRmlsdGVyKGlkOiBzdHJpbmcsIHByb3BzOiBNZXRyaWNGaWx0ZXJPcHRpb25zKTogTWV0cmljRmlsdGVyO1xuXG4gIC8qKlxuICAgKiBFeHRyYWN0IGEgbWV0cmljIGZyb20gc3RydWN0dXJlZCBsb2cgZXZlbnRzIGluIHRoZSBMb2dHcm91cFxuICAgKlxuICAgKiBDcmVhdGVzIGEgTWV0cmljRmlsdGVyIG9uIHRoaXMgTG9nR3JvdXAgdGhhdCB3aWxsIGV4dHJhY3QgdGhlIHZhbHVlXG4gICAqIG9mIHRoZSBpbmRpY2F0ZWQgSlNPTiBmaWVsZCBpbiBhbGwgcmVjb3JkcyB3aGVyZSBpdCBvY2N1cnMuXG4gICAqXG4gICAqIFRoZSBtZXRyaWMgd2lsbCBiZSBhdmFpbGFibGUgaW4gQ2xvdWRXYXRjaCBNZXRyaWNzIHVuZGVyIHRoZVxuICAgKiBpbmRpY2F0ZWQgbmFtZXNwYWNlIGFuZCBuYW1lLlxuICAgKlxuICAgKiBAcGFyYW0ganNvbkZpZWxkIEpTT04gZmllbGQgdG8gZXh0cmFjdCAoZXhhbXBsZTogJyQubXlmaWVsZCcpXG4gICAqIEBwYXJhbSBtZXRyaWNOYW1lc3BhY2UgTmFtZXNwYWNlIHRvIGVtaXQgdGhlIG1ldHJpYyB1bmRlclxuICAgKiBAcGFyYW0gbWV0cmljTmFtZSBOYW1lIHRvIGVtaXQgdGhlIG1ldHJpYyB1bmRlclxuICAgKiBAcmV0dXJucyBBIE1ldHJpYyBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBleHRyYWN0ZWQgbWV0cmljXG4gICAqL1xuICBleHRyYWN0TWV0cmljKGpzb25GaWVsZDogc3RyaW5nLCBtZXRyaWNOYW1lc3BhY2U6IHN0cmluZywgbWV0cmljTmFtZTogc3RyaW5nKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIEdpdmUgcGVybWlzc2lvbnMgdG8gd3JpdGUgdG8gY3JlYXRlIGFuZCB3cml0ZSB0byBzdHJlYW1zIGluIHRoaXMgbG9nIGdyb3VwXG4gICAqL1xuICBncmFudFdyaXRlKGdyYW50ZWU6IGlhbS5JR3JhbnRhYmxlKTogaWFtLkdyYW50O1xuXG4gIC8qKlxuICAgKiBHaXZlIHRoZSBpbmRpY2F0ZWQgcGVybWlzc2lvbnMgb24gdGhpcyBsb2cgZ3JvdXAgYW5kIGFsbCBzdHJlYW1zXG4gICAqL1xuICBncmFudChncmFudGVlOiBpYW0uSUdyYW50YWJsZSwgLi4uYWN0aW9uczogc3RyaW5nW10pOiBpYW0uR3JhbnQ7XG5cbiAgLyoqXG4gICAqIFB1YmxpYyBtZXRob2QgdG8gZ2V0IHRoZSBwaHlzaWNhbCBuYW1lIG9mIHRoaXMgbG9nIGdyb3VwXG4gICAqL1xuICBsb2dHcm91cFBoeXNpY2FsTmFtZSgpOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQW4gQ2xvdWRXYXRjaCBMb2cgR3JvdXBcbiAqL1xuYWJzdHJhY3QgY2xhc3MgTG9nR3JvdXBCYXNlIGV4dGVuZHMgUmVzb3VyY2UgaW1wbGVtZW50cyBJTG9nR3JvdXAge1xuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGlzIGxvZyBncm91cCwgd2l0aCAnOionIGFwcGVuZGVkXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgbG9nR3JvdXBBcm46IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhpcyBsb2cgZ3JvdXBcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBsb2dHcm91cE5hbWU6IHN0cmluZztcblxuXG4gIHByaXZhdGUgcG9saWN5PzogUmVzb3VyY2VQb2xpY3k7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBMb2cgU3RyZWFtIGZvciB0aGlzIExvZyBHcm91cFxuICAgKlxuICAgKiBAcGFyYW0gaWQgVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBjb25zdHJ1Y3QgaW4gaXRzIHBhcmVudFxuICAgKiBAcGFyYW0gcHJvcHMgUHJvcGVydGllcyBmb3IgY3JlYXRpbmcgdGhlIExvZ1N0cmVhbVxuICAgKi9cbiAgcHVibGljIGFkZFN0cmVhbShpZDogc3RyaW5nLCBwcm9wczogU3RyZWFtT3B0aW9ucyA9IHt9KTogTG9nU3RyZWFtIHtcbiAgICByZXR1cm4gbmV3IExvZ1N0cmVhbSh0aGlzLCBpZCwge1xuICAgICAgbG9nR3JvdXA6IHRoaXMsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgU3Vic2NyaXB0aW9uIEZpbHRlciBvbiB0aGlzIExvZyBHcm91cFxuICAgKlxuICAgKiBAcGFyYW0gaWQgVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBjb25zdHJ1Y3QgaW4gaXRzIHBhcmVudFxuICAgKiBAcGFyYW0gcHJvcHMgUHJvcGVydGllcyBmb3IgY3JlYXRpbmcgdGhlIFN1YnNjcmlwdGlvbkZpbHRlclxuICAgKi9cbiAgcHVibGljIGFkZFN1YnNjcmlwdGlvbkZpbHRlcihpZDogc3RyaW5nLCBwcm9wczogU3Vic2NyaXB0aW9uRmlsdGVyT3B0aW9ucyk6IFN1YnNjcmlwdGlvbkZpbHRlciB7XG4gICAgcmV0dXJuIG5ldyBTdWJzY3JpcHRpb25GaWx0ZXIodGhpcywgaWQsIHtcbiAgICAgIGxvZ0dyb3VwOiB0aGlzLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IE1ldHJpYyBGaWx0ZXIgb24gdGhpcyBMb2cgR3JvdXBcbiAgICpcbiAgICogQHBhcmFtIGlkIFVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgY29uc3RydWN0IGluIGl0cyBwYXJlbnRcbiAgICogQHBhcmFtIHByb3BzIFByb3BlcnRpZXMgZm9yIGNyZWF0aW5nIHRoZSBNZXRyaWNGaWx0ZXJcbiAgICovXG4gIHB1YmxpYyBhZGRNZXRyaWNGaWx0ZXIoaWQ6IHN0cmluZywgcHJvcHM6IE1ldHJpY0ZpbHRlck9wdGlvbnMpOiBNZXRyaWNGaWx0ZXIge1xuICAgIHJldHVybiBuZXcgTWV0cmljRmlsdGVyKHRoaXMsIGlkLCB7XG4gICAgICBsb2dHcm91cDogdGhpcyxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3QgYSBtZXRyaWMgZnJvbSBzdHJ1Y3R1cmVkIGxvZyBldmVudHMgaW4gdGhlIExvZ0dyb3VwXG4gICAqXG4gICAqIENyZWF0ZXMgYSBNZXRyaWNGaWx0ZXIgb24gdGhpcyBMb2dHcm91cCB0aGF0IHdpbGwgZXh0cmFjdCB0aGUgdmFsdWVcbiAgICogb2YgdGhlIGluZGljYXRlZCBKU09OIGZpZWxkIGluIGFsbCByZWNvcmRzIHdoZXJlIGl0IG9jY3Vycy5cbiAgICpcbiAgICogVGhlIG1ldHJpYyB3aWxsIGJlIGF2YWlsYWJsZSBpbiBDbG91ZFdhdGNoIE1ldHJpY3MgdW5kZXIgdGhlXG4gICAqIGluZGljYXRlZCBuYW1lc3BhY2UgYW5kIG5hbWUuXG4gICAqXG4gICAqIEBwYXJhbSBqc29uRmllbGQgSlNPTiBmaWVsZCB0byBleHRyYWN0IChleGFtcGxlOiAnJC5teWZpZWxkJylcbiAgICogQHBhcmFtIG1ldHJpY05hbWVzcGFjZSBOYW1lc3BhY2UgdG8gZW1pdCB0aGUgbWV0cmljIHVuZGVyXG4gICAqIEBwYXJhbSBtZXRyaWNOYW1lIE5hbWUgdG8gZW1pdCB0aGUgbWV0cmljIHVuZGVyXG4gICAqIEByZXR1cm5zIEEgTWV0cmljIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGV4dHJhY3RlZCBtZXRyaWNcbiAgICovXG4gIHB1YmxpYyBleHRyYWN0TWV0cmljKGpzb25GaWVsZDogc3RyaW5nLCBtZXRyaWNOYW1lc3BhY2U6IHN0cmluZywgbWV0cmljTmFtZTogc3RyaW5nKSB7XG4gICAgbmV3IE1ldHJpY0ZpbHRlcih0aGlzLCBgJHttZXRyaWNOYW1lc3BhY2V9XyR7bWV0cmljTmFtZX1gLCB7XG4gICAgICBsb2dHcm91cDogdGhpcyxcbiAgICAgIG1ldHJpY05hbWVzcGFjZSxcbiAgICAgIG1ldHJpY05hbWUsXG4gICAgICBmaWx0ZXJQYXR0ZXJuOiBGaWx0ZXJQYXR0ZXJuLmV4aXN0cyhqc29uRmllbGQpLFxuICAgICAgbWV0cmljVmFsdWU6IGpzb25GaWVsZCxcbiAgICB9KTtcblxuICAgIHJldHVybiBuZXcgY2xvdWR3YXRjaC5NZXRyaWMoeyBtZXRyaWNOYW1lLCBuYW1lc3BhY2U6IG1ldHJpY05hbWVzcGFjZSB9KS5hdHRhY2hUbyh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlIHBlcm1pc3Npb25zIHRvIGNyZWF0ZSBhbmQgd3JpdGUgdG8gc3RyZWFtcyBpbiB0aGlzIGxvZyBncm91cFxuICAgKi9cbiAgcHVibGljIGdyYW50V3JpdGUoZ3JhbnRlZTogaWFtLklHcmFudGFibGUpIHtcbiAgICByZXR1cm4gdGhpcy5ncmFudChncmFudGVlLCAnbG9nczpDcmVhdGVMb2dTdHJlYW0nLCAnbG9nczpQdXRMb2dFdmVudHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlIHRoZSBpbmRpY2F0ZWQgcGVybWlzc2lvbnMgb24gdGhpcyBsb2cgZ3JvdXAgYW5kIGFsbCBzdHJlYW1zXG4gICAqL1xuICBwdWJsaWMgZ3JhbnQoZ3JhbnRlZTogaWFtLklHcmFudGFibGUsIC4uLmFjdGlvbnM6IHN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIGlhbS5HcmFudC5hZGRUb1ByaW5jaXBhbE9yUmVzb3VyY2Uoe1xuICAgICAgZ3JhbnRlZSxcbiAgICAgIGFjdGlvbnMsXG4gICAgICAvLyBBIExvZ0dyb3VwIEFSTiBvdXQgb2YgQ2xvdWRGb3JtYXRpb24gYWxyZWFkeSBpbmNsdWRlcyBhICc6KicgYXQgdGhlIGVuZCB0byBpbmNsdWRlIHRoZSBsb2cgc3RyZWFtcyB1bmRlciB0aGUgZ3JvdXAuXG4gICAgICAvLyBTZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWxvZ3MtbG9nZ3JvdXAuaHRtbCN3MmFiMWMyMWMxMGM2M2M0M2MxMVxuICAgICAgcmVzb3VyY2VBcm5zOiBbdGhpcy5sb2dHcm91cEFybl0sXG4gICAgICByZXNvdXJjZTogdGhpcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWMgbWV0aG9kIHRvIGdldCB0aGUgcGh5c2ljYWwgbmFtZSBvZiB0aGlzIGxvZyBncm91cFxuICAgKiBAcmV0dXJucyBQaHlzaWNhbCBuYW1lIG9mIGxvZyBncm91cFxuICAgKi9cbiAgcHVibGljIGxvZ0dyb3VwUGh5c2ljYWxOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucGh5c2ljYWxOYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBzdGF0ZW1lbnQgdG8gdGhlIHJlc291cmNlIHBvbGljeSBhc3NvY2lhdGVkIHdpdGggdGhpcyBsb2cgZ3JvdXAuXG4gICAqIEEgcmVzb3VyY2UgcG9saWN5IHdpbGwgYmUgYXV0b21hdGljYWxseSBjcmVhdGVkIHVwb24gdGhlIGZpcnN0IGNhbGwgdG8gYGFkZFRvUmVzb3VyY2VQb2xpY3lgLlxuICAgKlxuICAgKiBBbnkgQVJOIFByaW5jaXBhbHMgaW5zaWRlIG9mIHRoZSBzdGF0ZW1lbnQgd2lsbCBiZSBjb252ZXJ0ZWQgaW50byBBV1MgQWNjb3VudCBJRCBzdHJpbmdzXG4gICAqIGJlY2F1c2UgQ2xvdWRXYXRjaCBMb2dzIFJlc291cmNlIFBvbGljaWVzIGRvIG5vdCBhY2NlcHQgQVJOIHByaW5jaXBhbHMuXG4gICAqXG4gICAqIEBwYXJhbSBzdGF0ZW1lbnQgVGhlIHBvbGljeSBzdGF0ZW1lbnQgdG8gYWRkXG4gICAqL1xuICBwdWJsaWMgYWRkVG9SZXNvdXJjZVBvbGljeShzdGF0ZW1lbnQ6IGlhbS5Qb2xpY3lTdGF0ZW1lbnQpOiBpYW0uQWRkVG9SZXNvdXJjZVBvbGljeVJlc3VsdCB7XG4gICAgaWYgKCF0aGlzLnBvbGljeSkge1xuICAgICAgdGhpcy5wb2xpY3kgPSBuZXcgUmVzb3VyY2VQb2xpY3kodGhpcywgJ1BvbGljeScpO1xuICAgIH1cbiAgICB0aGlzLnBvbGljeS5kb2N1bWVudC5hZGRTdGF0ZW1lbnRzKHN0YXRlbWVudC5jb3B5KHtcbiAgICAgIHByaW5jaXBhbHM6IHN0YXRlbWVudC5wcmluY2lwYWxzLm1hcChwID0+IHRoaXMuY29udmVydEFyblByaW5jcGFsVG9BY2NvdW50SWQocCkpLFxuICAgIH0pKTtcbiAgICByZXR1cm4geyBzdGF0ZW1lbnRBZGRlZDogdHJ1ZSwgcG9saWN5RGVwZW5kYWJsZTogdGhpcy5wb2xpY3kgfTtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydEFyblByaW5jcGFsVG9BY2NvdW50SWQocHJpbmNpcGFsOiBpYW0uSVByaW5jaXBhbCkge1xuICAgIGlmIChwcmluY2lwYWwucHJpbmNpcGFsQWNjb3VudCkge1xuICAgICAgLy8gd2UgdXNlIEFyblByaW5jaXBhbCBoZXJlIGJlY2F1c2UgdGhlIGNvbnN0cnVjdG9yIGluc2VydHMgdGhlIGFyZ3VtZW50XG4gICAgICAvLyBpbnRvIHRoZSB0ZW1wbGF0ZSB3aXRob3V0IG11dGF0aW5nIGl0LCB3aGljaCBtZWFucyB0aGF0IHRoZXJlIGlzIG5vXG4gICAgICAvLyBBUk4gY3JlYXRlZCBieSB0aGlzIGNhbGwuXG4gICAgICByZXR1cm4gbmV3IGlhbS5Bcm5QcmluY2lwYWwocHJpbmNpcGFsLnByaW5jaXBhbEFjY291bnQpO1xuICAgIH1cblxuICAgIGlmIChwcmluY2lwYWwgaW5zdGFuY2VvZiBpYW0uQXJuUHJpbmNpcGFsKSB7XG4gICAgICBjb25zdCBwYXJzZWRBcm4gPSBBcm4uc3BsaXQocHJpbmNpcGFsLmFybiwgQXJuRm9ybWF0LlNMQVNIX1JFU09VUkNFX05BTUUpO1xuICAgICAgaWYgKHBhcnNlZEFybi5hY2NvdW50KSB7XG4gICAgICAgIHJldHVybiBuZXcgaWFtLkFyblByaW5jaXBhbChwYXJzZWRBcm4uYWNjb3VudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHByaW5jaXBhbDtcbiAgfVxufVxuXG4vKipcbiAqIEhvdyBsb25nLCBpbiBkYXlzLCB0aGUgbG9nIGNvbnRlbnRzIHdpbGwgYmUgcmV0YWluZWQuXG4gKi9cbmV4cG9ydCBlbnVtIFJldGVudGlvbkRheXMge1xuICAvKipcbiAgICogMSBkYXlcbiAgICovXG4gIE9ORV9EQVkgPSAxLFxuXG4gIC8qKlxuICAgKiAzIGRheXNcbiAgICovXG4gIFRIUkVFX0RBWVMgPSAzLFxuXG4gIC8qKlxuICAgKiA1IGRheXNcbiAgICovXG4gIEZJVkVfREFZUyA9IDUsXG5cbiAgLyoqXG4gICAqIDEgd2Vla1xuICAgKi9cbiAgT05FX1dFRUsgPSA3LFxuXG4gIC8qKlxuICAgKiAyIHdlZWtzXG4gICAqL1xuICBUV09fV0VFS1MgPSAxNCxcblxuICAvKipcbiAgICogMSBtb250aFxuICAgKi9cbiAgT05FX01PTlRIID0gMzAsXG5cbiAgLyoqXG4gICAqIDIgbW9udGhzXG4gICAqL1xuICBUV09fTU9OVEhTID0gNjAsXG5cbiAgLyoqXG4gICAqIDMgbW9udGhzXG4gICAqL1xuICBUSFJFRV9NT05USFMgPSA5MCxcblxuICAvKipcbiAgICogNCBtb250aHNcbiAgICovXG4gIEZPVVJfTU9OVEhTID0gMTIwLFxuXG4gIC8qKlxuICAgKiA1IG1vbnRoc1xuICAgKi9cbiAgRklWRV9NT05USFMgPSAxNTAsXG5cbiAgLyoqXG4gICAqIDYgbW9udGhzXG4gICAqL1xuICBTSVhfTU9OVEhTID0gMTgwLFxuXG4gIC8qKlxuICAgKiAxIHllYXJcbiAgICovXG4gIE9ORV9ZRUFSID0gMzY1LFxuXG4gIC8qKlxuICAgKiAxMyBtb250aHNcbiAgICovXG4gIFRISVJURUVOX01PTlRIUyA9IDQwMCxcblxuICAvKipcbiAgICogMTggbW9udGhzXG4gICAqL1xuICBFSUdIVEVFTl9NT05USFMgPSA1NDUsXG5cbiAgLyoqXG4gICAqIDIgeWVhcnNcbiAgICovXG4gIFRXT19ZRUFSUyA9IDczMSxcblxuICAvKipcbiAgICogNSB5ZWFyc1xuICAgKi9cbiAgRklWRV9ZRUFSUyA9IDE4MjcsXG5cbiAgLyoqXG4gICAqIDYgeWVhcnNcbiAgICovXG4gIFNJWF9ZRUFSUyA9IDIxOTIsXG5cbiAgLyoqXG4gICAqIDcgeWVhcnNcbiAgICovXG4gIFNFVkVOX1lFQVJTID0gMjU1NyxcblxuICAvKipcbiAgICogOCB5ZWFyc1xuICAgKi9cbiAgRUlHSFRfWUVBUlMgPSAyOTIyLFxuXG4gIC8qKlxuICAgKiA5IHllYXJzXG4gICAqL1xuICBOSU5FX1lFQVJTID0gMzI4OCxcblxuICAvKipcbiAgICogMTAgeWVhcnNcbiAgICovXG4gIFRFTl9ZRUFSUyA9IDM2NTMsXG5cbiAgLyoqXG4gICAqIFJldGFpbiBsb2dzIGZvcmV2ZXJcbiAgICovXG4gIElORklOSVRFID0gOTk5OSxcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBhIExvZ0dyb3VwXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTG9nR3JvdXBQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgS01TIEtleSB0byBlbmNyeXB0IHRoZSBsb2cgZ3JvdXAgd2l0aC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBsb2cgZ3JvdXAgaXMgZW5jcnlwdGVkIHdpdGggdGhlIGRlZmF1bHQgbWFzdGVyIGtleVxuICAgKi9cbiAgcmVhZG9ubHkgZW5jcnlwdGlvbktleT86IGttcy5JS2V5O1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBsb2cgZ3JvdXAuXG4gICAqXG4gICAqIEBkZWZhdWx0IEF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkXG4gICAqL1xuICByZWFkb25seSBsb2dHcm91cE5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEhvdyBsb25nLCBpbiBkYXlzLCB0aGUgbG9nIGNvbnRlbnRzIHdpbGwgYmUgcmV0YWluZWQuXG4gICAqXG4gICAqIFRvIHJldGFpbiBhbGwgbG9ncywgc2V0IHRoaXMgdmFsdWUgdG8gUmV0ZW50aW9uRGF5cy5JTkZJTklURS5cbiAgICpcbiAgICogQGRlZmF1bHQgUmV0ZW50aW9uRGF5cy5UV09fWUVBUlNcbiAgICovXG4gIHJlYWRvbmx5IHJldGVudGlvbj86IFJldGVudGlvbkRheXM7XG5cbiAgLyoqXG4gICAqIERldGVybWluZSB0aGUgcmVtb3ZhbCBwb2xpY3kgb2YgdGhpcyBsb2cgZ3JvdXAuXG4gICAqXG4gICAqIE5vcm1hbGx5IHlvdSB3YW50IHRvIHJldGFpbiB0aGUgbG9nIGdyb3VwIHNvIHlvdSBjYW4gZGlhZ25vc2UgaXNzdWVzXG4gICAqIGZyb20gbG9ncyBldmVuIGFmdGVyIGEgZGVwbG95bWVudCB0aGF0IG5vIGxvbmdlciBpbmNsdWRlcyB0aGUgbG9nIGdyb3VwLlxuICAgKiBJbiB0aGF0IGNhc2UsIHVzZSB0aGUgbm9ybWFsIGRhdGUtYmFzZWQgcmV0ZW50aW9uIHBvbGljeSB0byBhZ2Ugb3V0IHlvdXJcbiAgICogbG9ncy5cbiAgICpcbiAgICogQGRlZmF1bHQgUmVtb3ZhbFBvbGljeS5SZXRhaW5cbiAgICovXG4gIHJlYWRvbmx5IHJlbW92YWxQb2xpY3k/OiBSZW1vdmFsUG9saWN5O1xufVxuXG4vKipcbiAqIERlZmluZSBhIENsb3VkV2F0Y2ggTG9nIEdyb3VwXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2dHcm91cCBleHRlbmRzIExvZ0dyb3VwQmFzZSB7XG4gIC8qKlxuICAgKiBJbXBvcnQgYW4gZXhpc3RpbmcgTG9nR3JvdXAgZ2l2ZW4gaXRzIEFSTlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tTG9nR3JvdXBBcm4oc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgbG9nR3JvdXBBcm46IHN0cmluZyk6IElMb2dHcm91cCB7XG4gICAgY29uc3QgYmFzZUxvZ0dyb3VwQXJuID0gbG9nR3JvdXBBcm4ucmVwbGFjZSgvOlxcKiQvLCAnJyk7XG5cbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBMb2dHcm91cEJhc2Uge1xuICAgICAgcHVibGljIHJlYWRvbmx5IGxvZ0dyb3VwQXJuID0gYCR7YmFzZUxvZ0dyb3VwQXJufToqYDtcbiAgICAgIHB1YmxpYyByZWFkb25seSBsb2dHcm91cE5hbWUgPSBTdGFjay5vZihzY29wZSkuc3BsaXRBcm4oYmFzZUxvZ0dyb3VwQXJuLCBBcm5Gb3JtYXQuQ09MT05fUkVTT1VSQ0VfTkFNRSkucmVzb3VyY2VOYW1lITtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEltcG9ydChzY29wZSwgaWQsIHtcbiAgICAgIGVudmlyb25tZW50RnJvbUFybjogYmFzZUxvZ0dyb3VwQXJuLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9ydCBhbiBleGlzdGluZyBMb2dHcm91cCBnaXZlbiBpdHMgbmFtZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tTG9nR3JvdXBOYW1lKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIGxvZ0dyb3VwTmFtZTogc3RyaW5nKTogSUxvZ0dyb3VwIHtcbiAgICBjb25zdCBiYXNlTG9nR3JvdXBOYW1lID0gbG9nR3JvdXBOYW1lLnJlcGxhY2UoLzpcXCokLywgJycpO1xuXG4gICAgY2xhc3MgSW1wb3J0IGV4dGVuZHMgTG9nR3JvdXBCYXNlIHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBsb2dHcm91cE5hbWUgPSBiYXNlTG9nR3JvdXBOYW1lO1xuICAgICAgcHVibGljIHJlYWRvbmx5IGxvZ0dyb3VwQXJuID0gU3RhY2sub2Yoc2NvcGUpLmZvcm1hdEFybih7XG4gICAgICAgIHNlcnZpY2U6ICdsb2dzJyxcbiAgICAgICAgcmVzb3VyY2U6ICdsb2ctZ3JvdXAnLFxuICAgICAgICBhcm5Gb3JtYXQ6IEFybkZvcm1hdC5DT0xPTl9SRVNPVVJDRV9OQU1FLFxuICAgICAgICByZXNvdXJjZU5hbWU6IGJhc2VMb2dHcm91cE5hbWUgKyAnOionLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoaXMgbG9nIGdyb3VwXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbG9nR3JvdXBBcm46IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhpcyBsb2cgZ3JvdXBcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBsb2dHcm91cE5hbWU6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTG9nR3JvdXBQcm9wcyA9IHt9KSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBwaHlzaWNhbE5hbWU6IHByb3BzLmxvZ0dyb3VwTmFtZSxcbiAgICB9KTtcblxuICAgIGxldCByZXRlbnRpb25JbkRheXMgPSBwcm9wcy5yZXRlbnRpb247XG4gICAgaWYgKHJldGVudGlvbkluRGF5cyA9PT0gdW5kZWZpbmVkKSB7IHJldGVudGlvbkluRGF5cyA9IFJldGVudGlvbkRheXMuVFdPX1lFQVJTOyB9XG4gICAgaWYgKHJldGVudGlvbkluRGF5cyA9PT0gSW5maW5pdHkgfHwgcmV0ZW50aW9uSW5EYXlzID09PSBSZXRlbnRpb25EYXlzLklORklOSVRFKSB7IHJldGVudGlvbkluRGF5cyA9IHVuZGVmaW5lZDsgfVxuXG4gICAgaWYgKHJldGVudGlvbkluRGF5cyAhPT0gdW5kZWZpbmVkICYmICFUb2tlbi5pc1VucmVzb2x2ZWQocmV0ZW50aW9uSW5EYXlzKSAmJiByZXRlbnRpb25JbkRheXMgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXRlbnRpb25JbkRheXMgbXVzdCBiZSBwb3NpdGl2ZSwgZ290ICR7cmV0ZW50aW9uSW5EYXlzfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc291cmNlID0gbmV3IENmbkxvZ0dyb3VwKHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIGttc0tleUlkOiBwcm9wcy5lbmNyeXB0aW9uS2V5Py5rZXlBcm4sXG4gICAgICBsb2dHcm91cE5hbWU6IHRoaXMucGh5c2ljYWxOYW1lLFxuICAgICAgcmV0ZW50aW9uSW5EYXlzLFxuICAgIH0pO1xuXG4gICAgcmVzb3VyY2UuYXBwbHlSZW1vdmFsUG9saWN5KHByb3BzLnJlbW92YWxQb2xpY3kpO1xuXG4gICAgdGhpcy5sb2dHcm91cEFybiA9IHRoaXMuZ2V0UmVzb3VyY2VBcm5BdHRyaWJ1dGUocmVzb3VyY2UuYXR0ckFybiwge1xuICAgICAgc2VydmljZTogJ2xvZ3MnLFxuICAgICAgcmVzb3VyY2U6ICdsb2ctZ3JvdXAnLFxuICAgICAgcmVzb3VyY2VOYW1lOiB0aGlzLnBoeXNpY2FsTmFtZSxcbiAgICAgIGFybkZvcm1hdDogQXJuRm9ybWF0LkNPTE9OX1JFU09VUkNFX05BTUUsXG4gICAgfSk7XG4gICAgdGhpcy5sb2dHcm91cE5hbWUgPSB0aGlzLmdldFJlc291cmNlTmFtZUF0dHJpYnV0ZShyZXNvdXJjZS5yZWYpO1xuICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgYSBuZXcgTG9nU3RyZWFtIGNyZWF0ZWQgZnJvbSBhIExvZ0dyb3VwXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgbG9nIHN0cmVhbSB0byBjcmVhdGUuXG4gICAqXG4gICAqIFRoZSBuYW1lIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgbG9nIGdyb3VwLlxuICAgKlxuICAgKiBAZGVmYXVsdCBBdXRvbWF0aWNhbGx5IGdlbmVyYXRlZFxuICAgKi9cbiAgcmVhZG9ubHkgbG9nU3RyZWFtTmFtZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBhIG5ldyBTdWJzY3JpcHRpb25GaWx0ZXIgY3JlYXRlZCBmcm9tIGEgTG9nR3JvdXBcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdWJzY3JpcHRpb25GaWx0ZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBkZXN0aW5hdGlvbiB0byBzZW5kIHRoZSBmaWx0ZXJlZCBldmVudHMgdG8uXG4gICAqXG4gICAqIEZvciBleGFtcGxlLCBhIEtpbmVzaXMgc3RyZWFtIG9yIGEgTGFtYmRhIGZ1bmN0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVzdGluYXRpb246IElMb2dTdWJzY3JpcHRpb25EZXN0aW5hdGlvbjtcblxuICAvKipcbiAgICogTG9nIGV2ZW50cyBtYXRjaGluZyB0aGlzIHBhdHRlcm4gd2lsbCBiZSBzZW50IHRvIHRoZSBkZXN0aW5hdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IGZpbHRlclBhdHRlcm46IElGaWx0ZXJQYXR0ZXJuO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGEgTWV0cmljRmlsdGVyIGNyZWF0ZWQgZnJvbSBhIExvZ0dyb3VwXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0cmljRmlsdGVyT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBQYXR0ZXJuIHRvIHNlYXJjaCBmb3IgbG9nIGV2ZW50cy5cbiAgICovXG4gIHJlYWRvbmx5IGZpbHRlclBhdHRlcm46IElGaWx0ZXJQYXR0ZXJuO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZXNwYWNlIG9mIHRoZSBtZXRyaWMgdG8gZW1pdC5cbiAgICovXG4gIHJlYWRvbmx5IG1ldHJpY05hbWVzcGFjZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgbWV0cmljIHRvIGVtaXQuXG4gICAqL1xuICByZWFkb25seSBtZXRyaWNOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSB0byBlbWl0IGZvciB0aGUgbWV0cmljLlxuICAgKlxuICAgKiBDYW4gZWl0aGVyIGJlIGEgbGl0ZXJhbCBudW1iZXIgKHR5cGljYWxseSBcIjFcIiksIG9yIHRoZSBuYW1lIG9mIGEgZmllbGQgaW4gdGhlIHN0cnVjdHVyZVxuICAgKiB0byB0YWtlIHRoZSB2YWx1ZSBmcm9tIHRoZSBtYXRjaGVkIGV2ZW50LiBJZiB5b3UgYXJlIHVzaW5nIGEgZmllbGQgdmFsdWUsIHRoZSBmaWVsZFxuICAgKiB2YWx1ZSBtdXN0IGhhdmUgYmVlbiBtYXRjaGVkIHVzaW5nIHRoZSBwYXR0ZXJuLlxuICAgKlxuICAgKiBJZiB5b3Ugd2FudCB0byBzcGVjaWZ5IGEgZmllbGQgZnJvbSBhIG1hdGNoZWQgSlNPTiBzdHJ1Y3R1cmUsIHVzZSAnJC5maWVsZE5hbWUnLFxuICAgKiBhbmQgbWFrZSBzdXJlIHRoZSBmaWVsZCBpcyBpbiB0aGUgcGF0dGVybiAoaWYgb25seSBhcyAnJC5maWVsZE5hbWUgPSAqJykuXG4gICAqXG4gICAqIElmIHlvdSB3YW50IHRvIHNwZWNpZnkgYSBmaWVsZCBmcm9tIGEgbWF0Y2hlZCBzcGFjZS1kZWxpbWl0ZWQgc3RydWN0dXJlLFxuICAgKiB1c2UgJyRmaWVsZE5hbWUnLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIjFcIlxuICAgKi9cbiAgcmVhZG9ubHkgbWV0cmljVmFsdWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSB0byBlbWl0IGlmIHRoZSBwYXR0ZXJuIGRvZXMgbm90IG1hdGNoIGEgcGFydGljdWxhciBldmVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgTm8gbWV0cmljIGVtaXR0ZWQuXG4gICAqL1xuICByZWFkb25seSBkZWZhdWx0VmFsdWU/OiBudW1iZXI7XG59XG4iXX0=