UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

380 lines 42.8 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 }); const cxschema = require("@aws-cdk/cloud-assembly-schema"); const cxapi = require("@aws-cdk/cx-api"); const constructs = require("constructs"); 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); if (disableTrace) { this.node.setContext(constructs.ConstructMetadata.DISABLE_STACK_TRACE_IN_METADATA, true); } } /** * 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 there 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 there 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) { /** * Depth-first, pre-order */ ConstructOrder[ConstructOrder["PREORDER"] = 0] = "PREORDER"; /** * Depth-first, post-order (leaf nodes first) */ 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._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; } /** * Synthesizes a CloudAssembly from a construct tree. * @param root The root of the construct tree. * @param options Synthesis options. */ static synth(root, options = {}) { const builder = new cxapi.CloudAssemblyBuilder(options.outdir); root._actualNode.synthesize({ outdir: builder.outdir, skipValidation: options.skipValidation, sessionContext: { assembly: builder, }, }); return builder.buildAssembly(options); } /** * Invokes "prepare" on all constructs (depth-first, post-order) in the tree under `node`. * @param node The root node */ static prepare(node) { 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. * * @throws if there is more than one child * @returns a construct or undefined if there is no default child */ get defaultChild() { return this._actualNode.defaultChild; } /** * 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. */ 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 thie 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). If null/undefined, metadata will not be added. * @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); } /** * 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. */ addInfo(message) { this._actualNode.addMetadata(cxschema.ArtifactMetadataEntryType.INFO, message); } /** * 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. */ addWarning(message) { this._actualNode.addMetadata(cxschema.ArtifactMetadataEntryType.WARN, message); } /** * Adds an { "error": <message> } metadata entry to this construct. * The toolkit will fail synthesis when errors are reported. * @param message The error message. */ addError(message) { this._actualNode.addMetadata(cxschema.ArtifactMetadataEntryType.ERROR, message); } /** * Applies the aspect to this Constructs node */ applyAspect(aspect) { this._actualNode.applyAspect(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; } /** * 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RydWN0LWNvbXBhdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNvbnN0cnVjdC1jb21wYXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7O0dBVUc7O0FBRUgsMkRBQTJEO0FBQzNELHlDQUF5QztBQUN6Qyx5Q0FBeUM7QUFHekMsbUNBQWdDO0FBRWhDLE1BQU0sOEJBQThCLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0FBQ2pGLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0FBMkIvRDs7Ozs7R0FLRztBQUNILE1BQWEsU0FBVSxTQUFRLFVBQVUsQ0FBQyxTQUFTO0lBYWpELFlBQVksS0FBZ0IsRUFBRSxFQUFVO1FBQ3RDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ2YsV0FBVyxFQUFFO2dCQUNYLFVBQVUsRUFBRSxDQUFDLENBQXVCLEVBQUUsQ0FBd0IsRUFBRSxDQUFTLEVBQUUsRUFBRSxDQUMzRSxJQUFJLGFBQWEsQ0FBQyxDQUFjLEVBQUUsQ0FBZSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVc7YUFDcEU7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLGFBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQUU7WUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsRUFBRSxFQUFFLENBQUMsQ0FBQztTQUM3RDtRQUVELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLElBQUksR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFNUQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDakYsSUFBSSxZQUFZLEVBQUU7WUFDaEIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLGlCQUFpQixDQUFDLCtCQUErQixFQUFFLElBQUksQ0FBQyxDQUFDO1NBQzFGO0lBQ0gsQ0FBQztJQS9CRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBTTtRQUM5QixPQUFPLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLGdCQUFnQixJQUFJLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBNEJEOzs7Ozs7O09BT0c7SUFDTyxVQUFVO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDTyxTQUFTO1FBQ2pCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNPLFlBQVksQ0FBQyxPQUFxQztRQUMxRCxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQ2QsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQ3RCLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUztTQUM1QixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNPLFFBQVE7UUFDaEIsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ08sT0FBTztRQUNmLE9BQU87SUFDVCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNPLFVBQVUsQ0FBQyxPQUEwQjtRQUM3QyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbEIsQ0FBQztDQUNGO0FBaEhELDhCQWdIQztBQUVEOztHQUVHO0FBQ0gsSUFBWSxjQVVYO0FBVkQsV0FBWSxjQUFjO0lBQ3hCOztPQUVHO0lBQ0gsMkRBQVEsQ0FBQTtJQUVSOztPQUVHO0lBQ0gsNkRBQVMsQ0FBQTtBQUNYLENBQUMsRUFWVyxjQUFjLEdBQWQsc0JBQWMsS0FBZCxzQkFBYyxRQVV6QjtBQW1CRDs7R0FFRztBQUNILE1BQWEsYUFBYTtJQThEeEIsWUFBWSxJQUFlLEVBQUUsS0FBaUIsRUFBRSxFQUFVO1FBQ3hELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFeEQsNEVBQTRFO1FBQzVFLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSw4QkFBOEIsRUFBRTtZQUN0RSxLQUFLLEVBQUUsSUFBSTtZQUNYLFlBQVksRUFBRSxLQUFLO1lBQ25CLFVBQVUsRUFBRSxLQUFLO1NBQ2xCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFqRUQ7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBa0I7UUFDdEMsTUFBTSxDQUFDLEdBQUksQ0FBUyxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLENBQUMsRUFBRTtZQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQztTQUMvQztRQUVELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQW1CLEVBQUUsVUFBNEIsRUFBRztRQUN0RSxNQUFNLE9BQU8sR0FBRyxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFL0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUM7WUFDMUIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQ3RCLGNBQWMsRUFBRSxPQUFPLENBQUMsY0FBYztZQUN0QyxjQUFjLEVBQUU7Z0JBQ2QsUUFBUSxFQUFFLE9BQU87YUFDbEI7U0FDRixDQUFDLENBQUM7UUFFSCxPQUFPLE9BQU8sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7T0FHRztJQUNJLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBbUI7UUFDdkMsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBbUI7UUFDeEMsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQW1CLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdkcsQ0FBQztJQWtCRDs7OztPQUlHO0lBQ0gsSUFBVyxLQUFLO1FBQ2QsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQW1CLENBQUM7SUFDOUMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxJQUFXLEVBQUUsS0FBSyxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUUvQzs7OztPQUlHO0lBQ0gsSUFBVyxJQUFJLEtBQWEsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFFM0Q7OztPQUdHO0lBQ0gsSUFBVyxRQUFRLEtBQWEsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFFbkU7Ozs7O09BS0c7SUFDSSxZQUFZLENBQUMsRUFBVSxJQUE0QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBZSxDQUFDLENBQUMsQ0FBQztJQUVuSDs7Ozs7OztPQU9HO0lBQ0ksU0FBUyxDQUFDLEVBQVUsSUFBZ0IsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQWUsQ0FBQyxDQUFDLENBQUM7SUFFakc7Ozs7Ozs7T0FPRztJQUNILElBQVcsWUFBWSxLQUE2QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBMEIsQ0FBQyxDQUFDLENBQUM7SUFFekc7Ozs7Ozs7OztPQVNHO0lBQ0gsSUFBVyxZQUFZLENBQUMsS0FBNkIsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBRWpHOztPQUVHO0lBQ0gsSUFBVyxRQUFRLEtBQW1CLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUF3QixDQUFDLENBQUMsQ0FBQztJQUV6Rjs7T0FFRztJQUNJLE9BQU8sQ0FBQyxRQUF3QixjQUFjLENBQUMsUUFBUSxJQUFrQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBaUIsQ0FBQyxDQUFDLENBQUM7SUFFekk7Ozs7OztPQU1HO0lBQ0ksVUFBVSxDQUFDLEdBQVcsRUFBRSxLQUFVO1FBQ3ZDLElBQUksYUFBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7U0FDNUU7UUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxhQUFhLENBQUMsR0FBVztRQUM5QixJQUFJLGFBQUssQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyx5REFBeUQsQ0FBQyxDQUFDO1NBQzVFO1FBQ0QsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFBVyxRQUFRLEtBQUssT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQWlDLENBQUMsQ0FBQyxDQUFDO0lBRXBGOzs7Ozs7Ozs7T0FTRztJQUNJLFdBQVcsQ0FBQyxJQUFZLEVBQUUsSUFBUyxFQUFFLFlBQWtCLElBQVUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFakk7Ozs7T0FJRztJQUNJLE9BQU8sQ0FBQyxPQUFlO1FBQzVCLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDakYsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksVUFBVSxDQUFDLE9BQWU7UUFDL0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLHlCQUF5QixDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLFFBQVEsQ0FBQyxPQUFlO1FBQzdCLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDbEYsQ0FBQztJQUVEOztPQUVHO0lBQ0ksV0FBVyxDQUFDLE1BQWUsSUFBVSxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFbkY7Ozs7OztPQU1HO0lBQ0gsSUFBVyxNQUFNLEtBQW1CLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFzQixDQUFDLENBQUMsQ0FBQztJQUVyRjs7T0FFRztJQUNILElBQVcsSUFBSSxLQUFpQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBa0IsQ0FBQyxDQUFDLENBQUM7SUFFN0U7OztPQUdHO0lBQ0gsSUFBVyxNQUFNLEtBQUssT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFFdkQ7Ozs7O09BS0c7SUFDSSxhQUFhLENBQUMsR0FBRyxZQUEyQixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXpHOztPQUVHO0lBQ0gsSUFBVyxZQUFZLEtBQW1CLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUE0QixDQUFDLENBQUMsQ0FBQztJQUVqRzs7Ozs7T0FLRztJQUNJLGNBQWMsQ0FBQyxTQUFpQixJQUFhLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDOztBQS9RMUcsc0NBZ1JDO0FBL1FDOztHQUVHO0FBQ29CLHNCQUFRLEdBQUcsR0FBRyxDQUFDO0FBNFN4QyxTQUFTLE1BQU0sQ0FBQyxFQUFPO0lBQ3JCLE9BQU87QUFDVCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb25zdHJ1Y3RzIGNvbXBhdGliaWxpdHkgbGF5ZXIuXG4gKlxuICogVGhpcyBmaWxlIGluY2x1ZGVzIHR5cGVzIHRoYXQgc2hhZG93IHR5cGVzIGluIHRoZSBcImNvbnN0cnVjdHNcIiBtb2R1bGUgaW5cbiAqIG9yZGVyIHRvIGFsbG93IGJhY2t3YXJkcy1jb21wYXRpYmxpdHkgaW4gdGhlIEFXUyBDREsgdjEuMCByZWxlYXNlIGxpbmUuXG4gKlxuICogVGhlcmUgYXJlIHByZXR0eSB1Z2x5IGhhY2tzIGhlcmUsIHdoaWNoIG1vc3RseSBpbnZvbHZlIGRvd25jYXN0aW5nIHR5cGVzIHRvXG4gKiBhZGhlcmUgdG8gbGVnYWN5IEFXUyBDREsgQVBJcy5cbiAqXG4gKiBUaGlzIGZpbGUsIGluIGl0cyBlbnRpcmV0eSwgaXMgZXhwZWN0ZWQgdG8gYmUgcmVtb3ZlZCBpbiB2Mi4wLlxuICovXG5cbmltcG9ydCAqIGFzIGN4c2NoZW1hIGZyb20gJ0Bhd3MtY2RrL2Nsb3VkLWFzc2VtYmx5LXNjaGVtYSc7XG5pbXBvcnQgKiBhcyBjeGFwaSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IElBc3BlY3QgfSBmcm9tICcuL2FzcGVjdCc7XG5pbXBvcnQgeyBJRGVwZW5kYWJsZSB9IGZyb20gJy4vZGVwZW5kZW5jeSc7XG5pbXBvcnQgeyBUb2tlbiB9IGZyb20gJy4vdG9rZW4nO1xuXG5jb25zdCBPUklHSU5BTF9DT05TVFJVQ1RfTk9ERV9TWU1CT0wgPSBTeW1ib2wuZm9yKCdAYXdzLWNkay9jb3JlLkNvbnN0cnVjdE5vZGUnKTtcbmNvbnN0IENPTlNUUlVDVF9TWU1CT0wgPSBTeW1ib2wuZm9yKCdAYXdzLWNkay9jb3JlLkNvbnN0cnVjdCcpO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBjb25zdHJ1Y3QuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUNvbnN0cnVjdCBleHRlbmRzIGNvbnN0cnVjdHMuSUNvbnN0cnVjdCwgSURlcGVuZGFibGUge1xuICAvKipcbiAgICogVGhlIGNvbnN0cnVjdCB0cmVlIG5vZGUgZm9yIHRoaXMgY29uc3RydWN0LlxuICAgKi9cbiAgcmVhZG9ubHkgbm9kZTogQ29uc3RydWN0Tm9kZTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgc2luZ2xlIHNlc3Npb24gb2Ygc3ludGhlc2lzLiBQYXNzZWQgaW50byBgQ29uc3RydWN0LnN5bnRoZXNpemUoKWAgbWV0aG9kcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJU3ludGhlc2lzU2Vzc2lvbiB7XG4gIC8qKlxuICAgKiBUaGUgb3V0cHV0IGRpcmVjdG9yeSBmb3IgdGhpcyBzeW50aGVzaXMgc2Vzc2lvbi5cbiAgICovXG4gIG91dGRpcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDbG91ZCBhc3NlbWJseSBidWlsZGVyLlxuICAgKi9cbiAgYXNzZW1ibHk6IGN4YXBpLkNsb3VkQXNzZW1ibHlCdWlsZGVyO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIGJ1aWxkaW5nIGJsb2NrIG9mIHRoZSBjb25zdHJ1Y3QgZ3JhcGguXG4gKlxuICogQWxsIGNvbnN0cnVjdHMgYmVzaWRlcyB0aGUgcm9vdCBjb25zdHJ1Y3QgbXVzdCBiZSBjcmVhdGVkIHdpdGhpbiB0aGUgc2NvcGUgb2ZcbiAqIGFub3RoZXIgY29uc3RydWN0LlxuICovXG5leHBvcnQgY2xhc3MgQ29uc3RydWN0IGV4dGVuZHMgY29uc3RydWN0cy5Db25zdHJ1Y3QgaW1wbGVtZW50cyBJQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFJldHVybiB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBDb25zdHJ1Y3RcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgaXNDb25zdHJ1Y3QoeDogYW55KTogeCBpcyBDb25zdHJ1Y3Qge1xuICAgIHJldHVybiB0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeCAhPT0gbnVsbCAmJiBDT05TVFJVQ1RfU1lNQk9MIGluIHg7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGNvbnN0cnVjdCB0cmVlIG5vZGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29uc3RydWN0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG5vZGU6IENvbnN0cnVjdE5vZGU7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgbm9kZUZhY3Rvcnk6IHtcbiAgICAgICAgY3JlYXRlTm9kZTogKGg6IGNvbnN0cnVjdHMuQ29uc3RydWN0LCBzOiBjb25zdHJ1Y3RzLklDb25zdHJ1Y3QsIGk6IHN0cmluZykgPT5cbiAgICAgICAgICBuZXcgQ29uc3RydWN0Tm9kZShoIGFzIENvbnN0cnVjdCwgcyBhcyBJQ29uc3RydWN0LCBpKS5fYWN0dWFsTm9kZSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKGlkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgdXNlIHRva2VucyBpbiBjb25zdHJ1Y3QgSUQ6ICR7aWR9YCk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIENPTlNUUlVDVF9TWU1CT0wsIHsgdmFsdWU6IHRydWUgfSk7XG4gICAgdGhpcy5ub2RlID0gQ29uc3RydWN0Tm9kZS5fdW53cmFwKGNvbnN0cnVjdHMuTm9kZS5vZih0aGlzKSk7XG5cbiAgICBjb25zdCBkaXNhYmxlVHJhY2UgPSB0aGlzLm5vZGUudHJ5R2V0Q29udGV4dChjeGFwaS5ESVNBQkxFX01FVEFEQVRBX1NUQUNLX1RSQUNFKTtcbiAgICBpZiAoZGlzYWJsZVRyYWNlKSB7XG4gICAgICB0aGlzLm5vZGUuc2V0Q29udGV4dChjb25zdHJ1Y3RzLkNvbnN0cnVjdE1ldGFkYXRhLkRJU0FCTEVfU1RBQ0tfVFJBQ0VfSU5fTUVUQURBVEEsIHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGUgY3VycmVudCBjb25zdHJ1Y3QuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNvbnN0cnVjdHMgaW4gb3JkZXIgdG8gcGVyZm9ybVxuICAgKiB2YWxpZGF0aW9uIGxvZ2ljLiBJdCBpcyBjYWxsZWQgb24gYWxsIGNvbnN0cnVjdHMgYmVmb3JlIHN5bnRoZXNpcy5cbiAgICpcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgdmFsaWRhdGlvbiBlcnJvciBtZXNzYWdlcywgb3IgYW4gZW1wdHkgYXJyYXkgaWYgdGhlcmUgdGhlIGNvbnN0cnVjdCBpcyB2YWxpZC5cbiAgICovXG4gIHByb3RlY3RlZCBvblZhbGlkYXRlKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy52YWxpZGF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gZmluYWwgbW9kaWZpY2F0aW9ucyBiZWZvcmUgc3ludGhlc2lzXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNvbnN0cnVjdHMgaW4gb3JkZXIgdG8gcGVyZm9ybVxuICAgKiBmaW5hbCBjaGFuZ2VzIGJlZm9yZSBzeW50aGVzaXMuIHByZXBhcmUoKSB3aWxsIGJlIGNhbGxlZCBhZnRlciBjaGlsZFxuICAgKiBjb25zdHJ1Y3RzIGhhdmUgYmVlbiBwcmVwYXJlZC5cbiAgICpcbiAgICogVGhpcyBpcyBhbiBhZHZhbmNlZCBmcmFtZXdvcmsgZmVhdHVyZS4gT25seSB1c2UgdGhpcyBpZiB5b3VcbiAgICogdW5kZXJzdGFuZCB0aGUgaW1wbGljYXRpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIG9uUHJlcGFyZSgpOiB2b2lkIHtcbiAgICB0aGlzLnByZXBhcmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbGxvd3MgdGhpcyBjb25zdHJ1Y3QgdG8gZW1pdCBhcnRpZmFjdHMgaW50byB0aGUgY2xvdWQgYXNzZW1ibHkgZHVyaW5nIHN5bnRoZXNpcy5cbiAgICpcbiAgICogVGhpcyBtZXRob2QgaXMgdXN1YWxseSBpbXBsZW1lbnRlZCBieSBmcmFtZXdvcmstbGV2ZWwgY29uc3RydWN0cyBzdWNoIGFzIGBTdGFja2AgYW5kIGBBc3NldGBcbiAgICogYXMgdGhleSBwYXJ0aWNpcGF0ZSBpbiBzeW50aGVzaXppbmcgdGhlIGNsb3VkIGFzc2VtYmx5LlxuICAgKlxuICAgKiBAcGFyYW0gc2Vzc2lvbiBUaGUgc3ludGhlc2lzIHNlc3Npb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgb25TeW50aGVzaXplKHNlc3Npb246IGNvbnN0cnVjdHMuSVN5bnRoZXNpc1Nlc3Npb24pOiB2b2lkIHtcbiAgICB0aGlzLnN5bnRoZXNpemUoe1xuICAgICAgb3V0ZGlyOiBzZXNzaW9uLm91dGRpcixcbiAgICAgIGFzc2VtYmx5OiBzZXNzaW9uLmFzc2VtYmx5ISxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGUgY3VycmVudCBjb25zdHJ1Y3QuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNvbnN0cnVjdHMgaW4gb3JkZXIgdG8gcGVyZm9ybVxuICAgKiB2YWxpZGF0aW9uIGxvZ2ljLiBJdCBpcyBjYWxsZWQgb24gYWxsIGNvbnN0cnVjdHMgYmVmb3JlIHN5bnRoZXNpcy5cbiAgICpcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgdmFsaWRhdGlvbiBlcnJvciBtZXNzYWdlcywgb3IgYW4gZW1wdHkgYXJyYXkgaWYgdGhlcmUgdGhlIGNvbnN0cnVjdCBpcyB2YWxpZC5cbiAgICovXG4gIHByb3RlY3RlZCB2YWxpZGF0ZSgpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gZmluYWwgbW9kaWZpY2F0aW9ucyBiZWZvcmUgc3ludGhlc2lzXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGNhbiBiZSBpbXBsZW1lbnRlZCBieSBkZXJpdmVkIGNvbnN0cnVjdHMgaW4gb3JkZXIgdG8gcGVyZm9ybVxuICAgKiBmaW5hbCBjaGFuZ2VzIGJlZm9yZSBzeW50aGVzaXMuIHByZXBhcmUoKSB3aWxsIGJlIGNhbGxlZCBhZnRlciBjaGlsZFxuICAgKiBjb25zdHJ1Y3RzIGhhdmUgYmVlbiBwcmVwYXJlZC5cbiAgICpcbiAgICogVGhpcyBpcyBhbiBhZHZhbmNlZCBmcmFtZXdvcmsgZmVhdHVyZS4gT25seSB1c2UgdGhpcyBpZiB5b3VcbiAgICogdW5kZXJzdGFuZCB0aGUgaW1wbGljYXRpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIHByZXBhcmUoKTogdm9pZCB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLyoqXG4gICAqIEFsbG93cyB0aGlzIGNvbnN0cnVjdCB0byBlbWl0IGFydGlmYWN0cyBpbnRvIHRoZSBjbG91ZCBhc3NlbWJseSBkdXJpbmcgc3ludGhlc2lzLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBpcyB1c3VhbGx5IGltcGxlbWVudGVkIGJ5IGZyYW1ld29yay1sZXZlbCBjb25zdHJ1Y3RzIHN1Y2ggYXMgYFN0YWNrYCBhbmQgYEFzc2V0YFxuICAgKiBhcyB0aGV5IHBhcnRpY2lwYXRlIGluIHN5bnRoZXNpemluZyB0aGUgY2xvdWQgYXNzZW1ibHkuXG4gICAqXG4gICAqIEBwYXJhbSBzZXNzaW9uIFRoZSBzeW50aGVzaXMgc2Vzc2lvbi5cbiAgICovXG4gIHByb3RlY3RlZCBzeW50aGVzaXplKHNlc3Npb246IElTeW50aGVzaXNTZXNzaW9uKTogdm9pZCB7XG4gICAgaWdub3JlKHNlc3Npb24pO1xuICB9XG59XG5cbi8qKlxuICogSW4gd2hhdCBvcmRlciB0byByZXR1cm4gY29uc3RydWN0c1xuICovXG5leHBvcnQgZW51bSBDb25zdHJ1Y3RPcmRlciB7XG4gIC8qKlxuICAgKiBEZXB0aC1maXJzdCwgcHJlLW9yZGVyXG4gICAqL1xuICBQUkVPUkRFUixcblxuICAvKipcbiAgICogRGVwdGgtZmlyc3QsIHBvc3Qtb3JkZXIgKGxlYWYgbm9kZXMgZmlyc3QpXG4gICAqL1xuICBQT1NUT1JERVJcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBzeW50aGVzaXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3ludGhlc2lzT3B0aW9ucyBleHRlbmRzIGN4YXBpLkFzc2VtYmx5QnVpbGRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBvdXRwdXQgZGlyZWN0b3J5IGludG8gd2hpY2ggdG8gc3ludGhlc2l6ZSB0aGUgY2xvdWQgYXNzZW1ibHkuXG4gICAqIEBkZWZhdWx0IC0gY3JlYXRlcyBhIHRlbXBvcmFyeSBkaXJlY3RvcnlcbiAgICovXG4gIHJlYWRvbmx5IG91dGRpcj86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciBzeW50aGVzaXMgc2hvdWxkIHNraXAgdGhlIHZhbGlkYXRpb24gcGhhc2UuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBza2lwVmFsaWRhdGlvbj86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyB0aGUgY29uc3RydWN0IG5vZGUgaW4gdGhlIHNjb3BlIHRyZWUuXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25zdHJ1Y3ROb2RlIHtcbiAgLyoqXG4gICAqIFNlcGFyYXRvciB1c2VkIHRvIGRlbGltaXQgY29uc3RydWN0IHBhdGggY29tcG9uZW50cy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUEFUSF9TRVAgPSAnLyc7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHdyYXBwaW5nIGBAYXdzLWNkay9jb3JlLkNvbnN0cnVjdE5vZGVgIGluc3RhbmNlIGZyb20gYSBgY29uc3RydWN0cy5Db25zdHJ1Y3ROb2RlYC5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIF91bndyYXAoYzogY29uc3RydWN0cy5Ob2RlKTogQ29uc3RydWN0Tm9kZSB7XG4gICAgY29uc3QgeCA9IChjIGFzIGFueSlbT1JJR0lOQUxfQ09OU1RSVUNUX05PREVfU1lNQk9MXTtcbiAgICBpZiAoIXgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBDb25zdHJ1Y3ROb2RlIHR5cGUnKTtcbiAgICB9XG5cbiAgICByZXR1cm4geDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTeW50aGVzaXplcyBhIENsb3VkQXNzZW1ibHkgZnJvbSBhIGNvbnN0cnVjdCB0cmVlLlxuICAgKiBAcGFyYW0gcm9vdCBUaGUgcm9vdCBvZiB0aGUgY29uc3RydWN0IHRyZWUuXG4gICAqIEBwYXJhbSBvcHRpb25zIFN5bnRoZXNpcyBvcHRpb25zLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBzeW50aChyb290OiBDb25zdHJ1Y3ROb2RlLCBvcHRpb25zOiBTeW50aGVzaXNPcHRpb25zID0geyB9KTogY3hhcGkuQ2xvdWRBc3NlbWJseSB7XG4gICAgY29uc3QgYnVpbGRlciA9IG5ldyBjeGFwaS5DbG91ZEFzc2VtYmx5QnVpbGRlcihvcHRpb25zLm91dGRpcik7XG5cbiAgICByb290Ll9hY3R1YWxOb2RlLnN5bnRoZXNpemUoe1xuICAgICAgb3V0ZGlyOiBidWlsZGVyLm91dGRpcixcbiAgICAgIHNraXBWYWxpZGF0aW9uOiBvcHRpb25zLnNraXBWYWxpZGF0aW9uLFxuICAgICAgc2Vzc2lvbkNvbnRleHQ6IHtcbiAgICAgICAgYXNzZW1ibHk6IGJ1aWxkZXIsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRBc3NlbWJseShvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZva2VzIFwicHJlcGFyZVwiIG9uIGFsbCBjb25zdHJ1Y3RzIChkZXB0aC1maXJzdCwgcG9zdC1vcmRlcikgaW4gdGhlIHRyZWUgdW5kZXIgYG5vZGVgLlxuICAgKiBAcGFyYW0gbm9kZSBUaGUgcm9vdCBub2RlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHByZXBhcmUobm9kZTogQ29uc3RydWN0Tm9kZSkge1xuICAgIHJldHVybiBub2RlLl9hY3R1YWxOb2RlLnByZXBhcmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZva2VzIFwidmFsaWRhdGVcIiBvbiBhbGwgY29uc3RydWN0cyBpbiB0aGUgdHJlZSAoZGVwdGgtZmlyc3QsIHByZS1vcmRlcikgYW5kIHJldHVybnNcbiAgICogdGhlIGxpc3Qgb2YgYWxsIGVycm9ycy4gQW4gZW1wdHkgbGlzdCBpbmRpY2F0ZXMgdGhhdCB0aGVyZSBhcmUgbm8gZXJyb3JzLlxuICAgKlxuICAgKiBAcGFyYW0gbm9kZSBUaGUgcm9vdCBub2RlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHZhbGlkYXRlKG5vZGU6IENvbnN0cnVjdE5vZGUpOiBWYWxpZGF0aW9uRXJyb3JbXSB7XG4gICAgcmV0dXJuIG5vZGUuX2FjdHVhbE5vZGUudmFsaWRhdGUoKS5tYXAoZSA9PiAoeyBzb3VyY2U6IGUuc291cmNlIGFzIENvbnN0cnVjdCwgbWVzc2FnZTogZS5tZXNzYWdlIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBfYWN0dWFsTm9kZTogY29uc3RydWN0cy5Ob2RlO1xuXG4gIGNvbnN0cnVjdG9yKGhvc3Q6IENvbnN0cnVjdCwgc2NvcGU6IElDb25zdHJ1Y3QsIGlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9hY3R1YWxOb2RlID0gbmV3IGNvbnN0cnVjdHMuTm9kZShob3N0LCBzY29wZSwgaWQpO1xuXG4gICAgLy8gc3RvcmUgYSBiYWNrIHJlZmVyZW5jZSBvbiBfYWN0dWFsTm9kZSBzbyB3ZSBjYW4gb3VyIENvbnN0cnVjdE5vZGUgZnJvbSBpdFxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLl9hY3R1YWxOb2RlLCBPUklHSU5BTF9DT05TVFJVQ1RfTk9ERV9TWU1CT0wsIHtcbiAgICAgIHZhbHVlOiB0aGlzLFxuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHNjb3BlIGluIHdoaWNoIHRoaXMgY29uc3RydWN0IGlzIGRlZmluZWQuXG4gICAqXG4gICAqIFRoZSB2YWx1ZSBpcyBgdW5kZWZpbmVkYCBhdCB0aGUgcm9vdCBvZiB0aGUgY29uc3RydWN0IHNjb3BlIHRyZWUuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHNjb3BlKCk6IElDb25zdHJ1Y3QgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLnNjb3BlIGFzIElDb25zdHJ1Y3Q7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGlkIG9mIHRoaXMgY29uc3RydWN0IHdpdGhpbiB0aGUgY3VycmVudCBzY29wZS5cbiAgICpcbiAgICogVGhpcyBpcyBhIGEgc2NvcGUtdW5pcXVlIGlkLiBUbyBvYnRhaW4gYW4gYXBwLXVuaXF1ZSBpZCBmb3IgdGhpcyBjb25zdHJ1Y3QsIHVzZSBgdW5pcXVlSWRgLlxuICAgKi9cbiAgcHVibGljIGdldCBpZCgpIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUuaWQ7IH1cblxuICAvKipcbiAgICogVGhlIGZ1bGwsIGFic29sdXRlIHBhdGggb2YgdGhpcyBjb25zdHJ1Y3QgaW4gdGhlIHRyZWUuXG4gICAqXG4gICAqIENvbXBvbmVudHMgYXJlIHNlcGFyYXRlZCBieSAnLycuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHBhdGgoKTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUucGF0aDsgfVxuXG4gIC8qKlxuICAgKiBBIHRyZWUtZ2xvYmFsIHVuaXF1ZSBhbHBoYW51bWVyaWMgaWRlbnRpZmllciBmb3IgdGhpcyBjb25zdHJ1Y3QuXG4gICAqIEluY2x1ZGVzIGFsbCBjb21wb25lbnRzIG9mIHRoZSB0cmVlLlxuICAgKi9cbiAgcHVibGljIGdldCB1bmlxdWVJZCgpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS51bmlxdWVJZDsgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBkaXJlY3QgY2hpbGQgYnkgaWQsIG9yIHVuZGVmaW5lZFxuICAgKlxuICAgKiBAcGFyYW0gaWQgSWRlbnRpZmllciBvZiBkaXJlY3QgY2hpbGRcbiAgICogQHJldHVybnMgdGhlIGNoaWxkIGlmIGZvdW5kLCBvciB1bmRlZmluZWRcbiAgICovXG4gIHB1YmxpYyB0cnlGaW5kQ2hpbGQoaWQ6IHN0cmluZyk6IElDb25zdHJ1Y3QgfCB1bmRlZmluZWQgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS50cnlGaW5kQ2hpbGQoaWQpIGFzIElDb25zdHJ1Y3Q7IH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgZGlyZWN0IGNoaWxkIGJ5IGlkXG4gICAqXG4gICAqIFRocm93cyBhbiBlcnJvciBpZiB0aGUgY2hpbGQgaXMgbm90IGZvdW5kLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgSWRlbnRpZmllciBvZiBkaXJlY3QgY2hpbGRcbiAgICogQHJldHVybnMgQ2hpbGQgd2l0aCB0aGUgZ2l2ZW4gaWQuXG4gICAqL1xuICBwdWJsaWMgZmluZENoaWxkKGlkOiBzdHJpbmcpOiBJQ29uc3RydWN0IHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUuZmluZENoaWxkKGlkKSBhcyBJQ29uc3RydWN0OyB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGNoaWxkIGNvbnN0cnVjdCB0aGF0IGhhcyB0aGUgaWQgYERlZmF1bHRgIG9yIGBSZXNvdXJjZVwiYC5cbiAgICogVGhpcyBpcyB1c3VhbGx5IHRoZSBjb25zdHJ1Y3QgdGhhdCBwcm92aWRlcyB0aGUgYnVsayBvZiB0aGUgdW5kZXJseWluZyBmdW5jdGlvbmFsaXR5LlxuICAgKiBVc2VmdWwgZm9yIG1vZGlmaWNhdGlvbnMgb2YgdGhlIHVuZGVybHlpbmcgY29uc3RydWN0IHRoYXQgYXJlIG5vdCBhdmFpbGFibGUgYXQgdGhlIGhpZ2hlciBsZXZlbHMuXG4gICAqXG4gICAqIEB0aHJvd3MgaWYgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSBjaGlsZFxuICAgKiBAcmV0dXJucyBhIGNvbnN0cnVjdCBvciB1bmRlZmluZWQgaWYgdGhlcmUgaXMgbm8gZGVmYXVsdCBjaGlsZFxuICAgKi9cbiAgcHVibGljIGdldCBkZWZhdWx0Q2hpbGQoKTogSUNvbnN0cnVjdCB8IHVuZGVmaW5lZCB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLmRlZmF1bHRDaGlsZCBhcyBJQ29uc3RydWN0OyB9XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRoZSBkZWZhdWx0Q2hpbGQgcHJvcGVydHkuXG4gICAqXG4gICAqIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbiB0aGUgY2FzZXMgd2hlcmUgdGhlIGNvcnJlY3RcbiAgICogZGVmYXVsdCBjaGlsZCBpcyBub3QgbmFtZWQgJ1Jlc291cmNlJyBvciAnRGVmYXVsdCcgYXMgaXRcbiAgICogc2hvdWxkIGJlLlxuICAgKlxuICAgKiBJZiB5b3Ugc2V0IHRoaXMgdG8gdW5kZWZpbmVkLCB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiBmaW5kaW5nXG4gICAqIHRoZSBjaGlsZCBuYW1lZCAnUmVzb3VyY2UnIG9yICdEZWZhdWx0JyB3aWxsIGJlIHVzZWQuXG4gICAqL1xuICBwdWJsaWMgc2V0IGRlZmF1bHRDaGlsZCh2YWx1ZTogSUNvbnN0cnVjdCB8IHVuZGVmaW5lZCkgeyB0aGlzLl9hY3R1YWxOb2RlLmRlZmF1bHRDaGlsZCA9IHZhbHVlOyB9XG5cbiAgLyoqXG4gICAqIEFsbCBkaXJlY3QgY2hpbGRyZW4gb2YgdGhpcyBjb25zdHJ1Y3QuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGNoaWxkcmVuKCk6IElDb25zdHJ1Y3RbXSB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLmNoaWxkcmVuIGFzIElDb25zdHJ1Y3RbXTsgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhpcyBjb25zdHJ1Y3QgYW5kIGFsbCBvZiBpdHMgY2hpbGRyZW4gaW4gdGhlIGdpdmVuIG9yZGVyXG4gICAqL1xuICBwdWJsaWMgZmluZEFsbChvcmRlcjogQ29uc3RydWN0T3JkZXIgPSBDb25zdHJ1Y3RPcmRlci5QUkVPUkRFUik6IElDb25zdHJ1Y3RbXSB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLmZpbmRBbGwob3JkZXIpIGFzIElDb25zdHJ1Y3RbXTsgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGNhbiBiZSB1c2VkIHRvIHNldCBjb250ZXh0dWFsIHZhbHVlcy5cbiAgICogQ29udGV4dCBtdXN0IGJlIHNldCBiZWZvcmUgYW55IGNoaWxkcmVuIGFyZSBhZGRlZCwgc2luY2UgY2hpbGRyZW4gbWF5IGNvbnN1bHQgY29udGV4dCBpbmZvIGR1cmluZyBjb25zdHJ1Y3Rpb24uXG4gICAqIElmIHRoZSBrZXkgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgb3ZlcnJpZGRlbi5cbiAgICogQHBhcmFtIGtleSBUaGUgY29udGV4dCBrZXlcbiAgICogQHBhcmFtIHZhbHVlIFRoZSBjb250ZXh0IHZhbHVlXG4gICAqL1xuICBwdWJsaWMgc2V0Q29udGV4dChrZXk6IHN0cmluZywgdmFsdWU6IGFueSkge1xuICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQoa2V5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvbnRleHQga2V5OiBjb250ZXh0IGtleXMgY2FuXFwndCBpbmNsdWRlIHRva2VucycpO1xuICAgIH1cbiAgICB0aGlzLl9hY3R1YWxOb2RlLnNldENvbnRleHQoa2V5LCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGEgdmFsdWUgZnJvbSB0cmVlIGNvbnRleHQuXG4gICAqXG4gICAqIENvbnRleHQgaXMgdXN1YWxseSBpbml0aWFsaXplZCBhdCB0aGUgcm9vdCwgYnV0IGNhbiBiZSBvdmVycmlkZGVuIGF0IGFueSBwb2ludCBpbiB0aGUgdHJlZS5cbiAgICpcbiAgICogQHBhcmFtIGtleSBUaGUgY29udGV4dCBrZXlcbiAgICogQHJldHVybnMgVGhlIGNvbnRleHQgdmFsdWUgb3IgYHVuZGVmaW5lZGAgaWYgdGhlcmUgaXMgbm8gY29udGV4dCB2YWx1ZSBmb3IgdGhpZSBrZXkuXG4gICAqL1xuICBwdWJsaWMgdHJ5R2V0Q29udGV4dChrZXk6IHN0cmluZyk6IGFueSB7XG4gICAgaWYgKFRva2VuLmlzVW5yZXNvbHZlZChrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29udGV4dCBrZXk6IGNvbnRleHQga2V5cyBjYW5cXCd0IGluY2x1ZGUgdG9rZW5zJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLnRyeUdldENvbnRleHQoa2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpbW11dGFibGUgYXJyYXkgb2YgbWV0YWRhdGEgb2JqZWN0cyBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb25zdHJ1Y3QuXG4gICAqIFRoaXMgY2FuIGJlIHVzZWQsIGZvciBleGFtcGxlLCB0byBpbXBsZW1lbnQgc3VwcG9ydCBmb3IgZGVwcmVjYXRpb24gbm90aWNlcywgc291cmNlIG1hcHBpbmcsIGV0Yy5cbiAgICovXG4gIHB1YmxpYyBnZXQgbWV0YWRhdGEoKSB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLm1ldGFkYXRhIGFzIGN4YXBpLk1ldGFkYXRhRW50cnlbXTsgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgbWV0YWRhdGEgZW50cnkgdG8gdGhpcyBjb25zdHJ1Y3QuXG4gICAqIEVudHJpZXMgYXJlIGFyYml0cmFyeSB2YWx1ZXMgYW5kIHdpbGwgYWxzbyBpbmNsdWRlIGEgc3RhY2sgdHJhY2UgdG8gYWxsb3cgdHJhY2luZyBiYWNrIHRvXG4gICAqIHRoZSBjb2RlIGxvY2F0aW9uIGZvciB3aGVuIHRoZSBlbnRyeSB3YXMgYWRkZWQuIEl0IGNhbiBiZSB1c2VkLCBmb3IgZXhhbXBsZSwgdG8gaW5jbHVkZSBzb3VyY2VcbiAgICogbWFwcGluZyBpbiBDbG91ZEZvcm1hdGlvbiB0ZW1wbGF0ZXMgdG8gaW1wcm92ZSBkaWFnbm9zdGljcy5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgYSBzdHJpbmcgZGVub3RpbmcgdGhlIHR5cGUgb2YgbWV0YWRhdGFcbiAgICogQHBhcmFtIGRhdGEgdGhlIHZhbHVlIG9mIHRoZSBtZXRhZGF0YSAoY2FuIGJlIGEgVG9rZW4pLiBJZiBudWxsL3VuZGVmaW5lZCwgbWV0YWRhdGEgd2lsbCBub3QgYmUgYWRkZWQuXG4gICAqIEBwYXJhbSBmcm9tRnVuY3Rpb24gYSBmdW5jdGlvbiB1bmRlciB3aGljaCB0byByZXN0cmljdCB0aGUgbWV0YWRhdGEgZW50cnkncyBzdGFjayB0cmFjZSAoZGVmYXVsdHMgdG8gdGhpcy5hZGRNZXRhZGF0YSlcbiAgICovXG4gIHB1YmxpYyBhZGRNZXRhZGF0YSh0eXBlOiBzdHJpbmcsIGRhdGE6IGFueSwgZnJvbUZ1bmN0aW9uPzogYW55KTogdm9pZCB7IHRoaXMuX2FjdHVhbE5vZGUuYWRkTWV0YWRhdGEodHlwZSwgZGF0YSwgZnJvbUZ1bmN0aW9uKTsgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgeyBcImluZm9cIjogPG1lc3NhZ2U+IH0gbWV0YWRhdGEgZW50cnkgdG8gdGhpcyBjb25zdHJ1Y3QuXG4gICAqIFRoZSB0b29sa2l0IHdpbGwgZGlzcGxheSB0aGUgaW5mbyBtZXNzYWdlIHdoZW4gYXBwcyBhcmUgc3ludGhlc2l6ZWQuXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBpbmZvIG1lc3NhZ2UuXG4gICAqL1xuICBwdWJsaWMgYWRkSW5mbyhtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl9hY3R1YWxOb2RlLmFkZE1ldGFkYXRhKGN4c2NoZW1hLkFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUuSU5GTywgbWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHsgXCJ3YXJuaW5nXCI6IDxtZXNzYWdlPiB9IG1ldGFkYXRhIGVudHJ5IHRvIHRoaXMgY29uc3RydWN0LlxuICAgKiBUaGUgdG9vbGtpdCB3aWxsIGRpc3BsYXkgdGhlIHdhcm5pbmcgd2hlbiBhbiBhcHAgaXMgc3ludGhlc2l6ZWQsIG9yIGZhaWxcbiAgICogaWYgcnVuIGluIC0tc3RyaWN0IG1vZGUuXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSB3YXJuaW5nIG1lc3NhZ2UuXG4gICAqL1xuICBwdWJsaWMgYWRkV2FybmluZyhtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl9hY3R1YWxOb2RlLmFkZE1ldGFkYXRhKGN4c2NoZW1hLkFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUuV0FSTiwgbWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhbiB7IFwiZXJyb3JcIjogPG1lc3NhZ2U+IH0gbWV0YWRhdGEgZW50cnkgdG8gdGhpcyBjb25zdHJ1Y3QuXG4gICAqIFRoZSB0b29sa2l0IHdpbGwgZmFpbCBzeW50aGVzaXMgd2hlbiBlcnJvcnMgYXJlIHJlcG9ydGVkLlxuICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZS5cbiAgICovXG4gIHB1YmxpYyBhZGRFcnJvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9hY3R1YWxOb2RlLmFkZE1ldGFkYXRhKGN4c2NoZW1hLkFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUuRVJST1IsIG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgdGhlIGFzcGVjdCB0byB0aGlzIENvbnN0cnVjdHMgbm9kZVxuICAgKi9cbiAgcHVibGljIGFwcGx5QXNwZWN0KGFzcGVjdDogSUFzcGVjdCk6IHZvaWQgeyB0aGlzLl9hY3R1YWxOb2RlLmFwcGx5QXNwZWN0KGFzcGVjdCk7IH1cblxuICAvKipcbiAgICogQWxsIHBhcmVudCBzY29wZXMgb2YgdGhpcyBjb25zdHJ1Y3QuXG4gICAqXG4gICAqIEByZXR1cm5zIGEgbGlzdCBvZiBwYXJlbnQgc2NvcGVzLiBUaGUgbGFzdCBlbGVtZW50IGluIHRoZSBsaXN0IHdpbGwgYWx3YXlzXG4gICAqIGJlIHRoZSBjdXJyZW50IGNvbnN0cnVjdCBhbmQgdGhlIGZpcnN0IGVsZW1lbnQgd2lsbCBiZSB0aGUgcm9vdCBvZiB0aGVcbiAgICogdHJlZS5cbiAgICovXG4gIHB1YmxpYyBnZXQgc2NvcGVzKCk6IElDb25zdHJ1Y3RbXSB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLnNjb3BlcyBhcyBJQ29uc3RydWN0W107IH1cblxuICAvKipcbiAgICogQHJldHVybnMgVGhlIHJvb3Qgb2YgdGhlIGNvbnN0cnVjdCB0cmVlLlxuICAgKi9cbiAgcHVibGljIGdldCByb290KCk6IElDb25zdHJ1Y3QgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5yb290IGFzIElDb25zdHJ1Y3Q7IH1cblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY29uc3RydWN0IG9yIHRoZSBzY29wZXMgaW4gd2hpY2ggaXQgaXMgZGVmaW5lZCBhcmVcbiAgICogbG9ja2VkLlxuICAgKi9cbiAgcHVibGljIGdldCBsb2NrZWQoKSB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLmxvY2tlZDsgfVxuXG4gIC8qKlxuICAgKiBBZGQgYW4gb3JkZXJpbmcgZGVwZW5kZW5jeSBvbiBhbm90aGVyIENvbnN0cnVjdC5cbiAgICpcbiAgICogQWxsIGNvbnN0cnVjdHMgaW4gdGhlIGRlcGVuZGVuY3kncyBzY29wZSB3aWxsIGJlIGRlcGxveWVkIGJlZm9yZSBhbnlcbiAgICogY29uc3RydWN0IGluIHRoaXMgY29uc3RydWN0J3Mgc2NvcGUuXG4gICAqL1xuICBwdWJsaWMgYWRkRGVwZW5kZW5jeSguLi5kZXBlbmRlbmNpZXM6IElEZXBlbmRhYmxlW10pIHsgdGhpcy5fYWN0dWFsTm9kZS5hZGREZXBlbmRlbmN5KC4uLmRlcGVuZGVuY2llcyk7IH1cblxuICAvKipcbiAgICogUmV0dXJuIGFsbCBkZXBlbmRlbmNpZXMgcmVnaXN0ZXJlZCBvbiB0aGlzIG5vZGUgb3IgYW55IG9mIGl0cyBjaGlsZHJlblxuICAgKi9cbiAgcHVibGljIGdldCBkZXBlbmRlbmNpZXMoKTogRGVwZW5kZW5jeVtdIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUuZGVwZW5kZW5jaWVzIGFzIERlcGVuZGVuY3lbXTsgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIGNoaWxkIHdpdGggdGhlIGdpdmVuIG5hbWUsIGlmIHByZXNlbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgYSBjaGlsZCB3aXRoIHRoZSBnaXZlbiBuYW1lIHdhcyBkZWxldGVkLlxuICAgKiBAZXhwZXJpbWVudGFsXG4gICAqL1xuICBwdWJsaWMgdHJ5UmVtb3ZlQ2hpbGQoY2hpbGROYW1lOiBzdHJpbmcpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUudHJ5UmVtb3ZlQ2hpbGQoY2hpbGROYW1lKTsgfVxufVxuXG4vKipcbiAqIEFuIGVycm9yIHJldHVybmVkIGR1cmluZyB0aGUgdmFsaWRhdGlvbiBwaGFzZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uRXJyb3Ige1xuICAvKipcbiAgICogVGhlIGNvbnN0cnVjdCB3aGljaCBlbWl0dGVkIHRoZSBlcnJvci5cbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZTogQ29uc3RydWN0O1xuXG4gIC8qKlxuICAgKiBUaGUgZXJyb3IgbWVzc2FnZS5cbiAgICovXG4gIHJlYWRvbmx5IG1lc3NhZ2U6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIHNpbmdsZSBkZXBlbmRlbmN5XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGVwZW5kZW5jeSB7XG4gIC8qKlxuICAgKiBTb3VyY2UgdGhlIGRlcGVuZGVuY3lcbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZTogSUNvbnN0cnVjdDtcblxuICAvKipcbiAgICogVGFyZ2V0IG9mIHRoZSBkZXBlbmRlbmN5XG4gICAqL1xuICByZWFkb25seSB0YXJnZXQ6IElDb25zdHJ1Y3Q7XG59XG5cbmZ1bmN0aW9uIGlnbm9yZShfeDogYW55KSB7XG4gIHJldHVybjtcbn1cbiJdfQ==