@aws-solutions-constructs/core
Version:
Core CDK Construct for patterns library
101 lines • 14.8 kB
JavaScript
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.flagOverriddenDefaults = flagOverriddenDefaults;
/*
* The functions found here in the core library are for internal use and can be changed
* or removed outside of a major release. We recommend against calling them directly from client code.
*/
const deepdiff = require("deep-diff");
const utils_1 = require("./utils");
/**
* @internal This is an internal core function and should not be called directly by Solutions Constructs clients.
*
* Emits a warning to the console when a prescriptive default value is overridden by the user.
* @param {object} defaultProps the prescriptive defaults for the pattern.
* @param {object} userProps the properties provided by the user, to be compared against the defaultProps.
*/
function flagOverriddenDefaults(defaultProps, userProps) {
// Compare the properties and return any overrides
const overrides = findOverrides(defaultProps, userProps);
// Emit a warning for each override
for (let i = 0; i < ((overrides !== undefined) ? overrides.length : 0); i++) {
const e = Object.assign(overrides[i]);
// Determine appropriate logging granularity
const valuesAreReadable = (checkReadability(e.lhs) &&
checkReadability(e.rhs));
// Format the path for readability
const path = formatOverridePath(e.path);
// Output
const details = (valuesAreReadable) ? ` Default value: '${e.lhs}'. You provided: '${e.rhs}'.` : '';
(0, utils_1.printWarning)(`An override has been provided for the property: ${path}.` + details);
}
}
/** The prefilter function returns true for any filtered path/key that should be excluded from the diff check.
* Any Construct Props using cdk.Duration type is not properly handled by
* 'deep-diff' library, whenever it encounters a Duration object, it throws the exception
* 'Argument to Intrinsic must be a plain value object', so such props are excluded from the diff check.
*/
// This function is called from within deep-diff with 2 arguments, but we only use one of them, so we have to
// disable the "is never read" typescript error
// @ts-ignore
function prefilter(path, key) {
const prefilters = ['maxRecordAge', 'expiration', 'transitionAfter', 'destination', 'timeout', 'period', 'node'];
if (prefilters.indexOf(key) >= 0) {
if (key !== 'node') {
(0, utils_1.printWarning)(`Possible override of ${key} value.`);
}
return true;
}
return false;
}
/**
* Performs a diff check of the userProps against the defaultProps to detect overridden properties.
* @param {object} defaultProps the prescriptive defaults for the pattern.
* @param {object} userProps the properties provided by the user, to be compared against the defaultProps.
* @return {Array} an array containing the overridden values.
*/
function findOverrides(defaultProps, userProps) {
const diff = deepdiff.diff(defaultProps, userProps, prefilter);
// Filter the results
return (diff !== undefined) ? diff?.filter((e) => (e.kind === 'E' && // only return overrides
!e.path?.includes('node') && // stop traversing once the object graph hits the node
!e.path?.includes('bind') // stop traversing once the object graph hits internal functions
)) : [];
}
/**
* Converts the path object from the deep-diff module to a user-readable, bracket notation format.
* @param {string | string[]} path either a string value or an array of strings.
* @return {string} the formatted override path.
*/
function formatOverridePath(path) {
return (path !== undefined && path.length > 1) ? path.toString()
.replace(/,/g, '][')
.replace(/\]/, '')
.replace(/$/, ']') : path;
}
/**
* Check the readability of an input value and, in the context of the override warning service, return true if it
* meets the established criteria. This function is used to determine whether more-detailed log output can be given.
* @param {any} value input to be evaluated against the given criteria.
* @return {boolean} true if the value meets the given criteria.
* @return {boolean} false if the value does not meet the given criteria.
*/
function checkReadability(value) {
return (typeof (value) === 'string' && // strings only
!value.includes('${Token[') && // no circular refs
value !== '' // no empty strings
);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcnJpZGUtd2FybmluZy1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsib3ZlcnJpZGUtd2FybmluZy1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7R0FXRzs7QUFpQkgsd0RBaUJDO0FBaENEOzs7R0FHRztBQUVILHNDQUFzQztBQUN0QyxtQ0FBdUM7QUFFdkM7Ozs7OztHQU1HO0FBQ0gsU0FBZ0Isc0JBQXNCLENBQUMsWUFBb0IsRUFBRSxTQUFpQjtJQUM1RSxrREFBa0Q7SUFDbEQsTUFBTSxTQUFTLEdBQUcsYUFBYSxDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN6RCxtQ0FBbUM7SUFDbkMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDNUUsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0Qyw0Q0FBNEM7UUFDNUMsTUFBTSxpQkFBaUIsR0FBRyxDQUN4QixnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQ3ZCLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FDeEIsQ0FBQztRQUNGLGtDQUFrQztRQUNsQyxNQUFNLElBQUksR0FBRyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEMsU0FBUztRQUNULE1BQU0sT0FBTyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLHFCQUFxQixDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNuRyxJQUFBLG9CQUFZLEVBQUMsbURBQW1ELElBQUksR0FBRyxHQUFHLE9BQU8sQ0FBQyxDQUFDO0lBQ3JGLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILDZHQUE2RztBQUM3RywrQ0FBK0M7QUFDL0MsYUFBYTtBQUNiLFNBQVMsU0FBUyxDQUFDLElBQVcsRUFBRSxHQUFXO0lBQ3pDLE1BQU0sVUFBVSxHQUFHLENBQUMsY0FBYyxFQUFFLFlBQVksRUFBRSxpQkFBaUIsRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUVqSCxJQUFJLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDakMsSUFBSSxHQUFHLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDbkIsSUFBQSxvQkFBWSxFQUFDLHdCQUF3QixHQUFHLFNBQVMsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsYUFBYSxDQUFDLFlBQW9CLEVBQUUsU0FBaUI7SUFDNUQsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQy9ELHFCQUFxQjtJQUNyQixPQUFPLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUNoRCxDQUFDLENBQUMsSUFBSSxLQUFLLEdBQUcsSUFBSSx3QkFBd0I7UUFDMUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxzREFBc0Q7UUFDbkYsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxnRUFBZ0U7S0FDM0YsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDVixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsa0JBQWtCLENBQUMsSUFBdUI7SUFDakQsT0FBTyxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtTQUM3RCxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQztTQUNuQixPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztTQUNqQixPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDOUIsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsZ0JBQWdCLENBQUMsS0FBVTtJQUNsQyxPQUFPLENBQ0wsT0FBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLFFBQVEsSUFBSSxlQUFlO1FBQzdDLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxtQkFBbUI7UUFDbEQsS0FBSyxLQUFLLEVBQUUsQ0FBQyxtQkFBbUI7S0FDakMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqICBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKS4gWW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICogIHdpdGggdGhlIExpY2Vuc2UuIEEgY29weSBvZiB0aGUgTGljZW5zZSBpcyBsb2NhdGVkIGF0XG4gKlxuICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiAgb3IgaW4gdGhlICdsaWNlbnNlJyBmaWxlIGFjY29tcGFueWluZyB0aGlzIGZpbGUuIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAnQVMgSVMnIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVNcbiAqICBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9uc1xuICogIGFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vKlxuICogIFRoZSBmdW5jdGlvbnMgZm91bmQgaGVyZSBpbiB0aGUgY29yZSBsaWJyYXJ5IGFyZSBmb3IgaW50ZXJuYWwgdXNlIGFuZCBjYW4gYmUgY2hhbmdlZFxuICogIG9yIHJlbW92ZWQgb3V0c2lkZSBvZiBhIG1ham9yIHJlbGVhc2UuIFdlIHJlY29tbWVuZCBhZ2FpbnN0IGNhbGxpbmcgdGhlbSBkaXJlY3RseSBmcm9tIGNsaWVudCBjb2RlLlxuICovXG5cbmltcG9ydCAqIGFzIGRlZXBkaWZmIGZyb20gJ2RlZXAtZGlmZic7XG5pbXBvcnQgeyBwcmludFdhcm5pbmcgfSBmcm9tICcuL3V0aWxzJztcblxuLyoqXG4gKiBAaW50ZXJuYWwgVGhpcyBpcyBhbiBpbnRlcm5hbCBjb3JlIGZ1bmN0aW9uIGFuZCBzaG91bGQgbm90IGJlIGNhbGxlZCBkaXJlY3RseSBieSBTb2x1dGlvbnMgQ29uc3RydWN0cyBjbGllbnRzLlxuICpcbiAqIEVtaXRzIGEgd2FybmluZyB0byB0aGUgY29uc29sZSB3aGVuIGEgcHJlc2NyaXB0aXZlIGRlZmF1bHQgdmFsdWUgaXMgb3ZlcnJpZGRlbiBieSB0aGUgdXNlci5cbiAqIEBwYXJhbSB7b2JqZWN0fSBkZWZhdWx0UHJvcHMgdGhlIHByZXNjcmlwdGl2ZSBkZWZhdWx0cyBmb3IgdGhlIHBhdHRlcm4uXG4gKiBAcGFyYW0ge29iamVjdH0gdXNlclByb3BzIHRoZSBwcm9wZXJ0aWVzIHByb3ZpZGVkIGJ5IHRoZSB1c2VyLCB0byBiZSBjb21wYXJlZCBhZ2FpbnN0IHRoZSBkZWZhdWx0UHJvcHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbGFnT3ZlcnJpZGRlbkRlZmF1bHRzKGRlZmF1bHRQcm9wczogb2JqZWN0LCB1c2VyUHJvcHM6IG9iamVjdCkge1xuICAvLyBDb21wYXJlIHRoZSBwcm9wZXJ0aWVzIGFuZCByZXR1cm4gYW55IG92ZXJyaWRlc1xuICBjb25zdCBvdmVycmlkZXMgPSBmaW5kT3ZlcnJpZGVzKGRlZmF1bHRQcm9wcywgdXNlclByb3BzKTtcbiAgLy8gRW1pdCBhIHdhcm5pbmcgZm9yIGVhY2ggb3ZlcnJpZGVcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCAoKG92ZXJyaWRlcyAhPT0gdW5kZWZpbmVkKSA/IG92ZXJyaWRlcy5sZW5ndGggOiAwKTsgaSsrKSB7XG4gICAgY29uc3QgZSA9IE9iamVjdC5hc3NpZ24ob3ZlcnJpZGVzW2ldKTtcbiAgICAvLyBEZXRlcm1pbmUgYXBwcm9wcmlhdGUgbG9nZ2luZyBncmFudWxhcml0eVxuICAgIGNvbnN0IHZhbHVlc0FyZVJlYWRhYmxlID0gKFxuICAgICAgY2hlY2tSZWFkYWJpbGl0eShlLmxocykgJiZcbiAgICAgIGNoZWNrUmVhZGFiaWxpdHkoZS5yaHMpXG4gICAgKTtcbiAgICAvLyBGb3JtYXQgdGhlIHBhdGggZm9yIHJlYWRhYmlsaXR5XG4gICAgY29uc3QgcGF0aCA9IGZvcm1hdE92ZXJyaWRlUGF0aChlLnBhdGgpO1xuICAgIC8vIE91dHB1dFxuICAgIGNvbnN0IGRldGFpbHMgPSAodmFsdWVzQXJlUmVhZGFibGUpID8gYCBEZWZhdWx0IHZhbHVlOiAnJHtlLmxoc30nLiBZb3UgcHJvdmlkZWQ6ICcke2UucmhzfScuYCA6ICcnO1xuICAgIHByaW50V2FybmluZyhgQW4gb3ZlcnJpZGUgaGFzIGJlZW4gcHJvdmlkZWQgZm9yIHRoZSBwcm9wZXJ0eTogJHtwYXRofS5gICsgZGV0YWlscyk7XG4gIH1cbn1cblxuLyoqIFRoZSBwcmVmaWx0ZXIgZnVuY3Rpb24gcmV0dXJucyB0cnVlIGZvciBhbnkgZmlsdGVyZWQgcGF0aC9rZXkgdGhhdCBzaG91bGQgYmUgZXhjbHVkZWQgZnJvbSB0aGUgZGlmZiBjaGVjay5cbiAqIEFueSBDb25zdHJ1Y3QgUHJvcHMgdXNpbmcgY2RrLkR1cmF0aW9uIHR5cGUgaXMgbm90IHByb3Blcmx5IGhhbmRsZWQgYnlcbiAqICdkZWVwLWRpZmYnIGxpYnJhcnksIHdoZW5ldmVyIGl0IGVuY291bnRlcnMgYSBEdXJhdGlvbiBvYmplY3QsIGl0IHRocm93cyB0aGUgZXhjZXB0aW9uXG4gKiAnQXJndW1lbnQgdG8gSW50cmluc2ljIG11c3QgYmUgYSBwbGFpbiB2YWx1ZSBvYmplY3QnLCBzbyBzdWNoIHByb3BzIGFyZSBleGNsdWRlZCBmcm9tIHRoZSBkaWZmIGNoZWNrLlxuICovXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBmcm9tIHdpdGhpbiBkZWVwLWRpZmYgd2l0aCAyIGFyZ3VtZW50cywgYnV0IHdlIG9ubHkgdXNlIG9uZSBvZiB0aGVtLCBzbyB3ZSBoYXZlIHRvXG4vLyBkaXNhYmxlIHRoZSBcImlzIG5ldmVyIHJlYWRcIiB0eXBlc2NyaXB0IGVycm9yXG4vLyBAdHMtaWdub3JlXG5mdW5jdGlvbiBwcmVmaWx0ZXIocGF0aDogYW55W10sIGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IHByZWZpbHRlcnMgPSBbJ21heFJlY29yZEFnZScsICdleHBpcmF0aW9uJywgJ3RyYW5zaXRpb25BZnRlcicsICdkZXN0aW5hdGlvbicsICd0aW1lb3V0JywgJ3BlcmlvZCcsICdub2RlJ107XG5cbiAgaWYgKHByZWZpbHRlcnMuaW5kZXhPZihrZXkpID49IDApIHtcbiAgICBpZiAoa2V5ICE9PSAnbm9kZScpIHtcbiAgICAgIHByaW50V2FybmluZyhgUG9zc2libGUgb3ZlcnJpZGUgb2YgJHtrZXl9IHZhbHVlLmApO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogUGVyZm9ybXMgYSBkaWZmIGNoZWNrIG9mIHRoZSB1c2VyUHJvcHMgYWdhaW5zdCB0aGUgZGVmYXVsdFByb3BzIHRvIGRldGVjdCBvdmVycmlkZGVuIHByb3BlcnRpZXMuXG4gKiBAcGFyYW0ge29iamVjdH0gZGVmYXVsdFByb3BzIHRoZSBwcmVzY3JpcHRpdmUgZGVmYXVsdHMgZm9yIHRoZSBwYXR0ZXJuLlxuICogQHBhcmFtIHtvYmplY3R9IHVzZXJQcm9wcyB0aGUgcHJvcGVydGllcyBwcm92aWRlZCBieSB0aGUgdXNlciwgdG8gYmUgY29tcGFyZWQgYWdhaW5zdCB0aGUgZGVmYXVsdFByb3BzLlxuICogQHJldHVybiB7QXJyYXl9IGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIG92ZXJyaWRkZW4gdmFsdWVzLlxuICovXG5mdW5jdGlvbiBmaW5kT3ZlcnJpZGVzKGRlZmF1bHRQcm9wczogb2JqZWN0LCB1c2VyUHJvcHM6IG9iamVjdCkge1xuICBjb25zdCBkaWZmID0gZGVlcGRpZmYuZGlmZihkZWZhdWx0UHJvcHMsIHVzZXJQcm9wcywgcHJlZmlsdGVyKTtcbiAgLy8gRmlsdGVyIHRoZSByZXN1bHRzXG4gIHJldHVybiAoZGlmZiAhPT0gdW5kZWZpbmVkKSA/IGRpZmY/LmZpbHRlcigoZSkgPT4gKFxuICAgIGUua2luZCA9PT0gJ0UnICYmIC8vIG9ubHkgcmV0dXJuIG92ZXJyaWRlc1xuICAgICFlLnBhdGg/LmluY2x1ZGVzKCdub2RlJykgJiYgLy8gc3RvcCB0cmF2ZXJzaW5nIG9uY2UgdGhlIG9iamVjdCBncmFwaCBoaXRzIHRoZSBub2RlXG4gICAgIWUucGF0aD8uaW5jbHVkZXMoJ2JpbmQnKSAvLyBzdG9wIHRyYXZlcnNpbmcgb25jZSB0aGUgb2JqZWN0IGdyYXBoIGhpdHMgaW50ZXJuYWwgZnVuY3Rpb25zXG4gICkpIDogW107XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIHBhdGggb2JqZWN0IGZyb20gdGhlIGRlZXAtZGlmZiBtb2R1bGUgdG8gYSB1c2VyLXJlYWRhYmxlLCBicmFja2V0IG5vdGF0aW9uIGZvcm1hdC5cbiAqIEBwYXJhbSB7c3RyaW5nIHwgc3RyaW5nW119IHBhdGggZWl0aGVyIGEgc3RyaW5nIHZhbHVlIG9yIGFuIGFycmF5IG9mIHN0cmluZ3MuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBmb3JtYXR0ZWQgb3ZlcnJpZGUgcGF0aC5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0T3ZlcnJpZGVQYXRoKHBhdGg6IHN0cmluZyB8IHN0cmluZ1tdKSB7XG4gIHJldHVybiAocGF0aCAhPT0gdW5kZWZpbmVkICYmIHBhdGgubGVuZ3RoID4gMSkgPyBwYXRoLnRvU3RyaW5nKClcbiAgICAucmVwbGFjZSgvLC9nLCAnXVsnKVxuICAgIC5yZXBsYWNlKC9cXF0vLCAnJylcbiAgICAucmVwbGFjZSgvJC8sICddJykgOiBwYXRoO1xufVxuXG4vKipcbiAqIENoZWNrIHRoZSByZWFkYWJpbGl0eSBvZiBhbiBpbnB1dCB2YWx1ZSBhbmQsIGluIHRoZSBjb250ZXh0IG9mIHRoZSBvdmVycmlkZSB3YXJuaW5nIHNlcnZpY2UsIHJldHVybiB0cnVlIGlmIGl0XG4gKiBtZWV0cyB0aGUgZXN0YWJsaXNoZWQgY3JpdGVyaWEuIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBkZXRlcm1pbmUgd2hldGhlciBtb3JlLWRldGFpbGVkIGxvZyBvdXRwdXQgY2FuIGJlIGdpdmVuLlxuICogQHBhcmFtIHthbnl9IHZhbHVlIGlucHV0IHRvIGJlIGV2YWx1YXRlZCBhZ2FpbnN0IHRoZSBnaXZlbiBjcml0ZXJpYS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgdGhlIHZhbHVlIG1lZXRzIHRoZSBnaXZlbiBjcml0ZXJpYS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IGZhbHNlIGlmIHRoZSB2YWx1ZSBkb2VzIG5vdCBtZWV0IHRoZSBnaXZlbiBjcml0ZXJpYS5cbiAqL1xuZnVuY3Rpb24gY2hlY2tSZWFkYWJpbGl0eSh2YWx1ZTogYW55KSB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mKHZhbHVlKSA9PT0gJ3N0cmluZycgJiYgLy8gc3RyaW5ncyBvbmx5XG4gICAgIXZhbHVlLmluY2x1ZGVzKCcke1Rva2VuWycpICYmIC8vIG5vIGNpcmN1bGFyIHJlZnNcbiAgICB2YWx1ZSAhPT0gJycgLy8gbm8gZW1wdHkgc3RyaW5nc1xuICApO1xufSJdfQ==
;