UNPKG

54.9 kBJavaScriptView Raw
1"use strict";
2var _a, _b;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.ConstructNode = exports.ConstructOrder = exports.Construct = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7/**
8 * Constructs compatibility layer.
9 *
10 * This file includes types that shadow types in the "constructs" module in
11 * order to allow backwards-compatiblity in the AWS CDK v1.0 release line.
12 *
13 * There are pretty ugly hacks here, which mostly involve downcasting types to
14 * adhere to legacy AWS CDK APIs.
15 *
16 * This file, in its entirety, is expected to be removed in v2.0.
17 */
18const cxapi = require("@aws-cdk/cx-api");
19const constructs = require("constructs");
20const annotations_1 = require("./annotations");
21const aspect_1 = require("./aspect");
22const token_1 = require("./token");
23const ORIGINAL_CONSTRUCT_NODE_SYMBOL = Symbol.for('@aws-cdk/core.ConstructNode');
24const CONSTRUCT_SYMBOL = Symbol.for('@aws-cdk/core.Construct');
25/**
26 * Represents the building block of the construct graph.
27 *
28 * All constructs besides the root construct must be created within the scope of
29 * another construct.
30 */
31class Construct extends constructs.Construct {
32 constructor(scope, id) {
33 super(scope, id, {
34 nodeFactory: {
35 createNode: (h, s, i) => new ConstructNode(h, s, i)._actualNode,
36 },
37 });
38 if (token_1.Token.isUnresolved(id)) {
39 throw new Error(`Cannot use tokens in construct ID: ${id}`);
40 }
41 Object.defineProperty(this, CONSTRUCT_SYMBOL, { value: true });
42 this.node = ConstructNode._unwrap(constructs.Node.of(this));
43 const disableTrace = this.node.tryGetContext(cxapi.DISABLE_METADATA_STACK_TRACE) ||
44 this.node.tryGetContext(constructs.ConstructMetadata.DISABLE_STACK_TRACE_IN_METADATA) ||
45 process.env.CDK_DISABLE_STACK_TRACE;
46 if (disableTrace) {
47 this.node.setContext(cxapi.DISABLE_METADATA_STACK_TRACE, true);
48 this.node.setContext(constructs.ConstructMetadata.DISABLE_STACK_TRACE_IN_METADATA, true);
49 process.env.CDK_DISABLE_STACK_TRACE = '1';
50 }
51 }
52 /**
53 * Return whether the given object is a Construct
54 */
55 static isConstruct(x) {
56 return typeof x === 'object' && x !== null && CONSTRUCT_SYMBOL in x;
57 }
58 /**
59 * Validate the current construct.
60 *
61 * This method can be implemented by derived constructs in order to perform
62 * validation logic. It is called on all constructs before synthesis.
63 *
64 * @returns An array of validation error messages, or an empty array if the construct is valid.
65 */
66 onValidate() {
67 return this.validate();
68 }
69 /**
70 * Perform final modifications before synthesis
71 *
72 * This method can be implemented by derived constructs in order to perform
73 * final changes before synthesis. prepare() will be called after child
74 * constructs have been prepared.
75 *
76 * This is an advanced framework feature. Only use this if you
77 * understand the implications.
78 */
79 onPrepare() {
80 this.prepare();
81 }
82 /**
83 * Allows this construct to emit artifacts into the cloud assembly during synthesis.
84 *
85 * This method is usually implemented by framework-level constructs such as `Stack` and `Asset`
86 * as they participate in synthesizing the cloud assembly.
87 *
88 * @param session The synthesis session.
89 */
90 onSynthesize(session) {
91 this.synthesize({
92 outdir: session.outdir,
93 assembly: session.assembly,
94 });
95 }
96 /**
97 * Validate the current construct.
98 *
99 * This method can be implemented by derived constructs in order to perform
100 * validation logic. It is called on all constructs before synthesis.
101 *
102 * @returns An array of validation error messages, or an empty array if the construct is valid.
103 */
104 validate() {
105 return [];
106 }
107 /**
108 * Perform final modifications before synthesis
109 *
110 * This method can be implemented by derived constructs in order to perform
111 * final changes before synthesis. prepare() will be called after child
112 * constructs have been prepared.
113 *
114 * This is an advanced framework feature. Only use this if you
115 * understand the implications.
116 */
117 prepare() {
118 return;
119 }
120 /**
121 * Allows this construct to emit artifacts into the cloud assembly during synthesis.
122 *
123 * This method is usually implemented by framework-level constructs such as `Stack` and `Asset`
124 * as they participate in synthesizing the cloud assembly.
125 *
126 * @param session The synthesis session.
127 */
128 synthesize(session) {
129 try {
130 jsiiDeprecationWarnings._aws_cdk_core_ISynthesisSession(session);
131 }
132 catch (error) {
133 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
134 Error.captureStackTrace(error, this.synthesize);
135 }
136 throw error;
137 }
138 ignore(session);
139 }
140}
141exports.Construct = Construct;
142_a = JSII_RTTI_SYMBOL_1;
143Construct[_a] = { fqn: "@aws-cdk/core.Construct", version: "1.204.0" };
144/**
145 * In what order to return constructs
146 */
147var ConstructOrder;
148(function (ConstructOrder) {
149 /**
150 * Depth-first, pre-order
151 */
152 ConstructOrder[ConstructOrder["PREORDER"] = 0] = "PREORDER";
153 /**
154 * Depth-first, post-order (leaf nodes first)
155 */
156 ConstructOrder[ConstructOrder["POSTORDER"] = 1] = "POSTORDER";
157})(ConstructOrder = exports.ConstructOrder || (exports.ConstructOrder = {}));
158/**
159 * Represents the construct node in the scope tree.
160 */
161class ConstructNode {
162 constructor(host, scope, id) {
163 try {
164 jsiiDeprecationWarnings._aws_cdk_core_Construct(host);
165 jsiiDeprecationWarnings._aws_cdk_core_IConstruct(scope);
166 }
167 catch (error) {
168 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
169 Error.captureStackTrace(error, ConstructNode);
170 }
171 throw error;
172 }
173 this.host = host;
174 this._actualNode = new constructs.Node(host, scope, id);
175 // store a back reference on _actualNode so we can our ConstructNode from it
176 Object.defineProperty(this._actualNode, ORIGINAL_CONSTRUCT_NODE_SYMBOL, {
177 value: this,
178 configurable: false,
179 enumerable: false,
180 });
181 }
182 /**
183 * Returns the wrapping `@aws-cdk/core.ConstructNode` instance from a `constructs.ConstructNode`.
184 *
185 * @internal
186 */
187 static _unwrap(c) {
188 const x = c[ORIGINAL_CONSTRUCT_NODE_SYMBOL];
189 if (!x) {
190 throw new Error('invalid ConstructNode type');
191 }
192 return x;
193 }
194 /**
195 * Synthesizes a CloudAssembly from a construct tree.
196 * @param node The root of the construct tree.
197 * @param options Synthesis options.
198 * @deprecated Use `app.synth()` or `stage.synth()` instead
199 */
200 static synth(node, options = {}) {
201 try {
202 jsiiDeprecationWarnings.print("@aws-cdk/core.ConstructNode#synth", "Use `app.synth()` or `stage.synth()` instead");
203 jsiiDeprecationWarnings._aws_cdk_core_ConstructNode(node);
204 jsiiDeprecationWarnings._aws_cdk_core_SynthesisOptions(options);
205 }
206 catch (error) {
207 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
208 Error.captureStackTrace(error, this.synth);
209 }
210 throw error;
211 }
212 // eslint-disable-next-line @typescript-eslint/no-require-imports
213 const a = require('./private/synthesis');
214 return a.synthesize(node.root, options);
215 }
216 /**
217 * Invokes "prepare" on all constructs (depth-first, post-order) in the tree under `node`.
218 * @param node The root node
219 * @deprecated Use `app.synth()` instead
220 */
221 static prepare(node) {
222 try {
223 jsiiDeprecationWarnings.print("@aws-cdk/core.ConstructNode#prepare", "Use `app.synth()` instead");
224 jsiiDeprecationWarnings._aws_cdk_core_ConstructNode(node);
225 }
226 catch (error) {
227 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
228 Error.captureStackTrace(error, this.prepare);
229 }
230 throw error;
231 }
232 // eslint-disable-next-line @typescript-eslint/no-require-imports
233 const p = require('./private/prepare-app');
234 p.prepareApp(node.root); // resolve cross refs and nested stack assets.
235 return node._actualNode.prepare();
236 }
237 /**
238 * Invokes "validate" on all constructs in the tree (depth-first, pre-order) and returns
239 * the list of all errors. An empty list indicates that there are no errors.
240 *
241 * @param node The root node
242 */
243 static validate(node) {
244 try {
245 jsiiDeprecationWarnings._aws_cdk_core_ConstructNode(node);
246 }
247 catch (error) {
248 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
249 Error.captureStackTrace(error, this.validate);
250 }
251 throw error;
252 }
253 return node._actualNode.validate().map(e => ({ source: e.source, message: e.message }));
254 }
255 /**
256 * Returns the scope in which this construct is defined.
257 *
258 * The value is `undefined` at the root of the construct scope tree.
259 */
260 get scope() {
261 return this._actualNode.scope;
262 }
263 /**
264 * The id of this construct within the current scope.
265 *
266 * This is a a scope-unique id. To obtain an app-unique id for this construct, use `uniqueId`.
267 */
268 get id() { return this._actualNode.id; }
269 /**
270 * The full, absolute path of this construct in the tree.
271 *
272 * Components are separated by '/'.
273 */
274 get path() { return this._actualNode.path; }
275 /**
276 * A tree-global unique alphanumeric identifier for this construct. Includes
277 * all components of the tree.
278 *
279 * @deprecated use `node.addr` to obtain a consistent 42 character address for
280 * this node (see https://github.com/aws/constructs/pull/314).
281 * Alternatively, to get a CloudFormation-compatible unique identifier, use
282 * `Names.uniqueId()`.
283 */
284 get uniqueId() { try {
285 jsiiDeprecationWarnings.print("@aws-cdk/core.ConstructNode#uniqueId", "use `node.addr` to obtain a consistent 42 character address for\nthis node (see https://github.com/aws/constructs/pull/314).\nAlternatively, to get a CloudFormation-compatible unique identifier, use\n`Names.uniqueId()`.");
286 }
287 catch (error) {
288 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
289 Error.captureStackTrace(error, jsiiDeprecationWarnings.getPropertyDescriptor(this, "uniqueId").get);
290 }
291 throw error;
292 } return this._actualNode.uniqueId; }
293 /**
294 * Returns an opaque tree-unique address for this construct.
295 *
296 * Addresses are 42 characters hexadecimal strings. They begin with "c8"
297 * followed by 40 lowercase hexadecimal characters (0-9a-f).
298 *
299 * Addresses are calculated using a SHA-1 of the components of the construct
300 * path.
301 *
302 * To enable refactorings of construct trees, constructs with the ID `Default`
303 * will be excluded from the calculation. In those cases constructs in the
304 * same tree may have the same addreess.
305 *
306 * Example value: `c83a2846e506bcc5f10682b564084bca2d275709ee`
307 */
308 get addr() { return this._actualNode.addr; }
309 /**
310 * Return a direct child by id, or undefined
311 *
312 * @param id Identifier of direct child
313 * @returns the child if found, or undefined
314 */
315 tryFindChild(id) { return this._actualNode.tryFindChild(id); }
316 /**
317 * Return a direct child by id
318 *
319 * Throws an error if the child is not found.
320 *
321 * @param id Identifier of direct child
322 * @returns Child with the given id.
323 */
324 findChild(id) { return this._actualNode.findChild(id); }
325 /**
326 * Returns the child construct that has the id `Default` or `Resource"`.
327 * This is usually the construct that provides the bulk of the underlying functionality.
328 * Useful for modifications of the underlying construct that are not available at the higher levels.
329 *
330 * @throws if there is more than one child
331 * @returns a construct or undefined if there is no default child
332 */
333 get defaultChild() { return this._actualNode.defaultChild; }
334 /**
335 * Override the defaultChild property.
336 *
337 * This should only be used in the cases where the correct
338 * default child is not named 'Resource' or 'Default' as it
339 * should be.
340 *
341 * If you set this to undefined, the default behavior of finding
342 * the child named 'Resource' or 'Default' will be used.
343 */
344 set defaultChild(value) { this._actualNode.defaultChild = value; }
345 /**
346 * All direct children of this construct.
347 */
348 get children() { return this._actualNode.children; }
349 /**
350 * Return this construct and all of its children in the given order
351 */
352 findAll(order = ConstructOrder.PREORDER) { try {
353 jsiiDeprecationWarnings._aws_cdk_core_ConstructOrder(order);
354 }
355 catch (error) {
356 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
357 Error.captureStackTrace(error, this.findAll);
358 }
359 throw error;
360 } return this._actualNode.findAll(order); }
361 /**
362 * This can be used to set contextual values.
363 * Context must be set before any children are added, since children may consult context info during construction.
364 * If the key already exists, it will be overridden.
365 * @param key The context key
366 * @param value The context value
367 */
368 setContext(key, value) {
369 if (token_1.Token.isUnresolved(key)) {
370 throw new Error('Invalid context key: context keys can\'t include tokens');
371 }
372 this._actualNode.setContext(key, value);
373 }
374 /**
375 * Retrieves a value from tree context.
376 *
377 * Context is usually initialized at the root, but can be overridden at any point in the tree.
378 *
379 * @param key The context key
380 * @returns The context value or `undefined` if there is no context value for the key.
381 */
382 tryGetContext(key) {
383 if (token_1.Token.isUnresolved(key)) {
384 throw new Error('Invalid context key: context keys can\'t include tokens');
385 }
386 return this._actualNode.tryGetContext(key);
387 }
388 /**
389 * DEPRECATED
390 * @deprecated use `metadataEntry`
391 */
392 get metadata() { try {
393 jsiiDeprecationWarnings.print("@aws-cdk/core.ConstructNode#metadata", "use `metadataEntry`");
394 }
395 catch (error) {
396 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
397 Error.captureStackTrace(error, jsiiDeprecationWarnings.getPropertyDescriptor(this, "metadata").get);
398 }
399 throw error;
400 } return this._actualNode.metadata; }
401 /**
402 * An immutable array of metadata objects associated with this construct.
403 * This can be used, for example, to implement support for deprecation notices, source mapping, etc.
404 */
405 get metadataEntry() { return this._actualNode.metadata; }
406 /**
407 * Adds a metadata entry to this construct.
408 * Entries are arbitrary values and will also include a stack trace to allow tracing back to
409 * the code location for when the entry was added. It can be used, for example, to include source
410 * mapping in CloudFormation templates to improve diagnostics.
411 *
412 * @param type a string denoting the type of metadata
413 * @param data the value of the metadata (can be a Token). If null/undefined, metadata will not be added.
414 * @param fromFunction a function under which to restrict the metadata entry's stack trace (defaults to this.addMetadata)
415 */
416 addMetadata(type, data, fromFunction) { this._actualNode.addMetadata(type, data, fromFunction); }
417 /**
418 * DEPRECATED: Adds a { "info": <message> } metadata entry to this construct.
419 * The toolkit will display the info message when apps are synthesized.
420 * @param message The info message.
421 * @deprecated use `Annotations.of(construct).addInfo()`
422 */
423 addInfo(message) {
424 try {
425 jsiiDeprecationWarnings.print("@aws-cdk/core.ConstructNode#addInfo", "use `Annotations.of(construct).addInfo()`");
426 }
427 catch (error) {
428 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
429 Error.captureStackTrace(error, this.addInfo);
430 }
431 throw error;
432 }
433 annotations_1.Annotations.of(this.host).addInfo(message);
434 }
435 /**
436 * DEPRECATED: Adds a { "warning": <message> } metadata entry to this construct.
437 * The toolkit will display the warning when an app is synthesized, or fail
438 * if run in --strict mode.
439 * @param message The warning message.
440 * @deprecated use `Annotations.of(construct).addWarning()`
441 */
442 addWarning(message) {
443 try {
444 jsiiDeprecationWarnings.print("@aws-cdk/core.ConstructNode#addWarning", "use `Annotations.of(construct).addWarning()`");
445 }
446 catch (error) {
447 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
448 Error.captureStackTrace(error, this.addWarning);
449 }
450 throw error;
451 }
452 annotations_1.Annotations.of(this.host).addWarning(message);
453 }
454 /**
455 * DEPRECATED: Adds an { "error": <message> } metadata entry to this construct.
456 * The toolkit will fail synthesis when errors are reported.
457 * @param message The error message.
458 * @deprecated use `Annotations.of(construct).addError()`
459 */
460 addError(message) {
461 try {
462 jsiiDeprecationWarnings.print("@aws-cdk/core.ConstructNode#addError", "use `Annotations.of(construct).addError()`");
463 }
464 catch (error) {
465 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
466 Error.captureStackTrace(error, this.addError);
467 }
468 throw error;
469 }
470 annotations_1.Annotations.of(this.host).addError(message);
471 }
472 /**
473 * DEPRECATED: Applies the aspect to this Constructs node
474 *
475 * @deprecated This API is going to be removed in the next major version of
476 * the AWS CDK. Please use `Aspects.of(scope).add()` instead.
477 */
478 applyAspect(aspect) {
479 try {
480 jsiiDeprecationWarnings.print("@aws-cdk/core.ConstructNode#applyAspect", "This API is going to be removed in the next major version of\nthe AWS CDK. Please use `Aspects.of(scope).add()` instead.");
481 jsiiDeprecationWarnings._aws_cdk_core_IAspect(aspect);
482 }
483 catch (error) {
484 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
485 Error.captureStackTrace(error, this.applyAspect);
486 }
487 throw error;
488 }
489 annotations_1.Annotations.of(this.host).addDeprecation('@aws-cdk/core.ConstructNode.applyAspect', 'Use "Aspects.of(construct).add(aspect)" instead');
490 aspect_1.Aspects.of(this.host).add(aspect);
491 }
492 /**
493 * Add a validator to this construct Node
494 */
495 addValidation(validation) {
496 this._actualNode.addValidation(validation);
497 }
498 /**
499 * All parent scopes of this construct.
500 *
501 * @returns a list of parent scopes. The last element in the list will always
502 * be the current construct and the first element will be the root of the
503 * tree.
504 */
505 get scopes() { return this._actualNode.scopes; }
506 /**
507 * @returns The root of the construct tree.
508 */
509 get root() { return this._actualNode.root; }
510 /**
511 * Returns true if this construct or the scopes in which it is defined are
512 * locked.
513 */
514 get locked() { return this._actualNode.locked; }
515 /**
516 * Add an ordering dependency on another Construct.
517 *
518 * All constructs in the dependency's scope will be deployed before any
519 * construct in this construct's scope.
520 */
521 addDependency(...dependencies) { try {
522 jsiiDeprecationWarnings._aws_cdk_core_IDependable(dependencies);
523 }
524 catch (error) {
525 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
526 Error.captureStackTrace(error, this.addDependency);
527 }
528 throw error;
529 } this._actualNode.addDependency(...dependencies); }
530 /**
531 * Return all dependencies registered on this node or any of its children
532 */
533 get dependencies() { return this._actualNode.dependencies; }
534 /**
535 * Remove the child with the given name, if present.
536 *
537 * @returns Whether a child with the given name was deleted.
538 */
539 tryRemoveChild(childName) { return this._actualNode.tryRemoveChild(childName); }
540}
541exports.ConstructNode = ConstructNode;
542_b = JSII_RTTI_SYMBOL_1;
543ConstructNode[_b] = { fqn: "@aws-cdk/core.ConstructNode", version: "1.204.0" };
544/**
545 * Separator used to delimit construct path components.
546 */
547ConstructNode.PATH_SEP = '/';
548function ignore(_x) {
549 return;
550}
551//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RydWN0LWNvbXBhdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNvbnN0cnVjdC1jb21wYXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7Ozs7Ozs7Ozs7R0FVRztBQUVILHlDQUF5QztBQUN6Qyx5Q0FBeUM7QUFDekMsK0NBQTRDO0FBQzVDLHFDQUE0QztBQUU1QyxtQ0FBZ0M7QUFFaEMsTUFBTSw4QkFBOEIsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLDZCQUE2QixDQUFDLENBQUM7QUFDakYsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLHlCQUF5QixDQUFDLENBQUM7QUFrQy9EOzs7OztHQUtHO0FBQ0gsTUFBYSxTQUFVLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFhakQsWUFBWSxLQUEyQixFQUFFLEVBQVU7UUFDakQsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDZixXQUFXLEVBQUU7Z0JBQ1gsVUFBVSxFQUFFLENBQUMsQ0FBdUIsRUFBRSxDQUF3QixFQUFFLENBQVMsRUFBRSxFQUFFLENBQzNFLElBQUksYUFBYSxDQUFDLENBQWMsRUFBRSxDQUFlLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVzthQUNwRTtTQUNGLENBQUMsQ0FBQztRQUVILElBQUksYUFBSyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsRUFBRTtZQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLHNDQUFzQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQzdEO1FBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsSUFBSSxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUU1RCxNQUFNLFlBQVksR0FDaEIsSUFB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LENBQUM7UUFDdkksZ0JBQU8sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztLQUNuQztJQUVEOztPQUVHO0lBQ0ksYUFBYSxDQUFDLFVBQWtDO1FBQ3JELElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0tBQzVDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsSUFBVyxNQUFNLEtBQW1CLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFzQixDQUFDLEVBQUU7SUFFckY7O09BRUc7SUFDSCxJQUFXLElBQUksS0FBaUIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQWtCLENBQUMsRUFBRTtJQUU3RTs7O09BR0c7SUFDSCxJQUFXLE1BQU0sS0FBSyxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEVBQUU7SUFFdkQ7Ozs7O09BS0c7SUFDSSxhQUFhLENBQUMsR0FBRyxZQUEyQjs7Ozs7Ozs7TUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFDLEVBQUU7SUFFekc7O09BRUc7SUFDSCxJQUFXLFlBQVksS0FBbUIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQTRCLENBQUMsRUFBRTtJQUVqRzs7OztPQUlHO0lBQ0ksY0FBYyxDQUFDLFNBQWlCLElBQWEsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFOztBQTdUMUcsc0NBOFRDOzs7QUE3VEM7O0dBRUc7QUFDb0Isc0JBQVEsR0FBRyxHQUFHLENBQUM7QUEwVnhDLFNBQVMsTUFBTSxDQUFDLEVBQU87SUFDckIsT0FBTztBQUNULENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbnN0cnVjdHMgY29tcGF0aWJpbGl0eSBsYXllci5cbiAqXG4gKiBUaGlzIGZpbGUgaW5jbHVkZXMgdHlwZXMgdGhhdCBzaGFkb3cgdHlwZXMgaW4gdGhlIFwiY29uc3RydWN0c1wiIG1vZHVsZSBpblxuICogb3JkZXIgdG8gYWxsb3cgYmFja3dhcmRzLWNvbXBhdGlibGl0eSBpbiB0aGUgQVdTIENESyB2MS4wIHJlbGVhc2UgbGluZS5cbiAqXG4gKiBUaGVyZSBhcmUgcHJldHR5IHVnbHkgaGFja3MgaGVyZSwgd2hpY2ggbW9zdGx5IGludm9sdmUgZG93bmNhc3RpbmcgdHlwZXMgdG9cbiAqIGFkaGVyZSB0byBsZWdhY3kgQVdTIENESyBBUElzLlxuICpcbiAqIFRoaXMgZmlsZSwgaW4gaXRzIGVudGlyZXR5LCBpcyBleHBlY3RlZCB0byBiZSByZW1vdmVkIGluIHYyLjAuXG4gKi9cblxuaW1wb3J0ICogYXMgY3hhcGkgZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCAqIGFzIGNvbnN0cnVjdHMgZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBBbm5vdGF0aW9ucyB9IGZyb20gJy4vYW5ub3RhdGlvbnMnO1xuaW1wb3J0IHsgSUFzcGVjdCwgQXNwZWN0cyB9IGZyb20gJy4vYXNwZWN0JztcbmltcG9ydCB7IElEZXBlbmRhYmxlIH0gZnJvbSAnLi9kZXBlbmRlbmN5JztcbmltcG9ydCB7IFRva2VuIH0gZnJvbSAnLi90b2tlbic7XG5cbmNvbnN0IE9SSUdJTkFMX0NPTlNUUlVDVF9OT0RFX1NZTUJPTCA9IFN5bWJvbC5mb3IoJ0Bhd3MtY2RrL2NvcmUuQ29uc3RydWN0Tm9kZScpO1xuY29uc3QgQ09OU1RSVUNUX1NZTUJPTCA9IFN5bWJvbC5mb3IoJ0Bhd3MtY2RrL2NvcmUuQ29uc3RydWN0Jyk7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIGNvbnN0cnVjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJQ29uc3RydWN0IGV4dGVuZHMgY29uc3RydWN0cy5JQ29uc3RydWN0LCBJRGVwZW5kYWJsZSB7XG4gIC8qKlxuICAgKiBUaGUgY29uc3RydWN0IHRyZWUgbm9kZSBmb3IgdGhpcyBjb25zdHJ1Y3QuXG4gICAqL1xuICByZWFkb25seSBub2RlOiBDb25zdHJ1Y3ROb2RlO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBzaW5nbGUgc2Vzc2lvbiBvZiBzeW50aGVzaXMuIFBhc3NlZCBpbnRvIGBDb25zdHJ1Y3Quc3ludGhlc2l6ZSgpYCBtZXRob2RzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElTeW50aGVzaXNTZXNzaW9uIHtcbiAgLyoqXG4gICAqIFRoZSBvdXRwdXQgZGlyZWN0b3J5IGZvciB0aGlzIHN5bnRoZXNpcyBzZXNzaW9uLlxuICAgKi9cbiAgb3V0ZGlyOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENsb3VkIGFzc2VtYmx5IGJ1aWxkZXIuXG4gICAqL1xuICBhc3NlbWJseTogY3hhcGkuQ2xvdWRBc3NlbWJseUJ1aWxkZXI7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHN0YWNrIHNob3VsZCBiZSB2YWxpZGF0ZWQgYWZ0ZXIgc3ludGhlc2lzIHRvIGNoZWNrIGZvciBlcnJvciBtZXRhZGF0YVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGZhbHNlXG4gICAqL1xuICB2YWxpZGF0ZU9uU3ludGg/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIGJ1aWxkaW5nIGJsb2NrIG9mIHRoZSBjb25zdHJ1Y3QgZ3JhcGguXG4gKlxuICogQWxsIGNvbnN0cnVjdHMgYmVzaWRlcyB0aGUgcm9vdCBjb25zdHJ1Y3QgbXVzdCBiZSBjcmVhdGVkIHdpdGhpbiB0aGUgc2NvcGUgb2ZcbiAqIGFub3RoZXIgY29uc3RydWN0LlxuICovXG5leHBvcnQgY2xhc3MgQ29uc3RydWN0IGV4dGVuZHMgY29uc3RydWN0cy5Db25zdHJ1Y3QgaW1wbGVtZW50cyBJQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFJldHVybiB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBDb25zdHJ1Y3RcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgaXNDb25zdHJ1Y3QoeDogYW55KTogeCBpcyBDb25zdHJ1Y3Qge1xuICAgIHJldHVybiB0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeCAhPT0gbnVsbCAmJiBDT05TVFJVQ1RfU1lNQk9MIGluIHg7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGNvbnN0cnVjdCB0cmVlIG5vZGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29uc3RydWN0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG5vZGU6IENvbnN0cnVjdE5vZGU7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LCBpZDogc3RyaW5nKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBub2RlRmFjdG9yeToge1xuICAgICAgICBjcmVhdGVOb2RlOiAoaDogY29uc3RydWN0cy5Db25zdHJ1Y3QsIHM6IGNvbnN0cnVjdHMuSUNvbnN0cnVjdCwgaTogc3RyaW5nKSA9PlxuICAgICAgICAgIG5ldyBDb25zdHJ1Y3ROb2RlKGggYXMgQ29uc3RydWN0LCBzIGFzIElDb25zdHJ1Y3QsIGkpLl9hY3R1YWxOb2RlLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQoaWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCB1c2UgdG9rZW5zIGluIGNvbnN0cnVjdCBJRDogJHtpZH1gKTtcbiAgICB9XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgQ09OU1RSVUNUX1NZTUJPTCwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiAgICB0aGlzLm5vZGUgPSBDb25zdHJ1Y3ROb2RlLl91bndyYXAoY29uc3RydWN0cy5Ob2RlLm9mKHRoaXMpKTtcblxuICAgIGNvbnN0IGRpc2FibGVUcmFjZSA9XG4gICAgICB0aGlzLm5vZGUudHJ5R2V0Q29udGV4dChjeGFwaS5ESVNBQkxFX01FVEFEQVRBX1NUQUNLX1RSQUNFKSB8fFxuICAgICAgdGhpcy5ub2RlLnRyeUdldENvbnRleHQoY29uc3RydWN0cy5Db25zdHJ1Y3RNZXRhZGF0YS5ESVNBQkxFX1NUQUNLX1RSQUNFX0lOX01FVEFEQVRBKSB8fFxuICAgICAgcHJvY2Vzcy5lbnYuQ0RLX0RJU0FCTEVfU1RBQ0tfVFJBQ0U7XG5cbiAgICBpZiAoZGlzYWJsZVRyYWNlKSB7XG4gICAgICB0aGlzLm5vZGUuc2V0Q29udGV4dChjeGFwaS5ESVNBQkxFX01FVEFEQVRBX1NUQUNLX1RSQUNFLCB0cnVlKTtcbiAgICAgIHRoaXMubm9kZS5zZXRDb250ZXh0KGNvbnN0cnVjdHMuQ29uc3RydWN0TWV0YWRhdGEuRElTQUJMRV9TVEFDS19UUkFDRV9JTl9NRVRBREFUQSwgdHJ1ZSk7XG4gICAgICBwcm9jZXNzLmVudi5DREtfRElTQUJMRV9TVEFDS19UUkFDRSA9ICcxJztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhlIGN1cnJlbnQgY29uc3RydWN0LlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjb25zdHJ1Y3RzIGluIG9yZGVyIHRvIHBlcmZvcm1cbiAgICogdmFsaWRhdGlvbiBsb2dpYy4gSXQgaXMgY2FsbGVkIG9uIGFsbCBjb25zdHJ1Y3RzIGJlZm9yZSBzeW50aGVzaXMuXG4gICAqXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHZhbGlkYXRpb24gZXJyb3IgbWVzc2FnZXMsIG9yIGFuIGVtcHR5IGFycmF5IGlmIHRoZSBjb25zdHJ1Y3QgaXMgdmFsaWQuXG4gICAqL1xuICBwcm90ZWN0ZWQgb25WYWxpZGF0ZSgpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIGZpbmFsIG1vZGlmaWNhdGlvbnMgYmVmb3JlIHN5bnRoZXNpc1xuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjb25zdHJ1Y3RzIGluIG9yZGVyIHRvIHBlcmZvcm1cbiAgICogZmluYWwgY2hhbmdlcyBiZWZvcmUgc3ludGhlc2lzLiBwcmVwYXJlKCkgd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgY2hpbGRcbiAgICogY29uc3RydWN0cyBoYXZlIGJlZW4gcHJlcGFyZWQuXG4gICAqXG4gICAqIFRoaXMgaXMgYW4gYWR2YW5jZWQgZnJhbWV3b3JrIGZlYXR1cmUuIE9ubHkgdXNlIHRoaXMgaWYgeW91XG4gICAqIHVuZGVyc3RhbmQgdGhlIGltcGxpY2F0aW9ucy5cbiAgICovXG4gIHByb3RlY3RlZCBvblByZXBhcmUoKTogdm9pZCB7XG4gICAgdGhpcy5wcmVwYXJlKCk7XG4gIH1cblxuICAvKipcbiAgICogQWxsb3dzIHRoaXMgY29uc3RydWN0IHRvIGVtaXQgYXJ0aWZhY3RzIGludG8gdGhlIGNsb3VkIGFzc2VtYmx5IGR1cmluZyBzeW50aGVzaXMuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGlzIHVzdWFsbHkgaW1wbGVtZW50ZWQgYnkgZnJhbWV3b3JrLWxldmVsIGNvbnN0cnVjdHMgc3VjaCBhcyBgU3RhY2tgIGFuZCBgQXNzZXRgXG4gICAqIGFzIHRoZXkgcGFydGljaXBhdGUgaW4gc3ludGhlc2l6aW5nIHRoZSBjbG91ZCBhc3NlbWJseS5cbiAgICpcbiAgICogQHBhcmFtIHNlc3Npb24gVGhlIHN5bnRoZXNpcyBzZXNzaW9uLlxuICAgKi9cbiAgcHJvdGVjdGVkIG9uU3ludGhlc2l6ZShzZXNzaW9uOiBjb25zdHJ1Y3RzLklTeW50aGVzaXNTZXNzaW9uKTogdm9pZCB7XG4gICAgdGhpcy5zeW50aGVzaXplKHtcbiAgICAgIG91dGRpcjogc2Vzc2lvbi5vdXRkaXIsXG4gICAgICBhc3NlbWJseTogc2Vzc2lvbi5hc3NlbWJseSEsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhlIGN1cnJlbnQgY29uc3RydWN0LlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjb25zdHJ1Y3RzIGluIG9yZGVyIHRvIHBlcmZvcm1cbiAgICogdmFsaWRhdGlvbiBsb2dpYy4gSXQgaXMgY2FsbGVkIG9uIGFsbCBjb25zdHJ1Y3RzIGJlZm9yZSBzeW50aGVzaXMuXG4gICAqXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHZhbGlkYXRpb24gZXJyb3IgbWVzc2FnZXMsIG9yIGFuIGVtcHR5IGFycmF5IGlmIHRoZSBjb25zdHJ1Y3QgaXMgdmFsaWQuXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsaWRhdGUoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIGZpbmFsIG1vZGlmaWNhdGlvbnMgYmVmb3JlIHN5bnRoZXNpc1xuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBjYW4gYmUgaW1wbGVtZW50ZWQgYnkgZGVyaXZlZCBjb25zdHJ1Y3RzIGluIG9yZGVyIHRvIHBlcmZvcm1cbiAgICogZmluYWwgY2hhbmdlcyBiZWZvcmUgc3ludGhlc2lzLiBwcmVwYXJlKCkgd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgY2hpbGRcbiAgICogY29uc3RydWN0cyBoYXZlIGJlZW4gcHJlcGFyZWQuXG4gICAqXG4gICAqIFRoaXMgaXMgYW4gYWR2YW5jZWQgZnJhbWV3b3JrIGZlYXR1cmUuIE9ubHkgdXNlIHRoaXMgaWYgeW91XG4gICAqIHVuZGVyc3RhbmQgdGhlIGltcGxpY2F0aW9ucy5cbiAgICovXG4gIHByb3RlY3RlZCBwcmVwYXJlKCk6IHZvaWQge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbGxvd3MgdGhpcyBjb25zdHJ1Y3QgdG8gZW1pdCBhcnRpZmFjdHMgaW50byB0aGUgY2xvdWQgYXNzZW1ibHkgZHVyaW5nIHN5bnRoZXNpcy5cbiAgICpcbiAgICogVGhpcyBtZXRob2QgaXMgdXN1YWxseSBpbXBsZW1lbnRlZCBieSBmcmFtZXdvcmstbGV2ZWwgY29uc3RydWN0cyBzdWNoIGFzIGBTdGFja2AgYW5kIGBBc3NldGBcbiAgICogYXMgdGhleSBwYXJ0aWNpcGF0ZSBpbiBzeW50aGVzaXppbmcgdGhlIGNsb3VkIGFzc2VtYmx5LlxuICAgKlxuICAgKiBAcGFyYW0gc2Vzc2lvbiBUaGUgc3ludGhlc2lzIHNlc3Npb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgc3ludGhlc2l6ZShzZXNzaW9uOiBJU3ludGhlc2lzU2Vzc2lvbik6IHZvaWQge1xuICAgIGlnbm9yZShzZXNzaW9uKTtcbiAgfVxufVxuXG4vKipcbiAqIEluIHdoYXQgb3JkZXIgdG8gcmV0dXJuIGNvbnN0cnVjdHNcbiAqL1xuZXhwb3J0IGVudW0gQ29uc3RydWN0T3JkZXIge1xuICAvKipcbiAgICogRGVwdGgtZmlyc3QsIHByZS1vcmRlclxuICAgKi9cbiAgUFJFT1JERVIsXG5cbiAgLyoqXG4gICAqIERlcHRoLWZpcnN0LCBwb3N0LW9yZGVyIChsZWFmIG5vZGVzIGZpcnN0KVxuICAgKi9cbiAgUE9TVE9SREVSXG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3Igc3ludGhlc2lzLlxuICpcbiAqIEBkZXByZWNhdGVkIHVzZSBgYXBwLnN5bnRoKClgIG9yIGBzdGFnZS5zeW50aCgpYCBpbnN0ZWFkXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3ludGhlc2lzT3B0aW9ucyBleHRlbmRzIGN4YXBpLkFzc2VtYmx5QnVpbGRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBvdXRwdXQgZGlyZWN0b3J5IGludG8gd2hpY2ggdG8gc3ludGhlc2l6ZSB0aGUgY2xvdWQgYXNzZW1ibHkuXG4gICAqIEBkZWZhdWx0IC0gY3JlYXRlcyBhIHRlbXBvcmFyeSBkaXJlY3RvcnlcbiAgICovXG4gIHJlYWRvbmx5IG91dGRpcj86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciBzeW50aGVzaXMgc2hvdWxkIHNraXAgdGhlIHZhbGlkYXRpb24gcGhhc2UuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBza2lwVmFsaWRhdGlvbj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHN0YWNrIHNob3VsZCBiZSB2YWxpZGF0ZWQgYWZ0ZXIgc3ludGhlc2lzIHRvIGNoZWNrIGZvciBlcnJvciBtZXRhZGF0YVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGZhbHNlXG4gICAqL1xuICByZWFkb25seSB2YWxpZGF0ZU9uU3ludGhlc2lzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIHRoZSBjb25zdHJ1Y3Qgbm9kZSBpbiB0aGUgc2NvcGUgdHJlZS5cbiAqL1xuZXhwb3J0IGNsYXNzIENvbnN0cnVjdE5vZGUge1xuICAvKipcbiAgICogU2VwYXJhdG9yIHVzZWQgdG8gZGVsaW1pdCBjb25zdHJ1Y3QgcGF0aCBjb21wb25lbnRzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQQVRIX1NFUCA9ICcvJztcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgd3JhcHBpbmcgYEBhd3MtY2RrL2NvcmUuQ29uc3RydWN0Tm9kZWAgaW5zdGFuY2UgZnJvbSBhIGBjb25zdHJ1Y3RzLkNvbnN0cnVjdE5vZGVgLlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgX3Vud3JhcChjOiBjb25zdHJ1Y3RzLk5vZGUpOiBDb25zdHJ1Y3ROb2RlIHtcbiAgICBjb25zdCB4ID0gKGMgYXMgYW55KVtPUklHSU5BTF9DT05TVFJVQ1RfTk9ERV9TWU1CT0xdO1xuICAgIGlmICgheCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIENvbnN0cnVjdE5vZGUgdHlwZScpO1xuICAgIH1cblxuICAgIHJldHVybiB4O1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bnRoZXNpemVzIGEgQ2xvdWRBc3NlbWJseSBmcm9tIGEgY29uc3RydWN0IHRyZWUuXG4gICAqIEBwYXJhbSBub2RlIFRoZSByb290IG9mIHRoZSBjb25zdHJ1Y3QgdHJlZS5cbiAgICogQHBhcmFtIG9wdGlvbnMgU3ludGhlc2lzIG9wdGlvbnMuXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYXBwLnN5bnRoKClgIG9yIGBzdGFnZS5zeW50aCgpYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHN5bnRoKG5vZGU6IENvbnN0cnVjdE5vZGUsIG9wdGlvbnM6IFN5bnRoZXNpc09wdGlvbnMgPSB7IH0pOiBjeGFwaS5DbG91ZEFzc2VtYmx5IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgIGNvbnN0IGE6IHR5cGVvZiBpbXBvcnQoJy4vLi9wcml2YXRlL3N5bnRoZXNpcycpID0gcmVxdWlyZSgnLi9wcml2YXRlL3N5bnRoZXNpcycpO1xuICAgIHJldHVybiBhLnN5bnRoZXNpemUobm9kZS5yb290LCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZva2VzIFwicHJlcGFyZVwiIG9uIGFsbCBjb25zdHJ1Y3RzIChkZXB0aC1maXJzdCwgcG9zdC1vcmRlcikgaW4gdGhlIHRyZWUgdW5kZXIgYG5vZGVgLlxuICAgKiBAcGFyYW0gbm9kZSBUaGUgcm9vdCBub2RlXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYXBwLnN5bnRoKClgIGluc3RlYWRcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcHJlcGFyZShub2RlOiBDb25zdHJ1Y3ROb2RlKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICBjb25zdCBwOiB0eXBlb2YgaW1wb3J0KCcuL3ByaXZhdGUvcHJlcGFyZS1hcHAnKSA9IHJlcXVpcmUoJy4vcHJpdmF0ZS9wcmVwYXJlLWFwcCcpO1xuICAgIHAucHJlcGFyZUFwcChub2RlLnJvb3QpOyAvLyByZXNvbHZlIGNyb3NzIHJlZnMgYW5kIG5lc3RlZCBzdGFjayBhc3NldHMuXG4gICAgcmV0dXJuIG5vZGUuX2FjdHVhbE5vZGUucHJlcGFyZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZXMgXCJ2YWxpZGF0ZVwiIG9uIGFsbCBjb25zdHJ1Y3RzIGluIHRoZSB0cmVlIChkZXB0aC1maXJzdCwgcHJlLW9yZGVyKSBhbmQgcmV0dXJuc1xuICAgKiB0aGUgbGlzdCBvZiBhbGwgZXJyb3JzLiBBbiBlbXB0eSBsaXN0IGluZGljYXRlcyB0aGF0IHRoZXJlIGFyZSBubyBlcnJvcnMuXG4gICAqXG4gICAqIEBwYXJhbSBub2RlIFRoZSByb290IG5vZGVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgdmFsaWRhdGUobm9kZTogQ29uc3RydWN0Tm9kZSk6IFZhbGlkYXRpb25FcnJvcltdIHtcbiAgICByZXR1cm4gbm9kZS5fYWN0dWFsTm9kZS52YWxpZGF0ZSgpLm1hcChlID0+ICh7IHNvdXJjZTogZS5zb3VyY2UgYXMgQ29uc3RydWN0LCBtZXNzYWdlOiBlLm1lc3NhZ2UgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IF9hY3R1YWxOb2RlOiBjb25zdHJ1Y3RzLk5vZGU7XG5cbiAgLyoqXG4gICAqIFRoZSBDb25zdHJ1Y3QgY2xhc3MgdGhhdCBob3N0cyB0aGlzIEFQSS5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgaG9zdDogQ29uc3RydWN0O1xuXG4gIGNvbnN0cnVjdG9yKGhvc3Q6IENvbnN0cnVjdCwgc2NvcGU6IElDb25zdHJ1Y3QsIGlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmhvc3QgPSBob3N0O1xuICAgIHRoaXMuX2FjdHVhbE5vZGUgPSBuZXcgY29uc3RydWN0cy5Ob2RlKGhvc3QsIHNjb3BlLCBpZCk7XG5cbiAgICAvLyBzdG9yZSBhIGJhY2sgcmVmZXJlbmNlIG9uIF9hY3R1YWxOb2RlIHNvIHdlIGNhbiBvdXIgQ29uc3RydWN0Tm9kZSBmcm9tIGl0XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMuX2FjdHVhbE5vZGUsIE9SSUdJTkFMX0NPTlNUUlVDVF9OT0RFX1NZTUJPTCwge1xuICAgICAgdmFsdWU6IHRoaXMsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc2NvcGUgaW4gd2hpY2ggdGhpcyBjb25zdHJ1Y3QgaXMgZGVmaW5lZC5cbiAgICpcbiAgICogVGhlIHZhbHVlIGlzIGB1bmRlZmluZWRgIGF0IHRoZSByb290IG9mIHRoZSBjb25zdHJ1Y3Qgc2NvcGUgdHJlZS5cbiAgICovXG4gIHB1YmxpYyBnZXQgc2NvcGUoKTogSUNvbnN0cnVjdCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUuc2NvcGUgYXMgSUNvbnN0cnVjdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgaWQgb2YgdGhpcyBjb25zdHJ1Y3Qgd2l0aGluIHRoZSBjdXJyZW50IHNjb3BlLlxuICAgKlxuICAgKiBUaGlzIGlzIGEgYSBzY29wZS11bmlxdWUgaWQuIFRvIG9idGFpbiBhbiBhcHAtdW5pcXVlIGlkIGZvciB0aGlzIGNvbnN0cnVjdCwgdXNlIGB1bmlxdWVJZGAuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGlkKCkgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5pZDsgfVxuXG4gIC8qKlxuICAgKiBUaGUgZnVsbCwgYWJzb2x1dGUgcGF0aCBvZiB0aGlzIGNvbnN0cnVjdCBpbiB0aGUgdHJlZS5cbiAgICpcbiAgICogQ29tcG9uZW50cyBhcmUgc2VwYXJhdGVkIGJ5ICcvJy5cbiAgICovXG4gIHB1YmxpYyBnZXQgcGF0aCgpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5wYXRoOyB9XG5cbiAgLyoqXG4gICAqIEEgdHJlZS1nbG9iYWwgdW5pcXVlIGFscGhhbnVtZXJpYyBpZGVudGlmaWVyIGZvciB0aGlzIGNvbnN0cnVjdC4gSW5jbHVkZXNcbiAgICogYWxsIGNvbXBvbmVudHMgb2YgdGhlIHRyZWUuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBgbm9kZS5hZGRyYCB0byBvYnRhaW4gYSBjb25zaXN0ZW50IDQyIGNoYXJhY3RlciBhZGRyZXNzIGZvclxuICAgKiB0aGlzIG5vZGUgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vYXdzL2NvbnN0cnVjdHMvcHVsbC8zMTQpLlxuICAgKiBBbHRlcm5hdGl2ZWx5LCB0byBnZXQgYSBDbG91ZEZvcm1hdGlvbi1jb21wYXRpYmxlIHVuaXF1ZSBpZGVudGlmaWVyLCB1c2VcbiAgICogYE5hbWVzLnVuaXF1ZUlkKClgLlxuICAgKi9cbiAgcHVibGljIGdldCB1bmlxdWVJZCgpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS51bmlxdWVJZDsgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIG9wYXF1ZSB0cmVlLXVuaXF1ZSBhZGRyZXNzIGZvciB0aGlzIGNvbnN0cnVjdC5cbiAgICpcbiAgICogQWRkcmVzc2VzIGFyZSA0MiBjaGFyYWN0ZXJzIGhleGFkZWNpbWFsIHN0cmluZ3MuIFRoZXkgYmVnaW4gd2l0aCBcImM4XCJcbiAgICogZm9sbG93ZWQgYnkgNDAgbG93ZXJjYXNlIGhleGFkZWNpbWFsIGNoYXJhY3RlcnMgKDAtOWEtZikuXG4gICAqXG4gICAqIEFkZHJlc3NlcyBhcmUgY2FsY3VsYXRlZCB1c2luZyBhIFNIQS0xIG9mIHRoZSBjb21wb25lbnRzIG9mIHRoZSBjb25zdHJ1Y3RcbiAgICogcGF0aC5cbiAgICpcbiAgICogVG8gZW5hYmxlIHJlZmFjdG9yaW5ncyBvZiBjb25zdHJ1Y3QgdHJlZXMsIGNvbnN0cnVjdHMgd2l0aCB0aGUgSUQgYERlZmF1bHRgXG4gICAqIHdpbGwgYmUgZXhjbHVkZWQgZnJvbSB0aGUgY2FsY3VsYXRpb24uIEluIHRob3NlIGNhc2VzIGNvbnN0cnVjdHMgaW4gdGhlXG4gICAqIHNhbWUgdHJlZSBtYXkgaGF2ZSB0aGUgc2FtZSBhZGRyZWVzcy5cbiAgICpcbiAgICogRXhhbXBsZSB2YWx1ZTogYGM4M2EyODQ2ZTUwNmJjYzVmMTA2ODJiNTY0MDg0YmNhMmQyNzU3MDllZWBcbiAgICovXG4gIHB1YmxpYyBnZXQgYWRkcigpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5hZGRyOyB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGRpcmVjdCBjaGlsZCBieSBpZCwgb3IgdW5kZWZpbmVkXG4gICAqXG4gICAqIEBwYXJhbSBpZCBJZGVudGlmaWVyIG9mIGRpcmVjdCBjaGlsZFxuICAgKiBAcmV0dXJucyB0aGUgY2hpbGQgaWYgZm91bmQsIG9yIHVuZGVmaW5lZFxuICAgKi9cbiAgcHVibGljIHRyeUZpbmRDaGlsZChpZDogc3RyaW5nKTogSUNvbnN0cnVjdCB8IHVuZGVmaW5lZCB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLnRyeUZpbmRDaGlsZChpZCkgYXMgSUNvbnN0cnVjdDsgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBkaXJlY3QgY2hpbGQgYnkgaWRcbiAgICpcbiAgICogVGhyb3dzIGFuIGVycm9yIGlmIHRoZSBjaGlsZCBpcyBub3QgZm91bmQuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBJZGVudGlmaWVyIG9mIGRpcmVjdCBjaGlsZFxuICAgKiBAcmV0dXJucyBDaGlsZCB3aXRoIHRoZSBnaXZlbiBpZC5cbiAgICovXG4gIHB1YmxpYyBmaW5kQ2hpbGQoaWQ6IHN0cmluZyk6IElDb25zdHJ1Y3QgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5maW5kQ2hpbGQoaWQpIGFzIElDb25zdHJ1Y3Q7IH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY2hpbGQgY29uc3RydWN0IHRoYXQgaGFzIHRoZSBpZCBgRGVmYXVsdGAgb3IgYFJlc291cmNlXCJgLlxuICAgKiBUaGlzIGlzIHVzdWFsbHkgdGhlIGNvbnN0cnVjdCB0aGF0IHByb3ZpZGVzIHRoZSBidWxrIG9mIHRoZSB1bmRlcmx5aW5nIGZ1bmN0aW9uYWxpdHkuXG4gICAqIFVzZWZ1bCBmb3IgbW9kaWZpY2F0aW9ucyBvZiB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3QgdGhhdCBhcmUgbm90IGF2YWlsYWJsZSBhdCB0aGUgaGlnaGVyIGxldmVscy5cbiAgICpcbiAgICogQHRocm93cyBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGNoaWxkXG4gICAqIEByZXR1cm5zIGEgY29uc3RydWN0IG9yIHVuZGVmaW5lZCBpZiB0aGVyZSBpcyBubyBkZWZhdWx0IGNoaWxkXG4gICAqL1xuICBwdWJsaWMgZ2V0IGRlZmF1bHRDaGlsZCgpOiBJQ29uc3RydWN0IHwgdW5kZWZpbmVkIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUuZGVmYXVsdENoaWxkIGFzIElDb25zdHJ1Y3Q7IH1cblxuICAvKipcbiAgICogT3ZlcnJpZGUgdGhlIGRlZmF1bHRDaGlsZCBwcm9wZXJ0eS5cbiAgICpcbiAgICogVGhpcyBzaG91bGQgb25seSBiZSB1c2VkIGluIHRoZSBjYXNlcyB3aGVyZSB0aGUgY29ycmVjdFxuICAgKiBkZWZhdWx0IGNoaWxkIGlzIG5vdCBuYW1lZCAnUmVzb3VyY2UnIG9yICdEZWZhdWx0JyBhcyBpdFxuICAgKiBzaG91bGQgYmUuXG4gICAqXG4gICAqIElmIHlvdSBzZXQgdGhpcyB0byB1bmRlZmluZWQsIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIGZpbmRpbmdcbiAgICogdGhlIGNoaWxkIG5hbWVkICdSZXNvdXJjZScgb3IgJ0RlZmF1bHQnIHdpbGwgYmUgdXNlZC5cbiAgICovXG4gIHB1YmxpYyBzZXQgZGVmYXVsdENoaWxkKHZhbHVlOiBJQ29uc3RydWN0IHwgdW5kZWZpbmVkKSB7IHRoaXMuX2FjdHVhbE5vZGUuZGVmYXVsdENoaWxkID0gdmFsdWU7IH1cblxuICAvKipcbiAgICogQWxsIGRpcmVjdCBjaGlsZHJlbiBvZiB0aGlzIGNvbnN0cnVjdC5cbiAgICovXG4gIHB1YmxpYyBnZXQgY2hpbGRyZW4oKTogSUNvbnN0cnVjdFtdIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUuY2hpbGRyZW4gYXMgSUNvbnN0cnVjdFtdOyB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGlzIGNvbnN0cnVjdCBhbmQgYWxsIG9mIGl0cyBjaGlsZHJlbiBpbiB0aGUgZ2l2ZW4gb3JkZXJcbiAgICovXG4gIHB1YmxpYyBmaW5kQWxsKG9yZGVyOiBDb25zdHJ1Y3RPcmRlciA9IENvbnN0cnVjdE9yZGVyLlBSRU9SREVSKTogSUNvbnN0cnVjdFtdIHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUuZmluZEFsbChvcmRlcikgYXMgSUNvbnN0cnVjdFtdOyB9XG5cbiAgLyoqXG4gICAqIFRoaXMgY2FuIGJlIHVzZWQgdG8gc2V0IGNvbnRleHR1YWwgdmFsdWVzLlxuICAgKiBDb250ZXh0IG11c3QgYmUgc2V0IGJlZm9yZSBhbnkgY2hpbGRyZW4gYXJlIGFkZGVkLCBzaW5jZSBjaGlsZHJlbiBtYXkgY29uc3VsdCBjb250ZXh0IGluZm8gZHVyaW5nIGNvbnN0cnVjdGlvbi5cbiAgICogSWYgdGhlIGtleSBhbHJlYWR5IGV4aXN0cywgaXQgd2lsbCBiZSBvdmVycmlkZGVuLlxuICAgKiBAcGFyYW0ga2V5IFRoZSBjb250ZXh0IGtleVxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIGNvbnRleHQgdmFsdWVcbiAgICovXG4gIHB1YmxpYyBzZXRDb250ZXh0KGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSB7XG4gICAgaWYgKFRva2VuLmlzVW5yZXNvbHZlZChrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29udGV4dCBrZXk6IGNvbnRleHQga2V5cyBjYW5cXCd0IGluY2x1ZGUgdG9rZW5zJyk7XG4gICAgfVxuICAgIHRoaXMuX2FjdHVhbE5vZGUuc2V0Q29udGV4dChrZXksIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgYSB2YWx1ZSBmcm9tIHRyZWUgY29udGV4dC5cbiAgICpcbiAgICogQ29udGV4dCBpcyB1c3VhbGx5IGluaXRpYWxpemVkIGF0IHRoZSByb290LCBidXQgY2FuIGJlIG92ZXJyaWRkZW4gYXQgYW55IHBvaW50IGluIHRoZSB0cmVlLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IFRoZSBjb250ZXh0IGtleVxuICAgKiBAcmV0dXJucyBUaGUgY29udGV4dCB2YWx1ZSBvciBgdW5kZWZpbmVkYCBpZiB0aGVyZSBpcyBubyBjb250ZXh0IHZhbHVlIGZvciB0aGUga2V5LlxuICAgKi9cbiAgcHVibGljIHRyeUdldENvbnRleHQoa2V5OiBzdHJpbmcpOiBhbnkge1xuICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQoa2V5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvbnRleHQga2V5OiBjb250ZXh0IGtleXMgY2FuXFwndCBpbmNsdWRlIHRva2VucycpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS50cnlHZXRDb250ZXh0KGtleSk7XG4gIH1cblxuICAvKipcbiAgICogREVQUkVDQVRFRFxuICAgKiBAZGVwcmVjYXRlZCB1c2UgYG1ldGFkYXRhRW50cnlgXG4gICAqL1xuICBwdWJsaWMgZ2V0IG1ldGFkYXRhKCkgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5tZXRhZGF0YSBhcyBjeGFwaS5NZXRhZGF0YUVudHJ5W107IH1cblxuICAvKipcbiAgICogQW4gaW1tdXRhYmxlIGFycmF5IG9mIG1ldGFkYXRhIG9iamVjdHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29uc3RydWN0LlxuICAgKiBUaGlzIGNhbiBiZSB1c2VkLCBmb3IgZXhhbXBsZSwgdG8gaW1wbGVtZW50IHN1cHBvcnQgZm9yIGRlcHJlY2F0aW9uIG5vdGljZXMsIHNvdXJjZSBtYXBwaW5nLCBldGMuXG4gICAqL1xuICBwdWJsaWMgZ2V0IG1ldGFkYXRhRW50cnkoKSB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLm1ldGFkYXRhOyB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBtZXRhZGF0YSBlbnRyeSB0byB0aGlzIGNvbnN0cnVjdC5cbiAgICogRW50cmllcyBhcmUgYXJiaXRyYXJ5IHZhbHVlcyBhbmQgd2lsbCBhbHNvIGluY2x1ZGUgYSBzdGFjayB0cmFjZSB0byBhbGxvdyB0cmFjaW5nIGJhY2sgdG9cbiAgICogdGhlIGNvZGUgbG9jYXRpb24gZm9yIHdoZW4gdGhlIGVudHJ5IHdhcyBhZGRlZC4gSXQgY2FuIGJlIHVzZWQsIGZvciBleGFtcGxlLCB0byBpbmNsdWRlIHNvdXJjZVxuICAgKiBtYXBwaW5nIGluIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlcyB0byBpbXByb3ZlIGRpYWdub3N0aWNzLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSBhIHN0cmluZyBkZW5vdGluZyB0aGUgdHlwZSBvZiBtZXRhZGF0YVxuICAgKiBAcGFyYW0gZGF0YSB0aGUgdmFsdWUgb2YgdGhlIG1ldGFkYXRhIChjYW4gYmUgYSBUb2tlbikuIElmIG51bGwvdW5kZWZpbmVkLCBtZXRhZGF0YSB3aWxsIG5vdCBiZSBhZGRlZC5cbiAgICogQHBhcmFtIGZyb21GdW5jdGlvbiBhIGZ1bmN0aW9uIHVuZGVyIHdoaWNoIHRvIHJlc3RyaWN0IHRoZSBtZXRhZGF0YSBlbnRyeSdzIHN0YWNrIHRyYWNlIChkZWZhdWx0cyB0byB0aGlzLmFkZE1ldGFkYXRhKVxuICAgKi9cbiAgcHVibGljIGFkZE1ldGFkYXRhKHR5cGU6IHN0cmluZywgZGF0YTogYW55LCBmcm9tRnVuY3Rpb24/OiBhbnkpOiB2b2lkIHsgdGhpcy5fYWN0dWFsTm9kZS5hZGRNZXRhZGF0YSh0eXBlLCBkYXRhLCBmcm9tRnVuY3Rpb24pOyB9XG5cbiAgLyoqXG4gICAqIERFUFJFQ0FURUQ6IEFkZHMgYSB7IFwiaW5mb1wiOiA8bWVzc2FnZT4gfSBtZXRhZGF0YSBlbnRyeSB0byB0aGlzIGNvbnN0cnVjdC5cbiAgICogVGhlIHRvb2xraXQgd2lsbCBkaXNwbGF5IHRoZSBpbmZvIG1lc3NhZ2Ugd2hlbiBhcHBzIGFyZSBzeW50aGVzaXplZC5cbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGluZm8gbWVzc2FnZS5cbiAgICogQGRlcHJlY2F0ZWQgdXNlIGBBbm5vdGF0aW9ucy5vZihjb25zdHJ1Y3QpLmFkZEluZm8oKWBcbiAgICovXG4gIHB1YmxpYyBhZGRJbmZvKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgIEFubm90YXRpb25zLm9mKHRoaXMuaG9zdCkuYWRkSW5mbyhtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBERVBSRUNBVEVEOiBBZGRzIGEgeyBcIndhcm5pbmdcIjogPG1lc3NhZ2U+IH0gbWV0YWRhdGEgZW50cnkgdG8gdGhpcyBjb25zdHJ1Y3QuXG4gICAqIFRoZSB0b29sa2l0IHdpbGwgZGlzcGxheSB0aGUgd2FybmluZyB3aGVuIGFuIGFwcCBpcyBzeW50aGVzaXplZCwgb3IgZmFpbFxuICAgKiBpZiBydW4gaW4gLS1zdHJpY3QgbW9kZS5cbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIHdhcm5pbmcgbWVzc2FnZS5cbiAgICogQGRlcHJlY2F0ZWQgdXNlIGBBbm5vdGF0aW9ucy5vZihjb25zdHJ1Y3QpLmFkZFdhcm5pbmcoKWBcbiAgICovXG4gIHB1YmxpYyBhZGRXYXJuaW5nKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgIEFubm90YXRpb25zLm9mKHRoaXMuaG9zdCkuYWRkV2FybmluZyhtZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBERVBSRUNBVEVEOiBBZGRzIGFuIHsgXCJlcnJvclwiOiA8bWVzc2FnZT4gfSBtZXRhZGF0YSBlbnRyeSB0byB0aGlzIGNvbnN0cnVjdC5cbiAgICogVGhlIHRvb2xraXQgd2lsbCBmYWlsIHN5bnRoZXNpcyB3aGVuIGVycm9ycyBhcmUgcmVwb3J0ZWQuXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLlxuICAgKiBAZGVwcmVjYXRlZCB1c2UgYEFubm90YXRpb25zLm9mKGNvbnN0cnVjdCkuYWRkRXJyb3IoKWBcbiAgICovXG4gIHB1YmxpYyBhZGRFcnJvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBBbm5vdGF0aW9ucy5vZih0aGlzLmhvc3QpLmFkZEVycm9yKG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIERFUFJFQ0FURUQ6IEFwcGxpZXMgdGhlIGFzcGVjdCB0byB0aGlzIENvbnN0cnVjdHMgbm9kZVxuICAgKlxuICAgKiBAZGVwcmVjYXRlZCBUaGlzIEFQSSBpcyBnb2luZyB0byBiZSByZW1vdmVkIGluIHRoZSBuZXh0IG1ham9yIHZlcnNpb24gb2ZcbiAgICogdGhlIEFXUyBDREsuIFBsZWFzZSB1c2UgYEFzcGVjdHMub2Yoc2NvcGUpLmFkZCgpYCBpbnN0ZWFkLlxuICAgKi9cbiAgcHVibGljIGFwcGx5QXNwZWN0KGFzcGVjdDogSUFzcGVjdCk6IHZvaWQge1xuICAgIEFubm90YXRpb25zLm9mKHRoaXMuaG9zdCkuYWRkRGVwcmVjYXRpb24oJ0Bhd3MtY2RrL2NvcmUuQ29uc3RydWN0Tm9kZS5hcHBseUFzcGVjdCcsICdVc2UgXCJBc3BlY3RzLm9mKGNvbnN0cnVjdCkuYWRkKGFzcGVjdClcIiBpbnN0ZWFkJyk7XG4gICAgQXNwZWN0cy5vZih0aGlzLmhvc3QpLmFkZChhc3BlY3QpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIHZhbGlkYXRvciB0byB0aGlzIGNvbnN0cnVjdCBOb2RlXG4gICAqL1xuICBwdWJsaWMgYWRkVmFsaWRhdGlvbih2YWxpZGF0aW9uOiBjb25zdHJ1Y3RzLklWYWxpZGF0aW9uKSB7XG4gICAgdGhpcy5fYWN0dWFsTm9kZS5hZGRWYWxpZGF0aW9uKHZhbGlkYXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFsbCBwYXJlbnQgc2NvcGVzIG9mIHRoaXMgY29uc3RydWN0LlxuICAgKlxuICAgKiBAcmV0dXJucyBhIGxpc3Qgb2YgcGFyZW50IHNjb3Blcy4gVGhlIGxhc3QgZWxlbWVudCBpbiB0aGUgbGlzdCB3aWxsIGFsd2F5c1xuICAgKiBiZSB0aGUgY3VycmVudCBjb25zdHJ1Y3QgYW5kIHRoZSBmaXJzdCBlbGVtZW50IHdpbGwgYmUgdGhlIHJvb3Qgb2YgdGhlXG4gICAqIHRyZWUuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHNjb3BlcygpOiBJQ29uc3RydWN0W10geyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5zY29wZXMgYXMgSUNvbnN0cnVjdFtdOyB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIFRoZSByb290IG9mIHRoZSBjb25zdHJ1Y3QgdHJlZS5cbiAgICovXG4gIHB1YmxpYyBnZXQgcm9vdCgpOiBJQ29uc3RydWN0IHsgcmV0dXJuIHRoaXMuX2FjdHVhbE5vZGUucm9vdCBhcyBJQ29uc3RydWN0OyB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGNvbnN0cnVjdCBvciB0aGUgc2NvcGVzIGluIHdoaWNoIGl0IGlzIGRlZmluZWQgYXJlXG4gICAqIGxvY2tlZC5cbiAgICovXG4gIHB1YmxpYyBnZXQgbG9ja2VkKCkgeyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS5sb2NrZWQ7IH1cblxuICAvKipcbiAgICogQWRkIGFuIG9yZGVyaW5nIGRlcGVuZGVuY3kgb24gYW5vdGhlciBDb25zdHJ1Y3QuXG4gICAqXG4gICAqIEFsbCBjb25zdHJ1Y3RzIGluIHRoZSBkZXBlbmRlbmN5J3Mgc2NvcGUgd2lsbCBiZSBkZXBsb3llZCBiZWZvcmUgYW55XG4gICAqIGNvbnN0cnVjdCBpbiB0aGlzIGNvbnN0cnVjdCdzIHNjb3BlLlxuICAgKi9cbiAgcHVibGljIGFkZERlcGVuZGVuY3koLi4uZGVwZW5kZW5jaWVzOiBJRGVwZW5kYWJsZVtdKSB7IHRoaXMuX2FjdHVhbE5vZGUuYWRkRGVwZW5kZW5jeSguLi5kZXBlbmRlbmNpZXMpOyB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbGwgZGVwZW5kZW5jaWVzIHJlZ2lzdGVyZWQgb24gdGhpcyBub2RlIG9yIGFueSBvZiBpdHMgY2hpbGRyZW5cbiAgICovXG4gIHB1YmxpYyBnZXQgZGVwZW5kZW5jaWVzKCk6IERlcGVuZGVuY3lbXSB7IHJldHVybiB0aGlzLl9hY3R1YWxOb2RlLmRlcGVuZGVuY2llcyBhcyBEZXBlbmRlbmN5W107IH1cblxuICAvKipcbiAgICogUmVtb3ZlIHRoZSBjaGlsZCB3aXRoIHRoZSBnaXZlbiBuYW1lLCBpZiBwcmVzZW50LlxuICAgKlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIGEgY2hpbGQgd2l0aCB0aGUgZ2l2ZW4gbmFtZSB3YXMgZGVsZXRlZC5cbiAgICovXG4gIHB1YmxpYyB0cnlSZW1vdmVDaGlsZChjaGlsZE5hbWU6IHN0cmluZyk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5fYWN0dWFsTm9kZS50cnlSZW1vdmVDaGlsZChjaGlsZE5hbWUpOyB9XG59XG5cbi8qKlxuICogQW4gZXJyb3IgcmV0dXJuZWQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uIHBoYXNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25FcnJvciB7XG4gIC8qKlxuICAgKiBUaGUgY29uc3RydWN0IHdoaWNoIGVtaXR0ZWQgdGhlIGVycm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlOiBDb25zdHJ1Y3Q7XG5cbiAgLyoqXG4gICAqIFRoZSBlcnJvciBtZXNzYWdlLlxuICAgKi9cbiAgcmVhZG9ubHkgbWVzc2FnZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgc2luZ2xlIGRlcGVuZGVuY3lcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZXBlbmRlbmN5IHtcbiAgLyoqXG4gICAqIFNvdXJjZSB0aGUgZGVwZW5kZW5jeVxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlOiBJQ29uc3RydWN0O1xuXG4gIC8qKlxuICAgKiBUYXJnZXQgb2YgdGhlIGRlcGVuZGVuY3lcbiAgICovXG4gIHJlYWRvbmx5IHRhcmdldDogSUNvbnN0cnVjdDtcbn1cblxuZnVuY3Rpb24gaWdub3JlKF94OiBhbnkpIHtcbiAgcmV0dXJuO1xufVxuIl19
\No newline at end of file