@oaklean/profiler-core
Version:
Part of the @oaklean suite. It provides all basic functions to work with the `.oak` file format. It allows parsing the `.oak` file format as well as tools for analyzing the measurement values. It also provides all necessary capabilities required for prec
443 lines • 44.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SensorValues = exports.LANG_INTERNAL_SENSOR_VALUE_NAMES = exports.EXTERN_SENSOR_VALUE_NAMES = exports.INTERN_SENSOR_VALUE_NAMES = exports.AGGREGATED_SENSOR_VALUE_NAMES = exports.SENSOR_VALUES_BYTE_SIZE_MAP = void 0;
const BaseModel_1 = require("./BaseModel");
const BufferHelper_1 = require("../helper/BufferHelper");
// Types
const types_1 = require("../types");
const UnitHelper_1 = require("../helper/UnitHelper");
exports.SENSOR_VALUES_BYTE_SIZE_MAP = {
profilerHits: types_1.PrimitiveBufferTypes.UInt,
selfCPUTime: types_1.PrimitiveBufferTypes.UInt,
aggregatedCPUTime: types_1.PrimitiveBufferTypes.UInt,
internCPUTime: types_1.PrimitiveBufferTypes.UInt,
externCPUTime: types_1.PrimitiveBufferTypes.UInt,
langInternalCPUTime: types_1.PrimitiveBufferTypes.UInt,
selfCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double,
aggregatedCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double,
internCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double,
externCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double,
langInternalCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double,
selfRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double,
aggregatedRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double,
internRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double,
externRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double,
langInternalRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double
};
exports.AGGREGATED_SENSOR_VALUE_NAMES = [
'aggregatedCPUTime',
'aggregatedCPUEnergyConsumption',
'aggregatedRAMEnergyConsumption'
];
exports.INTERN_SENSOR_VALUE_NAMES = [
'internCPUTime',
'internCPUEnergyConsumption',
'internRAMEnergyConsumption'
];
exports.EXTERN_SENSOR_VALUE_NAMES = [
'externCPUTime',
'externCPUEnergyConsumption',
'externRAMEnergyConsumption'
];
exports.LANG_INTERNAL_SENSOR_VALUE_NAMES = [
'langInternalCPUTime',
'langInternalCPUEnergyConsumption',
'langInternalRAMEnergyConsumption'
];
class SensorValues extends BaseModel_1.BaseModel {
constructor({ profilerHits, selfCPUTime, aggregatedCPUTime, internCPUTime, externCPUTime, langInternalCPUTime, selfCPUEnergyConsumption, aggregatedCPUEnergyConsumption, internCPUEnergyConsumption, externCPUEnergyConsumption, langInternalCPUEnergyConsumption, selfRAMEnergyConsumption, aggregatedRAMEnergyConsumption, internRAMEnergyConsumption, externRAMEnergyConsumption, langInternalRAMEnergyConsumption }) {
super();
this._profilerHits = profilerHits;
this._selfCPUTime = selfCPUTime;
this._aggregatedCPUTime = aggregatedCPUTime;
this._internCPUTime = internCPUTime;
this._externCPUTime = externCPUTime;
this._langInternalCPUTime = langInternalCPUTime;
this._selfCPUEnergyConsumption = selfCPUEnergyConsumption;
this._aggregatedCPUEnergyConsumption = aggregatedCPUEnergyConsumption;
this._internCPUEnergyConsumption = internCPUEnergyConsumption;
this._externCPUEnergyConsumption = externCPUEnergyConsumption;
this._langInternalCPUEnergyConsumption = langInternalCPUEnergyConsumption;
this._selfRAMEnergyConsumption = selfRAMEnergyConsumption;
this._aggregatedRAMEnergyConsumption = aggregatedRAMEnergyConsumption;
this._internRAMEnergyConsumption = internRAMEnergyConsumption;
this._externRAMEnergyConsumption = externRAMEnergyConsumption;
this._langInternalRAMEnergyConsumption = langInternalRAMEnergyConsumption;
}
set profilerHits(v) {
this._profilerHits = v;
}
get profilerHits() {
return this._profilerHits || 0;
}
// CPU Time
set selfCPUTime(v) {
this._selfCPUTime = v;
}
get selfCPUTime() {
return this._selfCPUTime || 0;
}
set aggregatedCPUTime(v) {
this._aggregatedCPUTime = v;
}
get aggregatedCPUTime() {
return this._aggregatedCPUTime || 0;
}
set internCPUTime(v) {
this._internCPUTime = v;
}
get internCPUTime() {
return this._internCPUTime || 0;
}
set externCPUTime(v) {
this._externCPUTime = v;
}
get externCPUTime() {
return this._externCPUTime || 0;
}
set langInternalCPUTime(v) {
this._langInternalCPUTime = v;
}
get langInternalCPUTime() {
return this._langInternalCPUTime || 0;
}
// CPU Energy
set selfCPUEnergyConsumption(v) {
this._selfCPUEnergyConsumption = v;
}
get selfCPUEnergyConsumption() {
return this._selfCPUEnergyConsumption || 0;
}
set aggregatedCPUEnergyConsumption(v) {
this._aggregatedCPUEnergyConsumption = v;
}
get aggregatedCPUEnergyConsumption() {
return this._aggregatedCPUEnergyConsumption || 0;
}
set internCPUEnergyConsumption(v) {
this._internCPUEnergyConsumption = v;
}
get internCPUEnergyConsumption() {
return this._internCPUEnergyConsumption || 0;
}
set externCPUEnergyConsumption(v) {
this._externCPUEnergyConsumption = v;
}
get externCPUEnergyConsumption() {
return this._externCPUEnergyConsumption || 0;
}
set langInternalCPUEnergyConsumption(v) {
this._langInternalCPUEnergyConsumption = v;
}
get langInternalCPUEnergyConsumption() {
return this._langInternalCPUEnergyConsumption || 0;
}
// RAM Energy
set selfRAMEnergyConsumption(v) {
this._selfRAMEnergyConsumption = v;
}
get selfRAMEnergyConsumption() {
return this._selfRAMEnergyConsumption || 0;
}
set aggregatedRAMEnergyConsumption(v) {
this._aggregatedRAMEnergyConsumption = v;
}
get aggregatedRAMEnergyConsumption() {
return this._aggregatedRAMEnergyConsumption || 0;
}
set internRAMEnergyConsumption(v) {
this._internRAMEnergyConsumption = v;
}
get internRAMEnergyConsumption() {
return this._internRAMEnergyConsumption || 0;
}
set externRAMEnergyConsumption(v) {
this._externRAMEnergyConsumption = v;
}
get externRAMEnergyConsumption() {
return this._externRAMEnergyConsumption || 0;
}
set langInternalRAMEnergyConsumption(v) {
this._langInternalRAMEnergyConsumption = v;
}
get langInternalRAMEnergyConsumption() {
return this._langInternalRAMEnergyConsumption || 0;
}
validate(path, identifier) {
const valid = (this.profilerHits >= 0 &&
this.selfCPUTime >= 0 &&
this.aggregatedCPUTime >= 0 &&
this.internCPUTime >= 0 &&
this.externCPUTime >= 0 &&
this.langInternalCPUTime >= 0 &&
this.selfCPUEnergyConsumption >= 0 &&
this.aggregatedCPUEnergyConsumption >= 0 &&
this.internCPUEnergyConsumption >= 0 &&
this.externCPUEnergyConsumption >= 0 &&
this.langInternalCPUEnergyConsumption >= 0,
this.selfRAMEnergyConsumption >= 0 &&
this.aggregatedRAMEnergyConsumption >= 0 &&
this.internRAMEnergyConsumption >= 0 &&
this.externRAMEnergyConsumption >= 0 &&
this.langInternalRAMEnergyConsumption >= 0);
if (!valid) {
throw new Error(`SourceNodeMetaData.validate: Assertion error (SourceNode validation) ${path}:${identifier} \n` +
JSON.stringify(this, null, 2) +
'\n');
}
}
// IMPORTANT to change when new measurement type gets added
static sum(...args) {
const result = new SensorValues({});
for (const sensorValues of args) {
result.profilerHits += sensorValues.profilerHits;
result.selfCPUTime = (result.selfCPUTime +
sensorValues.selfCPUTime);
result.aggregatedCPUTime = (result.aggregatedCPUTime +
sensorValues.aggregatedCPUTime);
result.internCPUTime = (result.internCPUTime +
sensorValues.internCPUTime);
result.externCPUTime = (result.externCPUTime +
sensorValues.externCPUTime);
result.langInternalCPUTime = (result.langInternalCPUTime +
sensorValues.langInternalCPUTime);
result.selfCPUEnergyConsumption = (result.selfCPUEnergyConsumption +
sensorValues.selfCPUEnergyConsumption);
result.aggregatedCPUEnergyConsumption =
(result.aggregatedCPUEnergyConsumption +
sensorValues.aggregatedCPUEnergyConsumption);
result.internCPUEnergyConsumption = (result.internCPUEnergyConsumption +
sensorValues.internCPUEnergyConsumption);
result.externCPUEnergyConsumption = (result.externCPUEnergyConsumption +
sensorValues.externCPUEnergyConsumption);
result.langInternalCPUEnergyConsumption =
(result.langInternalCPUEnergyConsumption +
sensorValues.langInternalCPUEnergyConsumption);
result.selfRAMEnergyConsumption = (result.selfRAMEnergyConsumption +
sensorValues.selfRAMEnergyConsumption);
result.aggregatedRAMEnergyConsumption =
(result.aggregatedRAMEnergyConsumption +
sensorValues.aggregatedRAMEnergyConsumption);
result.internRAMEnergyConsumption = (result.internRAMEnergyConsumption +
sensorValues.internRAMEnergyConsumption);
result.externRAMEnergyConsumption = (result.externRAMEnergyConsumption +
sensorValues.externRAMEnergyConsumption);
result.langInternalRAMEnergyConsumption =
(result.langInternalRAMEnergyConsumption +
sensorValues.langInternalRAMEnergyConsumption);
}
return result;
}
// IMPORTANT to change when new measurement type gets added
static max(...args) {
const result = new SensorValues({});
for (const sensorValues of args) {
result.profilerHits = Math.max(result.profilerHits, sensorValues.profilerHits);
result.selfCPUTime = Math.max(result.selfCPUTime, sensorValues.selfCPUTime);
result.aggregatedCPUTime = Math.max(result.aggregatedCPUTime, sensorValues.aggregatedCPUTime);
result.internCPUTime = Math.max(result.internCPUTime, sensorValues.internCPUTime);
result.externCPUTime = Math.max(result.externCPUTime, sensorValues.externCPUTime);
result.langInternalCPUTime = Math.max(result.langInternalCPUTime, sensorValues.langInternalCPUTime);
result.selfCPUEnergyConsumption = Math.max(result.selfCPUEnergyConsumption, sensorValues.selfCPUEnergyConsumption);
result.aggregatedCPUEnergyConsumption = Math.max(result.aggregatedCPUEnergyConsumption, sensorValues.aggregatedCPUEnergyConsumption);
result.internCPUEnergyConsumption = Math.max(result.internCPUEnergyConsumption, sensorValues.internCPUEnergyConsumption);
result.externCPUEnergyConsumption = Math.max(result.externCPUEnergyConsumption, sensorValues.externCPUEnergyConsumption);
result.langInternalCPUEnergyConsumption = Math.max(result.langInternalCPUEnergyConsumption, sensorValues.langInternalCPUEnergyConsumption);
result.selfRAMEnergyConsumption = Math.max(result.selfRAMEnergyConsumption, sensorValues.selfRAMEnergyConsumption);
result.aggregatedRAMEnergyConsumption = Math.max(result.aggregatedRAMEnergyConsumption, sensorValues.aggregatedRAMEnergyConsumption);
result.internRAMEnergyConsumption = Math.max(result.internRAMEnergyConsumption, sensorValues.internRAMEnergyConsumption);
result.externRAMEnergyConsumption = Math.max(result.externRAMEnergyConsumption, sensorValues.externRAMEnergyConsumption);
result.langInternalRAMEnergyConsumption = Math.max(result.langInternalRAMEnergyConsumption, sensorValues.langInternalRAMEnergyConsumption);
}
return result;
}
// IMPORTANT to change when new measurement type gets added
static equals(...args) {
if (args.length === 0) {
return true;
}
const compare = args[0];
for (let i = 1; i < args.length; i++) {
const a = args[i];
if (a.profilerHits !== compare.profilerHits ||
a.selfCPUTime !== compare.selfCPUTime ||
a.aggregatedCPUTime !== compare.aggregatedCPUTime ||
a.internCPUTime !== compare.internCPUTime ||
a.externCPUTime !== compare.externCPUTime ||
a.langInternalCPUTime !== compare.langInternalCPUTime ||
a.selfCPUEnergyConsumption !== compare.selfCPUEnergyConsumption ||
a.aggregatedCPUEnergyConsumption !==
compare.aggregatedCPUEnergyConsumption ||
a.internCPUEnergyConsumption !== compare.internCPUEnergyConsumption ||
a.externCPUEnergyConsumption !== compare.externCPUEnergyConsumption ||
a.langInternalCPUEnergyConsumption !==
compare.langInternalCPUEnergyConsumption ||
a.selfRAMEnergyConsumption !== compare.selfRAMEnergyConsumption ||
a.aggregatedRAMEnergyConsumption !==
compare.aggregatedRAMEnergyConsumption ||
a.internRAMEnergyConsumption !== compare.internRAMEnergyConsumption ||
a.externRAMEnergyConsumption !== compare.externRAMEnergyConsumption ||
a.langInternalRAMEnergyConsumption !==
compare.langInternalRAMEnergyConsumption) {
return false;
}
}
return true;
}
undefinedIfZero(value) {
if (value === 0) {
return undefined;
}
return value;
}
toJSON() {
return {
profilerHits: this.undefinedIfZero(this.profilerHits),
selfCPUTime: this.undefinedIfZero(this.selfCPUTime),
aggregatedCPUTime: this.undefinedIfZero(this.aggregatedCPUTime),
internCPUTime: this.undefinedIfZero(this.internCPUTime),
externCPUTime: this.undefinedIfZero(this.externCPUTime),
langInternalCPUTime: this.undefinedIfZero(this.langInternalCPUTime),
selfCPUEnergyConsumption: this.undefinedIfZero(this.selfCPUEnergyConsumption),
aggregatedCPUEnergyConsumption: this.undefinedIfZero(this.aggregatedCPUEnergyConsumption),
internCPUEnergyConsumption: this.undefinedIfZero(this.internCPUEnergyConsumption),
externCPUEnergyConsumption: this.undefinedIfZero(this.externCPUEnergyConsumption),
langInternalCPUEnergyConsumption: this.undefinedIfZero(this.langInternalCPUEnergyConsumption),
selfRAMEnergyConsumption: this.undefinedIfZero(this.selfRAMEnergyConsumption),
aggregatedRAMEnergyConsumption: this.undefinedIfZero(this.aggregatedRAMEnergyConsumption),
internRAMEnergyConsumption: this.undefinedIfZero(this.internRAMEnergyConsumption),
externRAMEnergyConsumption: this.undefinedIfZero(this.externRAMEnergyConsumption),
langInternalRAMEnergyConsumption: this.undefinedIfZero(this.langInternalRAMEnergyConsumption)
};
}
static fromJSON(json) {
let data;
if (typeof json === 'string') {
data = JSON.parse(json);
}
else {
data = json;
}
const result = new SensorValues({
profilerHits: data.profilerHits || 0,
selfCPUTime: data.selfCPUTime || 0,
aggregatedCPUTime: data.aggregatedCPUTime || 0,
internCPUTime: data.internCPUTime || 0,
externCPUTime: data.externCPUTime || 0,
langInternalCPUTime: data.langInternalCPUTime || 0,
selfCPUEnergyConsumption: data.selfCPUEnergyConsumption || 0,
aggregatedCPUEnergyConsumption: data.aggregatedCPUEnergyConsumption || 0,
internCPUEnergyConsumption: data.internCPUEnergyConsumption || 0,
externCPUEnergyConsumption: data.externCPUEnergyConsumption || 0,
langInternalCPUEnergyConsumption: data.langInternalCPUEnergyConsumption || 0,
selfRAMEnergyConsumption: data.selfRAMEnergyConsumption || 0,
aggregatedRAMEnergyConsumption: data.aggregatedRAMEnergyConsumption || 0,
internRAMEnergyConsumption: data.internRAMEnergyConsumption || 0,
externRAMEnergyConsumption: data.externRAMEnergyConsumption || 0,
langInternalRAMEnergyConsumption: data.langInternalRAMEnergyConsumption || 0
});
return result;
}
toBuffer(tag) {
return BufferHelper_1.BufferHelper.numberMapToBuffer(exports.SENSOR_VALUES_BYTE_SIZE_MAP,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this, 0, tag + '.SensorValues.toBuffer');
}
static consumeFromBuffer(buffer) {
const { instance, remainingBuffer } = BufferHelper_1.BufferHelper.numberMapFromBuffer(exports.SENSOR_VALUES_BYTE_SIZE_MAP, buffer);
return {
instance: new SensorValues(instance),
remainingBuffer
};
}
// IMPORTANT to change when new measurement type gets added
addToSelf(other, sign = 1) {
this.selfCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.selfCPUTime, other.selfCPUTime, sign);
this.selfCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.selfCPUEnergyConsumption, other.selfCPUEnergyConsumption, sign);
this.selfRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.selfRAMEnergyConsumption, other.selfRAMEnergyConsumption, sign);
return this;
}
// IMPORTANT to change when new measurement type gets added
addToAggregated(other, sign = 1) {
this.aggregatedCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.aggregatedCPUTime, other.aggregatedCPUTime, sign);
this.aggregatedCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.aggregatedCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign);
this.aggregatedRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.aggregatedRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign);
return this;
}
// IMPORTANT to change when new measurement type gets added
addToIntern(other, sign = 1) {
this.internCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.internCPUTime, other.aggregatedCPUTime, sign);
this.internCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.internCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign);
this.internRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.internRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign);
return this;
}
// IMPORTANT to change when new measurement type gets added
addToExtern(other, sign = 1) {
this.externCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.externCPUTime, other.aggregatedCPUTime, sign);
this.externCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.externCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign);
this.externRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.externRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign);
return this;
}
// IMPORTANT to change when new measurement type gets added
addSelfToExtern(other, sign = 1) {
this.externCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.externCPUTime, other.selfCPUTime, sign);
this.externCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.externCPUEnergyConsumption, other.selfCPUEnergyConsumption, sign);
this.externRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.externRAMEnergyConsumption, other.selfRAMEnergyConsumption, sign);
return this;
}
// IMPORTANT to change when new measurement type gets added
addToLangInternal(other, sign = 1) {
this.langInternalCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.langInternalCPUTime, other.aggregatedCPUTime, sign);
this.langInternalCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.langInternalCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign);
this.langInternalRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.langInternalRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign);
return this;
}
// IMPORTANT to change when new measurement type gets added
addSelfToLangInternal(other, sign = 1) {
this.langInternalCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.langInternalCPUTime, other.selfCPUTime, sign);
this.langInternalCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.langInternalCPUEnergyConsumption, other.selfCPUEnergyConsumption, sign);
this.langInternalRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.langInternalRAMEnergyConsumption, other.selfRAMEnergyConsumption, sign);
return this;
}
add({ internSensorValues, externSensorValues, langInternalSensorValues }) {
const result = SensorValues.fromJSON(this.toJSON());
if (internSensorValues) {
result.addToAggregated(internSensorValues);
result.addToIntern(internSensorValues);
}
if (externSensorValues) {
result.addToAggregated(externSensorValues);
result.addToExtern(externSensorValues);
}
if (langInternalSensorValues) {
result.addToAggregated(langInternalSensorValues);
result.addToLangInternal(langInternalSensorValues);
}
return result;
}
clone() {
return new SensorValues(this.toJSON());
}
// clones the object but removes all reference values to other objects
// the aggregated values equal the self values
cloneAsIsolated() {
// IMPORTANT to change when new measurement type gets added
return new SensorValues({
profilerHits: this.profilerHits,
selfCPUTime: this.selfCPUTime,
aggregatedCPUTime: this.selfCPUTime,
selfCPUEnergyConsumption: this.selfCPUEnergyConsumption,
aggregatedCPUEnergyConsumption: this.selfCPUEnergyConsumption,
selfRAMEnergyConsumption: this.selfRAMEnergyConsumption,
aggregatedRAMEnergyConsumption: this.selfRAMEnergyConsumption
});
}
// clones the object but only the aggregated values
cloneAsAggregated() {
const result = new SensorValues({});
result.addToAggregated(this);
return result;
}
}
exports.SensorValues = SensorValues;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2Vuc29yVmFsdWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21vZGVsL1NlbnNvclZhbHVlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBdUM7QUFFdkMseURBQXFEO0FBQ3JELFFBQVE7QUFDUixvQ0FTaUI7QUFDakIscURBQWlEO0FBRXBDLFFBQUEsMkJBQTJCLEdBQTZCO0lBQ3BFLFlBQVksRUFBRSw0QkFBb0IsQ0FBQyxJQUFJO0lBRXZDLFdBQVcsRUFBRSw0QkFBb0IsQ0FBQyxJQUFJO0lBQ3RDLGlCQUFpQixFQUFFLDRCQUFvQixDQUFDLElBQUk7SUFDNUMsYUFBYSxFQUFFLDRCQUFvQixDQUFDLElBQUk7SUFDeEMsYUFBYSxFQUFFLDRCQUFvQixDQUFDLElBQUk7SUFDeEMsbUJBQW1CLEVBQUUsNEJBQW9CLENBQUMsSUFBSTtJQUU5Qyx3QkFBd0IsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0lBQ3JELDhCQUE4QixFQUFFLDRCQUFvQixDQUFDLE1BQU07SUFDM0QsMEJBQTBCLEVBQUUsNEJBQW9CLENBQUMsTUFBTTtJQUN2RCwwQkFBMEIsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0lBQ3ZELGdDQUFnQyxFQUFFLDRCQUFvQixDQUFDLE1BQU07SUFFN0Qsd0JBQXdCLEVBQUUsNEJBQW9CLENBQUMsTUFBTTtJQUNyRCw4QkFBOEIsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0lBQzNELDBCQUEwQixFQUFFLDRCQUFvQixDQUFDLE1BQU07SUFDdkQsMEJBQTBCLEVBQUUsNEJBQW9CLENBQUMsTUFBTTtJQUN2RCxnQ0FBZ0MsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0NBQzdELENBQUE7QUFFWSxRQUFBLDZCQUE2QixHQUE0QjtJQUNyRSxtQkFBbUI7SUFDbkIsZ0NBQWdDO0lBQ2hDLGdDQUFnQztDQUNoQyxDQUFBO0FBRVksUUFBQSx5QkFBeUIsR0FBNEI7SUFDakUsZUFBZTtJQUNmLDRCQUE0QjtJQUM1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