aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
183 lines • 18.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyDefaults = applyDefaults;
exports.isEmpty = isEmpty;
exports.deepClone = deepClone;
exports.mapObject = mapObject;
exports.makeObject = makeObject;
exports.deepGet = deepGet;
exports.deepSet = deepSet;
exports.deepMerge = deepMerge;
exports.splitBySize = splitBySize;
const types_1 = require("./types");
const error_1 = require("../toolkit/error");
/**
* Return a new object by adding missing keys into another object
*/
function applyDefaults(hash, defaults) {
const result = {};
Object.keys(hash).forEach(k => result[k] = hash[k]);
Object.keys(defaults)
.filter(k => !(k in result))
.forEach(k => result[k] = defaults[k]);
return result;
}
/**
* Return whether the given parameter is an empty object or empty list.
*/
function isEmpty(x) {
if (x == null) {
return false;
}
if ((0, types_1.isArray)(x)) {
return x.length === 0;
}
return Object.keys(x).length === 0;
}
/**
* Deep clone a tree of objects, lists or scalars
*
* Does not support cycles.
*/
function deepClone(x) {
if (typeof x === 'undefined') {
return undefined;
}
if (x === null) {
return null;
}
if ((0, types_1.isArray)(x)) {
return x.map(deepClone);
}
if ((0, types_1.isObject)(x)) {
return makeObject(mapObject(x, (k, v) => [k, deepClone(v)]));
}
return x;
}
/**
* Map over an object, treating it as a dictionary
*/
function mapObject(x, fn) {
const ret = [];
Object.keys(x).forEach(key => {
ret.push(fn(key, x[key]));
});
return ret;
}
/**
* Construct an object from a list of (k, v) pairs
*/
function makeObject(pairs) {
const ret = {};
for (const pair of pairs) {
ret[pair[0]] = pair[1];
}
return ret;
}
/**
* Deep get a value from a tree of nested objects
*
* Returns undefined if any part of the path was unset or
* not an object.
*/
function deepGet(x, path) {
path = path.slice();
while (path.length > 0 && (0, types_1.isObject)(x)) {
const key = path.shift();
x = x[key];
}
return path.length === 0 ? x : undefined;
}
/**
* Deep set a value in a tree of nested objects
*
* Throws an error if any part of the path is not an object.
*/
function deepSet(x, path, value) {
path = path.slice();
if (path.length === 0) {
throw new error_1.ToolkitError('Path may not be empty');
}
while (path.length > 1 && (0, types_1.isObject)(x)) {
const key = path.shift();
if (!(key in x)) {
x[key] = {};
}
x = x[key];
}
if (!(0, types_1.isObject)(x)) {
throw new error_1.ToolkitError(`Expected an object, got '${x}'`);
}
if (value !== undefined) {
x[path[0]] = value;
}
else {
delete x[path[0]];
}
}
/**
* Recursively merge objects together
*
* The leftmost object is mutated and returned. Arrays are not merged
* but overwritten just like scalars.
*
* If an object is merged into a non-object, the non-object is lost.
*/
function deepMerge(...objects) {
function mergeOne(target, source) {
for (const key of Object.keys(source)) {
if (key === '__proto__' || key === 'constructor') {
continue;
}
const value = source[key];
if ((0, types_1.isObject)(value)) {
if (!(0, types_1.isObject)(target[key])) {
target[key] = {};
} // Overwrite on purpose
mergeOne(target[key], value);
}
else if (typeof value !== 'undefined') {
target[key] = value;
}
}
}
const others = objects.filter(x => x != null);
if (others.length === 0) {
return {};
}
const into = others.splice(0, 1)[0];
others.forEach(other => mergeOne(into, other));
return into;
}
/**
* Splits the given object into two, such that:
*
* 1. The size of the first object (after stringified in UTF-8) is less than or equal to the provided size limit.
* 2. Merging the two objects results in the original one.
*/
function splitBySize(data, maxSizeBytes) {
if (maxSizeBytes < 2) {
// It's impossible to fit anything in the first object
return [undefined, data];
}
const entries = Object.entries(data);
return recurse(0, 0);
function recurse(index, runningTotalSize) {
if (index >= entries.length) {
// Everything fits in the first object
return [data, undefined];
}
const size = runningTotalSize + entrySize(entries[index]);
return (size > maxSizeBytes) ? cutAt(index) : recurse(index + 1, size);
}
function entrySize(entry) {
return Buffer.byteLength(JSON.stringify(Object.fromEntries([entry])));
}
function cutAt(index) {
return [
Object.fromEntries(entries.slice(0, index)),
Object.fromEntries(entries.slice(index)),
];
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm9iamVjdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFNQSxzQ0FVQztBQUtELDBCQUlDO0FBT0QsOEJBTUM7QUFLRCw4QkFNQztBQUtELGdDQU1DO0FBUUQsMEJBUUM7QUFPRCwwQkFzQkM7QUFVRCw4QkF5QkM7QUFRRCxrQ0E0QkM7QUFoTEQsbUNBQWlEO0FBQ2pELDRDQUFnRDtBQUVoRDs7R0FFRztBQUNILFNBQWdCLGFBQWEsQ0FBQyxJQUFTLEVBQUUsUUFBYTtJQUNwRCxNQUFNLE1BQU0sR0FBUSxFQUFHLENBQUM7SUFFeEIsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFcEQsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7U0FDbEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQztTQUMzQixPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFekMsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFDLENBQU07SUFDNUIsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7UUFBQyxPQUFPLEtBQUssQ0FBQztJQUFDLENBQUM7SUFDaEMsSUFBSSxJQUFBLGVBQU8sRUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQztJQUFDLENBQUM7SUFDMUMsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7QUFDckMsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixTQUFTLENBQUMsQ0FBTTtJQUM5QixJQUFJLE9BQU8sQ0FBQyxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQUMsT0FBTyxTQUFTLENBQUM7SUFBQyxDQUFDO0lBQ25ELElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQUMsT0FBTyxJQUFJLENBQUM7SUFBQyxDQUFDO0lBQ2hDLElBQUksSUFBQSxlQUFPLEVBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUFDLENBQUM7SUFDNUMsSUFBSSxJQUFBLGdCQUFRLEVBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUFDLE9BQU8sVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQWtCLENBQUMsQ0FBQyxDQUFDO0lBQUMsQ0FBQztJQUNuRyxPQUFPLENBQUMsQ0FBQztBQUNYLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLFNBQVMsQ0FBTyxDQUFTLEVBQUUsRUFBZ0M7SUFDekUsTUFBTSxHQUFHLEdBQVEsRUFBRSxDQUFDO0lBQ3BCLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1FBQzNCLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVCLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixVQUFVLENBQUksS0FBeUI7SUFDckQsTUFBTSxHQUFHLEdBQVcsRUFBRSxDQUFDO0lBQ3ZCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7UUFDekIsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFnQixPQUFPLENBQUMsQ0FBTSxFQUFFLElBQWM7SUFDNUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUVwQixPQUFPLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUEsZ0JBQVEsRUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3RDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUcsQ0FBQztRQUMxQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQzNDLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFDLENBQU0sRUFBRSxJQUFjLEVBQUUsS0FBVTtJQUN4RCxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBRXBCLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN0QixNQUFNLElBQUksb0JBQVksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUEsZ0JBQVEsRUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3RDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUcsQ0FBQztRQUMxQixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7UUFBQyxDQUFDO1FBQ2pDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDYixDQUFDO0lBRUQsSUFBSSxDQUFDLElBQUEsZ0JBQVEsRUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2pCLE1BQU0sSUFBSSxvQkFBWSxDQUFDLDRCQUE0QixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRCxJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUN4QixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLENBQUM7U0FBTSxDQUFDO1FBQ04sT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEIsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsU0FBZ0IsU0FBUyxDQUFDLEdBQUcsT0FBb0M7SUFDL0QsU0FBUyxRQUFRLENBQUMsTUFBZ0IsRUFBRSxNQUFnQjtRQUNsRCxLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUN0QyxJQUFJLEdBQUcsS0FBSyxXQUFXLElBQUksR0FBRyxLQUFLLGFBQWEsRUFBRSxDQUFDO2dCQUNqRCxTQUFTO1lBQ1gsQ0FBQztZQUVELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUUxQixJQUFJLElBQUEsZ0JBQVEsRUFBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNwQixJQUFJLENBQUMsSUFBQSxnQkFBUSxFQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFBQyxDQUFDLENBQUMsdUJBQXVCO2dCQUN6RSxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQy9CLENBQUM7aUJBQU0sSUFBSSxPQUFPLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQztnQkFDeEMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztZQUN0QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBb0IsQ0FBQztJQUVqRSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFBQyxPQUFPLEVBQUUsQ0FBQztJQUFDLENBQUM7SUFDdkMsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFcEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUMvQyxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLFdBQVcsQ0FBQyxJQUFTLEVBQUUsWUFBb0I7SUFDekQsSUFBSSxZQUFZLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDckIsc0RBQXNEO1FBQ3RELE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUNELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDckMsT0FBTyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXJCLFNBQVMsT0FBTyxDQUFDLEtBQWEsRUFBRSxnQkFBd0I7UUFDdEQsSUFBSSxLQUFLLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzVCLHNDQUFzQztZQUN0QyxPQUFPLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzNCLENBQUM7UUFFRCxNQUFNLElBQUksR0FBRyxnQkFBZ0IsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDMUQsT0FBTyxDQUFDLElBQUksR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRUQsU0FBUyxTQUFTLENBQUMsS0FBd0I7UUFDekMsT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFFRCxTQUFTLEtBQUssQ0FBQyxLQUFhO1FBQzFCLE9BQU87WUFDTCxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzNDLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN6QyxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc0FycmF5LCBpc09iamVjdCwgT2JqIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBUb29sa2l0RXJyb3IgfSBmcm9tICcuLi90b29sa2l0L2Vycm9yJztcblxuLyoqXG4gKiBSZXR1cm4gYSBuZXcgb2JqZWN0IGJ5IGFkZGluZyBtaXNzaW5nIGtleXMgaW50byBhbm90aGVyIG9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlEZWZhdWx0cyhoYXNoOiBhbnksIGRlZmF1bHRzOiBhbnkpIHtcbiAgY29uc3QgcmVzdWx0OiBhbnkgPSB7IH07XG5cbiAgT2JqZWN0LmtleXMoaGFzaCkuZm9yRWFjaChrID0+IHJlc3VsdFtrXSA9IGhhc2hba10pO1xuXG4gIE9iamVjdC5rZXlzKGRlZmF1bHRzKVxuICAgIC5maWx0ZXIoayA9PiAhKGsgaW4gcmVzdWx0KSlcbiAgICAuZm9yRWFjaChrID0+IHJlc3VsdFtrXSA9IGRlZmF1bHRzW2tdKTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJldHVybiB3aGV0aGVyIHRoZSBnaXZlbiBwYXJhbWV0ZXIgaXMgYW4gZW1wdHkgb2JqZWN0IG9yIGVtcHR5IGxpc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0VtcHR5KHg6IGFueSkge1xuICBpZiAoeCA9PSBudWxsKSB7IHJldHVybiBmYWxzZTsgfVxuICBpZiAoaXNBcnJheSh4KSkgeyByZXR1cm4geC5sZW5ndGggPT09IDA7IH1cbiAgcmV0dXJuIE9iamVjdC5rZXlzKHgpLmxlbmd0aCA9PT0gMDtcbn1cblxuLyoqXG4gKiBEZWVwIGNsb25lIGEgdHJlZSBvZiBvYmplY3RzLCBsaXN0cyBvciBzY2FsYXJzXG4gKlxuICogRG9lcyBub3Qgc3VwcG9ydCBjeWNsZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWVwQ2xvbmUoeDogYW55KTogYW55IHtcbiAgaWYgKHR5cGVvZiB4ID09PSAndW5kZWZpbmVkJykgeyByZXR1cm4gdW5kZWZpbmVkOyB9XG4gIGlmICh4ID09PSBudWxsKSB7IHJldHVybiBudWxsOyB9XG4gIGlmIChpc0FycmF5KHgpKSB7IHJldHVybiB4Lm1hcChkZWVwQ2xvbmUpOyB9XG4gIGlmIChpc09iamVjdCh4KSkgeyByZXR1cm4gbWFrZU9iamVjdChtYXBPYmplY3QoeCwgKGssIHYpID0+IFtrLCBkZWVwQ2xvbmUodildIGFzIFtzdHJpbmcsIGFueV0pKTsgfVxuICByZXR1cm4geDtcbn1cblxuLyoqXG4gKiBNYXAgb3ZlciBhbiBvYmplY3QsIHRyZWF0aW5nIGl0IGFzIGEgZGljdGlvbmFyeVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwT2JqZWN0PFQsIFU+KHg6IE9iajxUPiwgZm46IChrZXk6IHN0cmluZywgdmFsdWU6IFQpID0+IFUpOiBVW10ge1xuICBjb25zdCByZXQ6IFVbXSA9IFtdO1xuICBPYmplY3Qua2V5cyh4KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgcmV0LnB1c2goZm4oa2V5LCB4W2tleV0pKTtcbiAgfSk7XG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQ29uc3RydWN0IGFuIG9iamVjdCBmcm9tIGEgbGlzdCBvZiAoaywgdikgcGFpcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VPYmplY3Q8VD4ocGFpcnM6IEFycmF5PFtzdHJpbmcsIFRdPik6IE9iajxUPiB7XG4gIGNvbnN0IHJldDogT2JqPFQ+ID0ge307XG4gIGZvciAoY29uc3QgcGFpciBvZiBwYWlycykge1xuICAgIHJldFtwYWlyWzBdXSA9IHBhaXJbMV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBEZWVwIGdldCBhIHZhbHVlIGZyb20gYSB0cmVlIG9mIG5lc3RlZCBvYmplY3RzXG4gKlxuICogUmV0dXJucyB1bmRlZmluZWQgaWYgYW55IHBhcnQgb2YgdGhlIHBhdGggd2FzIHVuc2V0IG9yXG4gKiBub3QgYW4gb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVlcEdldCh4OiBhbnksIHBhdGg6IHN0cmluZ1tdKTogYW55IHtcbiAgcGF0aCA9IHBhdGguc2xpY2UoKTtcblxuICB3aGlsZSAocGF0aC5sZW5ndGggPiAwICYmIGlzT2JqZWN0KHgpKSB7XG4gICAgY29uc3Qga2V5ID0gcGF0aC5zaGlmdCgpITtcbiAgICB4ID0geFtrZXldO1xuICB9XG4gIHJldHVybiBwYXRoLmxlbmd0aCA9PT0gMCA/IHggOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRGVlcCBzZXQgYSB2YWx1ZSBpbiBhIHRyZWUgb2YgbmVzdGVkIG9iamVjdHNcbiAqXG4gKiBUaHJvd3MgYW4gZXJyb3IgaWYgYW55IHBhcnQgb2YgdGhlIHBhdGggaXMgbm90IGFuIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZXBTZXQoeDogYW55LCBwYXRoOiBzdHJpbmdbXSwgdmFsdWU6IGFueSkge1xuICBwYXRoID0gcGF0aC5zbGljZSgpO1xuXG4gIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ1BhdGggbWF5IG5vdCBiZSBlbXB0eScpO1xuICB9XG5cbiAgd2hpbGUgKHBhdGgubGVuZ3RoID4gMSAmJiBpc09iamVjdCh4KSkge1xuICAgIGNvbnN0IGtleSA9IHBhdGguc2hpZnQoKSE7XG4gICAgaWYgKCEoa2V5IGluIHgpKSB7IHhba2V5XSA9IHt9OyB9XG4gICAgeCA9IHhba2V5XTtcbiAgfVxuXG4gIGlmICghaXNPYmplY3QoeCkpIHtcbiAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKGBFeHBlY3RlZCBhbiBvYmplY3QsIGdvdCAnJHt4fSdgKTtcbiAgfVxuXG4gIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgeFtwYXRoWzBdXSA9IHZhbHVlO1xuICB9IGVsc2Uge1xuICAgIGRlbGV0ZSB4W3BhdGhbMF1dO1xuICB9XG59XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgbWVyZ2Ugb2JqZWN0cyB0b2dldGhlclxuICpcbiAqIFRoZSBsZWZ0bW9zdCBvYmplY3QgaXMgbXV0YXRlZCBhbmQgcmV0dXJuZWQuIEFycmF5cyBhcmUgbm90IG1lcmdlZFxuICogYnV0IG92ZXJ3cml0dGVuIGp1c3QgbGlrZSBzY2FsYXJzLlxuICpcbiAqIElmIGFuIG9iamVjdCBpcyBtZXJnZWQgaW50byBhIG5vbi1vYmplY3QsIHRoZSBub24tb2JqZWN0IGlzIGxvc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWVwTWVyZ2UoLi4ub2JqZWN0czogQXJyYXk8T2JqPGFueT4gfCB1bmRlZmluZWQ+KSB7XG4gIGZ1bmN0aW9uIG1lcmdlT25lKHRhcmdldDogT2JqPGFueT4sIHNvdXJjZTogT2JqPGFueT4pIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzb3VyY2UpKSB7XG4gICAgICBpZiAoa2V5ID09PSAnX19wcm90b19fJyB8fCBrZXkgPT09ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gc291cmNlW2tleV07XG5cbiAgICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdCh0YXJnZXRba2V5XSkpIHsgdGFyZ2V0W2tleV0gPSB7fTsgfSAvLyBPdmVyd3JpdGUgb24gcHVycG9zZVxuICAgICAgICBtZXJnZU9uZSh0YXJnZXRba2V5XSwgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRhcmdldFtrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgb3RoZXJzID0gb2JqZWN0cy5maWx0ZXIoeCA9PiB4ICE9IG51bGwpIGFzIEFycmF5PE9iajxhbnk+PjtcblxuICBpZiAob3RoZXJzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4ge307IH1cbiAgY29uc3QgaW50byA9IG90aGVycy5zcGxpY2UoMCwgMSlbMF07XG5cbiAgb3RoZXJzLmZvckVhY2gob3RoZXIgPT4gbWVyZ2VPbmUoaW50bywgb3RoZXIpKTtcbiAgcmV0dXJuIGludG87XG59XG5cbi8qKlxuICogU3BsaXRzIHRoZSBnaXZlbiBvYmplY3QgaW50byB0d28sIHN1Y2ggdGhhdDpcbiAqXG4gKiAxLiBUaGUgc2l6ZSBvZiB0aGUgZmlyc3Qgb2JqZWN0IChhZnRlciBzdHJpbmdpZmllZCBpbiBVVEYtOCkgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBwcm92aWRlZCBzaXplIGxpbWl0LlxuICogMi4gTWVyZ2luZyB0aGUgdHdvIG9iamVjdHMgcmVzdWx0cyBpbiB0aGUgb3JpZ2luYWwgb25lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3BsaXRCeVNpemUoZGF0YTogYW55LCBtYXhTaXplQnl0ZXM6IG51bWJlcik6IFthbnksIGFueV0ge1xuICBpZiAobWF4U2l6ZUJ5dGVzIDwgMikge1xuICAgIC8vIEl0J3MgaW1wb3NzaWJsZSB0byBmaXQgYW55dGhpbmcgaW4gdGhlIGZpcnN0IG9iamVjdFxuICAgIHJldHVybiBbdW5kZWZpbmVkLCBkYXRhXTtcbiAgfVxuICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXMoZGF0YSk7XG4gIHJldHVybiByZWN1cnNlKDAsIDApO1xuXG4gIGZ1bmN0aW9uIHJlY3Vyc2UoaW5kZXg6IG51bWJlciwgcnVubmluZ1RvdGFsU2l6ZTogbnVtYmVyKTogW2FueSwgYW55XSB7XG4gICAgaWYgKGluZGV4ID49IGVudHJpZXMubGVuZ3RoKSB7XG4gICAgICAvLyBFdmVyeXRoaW5nIGZpdHMgaW4gdGhlIGZpcnN0IG9iamVjdFxuICAgICAgcmV0dXJuIFtkYXRhLCB1bmRlZmluZWRdO1xuICAgIH1cblxuICAgIGNvbnN0IHNpemUgPSBydW5uaW5nVG90YWxTaXplICsgZW50cnlTaXplKGVudHJpZXNbaW5kZXhdKTtcbiAgICByZXR1cm4gKHNpemUgPiBtYXhTaXplQnl0ZXMpID8gY3V0QXQoaW5kZXgpIDogcmVjdXJzZShpbmRleCArIDEsIHNpemUpO1xuICB9XG5cbiAgZnVuY3Rpb24gZW50cnlTaXplKGVudHJ5OiBbc3RyaW5nLCB1bmtub3duXSkge1xuICAgIHJldHVybiBCdWZmZXIuYnl0ZUxlbmd0aChKU09OLnN0cmluZ2lmeShPYmplY3QuZnJvbUVudHJpZXMoW2VudHJ5XSkpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGN1dEF0KGluZGV4OiBudW1iZXIpOiBbYW55LCBhbnldIHtcbiAgICByZXR1cm4gW1xuICAgICAgT2JqZWN0LmZyb21FbnRyaWVzKGVudHJpZXMuc2xpY2UoMCwgaW5kZXgpKSxcbiAgICAgIE9iamVjdC5mcm9tRW50cmllcyhlbnRyaWVzLnNsaWNlKGluZGV4KSksXG4gICAgXTtcbiAgfVxufVxuIl19