@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
409 lines • 41.1 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');
}
}
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;
}
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;
}
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() {
return BufferHelper_1.BufferHelper.numberMapToBuffer(exports.SENSOR_VALUES_BYTE_SIZE_MAP, this // eslint-disable-line @typescript-eslint/no-explicit-any
);
}
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);
}
// 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);
}
// 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);
}
// 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);
}
// 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);
}
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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