UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

424 lines 46 kB
"use strict"; /** * Constructs compatibility layer. * * This file includes types that shadow types in the "constructs" module in * order to allow backwards-compatiblity in the AWS CDK v1.0 release line. * * There are pretty ugly hacks here, which mostly involve downcasting types to * adhere to legacy AWS CDK APIs. * * This file, in its entirety, is expected to be removed in v2.0. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ConstructNode = exports.ConstructOrder = exports.Construct = void 0; const cxapi = require("@aws-cdk/cx-api"); const constructs = require("constructs"); const annotations_1 = require("./annotations"); const aspect_1 = require("./aspect"); const token_1 = require("./token"); const ORIGINAL_CONSTRUCT_NODE_SYMBOL = Symbol.for('@aws-cdk/core.ConstructNode'); const CONSTRUCT_SYMBOL = Symbol.for('@aws-cdk/core.Construct'); /** * Represents the building block of the construct graph. * * All constructs besides the root construct must be created within the scope of * another construct. */ class Construct extends constructs.Construct { /** * */ constructor(scope, id) { super(scope, id, { nodeFactory: { createNode: (h, s, i) => new ConstructNode(h, s, i)._actualNode, }, }); if (token_1.Token.isUnresolved(id)) { throw new Error(`Cannot use tokens in construct ID: ${id}`); } Object.defineProperty(this, CONSTRUCT_SYMBOL, { value: true }); this.node = ConstructNode._unwrap(constructs.Node.of(this)); const disableTrace = this.node.tryGetContext(cxapi.DISABLE_METADATA_STACK_TRACE) || this.node.tryGetContext(constructs.ConstructMetadata.DISABLE_STACK_TRACE_IN_METADATA) || process.env.CDK_DISABLE_STACK_TRACE; if (disableTrace) { this.node.setContext(cxapi.DISABLE_METADATA_STACK_TRACE, true); this.node.setContext(constructs.ConstructMetadata.DISABLE_STACK_TRACE_IN_METADATA, true); process.env.CDK_DISABLE_STACK_TRACE = '1'; } } /** * Return whether the given object is a Construct. */ static isConstruct(x) { return typeof x === 'object' && x !== null && CONSTRUCT_SYMBOL in x; } /** * Validate the current construct. * * This method can be implemented by derived constructs in order to perform * validation logic. It is called on all constructs before synthesis. * * @returns An array of validation error messages, or an empty array if the construct is valid. */ onValidate() { return this.validate(); } /** * Perform final modifications before synthesis. * * This method can be implemented by derived constructs in order to perform * final changes before synthesis. prepare() will be called after child * constructs have been prepared. * * This is an advanced framework feature. Only use this if you * understand the implications. */ onPrepare() { this.prepare(); } /** * Allows this construct to emit artifacts into the cloud assembly during synthesis. * * This method is usually implemented by framework-level constructs such as `Stack` and `Asset` * as they participate in synthesizing the cloud assembly. * * @param session The synthesis session. */ onSynthesize(session) { this.synthesize({ outdir: session.outdir, assembly: session.assembly, }); } /** * Validate the current construct. * * This method can be implemented by derived constructs in order to perform * validation logic. It is called on all constructs before synthesis. * * @returns An array of validation error messages, or an empty array if the construct is valid. */ validate() { return []; } /** * Perform final modifications before synthesis. * * This method can be implemented by derived constructs in order to perform * final changes before synthesis. prepare() will be called after child * constructs have been prepared. * * This is an advanced framework feature. Only use this if you * understand the implications. */ prepare() { return; } /** * Allows this construct to emit artifacts into the cloud assembly during synthesis. * * This method is usually implemented by framework-level constructs such as `Stack` and `Asset` * as they participate in synthesizing the cloud assembly. * * @param session The synthesis session. */ synthesize(session) { ignore(session); } } exports.Construct = Construct; /** * In what order to return constructs. */ var ConstructOrder; (function (ConstructOrder) { ConstructOrder[ConstructOrder["PREORDER"] = 0] = "PREORDER"; ConstructOrder[ConstructOrder["POSTORDER"] = 1] = "POSTORDER"; })(ConstructOrder = exports.ConstructOrder || (exports.ConstructOrder = {})); /** * Represents the construct node in the scope tree. */ class ConstructNode { /** * */ constructor(host, scope, id) { this.host = host; this._actualNode = new constructs.Node(host, scope, id); // store a back reference on _actualNode so we can our ConstructNode from it Object.defineProperty(this._actualNode, ORIGINAL_CONSTRUCT_NODE_SYMBOL, { value: this, configurable: false, enumerable: false, }); } /** * Returns the wrapping `@aws-cdk/core.ConstructNode` instance from a `constructs.ConstructNode`. * * @internal */ static _unwrap(c) { const x = c[ORIGINAL_CONSTRUCT_NODE_SYMBOL]; if (!x) { throw new Error('invalid ConstructNode type'); } return x; } /** * (deprecated) Synthesizes a CloudAssembly from a construct tree. * * @param node The root of the construct tree. * @param options Synthesis options. * @deprecated Use `app.synth()` or `stage.synth()` instead */ static synth(node, options = {}) { // eslint-disable-next-line @typescript-eslint/no-require-imports const a = require('./private/synthesis'); return a.synthesize(node.root, options); } /** * (deprecated) Invokes "prepare" on all constructs (depth-first, post-order) in the tree under `node`. * * @param node The root node. * @deprecated Use `app.synth()` instead */ static prepare(node) { // eslint-disable-next-line @typescript-eslint/no-require-imports const p = require('./private/prepare-app'); p.prepareApp(node.root); // resolve cross refs and nested stack assets. return node._actualNode.prepare(); } /** * Invokes "validate" on all constructs in the tree (depth-first, pre-order) and returns the list of all errors. * * An empty list indicates that there are no errors. * * @param node The root node. */ static validate(node) { return node._actualNode.validate().map(e => ({ source: e.source, message: e.message })); } /** * Returns the scope in which this construct is defined. * * The value is `undefined` at the root of the construct scope tree. */ get scope() { return this._actualNode.scope; } /** * The id of this construct within the current scope. * * This is a a scope-unique id. To obtain an app-unique id for this construct, use `uniqueId`. */ get id() { return this._actualNode.id; } /** * The full, absolute path of this construct in the tree. * * Components are separated by '/'. */ get path() { return this._actualNode.path; } /** * A tree-global unique alphanumeric identifier for this construct. * * Includes all components of the tree. */ get uniqueId() { return this._actualNode.uniqueId; } /** * Return a direct child by id, or undefined. * * @param id Identifier of direct child. * @returns the child if found, or undefined */ tryFindChild(id) { return this._actualNode.tryFindChild(id); } /** * Return a direct child by id. * * Throws an error if the child is not found. * * @param id Identifier of direct child. * @returns Child with the given id. */ findChild(id) { return this._actualNode.findChild(id); } /** * Returns the child construct that has the id `Default` or `Resource"`. * * This is usually the construct that provides the bulk of the underlying functionality. * Useful for modifications of the underlying construct that are not available at the higher levels. * Override the defaultChild property. * * This should only be used in the cases where the correct * default child is not named 'Resource' or 'Default' as it * should be. * * If you set this to undefined, the default behavior of finding * the child named 'Resource' or 'Default' will be used. * * @returns a construct or undefined if there is no default child * @throws if there is more than one child */ get defaultChild() { return this._actualNode.defaultChild; } /** * Returns the child construct that has the id `Default` or `Resource"`. * * This is usually the construct that provides the bulk of the underlying functionality. * Useful for modifications of the underlying construct that are not available at the higher levels. * Override the defaultChild property. * * This should only be used in the cases where the correct * default child is not named 'Resource' or 'Default' as it * should be. * * If you set this to undefined, the default behavior of finding * the child named 'Resource' or 'Default' will be used. * * @returns a construct or undefined if there is no default child * @throws if there is more than one child */ set defaultChild(value) { this._actualNode.defaultChild = value; } /** * All direct children of this construct. */ get children() { return this._actualNode.children; } /** * Return this construct and all of its children in the given order. */ findAll(order = ConstructOrder.PREORDER) { return this._actualNode.findAll(order); } /** * This can be used to set contextual values. * * Context must be set before any children are added, since children may consult context info during construction. * If the key already exists, it will be overridden. * * @param key The context key. * @param value The context value. */ setContext(key, value) { if (token_1.Token.isUnresolved(key)) { throw new Error('Invalid context key: context keys can\'t include tokens'); } this._actualNode.setContext(key, value); } /** * Retrieves a value from tree context. * * Context is usually initialized at the root, but can be overridden at any point in the tree. * * @param key The context key. * @returns The context value or `undefined` if there is no context value for the key. */ tryGetContext(key) { if (token_1.Token.isUnresolved(key)) { throw new Error('Invalid context key: context keys can\'t include tokens'); } return this._actualNode.tryGetContext(key); } /** * An immutable array of metadata objects associated with this construct. * * This can be used, for example, to implement support for deprecation notices, source mapping, etc. */ get metadata() { return this._actualNode.metadata; } /** * Adds a metadata entry to this construct. * * Entries are arbitrary values and will also include a stack trace to allow tracing back to * the code location for when the entry was added. It can be used, for example, to include source * mapping in CloudFormation templates to improve diagnostics. * * @param type a string denoting the type of metadata. * @param data the value of the metadata (can be a Token). * @param fromFunction a function under which to restrict the metadata entry's stack trace (defaults to this.addMetadata). */ addMetadata(type, data, fromFunction) { this._actualNode.addMetadata(type, data, fromFunction); } /** * (deprecated) DEPRECATED: Adds a { "info": <message> } metadata entry to this construct. * * The toolkit will display the info message when apps are synthesized. * * @param message The info message. * @deprecated use `Annotations.of(construct).addInfo()` */ addInfo(message) { annotations_1.Annotations.of(this.host).addInfo(message); } /** * (deprecated) DEPRECATED: Adds a { "warning": <message> } metadata entry to this construct. * * The toolkit will display the warning when an app is synthesized, or fail * if run in --strict mode. * * @param message The warning message. * @deprecated use `Annotations.of(construct).addWarning()` */ addWarning(message) { annotations_1.Annotations.of(this.host).addWarning(message); } /** * (deprecated) DEPRECATED: Adds an { "error": <message> } metadata entry to this construct. * * The toolkit will fail synthesis when errors are reported. * * @param message The error message. * @deprecated use `Annotations.of(construct).addError()` */ addError(message) { annotations_1.Annotations.of(this.host).addError(message); } /** * (deprecated) DEPRECATED: Applies the aspect to this Constructs node. * * @deprecated This API is going to be removed in the next major version of * the AWS CDK. Please use `Aspects.of(scope).add()` instead. */ applyAspect(aspect) { annotations_1.Annotations.of(this.host).addDeprecation('@aws-cdk/core.ConstructNode.applyAspect', 'Use "Aspects.of(construct).add(aspect)" instead'); aspect_1.Aspects.of(this.host).add(aspect); } /** * All parent scopes of this construct. * * @returns a list of parent scopes. The last element in the list will always * be the current construct and the first element will be the root of the * tree. */ get scopes() { return this._actualNode.scopes; } /** * @returns The root of the construct tree. */ get root() { return this._actualNode.root; } /** * Returns true if this construct or the scopes in which it is defined are locked. */ get locked() { return this._actualNode.locked; } /** * Add an ordering dependency on another Construct. * * All constructs in the dependency's scope will be deployed before any * construct in this construct's scope. */ addDependency(...dependencies) { this._actualNode.addDependency(...dependencies); } /** * Return all dependencies registered on this node or any of its children. */ get dependencies() { return this._actualNode.dependencies; } /** * (experimental) Remove the child with the given name, if present. * * @returns Whether a child with the given name was deleted. * @experimental */ tryRemoveChild(childName) { return this._actualNode.tryRemoveChild(childName); } } exports.ConstructNode = ConstructNode; /** * Separator used to delimit construct path components. */ ConstructNode.PATH_SEP = '/'; function ignore(_x) { return; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RydWN0LWNvbXBhdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNvbnN0cnVjdC1jb21wYXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7O0dBVUc7OztBQUVILHlDQUF5QztBQUN6Qyx5Q0FBeUM7QUFDekMsK0NBQTRDO0FBQzVDLHFDQUE0QztBQUU1QyxtQ0FBZ0M7QUFFaEMsTUFBTSw4QkFBOEIsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLDZCQUE2QixDQUFDLENBQUM7QUFDakYsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLHlCQUF5QixDQUFDLENBQUM7Ozs7Ozs7QUFpQy9ELE1BQWEsU0FBVSxTQUFRLFVBQVUsQ0FBQyxTQUFTOzs7O0lBYWpELFlBQVksS0FBMkIsRUFBRSxFQUFVO1FBQ2pELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ2YsV0FBVyxFQUFFO2dCQUNYLFVBQVUsRUFBRSxDQUFDLENBQXVCLEVBQUUsQ0FBd0IsRUFBRSxDQUFTLEVBQUUsRUFBRSxDQUMzRSxJQUFJLGFBQWEsQ0FBQyxDQUFjLEVBQUUsQ0FBZSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVc7YUFDcEU7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLGFBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUU7WUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsRUFBRSxFQUFFLENBQUMsQ0FBQztTQUM3RDtRQUVELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLElBQUksR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFNUQsTUFBTSxZQUFZLEdBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQztZQUMzRCxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsK0JBQStCLENBQUM7WUFDckYsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQztRQUV0QyxJQUFJLFlBQVksRUFBRTtZQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDL0QsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLGlCQUFpQixDQUFDLCtCQUErQixFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3pGLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLEdBQUcsR0FBRyxDQUFDO1NBQzNDO0lBQ0gsQ0FBQzs7OztJQWxDTSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQU07UUFDOUIsT0FBTyxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxnQkFBZ0IsSUFBSSxDQUFDLENBQUM7SUFDdEUsQ0FBQzs7Ozs7Ozs7O0lBMENTLFVBQVU7UUFDbEIsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDekIsQ0FBQzs7Ozs7Ozs7Ozs7SUFZUyxTQUFTO1FBQ2pCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNqQixDQUFDOzs7Ozs7Ozs7SUFVUyxZQUFZLENBQUMsT0FBcUM7UUFDMUQsSUFBSSxDQUFDLFVBQVUsQ0FBQztZQUNkLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtZQUN0QixRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVM7U0FDNUIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7Ozs7Ozs7O0lBVVMsUUFBUTtRQUNoQixPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7Ozs7Ozs7Ozs7O0lBWVMsT0FBTztRQUNmLE9BQU87SUFDVCxDQUFDOzs7Ozs7Ozs7SUFVUyxVQUFVLENBQUMsT0FBMEI7UUFDN0MsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2xCLENBQUM7Q0FDRjtBQXRIRCw4QkFzSEM7Ozs7QUFLRCxJQUFZLGNBVVg7QUFWRCxXQUFZLGNBQWM7SUFJeEIsMkRBQVEsQ0FBQTtJQUtSLDZEQUFTLENBQUE7QUFDWCxDQUFDLEVBVlcsY0FBYyxHQUFkLHNCQUFjLEtBQWQsc0JBQWMsUUFVekI7Ozs7QUF3QkQsTUFBYSxhQUFhOzs7O0lBZ0V4QixZQUFZLElBQWUsRUFBRSxLQUFpQixFQUFFLEVBQVU7UUFDeEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUV4RCw0RUFBNEU7UUFDNUUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLDhCQUE4QixFQUFFO1lBQ3RFLEtBQUssRUFBRSxJQUFJO1lBQ1gsWUFBWSxFQUFFLEtBQUs7WUFDbkIsVUFBVSxFQUFFLEtBQUs7U0FDbEIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQXBFRDs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFrQjtRQUN0QyxNQUFNLENBQUMsR0FBSSxDQUFTLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsQ0FBQyxFQUFFO1lBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1NBQy9DO1FBRUQsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDOzs7Ozs7OztJQVFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBbUIsRUFBRSxVQUE0QixFQUFHO1FBQ3RFLGlFQUFpRTtRQUNqRSxNQUFNLENBQUMsR0FBMkMsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDakYsT0FBTyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDMUMsQ0FBQzs7Ozs7OztJQU9NLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBbUI7UUFDdkMsaUVBQWlFO1FBQ2pFLE1BQU0sQ0FBQyxHQUEyQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUNuRixDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLDhDQUE4QztRQUN2RSxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDcEMsQ0FBQzs7Ozs7Ozs7SUFRTSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQW1CO1FBQ3hDLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFtQixFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZHLENBQUM7Ozs7OztJQTZCRCxJQUFXLEtBQUs7UUFDZCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBbUIsQ0FBQztJQUM5QyxDQUFDOzs7Ozs7SUFPRCxJQUFXLEVBQUUsS0FBSyxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzs7Ozs7O0lBTy9DLElBQVcsSUFBSSxLQUFhLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDOzs7Ozs7SUFNM0QsSUFBVyxRQUFRLEtBQWEsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Ozs7Ozs7SUFRNUQsWUFBWSxDQUFDLEVBQVUsSUFBNEIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQWUsQ0FBQyxDQUFDLENBQUM7Ozs7Ozs7OztJQVU1RyxTQUFTLENBQUMsRUFBVSxJQUFnQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBZSxDQUFDLENBQUMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBVWpHLElBQVcsWUFBWSxLQUE2QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBMEIsQ0FBQyxDQUFDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQVl6RyxJQUFXLFlBQVksQ0FBQyxLQUE2QixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7Ozs7SUFLakcsSUFBVyxRQUFRLEtBQW1CLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUF3QixDQUFDLENBQUMsQ0FBQzs7OztJQUtsRixPQUFPLENBQUMsUUFBd0IsY0FBYyxDQUFDLFFBQVEsSUFBa0IsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQWlCLENBQUMsQ0FBQyxDQUFDOzs7Ozs7Ozs7O0lBU2xJLFVBQVUsQ0FBQyxHQUFXLEVBQUUsS0FBVTtRQUN2QyxJQUFJLGFBQUssQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyx5REFBeUQsQ0FBQyxDQUFDO1NBQzVFO1FBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzFDLENBQUM7Ozs7Ozs7OztJQVVNLGFBQWEsQ0FBQyxHQUFXO1FBQzlCLElBQUksYUFBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7U0FDNUU7UUFDRCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzdDLENBQUM7Ozs7OztJQU1ELElBQVcsUUFBUSxLQUFLLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFpQyxDQUFDLENBQUMsQ0FBQzs7Ozs7Ozs7Ozs7O0lBWTdFLFdBQVcsQ0FBQyxJQUFZLEVBQUUsSUFBUyxFQUFFLFlBQWtCLElBQVUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7Ozs7Ozs7OztJQVExSCxPQUFPLENBQUMsT0FBZTtRQUM1Qix5QkFBVyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzdDLENBQUM7Ozs7Ozs7Ozs7SUFTTSxVQUFVLENBQUMsT0FBZTtRQUMvQix5QkFBVyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2hELENBQUM7Ozs7Ozs7OztJQVFNLFFBQVEsQ0FBQyxPQUFlO1FBQzdCLHlCQUFXLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDOUMsQ0FBQzs7Ozs7OztJQVFNLFdBQVcsQ0FBQyxNQUFlO1FBQ2hDLHlCQUFXLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxjQUFjLENBQUMseUNBQXlDLEVBQUUsaURBQWlELENBQUMsQ0FBQztRQUN2SSxnQkFBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3BDLENBQUM7Ozs7Ozs7O0lBU0QsSUFBVyxNQUFNLEtBQW1CLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFzQixDQUFDLENBQUMsQ0FBQzs7OztJQUtyRixJQUFXLElBQUksS0FBaUIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQWtCLENBQUMsQ0FBQyxDQUFDOzs7O0lBTTdFLElBQVcsTUFBTSxLQUFLLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDOzs7Ozs7O0lBUWhELGFBQWEsQ0FBQyxHQUFHLFlBQTJCLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7Ozs7SUFLekcsSUFBVyxZQUFZLEtBQW1CLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUE0QixDQUFDLENBQUMsQ0FBQzs7Ozs7OztJQVExRixjQUFjLENBQUMsU0FBaUIsSUFBYSxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQzs7QUEzUjFHLHNDQTRSQzs7OztBQXhSd0Isc0JBQVEsR0FBRyxHQUFHLENBQUM7QUF3VHhDLFNBQVMsTUFBTSxDQUFDLEVBQU87SUFDckIsT0FBTztBQUNULENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnN0cnVjdHMgY29tcGF0aWJpbGl0eSBsYXllci5cbiAqXG4gKiBUaGlzIGZpbGUgaW5jbHVkZXMgdHlwZXMgdGhhdCBzaGFkb3cgdHlwZXMgaW4gdGhlIFwiY29uc3RydWN0c1wiIG1vZHVsZSBpblxuICogb3JkZXIgdG8gYWxsb3cgYmFja3dhcmRzLWNvbXBhdGlibGl0eSBpbiB0aGUgQVdTIENESyB2MS4wIHJlbGVhc2UgbGluZS5cbiAqXG4gKiBUaGVyZSBhcmUgcHJldHR5IHVnbHkgaGFja3MgaGVyZSwgd2hpY2ggbW9zdGx5IGludm9sdmUgZG93bmNhc3RpbmcgdHlwZXMgdG9cbiAqIGFkaGVyZSB0byBsZWdhY3kgQVdTIENESyBBUElzLlxuICpcbiAqIFRoaXMgZmlsZSwgaW4gaXRzIGVudGlyZXR5LCBpcyBleHBlY3RlZCB0byBiZSByZW1vdmVkIGluIHYyLjAuXG4gKi9cblxuaW1wb3J0ICogYXMgY3hhcGkgZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCAqIGFzIGNvbnN0cnVjdHMgZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBBbm5vdGF0aW9ucyB9IGZyb20gJy4vYW5ub3RhdGlvbnMnO1xuaW1wb3J0IHsgSUFzcGVjdCwgQXNwZWN0cyB9IGZyb20gJy4vYXNwZWN0JztcbmltcG9ydCB7IElEZXBlbmRhYmxlIH0gZnJvbSAnLi9kZXBlbmRlbmN5JztcbmltcG9ydCB7IFRva2VuIH0gZnJvbSAnLi90b2tlbic7XG5cbmNvbnN0IE9SSUdJTkFMX0NPTlNUUlVDVF9OT0RFX1NZTUJPTCA9IFN5bWJvbC5mb3IoJ0Bhd3MtY2RrL2NvcmUuQ29uc3RydWN0Tm9kZScpO1xuY29uc3QgQ09OU1RSVUNUX1NZTUJPTCA9IFN5bWJvbC5mb3IoJ0Bhd3MtY2RrL2NvcmUuQ29uc3RydWN0Jyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgSUNvbnN0cnVjdCBleHRlbmRzIGNvbnN0cnVjdHMuSUNvbnN0cnVjdCwgSURlcGVuZGFibGUge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IG5vZGU6IENvbnN0cnVjdE5vZGU7XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIElTeW50aGVzaXNTZXNzaW9uIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIG91dGRpcjogc3RyaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIGFzc2VtYmx5OiBjeGFwaS5DbG91ZEFzc2VtYmx5QnVpbGRlcjtcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBjbGFzcyBDb25zdHJ1Y3QgZXh0ZW5kcyBjb25zdHJ1Y3RzLkNvbnN0cnVjdCBpbXBsZW1lbnRzIElDb25zdHJ1Y3Qge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgaXNDb25zdHJ1Y3QoeDogYW55KTogeCBpcyBDb25zdHJ1Y3Qge1xuICAgIHJldHVybiB0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeCAhPT0gbnVsbCAmJiBDT05TVFJVQ1RfU1lNQk9MIGluIHg7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZWFkb25seSBub2RlOiBDb25zdHJ1Y3ROb2RlO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBjb25zdHJ1Y3RzLkNvbnN0cnVjdCwgaWQ6IHN0cmluZykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgbm9kZUZhY3Rvcnk6IHtcbiAgICAgICAgY3JlYXRlTm9kZTogKGg6IGNvbnN0cnVjdHMuQ29uc3RydWN0LCBzOiBjb25zdHJ1Y3RzLklDb25zdHJ1Y3QsIGk6IHN0cmluZykgPT5cbiAgICAgICAgICBuZXcgQ29uc3RydWN0Tm9kZShoIGFzIENvbnN0cnVjdCwgcyBhcyBJQ29uc3RydWN0LCBpKS5fYWN0dWFsTm9kZSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKGlkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgdXNlIHRva2VucyBpbiBjb25zdHJ1Y3QgSUQ6ICR7aWR9YCk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIENPTlNUUlVDVF9TWU1CT0wsIHsgdmFsdWU6IHRydWUgfSk7XG4gICAgdGhpcy5ub2RlID0gQ29uc3RydWN0Tm9kZS5fdW53cmFwKGNvbnN0cnVjdHMuTm9kZS5vZih0aGlzKSk7XG5cbiAgICBjb25zdCBkaXNhYmxlVHJhY2UgPVxuICAgICAgdGhpcy5ub2RlLnRyeUdldENvbnRleHQoY3hhcGkuRElTQUJMRV9NRVRBREFUQV9TVEFDS19UUkFDRSkgfHxcbiAgICAgIHRoaXMubm9kZS50cnlHZXRDb250ZXh0KGNvbnN0cnVjdHMuQ29uc3RydWN0TWV0YWRhdGEuRElTQUJMRV9TVEFDS19UUkFDRV9JTl9NRVRBREFUQSkgfHxcbiAgICAgIHByb2Nlc3MuZW52LkNES19ESVNBQkxFX1NUQUNLX1RSQUNFO1xuXG4gICAgaWYgKGRpc2FibGVUcmFjZSkge1xuICAgICAgdGhpcy5ub2RlLnNldENvbnRleHQoY3hhcGkuRElTQUJMRV9NRVRBREFUQV9TVEFDS19UUkFDRSwgdHJ1ZSk7XG4gICAgICB0aGlzLm5vZGUuc2V0Q29udGV4dChjb25zdHJ1Y3RzLkNvbnN0cnVjdE1ldGFkYXRhLkRJU0FCTEVfU1RBQ0tfVFJBQ0VfSU5fTUVUQURBVEEsIHRydWUpO1xuICAgICAgcHJvY2Vzcy5lbnYuQ0RLX0RJU0FCTEVfU1RBQ0tfVFJBQ0UgPSAnMSc7XG4gICAgfVxuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwcm90ZWN0ZWQgb25WYWxpZGF0ZSgpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdGUoKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHByb3RlY3RlZCBvblByZXBhcmUoKTogdm9pZCB7XG4gICAgdGhpcy5wcmVwYXJlKCk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwcm90ZWN0ZWQgb25TeW50aGVzaXplKHNlc3Npb246IGNvbnN0cnVjdHMuSVN5bnRoZXNpc1Nlc3Npb24pOiB2b2lkIHtcbiAgICB0aGlzLnN5bnRoZXNpemUoe1xuICAgICAgb3V0ZGlyOiBzZXNzaW9uLm91dGRpcixcbiAgICAgIGFzc2VtYmx5OiBzZXNzaW9uLmFzc2VtYmx5ISxcbiAgICB9KTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHJvdGVjdGVkIHZhbGlkYXRlKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwcm90ZWN0ZWQgcHJlcGFyZSgpOiB2b2lkIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwcm90ZWN0ZWQgc3ludGhlc2l6ZShzZXNzaW9uOiBJU3ludGhlc2lzU2Vzc2lvbik6IHZvaWQge1xuICAgIGlnbm9yZShzZXNzaW9uKTtcbiAgfVxufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBlbnVtIENvbnN0cnVjdE9yZGVyIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBQUkVPUkRFUixcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgUE9TVE9SREVSXG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGludGVyZmFjZSBTeW50aGVzaXNPcHRpb25zIGV4dGVuZHMgY3hhcGkuQXNzZW1ibHlCdWlsZE9wdGlvbnMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgb3V0ZGlyPzogc3RyaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHNraXBWYWxpZGF0aW9uPzogYm9vbGVhbjtcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBjbGFzcyBDb25zdHJ1Y3ROb2RlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFBBVEhfU0VQID0gJy8nO1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB3cmFwcGluZyBgQGF3cy1jZGsvY29yZS5Db25zdHJ1Y3ROb2RlYCBpbnN0YW5jZSBmcm9tIGEgYGNvbnN0cnVjdHMuQ29uc3RydWN0Tm9kZWAuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBfdW53cmFwKGM6IGNvbnN0cnVjdHMuTm9kZSk6IENvbnN0cnVjdE5vZGUge1xuICAgIGNvbnN0IHggPSAoYyBhcyBhbnkpW09SSUdJTkFMX0NPTlNUUlVDVF9OT0RFX1NZTUJPTF07XG4gICAgaWYgKCF4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgQ29uc3RydWN0Tm9kZSB0eXBlJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHg7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIHN5bnRoKG5vZGU6IENvbnN0cnVjdE5vZGUsIG9wdGlvbnM6IFN5bnRoZXNpc09wdGlvbnMgPSB7IH0pOiBjeGFwaS5DbG91ZEFzc2VtYmx5IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgIGNvbnN0IGE6IHR5cGVvZiBpbXBvcnQoJy4vLi9wcml2YXRlL3N5bnRoZXNpcycpID0gcmVxdWlyZSgnLi9wcml2YXRlL3N5bnRoZXNpcycpO1xuICAgIHJldHVybiBhLnN5bnRoZXNpemUobm9kZS5yb290LCBvcHRpb25zKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgcHJlcGFyZShub2RlOiBDb25zdHJ1Y3ROb2RlKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICBjb25zdCBwOiB0eXBlb2YgaW1wb3J0KCcuL3ByaXZhdGUvcHJlcGFyZS1hcHAnKSA9IHJlcXVpcmUoJy4vcHJpdmF0ZS9wcmVwYXJlLWFwcCcpO1xuICAgIHAucHJlcGFyZUFwcChub2RlLnJvb3QpOyAvLyByZXNvbHZlIGNyb3NzIHJlZnMgYW5kIG5lc3RlZCBzdGFjayBhc3NldHMuXG4gICAgcmV0dXJuIG5vZGUuX2FjdHVhbE5vZGUucHJlcGFyZSgpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyB2YWxpZGF0ZShub2RlOiBDb25zdHJ1Y3ROb2RlKTogVmFsaWRhdGlvbkVycm9yW10ge1xuICAgIHJldHVybiBub2RlLl9hY3R1YWxOb2RlLnZhbGlkYXRlKCkubWFwKGUgPT4gKHsgc291cmNlOiBlLnNvdXJjZSBhcyBDb25zdHJ1Y3QsIG1lc3NhZ2U6IGUubWVzc2FnZSB9KSk7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgX2FjdHVhbE5vZGU6IGNvbnN0cnVjdHMuTm9kZTtcblxuICAvKipcbiAgICogVGhlIENvbnN0cnVjdCBjbGFzcyB0aGF0IGhvc3RzIHRoaXMgQVBJLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBDb25zdHJ1Y3Q7XG5cbiAgY29uc3RydWN0b3IoaG9zdDogQ29uc3RydWN0LCBzY29wZTogSUNvbnN0cnVjdCwgaWQ6IHN0cmluZykge1xuICAgIHRoaXMuaG9zdCA9IGhvc3Q7XG4gICAgdGhpcy5fYWN0dWFsTm9kZSA9IG5ldyBjb25zdHJ1Y3RzLk5vZGUoaG9zdCwgc2NvcGUsIGlkKTtcblxuICAgIC8vIHN0b3JlIGEgYmFjayByZWZlcmVuY2Ugb24gX2FjdHVhbE5vZGUgc28gd2UgY2FuIG91ciBDb25zdHJ1Y3ROb2RlIGZyb20gaXRcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcy5fYWN0dWFsTm9kZSwgT1JJR0lOQUxfQ09OU1RSVUNUX05PREVfU1lNQk9MLCB7XG4gICAgICB2YWx1ZTogdGhpcyxcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICB9KTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgZ2V0IHNjb3BlKCk6IElDb25zdHJ1Y3QgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLnNjb3BlIGFzIElDb25zdHJ1Y3Q7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgZ2V0IGlkKCkgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5pZDsgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGdldCBwYXRoKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLnBhdGg7IH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBnZXQgdW5pcXVlSWQoKTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUudW5pcXVlSWQ7IH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHRyeUZpbmRDaGlsZChpZDogc3RyaW5nKTogSUNvbnN0cnVjdCB8IHVuZGVmaW5lZCB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLnRyeUZpbmRDaGlsZChpZCkgYXMgSUNvbnN0cnVjdDsgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGZpbmRDaGlsZChpZDogc3RyaW5nKTogSUNvbnN0cnVjdCB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLmZpbmRDaGlsZChpZCkgYXMgSUNvbnN0cnVjdDsgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgZ2V0IGRlZmF1bHRDaGlsZCgpOiBJQ29uc3RydWN0IHwgdW5kZWZpbmVkIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUuZGVmYXVsdENoaWxkIGFzIElDb25zdHJ1Y3Q7IH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzZXQgZGVmYXVsdENoaWxkKHZhbHVlOiBJQ29uc3RydWN0IHwgdW5kZWZpbmVkKSB7IHRoaXMuX2FjdHVhbE5vZGUuZGVmYXVsdENoaWxkID0gdmFsdWU7IH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgZ2V0IGNoaWxkcmVuKCk6IElDb25zdHJ1Y3RbXSB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLmNoaWxkcmVuIGFzIElDb25zdHJ1Y3RbXTsgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGZpbmRBbGwob3JkZXI6IENvbnN0cnVjdE9yZGVyID0gQ29uc3RydWN0T3JkZXIuUFJFT1JERVIpOiBJQ29uc3RydWN0W10geyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5maW5kQWxsKG9yZGVyKSBhcyBJQ29uc3RydWN0W107IH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHNldENvbnRleHQoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpIHtcbiAgICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKGtleSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb250ZXh0IGtleTogY29udGV4dCBrZXlzIGNhblxcJ3QgaW5jbHVkZSB0b2tlbnMnKTtcbiAgICB9XG4gICAgdGhpcy5fYWN0dWFsTm9kZS5zZXRDb250ZXh0KGtleSwgdmFsdWUpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyB0cnlHZXRDb250ZXh0KGtleTogc3RyaW5nKTogYW55IHtcbiAgICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKGtleSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb250ZXh0IGtleTogY29udGV4dCBrZXlzIGNhblxcJ3QgaW5jbHVkZSB0b2tlbnMnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUudHJ5R2V0Q29udGV4dChrZXkpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGdldCBtZXRhZGF0YSgpIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUubWV0YWRhdGEgYXMgY3hhcGkuTWV0YWRhdGFFbnRyeVtdOyB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGFkZE1ldGFkYXRhKHR5cGU6IHN0cmluZywgZGF0YTogYW55LCBmcm9tRnVuY3Rpb24/OiBhbnkpOiB2b2lkIHsgdGhpcy5fYWN0dWFsTm9kZS5hZGRNZXRhZGF0YSh0eXBlLCBkYXRhLCBmcm9tRnVuY3Rpb24pOyB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGFkZEluZm8obWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gICAgQW5ub3RhdGlvbnMub2YodGhpcy5ob3N0KS5hZGRJbmZvKG1lc3NhZ2UpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBhZGRXYXJuaW5nKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgIEFubm90YXRpb25zLm9mKHRoaXMuaG9zdCkuYWRkV2FybmluZyhtZXNzYWdlKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGFkZEVycm9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIEFubm90YXRpb25zLm9mKHRoaXMuaG9zdCkuYWRkRXJyb3IobWVzc2FnZSk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGFwcGx5QXNwZWN0KGFzcGVjdDogSUFzcGVjdCk6IHZvaWQge1xuICAgIEFubm90YXRpb25zLm9mKHRoaXMuaG9zdCkuYWRkRGVwcmVjYXRpb24oJ0Bhd3MtY2RrL2NvcmUuQ29uc3RydWN0Tm9kZS5hcHBseUFzcGVjdCcsICdVc2UgXCJBc3BlY3RzLm9mKGNvbnN0cnVjdCkuYWRkKGFzcGVjdClcIiBpbnN0ZWFkJyk7XG4gICAgQXNwZWN0cy5vZih0aGlzLmhvc3QpLmFkZChhc3BlY3QpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgZ2V0IHNjb3BlcygpOiBJQ29uc3RydWN0W10geyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5zY29wZXMgYXMgSUNvbnN0cnVjdFtdOyB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgZ2V0IHJvb3QoKTogSUNvbnN0cnVjdCB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLnJvb3QgYXMgSUNvbnN0cnVjdDsgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgZ2V0IGxvY2tlZCgpIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUubG9ja2VkOyB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgYWRkRGVwZW5kZW5jeSguLi5kZXBlbmRlbmNpZXM6IElEZXBlbmRhYmxlW10pIHsgdGhpcy5fYWN0dWFsTm9kZS5hZGREZXBlbmRlbmN5KC4uLmRlcGVuZGVuY2llcyk7IH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBnZXQgZGVwZW5kZW5jaWVzKCk6IERlcGVuZGVuY3lbXSB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLmRlcGVuZGVuY2llcyBhcyBEZXBlbmRlbmN5W107IH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyB0cnlSZW1vdmVDaGlsZChjaGlsZE5hbWU6IHN0cmluZyk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS50cnlSZW1vdmVDaGlsZChjaGlsZE5hbWUpOyB9XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uRXJyb3Ige1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBzb3VyY2U6IENvbnN0cnVjdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgbWVzc2FnZTogc3RyaW5nO1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgRGVwZW5kZW5jeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBzb3VyY2U6IElDb25zdHJ1Y3Q7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHRhcmdldDogSUNvbnN0cnVjdDtcbn1cblxuZnVuY3Rpb24gaWdub3JlKF94OiBhbnkpIHtcbiAgcmV0dXJuO1xufVxuIl19