@pwrdrvr/microapps-cdk
Version:
MicroApps framework, by PwrDrvr LLC, delivered as an AWS CDK construct that provides the DynamoDB, Router service, Deploy service, API Gateway, and CloudFront distribution.
199 lines • 34.3 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MicroAppsCF = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path_1 = require("path");
const cf = require("aws-cdk-lib/aws-cloudfront");
const cforigins = require("aws-cdk-lib/aws-cloudfront-origins");
const r53 = require("aws-cdk-lib/aws-route53");
const r53targets = require("aws-cdk-lib/aws-route53-targets");
const constructs_1 = require("constructs");
const ReverseDomain_1 = require("./utils/ReverseDomain");
/**
* Create a new MicroApps CloudFront Distribution.
*/
class MicroAppsCF extends constructs_1.Construct {
/**
* Create or get the origin request policy
*
* If a custom domain name is NOT used for the origin then a policy
* will be created.
*
* If a custom domain name IS used for the origin then the ALL_VIEWER
* policy will be returned. This policy passes the Host header to the
* origin, which is fine when using a custom domain name on the origin.
*
* @param _scope
* @param _props
*/
static createAPIOriginPolicy(_scope, _props) {
// const { assetNameRoot, assetNameSuffix, domainNameEdge } = props;
// let apigwyOriginRequestPolicy: cf.IOriginRequestPolicy = cf.OriginRequestPolicy.ALL_VIEWER;
// if (domainNameEdge === undefined) {
// // When not using a custom domain name we must limit down the origin policy to
// // prevent it from passing the Host header (distribution_id.cloudfront.net) to
// // apigwy which will then reject it with a 403 because it does not match the
// // execute-api name that apigwy is expecting.
// //
// // 2021-12-28 - There is a bug in the name generation that causes the same asset
// // in different stacks to have the same generated name. We have to make the id
// // in all cases to ensure the generated name is unique.
// apigwyOriginRequestPolicy = new cf.OriginRequestPolicy(
// scope,
// `apigwy-origin-policy-${Stack.of(scope).stackName}`,
// {
// comment: assetNameRoot ? `${assetNameRoot}-apigwy${assetNameSuffix}` : undefined,
// originRequestPolicyName: assetNameRoot
// ? `${assetNameRoot}-apigwy${assetNameSuffix}`
// : undefined,
// cookieBehavior: cf.OriginRequestCookieBehavior.all(),
// queryStringBehavior: cf.OriginRequestQueryStringBehavior.all(),
// // TODO: If signing is enabled this should forward all signature headers
// // TODO: If set to "cfront.OriginRequestHeaderBehavior.all()" then
// // `replaceHostHeader` must be set to true to prevent API Gateway from rejecting
// // the request
// // headerBehavior: cf.OriginRequestHeaderBehavior.allowList('user-agent', 'referer'),
// headerBehavior: cf.OriginRequestHeaderBehavior.all(),
// },
// );
// }
return cf.OriginRequestPolicy.ALL_VIEWER;
}
/**
* Add API Gateway and S3 routes to an existing CloudFront Distribution
* @param _scope
* @param props
*/
static addRoutes(_scope, props) {
const { appOnlyOrigin, bucketOriginFallbackToApp, distro, appOriginRequestPolicy, rootPathPrefix = '', } = props;
//
// Add Behaviors
//
const s3BehaviorOptions = {
allowedMethods: cf.AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
cachePolicy: cf.CachePolicy.CACHING_OPTIMIZED,
compress: true,
originRequestPolicy: cf.OriginRequestPolicy.ALL_VIEWER,
viewerProtocolPolicy: cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
edgeLambdas: props.edgeLambdas,
};
const s3FallbackToAppOptions = {
allowedMethods: cf.AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
// TODO: Caching needs to be set by the app response
cachePolicy: cf.CachePolicy.CACHING_DISABLED,
compress: true,
originRequestPolicy: appOriginRequestPolicy,
viewerProtocolPolicy: cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
edgeLambdas: props.edgeLambdas,
};
const appOnlyBehaviorOptions = {
allowedMethods: cf.AllowedMethods.ALLOW_ALL,
// TODO: Caching needs to be set by the app response
cachePolicy: cf.CachePolicy.CACHING_DISABLED,
compress: true,
originRequestPolicy: appOriginRequestPolicy,
viewerProtocolPolicy: cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
edgeLambdas: props.edgeLambdas,
};
//
// Handle designated static assets
// Falls back to the app on 403/404
//
distro.addBehavior(path_1.posix.join(rootPathPrefix, '*/static/*.*'),
// TODO: 2023-03-04 - This could be the bucket origin without fallback, at least as an option
// which would allow skipping the OriginRequest (which has invoke cost and throughtput limits).
// This would be a distinct config from the `*/*.*` route below, which always has to have
// the OriginRequest function.
bucketOriginFallbackToApp, s3BehaviorOptions);
distro.addBehavior(path_1.posix.join(rootPathPrefix, '*/*.*'), bucketOriginFallbackToApp, s3FallbackToAppOptions);
//
// Default to sending everything else to the app only
// This is necessary because we allow all methods for the app but that is not
// allowed for an OriginGroup
//
distro.addBehavior(path_1.posix.join(rootPathPrefix, '/*'), appOnlyOrigin, appOnlyBehaviorOptions);
}
get cloudFrontDistro() {
return this._cloudFrontDistro;
}
constructor(scope, id, props) {
super(scope, id);
if (props === undefined) {
throw new Error('props must be set');
}
if ((props.r53Zone === undefined && props.domainNameEdge !== undefined) ||
(props.r53Zone !== undefined && props.domainNameEdge === undefined)) {
throw new Error('If either of r53Zone or domainNameEdge are set then the other must be set');
}
const { domainNameEdge, removalPolicy, certEdge, assetNameRoot, assetNameSuffix, r53Zone, bucketLogs, bucketAppsOriginS3, bucketAppsOriginApp, rootPathPrefix, edgeLambdas, } = props;
const appOriginRequestPolicy = MicroAppsCF.createAPIOriginPolicy(this, {
assetNameRoot,
assetNameSuffix,
domainNameEdge,
});
//
// Create fallback to S3 origin group
//
const appOrigin = bucketAppsOriginApp ?? bucketAppsOriginS3;
const bucketOriginFallbackToApp = new cforigins.OriginGroup({
primaryOrigin: bucketAppsOriginS3,
fallbackOrigin: appOrigin,
fallbackStatusCodes: [403, 404],
});
//
// CloudFront Distro
//
this._cloudFrontDistro = new cf.Distribution(this, 'cft', {
comment: assetNameRoot ? `${assetNameRoot}${assetNameSuffix}` : domainNameEdge,
domainNames: domainNameEdge !== undefined ? [domainNameEdge] : undefined,
certificate: certEdge,
httpVersion: cf.HttpVersion.HTTP2,
defaultBehavior: {
allowedMethods: cf.AllowedMethods.ALLOW_ALL,
cachePolicy: cf.CachePolicy.CACHING_DISABLED,
compress: true,
originRequestPolicy: appOriginRequestPolicy,
origin: appOrigin,
viewerProtocolPolicy: cf.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
edgeLambdas,
},
enableIpv6: true,
priceClass: cf.PriceClass.PRICE_CLASS_100,
logBucket: bucketLogs,
logFilePrefix: props.domainNameEdge
? `${(0, ReverseDomain_1.reverseDomain)(props.domainNameEdge)}/cloudfront-raw/`
: undefined,
});
if (removalPolicy !== undefined) {
this._cloudFrontDistro.applyRemovalPolicy(removalPolicy);
}
// Add routes to the CloudFront Distribution
MicroAppsCF.addRoutes(scope, {
appOnlyOrigin: appOrigin,
bucketOriginFallbackToApp,
distro: this._cloudFrontDistro,
appOriginRequestPolicy,
rootPathPrefix,
edgeLambdas,
});
//
// Create the edge name for the CloudFront distro
//
if (r53Zone !== undefined) {
const rrAppsEdge = new r53.RecordSet(this, 'edge-arecord', {
recordName: domainNameEdge,
recordType: r53.RecordType.A,
target: r53.RecordTarget.fromAlias(new r53targets.CloudFrontTarget(this._cloudFrontDistro)),
zone: r53Zone,
});
if (removalPolicy !== undefined) {
rrAppsEdge.applyRemovalPolicy(removalPolicy);
}
}
}
}
exports.MicroAppsCF = MicroAppsCF;
_a = JSII_RTTI_SYMBOL_1;
MicroAppsCF[_a] = { fqn: "@pwrdrvr/microapps-cdk.MicroAppsCF", version: "1.1.2" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWljcm9BcHBzQ0YuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvTWljcm9BcHBzQ0YudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwrQkFBMEM7QUFHMUMsaURBQWlEO0FBQ2pELGdFQUFnRTtBQUNoRSwrQ0FBK0M7QUFDL0MsOERBQThEO0FBRTlELDJDQUF1QztBQUN2Qyx5REFBc0Q7QUErTXREOztHQUVHO0FBQ0gsTUFBYSxXQUFZLFNBQVEsc0JBQVM7SUFDeEM7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ksTUFBTSxDQUFDLHFCQUFxQixDQUNqQyxNQUFpQixFQUNqQixNQUFvQztRQUVwQyxvRUFBb0U7UUFFcEUsOEZBQThGO1FBQzlGLHNDQUFzQztRQUN0QyxtRkFBbUY7UUFDbkYsbUZBQW1GO1FBQ25GLGlGQUFpRjtRQUNqRixrREFBa0Q7UUFDbEQsT0FBTztRQUNQLHFGQUFxRjtRQUNyRixvRkFBb0Y7UUFDcEYsNERBQTREO1FBQzVELDREQUE0RDtRQUM1RCxhQUFhO1FBQ2IsMkRBQTJEO1FBQzNELFFBQVE7UUFDUiwwRkFBMEY7UUFFMUYsK0NBQStDO1FBQy9DLHdEQUF3RDtRQUN4RCx1QkFBdUI7UUFDdkIsOERBQThEO1FBQzlELHdFQUF3RTtRQUN4RSxpRkFBaUY7UUFDakYsMkVBQTJFO1FBQzNFLHlGQUF5RjtRQUN6Rix1QkFBdUI7UUFDdkIsOEZBQThGO1FBQzlGLDhEQUE4RDtRQUM5RCxTQUFTO1FBQ1QsT0FBTztRQUNQLElBQUk7UUFFSixPQUFPLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxVQUFVLENBQUM7SUFDM0MsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQWlCLEVBQUUsS0FBdUI7UUFDaEUsTUFBTSxFQUNKLGFBQWEsRUFDYix5QkFBeUIsRUFDekIsTUFBTSxFQUNOLHNCQUFzQixFQUN0QixjQUFjLEdBQUcsRUFBRSxHQUNwQixHQUFHLEtBQUssQ0FBQztRQUVWLEVB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QUNoQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDL0MsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDOztBQW5PSCxrQ0FvT0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBwb3NpeCBhcyBwb3NpeFBhdGggfSBmcm9tICdwYXRoJztcbmltcG9ydCB7IFJlbW92YWxQb2xpY3kgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBhY20gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNlcnRpZmljYXRlbWFuYWdlcic7XG5pbXBvcnQgKiBhcyBjZiBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udCc7XG5pbXBvcnQgKiBhcyBjZm9yaWdpbnMgZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnQtb3JpZ2lucyc7XG5pbXBvcnQgKiBhcyByNTMgZnJvbSAnYXdzLWNkay1saWIvYXdzLXJvdXRlNTMnO1xuaW1wb3J0ICogYXMgcjUzdGFyZ2V0cyBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtcm91dGU1My10YXJnZXRzJztcbmltcG9ydCAqIGFzIHMzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IHJldmVyc2VEb21haW4gfSBmcm9tICcuL3V0aWxzL1JldmVyc2VEb21haW4nO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBNaWNyb0FwcHMgQ2xvdWRGcm9udFxuICovXG5leHBvcnQgaW50ZXJmYWNlIElNaWNyb0FwcHNDRiB7XG4gIC8qKlxuICAgKiBUaGUgQ2xvdWRGcm9udCBkaXN0cmlidXRpb25cbiAgICovXG4gIHJlYWRvbmx5IGNsb3VkRnJvbnREaXN0cm86IGNmLkRpc3RyaWJ1dGlvbjtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIHRvIGluaXRpYWxpemUgYW4gaW5zdGFuY2Ugb2YgYE1pY3JvQXBwc0NGYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNaWNyb0FwcHNDRlByb3BzIHtcbiAgLyoqXG4gICAqIFJlbW92YWxQb2xpY3kgb3ZlcnJpZGUgZm9yIGNoaWxkIHJlc291cmNlc1xuICAgKlxuICAgKiBOb3RlOiBpZiBzZXQgdG8gREVTVFJPWSB0aGUgUzMgYnVja2VzIHdpbGwgaGF2ZSBgYXV0b0RlbGV0ZU9iamVjdHNgIHNldCB0byBgdHJ1ZWBcbiAgICpcbiAgICogQGRlZmF1bHQgLSBwZXIgcmVzb3VyY2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgcmVtb3ZhbFBvbGljeT86IFJlbW92YWxQb2xpY3k7XG5cbiAgLyoqXG4gICAqIFMzIGJ1Y2tldCBvcmlnaW4gZm9yIGRlcGxveWVkIGFwcGxpY2F0aW9uc1xuICAgKiBNYXJrZWQgd2l0aCBgeC1taWNyb2FwcHMtb3JpZ2luOiBzM2BcbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldEFwcHNPcmlnaW5TMzogY2ZvcmlnaW5zLlMzT3JpZ2luO1xuXG4gIC8qKlxuICAgKiBTMyBidWNrZXQgb3JpZ2luIGZvciBkZXBsb3llZCBhcHBsaWNhdGlvbnNcbiAgICogTWFya2VkIHdpdGggYHgtbWljcm9hcHBzLW9yaWdpbjogYXBwYFxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0QXBwc09yaWdpbkFwcDogY2ZvcmlnaW5zLlMzT3JpZ2luO1xuXG4gIC8qKlxuICAgKiBTMyBidWNrZXQgZm9yIENsb3VkRnJvbnQgbG9nc1xuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0TG9ncz86IHMzLklCdWNrZXQ7XG5cbiAgLyoqXG4gICAqIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uIGRvbWFpbiBuYW1lXG4gICAqXG4gICAqIEBleGFtcGxlIGFwcHMucHdyZHJ2ci5jb21cbiAgICogQGRlZmF1bHQgYXV0by1hc3NpZ25lZFxuICAgKi9cbiAgcmVhZG9ubHkgZG9tYWluTmFtZUVkZ2U/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFQSSBHYXRld2F5IGN1c3RvbSBvcmlnaW4gZG9tYWluIG5hbWVcbiAgICpcbiAgICogQGV4YW1wbGUgYXBwcy5wd3JkcnZyLmNvbVxuICAgKiBAZGVmYXVsdCAtIHJldHJpZXZlZCBmcm9tIGh0dHBBcGksIGlmIHBvc3NpYmxlXG4gICAqL1xuICByZWFkb25seSBkb21haW5OYW1lT3JpZ2luPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBhc3NldCBuYW1lIHJvb3RcbiAgICpcbiAgICogQGV4YW1wbGUgbWljcm9hcHBzXG4gICAqIEBkZWZhdWx0IC0gcmVzb3VyY2UgbmFtZXMgYXV0byBhc3NpZ25lZFxuICAgKi9cbiAgcmVhZG9ubHkgYXNzZXROYW1lUm9vdD86IHN0cmluZztcblxuICAvKipcbiAgICogT3B0aW9uYWwgYXNzZXQgbmFtZSBzdWZmaXhcbiAgICpcbiAgICogQGV4YW1wbGUgLWRldi1wci0xMlxuICAgKiBAZGVmYXVsdCBub25lXG4gICAqL1xuICByZWFkb25seSBhc3NldE5hbWVTdWZmaXg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFDTSBDZXJ0aWZpY2F0ZSB0aGF0IGNvdmVycyBgZG9tYWluTmFtZUVkZ2VgIG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IGNlcnRFZGdlPzogYWNtLklDZXJ0aWZpY2F0ZTtcblxuICAvKipcbiAgICogUm91dGU1MyB6b25lIGluIHdoaWNoIHRvIGNyZWF0ZSBvcHRpb25hbCBgZG9tYWluTmFtZUVkZ2VgIHJlY29yZFxuICAgKi9cbiAgcmVhZG9ubHkgcjUzWm9uZT86IHI1My5JSG9zdGVkWm9uZTtcblxuICAvKipcbiAgICogUGF0aCBwcmVmaXggb24gdGhlIHJvb3Qgb2YgdGhlIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlIGRldi9cbiAgICovXG4gIHJlYWRvbmx5IHJvb3RQYXRoUHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW4gZXh0cmEgQmVoYXZpb3IgKFJvdXRlKSBmb3IgL2FwaS8gdGhhdCBhbGxvd3NcbiAgICogQVBJIHJvdXRlcyB0byBoYXZlIGEgcGVyaW9kIGluIHRoZW0uXG4gICAqXG4gICAqIFdoZW4gZmFsc2UgQVBJIHJvdXRlcyB3aXRoIGEgcGVyaW9kIGluIHRoZSBwYXRoIHdpbGwgZ2V0IHJvdXRlZCB0byBTMy5cbiAgICpcbiAgICogV2hlbiB0cnVlIEFQSSByb3V0ZXMgdGhhdCBjb250YWluIC9hcGkvIGluIHRoZSBwYXRoIHdpbGwgZ2V0IHJvdXRlZCB0byBBUEkgR2F0ZXdheVxuICAgKiBldmVuIGlmIHRoZXkgaGF2ZSBhIHBlcmlvZCBpbiB0aGUgcGF0aC5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZSBpZiBodHRwQXBpIGlzIHByb3ZpZGVkXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVBUElQYXRoUm91dGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW4gZXh0cmEgQmVoYXZpb3IgKFJvdXRlKSBmb3IgL19uZXh0L2RhdGEvXG4gICAqIFRoaXMgcm91dGUgaXMgdXNlZCBieSBOZXh0LmpzIHRvIGxvYWQgZGF0YSBmcm9tIHRoZSBBUEkgR2F0ZXdheVxuICAgKiBvbiBgZ2V0U2VydmVyU2lkZVByb3BzYCBjYWxscy4gIFRoZSByZXF1ZXN0cyBjYW4gZW5kIGluIGAuanNvbmAsXG4gICAqIHdoaWNoIHdvdWxkIGNhdXNlIHRoZW0gdG8gYmUgcm91dGVkIHRvIFMzIGlmIHRoaXMgcm91dGUgaXMgbm90IGNyZWF0ZWQuXG4gICAqXG4gICAqIFdoZW4gZmFsc2UgQVBJIHJvdXRlcyB3aXRoIGEgcGVyaW9kIGluIHRoZSBwYXRoIHdpbGwgZ2V0IHJvdXRlZCB0byBTMy5cbiAgICpcbiAgICogV2hlbiB0cnVlIEFQSSByb3V0ZXMgdGhhdCBjb250YWluIC9fbmV4dC9kYXRhLyBpbiB0aGUgcGF0aCB3aWxsIGdldCByb3V0ZWQgdG8gQVBJIEdhdGV3YXlcbiAgICogZXZlbiBpZiB0aGV5IGhhdmUgYSBwZXJpb2QgaW4gdGhlIHBhdGguXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWUgaWYgaHR0cEFwaSBpcyBwcm92aWRlZFxuICAgKi9cbiAgcmVhZG9ubHkgY3JlYXRlTmV4dERhdGFQYXRoUm91dGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDb25maWd1cmF0aW9uIG9mIHRoZSBlZGdlIHRvIG9yaWdpbiBsYW1iZGEgZnVuY3Rpb25zXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gZWRnZSB0byBBUEkgR2F0ZXdheSBvcmlnaW4gZnVuY3Rpb25zIGFkZGVkXG4gICAqL1xuICByZWFkb25seSBlZGdlTGFtYmRhcz86IGNmLkVkZ2VMYW1iZGFbXTtcblxuICAvKipcbiAgICogT3B0aW9uYWwgT3JpZ2luIFNoaWVsZCBSZWdpb25cbiAgICpcbiAgICogVGhpcyBzaG91bGQgYmUgdGhlIHJlZ2lvbiB3aGVyZSB0aGUgRHluYW1vREIgaXMgbG9jYXRlZCBzbyB0aGVcbiAgICogRWRnZVRvT3JpZ2luIGNhbGxzIGhhdmUgdGhlIGxvd2VzdCBsYXRlbmN5ICh+MSBtcykuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgb3JpZ2luU2hpZWxkUmVnaW9uPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSBgQ3JlYXRlQVBJT3JpZ2luUG9saWN5YFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUFQSU9yaWdpblBvbGljeU9wdGlvbnMge1xuICAvKipcbiAgICogT3B0aW9uYWwgYXNzZXQgbmFtZSByb290XG4gICAqXG4gICAqIEBleGFtcGxlIG1pY3JvYXBwc1xuICAgKiBAZGVmYXVsdCAtIHJlc291cmNlIG5hbWVzIGF1dG8gYXNzaWduZWRcbiAgICovXG4gIHJlYWRvbmx5IGFzc2V0TmFtZVJvb3Q/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIGFzc2V0IG5hbWUgc3VmZml4XG4gICAqXG4gICAqIEBleGFtcGxlIC1kZXYtcHItMTJcbiAgICogQGRlZmF1bHQgbm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgYXNzZXROYW1lU3VmZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFZGdlIGRvbWFpbiBuYW1lIHVzZWQgYnkgQ2xvdWRGcm9udCAtIElmIHNldCBhIGN1c3RvbVxuICAgKiBPcmlnaW5SZXF1ZXN0UG9saWN5IHdpbGwgYmUgY3JlYXRlZCB0aGF0IHByZXZlbnRzXG4gICAqIHRoZSBIb3N0IGhlYWRlciBmcm9tIGJlaW5nIHBhc3NlZCB0byB0aGUgb3JpZ2luLlxuICAgKi9cbiAgcmVhZG9ubHkgZG9tYWluTmFtZUVkZ2U/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYEFkZFJvdXRlc2BcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBZGRSb3V0ZXNPcHRpb25zIHtcbiAgLyoqXG4gICAqIEFwcGxpY2F0aW9uIG9yaWdpblxuICAgKlxuICAgKiBUeXBpY2FsbHkgYW4gUzMgYnVja2V0IHdpdGggYSBgeC1taWNyb2FwcHMtb3JpZ2luOiBhcHBgIGN1c3RvbSBoZWFkZXJcbiAgICpcbiAgICogVGhlIHJlcXVlc3QgbmV2ZXIgYWN0dWFsbHkgZmFsbHMgdGhyb3VnaCB0byB0aGUgUzMgYnVja2V0LlxuICAgKi9cbiAgcmVhZG9ubHkgYXBwT25seU9yaWdpbjogY2YuSU9yaWdpbjtcblxuICAvKipcbiAgICogT3JpZ2luIEdyb3VwIHdpdGggUHJpbWFyeSBvZiBTMyBidWNrZXQgd2l0aCBgeC1taWNyb2FwcHMtb3JpZ2luOiBzM2AgY3VzdG9tIGhlYWRlclxuICAgKiBhbmQgRmFsbGJhY2sgb2YgYGFwcE9ubHlPcmlnaW5gXG4gICAqL1xuICByZWFkb25seSBidWNrZXRPcmlnaW5GYWxsYmFja1RvQXBwOiBjZm9yaWdpbnMuT3JpZ2luR3JvdXA7XG5cbiAgLyoqXG4gICAqIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uIHRvIGFkZCB0aGUgQmVoYXZpb3JzIChSb3V0ZXMpIHRvXG4gICAqL1xuICByZWFkb25seSBkaXN0cm86IGNmLkRpc3RyaWJ1dGlvbjtcblxuICAvKipcbiAgICogT3JpZ2luIFJlcXVlc3QgcG9saWN5IGZvciBBUEkgR2F0ZXdheSBPcmlnaW5cbiAgICovXG4gIHJlYWRvbmx5IGFwcE9yaWdpblJlcXVlc3RQb2xpY3k6IGNmLklPcmlnaW5SZXF1ZXN0UG9saWN5O1xuXG4gIC8qKlxuICAgKiBQYXRoIHByZWZpeCBvbiB0aGUgcm9vdCBvZiB0aGUgQ2xvdWRGcm9udCBkaXN0cmlidXRpb25cbiAgICpcbiAgICogQGV4YW1wbGUgZGV2L1xuICAgKi9cbiAgcmVhZG9ubHkgcm9vdFBhdGhQcmVmaXg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEVkZ2UgbGFtYmRhcyB0byBhc3NvY2lhdGUgd2l0aCB0aGUgQVBJIEdhdGV3YXkgcm91dGVzXG4gICAqL1xuICByZWFkb25seSBlZGdlTGFtYmRhcz86IGNmLkVkZ2VMYW1iZGFbXTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgTWljcm9BcHBzIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgTWljcm9BcHBzQ0YgZXh0ZW5kcyBDb25zdHJ1Y3QgaW1wbGVtZW50cyBJTWljcm9BcHBzQ0Yge1xuICAvKipcbiAgICogQ3JlYXRlIG9yIGdldCB0aGUgb3JpZ2luIHJlcXVlc3QgcG9saWN5XG4gICAqXG4gICAqIElmIGEgY3VzdG9tIGRvbWFpbiBuYW1lIGlzIE5PVCB1c2VkIGZvciB0aGUgb3JpZ2luIHRoZW4gYSBwb2xpY3lcbiAgICogd2lsbCBiZSBjcmVhdGVkLlxuICAgKlxuICAgKiBJZiBhIGN1c3RvbSBkb21haW4gbmFtZSBJUyB1c2VkIGZvciB0aGUgb3JpZ2luIHRoZW4gdGhlIEFMTF9WSUVXRVJcbiAgICogcG9saWN5IHdpbGwgYmUgcmV0dXJuZWQuICBUaGlzIHBvbGljeSBwYXNzZXMgdGhlIEhvc3QgaGVhZGVyIHRvIHRoZVxuICAgKiBvcmlnaW4sIHdoaWNoIGlzIGZpbmUgd2hlbiB1c2luZyBhIGN1c3RvbSBkb21haW4gbmFtZSBvbiB0aGUgb3JpZ2luLlxuICAgKlxuICAgKiBAcGFyYW0gX3Njb3BlXG4gICAqIEBwYXJhbSBfcHJvcHNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY3JlYXRlQVBJT3JpZ2luUG9saWN5KFxuICAgIF9zY29wZTogQ29uc3RydWN0LFxuICAgIF9wcm9wczogQ3JlYXRlQVBJT3JpZ2luUG9saWN5T3B0aW9ucyxcbiAgKTogY2YuSU9yaWdpblJlcXVlc3RQb2xpY3kge1xuICAgIC8vIGNvbnN0IHsgYXNzZXROYW1lUm9vdCwgYXNzZXROYW1lU3VmZml4LCBkb21haW5OYW1lRWRnZSB9ID0gcHJvcHM7XG5cbiAgICAvLyBsZXQgYXBpZ3d5T3JpZ2luUmVxdWVzdFBvbGljeTogY2YuSU9yaWdpblJlcXVlc3RQb2xpY3kgPSBjZi5PcmlnaW5SZXF1ZXN0UG9saWN5LkFMTF9WSUVXRVI7XG4gICAgLy8gaWYgKGRvbWFpbk5hbWVFZGdlID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyAgIC8vIFdoZW4gbm90IHVzaW5nIGEgY3VzdG9tIGRvbWFpbiBuYW1lIHdlIG11c3QgbGltaXQgZG93biB0aGUgb3JpZ2luIHBvbGljeSB0b1xuICAgIC8vICAgLy8gcHJldmVudCBpdCBmcm9tIHBhc3NpbmcgdGhlIEhvc3QgaGVhZGVyIChkaXN0cmlidXRpb25faWQuY2xvdWRmcm9udC5uZXQpIHRvXG4gICAgLy8gICAvLyBhcGlnd3kgd2hpY2ggd2lsbCB0aGVuIHJlamVjdCBpdCB3aXRoIGEgNDAzIGJlY2F1c2UgaXQgZG9lcyBub3QgbWF0Y2ggdGhlXG4gICAgLy8gICAvLyBleGVjdXRlLWFwaSBuYW1lIHRoYXQgYXBpZ3d5IGlzIGV4cGVjdGluZy5cbiAgICAvLyAgIC8vXG4gICAgLy8gICAvLyAyMDIxLTEyLTI4IC0gVGhlcmUgaXMgYSBidWcgaW4gdGhlIG5hbWUgZ2VuZXJhdGlvbiB0aGF0IGNhdXNlcyB0aGUgc2FtZSBhc3NldFxuICAgIC8vICAgLy8gaW4gZGlmZmVyZW50IHN0YWNrcyB0byBoYXZlIHRoZSBzYW1lIGdlbmVyYXRlZCBuYW1lLiAgV2UgaGF2ZSB0byBtYWtlIHRoZSBpZFxuICAgIC8vICAgLy8gaW4gYWxsIGNhc2VzIHRvIGVuc3VyZSB0aGUgZ2VuZXJhdGVkIG5hbWUgaXMgdW5pcXVlLlxuICAgIC8vICAgYXBpZ3d5T3JpZ2luUmVxdWVzdFBvbGljeSA9IG5ldyBjZi5PcmlnaW5SZXF1ZXN0UG9saWN5KFxuICAgIC8vICAgICBzY29wZSxcbiAgICAvLyAgICAgYGFwaWd3eS1vcmlnaW4tcG9saWN5LSR7U3RhY2sub2Yoc2NvcGUpLnN0YWNrTmFtZX1gLFxuICAgIC8vICAgICB7XG4gICAgLy8gICAgICAgY29tbWVudDogYXNzZXROYW1lUm9vdCA/IGAke2Fzc2V0TmFtZVJvb3R9LWFwaWd3eSR7YXNzZXROYW1lU3VmZml4fWAgOiB1bmRlZmluZWQsXG5cbiAgICAvLyAgICAgICBvcmlnaW5SZXF1ZXN0UG9saWN5TmFtZTogYXNzZXROYW1lUm9vdFxuICAgIC8vICAgICAgICAgPyBgJHthc3NldE5hbWVSb290fS1hcGlnd3kke2Fzc2V0TmFtZVN1ZmZpeH1gXG4gICAgLy8gICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAvLyAgICAgICBjb29raWVCZWhhdmlvcjogY2YuT3JpZ2luUmVxdWVzdENvb2tpZUJlaGF2aW9yLmFsbCgpLFxuICAgIC8vICAgICAgIHF1ZXJ5U3RyaW5nQmVoYXZpb3I6IGNmLk9yaWdpblJlcXVlc3RRdWVyeVN0cmluZ0JlaGF2aW9yLmFsbCgpLFxuICAgIC8vICAgICAgIC8vIFRPRE86IElmIHNpZ25pbmcgaXMgZW5hYmxlZCB0aGlzIHNob3VsZCBmb3J3YXJkIGFsbCBzaWduYXR1cmUgaGVhZGVyc1xuICAgIC8vICAgICAgIC8vIFRPRE86IElmIHNldCB0byBcImNmcm9udC5PcmlnaW5SZXF1ZXN0SGVhZGVyQmVoYXZpb3IuYWxsKClcIiB0aGVuXG4gICAgLy8gICAgICAgLy8gYHJlcGxhY2VIb3N0SGVhZGVyYCBtdXN0IGJlIHNldCB0byB0cnVlIHRvIHByZXZlbnQgQVBJIEdhdGV3YXkgZnJvbSByZWplY3RpbmdcbiAgICAvLyAgICAgICAvLyB0aGUgcmVxdWVzdFxuICAgIC8vICAgICAgIC8vIGhlYWRlckJlaGF2aW9yOiBjZi5PcmlnaW5SZXF1ZXN0SGVhZGVyQmVoYXZpb3IuYWxsb3dMaXN0KCd1c2VyLWFnZW50JywgJ3JlZmVyZXInKSxcbiAgICAvLyAgICAgICBoZWFkZXJCZWhhdmlvcjogY2YuT3JpZ2luUmVxdWVzdEhlYWRlckJlaGF2aW9yLmFsbCgpLFxuICAgIC8vICAgICB9LFxuICAgIC8vICAgKTtcbiAgICAvLyB9XG5cbiAgICByZXR1cm4gY2YuT3JpZ2luUmVxdWVzdFBvbGljeS5BTExfVklFV0VSO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBBUEkgR2F0ZXdheSBhbmQgUzMgcm91dGVzIHRvIGFuIGV4aXN0aW5nIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uXG4gICAqIEBwYXJhbSBfc2NvcGVcbiAgICogQHBhcmFtIHByb3BzXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFkZFJvdXRlcyhfc2NvcGU6IENvbnN0cnVjdCwgcHJvcHM6IEFkZFJvdXRlc09wdGlvbnMpIHtcbiAgICBjb25zdCB7XG4gICAgICBhcHBPbmx5T3JpZ2luLFxuICAgICAgYnVja2V0T3JpZ2luRmFsbGJhY2tUb0FwcCxcbiAgICAgIGRpc3RybyxcbiAgICAgIGFwcE9yaWdpblJlcXVlc3RQb2xpY3ksXG4gICAgICByb290UGF0aFByZWZpeCA9ICcnLFxuICAgIH0gPSBwcm9wcztcblxuICAgIC8vXG4gICAgLy8gQWRkIEJlaGF2aW9yc1xuICAgIC8vXG4gICAgY29uc3QgczNCZWhhdmlvck9wdGlvbnM6IGNmLkFkZEJlaGF2aW9yT3B0aW9ucyA9IHtcbiAgICAgIGFsbG93ZWRNZXRob2RzOiBjZi5BbGxvd2VkTWV0aG9kcy5BTExPV19HRVRfSEVBRF9PUFRJT05TLFxuICAgICAgY2FjaGVQb2xpY3k6IGNmLkNhY2hlUG9saWN5LkNBQ0hJTkdfT1BUSU1JWkVELFxuICAgICAgY29tcHJlc3M6IHRydWUsXG4gICAgICBvcmlnaW5SZXF1ZXN0UG9saWN5OiBjZi5PcmlnaW5SZXF1ZXN0UG9saWN5LkFMTF9WSUVXRVIsXG4gICAgICB2aWV3ZXJQcm90b2NvbFBvbGljeTogY2YuVmlld2VyUHJvdG9jb2xQb2xpY3kuUkVESVJFQ1RfVE9fSFRUUFMsXG4gICAgICBlZGdlTGFtYmRhczogcHJvcHMuZWRnZUxhbWJkYXMsXG4gICAgfTtcbiAgICBjb25zdCBzM0ZhbGxiYWNrVG9BcHBPcHRpb25zOiBjZi5BZGRCZWhhdmlvck9wdGlvbnMgPSB7XG4gICAgICBhbGxvd2VkTWV0aG9kczogY2YuQWxsb3dlZE1ldGhvZHMuQUxMT1dfR0VUX0hFQURfT1BUSU9OUyxcbiAgICAgIC8vIFRPRE86IENhY2hpbmcgbmVlZHMgdG8gYmUgc2V0IGJ5IHRoZSBhcHAgcmVzcG9uc2VcbiAgICAgIGNhY2hlUG9saWN5OiBjZi5DYWNoZVBvbGljeS5DQUNISU5HX0RJU0FCTEVELFxuICAgICAgY29tcHJlc3M6IHRydWUsXG4gICAgICBvcmlnaW5SZXF1ZXN0UG9saWN5OiBhcHBPcmlnaW5SZXF1ZXN0UG9saWN5LFxuICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IGNmLlZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgICAgZWRnZUxhbWJkYXM6IHByb3BzLmVkZ2VMYW1iZGFzLFxuICAgIH07XG4gICAgY29uc3QgYXBwT25seUJlaGF2aW9yT3B0aW9uczogY2YuQWRkQmVoYXZpb3JPcHRpb25zID0ge1xuICAgICAgYWxsb3dlZE1ldGhvZHM6IGNmLkFsbG93ZWRNZXRob2RzLkFMTE9XX0FMTCxcbiAgICAgIC8vIFRPRE86IENhY2hpbmcgbmVlZHMgdG8gYmUgc2V0IGJ5IHRoZSBhcHAgcmVzcG9uc2VcbiAgICAgIGNhY2hlUG9saWN5OiBjZi5DYWNoZVBvbGljeS5DQUNISU5HX0RJU0FCTEVELFxuICAgICAgY29tcHJlc3M6IHRydWUsXG4gICAgICBvcmlnaW5SZXF1ZXN0UG9saWN5OiBhcHBPcmlnaW5SZXF1ZXN0UG9saWN5LFxuICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IGNmLlZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgICAgZWRnZUxhbWJkYXM6IHByb3BzLmVkZ2VMYW1iZGFzLFxuICAgIH07XG5cbiAgICAvL1xuICAgIC8vIEhhbmRsZSBkZXNpZ25hdGVkIHN0YXRpYyBhc3NldHNcbiAgICAvLyBGYWxscyBiYWNrIHRvIHRoZSBhcHAgb24gNDAzLzQwNFxuICAgIC8vXG4gICAgZGlzdHJvLmFkZEJlaGF2aW9yKFxuICAgICAgcG9zaXhQYXRoLmpvaW4ocm9vdFBhdGhQcmVmaXgsICcqL3N0YXRpYy8qLionKSxcbiAgICAgIC8vIFRPRE86IDIwMjMtMDMtMDQgLSBUaGlzIGNvdWxkIGJlIHRoZSBidWNrZXQgb3JpZ2luIHdpdGhvdXQgZmFsbGJhY2ssIGF0IGxlYXN0IGFzIGFuIG9wdGlvblxuICAgICAgLy8gd2hpY2ggd291bGQgYWxsb3cgc2tpcHBpbmcgdGhlIE9yaWdpblJlcXVlc3QgKHdoaWNoIGhhcyBpbnZva2UgY29zdCBhbmQgdGhyb3VnaHRwdXQgbGltaXRzKS5cbiAgICAgIC8vIFRoaXMgd291bGQgYmUgYSBkaXN0aW5jdCBjb25maWcgZnJvbSB0aGUgYCovKi4qYCByb3V0ZSBiZWxvdywgd2hpY2ggYWx3YXlzIGhhcyB0byBoYXZlXG4gICAgICAvLyB0aGUgT3JpZ2luUmVxdWVzdCBmdW5jdGlvbi5cbiAgICAgIGJ1Y2tldE9yaWdpbkZhbGxiYWNrVG9BcHAsXG4gICAgICBzM0JlaGF2aW9yT3B0aW9ucyxcbiAgICApO1xuICAgIGRpc3Ryby5hZGRCZWhhdmlvcihcbiAgICAgIHBvc2l4UGF0aC5qb2luKHJvb3RQYXRoUHJlZml4LCAnKi8qLionKSxcbiAgICAgIGJ1Y2tldE9yaWdpbkZhbGxiYWNrVG9BcHAsXG4gICAgICBzM0ZhbGxiYWNrVG9BcHBPcHRpb25zLFxuICAgICk7XG5cbiAgICAvL1xuICAgIC8vIERlZmF1bHQgdG8gc2VuZGluZyBldmVyeXRoaW5nIGVsc2UgdG8gdGhlIGFwcCBvbmx5XG4gICAgLy8gVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSB3ZSBhbGxvdyBhbGwgbWV0aG9kcyBmb3IgdGhlIGFwcCBidXQgdGhhdCBpcyBub3RcbiAgICAvLyBhbGxvd2VkIGZvciBhbiBPcmlnaW5Hcm91cFxuICAgIC8vXG4gICAgZGlzdHJvLmFkZEJlaGF2aW9yKHBvc2l4UGF0aC5qb2luKHJvb3RQYXRoUHJlZml4LCAnLyonKSwgYXBwT25seU9yaWdpbiwgYXBwT25seUJlaGF2aW9yT3B0aW9ucyk7XG4gIH1cblxuICBwcml2YXRlIF9jbG91ZEZyb250RGlzdHJvOiBjZi5EaXN0cmlidXRpb247XG4gIHB1YmxpYyBnZXQgY2xvdWRGcm9udERpc3RybygpOiBjZi5EaXN0cmlidXRpb24ge1xuICAgIHJldHVybiB0aGlzLl9jbG91ZEZyb250RGlzdHJvO1xuICB9XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE1pY3JvQXBwc0NGUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgaWYgKHByb3BzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncHJvcHMgbXVzdCBiZSBzZXQnKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAocHJvcHMucjUzWm9uZSA9PT0gdW5kZWZpbmVkICYmIHByb3BzLmRvbWFpbk5hbWVFZGdlICE9PSB1bmRlZmluZWQpIHx8XG4gICAgICAocHJvcHMucjUzWm9uZSAhPT0gdW5kZWZpbmVkICYmIHByb3BzLmRvbWFpbk5hbWVFZGdlID09PSB1bmRlZmluZWQpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lmIGVpdGhlciBvZiByNTNab25lIG9yIGRvbWFpbk5hbWVFZGdlIGFyZSBzZXQgdGhlbiB0aGUgb3RoZXIgbXVzdCBiZSBzZXQnKTtcbiAgICB9XG5cbiAgICBjb25zdCB7XG4gICAgICBkb21haW5OYW1lRWRnZSxcbiAgICAgIHJlbW92YWxQb2xpY3ksXG4gICAgICBjZXJ0RWRnZSxcbiAgICAgIGFzc2V0TmFtZVJvb3QsXG4gICAgICBhc3NldE5hbWVTdWZmaXgsXG4gICAgICByNTNab25lLFxuICAgICAgYnVja2V0TG9ncyxcbiAgICAgIGJ1Y2tldEFwcHNPcmlnaW5TMyxcbiAgICAgIGJ1Y2tldEFwcHNPcmlnaW5BcHAsXG4gICAgICByb290UGF0aFByZWZpeCxcbiAgICAgIGVkZ2VMYW1iZGFzLFxuICAgIH0gPSBwcm9wcztcblxuICAgIGNvbnN0IGFwcE9yaWdpblJlcXVlc3RQb2xpY3kgPSBNaWNyb0FwcHNDRi5jcmVhdGVBUElPcmlnaW5Qb2xpY3kodGhpcywge1xuICAgICAgYXNzZXROYW1lUm9vdCxcbiAgICAgIGFzc2V0TmFtZVN1ZmZpeCxcbiAgICAgIGRvbWFpbk5hbWVFZGdlLFxuICAgIH0pO1xuXG4gICAgLy9cbiAgICAvLyBDcmVhdGUgZmFsbGJhY2sgdG8gUzMgb3JpZ2luIGdyb3VwXG4gICAgLy9cbiAgICBjb25zdCBhcHBPcmlnaW4gPSBidWNrZXRBcHBzT3JpZ2luQXBwID8/IGJ1Y2tldEFwcHNPcmlnaW5TMztcbiAgICBjb25zdCBidWNrZXRPcmlnaW5GYWxsYmFja1RvQXBwID0gbmV3IGNmb3JpZ2lucy5PcmlnaW5Hcm91cCh7XG4gICAgICBwcmltYXJ5T3JpZ2luOiBidWNrZXRBcHBzT3JpZ2luUzMsXG4gICAgICBmYWxsYmFja09yaWdpbjogYXBwT3JpZ2luLFxuICAgICAgZmFsbGJhY2tTdGF0dXNDb2RlczogWzQwMywgNDA0XSxcbiAgICB9KTtcblxuICAgIC8vXG4gICAgLy8gQ2xvdWRGcm9udCBEaXN0cm9cbiAgICAvL1xuICAgIHRoaXMuX2Nsb3VkRnJvbnREaXN0cm8gPSBuZXcgY2YuRGlzdHJpYnV0aW9uKHRoaXMsICdjZnQnLCB7XG4gICAgICBjb21tZW50OiBhc3NldE5hbWVSb290ID8gYCR7YXNzZXROYW1lUm9vdH0ke2Fzc2V0TmFtZVN1ZmZpeH1gIDogZG9tYWluTmFtZUVkZ2UsXG4gICAgICBkb21haW5OYW1lczogZG9tYWluTmFtZUVkZ2UgIT09IHVuZGVmaW5lZCA/IFtkb21haW5OYW1lRWRnZV0gOiB1bmRlZmluZWQsXG4gICAgICBjZXJ0aWZpY2F0ZTogY2VydEVkZ2UsXG4gICAgICBodHRwVmVyc2lvbjogY2YuSHR0cFZlcnNpb24uSFRUUDIsXG4gICAgICBkZWZhdWx0QmVoYXZpb3I6IHtcbiAgICAgICAgYWxsb3dlZE1ldGhvZHM6IGNmLkFsbG93ZWRNZXRob2RzLkFMTE9XX0FMTCxcbiAgICAgICAgY2FjaGVQb2xpY3k6IGNmLkNhY2hlUG9saWN5LkNBQ0hJTkdfRElTQUJMRUQsXG4gICAgICAgIGNvbXByZXNzOiB0cnVlLFxuICAgICAgICBvcmlnaW5SZXF1ZXN0UG9saWN5OiBhcHBPcmlnaW5SZXF1ZXN0UG9saWN5LFxuICAgICAgICBvcmlnaW46IGFwcE9yaWdpbixcbiAgICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IGNmLlZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgICAgICBlZGdlTGFtYmRhcyxcbiAgICAgIH0sXG4gICAgICBlbmFibGVJcHY2OiB0cnVlLFxuICAgICAgcHJpY2VDbGFzczogY2YuUHJpY2VDbGFzcy5QUklDRV9DTEFTU18xMDAsXG4gICAgICBsb2dCdWNrZXQ6IGJ1Y2tldExvZ3MsXG4gICAgICBsb2dGaWxlUHJlZml4OiBwcm9wcy5kb21haW5OYW1lRWRnZVxuICAgICAgICA/IGAke3JldmVyc2VEb21haW4ocHJvcHMuZG9tYWluTmFtZUVkZ2UpfS9jbG91ZGZyb250LXJhdy9gXG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgIH0pO1xuICAgIGlmIChyZW1vdmFsUG9saWN5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuX2Nsb3VkRnJvbnREaXN0cm8uYXBwbHlSZW1vdmFsUG9saWN5KHJlbW92YWxQb2xpY3kpO1xuICAgIH1cblxuICAgIC8vIEFkZCByb3V0ZXMgdG8gdGhlIENsb3VkRnJvbnQgRGlzdHJpYnV0aW9uXG4gICAgTWljcm9BcHBzQ0YuYWRkUm91dGVzKHNjb3BlLCB7XG4gICAgICBhcHBPbmx5T3JpZ2luOiBhcHBPcmlnaW4sXG4gICAgICBidWNrZXRPcmlnaW5GYWxsYmFja1RvQXBwLFxuICAgICAgZGlzdHJvOiB0aGlzLl9jbG91ZEZyb250RGlzdHJvLFxuICAgICAgYXBwT3JpZ2luUmVxdWVzdFBvbGljeSxcbiAgICAgIHJvb3RQYXRoUHJlZml4LFxuICAgICAgZWRnZUxhbWJkYXMsXG4gICAgfSk7XG5cbiAgICAvL1xuICAgIC8vIENyZWF0ZSB0aGUgZWRnZSBuYW1lIGZvciB0aGUgQ2xvdWRGcm9udCBkaXN0cm9cbiAgICAvL1xuXG4gICAgaWYgKHI1M1pvbmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgcnJBcHBzRWRnZSA9IG5ldyByNTMuUmVjb3JkU2V0KHRoaXMsICdlZGdlLWFyZWNvcmQnLCB7XG4gICAgICAgIHJlY29yZE5hbWU6IGRvbWFpbk5hbWVFZGdlLFxuICAgICAgICByZWNvcmRUeXBlOiByNTMuUmVjb3JkVHlwZS5BLFxuICAgICAgICB0YXJnZXQ6IHI1My5SZWNvcmRUYXJnZXQuZnJvbUFsaWFzKG5ldyByNTN0YXJnZXRzLkNsb3VkRnJvbnRUYXJnZXQodGhpcy5fY2xvdWRGcm9udERpc3RybykpLFxuICAgICAgICB6b25lOiByNTNab25lLFxuICAgICAgfSk7XG4gICAgICBpZiAocmVtb3ZhbFBvbGljeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJyQXBwc0VkZ2UuYXBwbHlSZW1vdmFsUG9saWN5KHJlbW92YWxQb2xpY3kpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19