@openfisca/json-model
Version:
Library to handle informations extracted in JSON or YAML format from OpenFisca parameters, variables, etc
242 lines • 30 kB
JavaScript
import { Instant, Period } from "../periods.js";
import { AstTransformer } from "./visitors.js";
class InstantOrPeriodMethod {
constructor(instantOrPeriod, methodName) {
this.instantOrPeriod = instantOrPeriod;
this.methodName = methodName;
}
}
class InstantOrPeriodEvaluator extends AstTransformer {
constructor(period) {
super();
this.period = period;
}
transform_Attribute(attribute) {
const value = this.transform(attribute.value);
const {
output: valueOutput
} = value;
if (value.error === undefined) {
if (valueOutput instanceof Instant) {
switch (attribute.attr) {
case "offset":
case "period":
// Method
return {
input: attribute,
output: new InstantOrPeriodMethod(valueOutput, attribute.attr)
};
default:
{
return {
input: attribute,
output: valueOutput,
error: `Unknown instant attribute: ${attribute.attr}`
};
}
}
}
if (valueOutput instanceof Period) {
switch (attribute.attr) {
case "days":
case "first_month":
case "last_3_months":
case "last_month":
case "last_year":
case "n_2":
case "start":
case "this_year":
// Simple attribute
return {
input: attribute,
output: valueOutput[attribute.attr]
};
case "offset":
// Method
return {
input: attribute,
output: new InstantOrPeriodMethod(valueOutput, attribute.attr)
};
default:
{
return {
input: attribute,
output: valueOutput,
error: `Unknown period attribute: ${attribute.attr}`
};
}
}
}
}
const result = this.reduceErrorByKey(attribute, {
...attribute,
value: valueOutput
}, {
value: value.error
});
return result.error === undefined ? {
...result,
error: "Unhandled Attribute in evaluation of instant or period"
} : result;
}
transform_Call(call) {
const args = this.reduceMapErrors(call.args.map(arg => this.transform(arg)));
const func = this.transform(call.func);
const {
output: funcOutput
} = func;
const keywords = this.reduceMapErrors(call.keywords.map(keyword => this.transform(keyword)));
if (args.error === undefined && func.error === undefined && keywords.error === undefined) {
if (funcOutput instanceof InstantOrPeriodMethod) {
const {
instantOrPeriod,
methodName
} = funcOutput;
if (instantOrPeriod instanceof Instant) {
switch (methodName) {
case "offset":
{
console.assert(keywords.output.length === 0, "Unexpected keyword argument for Instant.offset() method");
return {
input: call,
output: instantOrPeriod.offset(...args.output)
};
}
case "period":
{
console.assert(keywords.output.length === 0, "Unexpected keyword argument for Instant.period() method");
return {
input: call,
output: instantOrPeriod.period(...args.output)
};
}
default:
{
return {
input: call,
output: instantOrPeriod,
error: `Unknown instant method: ${methodName}`
};
}
}
}
if (instantOrPeriod instanceof Period) {
switch (methodName) {
case "offset":
{
console.assert(keywords.output.length === 0, "Unexpected keyword argument for Period.offset() method");
return {
input: call,
output: instantOrPeriod.offset(...args.output)
};
}
default:
{
return {
input: call,
output: instantOrPeriod,
error: `Unknown period method: ${methodName}`
};
}
}
}
}
}
const result = this.reduceErrorByKey(call, {
...call,
args: args.output,
func: funcOutput,
keywords: keywords.output
}, {
args: args.error,
func: func.error,
keywords: keywords.error
});
return result.error === undefined ? {
...result,
error: "Unhandled Call in evaluation of instant or period"
} : result;
}
transform_Constant(constant) {
return {
input: constant,
output: constant.value
};
}
transform_instant_or_period_expression(instantOrPeriodExpression) {
const expression = this.transform(instantOrPeriodExpression.expression);
return this.reduceErrorByKey(instantOrPeriodExpression, expression.output, {
expression: expression.error
});
}
transform_period(period) {
return {
input: period,
output: this.period
};
}
transform_UnaryOp(unaryOp) {
const operand = this.transform(unaryOp.operand);
if (operand.error === undefined) {
switch (unaryOp.op.ast_class) {
case "Invert":
case "Not":
break;
case "UAdd":
return {
input: unaryOp,
output: operand.output
};
case "USub":
return {
input: unaryOp,
output: -operand.output
};
default:
assertNever("unary operator", unaryOp.op);
}
}
const result = this.reduceErrorByKey(unaryOp, {
...unaryOp,
operand: operand.output
}, {
operand: operand.error
});
return result.error === undefined ? {
...result,
error: "Unhandled UnaryOp in evaluation of instant or period"
} : result;
}
transformGenericOutputByKey(input, _outputByKey, _errorByKey) {
return {
input,
output: new Instant(9999, 12, 31),
error: `Missing instant or period transformer for ${input.ast_class}`
};
}
}
function assertNever(type, value) {
throw new Error(`Unexpected ${type}: ${JSON.stringify(value)}`);
}
export function evaluateOpenfiscaAstInstantOrPeriod(instantOrPeriod, period) {
const instantOrPeriodEvaluator = new InstantOrPeriodEvaluator(period);
const instantOrPeriodResult = instantOrPeriodEvaluator.transform(instantOrPeriod);
if (instantOrPeriodResult.output instanceof InstantOrPeriodMethod) {
// Error: Result output is a method instead of a instant or a period.
return {
input: instantOrPeriodResult.input,
output: instantOrPeriodResult.output.instantOrPeriod,
error: instantOrPeriodResult.error ?? "Evaluation of instant or period expression is a method instead of a value"
};
}
if (!(instantOrPeriodResult.output instanceof Instant) && !(instantOrPeriodResult.output instanceof Period) && !Number.isInteger(instantOrPeriodResult.output)) {
// Error: Unexpected result output.
return {
input: instantOrPeriodResult.input,
output: new Instant(9999, 12, 31),
error: instantOrPeriodResult.error ?? "Unexpected result for evaluation of instant or period"
};
}
return instantOrPeriodResult;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJJbnN0YW50IiwiUGVyaW9kIiwiQXN0VHJhbnNmb3JtZXIiLCJJbnN0YW50T3JQZXJpb2RNZXRob2QiLCJjb25zdHJ1Y3RvciIsImluc3RhbnRPclBlcmlvZCIsIm1ldGhvZE5hbWUiLCJJbnN0YW50T3JQZXJpb2RFdmFsdWF0b3IiLCJwZXJpb2QiLCJ0cmFuc2Zvcm1fQXR0cmlidXRlIiwiYXR0cmlidXRlIiwidmFsdWUiLCJ0cmFuc2Zvcm0iLCJvdXRwdXQiLCJ2YWx1ZU91dHB1dCIsImVycm9yIiwidW5kZWZpbmVkIiwiYXR0ciIsImlucHV0IiwicmVzdWx0IiwicmVkdWNlRXJyb3JCeUtleSIsInRyYW5zZm9ybV9DYWxsIiwiY2FsbCIsImFyZ3MiLCJyZWR1Y2VNYXBFcnJvcnMiLCJtYXAiLCJhcmciLCJmdW5jIiwiZnVuY091dHB1dCIsImtleXdvcmRzIiwia2V5d29yZCIsImNvbnNvbGUiLCJhc3NlcnQiLCJsZW5ndGgiLCJvZmZzZXQiLCJ0cmFuc2Zvcm1fQ29uc3RhbnQiLCJjb25zdGFudCIsInRyYW5zZm9ybV9pbnN0YW50X29yX3BlcmlvZF9leHByZXNzaW9uIiwiaW5zdGFudE9yUGVyaW9kRXhwcmVzc2lvbiIsImV4cHJlc3Npb24iLCJ0cmFuc2Zvcm1fcGVyaW9kIiwidHJhbnNmb3JtX1VuYXJ5T3AiLCJ1bmFyeU9wIiwib3BlcmFuZCIsIm9wIiwiYXN0X2NsYXNzIiwiYXNzZXJ0TmV2ZXIiLCJ0cmFuc2Zvcm1HZW5lcmljT3V0cHV0QnlLZXkiLCJfb3V0cHV0QnlLZXkiLCJfZXJyb3JCeUtleSIsInR5cGUiLCJFcnJvciIsIkpTT04iLCJzdHJpbmdpZnkiLCJldmFsdWF0ZU9wZW5maXNjYUFzdEluc3RhbnRPclBlcmlvZCIsImluc3RhbnRPclBlcmlvZEV2YWx1YXRvciIsImluc3RhbnRPclBlcmlvZFJlc3VsdCIsIk51bWJlciIsImlzSW50ZWdlciJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hc3QvcGVyaW9kcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbnN0YW50LCBQZXJpb2QsIFBlcmlvZFVuaXQgfSBmcm9tIFwiLi4vcGVyaW9kc1wiXG5cbmltcG9ydCB0eXBlIHtcbiAgT3BlbmZpc2NhQXN0SW5zdGFudE9yUGVyaW9kRXhwcmVzc2lvbixcbiAgT3BlbmZpc2NhQXN0Tm9kZSxcbiAgT3BlbmZpc2NhQXN0UGVyaW9kLFxuICBQeXRob25Bc3RBdHRyaWJ1dGUsXG4gIFB5dGhvbkFzdENhbGwsXG4gIFB5dGhvbkFzdENvbnN0YW50LFxuICBQeXRob25Bc3RLZXl3b3JkLFxuICBQeXRob25Bc3RVbmFyeU9wLFxufSBmcm9tIFwiLi9ub2Rlc1wiXG5pbXBvcnQgeyBBc3RUcmFuc2Zvcm1lciB9IGZyb20gXCIuL3Zpc2l0b3JzXCJcblxuY2xhc3MgSW5zdGFudE9yUGVyaW9kTWV0aG9kIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGluc3RhbnRPclBlcmlvZDogSW5zdGFudCB8IFBlcmlvZCxcbiAgICBwdWJsaWMgcmVhZG9ubHkgbWV0aG9kTmFtZTogc3RyaW5nLFxuICApIHt9XG59XG5cbmNsYXNzIEluc3RhbnRPclBlcmlvZEV2YWx1YXRvciBleHRlbmRzIEFzdFRyYW5zZm9ybWVyPFxuICBPcGVuZmlzY2FBc3ROb2RlLFxuICB1bmtub3duXG4+IHtcbiAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHBlcmlvZDogUGVyaW9kKSB7XG4gICAgc3VwZXIoKVxuICB9XG5cbiAgdHJhbnNmb3JtX0F0dHJpYnV0ZShhdHRyaWJ1dGU6IFB5dGhvbkFzdEF0dHJpYnV0ZSk6IHtcbiAgICBpbnB1dDogT3BlbmZpc2NhQXN0Tm9kZVxuICAgIG91dHB1dDogdW5rbm93blxuICAgIGVycm9yPzogdW5rbm93blxuICB9IHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMudHJhbnNmb3JtKGF0dHJpYnV0ZS52YWx1ZSlcbiAgICBjb25zdCB7IG91dHB1dDogdmFsdWVPdXRwdXQgfSA9IHZhbHVlXG5cbiAgICBpZiAodmFsdWUuZXJyb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHZhbHVlT3V0cHV0IGluc3RhbmNlb2YgSW5zdGFudCkge1xuICAgICAgICBzd2l0Y2ggKGF0dHJpYnV0ZS5hdHRyKSB7XG4gICAgICAgICAgY2FzZSBcIm9mZnNldFwiOlxuICAgICAgICAgIGNhc2UgXCJwZXJpb2RcIjpcbiAgICAgICAgICAgIC8vIE1ldGhvZFxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgaW5wdXQ6IGF0dHJpYnV0ZSxcbiAgICAgICAgICAgICAgb3V0cHV0OiBuZXcgSW5zdGFudE9yUGVyaW9kTWV0aG9kKHZhbHVlT3V0cHV0LCBhdHRyaWJ1dGUuYXR0ciksXG4gICAgICAgICAgICB9XG4gICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgaW5wdXQ6IGF0dHJpYnV0ZSxcbiAgICAgICAgICAgICAgb3V0cHV0OiB2YWx1ZU91dHB1dCxcbiAgICAgICAgICAgICAgZXJyb3I6IGBVbmtub3duIGluc3RhbnQgYXR0cmlidXRlOiAke2F0dHJpYnV0ZS5hdHRyfWAsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodmFsdWVPdXRwdXQgaW5zdGFuY2VvZiBQZXJpb2QpIHtcbiAgICAgICAgc3dpdGNoIChhdHRyaWJ1dGUuYXR0cikge1xuICAgICAgICAgIGNhc2UgXCJkYXlzXCI6XG4gICAgICAgICAgY2FzZSBcImZpcnN0X21vbnRoXCI6XG4gICAgICAgICAgY2FzZSBcImxhc3RfM19tb250aHNcIjpcbiAgICAgICAgICBjYXNlIFwibGFzdF9tb250aFwiOlxuICAgICAgICAgIGNhc2UgXCJsYXN0X3llYXJcIjpcbiAgICAgICAgICBjYXNlIFwibl8yXCI6XG4gICAgICAgICAgY2FzZSBcInN0YXJ0XCI6XG4gICAgICAgICAgY2FzZSBcInRoaXNfeWVhclwiOlxuICAgICAgICAgICAgLy8gU2ltcGxlIGF0dHJpYnV0ZVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgaW5wdXQ6IGF0dHJpYnV0ZSxcbiAgICAgICAgICAgICAgb3V0cHV0OiAodmFsdWVPdXRwdXQgYXMgdW5rbm93biBhcyB7IFthdHRyOiBzdHJpbmddOiB1bmtub3duIH0pW1xuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS5hdHRyXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSBcIm9mZnNldFwiOlxuICAgICAgICAgICAgLy8gTWV0aG9kXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBpbnB1dDogYXR0cmlidXRlLFxuICAgICAgICAgICAgICBvdXRwdXQ6IG5ldyBJbnN0YW50T3JQZXJpb2RNZXRob2QodmFsdWVPdXRwdXQsIGF0dHJpYnV0ZS5hdHRyKSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBpbnB1dDogYXR0cmlidXRlLFxuICAgICAgICAgICAgICBvdXRwdXQ6IHZhbHVlT3V0cHV0LFxuICAgICAgICAgICAgICBlcnJvcjogYFVua25vd24gcGVyaW9kIGF0dHJpYnV0ZTogJHthdHRyaWJ1dGUuYXR0cn1gLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMucmVkdWNlRXJyb3JCeUtleShcbiAgICAgIGF0dHJpYnV0ZSxcbiAgICAgIHtcbiAgICAgICAgLi4uYXR0cmlidXRlLFxuICAgICAgICB2YWx1ZTogdmFsdWVPdXRwdXQsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB2YWx1ZTogdmFsdWUuZXJyb3IsXG4gICAgICB9LFxuICAgIClcbiAgICByZXR1cm4gcmVzdWx0LmVycm9yID09PSB1bmRlZmluZWRcbiAgICAgID8ge1xuICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICBlcnJvcjogXCJVbmhhbmRsZWQgQXR0cmlidXRlIGluIGV2YWx1YXRpb24gb2YgaW5zdGFudCBvciBwZXJpb2RcIixcbiAgICAgICAgfVxuICAgICAgOiByZXN1bHRcbiAgfVxuXG4gIHRyYW5zZm9ybV9DYWxsKGNhbGw6IFB5dGhvbkFzdENhbGwpOiB7XG4gICAgaW5wdXQ6IE9wZW5maXNjYUFzdE5vZGVcbiAgICBvdXRwdXQ6IHVua25vd25cbiAgICBlcnJvcj86IHVua25vd25cbiAgfSB7XG4gICAgY29uc3QgYXJncyA9IHRoaXMucmVkdWNlTWFwRXJyb3JzKFxuICAgICAgY2FsbC5hcmdzLm1hcCgoYXJnKSA9PiB0aGlzLnRyYW5zZm9ybShhcmcpKSxcbiAgICApXG4gICAgY29uc3QgZnVuYyA9IHRoaXMudHJhbnNmb3JtKGNhbGwuZnVuYylcbiAgICBjb25zdCB7IG91dHB1dDogZnVuY091dHB1dCB9ID0gZnVuY1xuICAgIGNvbnN0IGtleXdvcmRzID0gdGhpcy5yZWR1Y2VNYXBFcnJvcnMoXG4gICAgICBjYWxsLmtleXdvcmRzLm1hcCgoa2V5d29yZCkgPT4gdGhpcy50cmFuc2Zvcm0oa2V5d29yZCkpLFxuICAgICkgYXMge1xuICAgICAgaW5wdXQ6IE9wZW5maXNjYUFzdE5vZGVbXVxuICAgICAgb3V0cHV0OiBQeXRob25Bc3RLZXl3b3JkW11cbiAgICAgIGVycm9yPzogdW5rbm93blxuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGFyZ3MuZXJyb3IgPT09IHVuZGVmaW5lZCAmJlxuICAgICAgZnVuYy5lcnJvciA9PT0gdW5kZWZpbmVkICYmXG4gICAgICBrZXl3b3Jkcy5lcnJvciA9PT0gdW5kZWZpbmVkXG4gICAgKSB7XG4gICAgICBpZiAoZnVuY091dHB1dCBpbnN0YW5jZW9mIEluc3RhbnRPclBlcmlvZE1ldGhvZCkge1xuICAgICAgICBjb25zdCB7IGluc3RhbnRPclBlcmlvZCwgbWV0aG9kTmFtZSB9ID0gZnVuY091dHB1dFxuICAgICAgICBpZiAoaW5zdGFudE9yUGVyaW9kIGluc3RhbmNlb2YgSW5zdGFudCkge1xuICAgICAgICAgIHN3aXRjaCAobWV0aG9kTmFtZSkge1xuICAgICAgICAgICAgY2FzZSBcIm9mZnNldFwiOiB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuYXNzZXJ0KFxuICAgICAgICAgICAgICAgIGtleXdvcmRzLm91dHB1dC5sZW5ndGggPT09IDAsXG4gICAgICAgICAgICAgICAgXCJVbmV4cGVjdGVkIGtleXdvcmQgYXJndW1lbnQgZm9yIEluc3RhbnQub2Zmc2V0KCkgbWV0aG9kXCIsXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBpbnB1dDogY2FsbCxcbiAgICAgICAgICAgICAgICBvdXRwdXQ6IGluc3RhbnRPclBlcmlvZC5vZmZzZXQoXG4gICAgICAgICAgICAgICAgICAuLi4oYXJncy5vdXRwdXQgYXMgW1xuICAgICAgICAgICAgICAgICAgICBcImZpcnN0LW9mXCIgfCBcImxhc3Qtb2ZcIiB8IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgUGVyaW9kVW5pdCxcbiAgICAgICAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJwZXJpb2RcIjoge1xuICAgICAgICAgICAgICBjb25zb2xlLmFzc2VydChcbiAgICAgICAgICAgICAgICBrZXl3b3Jkcy5vdXRwdXQubGVuZ3RoID09PSAwLFxuICAgICAgICAgICAgICAgIFwiVW5leHBlY3RlZCBrZXl3b3JkIGFyZ3VtZW50IGZvciBJbnN0YW50LnBlcmlvZCgpIG1ldGhvZFwiLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgaW5wdXQ6IGNhbGwsXG4gICAgICAgICAgICAgICAgb3V0cHV0OiBpbnN0YW50T3JQZXJpb2QucGVyaW9kKFxuICAgICAgICAgICAgICAgICAgLi4uKGFyZ3Mub3V0cHV0IGFzIFtQZXJpb2RVbml0LCBudW1iZXJdKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgaW5wdXQ6IGNhbGwsXG4gICAgICAgICAgICAgICAgb3V0cHV0OiBpbnN0YW50T3JQZXJpb2QsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGBVbmtub3duIGluc3RhbnQgbWV0aG9kOiAke21ldGhvZE5hbWV9YCxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5zdGFudE9yUGVyaW9kIGluc3RhbmNlb2YgUGVyaW9kKSB7XG4gICAgICAgICAgc3dpdGNoIChtZXRob2ROYW1lKSB7XG4gICAgICAgICAgICBjYXNlIFwib2Zmc2V0XCI6IHtcbiAgICAgICAgICAgICAgY29uc29sZS5hc3NlcnQoXG4gICAgICAgICAgICAgICAga2V5d29yZHMub3V0cHV0Lmxlbmd0aCA9PT0gMCxcbiAgICAgICAgICAgICAgICBcIlVuZXhwZWN0ZWQga2V5d29yZCBhcmd1bWVudCBmb3IgUGVyaW9kLm9mZnNldCgpIG1ldGhvZFwiLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgaW5wdXQ6IGNhbGwsXG4gICAgICAgICAgICAgICAgb3V0cHV0OiBpbnN0YW50T3JQZXJpb2Qub2Zmc2V0KFxuICAgICAgICAgICAgICAgICAgLi4uKGFyZ3Mub3V0cHV0IGFzIFtcbiAgICAgICAgICAgICAgICAgICAgXCJmaXJzdC1vZlwiIHwgXCJsYXN0LW9mXCIgfCBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgIFBlcmlvZFVuaXQgfCB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgaW5wdXQ6IGNhbGwsXG4gICAgICAgICAgICAgICAgb3V0cHV0OiBpbnN0YW50T3JQZXJpb2QsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGBVbmtub3duIHBlcmlvZCBtZXRob2Q6ICR7bWV0aG9kTmFtZX1gLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5yZWR1Y2VFcnJvckJ5S2V5KFxuICAgICAgY2FsbCxcbiAgICAgIHtcbiAgICAgICAgLi4uY2FsbCxcbiAgICAgICAgYXJnczogYXJncy5vdXRwdXQsXG4gICAgICAgIGZ1bmM6IGZ1bmNPdXRwdXQsXG4gICAgICAgIGtleXdvcmRzOiBrZXl3b3Jkcy5vdXRwdXQsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBhcmdzOiBhcmdzLmVycm9yLFxuICAgICAgICBmdW5jOiBmdW5jLmVycm9yLFxuICAgICAgICBrZXl3b3Jkczoga2V5d29yZHMuZXJyb3IsXG4gICAgICB9LFxuICAgIClcbiAgICByZXR1cm4gcmVzdWx0LmVycm9yID09PSB1bmRlZmluZWRcbiAgICAgID8ge1xuICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICBlcnJvcjogXCJVbmhhbmRsZWQgQ2FsbCBpbiBldmFsdWF0aW9uIG9mIGluc3RhbnQgb3IgcGVyaW9kXCIsXG4gICAgICAgIH1cbiAgICAgIDogcmVzdWx0XG4gIH1cblxuICB0cmFuc2Zvcm1fQ29uc3RhbnQoY29uc3RhbnQ6IFB5dGhvbkFzdENvbnN0YW50KToge1xuICAgIGlucHV0OiBPcGVuZmlzY2FBc3ROb2RlXG4gICAgb3V0cHV0OiB1bmtub3duXG4gICAgZXJyb3I/OiB1bmtub3duXG4gIH0ge1xuICAgIHJldHVybiB7IGlucHV0OiBjb25zdGFudCwgb3V0cHV0OiBjb25zdGFudC52YWx1ZSB9XG4gIH1cblxuICB0cmFuc2Zvcm1faW5zdGFudF9vcl9wZXJpb2RfZXhwcmVzc2lvbihcbiAgICBpbnN0YW50T3JQZXJpb2RFeHByZXNzaW9uOiBPcGVuZmlzY2FBc3RJbnN0YW50T3JQZXJpb2RFeHByZXNzaW9uLFxuICApOiB7XG4gICAgaW5wdXQ6IE9wZW5maXNjYUFzdE5vZGVcbiAgICBvdXRwdXQ6IHVua25vd25cbiAgICBlcnJvcj86IHVua25vd25cbiAgfSB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IHRoaXMudHJhbnNmb3JtKGluc3RhbnRPclBlcmlvZEV4cHJlc3Npb24uZXhwcmVzc2lvbilcbiAgICByZXR1cm4gdGhpcy5yZWR1Y2VFcnJvckJ5S2V5KGluc3RhbnRPclBlcmlvZEV4cHJlc3Npb24sIGV4cHJlc3Npb24ub3V0cHV0LCB7XG4gICAgICBleHByZXNzaW9uOiBleHByZXNzaW9uLmVycm9yLFxuICAgIH0pXG4gIH1cblxuICB0cmFuc2Zvcm1fcGVyaW9kKHBlcmlvZDogT3BlbmZpc2NhQXN0UGVyaW9kKToge1xuICAgIGlucHV0OiBPcGVuZmlzY2FBc3ROb2RlXG4gICAgb3V0cHV0OiB1bmtub3duXG4gICAgZXJyb3I/OiB1bmtub3duXG4gIH0ge1xuICAgIHJldHVybiB7IGlucHV0OiBwZXJpb2QsIG91dHB1dDogdGhpcy5wZXJpb2QgfVxuICB9XG5cbiAgdHJhbnNmb3JtX1VuYXJ5T3AodW5hcnlPcDogUHl0aG9uQXN0VW5hcnlPcCk6IHtcbiAgICBpbnB1dDogT3BlbmZpc2NhQXN0Tm9kZVxuICAgIG91dHB1dDogdW5rbm93blxuICAgIGVycm9yPzogdW5rbm93blxuICB9IHtcbiAgICBjb25zdCBvcGVyYW5kID0gdGhpcy50cmFuc2Zvcm0odW5hcnlPcC5vcGVyYW5kKVxuICAgIGlmIChvcGVyYW5kLmVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHN3aXRjaCAodW5hcnlPcC5vcC5hc3RfY2xhc3MpIHtcbiAgICAgICAgY2FzZSBcIkludmVydFwiOlxuICAgICAgICBjYXNlIFwiTm90XCI6XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSBcIlVBZGRcIjpcbiAgICAgICAgICByZXR1cm4geyBpbnB1dDogdW5hcnlPcCwgb3V0cHV0OiBvcGVyYW5kLm91dHB1dCB9XG4gICAgICAgIGNhc2UgXCJVU3ViXCI6XG4gICAgICAgICAgcmV0dXJuIHsgaW5wdXQ6IHVuYXJ5T3AsIG91dHB1dDogLShvcGVyYW5kLm91dHB1dCBhcyBudW1iZXIpIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBhc3NlcnROZXZlcihcInVuYXJ5IG9wZXJhdG9yXCIsIHVuYXJ5T3Aub3ApXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5yZWR1Y2VFcnJvckJ5S2V5KFxuICAgICAgdW5hcnlPcCxcbiAgICAgIHtcbiAgICAgICAgLi4udW5hcnlPcCxcbiAgICAgICAgb3BlcmFuZDogb3BlcmFuZC5vdXRwdXQsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBvcGVyYW5kOiBvcGVyYW5kLmVycm9yLFxuICAgICAgfSxcbiAgICApXG4gICAgcmV0dXJuIHJlc3VsdC5lcnJvciA9PT0gdW5kZWZpbmVkXG4gICAgICA/IHtcbiAgICAgICAgICAuLi5yZXN1bHQsXG4gICAgICAgICAgZXJyb3I6IFwiVW5oYW5kbGVkIFVuYXJ5T3AgaW4gZXZhbHVhdGlvbiBvZiBpbnN0YW50IG9yIHBlcmlvZFwiLFxuICAgICAgICB9XG4gICAgICA6IHJlc3VsdFxuICB9XG5cbiAgdHJhbnNmb3JtR2VuZXJpY091dHB1dEJ5S2V5KFxuICAgIGlucHV0OiBPcGVuZmlzY2FBc3ROb2RlLFxuICAgIF9vdXRwdXRCeUtleToge1xuICAgICAgW2tleTogc3RyaW5nXTogdW5rbm93blxuICAgIH0sXG4gICAgX2Vycm9yQnlLZXk6IHtcbiAgICAgIFtrZXk6IHN0cmluZ106IHVua25vd25cbiAgICB9LFxuICApOiB7XG4gICAgaW5wdXQ6IE9wZW5maXNjYUFzdE5vZGVcbiAgICBvdXRwdXQ6IHVua25vd25cbiAgICBlcnJvcj86IHVua25vd25cbiAgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlucHV0LFxuICAgICAgb3V0cHV0OiBuZXcgSW5zdGFudCg5OTk5LCAxMiwgMzEpLFxuICAgICAgZXJyb3I6IGBNaXNzaW5nIGluc3RhbnQgb3IgcGVyaW9kIHRyYW5zZm9ybWVyIGZvciAke2lucHV0LmFzdF9jbGFzc31gLFxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NlcnROZXZlcih0eXBlOiBzdHJpbmcsIHZhbHVlOiBuZXZlcik6IG5ldmVyIHtcbiAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkICR7dHlwZX06ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfWApXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBldmFsdWF0ZU9wZW5maXNjYUFzdEluc3RhbnRPclBlcmlvZChcbiAgaW5zdGFudE9yUGVyaW9kOiBPcGVuZmlzY2FBc3ROb2RlLFxuICBwZXJpb2Q6IFBlcmlvZCxcbik6IHtcbiAgaW5wdXQ6IE9wZW5maXNjYUFzdE5vZGVcbiAgb3V0cHV0OiBJbnN0YW50IHwgUGVyaW9kIHwgbnVtYmVyXG4gIGVycm9yPzogdW5rbm93blxufSB7XG4gIGNvbnN0IGluc3RhbnRPclBlcmlvZEV2YWx1YXRvciA9IG5ldyBJbnN0YW50T3JQZXJpb2RFdmFsdWF0b3IocGVyaW9kKVxuICBjb25zdCBpbnN0YW50T3JQZXJpb2RSZXN1bHQgPVxuICAgIGluc3RhbnRPclBlcmlvZEV2YWx1YXRvci50cmFuc2Zvcm0oaW5zdGFudE9yUGVyaW9kKVxuICBpZiAoaW5zdGFudE9yUGVyaW9kUmVzdWx0Lm91dHB1dCBpbnN0YW5jZW9mIEluc3RhbnRPclBlcmlvZE1ldGhvZCkge1xuICAgIC8vIEVycm9yOiBSZXN1bHQgb3V0cHV0IGlzIGEgbWV0aG9kIGluc3RlYWQgb2YgYSBpbnN0YW50IG9yIGEgcGVyaW9kLlxuICAgIHJldHVybiB7XG4gICAgICBpbnB1dDogaW5zdGFudE9yUGVyaW9kUmVzdWx0LmlucHV0LFxuICAgICAgb3V0cHV0OiBpbnN0YW50T3JQZXJpb2RSZXN1bHQub3V0cHV0Lmluc3RhbnRPclBlcmlvZCxcbiAgICAgIGVycm9yOlxuICAgICAgICBpbnN0YW50T3JQZXJpb2RSZXN1bHQuZXJyb3IgPz9cbiAgICAgICAgXCJFdmFsdWF0aW9uIG9mIGluc3RhbnQgb3IgcGVyaW9kIGV4cHJlc3Npb24gaXMgYSBtZXRob2QgaW5zdGVhZCBvZiBhIHZhbHVlXCIsXG4gICAgfVxuICB9XG4gIGlmIChcbiAgICAhKGluc3RhbnRPclBlcmlvZFJlc3VsdC5vdXRwdXQgaW5zdGFuY2VvZiBJbnN0YW50KSAmJlxuICAgICEoaW5zdGFudE9yUGVyaW9kUmVzdWx0Lm91dHB1dCBpbnN0YW5jZW9mIFBlcmlvZCkgJiZcbiAgICAhTnVtYmVyLmlzSW50ZWdlcihpbnN0YW50T3JQZXJpb2RSZXN1bHQub3V0cHV0KVxuICApIHtcbiAgICAvLyBFcnJvcjogVW5leHBlY3RlZCByZXN1bHQgb3V0cHV0LlxuICAgIHJldHVybiB7XG4gICAgICBpbnB1dDogaW5zdGFudE9yUGVyaW9kUmVzdWx0LmlucHV0LFxuICAgICAgb3V0cHV0OiBuZXcgSW5zdGFudCg5OTk5LCAxMiwgMzEpLFxuICAgICAgZXJyb3I6XG4gICAgICAgIGluc3RhbnRPclBlcmlvZFJlc3VsdC5lcnJvciA/P1xuICAgICAgICBcIlVuZXhwZWN0ZWQgcmVzdWx0IGZvciBldmFsdWF0aW9uIG9mIGluc3RhbnQgb3IgcGVyaW9kXCIsXG4gICAgfVxuICB9XG4gIHJldHVybiBpbnN0YW50T3JQZXJpb2RSZXN1bHQgYXMge1xuICAgIGlucHV0OiBPcGVuZmlzY2FBc3ROb2RlXG4gICAgb3V0cHV0OiBJbnN0YW50IHwgUGVyaW9kXG4gICAgZXJyb3I/OiB1bmtub3duXG4gIH1c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