angular6-json-schema-form
Version:
Angular JSON Schema Form builder
419 lines • 60.6 kB
JavaScript
import * as tslib_1 from "tslib";
import isEqual from 'lodash-es/isEqual';
import { isArray, isEmpty, isNumber, isObject, isString } from './validator.functions';
import { hasOwn, uniqueItems, commonItems } from './utility.functions';
/**
* 'mergeSchemas' function
*
* Merges multiple JSON schemas into a single schema with combined rules.
*
* If able to logically merge properties from all schemas,
* returns a single schema object containing all merged properties.
*
* Example: ({ a: b, max: 1 }, { c: d, max: 2 }) => { a: b, c: d, max: 1 }
*
* If unable to logically merge, returns an allOf schema object containing
* an array of the original schemas;
*
* Example: ({ a: b }, { a: d }) => { allOf: [ { a: b }, { a: d } ] }
*
* // schemas - one or more input schemas
* // - merged schema
*/
export function mergeSchemas() {
var e_1, _a, e_2, _b;
var schemas = [];
for (var _i = 0; _i < arguments.length; _i++) {
schemas[_i] = arguments[_i];
}
schemas = schemas.filter(function (schema) { return !isEmpty(schema); });
if (schemas.some(function (schema) { return !isObject(schema); })) {
return null;
}
var combinedSchema = {};
try {
for (var schemas_1 = tslib_1.__values(schemas), schemas_1_1 = schemas_1.next(); !schemas_1_1.done; schemas_1_1 = schemas_1.next()) {
var schema = schemas_1_1.value;
var _loop_1 = function (key) {
var e_3, _a, e_4, _b, e_5, _c, e_6, _d;
var combinedValue = combinedSchema[key];
var schemaValue = schema[key];
if (!hasOwn(combinedSchema, key) || isEqual(combinedValue, schemaValue)) {
combinedSchema[key] = schemaValue;
}
else {
switch (key) {
case 'allOf':
// Combine all items from both arrays
if (isArray(combinedValue) && isArray(schemaValue)) {
combinedSchema.allOf = mergeSchemas.apply(void 0, tslib_1.__spread(combinedValue, schemaValue));
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'additionalItems':
case 'additionalProperties':
case 'contains':
case 'propertyNames':
// Merge schema objects
if (isObject(combinedValue) && isObject(schemaValue)) {
combinedSchema[key] = mergeSchemas(combinedValue, schemaValue);
// additionalProperties == false in any schema overrides all other values
}
else if (key === 'additionalProperties' &&
(combinedValue === false || schemaValue === false)) {
combinedSchema.combinedSchema = false;
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'anyOf':
case 'oneOf':
case 'enum':
// Keep only items that appear in both arrays
if (isArray(combinedValue) && isArray(schemaValue)) {
combinedSchema[key] = combinedValue.filter(function (item1) {
return schemaValue.findIndex(function (item2) { return isEqual(item1, item2); }) > -1;
});
if (!combinedSchema[key].length) {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'definitions':
// Combine keys from both objects
if (isObject(combinedValue) && isObject(schemaValue)) {
var combinedObject = tslib_1.__assign({}, combinedValue);
try {
for (var _e = tslib_1.__values(Object.keys(schemaValue)), _f = _e.next(); !_f.done; _f = _e.next()) {
var subKey = _f.value;
if (!hasOwn(combinedObject, subKey) ||
isEqual(combinedObject[subKey], schemaValue[subKey])) {
combinedObject[subKey] = schemaValue[subKey];
// Don't combine matching keys with different values
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
}
finally { if (e_3) throw e_3.error; }
}
combinedSchema.definitions = combinedObject;
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'dependencies':
// Combine all keys from both objects
// and merge schemas on matching keys,
// converting from arrays to objects if necessary
if (isObject(combinedValue) && isObject(schemaValue)) {
var combinedObject = tslib_1.__assign({}, combinedValue);
try {
for (var _g = tslib_1.__values(Object.keys(schemaValue)), _h = _g.next(); !_h.done; _h = _g.next()) {
var subKey = _h.value;
if (!hasOwn(combinedObject, subKey) ||
isEqual(combinedObject[subKey], schemaValue[subKey])) {
combinedObject[subKey] = schemaValue[subKey];
// If both keys are arrays, include all items from both arrays,
// excluding duplicates
}
else if (isArray(schemaValue[subKey]) && isArray(combinedObject[subKey])) {
combinedObject[subKey] = uniqueItems.apply(void 0, tslib_1.__spread(combinedObject[subKey], schemaValue[subKey]));
// If either key is an object, merge the schemas
}
else if ((isArray(schemaValue[subKey]) || isObject(schemaValue[subKey])) &&
(isArray(combinedObject[subKey]) || isObject(combinedObject[subKey]))) {
// If either key is an array, convert it to an object first
var required = isArray(combinedSchema.required) ?
combinedSchema.required : [];
var combinedDependency = isArray(combinedObject[subKey]) ?
{ required: uniqueItems.apply(void 0, tslib_1.__spread(required, [combinedObject[subKey]])) } :
combinedObject[subKey];
var schemaDependency = isArray(schemaValue[subKey]) ?
{ required: uniqueItems.apply(void 0, tslib_1.__spread(required, [schemaValue[subKey]])) } :
schemaValue[subKey];
combinedObject[subKey] =
mergeSchemas(combinedDependency, schemaDependency);
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
}
finally { if (e_4) throw e_4.error; }
}
combinedSchema.dependencies = combinedObject;
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'items':
// If arrays, keep only items that appear in both arrays
if (isArray(combinedValue) && isArray(schemaValue)) {
combinedSchema.items = combinedValue.filter(function (item1) {
return schemaValue.findIndex(function (item2) { return isEqual(item1, item2); }) > -1;
});
if (!combinedSchema.items.length) {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
// If both keys are objects, merge them
}
else if (isObject(combinedValue) && isObject(schemaValue)) {
combinedSchema.items = mergeSchemas(combinedValue, schemaValue);
// If object + array, combine object with each array item
}
else if (isArray(combinedValue) && isObject(schemaValue)) {
combinedSchema.items =
combinedValue.map(function (item) { return mergeSchemas(item, schemaValue); });
}
else if (isObject(combinedValue) && isArray(schemaValue)) {
combinedSchema.items =
schemaValue.map(function (item) { return mergeSchemas(item, combinedValue); });
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'multipleOf':
// TODO: Adjust to correctly handle decimal values
// If numbers, set to least common multiple
if (isNumber(combinedValue) && isNumber(schemaValue)) {
var gcd_1 = function (x, y) { return !y ? x : gcd_1(y, x % y); };
var lcm = function (x, y) { return (x * y) / gcd_1(x, y); };
combinedSchema.multipleOf = lcm(combinedValue, schemaValue);
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'maximum':
case 'exclusiveMaximum':
case 'maxLength':
case 'maxItems':
case 'maxProperties':
// If numbers, set to lowest value
if (isNumber(combinedValue) && isNumber(schemaValue)) {
combinedSchema[key] = Math.min(combinedValue, schemaValue);
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'minimum':
case 'exclusiveMinimum':
case 'minLength':
case 'minItems':
case 'minProperties':
// If numbers, set to highest value
if (isNumber(combinedValue) && isNumber(schemaValue)) {
combinedSchema[key] = Math.max(combinedValue, schemaValue);
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'not':
// Combine not values into anyOf array
if (isObject(combinedValue) && isObject(schemaValue)) {
var notAnyOf = [combinedValue, schemaValue]
.reduce(function (notAnyOfArray, notSchema) {
return isArray(notSchema.anyOf) &&
Object.keys(notSchema).length === 1 ? tslib_1.__spread(notAnyOfArray, notSchema.anyOf) : tslib_1.__spread(notAnyOfArray, [notSchema]);
}, []);
// TODO: Remove duplicate items from array
combinedSchema.not = { anyOf: notAnyOf };
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'patternProperties':
// Combine all keys from both objects
// and merge schemas on matching keys
if (isObject(combinedValue) && isObject(schemaValue)) {
var combinedObject = tslib_1.__assign({}, combinedValue);
try {
for (var _j = tslib_1.__values(Object.keys(schemaValue)), _k = _j.next(); !_k.done; _k = _j.next()) {
var subKey = _k.value;
if (!hasOwn(combinedObject, subKey) ||
isEqual(combinedObject[subKey], schemaValue[subKey])) {
combinedObject[subKey] = schemaValue[subKey];
// If both keys are objects, merge them
}
else if (isObject(schemaValue[subKey]) && isObject(combinedObject[subKey])) {
combinedObject[subKey] =
mergeSchemas(combinedObject[subKey], schemaValue[subKey]);
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
}
}
catch (e_5_1) { e_5 = { error: e_5_1 }; }
finally {
try {
if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
}
finally { if (e_5) throw e_5.error; }
}
combinedSchema.patternProperties = combinedObject;
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'properties':
// Combine all keys from both objects
// unless additionalProperties === false
// and merge schemas on matching keys
if (isObject(combinedValue) && isObject(schemaValue)) {
var combinedObject_1 = tslib_1.__assign({}, combinedValue);
// If new schema has additionalProperties,
// merge or remove non-matching property keys in combined schema
if (hasOwn(schemaValue, 'additionalProperties')) {
Object.keys(combinedValue)
.filter(function (combinedKey) { return !Object.keys(schemaValue).includes(combinedKey); })
.forEach(function (nonMatchingKey) {
if (schemaValue.additionalProperties === false) {
delete combinedObject_1[nonMatchingKey];
}
else if (isObject(schemaValue.additionalProperties)) {
combinedObject_1[nonMatchingKey] = mergeSchemas(combinedObject_1[nonMatchingKey], schemaValue.additionalProperties);
}
});
}
try {
for (var _l = tslib_1.__values(Object.keys(schemaValue)), _m = _l.next(); !_m.done; _m = _l.next()) {
var subKey = _m.value;
if (isEqual(combinedObject_1[subKey], schemaValue[subKey]) || (!hasOwn(combinedObject_1, subKey) &&
!hasOwn(combinedObject_1, 'additionalProperties'))) {
combinedObject_1[subKey] = schemaValue[subKey];
// If combined schema has additionalProperties,
// merge or ignore non-matching property keys in new schema
}
else if (!hasOwn(combinedObject_1, subKey) &&
hasOwn(combinedObject_1, 'additionalProperties')) {
// If combinedObject.additionalProperties === false,
// do nothing (don't set key)
// If additionalProperties is object, merge with new key
if (isObject(combinedObject_1.additionalProperties)) {
combinedObject_1[subKey] = mergeSchemas(combinedObject_1.additionalProperties, schemaValue[subKey]);
}
// If both keys are objects, merge them
}
else if (isObject(schemaValue[subKey]) &&
isObject(combinedObject_1[subKey])) {
combinedObject_1[subKey] =
mergeSchemas(combinedObject_1[subKey], schemaValue[subKey]);
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
}
}
catch (e_6_1) { e_6 = { error: e_6_1 }; }
finally {
try {
if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
}
finally { if (e_6) throw e_6.error; }
}
combinedSchema.properties = combinedObject_1;
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'required':
// If arrays, include all items from both arrays, excluding duplicates
if (isArray(combinedValue) && isArray(schemaValue)) {
combinedSchema.required = uniqueItems.apply(void 0, tslib_1.__spread(combinedValue, schemaValue));
// If booleans, aet true if either true
}
else if (typeof schemaValue === 'boolean' &&
typeof combinedValue === 'boolean') {
combinedSchema.required = !!combinedValue || !!schemaValue;
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case '$schema':
case '$id':
case 'id':
// Don't combine these keys
break;
case 'title':
case 'description':
case '$comment':
// Return the last value, overwriting any previous one
// These properties are not used for validation, so conflicts don't matter
combinedSchema[key] = schemaValue;
break;
case 'type':
if ((isArray(schemaValue) || isString(schemaValue)) &&
(isArray(combinedValue) || isString(combinedValue))) {
var combinedTypes = commonItems(combinedValue, schemaValue);
if (!combinedTypes.length) {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
combinedSchema.type = combinedTypes.length > 1 ? combinedTypes : combinedTypes[0];
}
else {
return { value: { allOf: tslib_1.__spread(schemas) } };
}
break;
case 'uniqueItems':
// Set true if either true
combinedSchema.uniqueItems = !!combinedValue || !!schemaValue;
break;
default: return { value: { allOf: tslib_1.__spread(schemas) } };
}
}
};
try {
for (var _c = tslib_1.__values(Object.keys(schema)), _d = _c.next(); !_d.done; _d = _c.next()) {
var key = _d.value;
var state_1 = _loop_1(key);
if (typeof state_1 === "object")
return state_1.value;
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
}
finally { if (e_2) throw e_2.error; }
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (schemas_1_1 && !schemas_1_1.done && (_a = schemas_1.return)) _a.call(schemas_1);
}
finally { if (e_1) throw e_1.error; }
}
return combinedSchema;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVyZ2Utc2NoZW1hcy5mdW5jdGlvbi5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2FuZ3VsYXI2LWpzb24tc2NoZW1hLWZvcm0vIiwic291cmNlcyI6WyJsaWIvc2hhcmVkL21lcmdlLXNjaGVtYXMuZnVuY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBRXhDLE9BQU8sRUFDTCxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUMvQyxNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBR3ZFOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sVUFBVSxZQUFZOztJQUFDLGlCQUFVO1NBQVYsVUFBVSxFQUFWLHFCQUFVLEVBQVYsSUFBVTtRQUFWLDRCQUFVOztJQUNyQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFBLE1BQU0sSUFBSSxPQUFBLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFoQixDQUFnQixDQUFDLENBQUM7SUFDckQsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQUEsTUFBTSxJQUFJLE9BQUEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQWpCLENBQWlCLENBQUMsRUFBRTtRQUFFLE9BQU8sSUFBSSxDQUFDO0tBQUU7SUFDL0QsSUFBTSxjQUFjLEdBQVEsRUFBRSxDQUFDOztRQUMvQixLQUFxQixJQUFBLFlBQUEsaUJBQUEsT0FBTyxDQUFBLGdDQUFBLHFEQUFFO1lBQXpCLElBQU0sTUFBTSxvQkFBQTtvQ0FDSixHQUFHOztnQkFDWixJQUFNLGFBQWEsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzFDLElBQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDaEMsSUFBSSxD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LGlCQUNDLEVBQUUsS0FBSyxtQkFBTyxPQUFPLENBQUUsRUFBRSxHQUFDO3FCQUNwQztpQkFDRjs7O2dCQXJTSCxLQUFrQixJQUFBLEtBQUEsaUJBQUEsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQSxnQkFBQTtvQkFBaEMsSUFBTSxHQUFHLFdBQUE7MENBQUgsR0FBRzs7O2lCQXNTYjs7Ozs7Ozs7O1NBQ0Y7Ozs7Ozs7OztJQUNELE9BQU8sY0FBYyxDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgaXNFcXVhbCBmcm9tICdsb2Rhc2gtZXMvaXNFcXVhbCc7XG5cbmltcG9ydCB7XG4gIGlzQXJyYXksIGlzRW1wdHksIGlzTnVtYmVyLCBpc09iamVjdCwgaXNTdHJpbmdcbn0gZnJvbSAnLi92YWxpZGF0b3IuZnVuY3Rpb25zJztcbmltcG9ydCB7IGhhc093biwgdW5pcXVlSXRlbXMsIGNvbW1vbkl0ZW1zIH0gZnJvbSAnLi91dGlsaXR5LmZ1bmN0aW9ucyc7XG5pbXBvcnQgeyBKc29uUG9pbnRlciwgUG9pbnRlciB9IGZyb20gJy4vanNvbnBvaW50ZXIuZnVuY3Rpb25zJztcblxuLyoqXG4gKiAnbWVyZ2VTY2hlbWFzJyBmdW5jdGlvblxuICpcbiAqIE1lcmdlcyBtdWx0aXBsZSBKU09OIHNjaGVtYXMgaW50byBhIHNpbmdsZSBzY2hlbWEgd2l0aCBjb21iaW5lZCBydWxlcy5cbiAqXG4gKiBJZiBhYmxlIHRvIGxvZ2ljYWxseSBtZXJnZSBwcm9wZXJ0aWVzIGZyb20gYWxsIHNjaGVtYXMsXG4gKiByZXR1cm5zIGEgc2luZ2xlIHNjaGVtYSBvYmplY3QgY29udGFpbmluZyBhbGwgbWVyZ2VkIHByb3BlcnRpZXMuXG4gKlxuICogRXhhbXBsZTogKHsgYTogYiwgbWF4OiAxIH0sIHsgYzogZCwgbWF4OiAyIH0pID0+IHsgYTogYiwgYzogZCwgbWF4OiAxIH1cbiAqXG4gKiBJZiB1bmFibGUgdG8gbG9naWNhbGx5IG1lcmdlLCByZXR1cm5zIGFuIGFsbE9mIHNjaGVtYSBvYmplY3QgY29udGFpbmluZ1xuICogYW4gYXJyYXkgb2YgdGhlIG9yaWdpbmFsIHNjaGVtYXM7XG4gKlxuICogRXhhbXBsZTogKHsgYTogYiB9LCB7IGE6IGQgfSkgPT4geyBhbGxPZjogWyB7IGE6IGIgfSwgeyBhOiBkIH0gXSB9XG4gKlxuICogLy8gICBzY2hlbWFzIC0gb25lIG9yIG1vcmUgaW5wdXQgc2NoZW1hc1xuICogLy8gIC0gbWVyZ2VkIHNjaGVtYVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VTY2hlbWFzKC4uLnNjaGVtYXMpIHtcbiAgc2NoZW1hcyA9IHNjaGVtYXMuZmlsdGVyKHNjaGVtYSA9PiAhaXNFbXB0eShzY2hlbWEpKTtcbiAgaWYgKHNjaGVtYXMuc29tZShzY2hlbWEgPT4gIWlzT2JqZWN0KHNjaGVtYSkpKSB7IHJldHVybiBudWxsOyB9XG4gIGNvbnN0IGNvbWJpbmVkU2NoZW1hOiBhbnkgPSB7fTtcbiAgZm9yIChjb25zdCBzY2hlbWEgb2Ygc2NoZW1hcykge1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHNjaGVtYSkpIHtcbiAgICAgIGNvbnN0IGNvbWJpbmVkVmFsdWUgPSBjb21iaW5lZFNjaGVtYVtrZXldO1xuICAgICAgY29uc3Qgc2NoZW1hVmFsdWUgPSBzY2hlbWFba2V5XTtcbiAgICAgIGlmICghaGFzT3duKGNvbWJpbmVkU2NoZW1hLCBrZXkpIHx8IGlzRXF1YWwoY29tYmluZWRWYWx1ZSwgc2NoZW1hVmFsdWUpKSB7XG4gICAgICAgIGNvbWJpbmVkU2NoZW1hW2tleV0gPSBzY2hlbWFWYWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgICAgY2FzZSAnYWxsT2YnOlxuICAgICAgICAgICAgLy8gQ29tYmluZSBhbGwgaXRlbXMgZnJvbSBib3RoIGFycmF5c1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkoY29tYmluZWRWYWx1ZSkgJiYgaXNBcnJheShzY2hlbWFWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgY29tYmluZWRTY2hlbWEuYWxsT2YgPSBtZXJnZVNjaGVtYXMoLi4uY29tYmluZWRWYWx1ZSwgLi4uc2NoZW1hVmFsdWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnYWRkaXRpb25hbEl0ZW1zJzogY2FzZSAnYWRkaXRpb25hbFByb3BlcnRpZXMnOlxuICAgICAgICAgIGNhc2UgJ2NvbnRhaW5zJzogY2FzZSAncHJvcGVydHlOYW1lcyc6XG4gICAgICAgICAgICAvLyBNZXJnZSBzY2hlbWEgb2JqZWN0c1xuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KGNvbWJpbmVkVmFsdWUpICYmIGlzT2JqZWN0KHNjaGVtYVZhbHVlKSkge1xuICAgICAgICAgICAgICBjb21iaW5lZFNjaGVtYVtrZXldID0gbWVyZ2VTY2hlbWFzKGNvbWJpbmVkVmFsdWUsIHNjaGVtYVZhbHVlKTtcbiAgICAgICAgICAgIC8vIGFkZGl0aW9uYWxQcm9wZXJ0aWVzID09IGZhbHNlIGluIGFueSBzY2hlbWEgb3ZlcnJpZGVzIGFsbCBvdGhlciB2YWx1ZXNcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgIGtleSA9PT0gJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJyAmJlxuICAgICAgICAgICAgICAoY29tYmluZWRWYWx1ZSA9PT0gZmFsc2UgfHwgc2NoZW1hVmFsdWUgPT09IGZhbHNlKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLmNvbWJpbmVkU2NoZW1hID0gZmFsc2U7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4geyBhbGxPZjogWyAuLi5zY2hlbWFzIF0gfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdhbnlPZic6IGNhc2UgJ29uZU9mJzogY2FzZSAnZW51bSc6XG4gICAgICAgICAgICAvLyBLZWVwIG9ubHkgaXRlbXMgdGhhdCBhcHBlYXIgaW4gYm90aCBhcnJheXNcbiAgICAgICAgICAgIGlmIChpc0FycmF5KGNvbWJpbmVkVmFsdWUpICYmIGlzQXJyYXkoc2NoZW1hVmFsdWUpKSB7XG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hW2tleV0gPSBjb21iaW5lZFZhbHVlLmZpbHRlcihpdGVtMSA9PlxuICAgICAgICAgICAgICAgIHNjaGVtYVZhbHVlLmZpbmRJbmRleChpdGVtMiA9PiBpc0VxdWFsKGl0ZW0xLCBpdGVtMikpID4gLTFcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgaWYgKCFjb21iaW5lZFNjaGVtYVtrZXldLmxlbmd0aCkgeyByZXR1cm4geyBhbGxPZjogWyAuLi5zY2hlbWFzIF0gfTsgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZGVmaW5pdGlvbnMnOlxuICAgICAgICAgICAgLy8gQ29tYmluZSBrZXlzIGZyb20gYm90aCBvYmplY3RzXG4gICAgICAgICAgICBpZiAoaXNPYmplY3QoY29tYmluZWRWYWx1ZSkgJiYgaXNPYmplY3Qoc2NoZW1hVmFsdWUpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGNvbWJpbmVkT2JqZWN0ID0geyAuLi5jb21iaW5lZFZhbHVlIH07XG4gICAgICAgICAgICAgIGZvciAoY29uc3Qgc3ViS2V5IG9mIE9iamVjdC5rZXlzKHNjaGVtYVZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGlmICghaGFzT3duKGNvbWJpbmVkT2JqZWN0LCBzdWJLZXkpIHx8XG4gICAgICAgICAgICAgICAgICBpc0VxdWFsKGNvbWJpbmVkT2JqZWN0W3N1YktleV0sIHNjaGVtYVZhbHVlW3N1YktleV0pXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICBjb21iaW5lZE9iamVjdFtzdWJLZXldID0gc2NoZW1hVmFsdWVbc3ViS2V5XTtcbiAgICAgICAgICAgICAgICAvLyBEb24ndCBjb21iaW5lIG1hdGNoaW5nIGtleXMgd2l0aCBkaWZmZXJlbnQgdmFsdWVzXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB7IGFsbE9mOiBbIC4uLnNjaGVtYXMgXSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjb21iaW5lZFNjaGVtYS5kZWZpbml0aW9ucyA9IGNvbWJpbmVkT2JqZWN0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZGVwZW5kZW5jaWVzJzpcbiAgICAgICAgICAgIC8vIENvbWJpbmUgYWxsIGtleXMgZnJvbSBib3RoIG9iamVjdHNcbiAgICAgICAgICAgIC8vIGFuZCBtZXJnZSBzY2hlbWFzIG9uIG1hdGNoaW5nIGtleXMsXG4gICAgICAgICAgICAvLyBjb252ZXJ0aW5nIGZyb20gYXJyYXlzIHRvIG9iamVjdHMgaWYgbmVjZXNzYXJ5XG4gICAgICAgICAgICBpZiAoaXNPYmplY3QoY29tYmluZWRWYWx1ZSkgJiYgaXNPYmplY3Qoc2NoZW1hVmFsdWUpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGNvbWJpbmVkT2JqZWN0ID0geyAuLi5jb21iaW5lZFZhbHVlIH07XG4gICAgICAgICAgICAgIGZvciAoY29uc3Qgc3ViS2V5IG9mIE9iamVjdC5rZXlzKHNjaGVtYVZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGlmICghaGFzT3duKGNvbWJpbmVkT2JqZWN0LCBzdWJLZXkpIHx8XG4gICAgICAgICAgICAgICAgICBpc0VxdWFsKGNvbWJpbmVkT2JqZWN0W3N1YktleV0sIHNjaGVtYVZhbHVlW3N1YktleV0pXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICBjb21iaW5lZE9iamVjdFtzdWJLZXldID0gc2NoZW1hVmFsdWVbc3ViS2V5XTtcbiAgICAgICAgICAgICAgICAvLyBJZiBib3RoIGtleXMgYXJlIGFycmF5cywgaW5jbHVkZSBhbGwgaXRlbXMgZnJvbSBib3RoIGFycmF5cyxcbiAgICAgICAgICAgICAgICAvLyBleGNsdWRpbmcgZHVwbGljYXRlc1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgICBpc0FycmF5KHNjaGVtYVZhbHVlW3N1YktleV0pICYmIGlzQXJyYXkoY29tYmluZWRPYmplY3Rbc3ViS2V5XSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIGNvbWJpbmVkT2JqZWN0W3N1YktleV0gPVxuICAgICAgICAgICAgICAgICAgICB1bmlxdWVJdGVtcyguLi5jb21iaW5lZE9iamVjdFtzdWJLZXldLCAuLi5zY2hlbWFWYWx1ZVtzdWJLZXldKTtcbiAgICAgICAgICAgICAgICAvLyBJZiBlaXRoZXIga2V5IGlzIGFuIG9iamVjdCwgbWVyZ2UgdGhlIHNjaGVtYXNcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgICAgKGlzQXJyYXkoc2NoZW1hVmFsdWVbc3ViS2V5XSkgfHwgaXNPYmplY3Qoc2NoZW1hVmFsdWVbc3ViS2V5XSkpICYmXG4gICAgICAgICAgICAgICAgICAoaXNBcnJheShjb21iaW5lZE9iamVjdFtzdWJLZXldKSB8fCBpc09iamVjdChjb21iaW5lZE9iamVjdFtzdWJLZXldKSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIC8vIElmIGVpdGhlciBrZXkgaXMgYW4gYXJyYXksIGNvbnZlcnQgaXQgdG8gYW4gb2JqZWN0IGZpcnN0XG4gICAgICAgICAgICAgICAgICBjb25zdCByZXF1aXJlZCA9IGlzQXJyYXkoY29tYmluZWRTY2hlbWEucmVxdWlyZWQpID9cbiAgICAgICAgICAgICAgICAgICAgY29tYmluZWRTY2hlbWEucmVxdWlyZWQgOiBbXTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbWJpbmVkRGVwZW5kZW5jeSA9IGlzQXJyYXkoY29tYmluZWRPYmplY3Rbc3ViS2V5XSkgP1xuICAgICAgICAgICAgICAgICAgICB7IHJlcXVpcmVkOiB1bmlxdWVJdGVtcyguLi5yZXF1aXJlZCwgY29tYmluZWRPYmplY3Rbc3ViS2V5XSkgfSA6XG4gICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkT2JqZWN0W3N1YktleV07XG4gICAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWFEZXBlbmRlbmN5ID0gaXNBcnJheShzY2hlbWFWYWx1ZVtzdWJLZXldKSA/XG4gICAgICAgICAgICAgICAgICAgIHsgcmVxdWlyZWQ6IHVuaXF1ZUl0ZW1zKC4uLnJlcXVpcmVkLCBzY2hlbWFWYWx1ZVtzdWJLZXldKSB9IDpcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hVmFsdWVbc3ViS2V5XTtcbiAgICAgICAgICAgICAgICAgIGNvbWJpbmVkT2JqZWN0W3N1YktleV0gPVxuICAgICAgICAgICAgICAgICAgICBtZXJnZVNjaGVtYXMoY29tYmluZWREZXBlbmRlbmN5LCBzY2hlbWFEZXBlbmRlbmN5KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLmRlcGVuZGVuY2llcyA9IGNvbWJpbmVkT2JqZWN0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnaXRlbXMnOlxuICAgICAgICAgICAgLy8gSWYgYXJyYXlzLCBrZWVwIG9ubHkgaXRlbXMgdGhhdCBhcHBlYXIgaW4gYm90aCBhcnJheXNcbiAgICAgICAgICAgIGlmIChpc0FycmF5KGNvbWJpbmVkVmFsdWUpICYmIGlzQXJyYXkoc2NoZW1hVmFsdWUpKSB7XG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLml0ZW1zID0gY29tYmluZWRWYWx1ZS5maWx0ZXIoaXRlbTEgPT5cbiAgICAgICAgICAgICAgICBzY2hlbWFWYWx1ZS5maW5kSW5kZXgoaXRlbTIgPT4gaXNFcXVhbChpdGVtMSwgaXRlbTIpKSA+IC0xXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmICghY29tYmluZWRTY2hlbWEuaXRlbXMubGVuZ3RoKSB7IHJldHVybiB7IGFsbE9mOiBbIC4uLnNjaGVtYXMgXSB9OyB9XG4gICAgICAgICAgICAvLyBJZiBib3RoIGtleXMgYXJlIG9iamVjdHMsIG1lcmdlIHRoZW1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QoY29tYmluZWRWYWx1ZSkgJiYgaXNPYmplY3Qoc2NoZW1hVmFsdWUpKSB7XG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLml0ZW1zID0gbWVyZ2VTY2hlbWFzKGNvbWJpbmVkVmFsdWUsIHNjaGVtYVZhbHVlKTtcbiAgICAgICAgICAgIC8vIElmIG9iamVjdCArIGFycmF5LCBjb21iaW5lIG9iamVjdCB3aXRoIGVhY2ggYXJyYXkgaXRlbVxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc0FycmF5KGNvbWJpbmVkVmFsdWUpICYmIGlzT2JqZWN0KHNjaGVtYVZhbHVlKSkge1xuICAgICAgICAgICAgICBjb21iaW5lZFNjaGVtYS5pdGVtcyA9XG4gICAgICAgICAgICAgICAgY29tYmluZWRWYWx1ZS5tYXAoaXRlbSA9PiBtZXJnZVNjaGVtYXMoaXRlbSwgc2NoZW1hVmFsdWUpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QoY29tYmluZWRWYWx1ZSkgJiYgaXNBcnJheShzY2hlbWFWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgY29tYmluZWRTY2hlbWEuaXRlbXMgPVxuICAgICAgICAgICAgICAgIHNjaGVtYVZhbHVlLm1hcChpdGVtID0+IG1lcmdlU2NoZW1hcyhpdGVtLCBjb21iaW5lZFZhbHVlKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4geyBhbGxPZjogWyAuLi5zY2hlbWFzIF0gfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdtdWx0aXBsZU9mJzpcbiAgICAgICAgICAgIC8vIFRPRE86IEFkanVzdCB0byBjb3JyZWN0bHkgaGFuZGxlIGRlY2