@openfisca/json-model
Version:
Library to handle informations extracted in JSON or YAML format from OpenFisca parameters, variables, etc
233 lines (228 loc) • 46.9 kB
JavaScript
import { auditArray, auditBoolean, auditChain, auditCleanArray, auditFunction, auditKeyValueDictionary, auditNoop, auditNumber, auditOptions, auditRequire, auditString, auditSwitch, auditTest, auditTrimString, auditUnique } from "@auditors/core";
import { auditDate } from "../periods.js";
import { auditReference, auditReferencesByDate } from "../references.js";
import { ParameterClass, revaluationTypes, ScaleType, ValueType } from "../../parameters.js";
export function auditEditableAmountBracket(units) {
return function (audit, dataUnknown) {
if (dataUnknown == null) {
return [dataUnknown, null];
}
if (typeof dataUnknown !== "object") {
return audit.unexpectedType(dataUnknown, "object");
}
const data = {
...dataUnknown
};
const errors = {};
const remainingKeys = new Set(Object.keys(data));
audit.attribute(data, "amount", true, errors, remainingKeys, auditKeyValueDictionary(auditDate, [auditEditableValueOrExpected(units, auditNumber), auditRequire]), auditRequire);
audit.attribute(data, "threshold", true, errors, remainingKeys, auditKeyValueDictionary(auditDate, [auditEditableValueOrExpected(units, auditNumber), auditRequire]), auditRequire);
return audit.reduceRemaining(data, errors, remainingKeys);
};
}
export function auditEditableParameter(units, childrenId) {
return function (audit, dataUnknown) {
if (dataUnknown == null) {
return [dataUnknown, null];
}
if (typeof dataUnknown !== "object") {
return audit.unexpectedType(dataUnknown, "object");
}
const data = {
...dataUnknown
};
const errors = {};
const remainingKeys = new Set(Object.keys(data));
audit.attribute(data, "class", true, errors, remainingKeys, auditOptions(Object.values(ParameterClass)));
for (const key of ["description", "label_en", "documentation", "file_path", "short_label", "short_label_en"]) {
audit.attribute(data, key, true, errors, remainingKeys, auditTrimString);
}
audit.attribute(data, "documentation_start", true, errors, remainingKeys, auditBoolean, auditFunction(value => value ? true : null));
audit.attribute(data, "inflator", true, errors, remainingKeys, auditTrimString);
audit.attribute(data, "inflator_reference", true, errors, remainingKeys, auditReferencesByDate);
audit.attribute(data, "income_tax_year", true, errors, remainingKeys, auditBoolean);
audit.attribute(data, "last_value_still_valid_on", true, errors, remainingKeys, auditDate);
audit.attribute(data, "name", true, errors, remainingKeys, auditTrimString
// auditTest((name) => {
// const ids = name.split(".")
// return ids[ids.length - 1].match(/^[\d]/) === null
// }, "Last part of name must not start with a digit"),
);
audit.attribute(data, "notes", true, errors, remainingKeys, auditReferencesByDate);
audit.attribute(data, "official_journal_date", true, errors, remainingKeys, auditKeyValueDictionary(auditDate, [auditSwitch(auditDate, [auditString, auditFunction(text => text.split(";")), auditArray(auditDate),
// TODO: Return something other than a string?
auditFunction(instants => instants.join("; "))]), auditRequire]));
audit.attribute(data, "reference", true, errors, remainingKeys, auditReferencesByDate);
audit.attribute(data, "revaluation_reference", true, errors, remainingKeys, auditReferencesByDate);
audit.attribute(data, "revaluation_type", true, errors, remainingKeys, auditTrimString, auditOptions(revaluationTypes));
if (errors.class === undefined) {
switch (data.class) {
case ParameterClass.Node:
{
audit.attribute(data, "children", true, errors, remainingKeys, auditKeyValueDictionary(auditString, [auditEditableParameter(units), auditRequire])
// auditRequire, // A node may have no child (especially unprocessed nodes).
);
audit.attribute(data, "order", true, errors, remainingKeys, auditCleanArray(auditString, childrenId === undefined ? errors.children === undefined && data.children !== undefined ? auditOptions(Object.keys(data.children)) : auditNoop : auditOptions(childrenId)), auditUnique);
audit.attribute(data, "unit", true, errors, remainingKeys, auditEditableUnitName(units));
break;
}
case ParameterClass.Scale:
{
// Used only for compatibility with "barèmes IPP".
audit.attribute(data, "ipp_csv_id", true, errors, remainingKeys, auditSwitch(auditTrimString, auditKeyValueDictionary(auditOptions(["amount", "average_rate", "base", "rate", "threshold"]), [auditTrimString, auditRequire])));
audit.attribute(data, "type", true, errors, remainingKeys, auditOptions(Object.values(ScaleType)), auditRequire);
const type = data.type;
audit.attribute(data, "brackets", true, errors, remainingKeys, auditArray(errors.type === undefined ? [ScaleType.MarginalAmount, ScaleType.SingleAmount].includes(type) ? auditEditableAmountBracket(units) : auditEditableRateBracket(units) : auditNoop, auditRequire), auditRequire);
if (errors.type === undefined) {
if ([ScaleType.MarginalAmount, ScaleType.SingleAmount].includes(type)) {
audit.attribute(data, "amount_unit", true, errors, remainingKeys, auditEditableUnitName(units));
} else {
audit.attribute(data, "rate_unit", true, errors, remainingKeys, auditEditableUnitName(units));
}
audit.attribute(data, "threshold_unit", true, errors, remainingKeys, auditEditableUnitName(units));
} else {
for (const key of ["rate_unit", "threshold_unit", "unit"]) {
audit.attribute(data, key, true, errors, remainingKeys, auditNoop);
}
}
audit.attribute(
// UK
data, "period", true, errors, remainingKeys, auditString, auditOptions(["hour",
// UK
"month",
// UK
"week",
// UK
"year" // UK
]));
break;
}
case ParameterClass.Value:
{
// Used only for compatibility "barèmes IPP".
audit.attribute(data, "ipp_csv_id", true, errors, remainingKeys, auditTrimString);
audit.attribute(data, "type", true, errors, remainingKeys, auditOptions(Object.values(ValueType)));
audit.attribute(
// UK
data, "period", true, errors, remainingKeys, auditString, auditOptions(["hour",
// UK
"month",
// UK
"week",
// UK
"year" // UK
]));
audit.attribute(data, "unit", true, errors, remainingKeys, auditEditableUnitName(units));
const type = data.type;
audit.attribute(data, "values", true, errors, remainingKeys, auditKeyValueDictionary(auditDate, [auditEditableValueOrExpected(units, errors.type === undefined ? type === ValueType.Boolean ? auditBoolean : type === ValueType.Number ? auditNumber : type === ValueType.StringArray ? auditArray(auditString) :
// type === ValueType.StringByString
auditKeyValueDictionary(auditString, auditString) : auditNoop), auditRequire]), auditRequire);
// if (errors.values === undefined) {
// const validDates = new Set(
// Object.keys(data.values as { [date: string]: unknown }),
// )
// validDates.add("0001-01-01")
// if (errors.notes === undefined) {
// audit.attribute(
// data,
// "notes",
// true,
// errors,
// remainingKeys,
// auditKeyValueDictionary(
// auditTest(
// (date) => validDates.has(date),
// (date) => `Parameter has no value for date ${date}`,
// ),
// auditNoop,
// ),
// )
// }
// if (errors.official_journal_date === undefined) {
// audit.attribute(
// data,
// "official_journal_date",
// true,
// errors,
// remainingKeys,
// auditKeyValueDictionary(
// auditTest(
// (date) => validDates.has(date),
// (date) => `Parameter has no value for date ${date}`,
// ),
// auditNoop,
// ),
// )
// }
// if (errors.reference === undefined) {
// audit.attribute(
// data,
// "reference",
// true,
// errors,
// remainingKeys,
// auditKeyValueDictionary(
// auditTest(
// (date) => validDates.has(date),
// (date) => `Parameter has no value for date ${date}`,
// ),
// auditNoop,
// ),
// )
// }
// }
break;
}
}
}
return audit.reduceRemaining(data, errors, remainingKeys);
};
}
export function auditEditableRateBracket(units) {
return function (audit, dataUnknown) {
if (dataUnknown == null) {
return [dataUnknown, null];
}
if (typeof dataUnknown !== "object") {
return audit.unexpectedType(dataUnknown, "object");
}
const data = {
...dataUnknown
};
const errors = {};
const remainingKeys = new Set(Object.keys(data));
audit.attribute(data, "base", true, errors, remainingKeys, auditKeyValueDictionary(auditDate, [auditEditableValueOrExpected(units, auditNumber), auditRequire]));
audit.attribute(data, "rate", true, errors, remainingKeys, auditKeyValueDictionary(auditDate, auditEditableValueOrExpected(units, auditNumber)), auditRequire);
audit.attribute(data, "threshold", true, errors, remainingKeys, auditKeyValueDictionary(auditDate, [auditEditableValueOrExpected(units, auditNumber), auditRequire]), auditRequire);
return audit.reduceRemaining(data, errors, remainingKeys);
};
}
export function auditEditableUnitName(units) {
const unitsName = units.map(({
name
}) => name);
return auditChain(auditString, auditOptions(unitsName));
}
export function auditEditableValue(units, ...auditors) {
return (audit, dataUnknown) => {
if (dataUnknown == null) {
return [dataUnknown, null];
}
if (typeof dataUnknown !== "object") {
return audit.unexpectedType(dataUnknown, "object");
}
const data = {
...dataUnknown
};
const errors = {};
const remainingKeys = new Set(Object.keys(data));
audit.attribute(data, "reference", true, errors, remainingKeys, auditCleanArray(auditReference));
audit.attribute(data, "unit", true, errors, remainingKeys, auditEditableUnitName(units));
audit.attribute(data, "value", false,
// Keep null value.
errors, remainingKeys, ...auditors);
return audit.reduceRemaining(data, errors, remainingKeys);
};
}
export const auditEditableValueOrExpected = (units, ...auditors) => auditSwitch(auditTest(value => value === "expected"), auditEditableValue(units, ...auditors));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhdWRpdEFycmF5IiwiYXVkaXRCb29sZWFuIiwiYXVkaXRDaGFpbiIsImF1ZGl0Q2xlYW5BcnJheSIsImF1ZGl0RnVuY3Rpb24iLCJhdWRpdEtleVZhbHVlRGljdGlvbmFyeSIsImF1ZGl0Tm9vcCIsImF1ZGl0TnVtYmVyIiwiYXVkaXRPcHRpb25zIiwiYXVkaXRSZXF1aXJlIiwiYXVkaXRTdHJpbmciLCJhdWRpdFN3aXRjaCIsImF1ZGl0VGVzdCIsImF1ZGl0VHJpbVN0cmluZyIsImF1ZGl0VW5pcXVlIiwiYXVkaXREYXRlIiwiYXVkaXRSZWZlcmVuY2UiLCJhdWRpdFJlZmVyZW5jZXNCeURhdGUiLCJQYXJhbWV0ZXJDbGFzcyIsInJldmFsdWF0aW9uVHlwZXMiLCJTY2FsZVR5cGUiLCJWYWx1ZVR5cGUiLCJhdWRpdEVkaXRhYmxlQW1vdW50QnJhY2tldCIsInVuaXRzIiwiYXVkaXQiLCJkYXRhVW5rbm93biIsInVuZXhwZWN0ZWRUeXBlIiwiZGF0YSIsImVycm9ycyIsInJlbWFpbmluZ0tleXMiLCJTZXQiLCJPYmplY3QiLCJrZXlzIiwiYXR0cmlidXRlIiwiYXVkaXRFZGl0YWJsZVZhbHVlT3JFeHBlY3RlZCIsInJlZHVjZVJlbWFpbmluZyIsImF1ZGl0RWRpdGFibGVQYXJhbWV0ZXIiLCJjaGlsZHJlbklkIiwidmFsdWVzIiwia2V5IiwidmFsdWUiLCJ0ZXh0Iiwic3BsaXQiLCJpbnN0YW50cyIsImpvaW4iLCJjbGFzcyIsInVuZGVmaW5lZCIsIk5vZGUiLCJjaGlsZHJlbiIsImF1ZGl0RWRpdGFibGVVbml0TmFtZSIsIlNjYWxlIiwidHlwZSIsIk1hcmdpbmFsQW1vdW50IiwiU2luZ2xlQW1vdW50IiwiaW5jbHVkZXMiLCJhdWRpdEVkaXRhYmxlUmF0ZUJyYWNrZXQiLCJWYWx1ZSIsIkJvb2xlYW4iLCJOdW1iZXIiLCJTdHJpbmdBcnJheSIsInVuaXRzTmFtZSIsIm1hcCIsIm5hbWUiLCJhdWRpdEVkaXRhYmxlVmFsdWUiLCJhdWRpdG9ycyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdWRpdG9ycy9wYXJhbWV0ZXJzL2VkaXRhYmxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEF1ZGl0LFxuICBhdWRpdEFycmF5LFxuICBhdWRpdEJvb2xlYW4sXG4gIGF1ZGl0Q2hhaW4sXG4gIGF1ZGl0Q2xlYW5BcnJheSxcbiAgYXVkaXRGdW5jdGlvbixcbiAgYXVkaXRLZXlWYWx1ZURpY3Rpb25hcnksXG4gIGF1ZGl0Tm9vcCxcbiAgYXVkaXROdW1iZXIsXG4gIGF1ZGl0T3B0aW9ucyxcbiAgYXVkaXRSZXF1aXJlLFxuICBhdWRpdFN0cmluZyxcbiAgYXVkaXRTd2l0Y2gsXG4gIGF1ZGl0VGVzdCxcbiAgYXVkaXRUcmltU3RyaW5nLFxuICBhdWRpdFVuaXF1ZSxcbiAgdHlwZSBBdWRpdG9yLFxufSBmcm9tIFwiQGF1ZGl0b3JzL2NvcmVcIlxuXG5pbXBvcnQgeyBhdWRpdERhdGUgfSBmcm9tIFwiLi4vcGVyaW9kc1wiXG5pbXBvcnQgeyBhdWRpdFJlZmVyZW5jZSwgYXVkaXRSZWZlcmVuY2VzQnlEYXRlIH0gZnJvbSBcIi4uL3JlZmVyZW5jZXNcIlxuaW1wb3J0IHtcbiAgUGFyYW1ldGVyQ2xhc3MsXG4gIHJldmFsdWF0aW9uVHlwZXMsXG4gIFNjYWxlVHlwZSxcbiAgVmFsdWVUeXBlLFxufSBmcm9tIFwiLi4vLi4vcGFyYW1ldGVyc1wiXG5pbXBvcnQgdHlwZSB7IFVuaXQgfSBmcm9tIFwiLi4vLi4vdW5pdHNcIlxuXG5leHBvcnQgZnVuY3Rpb24gYXVkaXRFZGl0YWJsZUFtb3VudEJyYWNrZXQodW5pdHM6IFVuaXRbXSk6IEF1ZGl0b3Ige1xuICByZXR1cm4gZnVuY3Rpb24gKGF1ZGl0OiBBdWRpdCwgZGF0YVVua25vd246IHVua25vd24pOiBbdW5rbm93biwgdW5rbm93bl0ge1xuICAgIGlmIChkYXRhVW5rbm93biA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gW2RhdGFVbmtub3duLCBudWxsXVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGRhdGFVbmtub3duICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gYXVkaXQudW5leHBlY3RlZFR5cGUoZGF0YVVua25vd24sIFwib2JqZWN0XCIpXG4gICAgfVxuXG4gICAgY29uc3QgZGF0YTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0gPSB7IC4uLmRhdGFVbmtub3duIH1cbiAgICBjb25zdCBlcnJvcnM6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0ge31cbiAgICBjb25zdCByZW1haW5pbmdLZXlzID0gbmV3IFNldChPYmplY3Qua2V5cyhkYXRhKSlcblxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcImFtb3VudFwiLFxuICAgICAgdHJ1ZSxcbiAgICAgIGVycm9ycyxcbiAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICBhdWRpdEtleVZhbHVlRGljdGlvbmFyeShhdWRpdERhdGUsIFtcbiAgICAgICAgYXVkaXRFZGl0YWJsZVZhbHVlT3JFeHBlY3RlZCh1bml0cywgYXVkaXROdW1iZXIpLFxuICAgICAgICBhdWRpdFJlcXVpcmUsXG4gICAgICBdKSxcbiAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwidGhyZXNob2xkXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KGF1ZGl0RGF0ZSwgW1xuICAgICAgICBhdWRpdEVkaXRhYmxlVmFsdWVPckV4cGVjdGVkKHVuaXRzLCBhdWRpdE51bWJlciksXG4gICAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICAgIF0pLFxuICAgICAgYXVkaXRSZXF1aXJlLFxuICAgIClcblxuICAgIHJldHVybiBhdWRpdC5yZWR1Y2VSZW1haW5pbmcoZGF0YSwgZXJyb3JzLCByZW1haW5pbmdLZXlzKVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhdWRpdEVkaXRhYmxlUGFyYW1ldGVyKFxuICB1bml0czogVW5pdFtdLFxuICBjaGlsZHJlbklkPzogc3RyaW5nW10gfCB1bmRlZmluZWQsXG4pOiBBdWRpdG9yIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChhdWRpdDogQXVkaXQsIGRhdGFVbmtub3duOiB1bmtub3duKTogW3Vua25vd24sIHVua25vd25dIHtcbiAgICBpZiAoZGF0YVVua25vd24gPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFtkYXRhVW5rbm93biwgbnVsbF1cbiAgICB9XG4gICAgaWYgKHR5cGVvZiBkYXRhVW5rbm93biAhPT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIGF1ZGl0LnVuZXhwZWN0ZWRUeXBlKGRhdGFVbmtub3duLCBcIm9iamVjdFwiKVxuICAgIH1cblxuICAgIGNvbnN0IGRhdGE6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0geyAuLi5kYXRhVW5rbm93biB9XG4gICAgY29uc3QgZXJyb3JzOiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSA9IHt9XG4gICAgY29uc3QgcmVtYWluaW5nS2V5cyA9IG5ldyBTZXQoT2JqZWN0LmtleXMoZGF0YSkpXG5cbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJjbGFzc1wiLFxuICAgICAgdHJ1ZSxcbiAgICAgIGVycm9ycyxcbiAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICBhdWRpdE9wdGlvbnMoT2JqZWN0LnZhbHVlcyhQYXJhbWV0ZXJDbGFzcykpLFxuICAgIClcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBbXG4gICAgICBcImRlc2NyaXB0aW9uXCIsXG4gICAgICBcImxhYmVsX2VuXCIsXG4gICAgICBcImRvY3VtZW50YXRpb25cIixcbiAgICAgIFwiZmlsZV9wYXRoXCIsXG4gICAgICBcInNob3J0X2xhYmVsXCIsXG4gICAgICBcInNob3J0X2xhYmVsX2VuXCIsXG4gICAgXSkge1xuICAgICAgYXVkaXQuYXR0cmlidXRlKGRhdGEsIGtleSwgdHJ1ZSwgZXJyb3JzLCByZW1haW5pbmdLZXlzLCBhdWRpdFRyaW1TdHJpbmcpXG4gICAgfVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcImRvY3VtZW50YXRpb25fc3RhcnRcIixcbiAgICAgIHRydWUsXG4gICAgICBlcnJvcnMsXG4gICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgYXVkaXRCb29sZWFuLFxuICAgICAgYXVkaXRGdW5jdGlvbigodmFsdWUpID0+ICh2YWx1ZSA/IHRydWUgOiBudWxsKSksXG4gICAgKVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcImluZmxhdG9yXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0VHJpbVN0cmluZyxcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwiaW5mbGF0b3JfcmVmZXJlbmNlXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0UmVmZXJlbmNlc0J5RGF0ZSxcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwiaW5jb21lX3RheF95ZWFyXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0Qm9vbGVhbixcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwibGFzdF92YWx1ZV9zdGlsbF92YWxpZF9vblwiLFxuICAgICAgdHJ1ZSxcbiAgICAgIGVycm9ycyxcbiAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICBhdWRpdERhdGUsXG4gICAgKVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcIm5hbWVcIixcbiAgICAgIHRydWUsXG4gICAgICBlcnJvcnMsXG4gICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgYXVkaXRUcmltU3RyaW5nLFxuICAgICAgLy8gYXVkaXRUZXN0KChuYW1lKSA9PiB7XG4gICAgICAvLyAgIGNvbnN0IGlkcyA9IG5hbWUuc3BsaXQoXCIuXCIpXG4gICAgICAvLyAgIHJldHVybiBpZHNbaWRzLmxlbmd0aCAtIDFdLm1hdGNoKC9eW1xcZF0vKSA9PT0gbnVsbFxuICAgICAgLy8gfSwgXCJMYXN0IHBhcnQgb2YgbmFtZSBtdXN0IG5vdCBzdGFydCB3aXRoIGEgZGlnaXRcIiksXG4gICAgKVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcIm5vdGVzXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0UmVmZXJlbmNlc0J5RGF0ZSxcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwib2ZmaWNpYWxfam91cm5hbF9kYXRlXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KGF1ZGl0RGF0ZSwgW1xuICAgICAgICBhdWRpdFN3aXRjaChhdWRpdERhdGUsIFtcbiAgICAgICAgICBhdWRpdFN0cmluZyxcbiAgICAgICAgICBhdWRpdEZ1bmN0aW9uKCh0ZXh0KSA9PiB0ZXh0LnNwbGl0KFwiO1wiKSksXG4gICAgICAgICAgYXVkaXRBcnJheShhdWRpdERhdGUpLFxuICAgICAgICAgIC8vIFRPRE86IFJldHVybiBzb21ldGhpbmcgb3RoZXIgdGhhbiBhIHN0cmluZz9cbiAgICAgICAgICBhdWRpdEZ1bmN0aW9uKChpbnN0YW50cykgPT4gaW5zdGFudHMuam9pbihcIjsgXCIpKSxcbiAgICAgICAgXSksXG4gICAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICAgIF0pLFxuICAgIClcbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJyZWZlcmVuY2VcIixcbiAgICAgIHRydWUsXG4gICAgICBlcnJvcnMsXG4gICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgYXVkaXRSZWZlcmVuY2VzQnlEYXRlLFxuICAgIClcbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJyZXZhbHVhdGlvbl9yZWZlcmVuY2VcIixcbiAgICAgIHRydWUsXG4gICAgICBlcnJvcnMsXG4gICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgYXVkaXRSZWZlcmVuY2VzQnlEYXRlLFxuICAgIClcbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJyZXZhbHVhdGlvbl90eXBlXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0VHJpbVN0cmluZyxcbiAgICAgIGF1ZGl0T3B0aW9ucyhyZXZhbHVhdGlvblR5cGVzKSxcbiAgICApXG5cbiAgICBpZiAoZXJyb3JzLmNsYXNzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHN3aXRjaCAoZGF0YS5jbGFzcyBhcyBQYXJhbWV0ZXJDbGFzcykge1xuICAgICAgICBjYXNlIFBhcmFtZXRlckNsYXNzLk5vZGU6IHtcbiAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgXCJjaGlsZHJlblwiLFxuICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICBhdWRpdEtleVZhbHVlRGljdGlvbmFyeShhdWRpdFN0cmluZywgW1xuICAgICAgICAgICAgICBhdWRpdEVkaXRhYmxlUGFyYW1ldGVyKHVuaXRzKSxcbiAgICAgICAgICAgICAgYXVkaXRSZXF1aXJlLFxuICAgICAgICAgICAgXSksXG4gICAgICAgICAgICAvLyBhdWRpdFJlcXVpcmUsIC8vIEEgbm9kZSBtYXkgaGF2ZSBubyBjaGlsZCAoZXNwZWNpYWxseSB1bnByb2Nlc3NlZCBub2RlcykuXG4gICAgICAgICAgKVxuICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBcIm9yZGVyXCIsXG4gICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgIGF1ZGl0Q2xlYW5BcnJheShcbiAgICAgICAgICAgICAgYXVkaXRTdHJpbmcsXG4gICAgICAgICAgICAgIGNoaWxkcmVuSWQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgID8gZXJyb3JzLmNoaWxkcmVuID09PSB1bmRlZmluZWQgJiYgZGF0YS5jaGlsZHJlbiAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICA/IGF1ZGl0T3B0aW9ucyhcbiAgICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhkYXRhLmNoaWxkcmVuIGFzIHsgW2lkOiBzdHJpbmddOiB1bmtub3duIH0pLFxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICA6IGF1ZGl0Tm9vcFxuICAgICAgICAgICAgICAgIDogYXVkaXRPcHRpb25zKGNoaWxkcmVuSWQpLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGF1ZGl0VW5pcXVlLFxuICAgICAgICAgIClcbiAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgXCJ1bml0XCIsXG4gICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgIGF1ZGl0RWRpdGFibGVVbml0TmFtZSh1bml0cyksXG4gICAgICAgICAgKVxuXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBjYXNlIFBhcmFtZXRlckNsYXNzLlNjYWxlOiB7XG4gICAgICAgICAgLy8gVXNlZCBvbmx5IGZvciBjb21wYXRpYmlsaXR5IHdpdGggXCJiYXLDqG1lcyBJUFBcIi5cbiAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgXCJpcHBfY3N2X2lkXCIsXG4gICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgIGF1ZGl0U3dpdGNoKFxuICAgICAgICAgICAgICBhdWRpdFRyaW1TdHJpbmcsXG4gICAgICAgICAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KFxuICAgICAgICAgICAgICAgIGF1ZGl0T3B0aW9ucyhbXG4gICAgICAgICAgICAgICAgICBcImFtb3VudFwiLFxuICAgICAgICAgICAgICAgICAgXCJhdmVyYWdlX3JhdGVcIixcbiAgICAgICAgICAgICAgICAgIFwiYmFzZVwiLFxuICAgICAgICAgICAgICAgICAgXCJyYXRlXCIsXG4gICAgICAgICAgICAgICAgICBcInRocmVzaG9sZFwiLFxuICAgICAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgICAgIFthdWRpdFRyaW1TdHJpbmcsIGF1ZGl0UmVxdWlyZV0sXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIClcbiAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgXCJ0eXBlXCIsXG4gICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgIGF1ZGl0T3B0aW9ucyhPYmplY3QudmFsdWVzKFNjYWxlVHlwZSkpLFxuICAgICAgICAgICAgYXVkaXRSZXF1aXJlLFxuICAgICAgICAgIClcblxuICAgICAgICAgIGNvbnN0IHR5cGUgPSBkYXRhLnR5cGUgYXMgU2NhbGVUeXBlXG4gICAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIFwiYnJhY2tldHNcIixcbiAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgICAgYXVkaXRBcnJheShcbiAgICAgICAgICAgICAgZXJyb3JzLnR5cGUgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgID8gW1NjYWxlVHlwZS5NYXJnaW5hbEFtb3VudCwgU2NhbGVUeXBlLlNpbmdsZUFtb3VudF0uaW5jbHVkZXMoXG4gICAgICAgICAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICA/IGF1ZGl0RWRpdGFibGVBbW91bnRCcmFja2V0KHVuaXRzKVxuICAgICAgICAgICAgICAgICAgOiBhdWRpdEVkaXRhYmxlUmF0ZUJyYWNrZXQodW5pdHMpXG4gICAgICAgICAgICAgICAgOiBhdWRpdE5vb3AsXG4gICAgICAgICAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBhdWRpdFJlcXVpcmUsXG4gICAgICAgICAgKVxuICAgICAgICAgIGlmIChlcnJvcnMudHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIFtTY2FsZVR5cGUuTWFyZ2luYWxBbW91bnQsIFNjYWxlVHlwZS5TaW5nbGVBbW91bnRdLmluY2x1ZGVzKHR5cGUpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgICAgXCJhbW91bnRfdW5pdFwiLFxuICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICAgICAgYXVkaXRFZGl0YWJsZVVuaXROYW1lKHVuaXRzKSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgICAgXCJyYXRlX3VuaXRcIixcbiAgICAgICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgICAgICAgIGF1ZGl0RWRpdGFibGVVbml0TmFtZSh1bml0cyksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgXCJ0aHJlc2hvbGRfdW5pdFwiLFxuICAgICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICAgIGF1ZGl0RWRpdGFibGVVbml0TmFtZSh1bml0cyksXG4gICAgICAgICAgICApXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIFtcInJhdGVfdW5pdFwiLCBcInRocmVzaG9sZF91bml0XCIsIFwidW5pdFwiXSkge1xuICAgICAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoZGF0YSwga2V5LCB0cnVlLCBlcnJvcnMsIHJlbWFpbmluZ0tleXMsIGF1ZGl0Tm9vcClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICAvLyBVS1xuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIFwicGVyaW9kXCIsXG4gICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgIGF1ZGl0U3RyaW5nLFxuICAgICAgICAgICAgYXVkaXRPcHRpb25zKFtcbiAgICAgICAgICAgICAgXCJob3VyXCIsIC8vIFVLXG4gICAgICAgICAgICAgIFwibW9udGhcIiwgLy8gVUtcbiAgICAgICAgICAgICAgXCJ3ZWVrXCIsIC8vIFVLXG4gICAgICAgICAgICAgIFwieWVhclwiLCAvLyBVS1xuICAgICAgICAgICAgXSksXG4gICAgICAgICAgKVxuXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBjYXNlIFBhcmFtZXRlckNsYXNzLlZhbHVlOiB7XG4gICAgICAgICAgLy8gVXNlZCBvbmx5IGZvciBjb21wYXRpYmlsaXR5IFwiYmFyw6htZXMgSVBQXCIuXG4gICAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIFwiaXBwX2Nzdl9pZFwiLFxuICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICBhdWRpdFRyaW1TdHJpbmcsXG4gICAgICAgICAgKVxuICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBcInR5cGVcIixcbiAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgICAgYXVkaXRPcHRpb25zKE9iamVjdC52YWx1ZXMoVmFsdWVUeXBlKSksXG4gICAgICAgICAgKVxuICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAgIC8vIFVLXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgXCJwZXJpb2RcIixcbiAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgICAgYXVkaXRTdHJpbmcsXG4gICAgICAgICAgICBhdWRpdE9wdGlvbnMoW1xuICAgICAgICAgICAgICBcImhvdXJcIiwgLy8gVUtcbiAgICAgICAgICAgICAgXCJtb250aFwiLCAvLyBVS1xuICAgICAgICAgICAgICBcIndlZWtcIiwgLy8gVUtcbiAgICAgICAgICAgICAgXCJ5ZWFyXCIsIC8vIFVLXG4gICAgICAgICAgICBdKSxcbiAgICAgICAgICApXG4gICAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIFwidW5pdFwiLFxuICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICBhdWRpdEVkaXRhYmxlVW5pdE5hbWUodW5pdHMpLFxuICAgICAgICAgIClcbiAgICAgICAgICBjb25zdCB0eXBlID0gZGF0YS50eXBlIGFzIFZhbHVlVHlwZVxuICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBcInZhbHVlc1wiLFxuICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICBhdWRpdEtleVZhbHVlRGljdGlvbmFyeShhdWRpdERhdGUsIFtcbiAgICAgICAgICAgICAgYXVkaXRFZGl0YWJsZVZhbHVlT3JFeHBlY3RlZChcbiAgICAgICAgICAgICAgICB1bml0cyxcbiAgICAgICAgICAgICAgICBlcnJvcnMudHlwZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICA/IHR5cGUgPT09IFZhbHVlVHlwZS5Cb29sZWFuXG4gICAgICAgICAgICAgICAgICAgID8gYXVkaXRCb29sZWFuXG4gICAgICAgICAgICAgICAgICAgIDogdHlwZSA9PT0gVmFsdWVUeXBlLk51bWJlclxuICAgICAgICAgICAgICAgICAgICAgID8gYXVkaXROdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgICA6IHR5cGUgPT09IFZhbHVlVHlwZS5TdHJpbmdBcnJheVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBhdWRpdEFycmF5KGF1ZGl0U3RyaW5nKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiAvLyB0eXBlID09PSBWYWx1ZVR5cGUuU3RyaW5nQnlTdHJpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaXRLZXlWYWx1ZURpY3Rpb25hcnkoYXVkaXRTdHJpbmcsIGF1ZGl0U3RyaW5nKVxuICAgICAgICAgICAgICAgICAgOiBhdWRpdE5vb3AsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgYXVkaXRSZXF1aXJlLFxuICAgICAgICAgIClcblxuICAgICAgICAgIC8vIGlmIChlcnJvcnMudmFsdWVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyAgIGNvbnN0IHZhbGlkRGF0ZXMgPSBuZXcgU2V0KFxuICAgICAgICAgIC8vICAgICBPYmplY3Qua2V5cyhkYXRhLnZhbHVlcyBhcyB7IFtkYXRlOiBzdHJpbmddOiB1bmtub3duIH0pLFxuICAgICAgICAgIC8vICAgKVxuICAgICAgICAgIC8vICAgdmFsaWREYXRlcy5hZGQoXCIwMDAxLTAxLTAxXCIpXG5cbiAgICAgICAgICAvLyAgIGlmIChlcnJvcnMubm90ZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgLy8gICAgICAgZGF0YSxcbiAgICAgICAgICAvLyAgICAgICBcIm5vdGVzXCIsXG4gICAgICAgICAgLy8gICAgICAgdHJ1ZSxcbiAgICAgICAgICAvLyAgICAgICBlcnJvcnMsXG4gICAgICAgICAgLy8gICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAvLyAgICAgICBhdWRpdEtleVZhbHVlRGljdGlvbmFyeShcbiAgICAgICAgICAvLyAgICAgICAgIGF1ZGl0VGVzdChcbiAgICAgICAgICAvLyAgICAgICAgICAgKGRhdGUpID0+IHZhbGlkRGF0ZXMuaGFzKGRhdGUpLFxuICAgICAgICAgIC8vICAgICAgICAgICAoZGF0ZSkgPT4gYFBhcmFtZXRlciBoYXMgbm8gdmFsdWUgZm9yIGRhdGUgJHtkYXRlfWAsXG4gICAgICAgICAgLy8gICAgICAgICApLFxuICAgICAgICAgIC8vICAgICAgICAgYXVkaXROb29wLFxuICAgICAgICAgIC8vICAgICAgICksXG4gICAgICAgICAgLy8gICAgIClcbiAgICAgICAgICAvLyAgIH1cblxuICAgICAgICAgIC8vICAgaWYgKGVycm9ycy5vZmZpY2lhbF9qb3VybmFsX2RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgLy8gICAgICAgZGF0YSxcbiAgICAgICAgICAvLyAgICAgICBcIm9mZmljaWFsX2pvdXJuYWxfZGF0ZVwiLFxuICAgICAgICAgIC8vICAgICAgIHRydWUsXG4gICAgICAgICAgLy8gICAgICAgZXJyb3JzLFxuICAgICAgICAgIC8vICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgLy8gICAgICAgYXVkaXRLZXlWYWx1ZURpY3Rpb25hcnkoXG4gICAgICAgICAgLy8gICAgICAgICBhdWRpdFRlc3QoXG4gICAgICAgICAgLy8gICAgICAgICAgIChkYXRlKSA9PiB2YWxpZERhdGVzLmhhcyhkYXRlKSxcbiAgICAgICAgICAvLyAgICAgICAgICAgKGRhdGUpID0+IGBQYXJhbWV0ZXIgaGFzIG5vIHZhbHVlIGZvciBkYXRlICR7ZGF0ZX1gLFxuICAgICAgICAgIC8vICAgICAgICAgKSxcbiAgICAgICAgICAvLyAgICAgICAgIGF1ZGl0Tm9vcCxcbiAgICAgICAgICAvLyAgICAgICApLFxuICAgICAgICAgIC8vICAgICApXG4gICAgICAgICAgLy8gICB9XG5cbiAgICAgICAgICAvLyAgIGlmIChlcnJvcnMucmVmZXJlbmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgIC8vICAgICAgIGRhdGEsXG4gICAgICAgICAgLy8gICAgICAgXCJyZWZlcmVuY2VcIixcbiAgICAgICAgICAvLyAgICAgICB0cnVlLFxuICAgICAgICAgIC8vICAgICAgIGVycm9ycyxcbiAgICAgICAgICAvLyAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgIC8vICAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KFxuICAgICAgICAgIC8vICAgICAgICAgYXVkaXRUZXN0KFxuICAgICAgICAgIC8vICAgICAgICAgICAoZGF0ZSkgPT4gdmFsaWREYXRlcy5oYXMoZGF0ZSksXG4gICAgICAgICAgLy8gICAgICAgICAgIChkYXRlKSA9PiBgUGFyYW1ldGVyIGhhcyBubyB2YWx1ZSBmb3IgZGF0ZSAke2RhdGV9YCxcbiAgICAgICAgICAvLyAgICAgICAgICksXG4gICAgICAgICAgLy8gICAgICAgICBhdWRpdE5vb3AsXG4gICAgICAgICAgLy8gICAgICAgKSxcbiAgICAgICAgICAvLyAgICAgKVxuICAgICAgICAgIC8vICAgfVxuICAgICAgICAgIC8vIH1cblxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYXVkaXQucmVkdWNlUmVtYWluaW5nKGRhdGEsIGVycm9ycywgcmVtYWluaW5nS2V5cylcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXVkaXRFZGl0YWJsZVJhdGVCcmFja2V0KHVuaXRzOiBVbml0W10pOiBBdWRpdG9yIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChhdWRpdDogQXVkaXQsIGRhdGFVbmtub3duOiB1bmtub3duKTogW3Vua25vd24sIHVua25vd25dIHtcbiAgICBpZiAoZGF0YVVua25vd24gPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFtkYXRhVW5rbm93biwgbnVsbF1cbiAgICB9XG4gICAgaWYgKHR5cGVvZiBkYXRhVW5rbm93biAhPT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIGF1ZGl0LnVuZXhwZWN0ZWRUeXBlKGRhdGFVbmtub3duLCBcIm9iamVjdFwiKVxuICAgIH1cblxuICAgIGNvbnN0IGRhdGE6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0geyAuLi5kYXRhVW5rbm93biB9XG4gICAgY29uc3QgZXJyb3JzOiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSA9IHt9XG4gICAgY29uc3QgcmVtYWluaW5nS2V5cyA9IG5ldyBTZXQoT2JqZWN0LmtleXMoZGF0YSkpXG5cbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJiYXNlXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KGF1ZGl0RGF0ZSwgW1xuICAgICAgICBhdWRpdEVkaXRhYmxlVmFsdWVPckV4cGVjdGVkKHVuaXRzLCBhdWRpdE51bWJlciksXG4gICAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICAgIF0pLFxuICAgIClcbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJyYXRlXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KFxuICAgICAgICBhdWRpdERhdGUsXG4gICAgICAgIGF1ZGl0RWRpdGFibGVWYWx1ZU9yRXhwZWN0ZWQodW5pdHMsIGF1ZGl0TnVtYmVyKSxcbiAgICAgICksXG4gICAgICBhdWRpdFJlcXVpcmUsXG4gICAgKVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcInRocmVzaG9sZFwiLFxuICAgICAgdHJ1ZSxcbiAgICAgIGVycm9ycyxcbiAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICBhdWRpdEtleVZhbHVlRGljdGlvbmFyeShhdWRpdERhdGUsIFtcbiAgICAgICAgYXVkaXRFZGl0YWJsZVZhbHVlT3JFeHBlY3RlZCh1bml0cywgYXVkaXROdW1iZXIpLFxuICAgICAgICBhdWRpdFJlcXVpcmUsXG4gICAgICBdKSxcbiAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICApXG5cbiAgICByZXR1cm4gYXVkaXQucmVkdWNlUmVtYWluaW5nKGRhdGEsIGVycm9ycywgcmVtYWluaW5nS2V5cylcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXVkaXRFZGl0YWJsZVVuaXROYW1lKHVuaXRzOiBVbml0W10pOiBBdWRpdG9yIHtcbiAgY29uc3QgdW5pdHNOYW1lID0gdW5pdHMubWFwKCh7IG5hbWUgfSkgPT4gbmFtZSlcbiAgcmV0dXJuIGF1ZGl0Q2hhaW4oYXVkaXRTdHJpbmcsIGF1ZGl0T3B0aW9ucyh1bml0c05hbWUpKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXVkaXRFZGl0YWJsZVZhbHVlKFxuICB1bml0czogVW5pdFtdLFxuICAuLi5hdWRpdG9yczogQXVkaXRvcltdXG4pOiBBdWRpdG9yIHtcbiAgcmV0dXJuIChhdWRpdDogQXVkaXQsIGRhdGFVbmtub3duOiB1bmtub3duKTogW3Vua25vd24sIHVua25vd25dID0+IHtcbiAgICBpZiAoZGF0YVVua25vd24gPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFtkYXRhVW5rbm93biwgbnVsbF1cbiAgICB9XG4gICAgaWYgKHR5cGVvZiBkYXRhVW5rbm93biAhPT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIGF1ZGl0LnVuZXhwZWN0ZWRUeXBlKGRhdGFVbmtub3duLCBcIm9iamVjdFwiKVxuICAgIH1cblxuICAgIGNvbnN0IGRhdGE6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0geyAuLi5kYXRhVW5rbm93biB9XG4gICAgY29uc3QgZXJyb3JzOiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSA9IHt9XG4gICAgY29uc3QgcmVtYWluaW5nS2V5cyA9IG5ldyBTZXQoT2JqZWN0LmtleXMoZGF0YSkpXG5cbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJyZWZlcmVuY2VcIixcbiAgICAgIHRydWUsXG4gICAgICBlcnJvcnMsXG4gICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgYXVkaXRDbGVhbkFycmF5KGF1ZGl0UmVmZXJlbmNlKSxcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwidW5pdFwiLFxuICAgICAgdHJ1ZSxcbiAgICAgIGVycm9ycyxcbiAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICBhdWRpdEVkaXRhYmxlVW5pdE5hbWUodW5pdHMpLFxuICAgIClcbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJ2YWx1ZVwiLFxuICAgICAgZmFsc2UsIC8vIEtlZXAgbnVsbCB2YWx1ZS5cbiAgICAgIGVycm9ycyxcbiAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAuLi5hdWRpdG9ycyxcbiAgICApXG5cbiAgICByZXR1cm4gYXVkaXQucmVkdWNlUmVtYWluaW5nKGRhdGEsIGVycm9ycywgcmVtYWluaW5nS2V5cylcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgYXVkaXRFZGl0YWJsZVZhbHVlT3JFeHBlY3RlZCA9IChcbiAgdW5pdHM6IFVuaXRbXSxcbiAgLi4uYXVkaXRvcnM6IEF1ZGl0b3JbXVxuKTogQXVkaXRvciA9PlxuICBhdWRpdFN3aXRjaChcbiAgICBhdWRpdFRlc3QoKHZhbHVlKSA9PiB2YWx1ZSA9PT0gXCJleHBlY3RlZFwiKSxcbiAgICBhdWRpdEVkaXRhYmxlVmFsdWUodW5pdHMsIC4uLmF1ZGl0b3JzKSxcbiAgKVxuIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUVFQSxVQUFVLEVBQ1ZDLFlB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