UNPKG

@openfisca/json-model

Version:

Library to handle informations extracted in JSON or YAML format from OpenFisca parameters, variables, etc

230 lines (225 loc) 45.4 kB
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, 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, "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); 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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhdWRpdEFycmF5IiwiYXVkaXRCb29sZWFuIiwiYXVkaXRDaGFpbiIsImF1ZGl0Q2xlYW5BcnJheSIsImF1ZGl0RnVuY3Rpb24iLCJhdWRpdEtleVZhbHVlRGljdGlvbmFyeSIsImF1ZGl0Tm9vcCIsImF1ZGl0TnVtYmVyIiwiYXVkaXRPcHRpb25zIiwiYXVkaXRSZXF1aXJlIiwiYXVkaXRTdHJpbmciLCJhdWRpdFN3aXRjaCIsImF1ZGl0VGVzdCIsImF1ZGl0VHJpbVN0cmluZyIsImF1ZGl0VW5pcXVlIiwiYXVkaXREYXRlIiwiYXVkaXRSZWZlcmVuY2UiLCJhdWRpdFJlZmVyZW5jZXNCeURhdGUiLCJQYXJhbWV0ZXJDbGFzcyIsIlNjYWxlVHlwZSIsIlZhbHVlVHlwZSIsImF1ZGl0RWRpdGFibGVBbW91bnRCcmFja2V0IiwidW5pdHMiLCJhdWRpdCIsImRhdGFVbmtub3duIiwidW5leHBlY3RlZFR5cGUiLCJkYXRhIiwiZXJyb3JzIiwicmVtYWluaW5nS2V5cyIsIlNldCIsIk9iamVjdCIsImtleXMiLCJhdHRyaWJ1dGUiLCJhdWRpdEVkaXRhYmxlVmFsdWVPckV4cGVjdGVkIiwicmVkdWNlUmVtYWluaW5nIiwiYXVkaXRFZGl0YWJsZVBhcmFtZXRlciIsImNoaWxkcmVuSWQiLCJ2YWx1ZXMiLCJrZXkiLCJ2YWx1ZSIsInRleHQiLCJzcGxpdCIsImluc3RhbnRzIiwiam9pbiIsImNsYXNzIiwidW5kZWZpbmVkIiwiTm9kZSIsImNoaWxkcmVuIiwiYXVkaXRFZGl0YWJsZVVuaXROYW1lIiwiU2NhbGUiLCJ0eXBlIiwiTWFyZ2luYWxBbW91bnQiLCJTaW5nbGVBbW91bnQiLCJpbmNsdWRlcyIsImF1ZGl0RWRpdGFibGVSYXRlQnJhY2tldCIsIlZhbHVlIiwiQm9vbGVhbiIsIk51bWJlciIsIlN0cmluZ0FycmF5IiwidW5pdHNOYW1lIiwibWFwIiwibmFtZSIsImF1ZGl0RWRpdGFibGVWYWx1ZSIsImF1ZGl0b3JzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2F1ZGl0b3JzL3BhcmFtZXRlcnMvZWRpdGFibGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQXVkaXQsXG4gIGF1ZGl0QXJyYXksXG4gIGF1ZGl0Qm9vbGVhbixcbiAgYXVkaXRDaGFpbixcbiAgYXVkaXRDbGVhbkFycmF5LFxuICBhdWRpdEZ1bmN0aW9uLFxuICBhdWRpdEtleVZhbHVlRGljdGlvbmFyeSxcbiAgYXVkaXROb29wLFxuICBhdWRpdE51bWJlcixcbiAgYXVkaXRPcHRpb25zLFxuICBhdWRpdFJlcXVpcmUsXG4gIGF1ZGl0U3RyaW5nLFxuICBhdWRpdFN3aXRjaCxcbiAgYXVkaXRUZXN0LFxuICBhdWRpdFRyaW1TdHJpbmcsXG4gIGF1ZGl0VW5pcXVlLFxuICB0eXBlIEF1ZGl0b3IsXG59IGZyb20gXCJAYXVkaXRvcnMvY29yZVwiXG5cbmltcG9ydCB7IGF1ZGl0RGF0ZSB9IGZyb20gXCIuLi9wZXJpb2RzXCJcbmltcG9ydCB7IGF1ZGl0UmVmZXJlbmNlLCBhdWRpdFJlZmVyZW5jZXNCeURhdGUgfSBmcm9tIFwiLi4vcmVmZXJlbmNlc1wiXG5pbXBvcnQgeyBQYXJhbWV0ZXJDbGFzcywgU2NhbGVUeXBlLCBWYWx1ZVR5cGUgfSBmcm9tIFwiLi4vLi4vcGFyYW1ldGVyc1wiXG5pbXBvcnQgdHlwZSB7IFVuaXQgfSBmcm9tIFwiLi4vLi4vdW5pdHNcIlxuXG5leHBvcnQgZnVuY3Rpb24gYXVkaXRFZGl0YWJsZUFtb3VudEJyYWNrZXQodW5pdHM6IFVuaXRbXSk6IEF1ZGl0b3Ige1xuICByZXR1cm4gZnVuY3Rpb24gKGF1ZGl0OiBBdWRpdCwgZGF0YVVua25vd246IHVua25vd24pOiBbdW5rbm93biwgdW5rbm93bl0ge1xuICAgIGlmIChkYXRhVW5rbm93biA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gW2RhdGFVbmtub3duLCBudWxsXVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGRhdGFVbmtub3duICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gYXVkaXQudW5leHBlY3RlZFR5cGUoZGF0YVVua25vd24sIFwib2JqZWN0XCIpXG4gICAgfVxuXG4gICAgY29uc3QgZGF0YTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0gPSB7IC4uLmRhdGFVbmtub3duIH1cbiAgICBjb25zdCBlcnJvcnM6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0ge31cbiAgICBjb25zdCByZW1haW5pbmdLZXlzID0gbmV3IFNldChPYmplY3Qua2V5cyhkYXRhKSlcblxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcImFtb3VudFwiLFxuICAgICAgdHJ1ZSxcbiAgICAgIGVycm9ycyxcbiAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICBhdWRpdEtleVZhbHVlRGljdGlvbmFyeShhdWRpdERhdGUsIFtcbiAgICAgICAgYXVkaXRFZGl0YWJsZVZhbHVlT3JFeHBlY3RlZCh1bml0cywgYXVkaXROdW1iZXIpLFxuICAgICAgICBhdWRpdFJlcXVpcmUsXG4gICAgICBdKSxcbiAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwidGhyZXNob2xkXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KGF1ZGl0RGF0ZSwgW1xuICAgICAgICBhdWRpdEVkaXRhYmxlVmFsdWVPckV4cGVjdGVkKHVuaXRzLCBhdWRpdE51bWJlciksXG4gICAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICAgIF0pLFxuICAgICAgYXVkaXRSZXF1aXJlLFxuICAgIClcblxuICAgIHJldHVybiBhdWRpdC5yZWR1Y2VSZW1haW5pbmcoZGF0YSwgZXJyb3JzLCByZW1haW5pbmdLZXlzKVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhdWRpdEVkaXRhYmxlUGFyYW1ldGVyKFxuICB1bml0czogVW5pdFtdLFxuICBjaGlsZHJlbklkPzogc3RyaW5nW10gfCB1bmRlZmluZWQsXG4pOiBBdWRpdG9yIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChhdWRpdDogQXVkaXQsIGRhdGFVbmtub3duOiB1bmtub3duKTogW3Vua25vd24sIHVua25vd25dIHtcbiAgICBpZiAoZGF0YVVua25vd24gPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFtkYXRhVW5rbm93biwgbnVsbF1cbiAgICB9XG4gICAgaWYgKHR5cGVvZiBkYXRhVW5rbm93biAhPT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIGF1ZGl0LnVuZXhwZWN0ZWRUeXBlKGRhdGFVbmtub3duLCBcIm9iamVjdFwiKVxuICAgIH1cblxuICAgIGNvbnN0IGRhdGE6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0geyAuLi5kYXRhVW5rbm93biB9XG4gICAgY29uc3QgZXJyb3JzOiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSA9IHt9XG4gICAgY29uc3QgcmVtYWluaW5nS2V5cyA9IG5ldyBTZXQoT2JqZWN0LmtleXMoZGF0YSkpXG5cbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJjbGFzc1wiLFxuICAgICAgdHJ1ZSxcbiAgICAgIGVycm9ycyxcbiAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICBhdWRpdE9wdGlvbnMoT2JqZWN0LnZhbHVlcyhQYXJhbWV0ZXJDbGFzcykpLFxuICAgIClcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBbXG4gICAgICBcImRlc2NyaXB0aW9uXCIsXG4gICAgICBcImxhYmVsX2VuXCIsXG4gICAgICBcImRvY3VtZW50YXRpb25cIixcbiAgICAgIFwiZmlsZV9wYXRoXCIsXG4gICAgICBcInNob3J0X2xhYmVsXCIsXG4gICAgICBcInNob3J0X2xhYmVsX2VuXCIsXG4gICAgXSkge1xuICAgICAgYXVkaXQuYXR0cmlidXRlKGRhdGEsIGtleSwgdHJ1ZSwgZXJyb3JzLCByZW1haW5pbmdLZXlzLCBhdWRpdFRyaW1TdHJpbmcpXG4gICAgfVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcImRvY3VtZW50YXRpb25fc3RhcnRcIixcbiAgICAgIHRydWUsXG4gICAgICBlcnJvcnMsXG4gICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgYXVkaXRCb29sZWFuLFxuICAgICAgYXVkaXRGdW5jdGlvbigodmFsdWUpID0+ICh2YWx1ZSA/IHRydWUgOiBudWxsKSksXG4gICAgKVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcImluZmxhdG9yXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0VHJpbVN0cmluZyxcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwiaW5mbGF0b3JfcmVmZXJlbmNlXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0UmVmZXJlbmNlc0J5RGF0ZSxcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwibGFzdF92YWx1ZV9zdGlsbF92YWxpZF9vblwiLFxuICAgICAgdHJ1ZSxcbiAgICAgIGVycm9ycyxcbiAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICBhdWRpdERhdGUsXG4gICAgKVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcIm5hbWVcIixcbiAgICAgIHRydWUsXG4gICAgICBlcnJvcnMsXG4gICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgYXVkaXRUcmltU3RyaW5nLFxuICAgICAgLy8gYXVkaXRUZXN0KChuYW1lKSA9PiB7XG4gICAgICAvLyAgIGNvbnN0IGlkcyA9IG5hbWUuc3BsaXQoXCIuXCIpXG4gICAgICAvLyAgIHJldHVybiBpZHNbaWRzLmxlbmd0aCAtIDFdLm1hdGNoKC9eW1xcZF0vKSA9PT0gbnVsbFxuICAgICAgLy8gfSwgXCJMYXN0IHBhcnQgb2YgbmFtZSBtdXN0IG5vdCBzdGFydCB3aXRoIGEgZGlnaXRcIiksXG4gICAgKVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcIm5vdGVzXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0UmVmZXJlbmNlc0J5RGF0ZSxcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwib2ZmaWNpYWxfam91cm5hbF9kYXRlXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KGF1ZGl0RGF0ZSwgW1xuICAgICAgICBhdWRpdFN3aXRjaChhdWRpdERhdGUsIFtcbiAgICAgICAgICBhdWRpdFN0cmluZyxcbiAgICAgICAgICBhdWRpdEZ1bmN0aW9uKCh0ZXh0KSA9PiB0ZXh0LnNwbGl0KFwiO1wiKSksXG4gICAgICAgICAgYXVkaXRBcnJheShhdWRpdERhdGUpLFxuICAgICAgICAgIC8vIFRPRE86IFJldHVybiBzb21ldGhpbmcgb3RoZXIgdGhhbiBhIHN0cmluZz9cbiAgICAgICAgICBhdWRpdEZ1bmN0aW9uKChpbnN0YW50cykgPT4gaW5zdGFudHMuam9pbihcIjsgXCIpKSxcbiAgICAgICAgXSksXG4gICAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICAgIF0pLFxuICAgIClcbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJyZWZlcmVuY2VcIixcbiAgICAgIHRydWUsXG4gICAgICBlcnJvcnMsXG4gICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgYXVkaXRSZWZlcmVuY2VzQnlEYXRlLFxuICAgIClcblxuICAgIGlmIChlcnJvcnMuY2xhc3MgPT09IHVuZGVmaW5lZCkge1xuICAgICAgc3dpdGNoIChkYXRhLmNsYXNzIGFzIFBhcmFtZXRlckNsYXNzKSB7XG4gICAgICAgIGNhc2UgUGFyYW1ldGVyQ2xhc3MuTm9kZToge1xuICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBcImNoaWxkcmVuXCIsXG4gICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KGF1ZGl0U3RyaW5nLCBbXG4gICAgICAgICAgICAgIGF1ZGl0RWRpdGFibGVQYXJhbWV0ZXIodW5pdHMpLFxuICAgICAgICAgICAgICBhdWRpdFJlcXVpcmUsXG4gICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIC8vIGF1ZGl0UmVxdWlyZSwgLy8gQSBub2RlIG1heSBoYXZlIG5vIGNoaWxkIChlc3BlY2lhbGx5IHVucHJvY2Vzc2VkIG5vZGVzKS5cbiAgICAgICAgICApXG4gICAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIFwib3JkZXJcIixcbiAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgICAgYXVkaXRDbGVhbkFycmF5KFxuICAgICAgICAgICAgICBhdWRpdFN0cmluZyxcbiAgICAgICAgICAgICAgY2hpbGRyZW5JZCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBlcnJvcnMuY2hpbGRyZW4gPT09IHVuZGVmaW5lZCAmJiBkYXRhLmNoaWxkcmVuICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgID8gYXVkaXRPcHRpb25zKFxuICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKGRhdGEuY2hpbGRyZW4gYXMgeyBbaWQ6IHN0cmluZ106IHVua25vd24gfSksXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIDogYXVkaXROb29wXG4gICAgICAgICAgICAgICAgOiBhdWRpdE9wdGlvbnMoY2hpbGRyZW5JZCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgYXVkaXRVbmlxdWUsXG4gICAgICAgICAgKVxuICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBcInVuaXRcIixcbiAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgICAgYXVkaXRFZGl0YWJsZVVuaXROYW1lKHVuaXRzKSxcbiAgICAgICAgICApXG5cbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgUGFyYW1ldGVyQ2xhc3MuU2NhbGU6IHtcbiAgICAgICAgICAvLyBVc2VkIG9ubHkgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBcImJhcsOobWVzIElQUFwiLlxuICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBcImlwcF9jc3ZfaWRcIixcbiAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgICAgYXVkaXRTd2l0Y2goXG4gICAgICAgICAgICAgIGF1ZGl0VHJpbVN0cmluZyxcbiAgICAgICAgICAgICAgYXVkaXRLZXlWYWx1ZURpY3Rpb25hcnkoXG4gICAgICAgICAgICAgICAgYXVkaXRPcHRpb25zKFtcbiAgICAgICAgICAgICAgICAgIFwiYW1vdW50XCIsXG4gICAgICAgICAgICAgICAgICBcImF2ZXJhZ2VfcmF0ZVwiLFxuICAgICAgICAgICAgICAgICAgXCJiYXNlXCIsXG4gICAgICAgICAgICAgICAgICBcInJhdGVcIixcbiAgICAgICAgICAgICAgICAgIFwidGhyZXNob2xkXCIsXG4gICAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICAgICAgW2F1ZGl0VHJpbVN0cmluZywgYXVkaXRSZXF1aXJlXSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKVxuICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBcInR5cGVcIixcbiAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgICAgYXVkaXRPcHRpb25zKE9iamVjdC52YWx1ZXMoU2NhbGVUeXBlKSksXG4gICAgICAgICAgICBhdWRpdFJlcXVpcmUsXG4gICAgICAgICAgKVxuXG4gICAgICAgICAgY29uc3QgdHlwZSA9IGRhdGEudHlwZSBhcyBTY2FsZVR5cGVcbiAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgXCJicmFja2V0c1wiLFxuICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICBhdWRpdEFycmF5KFxuICAgICAgICAgICAgICBlcnJvcnMudHlwZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBbU2NhbGVUeXBlLk1hcmdpbmFsQW1vdW50LCBTY2FsZVR5cGUuU2luZ2xlQW1vdW50XS5pbmNsdWRlcyhcbiAgICAgICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgID8gYXVkaXRFZGl0YWJsZUFtb3VudEJyYWNrZXQodW5pdHMpXG4gICAgICAgICAgICAgICAgICA6IGF1ZGl0RWRpdGFibGVSYXRlQnJhY2tldCh1bml0cylcbiAgICAgICAgICAgICAgICA6IGF1ZGl0Tm9vcCxcbiAgICAgICAgICAgICAgYXVkaXRSZXF1aXJlLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICAgICAgICApXG4gICAgICAgICAgaWYgKGVycm9ycy50eXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgW1NjYWxlVHlwZS5NYXJnaW5hbEFtb3VudCwgU2NhbGVUeXBlLlNpbmdsZUFtb3VudF0uaW5jbHVkZXModHlwZSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgICBcImFtb3VudF91bml0XCIsXG4gICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgICAgICBhdWRpdEVkaXRhYmxlVW5pdE5hbWUodW5pdHMpLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgICBcInJhdGVfdW5pdFwiLFxuICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICAgICAgYXVkaXRFZGl0YWJsZVVuaXROYW1lKHVuaXRzKSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgICBcInRocmVzaG9sZF91bml0XCIsXG4gICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgICAgYXVkaXRFZGl0YWJsZVVuaXROYW1lKHVuaXRzKSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgW1wicmF0ZV91bml0XCIsIFwidGhyZXNob2xkX3VuaXRcIiwgXCJ1bml0XCJdKSB7XG4gICAgICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShkYXRhLCBrZXksIHRydWUsIGVycm9ycywgcmVtYWluaW5nS2V5cywgYXVkaXROb29wKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAgIC8vIFVLXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgXCJwZXJpb2RcIixcbiAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgICAgYXVkaXRTdHJpbmcsXG4gICAgICAgICAgICBhdWRpdE9wdGlvbnMoW1xuICAgICAgICAgICAgICBcImhvdXJcIiwgLy8gVUtcbiAgICAgICAgICAgICAgXCJtb250aFwiLCAvLyBVS1xuICAgICAgICAgICAgICBcIndlZWtcIiwgLy8gVUtcbiAgICAgICAgICAgICAgXCJ5ZWFyXCIsIC8vIFVLXG4gICAgICAgICAgICBdKSxcbiAgICAgICAgICApXG5cbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgUGFyYW1ldGVyQ2xhc3MuVmFsdWU6IHtcbiAgICAgICAgICAvLyBVc2VkIG9ubHkgZm9yIGNvbXBhdGliaWxpdHkgXCJiYXLDqG1lcyBJUFBcIi5cbiAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgXCJpcHBfY3N2X2lkXCIsXG4gICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgIGF1ZGl0VHJpbVN0cmluZyxcbiAgICAgICAgICApXG4gICAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIFwidHlwZVwiLFxuICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICBhdWRpdE9wdGlvbnMoT2JqZWN0LnZhbHVlcyhWYWx1ZVR5cGUpKSxcbiAgICAgICAgICApXG4gICAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgICAgLy8gVUtcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBcInBlcmlvZFwiLFxuICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICBhdWRpdFN0cmluZyxcbiAgICAgICAgICAgIGF1ZGl0T3B0aW9ucyhbXG4gICAgICAgICAgICAgIFwiaG91clwiLCAvLyBVS1xuICAgICAgICAgICAgICBcIm1vbnRoXCIsIC8vIFVLXG4gICAgICAgICAgICAgIFwid2Vla1wiLCAvLyBVS1xuICAgICAgICAgICAgICBcInllYXJcIiwgLy8gVUtcbiAgICAgICAgICAgIF0pLFxuICAgICAgICAgIClcbiAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgXCJ1bml0XCIsXG4gICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgIGF1ZGl0RWRpdGFibGVVbml0TmFtZSh1bml0cyksXG4gICAgICAgICAgKVxuICAgICAgICAgIGNvbnN0IHR5cGUgPSBkYXRhLnR5cGUgYXMgVmFsdWVUeXBlXG4gICAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIFwidmFsdWVzXCIsXG4gICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KGF1ZGl0RGF0ZSwgW1xuICAgICAgICAgICAgICBhdWRpdEVkaXRhYmxlVmFsdWVPckV4cGVjdGVkKFxuICAgICAgICAgICAgICAgIHVuaXRzLFxuICAgICAgICAgICAgICAgIGVycm9ycy50eXBlID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgID8gdHlwZSA9PT0gVmFsdWVUeXBlLkJvb2xlYW5cbiAgICAgICAgICAgICAgICAgICAgPyBhdWRpdEJvb2xlYW5cbiAgICAgICAgICAgICAgICAgICAgOiB0eXBlID09PSBWYWx1ZVR5cGUuTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgPyBhdWRpdE51bWJlclxuICAgICAgICAgICAgICAgICAgICAgIDogdHlwZSA9PT0gVmFsdWVUeXBlLlN0cmluZ0FycmF5XG4gICAgICAgICAgICAgICAgICAgICAgICA/IGF1ZGl0QXJyYXkoYXVkaXRTdHJpbmcpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IC8vIHR5cGUgPT09IFZhbHVlVHlwZS5TdHJpbmdCeVN0cmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpdEtleVZhbHVlRGljdGlvbmFyeShhdWRpdFN0cmluZywgYXVkaXRTdHJpbmcpXG4gICAgICAgICAgICAgICAgICA6IGF1ZGl0Tm9vcCxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgYXVkaXRSZXF1aXJlLFxuICAgICAgICAgICAgXSksXG4gICAgICAgICAgICBhdWRpdFJlcXVpcmUsXG4gICAgICAgICAgKVxuXG4gICAgICAgICAgLy8gaWYgKGVycm9ycy52YWx1ZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vICAgY29uc3QgdmFsaWREYXRlcyA9IG5ldyBTZXQoXG4gICAgICAgICAgLy8gICAgIE9iamVjdC5rZXlzKGRhdGEudmFsdWVzIGFzIHsgW2RhdGU6IHN0cmluZ106IHVua25vd24gfSksXG4gICAgICAgICAgLy8gICApXG4gICAgICAgICAgLy8gICB2YWxpZERhdGVzLmFkZChcIjAwMDEtMDEtMDFcIilcblxuICAgICAgICAgIC8vICAgaWYgKGVycm9ycy5ub3RlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgLy8gICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAvLyAgICAgICBkYXRhLFxuICAgICAgICAgIC8vICAgICAgIFwibm90ZXNcIixcbiAgICAgICAgICAvLyAgICAgICB0cnVlLFxuICAgICAgICAgIC8vICAgICAgIGVycm9ycyxcbiAgICAgICAgICAvLyAgICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgICAgIC8vICAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KFxuICAgICAgICAgIC8vICAgICAgICAgYXVkaXRUZXN0KFxuICAgICAgICAgIC8vICAgICAgICAgICAoZGF0ZSkgPT4gdmFsaWREYXRlcy5oYXMoZGF0ZSksXG4gICAgICAgICAgLy8gICAgICAgICAgIChkYXRlKSA9PiBgUGFyYW1ldGVyIGhhcyBubyB2YWx1ZSBmb3IgZGF0ZSAke2RhdGV9YCxcbiAgICAgICAgICAvLyAgICAgICAgICksXG4gICAgICAgICAgLy8gICAgICAgICBhdWRpdE5vb3AsXG4gICAgICAgICAgLy8gICAgICAgKSxcbiAgICAgICAgICAvLyAgICAgKVxuICAgICAgICAgIC8vICAgfVxuXG4gICAgICAgICAgLy8gICBpZiAoZXJyb3JzLm9mZmljaWFsX2pvdXJuYWxfZGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgLy8gICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgICAgICAvLyAgICAgICBkYXRhLFxuICAgICAgICAgIC8vICAgICAgIFwib2ZmaWNpYWxfam91cm5hbF9kYXRlXCIsXG4gICAgICAgICAgLy8gICAgICAgdHJ1ZSxcbiAgICAgICAgICAvLyAgICAgICBlcnJvcnMsXG4gICAgICAgICAgLy8gICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICAvLyAgICAgICBhdWRpdEtleVZhbHVlRGljdGlvbmFyeShcbiAgICAgICAgICAvLyAgICAgICAgIGF1ZGl0VGVzdChcbiAgICAgICAgICAvLyAgICAgICAgICAgKGRhdGUpID0+IHZhbGlkRGF0ZXMuaGFzKGRhdGUpLFxuICAgICAgICAgIC8vICAgICAgICAgICAoZGF0ZSkgPT4gYFBhcmFtZXRlciBoYXMgbm8gdmFsdWUgZm9yIGRhdGUgJHtkYXRlfWAsXG4gICAgICAgICAgLy8gICAgICAgICApLFxuICAgICAgICAgIC8vICAgICAgICAgYXVkaXROb29wLFxuICAgICAgICAgIC8vICAgICAgICksXG4gICAgICAgICAgLy8gICAgIClcbiAgICAgICAgICAvLyAgIH1cblxuICAgICAgICAgIC8vICAgaWYgKGVycm9ycy5yZWZlcmVuY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgLy8gICAgICAgZGF0YSxcbiAgICAgICAgICAvLyAgICAgICBcInJlZmVyZW5jZVwiLFxuICAgICAgICAgIC8vICAgICAgIHRydWUsXG4gICAgICAgICAgLy8gICAgICAgZXJyb3JzLFxuICAgICAgICAgIC8vICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgLy8gICAgICAgYXVkaXRLZXlWYWx1ZURpY3Rpb25hcnkoXG4gICAgICAgICAgLy8gICAgICAgICBhdWRpdFRlc3QoXG4gICAgICAgICAgLy8gICAgICAgICAgIChkYXRlKSA9PiB2YWxpZERhdGVzLmhhcyhkYXRlKSxcbiAgICAgICAgICAvLyAgICAgICAgICAgKGRhdGUpID0+IGBQYXJhbWV0ZXIgaGFzIG5vIHZhbHVlIGZvciBkYXRlICR7ZGF0ZX1gLFxuICAgICAgICAgIC8vICAgICAgICAgKSxcbiAgICAgICAgICAvLyAgICAgICAgIGF1ZGl0Tm9vcCxcbiAgICAgICAgICAvLyAgICAgICApLFxuICAgICAgICAgIC8vICAgICApXG4gICAgICAgICAgLy8gICB9XG4gICAgICAgICAgLy8gfVxuXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhdWRpdC5yZWR1Y2VSZW1haW5pbmcoZGF0YSwgZXJyb3JzLCByZW1haW5pbmdLZXlzKVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhdWRpdEVkaXRhYmxlUmF0ZUJyYWNrZXQodW5pdHM6IFVuaXRbXSk6IEF1ZGl0b3Ige1xuICByZXR1cm4gZnVuY3Rpb24gKGF1ZGl0OiBBdWRpdCwgZGF0YVVua25vd246IHVua25vd24pOiBbdW5rbm93biwgdW5rbm93bl0ge1xuICAgIGlmIChkYXRhVW5rbm93biA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gW2RhdGFVbmtub3duLCBudWxsXVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGRhdGFVbmtub3duICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gYXVkaXQudW5leHBlY3RlZFR5cGUoZGF0YVVua25vd24sIFwib2JqZWN0XCIpXG4gICAgfVxuXG4gICAgY29uc3QgZGF0YTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0gPSB7IC4uLmRhdGFVbmtub3duIH1cbiAgICBjb25zdCBlcnJvcnM6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0ge31cbiAgICBjb25zdCByZW1haW5pbmdLZXlzID0gbmV3IFNldChPYmplY3Qua2V5cyhkYXRhKSlcblxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcImJhc2VcIixcbiAgICAgIHRydWUsXG4gICAgICBlcnJvcnMsXG4gICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgYXVkaXRLZXlWYWx1ZURpY3Rpb25hcnkoYXVkaXREYXRlLCBbXG4gICAgICAgIGF1ZGl0RWRpdGFibGVWYWx1ZU9yRXhwZWN0ZWQodW5pdHMsIGF1ZGl0TnVtYmVyKSxcbiAgICAgICAgYXVkaXRSZXF1aXJlLFxuICAgICAgXSksXG4gICAgKVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcInJhdGVcIixcbiAgICAgIHRydWUsXG4gICAgICBlcnJvcnMsXG4gICAgICByZW1haW5pbmdLZXlzLFxuICAgICAgYXVkaXRLZXlWYWx1ZURpY3Rpb25hcnkoXG4gICAgICAgIGF1ZGl0RGF0ZSxcbiAgICAgICAgYXVkaXRFZGl0YWJsZVZhbHVlT3JFeHBlY3RlZCh1bml0cywgYXVkaXROdW1iZXIpLFxuICAgICAgKSxcbiAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICApXG4gICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgZGF0YSxcbiAgICAgIFwidGhyZXNob2xkXCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KGF1ZGl0RGF0ZSwgW1xuICAgICAgICBhdWRpdEVkaXRhYmxlVmFsdWVPckV4cGVjdGVkKHVuaXRzLCBhdWRpdE51bWJlciksXG4gICAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICAgIF0pLFxuICAgICAgYXVkaXRSZXF1aXJlLFxuICAgIClcblxuICAgIHJldHVybiBhdWRpdC5yZWR1Y2VSZW1haW5pbmcoZGF0YSwgZXJyb3JzLCByZW1haW5pbmdLZXlzKVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhdWRpdEVkaXRhYmxlVW5pdE5hbWUodW5pdHM6IFVuaXRbXSk6IEF1ZGl0b3Ige1xuICBjb25zdCB1bml0c05hbWUgPSB1bml0cy5tYXAoKHsgbmFtZSB9KSA9PiBuYW1lKVxuICByZXR1cm4gYXVkaXRDaGFpbihhdWRpdFN0cmluZywgYXVkaXRPcHRpb25zKHVuaXRzTmFtZSkpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhdWRpdEVkaXRhYmxlVmFsdWUoXG4gIHVuaXRzOiBVbml0W10sXG4gIC4uLmF1ZGl0b3JzOiBBdWRpdG9yW11cbik6IEF1ZGl0b3Ige1xuICByZXR1cm4gKGF1ZGl0OiBBdWRpdCwgZGF0YVVua25vd246IHVua25vd24pOiBbdW5rbm93biwgdW5rbm93bl0gPT4ge1xuICAgIGlmIChkYXRhVW5rbm93biA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gW2RhdGFVbmtub3duLCBudWxsXVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGRhdGFVbmtub3duICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gYXVkaXQudW5leHBlY3RlZFR5cGUoZGF0YVVua25vd24sIFwib2JqZWN0XCIpXG4gICAgfVxuXG4gICAgY29uc3QgZGF0YTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0gPSB7IC4uLmRhdGFVbmtub3duIH1cbiAgICBjb25zdCBlcnJvcnM6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0ge31cbiAgICBjb25zdCByZW1haW5pbmdLZXlzID0gbmV3IFNldChPYmplY3Qua2V5cyhkYXRhKSlcblxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcInJlZmVyZW5jZVwiLFxuICAgICAgdHJ1ZSxcbiAgICAgIGVycm9ycyxcbiAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICBhdWRpdENsZWFuQXJyYXkoYXVkaXRSZWZlcmVuY2UpLFxuICAgIClcbiAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICBkYXRhLFxuICAgICAgXCJ1bml0XCIsXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0RWRpdGFibGVVbml0TmFtZSh1bml0cyksXG4gICAgKVxuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBcInZhbHVlXCIsXG4gICAgICBmYWxzZSwgLy8gS2VlcCBudWxsIHZhbHVlLlxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIC4uLmF1ZGl0b3JzLFxuICAgIClcblxuICAgIHJldHVybiBhdWRpdC5yZWR1Y2VSZW1haW5pbmcoZGF0YSwgZXJyb3JzLCByZW1haW5pbmdLZXlzKVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBhdWRpdEVkaXRhYmxlVmFsdWVPckV4cGVjdGVkID0gKFxuICB1bml0czogVW5pdFtdLFxuICAuLi5hdWRpdG9yczogQXVkaXRvcltdXG4pOiBBdWRpdG9yID0+XG4gIGF1ZGl0U3dpdGNoKFxuICAgIGF1ZGl0VGVzdCgodmFsdWUpID0+IHZhbHVlID09PSBcImV4cGVjdGVkXCIpLFxuICAgIGF1ZGl0RWRpdGFibGVWYWx1ZSh1bml0cywgLi4uYXVkaXRvcnMpLFxuICApXG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBRUVBLFVBQVUsRUFDVkMsWUFBWSxFQUNaQyxVQUFVLEVBQ1ZDLGVBQWUsRUFDZkMsYUFBYSxFQUNiQyx1QkFBdUIsRUFDdkJDLFNBQVMsRUFDVEMsV0FBVyxFQUNYQyxZQUFZLEVBQ1pDLFlBQVksRUFDWkMsV0FBVyxFQUNYQyxXQUFXLEVBQ1hDLFNBQVMsRUFDVEMsZUFBZSxFQUNmQyxXQUFXLFFBRU4sZ0JBQWdCO0FBQUEsU0FFZEMsU0FBUztBQUFBLFNBQ1RDLGNBQWMsRUFBRUMscUJBQXFCO0FBQUEsU0FDckNDLGNBQWMsRUFBRUMsU0FBUyxFQUFFQyxTQUFTO0FBRzdDLE9BQU8sU0FBU0MsMEJBQTBCQSxDQUFDQyxLQUFhLEVBQVc7RUFDakUsT0FBTyxVQUFVQyxLQUFZLEVBQUVDLFdBQW9CLEVBQXNCO0lBQ3ZFLElBQUlBLFdBQVcsSUFBSSxJQUFJLEVBQUU7TUFDdkIsT0FBTyxDQUFDQSxXQUFXLEVBQUUsSUFBSSxDQUFDO0lBQzVCO0lBQ0EsSUFBSSxPQUFPQSxXQUFXLEtBQUssUUFBUSxFQUFFO01BQ25DLE9BQU9ELEtBQUssQ0FBQ0UsY0FBYyxDQUFDRCxXQUFXLEVBQUUsUUFBUSxDQUFDO0lBQ3BEO0lBRUEsTUFBTUUsSUFBZ0MsR0FBRztNQUFFLEdBQUdGO0lB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