UNPKG

@aws-cdk/aws-apigateway

Version:

The CDK Construct Library for AWS::ApiGateway

231 lines 37.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.AuthorizationType = exports.Method = void 0; const jsiiDeprecationWarnings = require("../.warnings.jsii.js"); const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const core_1 = require("@aws-cdk/core"); const apigateway_generated_1 = require("./apigateway.generated"); const authorizer_1 = require("./authorizer"); const mock_1 = require("./integrations/mock"); const restapi_1 = require("./restapi"); const util_1 = require("./util"); class Method extends core_1.Resource { constructor(scope, id, props) { super(scope, id); try { jsiiDeprecationWarnings._aws_cdk_aws_apigateway_MethodProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, Method); } throw error; } this.resource = props.resource; this.api = props.resource.api; this.httpMethod = props.httpMethod.toUpperCase(); util_1.validateHttpMethod(this.httpMethod); const options = props.options || {}; const defaultMethodOptions = props.resource.defaultMethodOptions || {}; const authorizer = options.authorizer || defaultMethodOptions.authorizer; const authorizerId = authorizer?.authorizerId; const authorizationTypeOption = options.authorizationType || defaultMethodOptions.authorizationType; const authorizationType = authorizer?.authorizationType || authorizationTypeOption || AuthorizationType.NONE; // if the authorizer defines an authorization type and we also have an explicit option set, check that they are the same if (authorizer?.authorizationType && authorizationTypeOption && authorizer?.authorizationType !== authorizationTypeOption) { throw new Error(`${this.resource}/${this.httpMethod} - Authorization type is set to ${authorizationTypeOption} ` + `which is different from what is required by the authorizer [${authorizer.authorizationType}]`); } if (authorizer_1.Authorizer.isAuthorizer(authorizer)) { authorizer._attachToApi(this.api); } this.methodResponses = options.methodResponses ?? []; const integration = props.integration ?? this.resource.defaultIntegration ?? new mock_1.MockIntegration(); const bindResult = integration.bind(this); const methodProps = { resourceId: props.resource.resourceId, restApiId: this.api.restApiId, httpMethod: this.httpMethod, operationName: options.operationName || defaultMethodOptions.operationName, apiKeyRequired: options.apiKeyRequired || defaultMethodOptions.apiKeyRequired, authorizationType, authorizerId, requestParameters: options.requestParameters || defaultMethodOptions.requestParameters, integration: this.renderIntegration(bindResult), methodResponses: core_1.Lazy.any({ produce: () => this.renderMethodResponses(this.methodResponses) }, { omitEmptyArray: true }), requestModels: this.renderRequestModels(options.requestModels), requestValidatorId: this.requestValidatorId(options), authorizationScopes: options.authorizationScopes ?? defaultMethodOptions.authorizationScopes, }; const resource = new apigateway_generated_1.CfnMethod(this, 'Resource', methodProps); this.methodId = resource.ref; if (restapi_1.RestApiBase._isRestApiBase(props.resource.api)) { props.resource.api._attachMethod(this); } const deployment = props.resource.api.latestDeployment; if (deployment) { deployment.node.addDependency(resource); deployment.addToLogicalId({ method: { ...methodProps, integrationToken: bindResult?.deploymentToken, }, }); } } /** * The RestApi associated with this Method * @deprecated - Throws an error if this Resource is not associated with an instance of `RestApi`. Use `api` instead. */ get restApi() { try { jsiiDeprecationWarnings.print("@aws-cdk/aws-apigateway.Method#restApi", "- Throws an error if this Resource is not associated with an instance of `RestApi`. Use `api` instead."); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, jsiiDeprecationWarnings.getPropertyDescriptor(this, "restApi").get); } throw error; } return this.resource.restApi; } /** * Returns an execute-api ARN for this method: * * arn:aws:execute-api:{region}:{account}:{restApiId}/{stage}/{method}/{path} * * NOTE: {stage} will refer to the `restApi.deploymentStage`, which will * automatically set if auto-deploy is enabled, or can be explicitly assigned. * When not configured, {stage} will be set to '*', as a shorthand for 'all stages'. * * @attribute */ get methodArn() { const stage = this.api.deploymentStage?.stageName; return this.api.arnForExecuteApi(this.httpMethod, pathForArn(this.resource.path), stage); } /** * Returns an execute-api ARN for this method's "test-invoke-stage" stage. * This stage is used by the AWS Console UI when testing the method. */ get testMethodArn() { return this.api.arnForExecuteApi(this.httpMethod, pathForArn(this.resource.path), 'test-invoke-stage'); } /** * Add a method response to this method */ addMethodResponse(methodResponse) { try { jsiiDeprecationWarnings._aws_cdk_aws_apigateway_MethodResponse(methodResponse); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.addMethodResponse); } throw error; } this.methodResponses.push(methodResponse); } renderIntegration(bindResult) { const options = bindResult.options ?? {}; let credentials; if (options.credentialsRole) { credentials = options.credentialsRole.roleArn; } else if (options.credentialsPassthrough) { // arn:aws:iam::*:user/* // eslint-disable-next-line max-len credentials = core_1.Stack.of(this).formatArn({ service: 'iam', region: '', account: '*', resource: 'user', arnFormat: core_1.ArnFormat.SLASH_RESOURCE_NAME, resourceName: '*' }); } return { type: bindResult.type, uri: bindResult.uri, cacheKeyParameters: options.cacheKeyParameters, cacheNamespace: options.cacheNamespace, contentHandling: options.contentHandling, integrationHttpMethod: bindResult.integrationHttpMethod, requestParameters: options.requestParameters, requestTemplates: options.requestTemplates, passthroughBehavior: options.passthroughBehavior, integrationResponses: options.integrationResponses, connectionType: options.connectionType, connectionId: options.vpcLink ? options.vpcLink.vpcLinkId : undefined, credentials, timeoutInMillis: options.timeout?.toMilliseconds(), }; } renderMethodResponses(methodResponses) { if (!methodResponses) { // Fall back to nothing return undefined; } return methodResponses.map(mr => { let responseModels; if (mr.responseModels) { responseModels = {}; for (const contentType in mr.responseModels) { if (mr.responseModels.hasOwnProperty(contentType)) { responseModels[contentType] = mr.responseModels[contentType].modelId; } } } const methodResponseProp = { statusCode: mr.statusCode, responseParameters: mr.responseParameters, responseModels, }; return methodResponseProp; }); } renderRequestModels(requestModels) { if (!requestModels) { // Fall back to nothing return undefined; } const models = {}; for (const contentType in requestModels) { if (requestModels.hasOwnProperty(contentType)) { models[contentType] = requestModels[contentType].modelId; } } return models; } requestValidatorId(options) { if (options.requestValidator && options.requestValidatorOptions) { throw new Error('Only one of \'requestValidator\' or \'requestValidatorOptions\' must be specified.'); } if (options.requestValidatorOptions) { const validator = this.api.addRequestValidator('validator', options.requestValidatorOptions); return validator.requestValidatorId; } // For backward compatibility return options.requestValidator?.requestValidatorId; } } exports.Method = Method; _a = JSII_RTTI_SYMBOL_1; Method[_a] = { fqn: "@aws-cdk/aws-apigateway.Method", version: "1.204.0" }; var AuthorizationType; (function (AuthorizationType) { /** * Open access. */ AuthorizationType["NONE"] = "NONE"; /** * Use AWS IAM permissions. */ AuthorizationType["IAM"] = "AWS_IAM"; /** * Use a custom authorizer. */ AuthorizationType["CUSTOM"] = "CUSTOM"; /** * Use an AWS Cognito user pool. */ AuthorizationType["COGNITO"] = "COGNITO_USER_POOLS"; })(AuthorizationType = exports.AuthorizationType || (exports.AuthorizationType = {})); function pathForArn(path) { return path.replace(/\{[^\}]*\}/g, '*'); // replace path parameters (like '{bookId}') with asterisk } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0aG9kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibWV0aG9kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHdDQUFpRTtBQUVqRSxpRUFBbUU7QUFDbkUsNkNBQXVEO0FBRXZELDhDQUFzRDtBQUt0RCx1Q0FBMkQ7QUFDM0QsaUNBQTRDO0FBb0o1QyxNQUFhLE1BQU8sU0FBUSxlQUFRO0lBYWxDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBa0I7UUFDMUQsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQzs7Ozs7OytDQWRSLE1BQU07Ozs7UUFnQmYsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO1FBQy9CLElBQUksQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7UUFDOUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRWpELHlCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUVwQyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUVwQyxNQUFNLG9CQUFvQixHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsb0JBQW9CLElBQUksRUFBRSxDQUFDO1FBQ3ZFLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLElBQUksb0JBQW9CLENBQUMsVUFBVSxDQUFDO1FBQ3pFLE1BQU0sWUFBWSxHQUFHLFVBQVUsRUFBRSxZQUFZLENBQUM7UUFFOUMsTUFBTSx1QkFBdUIsR0FBRyxPQUFPLENBQUMsaUJBQWlCLElBQUksb0JBQW9CLENBQUMsaUJBQWlCLENBQUM7UUFDcEcsTUFBTSxpQkFBaUIsR0FBRyxVQUFVLEVBQUUsaUJBQWlCLElBQUksdUJBQXVCLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDO1FBRTdHLHdIQUF3SDtRQUN4SCxJQUFJ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OztBQTlNSCx3QkErTUM7OztBQUVELElBQVksaUJBb0JYO0FBcEJELFdBQVksaUJBQWlCO0lBQzNCOztPQUVHO0lBQ0gsa0NBQWEsQ0FBQTtJQUViOztPQUVHO0lBQ0gsb0NBQWUsQ0FBQTtJQUVmOztPQUVHO0lBQ0gsc0NBQWlCLENBQUE7SUFFakI7O09BRUc7SUFDSCxtREFBOEIsQ0FBQTtBQUNoQyxDQUFDLEVBcEJXLGlCQUFpQixHQUFqQix5QkFBaUIsS0FBakIseUJBQWlCLFFBb0I1QjtBQUVELFNBQVMsVUFBVSxDQUFDLElBQVk7SUFDOUIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLDBEQUEwRDtBQUNyRyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXJuRm9ybWF0LCBMYXp5LCBSZXNvdXJjZSwgU3RhY2sgfSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQ2ZuTWV0aG9kLCBDZm5NZXRob2RQcm9wcyB9IGZyb20gJy4vYXBpZ2F0ZXdheS5nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgQXV0aG9yaXplciwgSUF1dGhvcml6ZXIgfSBmcm9tICcuL2F1dGhvcml6ZXInO1xuaW1wb3J0IHsgSW50ZWdyYXRpb24sIEludGVncmF0aW9uQ29uZmlnIH0gZnJvbSAnLi9pbnRlZ3JhdGlvbic7XG5pbXBvcnQgeyBNb2NrSW50ZWdyYXRpb24gfSBmcm9tICcuL2ludGVncmF0aW9ucy9tb2NrJztcbmltcG9ydCB7IE1ldGhvZFJlc3BvbnNlIH0gZnJvbSAnLi9tZXRob2RyZXNwb25zZSc7XG5pbXBvcnQgeyBJTW9kZWwgfSBmcm9tICcuL21vZGVsJztcbmltcG9ydCB7IElSZXF1ZXN0VmFsaWRhdG9yLCBSZXF1ZXN0VmFsaWRhdG9yT3B0aW9ucyB9IGZyb20gJy4vcmVxdWVzdHZhbGlkYXRvcic7XG5pbXBvcnQgeyBJUmVzb3VyY2UgfSBmcm9tICcuL3Jlc291cmNlJztcbmltcG9ydCB7IElSZXN0QXBpLCBSZXN0QXBpLCBSZXN0QXBpQmFzZSB9IGZyb20gJy4vcmVzdGFwaSc7XG5pbXBvcnQgeyB2YWxpZGF0ZUh0dHBNZXRob2QgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE1ldGhvZE9wdGlvbnMge1xuICAvKipcbiAgICogQSBmcmllbmRseSBvcGVyYXRpb24gbmFtZSBmb3IgdGhlIG1ldGhvZC4gRm9yIGV4YW1wbGUsIHlvdSBjYW4gYXNzaWduIHRoZVxuICAgKiBPcGVyYXRpb25OYW1lIG9mIExpc3RQZXRzIGZvciB0aGUgR0VUIC9wZXRzIG1ldGhvZC5cbiAgICovXG4gIHJlYWRvbmx5IG9wZXJhdGlvbk5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBhdXRob3JpemF0aW9uLlxuICAgKiBJZiB0aGUgdmFsdWUgaXMgc2V0IG9mIGBDdXN0b21gLCBhbiBgYXV0aG9yaXplcmAgbXVzdCBhbHNvIGJlIHNwZWNpZmllZC5cbiAgICpcbiAgICogSWYgeW91J3JlIHVzaW5nIG9uZSBvZiB0aGUgYXV0aG9yaXplcnMgdGhhdCBhcmUgYXZhaWxhYmxlIHZpYSB0aGUge0BsaW5rIEF1dGhvcml6ZXJ9IGNsYXNzLCBzdWNoIGFzIHtAbGluayBBdXRob3JpemVyI3Rva2VuKCl9LFxuICAgKiBpdCBpcyByZWNvbW1lbmRlZCB0aGF0IHRoaXMgb3B0aW9uIG5vdCBiZSBzcGVjaWZpZWQuIFRoZSBhdXRob3JpemVyIHdpbGwgdGFrZSBjYXJlIG9mIHNldHRpbmcgdGhlIGNvcnJlY3QgYXV0aG9yaXphdGlvbiB0eXBlLlxuICAgKiBIb3dldmVyLCBzcGVjaWZ5aW5nIGFuIGF1dGhvcml6YXRpb24gdHlwZSB1c2luZyB0aGlzIHByb3BlcnR5IHRoYXQgY29uZmxpY3RzIHdpdGggd2hhdCBpcyBleHBlY3RlZCBieSB0aGUge0BsaW5rIEF1dGhvcml6ZXJ9XG4gICAqIHdpbGwgcmVzdWx0IGluIGFuIGVycm9yLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG9wZW4gYWNjZXNzIHVubGVzcyBgYXV0aG9yaXplcmAgaXMgc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSBhdXRob3JpemF0aW9uVHlwZT86IEF1dGhvcml6YXRpb25UeXBlO1xuXG4gIC8qKlxuICAgKiBJZiBgYXV0aG9yaXphdGlvblR5cGVgIGlzIGBDdXN0b21gLCB0aGlzIHNwZWNpZmllcyB0aGUgSUQgb2YgdGhlIG1ldGhvZFxuICAgKiBhdXRob3JpemVyIHJlc291cmNlLlxuICAgKiBJZiBzcGVjaWZpZWQsIHRoZSB2YWx1ZSBvZiBgYXV0aG9yaXphdGlvblR5cGVgIG11c3QgYmUgc2V0IHRvIGBDdXN0b21gXG4gICAqL1xuICByZWFkb25seSBhdXRob3JpemVyPzogSUF1dGhvcml6ZXI7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBtZXRob2QgcmVxdWlyZXMgY2xpZW50cyB0byBzdWJtaXQgYSB2YWxpZCBBUEkga2V5LlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgYXBpS2V5UmVxdWlyZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2VzIHRoYXQgY2FuIGJlIHNlbnQgdG8gdGhlIGNsaWVudCB3aG8gY2FsbHMgdGhlIG1ldGhvZC5cbiAgICogQGRlZmF1bHQgTm9uZVxuICAgKlxuICAgKiBUaGlzIHByb3BlcnR5IGlzIG5vdCByZXF1aXJlZCwgYnV0IGlmIHRoZXNlIGFyZSBub3Qgc3VwcGxpZWQgZm9yIGEgTGFtYmRhXG4gICAqIHByb3h5IGludGVncmF0aW9uLCB0aGUgTGFtYmRhIGZ1bmN0aW9uIG11c3QgcmV0dXJuIGEgdmFsdWUgb2YgdGhlIGNvcnJlY3QgZm9ybWF0LFxuICAgKiBmb3IgdGhlIGludGVncmF0aW9uIHJlc3BvbnNlIHRvIGJlIGNvcnJlY3RseSBtYXBwZWQgdG8gYSByZXNwb25zZSB0byB0aGUgY2xpZW50LlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hcGlnYXRld2F5L2xhdGVzdC9kZXZlbG9wZXJndWlkZS9hcGktZ2F0ZXdheS1tZXRob2Qtc2V0dGluZ3MtbWV0aG9kLXJlc3BvbnNlLmh0bWxcbiAgICovXG4gIHJlYWRvbmx5IG1ldGhvZFJlc3BvbnNlcz86IE1ldGhvZFJlc3BvbnNlW107XG5cbiAgLyoqXG4gICAqIFRoZSByZXF1ZXN0IHBhcmFtZXRlcnMgdGhhdCBBUEkgR2F0ZXdheSBhY2NlcHRzLiBTcGVjaWZ5IHJlcXVlc3QgcGFyYW1ldGVyc1xuICAgKiBhcyBrZXktdmFsdWUgcGFpcnMgKHN0cmluZy10by1Cb29sZWFuIG1hcHBpbmcpLCB3aXRoIGEgc291cmNlIGFzIHRoZSBrZXkgYW5kXG4gICAqIGEgQm9vbGVhbiBhcyB0aGUgdmFsdWUuIFRoZSBCb29sZWFuIHNwZWNpZmllcyB3aGV0aGVyIGEgcGFyYW1ldGVyIGlzIHJlcXVpcmVkLlxuICAgKiBBIHNvdXJjZSBtdXN0IG1hdGNoIHRoZSBmb3JtYXQgbWV0aG9kLnJlcXVlc3QubG9jYXRpb24ubmFtZSwgd2hlcmUgdGhlIGxvY2F0aW9uXG4gICAqIGlzIHF1ZXJ5c3RyaW5nLCBwYXRoLCBvciBoZWFkZXIsIGFuZCBuYW1lIGlzIGEgdmFsaWQsIHVuaXF1ZSBwYXJhbWV0ZXIgbmFtZS5cbiAgICogQGRlZmF1bHQgTm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVxdWVzdFBhcmFtZXRlcnM/OiB7IFtwYXJhbTogc3RyaW5nXTogYm9vbGVhbiB9O1xuXG4gIC8qKlxuICAgKiBUaGUgbW9kZWxzIHdoaWNoIGRlc2NyaWJlIGRhdGEgc3RydWN0dXJlIG9mIHJlcXVlc3QgcGF5bG9hZC4gV2hlblxuICAgKiBjb21iaW5lZCB3aXRoIGByZXF1ZXN0VmFsaWRhdG9yYCBvciBgcmVxdWVzdFZhbGlkYXRvck9wdGlvbnNgLCB0aGUgc2VydmljZVxuICAgKiB3aWxsIHZhbGlkYXRlIHRoZSBBUEkgcmVxdWVzdCBwYXlsb2FkIGJlZm9yZSBpdCByZWFjaGVzIHRoZSBBUEkncyBJbnRlZ3JhdGlvbiAoaW5jbHVkaW5nIHByb3hpZXMpLlxuICAgKiBTcGVjaWZ5IGByZXF1ZXN0TW9kZWxzYCBhcyBrZXktdmFsdWUgcGFpcnMsIHdpdGggYSBjb250ZW50IHR5cGVcbiAgICogKGUuZy4gYCdhcHBsaWNhdGlvbi9qc29uJ2ApIGFzIHRoZSBrZXkgYW5kIGFuIEFQSSBHYXRld2F5IE1vZGVsIGFzIHRoZSB2YWx1ZS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogICAgIGRlY2xhcmUgY29uc3QgYXBpOiBhcGlnYXRld2F5LlJlc3RBcGk7XG4gICAqICAgICBkZWNsYXJlIGNvbnN0IHVzZXJMYW1iZGE6IGxhbWJkYS5GdW5jdGlvbjtcbiAgICpcbiAgICogICAgIGNvbnN0IHVzZXJNb2RlbDogYXBpZ2F0ZXdheS5Nb2RlbCA9IGFwaS5hZGRNb2RlbCgnVXNlck1vZGVsJywge1xuICAgKiAgICAgICAgIHNjaGVtYToge1xuICAgKiAgICAgICAgICAgICB0eXBlOiBhcGlnYXRld2F5Lkpzb25TY2hlbWFUeXBlLk9CSkVDVCxcbiAgICogICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgKiAgICAgICAgICAgICAgICAgdXNlcklkOiB7XG4gICAqICAgICAgICAgICAgICAgICAgICAgdHlwZTogYXBpZ2F0ZXdheS5Kc29uU2NoZW1hVHlwZS5TVFJJTkdcbiAgICogICAgICAgICAgICAgICAgIH0sXG4gICAqICAgICAgICAgICAgICAgICBuYW1lOiB7XG4gICAqICAgICAgICAgICAgICAgICAgICAgdHlwZTogYXBpZ2F0ZXdheS5Kc29uU2NoZW1hVHlwZS5TVFJJTkdcbiAgICogICAgICAgICAgICAgICAgIH1cbiAgICogICAgICAgICAgICAgfSxcbiAgICogICAgICAgICAgICAgcmVxdWlyZWQ6IFsndXNlcklkJ11cbiAgICogICAgICAgICB9XG4gICAqICAgICB9KTtcbiAgICogICAgIGFwaS5yb290LmFkZFJlc291cmNlKCd1c2VyJykuYWRkTWV0aG9kKCdQT1NUJyxcbiAgICogICAgICAgICBuZXcgYXBpZ2F0ZXdheS5MYW1iZGFJbnRlZ3JhdGlvbih1c2VyTGFtYmRhKSwge1xuICAgKiAgICAgICAgICAgICByZXF1ZXN0TW9kZWxzOiB7XG4gICAqICAgICAgICAgICAgICAgICAnYXBwbGljYXRpb24vanNvbic6IHVzZXJNb2RlbFxuICAgKiAgICAgICAgICAgICB9XG4gICAqICAgICAgICAgfVxuICAgKiAgICAgKTtcbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXBpZ2F0ZXdheS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYXBpLWdhdGV3YXktbWV0aG9kLXNldHRpbmdzLW1ldGhvZC1yZXF1ZXN0Lmh0bWwjc2V0dXAtbWV0aG9kLXJlcXVlc3QtbW9kZWxcbiAgICovXG4gIHJlYWRvbmx5IHJlcXVlc3RNb2RlbHM/OiB7IFtwYXJhbTogc3RyaW5nXTogSU1vZGVsIH07XG5cbiAgLyoqXG4gICAqIFRoZSBJRCBvZiB0aGUgYXNzb2NpYXRlZCByZXF1ZXN0IHZhbGlkYXRvci5cbiAgICogT25seSBvbmUgb2YgYHJlcXVlc3RWYWxpZGF0b3JgIG9yIGByZXF1ZXN0VmFsaWRhdG9yT3B0aW9uc2AgbXVzdCBiZSBzcGVjaWZpZWQuXG4gICAqIFdvcmtzIHRvZ2V0aGVyIHdpdGggYHJlcXVlc3RNb2RlbHNgIG9yIGByZXF1ZXN0UGFyYW1ldGVyc2AgdG8gdmFsaWRhdGVcbiAgICogdGhlIHJlcXVlc3QgYmVmb3JlIGl0IHJlYWNoZXMgaW50ZWdyYXRpb24gbGlrZSBMYW1iZGEgUHJveHkgSW50ZWdyYXRpb24uXG4gICAqIEBkZWZhdWx0IC0gTm8gZGVmYXVsdCB2YWxpZGF0b3JcbiAgICovXG4gIHJlYWRvbmx5IHJlcXVlc3RWYWxpZGF0b3I/OiBJUmVxdWVzdFZhbGlkYXRvcjtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIGF1dGhvcml6YXRpb24gc2NvcGVzIGNvbmZpZ3VyZWQgb24gdGhlIG1ldGhvZC4gVGhlIHNjb3BlcyBhcmUgdXNlZCB3aXRoXG4gICAqIGEgQ09HTklUT19VU0VSX1BPT0xTIGF1dGhvcml6ZXIgdG8gYXV0aG9yaXplIHRoZSBtZXRob2QgaW52b2NhdGlvbi5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtYXBpZ2F0ZXdheS1tZXRob2QuaHRtbCNjZm4tYXBpZ2F0ZXdheS1tZXRob2QtYXV0aG9yaXphdGlvbnNjb3Blc1xuICAgKiBAZGVmYXVsdCAtIG5vIGF1dGhvcml6YXRpb24gc2NvcGVzXG4gICAqL1xuICByZWFkb25seSBhdXRob3JpemF0aW9uU2NvcGVzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFJlcXVlc3QgdmFsaWRhdG9yIG9wdGlvbnMgdG8gY3JlYXRlIG5ldyB2YWxpZGF0b3JcbiAgICogT25seSBvbmUgb2YgYHJlcXVlc3RWYWxpZGF0b3JgIG9yIGByZXF1ZXN0VmFsaWRhdG9yT3B0aW9uc2AgbXVzdCBiZSBzcGVjaWZpZWQuXG4gICAqIFdvcmtzIHRvZ2V0aGVyIHdpdGggYHJlcXVlc3RNb2RlbHNgIG9yIGByZXF1ZXN0UGFyYW1ldGVyc2AgdG8gdmFsaWRhdGVcbiAgICogdGhlIHJlcXVlc3QgYmVmb3JlIGl0IHJlYWNoZXMgaW50ZWdyYXRpb24gbGlrZSBMYW1iZGEgUHJveHkgSW50ZWdyYXRpb24uXG4gICAqIEBkZWZhdWx0IC0gTm8gZGVmYXVsdCB2YWxpZGF0b3JcbiAgICovXG4gIHJlYWRvbmx5IHJlcXVlc3RWYWxpZGF0b3JPcHRpb25zPzogUmVxdWVzdFZhbGlkYXRvck9wdGlvbnM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWV0aG9kUHJvcHMge1xuICAvKipcbiAgICogVGhlIHJlc291cmNlIHRoaXMgbWV0aG9kIGlzIGFzc29jaWF0ZWQgd2l0aC4gRm9yIHJvb3QgcmVzb3VyY2UgbWV0aG9kcyxcbiAgICogc3BlY2lmeSB0aGUgYFJlc3RBcGlgIG9iamVjdC5cbiAgICovXG4gIHJlYWRvbmx5IHJlc291cmNlOiBJUmVzb3VyY2U7XG5cbiAgLyoqXG4gICAqIFRoZSBIVFRQIG1ldGhvZCAoXCJHRVRcIiwgXCJQT1NUXCIsIFwiUFVUXCIsIC4uLikgdGhhdCBjbGllbnRzIHVzZSB0byBjYWxsIHRoaXMgbWV0aG9kLlxuICAgKi9cbiAgcmVhZG9ubHkgaHR0cE1ldGhvZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYmFja2VuZCBzeXN0ZW0gdGhhdCB0aGUgbWV0aG9kIGNhbGxzIHdoZW4gaXQgcmVjZWl2ZXMgYSByZXF1ZXN0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGEgbmV3IGBNb2NrSW50ZWdyYXRpb25gLlxuICAgKi9cbiAgcmVhZG9ubHkgaW50ZWdyYXRpb24/OiBJbnRlZ3JhdGlvbjtcblxuICAvKipcbiAgICogTWV0aG9kIG9wdGlvbnMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gb3B0aW9ucy5cbiAgICovXG4gIHJlYWRvbmx5IG9wdGlvbnM/OiBNZXRob2RPcHRpb25zO1xufVxuXG5leHBvcnQgY2xhc3MgTWV0aG9kIGV4dGVuZHMgUmVzb3VyY2Uge1xuICAvKiogQGF0dHJpYnV0ZSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbWV0aG9kSWQ6IHN0cmluZztcblxuICBwdWJsaWMgcmVhZG9ubHkgaHR0cE1ldGhvZDogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcmVzb3VyY2U6IElSZXNvdXJjZTtcbiAgLyoqXG4gICAqIFRoZSBBUEkgR2F0ZXdheSBSZXN0QXBpIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1ldGhvZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhcGk6IElSZXN0QXBpO1xuXG4gIHByaXZhdGUgbWV0aG9kUmVzcG9uc2VzOiBNZXRob2RSZXNwb25zZVtdO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBNZXRob2RQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLnJlc291cmNlID0gcHJvcHMucmVzb3VyY2U7XG4gICAgdGhpcy5hcGkgPSBwcm9wcy5yZXNvdXJjZS5hcGk7XG4gICAgdGhpcy5odHRwTWV0aG9kID0gcHJvcHMuaHR0cE1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuXG4gICAgdmFsaWRhdGVIdHRwTWV0aG9kKHRoaXMuaHR0cE1ldGhvZCk7XG5cbiAgICBjb25zdCBvcHRpb25zID0gcHJvcHMub3B0aW9ucyB8fCB7fTtcblxuICAgIGNvbnN0IGRlZmF1bHRNZXRob2RPcHRpb25zID0gcHJvcHMucmVzb3VyY2UuZGVmYXVsdE1ldGhvZE9wdGlvbnMgfHwge307XG4gICAgY29uc3QgYXV0aG9yaXplciA9IG9wdGlvbnMuYXV0aG9yaXplciB8fCBkZWZhdWx0TWV0aG9kT3B0aW9ucy5hdXRob3JpemVyO1xuICAgIGNvbnN0IGF1dGhvcml6ZXJJZCA9IGF1dGhvcml6ZXI/LmF1dGhvcml6ZXJJZDtcblxuICAgIGNvbnN0IGF1dGhvcml6YXRpb25UeXBlT3B0aW9uID0gb3B0aW9ucy5hdXRob3JpemF0aW9uVHlwZSB8fCBkZWZhdWx0TWV0aG9kT3B0aW9ucy5hdXRob3JpemF0aW9uVHlwZTtcbiAgICBjb25zdCBhdXRob3JpemF0aW9uVHlwZSA9IGF1dGhvcml6ZXI/LmF1dGhvcml6YXRpb25UeXBlIHx8IGF1dGhvcml6YXRpb25UeXBlT3B0aW9uIHx8IEF1dGhvcml6YXRpb25UeXBlLk5PTkU7XG5cbiAgICAvLyBpZiB0aGUgYXV0aG9yaXplciBkZWZpbmVzIGFuIGF1dGhvcml6YXRpb24gdHlwZSBhbmQgd2UgYWxzbyBoYXZlIGFuIGV4cGxpY2l0IG9wdGlvbiBzZXQsIGNoZWNrIHRoYXQgdGhleSBhcmUgdGhlIHNhbWVcbiAgICBpZiAoYXV0aG9yaXplcj8uYXV0aG9yaXphdGlvblR5cGUgJiYgYXV0aG9yaXphdGlvblR5cGVPcHRpb24gJiYgYXV0aG9yaXplcj8uYXV0aG9yaXphdGlvblR5cGUgIT09IGF1dGhvcml6YXRpb25UeXBlT3B0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5yZXNvdXJjZX0vJHt0aGlzLmh0dHBNZXRob2R9IC0gQXV0aG9yaXphdGlvbiB0eXBlIGlzIHNldCB0byAke2F1dGhvcml6YXRpb25UeXBlT3B0aW9ufSBgICtcbiAgICAgICAgYHdoaWNoIGlzIGRpZmZlcmVudCBmcm9tIHdoYXQgaXMgcmVxdWlyZWQgYnkgdGhlIGF1dGhvcml6ZXIgWyR7YXV0aG9yaXplci5hdXRob3JpemF0aW9uVHlwZX1dYCk7XG4gICAgfVxuXG4gICAgaWYgKEF1dGhvcml6ZXIuaXNBdXRob3JpemVyKGF1dGhvcml6ZXIpKSB7XG4gICAgICBhdXRob3JpemVyLl9hdHRhY2hUb0FwaSh0aGlzLmFwaSk7XG4gICAgfVxuXG4gICAgdGhpcy5tZXRob2RSZXNwb25zZXMgPSBvcHRpb25zLm1ldGhvZFJlc3BvbnNlcyA/PyBbXTtcblxuICAgIGNvbnN0IGludGVncmF0aW9uID0gcHJvcHMuaW50ZWdyYXRpb24gPz8gdGhpcy5yZXNvdXJjZS5kZWZhdWx0SW50ZWdyYXRpb24gPz8gbmV3IE1vY2tJbnRlZ3JhdGlvbigpO1xuICAgIGNvbnN0IGJpbmRSZXN1bHQgPSBpbnRlZ3JhdGlvbi5iaW5kKHRoaXMpO1xuXG4gICAgY29uc3QgbWV0aG9kUHJvcHM6IENmbk1ldGhvZFByb3BzID0ge1xuICAgICAgcmVzb3VyY2VJZDogcHJvcHMucmVzb3VyY2UucmVzb3VyY2VJZCxcbiAgICAgIHJlc3RBcGlJZDogdGhpcy5hcGkucmVzdEFwaUlkLFxuICAgICAgaHR0cE1ldGhvZDogdGhpcy5odHRwTWV0aG9kLFxuICAgICAgb3BlcmF0aW9uTmFtZTogb3B0aW9ucy5vcGVyYXRpb25OYW1lIHx8IGRlZmF1bHRNZXRob2RPcHRpb25zLm9wZXJhdGlvbk5hbWUsXG4gICAgICBhcGlLZXlSZXF1aXJlZDogb3B0aW9ucy5hcGlLZXlSZXF1aXJlZCB8fCBkZWZhdWx0TWV0aG9kT3B0aW9ucy5hcGlLZXlSZXF1aXJlZCxcbiAgICAgIGF1dGhvcml6YXRpb25UeXBlLFxuICAgICAgYXV0aG9yaXplcklkLFxuICAgICAgcmVxdWVzdFBhcmFtZXRlcnM6IG9wdGlvbnMucmVxdWVzdFBhcmFtZXRlcnMgfHwgZGVmYXVsdE1ldGhvZE9wdGlvbnMucmVxdWVzdFBhcmFtZXRlcnMsXG4gICAgICBpbnRlZ3JhdGlvbjogdGhpcy5yZW5kZXJJbnRlZ3JhdGlvbihiaW5kUmVzdWx0KSxcbiAgICAgIG1ldGhvZFJlc3BvbnNlczogTGF6eS5hbnkoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLnJlbmRlck1ldGhvZFJlc3BvbnNlcyh0aGlzLm1ldGhvZFJlc3BvbnNlcykgfSwgeyBvbWl0RW1wdHlBcnJheTogdHJ1ZSB9KSxcbiAgICAgIHJlcXVlc3RNb2RlbHM6IHRoaXMucmVuZGVyUmVxdWVzdE1vZGVscyhvcHRpb25zLnJlcXVlc3RNb2RlbHMpLFxuICAgICAgcmVxdWVzdFZhbGlkYXRvcklkOiB0aGlzLnJlcXVlc3RWYWxpZGF0b3JJZChvcHRpb25zKSxcbiAgICAgIGF1dGhvcml6YXRpb25TY29wZXM6IG9wdGlvbnMuYXV0aG9yaXphdGlvblNjb3BlcyA/PyBkZWZhdWx0TWV0aG9kT3B0aW9ucy5hdXRob3JpemF0aW9uU2NvcGVzLFxuICAgIH07XG5cbiAgICBjb25zdCByZXNvdXJjZSA9IG5ldyBDZm5NZXRob2QodGhpcywgJ1Jlc291cmNlJywgbWV0aG9kUHJvcHMpO1xuXG4gICAgdGhpcy5tZXRob2RJZCA9IHJlc291cmNlLnJlZjtcblxuICAgIGlmIChSZXN0QXBpQmFzZS5faXNSZXN0QXBpQmFzZShwcm9wcy5yZXNvdXJjZS5hcGkpKSB7XG4gICAgICBwcm9wcy5yZXNvdXJjZS5hcGkuX2F0dGFjaE1ldGhvZCh0aGlzKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZXBsb3ltZW50ID0gcHJvcHMucmVzb3VyY2UuYXBpLmxhdGVzdERlcGxveW1lbnQ7XG4gICAgaWYgKGRlcGxveW1lbnQpIHtcbiAgICAgIGRlcGxveW1lbnQubm9kZS5hZGREZXBlbmRlbmN5KHJlc291cmNlKTtcbiAgICAgIGRlcGxveW1lbnQuYWRkVG9Mb2dpY2FsSWQoe1xuICAgICAgICBtZXRob2Q6IHtcbiAgICAgICAgICAuLi5tZXRob2RQcm9wcyxcbiAgICAgICAgICBpbnRlZ3JhdGlvblRva2VuOiBiaW5kUmVzdWx0Py5kZXBsb3ltZW50VG9rZW4sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIFJlc3RBcGkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgTWV0aG9kXG4gICAqIEBkZXByZWNhdGVkIC0gVGhyb3dzIGFuIGVycm9yIGlmIHRoaXMgUmVzb3VyY2UgaXMgbm90IGFzc29jaWF0ZWQgd2l0aCBhbiBpbnN0YW5jZSBvZiBgUmVzdEFwaWAuIFVzZSBgYXBpYCBpbnN0ZWFkLlxuICAgKi9cbiAgcHVibGljIGdldCByZXN0QXBpKCk6IFJlc3RBcGkge1xuICAgIHJldHVybiB0aGlzLnJlc291cmNlLnJlc3RBcGk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBleGVjdXRlLWFwaSBBUk4gZm9yIHRoaXMgbWV0aG9kOlxuICAgKlxuICAgKiAgIGFybjphd3M6ZXhlY3V0ZS1hcGk6e3JlZ2lvbn06e2FjY291bnR9OntyZXN0QXBpSWR9L3tzdGFnZX0ve21ldGhvZH0ve3BhdGh9XG4gICAqXG4gICAqIE5PVEU6IHtzdGFnZX0gd2lsbCByZWZlciB0byB0aGUgYHJlc3RBcGkuZGVwbG95bWVudFN0YWdlYCwgd2hpY2ggd2lsbFxuICAgKiBhdXRvbWF0aWNhbGx5IHNldCBpZiBhdXRvLWRlcGxveSBpcyBlbmFibGVkLCBvciBjYW4gYmUgZXhwbGljaXRseSBhc3NpZ25lZC5cbiAgICogV2hlbiBub3QgY29uZmlndXJlZCwge3N0YWdlfSB3aWxsIGJlIHNldCB0byAnKicsIGFzIGEgc2hvcnRoYW5kIGZvciAnYWxsIHN0YWdlcycuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyBnZXQgbWV0aG9kQXJuKCk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RhZ2UgPSB0aGlzLmFwaS5kZXBsb3ltZW50U3RhZ2U/LnN0YWdlTmFtZTtcbiAgICByZXR1cm4gdGhpcy5hcGkuYXJuRm9yRXhlY3V0ZUFwaSh0aGlzLmh0dHBNZXRob2QsIHBhdGhGb3JBcm4odGhpcy5yZXNvdXJjZS5wYXRoKSwgc3RhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gZXhlY3V0ZS1hcGkgQVJOIGZvciB0aGlzIG1ldGhvZCdzIFwidGVzdC1pbnZva2Utc3RhZ2VcIiBzdGFnZS5cbiAgICogVGhpcyBzdGFnZSBpcyB1c2VkIGJ5IHRoZSBBV1MgQ29uc29sZSBVSSB3aGVuIHRlc3RpbmcgdGhlIG1ldGhvZC5cbiAgICovXG4gIHB1YmxpYyBnZXQgdGVzdE1ldGhvZEFybigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmFwaS5hcm5Gb3JFeGVjdXRlQXBpKHRoaXMuaHR0cE1ldGhvZCwgcGF0aEZvckFybih0aGlzLnJlc291cmNlLnBhdGgpLCAndGVzdC1pbnZva2Utc3RhZ2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBtZXRob2QgcmVzcG9uc2UgdG8gdGhpcyBtZXRob2RcbiAgICovXG4gIHB1YmxpYyBhZGRNZXRob2RSZXNwb25zZShtZXRob2RSZXNwb25zZTogTWV0aG9kUmVzcG9uc2UpOiB2b2lkIHtcbiAgICB0aGlzLm1ldGhvZFJlc3BvbnNlcy5wdXNoKG1ldGhvZFJlc3BvbnNlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVySW50ZWdyYXRpb24oYmluZFJlc3VsdDogSW50ZWdyYXRpb25Db25maWcpOiBDZm5NZXRob2QuSW50ZWdyYXRpb25Qcm9wZXJ0eSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IGJpbmRSZXN1bHQub3B0aW9ucyA/PyB7fTtcbiAgICBsZXQgY3JlZGVudGlhbHM7XG4gICAgaWYgKG9wdGlvbnMuY3JlZGVudGlhbHNSb2xlKSB7XG4gICAgICBjcmVkZW50aWFscyA9IG9wdGlvbnMuY3JlZGVudGlhbHNSb2xlLnJvbGVBcm47XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLmNyZWRlbnRpYWxzUGFzc3Rocm91Z2gpIHtcbiAgICAgIC8vIGFybjphd3M6aWFtOjoqOnVzZXIvKlxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgIGNyZWRlbnRpYWxzID0gU3RhY2sub2YodGhpcykuZm9ybWF0QXJuKHsgc2VydmljZTogJ2lhbScsIHJlZ2lvbjogJycsIGFjY291bnQ6ICcqJywgcmVzb3VyY2U6ICd1c2VyJywgYXJuRm9ybWF0OiBBcm5Gb3JtYXQuU0xBU0hfUkVTT1VSQ0VfTkFNRSwgcmVzb3VyY2VOYW1lOiAnKicgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IGJpbmRSZXN1bHQudHlwZSxcbiAgICAgIHVyaTogYmluZFJlc3VsdC51cmksXG4gICAgICBjYWNoZUtleVBhcmFtZXRlcnM6IG9wdGlvbnMuY2FjaGVLZXlQYXJhbWV0ZXJzLFxuICAgICAgY2FjaGVOYW1lc3BhY2U6IG9wdGlvbnMuY2FjaGVOYW1lc3BhY2UsXG4gICAgICBjb250ZW50SGFuZGxpbmc6IG9wdGlvbnMuY29udGVudEhhbmRsaW5nLFxuICAgICAgaW50ZWdyYXRpb25IdHRwTWV0aG9kOiBiaW5kUmVzdWx0LmludGVncmF0aW9uSHR0cE1ldGhvZCxcbiAgICAgIHJlcXVlc3RQYXJhbWV0ZXJzOiBvcHRpb25zLnJlcXVlc3RQYXJhbWV0ZXJzLFxuICAgICAgcmVxdWVzdFRlbXBsYXRlczogb3B0aW9ucy5yZXF1ZXN0VGVtcGxhdGVzLFxuICAgICAgcGFzc3Rocm91Z2hCZWhhdmlvcjogb3B0aW9ucy5wYXNzdGhyb3VnaEJlaGF2aW9yLFxuICAgICAgaW50ZWdyYXRpb25SZXNwb25zZXM6IG9wdGlvbnMuaW50ZWdyYXRpb25SZXNwb25zZXMsXG4gICAgICBjb25uZWN0aW9uVHlwZTogb3B0aW9ucy5jb25uZWN0aW9uVHlwZSxcbiAgICAgIGNvbm5lY3Rpb25JZDogb3B0aW9ucy52cGNMaW5rID8gb3B0aW9ucy52cGNMaW5rLnZwY0xpbmtJZCA6IHVuZGVmaW5lZCxcbiAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgdGltZW91dEluTWlsbGlzOiBvcHRpb25zLnRpbWVvdXQ/LnRvTWlsbGlzZWNvbmRzKCksXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyTWV0aG9kUmVzcG9uc2VzKG1ldGhvZFJlc3BvbnNlczogTWV0aG9kUmVzcG9uc2VbXSB8IHVuZGVmaW5lZCk6IENmbk1ldGhvZC5NZXRob2RSZXNwb25zZVByb3BlcnR5W10gfCB1bmRlZmluZWQge1xuICAgIGlmICghbWV0aG9kUmVzcG9uc2VzKSB7XG4gICAgICAvLyBGYWxsIGJhY2sgdG8gbm90aGluZ1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gbWV0aG9kUmVzcG9uc2VzLm1hcChtciA9PiB7XG4gICAgICBsZXQgcmVzcG9uc2VNb2RlbHM6IHtbY29udGVudFR5cGU6IHN0cmluZ106IHN0cmluZ30gfCB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChtci5yZXNwb25zZU1vZGVscykge1xuICAgICAgICByZXNwb25zZU1vZGVscyA9IHt9O1xuICAgICAgICBmb3IgKGNvbnN0IGNvbnRlbnRUeXBlIGluIG1yLnJlc3BvbnNlTW9kZWxzKSB7XG4gICAgICAgICAgaWYgKG1yLnJlc3BvbnNlTW9kZWxzLmhhc093blByb3BlcnR5KGNvbnRlbnRUeXBlKSkge1xuICAgICAgICAgICAgcmVzcG9uc2VNb2RlbHNbY29udGVudFR5cGVdID0gbXIucmVzcG9uc2VNb2RlbHNbY29udGVudFR5cGVdLm1vZGVsSWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1ldGhvZFJlc3BvbnNlUHJvcCA9IHtcbiAgICAgICAgc3RhdHVzQ29kZTogbXIuc3RhdHVzQ29kZSxcbiAgICAgICAgcmVzcG9uc2VQYXJhbWV0ZXJzOiBtci5yZXNwb25zZVBhcmFtZXRlcnMsXG4gICAgICAgIHJlc3BvbnNlTW9kZWxzLFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIG1ldGhvZFJlc3BvbnNlUHJvcDtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyUmVxdWVzdE1vZGVscyhyZXF1ZXN0TW9kZWxzOiB7IFtwYXJhbTogc3RyaW5nXTogSU1vZGVsIH0gfCB1bmRlZmluZWQpOiB7IFtwYXJhbTogc3RyaW5nXTogc3RyaW5nIH0gfCB1bmRlZmluZWQge1xuICAgIGlmICghcmVxdWVzdE1vZGVscykge1xuICAgICAgLy8gRmFsbCBiYWNrIHRvIG5vdGhpbmdcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgbW9kZWxzOiB7W3BhcmFtOiBzdHJpbmddOiBzdHJpbmd9ID0ge307XG4gICAgZm9yIChjb25zdCBjb250ZW50VHlwZSBpbiByZXF1ZXN0TW9kZWxzKSB7XG4gICAgICBpZiAocmVxdWVzdE1vZGVscy5oYXNPd25Qcm9wZXJ0eShjb250ZW50VHlwZSkpIHtcbiAgICAgICAgbW9kZWxzW2NvbnRlbnRUeXBlXSA9IHJlcXVlc3RNb2RlbHNbY29udGVudFR5cGVdLm1vZGVsSWQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGVscztcbiAgfVxuXG4gIHByaXZhdGUgcmVxdWVzdFZhbGlkYXRvcklkKG9wdGlvbnM6IE1ldGhvZE9wdGlvbnMpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmIChvcHRpb25zLnJlcXVlc3RWYWxpZGF0b3IgJiYgb3B0aW9ucy5yZXF1ZXN0VmFsaWRhdG9yT3B0aW9ucykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IG9uZSBvZiBcXCdyZXF1ZXN0VmFsaWRhdG9yXFwnIG9yIFxcJ3JlcXVlc3RWYWxpZGF0b3JPcHRpb25zXFwnIG11c3QgYmUgc3BlY2lmaWVkLicpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnJlcXVlc3RWYWxpZGF0b3JPcHRpb25zKSB7XG4gICAgICBjb25zdCB2YWxpZGF0b3IgPSAodGhpcy5hcGkgYXMgUmVzdEFwaSkuYWRkUmVxdWVzdFZhbGlkYXRvcigndmFsaWRhdG9yJywgb3B0aW9ucy5yZXF1ZXN0VmFsaWRhdG9yT3B0aW9ucyk7XG4gICAgICByZXR1cm4gdmFsaWRhdG9yLnJlcXVlc3RWYWxpZGF0b3JJZDtcbiAgICB9XG5cbiAgICAvLyBGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICAgIHJldHVybiBvcHRpb25zLnJlcXVlc3RWYWxpZGF0b3I/LnJlcXVlc3RWYWxpZGF0b3JJZDtcbiAgfVxufVxuXG5leHBvcnQgZW51bSBBdXRob3JpemF0aW9uVHlwZSB7XG4gIC8qKlxuICAgKiBPcGVuIGFjY2Vzcy5cbiAgICovXG4gIE5PTkUgPSAnTk9ORScsXG5cbiAgLyoqXG4gICAqIFVzZSBBV1MgSUFNIHBlcm1pc3Npb25zLlxuICAgKi9cbiAgSUFNID0gJ0FXU19JQU0nLFxuXG4gIC8qKlxuICAgKiBVc2UgYSBjdXN0b20gYXV0aG9yaXplci5cbiAgICovXG4gIENVU1RPTSA9ICdDVVNUT00nLFxuXG4gIC8qKlxuICAgKiBVc2UgYW4gQVdTIENvZ25pdG8gdXNlciBwb29sLlxuICAgKi9cbiAgQ09HTklUTyA9ICdDT0dOSVRPX1VTRVJfUE9PTFMnLFxufVxuXG5mdW5jdGlvbiBwYXRoRm9yQXJuKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBwYXRoLnJlcGxhY2UoL1xce1teXFx9XSpcXH0vZywgJyonKTsgLy8gcmVwbGFjZSBwYXRoIHBhcmFtZXRlcnMgKGxpa2UgJ3tib29rSWR9Jykgd2l0aCBhc3Rlcmlza1xufVxuIl19