@synerty/vortexjs
Version:
Custom observable data serialisation and routing based on Angular 2+
251 lines • 31.8 kB
JavaScript
import { SerialiseUtil } from "./exports";
import { deepCopy } from "./UtilMisc";
import "./UtilString";
import { PayloadEnvelope } from "./PayloadEnvelope";
import { Payload } from "./Payload";
const JSONABLE_TYPES = {};
export function addJsonableType(jsonableType) {
return function (_Class) {
JSONABLE_TYPES[jsonableType] = _Class;
return _Class;
};
}
/**
* ############################################################################### #
* JSON Serialisation functions
* ###############################################################################
*/
export class Jsonable extends SerialiseUtil {
_tupleType;
_rawJonableFields = null;
static JSON_CLASS_TYPE = "_ct";
// private static readonly JSON_CLASS = "_c";
static JSON_TUPLE_TYPE = "_c";
static JSON_FIELD_TYPE = "_ft";
static JSON_FIELD_DATA = "_fd";
constructor() {
super();
/*
* Jsonable This class gives simple objects suport for serialising to/from json.
* It handles Number, String, Array and Date. It doesn't handle more complex
* structures (hence why Payloads have their own functions to do this)
*/
let self = this;
self.__rst = SerialiseUtil.T_GENERIC_CLASS;
}
_isRawJsonableField(name) {
if (name == null || name.length == 0) {
return false;
}
if (this._rawJonableFields == null) {
return false;
}
return this._rawJonableFields.indexOf(name) != -1;
}
_fieldNames() {
let self = this;
let keys = [];
for (let k in self) {
if (!k.startsWith("_") && self.hasOwnProperty(k)) {
keys.push(k);
}
}
return keys;
}
equals(other) {
let self = this;
return self.rapuiEquals(self, other, self._fieldNames(), other._fieldNames());
}
toRestfulJsonDict() {
return this._tupleToJsonDict(true);
}
toJsonDict() {
return this._tupleToJsonDict(false);
}
_tupleToJsonDict(useShortNames) {
let self = this;
let jsonDict = {};
if (!useShortNames) {
jsonDict[Jsonable.JSON_CLASS_TYPE] = self.__rst;
}
if (!useShortNames && self._tupleType != null) {
jsonDict[Jsonable.JSON_TUPLE_TYPE] = self._tupleType;
}
/* This is in the PY version
else
jsonDict[JSON_CLASS] = className(self)
*/
let fieldNames = self._fieldNames();
// fieldNames.sort(); // Why?
// Create the <items> base element
for (let i = 0; i < fieldNames.length; ++i) {
let name = fieldNames[i];
self.toJsonField(self[name], jsonDict, name, useShortNames);
}
return jsonDict;
}
fromJsonDict(jsonDict) {
/*
* From Json Returns and instance of this object populated with data from the
* json dict
*
*/
for (const name of Object.keys(jsonDict)) {
if (name.startsWith("_")) {
continue;
}
if (this._isRawJsonableField(name)) {
this[name] = jsonDict[name];
}
else {
this[name] = this.fromJsonField(jsonDict[name]);
}
}
// This is only required for unit tests new Tuple().fromJsonDict(..)
if (jsonDict[Jsonable.JSON_CLASS_TYPE] == SerialiseUtil.T_RAPUI_TUPLE) {
this._tupleType = jsonDict[Jsonable.JSON_TUPLE_TYPE];
}
return this;
}
toJsonField(value, jsonDict = null, name = null, useShortNames = false) {
let self = this;
let convertedValue = null;
let valueType = value == null ? SerialiseUtil.V_NULL : self.toRapuiType(value);
if (this._isRawJsonableField(name)) {
convertedValue = deepCopy(value);
}
else if (valueType === SerialiseUtil.T_RAPUI_TUPLE ||
valueType === SerialiseUtil.T_RAPUI_PAYLOAD ||
valueType === SerialiseUtil.T_RAPUI_PAYLOAD_ENVELOPE) {
if (useShortNames) {
convertedValue = value.toRestfulJsonDict();
}
else {
convertedValue = value.toJsonDict();
}
}
else if (valueType === SerialiseUtil.T_DICT) {
// Treat these like dicts
convertedValue = {};
for (const keyName of Object.keys(value)) {
if (useShortNames) {
self.toJsonField(value[keyName], convertedValue, keyName, true);
}
else {
self.toJsonField(value[keyName], convertedValue, keyName);
}
}
}
else if (valueType === SerialiseUtil.T_LIST) {
convertedValue = [];
// List
for (let i = 0; i < value.length; ++i) {
let element;
if (useShortNames) {
element = self.toJsonField(value[i], null, null, true);
}
else {
element = self.toJsonField(value[i]);
}
convertedValue.push(element);
}
}
else if (valueType === SerialiseUtil.T_FLOAT ||
valueType === SerialiseUtil.T_INT ||
valueType === SerialiseUtil.T_BOOL ||
valueType === SerialiseUtil.T_STR) {
convertedValue = value;
}
else if (valueType === SerialiseUtil.V_NULL) {
convertedValue = null;
}
else {
convertedValue = self.toStr(value);
}
// Non standard values need a dict to store their value type attributes
// Create a sub dict that contains the value and type
let jsonStandardTypes = [
SerialiseUtil.T_FLOAT,
SerialiseUtil.T_STR,
SerialiseUtil.T_INT,
SerialiseUtil.V_NULL,
SerialiseUtil.T_BOOL,
SerialiseUtil.T_LIST,
SerialiseUtil.T_DICT,
];
if (jsonStandardTypes.indexOf(valueType) === -1 &&
!(value instanceof Jsonable)) {
let typedData = {};
typedData[Jsonable.JSON_FIELD_TYPE] = valueType;
typedData[Jsonable.JSON_FIELD_DATA] = convertedValue;
convertedValue = typedData;
}
/* Now assign the value and it's value type if applicable */
if (name != null && jsonDict != null) {
jsonDict[name] = convertedValue;
}
return convertedValue;
}
// ----------------------------------------------------------------------------
fromJsonField(value, valueType = null) {
let self = this;
if (valueType === SerialiseUtil.V_NULL || value == null) {
return null;
}
if (valueType === SerialiseUtil.T_INT) {
return value;
}
if (value[Jsonable.JSON_CLASS_TYPE] != null) {
valueType = value[Jsonable.JSON_CLASS_TYPE];
}
// JSON handles these types natively,
// if there is no type then these are the right types
if (valueType == null) {
valueType = self.toRapuiType(value);
if ([
SerialiseUtil.T_BOOL,
SerialiseUtil.T_FLOAT,
SerialiseUtil.T_INT,
SerialiseUtil.T_STR,
].indexOf(valueType) !== -1) {
return value;
}
}
if (value[Jsonable.JSON_FIELD_TYPE] != null) {
return self.fromJsonField(value[Jsonable.JSON_FIELD_DATA], value[Jsonable.JSON_FIELD_TYPE]);
}
// Tuple
if (valueType === SerialiseUtil.T_RAPUI_TUPLE) {
let Tuple = JSONABLE_TYPES[SerialiseUtil.T_RAPUI_TUPLE];
let tupleType = value[Jsonable.JSON_TUPLE_TYPE];
let newTuple = Tuple.create(tupleType);
return newTuple.fromJsonDict(value);
}
// Handle the case of payloads within payloads
if (valueType === SerialiseUtil.T_RAPUI_PAYLOAD) {
return new Payload().fromJsonDict(value);
}
// Payload Endpoint
if (valueType === SerialiseUtil.T_RAPUI_PAYLOAD_ENVELOPE) {
return new PayloadEnvelope().fromJsonDict(value);
}
/* SKIP T_GENERIC_CLASS */
if (valueType === SerialiseUtil.T_DICT) {
let restoredDict = {};
for (const subName of Object.keys(value)) {
restoredDict[subName] = self.fromJsonField(value[subName]);
}
return restoredDict;
}
if (valueType === SerialiseUtil.T_LIST) {
let restoredList = [];
for (let i = 0; i < value.length; ++i) {
restoredList.push(self.fromJsonField(value[i]));
}
return restoredList;
}
// Handle single value
return self.fromStr(value, valueType);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSnNvbmFibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdm9ydGV4L0pzb25hYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDMUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN0QyxPQUFPLGNBQWMsQ0FBQztBQUN0QixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVwQyxNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUM7QUFFMUIsTUFBTSxVQUFVLGVBQWUsQ0FBQyxZQUFvQjtJQUNoRCxPQUFPLFVBQVUsTUFBVztRQUN4QixjQUFjLENBQUMsWUFBWSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ3RDLE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUMsQ0FBQztBQUNOLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLFFBQVMsU0FBUSxhQUFhO0lBQ2hDLFVBQVUsQ0FBUztJQUNoQixpQkFBaUIsR0FBRyxJQUFJLENBQUM7SUFFNUIsTUFBTSxDQUFVLGVBQWUsR0FBRyxLQUFLLENBQUM7SUFDL0MsNkNBQTZDO0lBQ3JDLE1BQU0sQ0FBVSxlQUFlLEdBQUcsSUFBSSxDQUFDO0lBQ3ZDLE1BQU0sQ0FBVSxlQUFlLEdBQUcsS0FBSyxDQUFDO0lBQ3hDLE1BQU0sQ0FBVSxlQUFlLEdBQUcsS0FBSyxDQUFDO0lBRWhEO1FBQ0ksS0FBSyxFQUFFLENBQUM7UUFDUjs7OztXQUlHO1FBQ0gsSUFBSSxJQUFJLEdBQWEsSUFBSSxDQUFDO1FBRTFCLElBQUksQ0FBQyxLQUFLLEdBQUcsYUFBYSxDQUFDLGVBQWUsQ0FBQztJQUMvQyxDQUFDO0lBRU8sbUJBQW1CLENBQUMsSUFBWTtRQUNwQyxJQUFJLElBQUksSUFBSSxJQUFJLElB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QVksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUM1QztRQUVELG1CQUFtQjtRQUNuQixJQUFJLFNBQVMsS0FBSyxhQUFhLENBQUMsd0JBQXdCLEVBQUU7WUFDdEQsT0FBTyxJQUFJLGVBQWUsRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNwRDtRQUVELDBCQUEwQjtRQUMxQixJQUFJLFNBQVMsS0FBSyxhQUFhLENBQUMsTUFBTSxFQUFFO1lBQ3BDLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQztZQUN0QixLQUFLLE1BQU0sT0FBTyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQ3RDLFlBQVksQ0FBQyxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2FBQzlEO1lBRUQsT0FBTyxZQUFZLENBQUM7U0FDdkI7UUFFRCxJQUFJLFNBQVMsS0FBSyxhQUFhLENBQUMsTUFBTSxFQUFFO1lBQ3BDLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQztZQUN0QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtnQkFDbkMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDbkQ7WUFFRCxPQUFPLFlBQVksQ0FBQztTQUN2QjtRQUVELHNCQUFzQjtRQUN0QixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTZXJpYWxpc2VVdGlsIH0gZnJvbSBcIi4vZXhwb3J0c1wiO1xuaW1wb3J0IHsgZGVlcENvcHkgfSBmcm9tIFwiLi9VdGlsTWlzY1wiO1xuaW1wb3J0IFwiLi9VdGlsU3RyaW5nXCI7XG5pbXBvcnQgeyBQYXlsb2FkRW52ZWxvcGUgfSBmcm9tIFwiLi9QYXlsb2FkRW52ZWxvcGVcIjtcbmltcG9ydCB7IFBheWxvYWQgfSBmcm9tIFwiLi9QYXlsb2FkXCI7XG5cbmNvbnN0IEpTT05BQkxFX1RZUEVTID0ge307XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRKc29uYWJsZVR5cGUoanNvbmFibGVUeXBlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKF9DbGFzczogYW55KSB7XG4gICAgICAgIEpTT05BQkxFX1RZUEVTW2pzb25hYmxlVHlwZV0gPSBfQ2xhc3M7XG4gICAgICAgIHJldHVybiBfQ2xhc3M7XG4gICAgfTtcbn1cblxuLyoqXG4gKiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICNcbiAqIEpTT04gU2VyaWFsaXNhdGlvbiBmdW5jdGlvbnNcbiAqICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcbiAqL1xuZXhwb3J0IGNsYXNzIEpzb25hYmxlIGV4dGVuZHMgU2VyaWFsaXNlVXRpbCB7XG4gICAgcHVibGljIF90dXBsZVR5cGU6IHN0cmluZztcbiAgICBwcm90ZWN0ZWQgX3Jhd0pvbmFibGVGaWVsZHMgPSBudWxsO1xuXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBKU09OX0NMQVNTX1RZUEUgPSBcIl9jdFwiO1xuICAgIC8vIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IEpTT05fQ0xBU1MgPSBcIl9jXCI7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgSlNPTl9UVVBMRV9UWVBFID0gXCJfY1wiO1xuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IEpTT05fRklFTERfVFlQRSA9IFwiX2Z0XCI7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgSlNPTl9GSUVMRF9EQVRBID0gXCJfZmRcIjtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICAvKlxuICAgICAgICAgKiBKc29uYWJsZSBUaGlzIGNsYXNzIGdpdmVzIHNpbXBsZSBvYmplY3RzIHN1cG9ydCBmb3Igc2VyaWFsaXNpbmcgdG8vZnJvbSBqc29uLlxuICAgICAgICAgKiBJdCBoYW5kbGVzIE51bWJlciwgU3RyaW5nLCBBcnJheSBhbmQgRGF0ZS4gSXQgZG9lc24ndCBoYW5kbGUgbW9yZSBjb21wbGV4XG4gICAgICAgICAqIHN0cnVjdHVyZXMgKGhlbmNlIHdoeSBQYXlsb2FkcyBoYXZlIHRoZWlyIG93biBmdW5jdGlvbnMgdG8gZG8gdGhpcylcbiAgICAgICAgICovXG4gICAgICAgIGxldCBzZWxmOiBKc29uYWJsZSA9IHRoaXM7XG5cbiAgICAgICAgc2VsZi5fX3JzdCA9IFNlcmlhbGlzZVV0aWwuVF9HRU5FUklDX0NMQVNTO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2lzUmF3SnNvbmFibGVGaWVsZChuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCB8fCBuYW1lLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3Jhd0pvbmFibGVGaWVsZHMgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yYXdKb25hYmxlRmllbGRzLmluZGV4T2YobmFtZSkgIT0gLTE7XG4gICAgfVxuXG4gICAgX2ZpZWxkTmFtZXMoKSB7XG4gICAgICAgIGxldCBzZWxmID0gdGhpcztcblxuICAgICAgICBsZXQga2V5cyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBrIGluIHNlbGYpIHtcbiAgICAgICAgICAgIGlmICghay5zdGFydHNXaXRoKFwiX1wiKSAmJiBzZWxmLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGspO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrZXlzO1xuICAgIH1cblxuICAgIGVxdWFscyhvdGhlcikge1xuICAgICAgICBsZXQgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIHNlbGYucmFwdWlFcXVhbHMoXG4gICAgICAgICAgICBzZWxmLFxuICAgICAgICAgICAgb3RoZXIsXG4gICAgICAgICAgICBzZWxmLl9maWVsZE5hbWVzKCksXG4gICAgICAgICAgICBvdGhlci5fZmllbGROYW1lcygpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHRvUmVzdGZ1bEpzb25EaWN0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHVwbGVUb0pzb25EaWN0KHRydWUpO1xuICAgIH1cblxuICAgIHRvSnNvbkRpY3QoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90dXBsZVRvSnNvbkRpY3QoZmFsc2UpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3R1cGxlVG9Kc29uRGljdCh1c2VTaG9ydE5hbWVzOiBib29sZWFuKSB7XG4gICAgICAgIGxldCBzZWxmID0gdGhpcztcblxuICAgICAgICBsZXQganNvbkRpY3QgPSB7fTtcbiAgICAgICAgaWYgKCF1c2VTaG9ydE5hbWVzKSB7XG4gICAgICAgICAgICBqc29uRGljdFtKc29uYWJsZS5KU09OX0NMQVNTX1RZUEVdID0gc2VsZi5fX3JzdDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdXNlU2hvcnROYW1lcyAmJiBzZWxmLl90dXBsZVR5cGUgIT0gbnVsbCkge1xuICAgICAgICAgICAganNvbkRpY3RbSnNvbmFibGUuSlNPTl9UVVBMRV9UWVBFXSA9IHNlbGYuX3R1cGxlVHlwZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qIFRoaXMgaXMgaW4gdGhlIFBZIHZlcnNpb25cbiAgICAgICAgIGVsc2VcbiAgICAgICAgIGpzb25EaWN0W0pTT05fQ0xBU1NdID0gY2xhc3NOYW1lKHNlbGYpXG4gICAgICAgICAqL1xuXG4gICAgICAgIGxldCBmaWVsZE5hbWVzID0gc2VsZi5fZmllbGROYW1lcygpO1xuICAgICAgICAvLyBmaWVsZE5hbWVzLnNvcnQoKTsgLy8gV2h5P1xuXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgPGl0ZW1zPiBiYXNlIGVsZW1lbnRcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWVsZE5hbWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBsZXQgbmFtZSA9IGZpZWxkTmFtZXNbaV07XG4gICAgICAgICAgICBzZWxmLnRvSnNvbkZpZWxkKHNlbGZbbmFtZV0sIGpzb25EaWN0LCBuYW1lLCB1c2VTaG9ydE5hbWVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBqc29uRGljdDtcbiAgICB9XG5cbiAgICBmcm9tSnNvbkRpY3QoanNvbkRpY3Q6IHt9KTogYW55IHtcbiAgICAgICAgLypcbiAgICAgICAgICogRnJvbSBKc29uIFJldHVybnMgYW5kIGluc3RhbmNlIG9mIHRoaXMgb2JqZWN0IHBvcHVsYXRlZCB3aXRoIGRhdGEgZnJvbSB0aGVcbiAgICAgICAgICoganNvbiBkaWN0XG4gICAgICAgICAqXG4gICAgICAgICAqL1xuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgT2JqZWN0LmtleXMoanNvbkRpY3QpKSB7XG4gICAgICAgICAgICBpZiAobmFtZS5zdGFydHNXaXRoKFwiX1wiKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5faXNSYXdKc29uYWJsZUZpZWxkKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpc1tuYW1lXSA9IGpzb25EaWN0W25hbWVdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzW25hbWVdID0gdGhpcy5mcm9tSnNvbkZpZWxkKGpzb25EaWN0W25hbWVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoaXMgaXMgb25seSByZXF1aXJlZCBmb3IgdW5pdCB0ZXN0cyBuZXcgVHVwbGUoKS5mcm9tSnNvbkRpY3QoLi4pXG4gICAgICAgIGlmIChqc29uRGljdFtKc29uYWJsZS5KU09OX0NMQVNTX1RZUEVdID09IFNlcmlhbGlzZVV0aWwuVF9SQVBVSV9UVVBMRSkge1xuICAgICAgICAgICAgdGhpcy5fdHVwbGVUeXBlID0ganNvbkRpY3RbSnNvbmFibGUuSlNPTl9UVVBMRV9UWVBFXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHRvSnNvbkZpZWxkKFxuICAgICAgICB2YWx1ZTogYW55LFxuICAgICAgICBqc29uRGljdDoge30gfCBudWxsID0gbnVsbCxcbiAgICAgICAgbmFtZTogc3RyaW5nIHwgbnVsbCA9IG51bGwsXG4gICAgICAgIHVzZVNob3J0TmFtZXM6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICApOiBhbnkge1xuICAgICAgICBsZXQgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgbGV0IGNvbnZlcnRlZFZhbHVlID0gbnVsbDtcbiAgICAgICAgbGV0IHZhbHVlVHlwZSA9XG4gICAgICAgICAgICB2YWx1ZSA9PSBudWxsID8gU2VyaWFsaXNlVXRpbC5WX05VTEwgOiBzZWxmLnRvUmFwdWlUeXBlKHZhbHVlKTtcblxuICAgICAgICBpZiAodGhpcy5faXNSYXdKc29uYWJsZUZpZWxkKG5hbWUpKSB7XG4gICAgICAgICAgICBjb252ZXJ0ZWRWYWx1ZSA9IGRlZXBDb3B5KHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgIHZhbHVlVHlwZSA9PT0gU2VyaWFsaXNlVXRpbC5UX1JBUFVJX1RVUExFIHx8XG4gICAgICAgICAgICB2YWx1ZVR5cGUgPT09IFNlcmlhbGlzZVV0aWwuVF9SQVBVSV9QQVlMT0FEIHx8XG4gICAgICAgICAgICB2YWx1ZVR5cGUgPT09IFNlcmlhbGlzZVV0aWwuVF9SQVBVSV9QQVlMT0FEX0VOVkVMT1BFXG4gICAgICAgICkge1xuICAgICAgICAgICAgaWYgKHVzZVNob3J0TmFtZXMpIHtcbiAgICAgICAgICAgICAgICBjb252ZXJ0ZWRWYWx1ZSA9IHZhbHVlLnRvUmVzdGZ1bEpzb25EaWN0KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnZlcnRlZFZhbHVlID0gdmFsdWUudG9Kc29uRGljdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gU2VyaWFsaXNlVXRpbC5UX0RJQ1QpIHtcbiAgICAgICAgICAgIC8vIFRyZWF0IHRoZXNlIGxpa2UgZGljdHNcbiAgICAgICAgICAgIGNvbnZlcnRlZFZhbHVlID0ge307XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleU5hbWUgb2YgT2JqZWN0LmtleXModmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHVzZVNob3J0TmFtZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi50b0pzb25GaWVsZChcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlW2tleU5hbWVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydGVkVmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXlOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLnRvSnNvbkZpZWxkKHZhbHVlW2tleU5hbWVdLCBjb252ZXJ0ZWRWYWx1ZSwga2V5TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gU2VyaWFsaXNlVXRpbC5UX0xJU1QpIHtcbiAgICAgICAgICAgIGNvbnZlcnRlZFZhbHVlID0gW107XG4gICAgICAgICAgICAvLyBMaXN0XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgaWYgKHVzZVNob3J0TmFtZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IHNlbGYudG9Kc29uRmllbGQodmFsdWVbaV0sIG51bGwsIG51bGwsIHRydWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBzZWxmLnRvSnNvbkZpZWxkKHZhbHVlW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29udmVydGVkVmFsdWUucHVzaChlbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgIHZhbHVlVHlwZSA9PT0gU2VyaWFsaXNlVXRpbC5UX0ZMT0FUIHx8XG4gICAgICAgICAgICB2YWx1ZVR5cGUgPT09IFNlcmlhbGlzZVV0aWwuVF9JTlQgfHxcbiAgICAgICAgICAgIHZhbHVlVHlwZSA9PT0gU2VyaWFsaXNlVXRpbC5UX0JPT0wgfHxcbiAgICAgICAgICAgIHZhbHVlVHlwZSA9PT0gU2VyaWFsaXNlVXRpbC5UX1NUUlxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnZlcnRlZFZhbHVlID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWVUeXBlID09PSBTZXJpYWxpc2VVdGlsLlZfTlVMTCkge1xuICAgICAgICAgICAgY29udmVydGVkVmFsdWUgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udmVydGVkVmFsdWUgPSBzZWxmLnRvU3RyKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE5vbiBzdGFuZGFyZCB2YWx1ZXMgbmVlZCBhIGRpY3QgdG8gc3RvcmUgdGhlaXIgdmFsdWUgdHlwZSBhdHRyaWJ1dGVzXG4gICAgICAgIC8vIENyZWF0ZSBhIHN1YiBkaWN0IHRoYXQgY29udGFpbnMgdGhlIHZhbHVlIGFuZCB0eXBlXG4gICAgICAgIGxldCBqc29uU3RhbmRhcmRUeXBlcyA9IFtcbiAgICAgICAgICAgIFNlcmlhbGlzZVV0aWwuVF9GTE9BVCxcbiAgICAgICAgICAgIFNlcmlhbGlzZVV0aWwuVF9TVFIsXG4gICAgICAgICAgICBTZXJpYWxpc2VVdGlsLlRfSU5ULFxuICAgICAgICAgICAgU2VyaWFsaXNlVXRpbC5WX05VTEwsXG4gICAgICAgICAgICBTZXJpYWxpc2VVdGlsLlRfQk9PTCxcbiAgICAgICAgICAgIFNlcmlhbGlzZVV0aWwuVF9MSVNULFxuICAgICAgICAgICAgU2VyaWFsaXNlVXRpbC5UX0RJQ1QsXG4gICAgICAgIF07XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAganNvblN0YW5kYXJkVHlwZXMuaW5kZXhPZih2YWx1ZVR5cGUpID09PSAtMSAmJlxuICAgICAgICAgICAgISh2YWx1ZSBpbnN0YW5jZW9mIEpzb25hYmxlKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGxldCB0eXBlZERhdGEgPSB7fTtcbiAgICAgICAgICAgIHR5cGVkRGF0YVtKc29uYWJsZS5KU09OX0ZJRUxEX1RZUEVdID0gdmFsdWVUeXBlO1xuICAgICAgICAgICAgdHlwZWREYXRhW0pzb25hYmxlLkpTT05fRklFTERfREFUQV0gPSBjb252ZXJ0ZWRWYWx1ZTtcbiAgICAgICAgICAgIGNvbnZlcnRlZFZhbHVlID0gdHlwZWREYXRhO1xuICAgICAgICB9XG5cbiAgICAgICAgLyogTm93IGFzc2lnbiB0aGUgdmFsdWUgYW5kIGl0J3MgdmFsdWUgdHlwZSBpZiBhcHBsaWNhYmxlICovXG4gICAgICAgIGlmIChuYW1lICE9IG51bGwgJiYganNvbkRpY3QgIT0gbnVsbCkge1xuICAgICAgICAgICAganNvbkRpY3RbbmFtZV0gPSBjb252ZXJ0ZWRWYWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb252ZXJ0ZWRWYWx1ZTtcbiAgICB9XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZnJvbUpzb25GaWVsZCh2YWx1ZTogYW55LCB2YWx1ZVR5cGU6IHN0cmluZyA9IG51bGwpIHtcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgICAgICBpZiAodmFsdWVUeXBlID09PSBTZXJpYWxpc2VVdGlsLlZfTlVMTCB8fCB2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZVR5cGUgPT09IFNlcmlhbGlzZVV0aWwuVF9JTlQpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZVtKc29uYWJsZS5KU09OX0NMQVNTX1RZUEVdICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhbHVlVHlwZSA9IHZhbHVlW0pzb25hYmxlLkpTT05fQ0xBU1NfVFlQRV07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBKU09OIGhhbmRsZXMgdGhlc2UgdHlwZXMgbmF0aXZlbHksXG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHR5cGUgdGhlbiB0aGVzZSBhcmUgdGhlIHJpZ2h0IHR5cGVzXG4gICAgICAgIGlmICh2YWx1ZVR5cGUgPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFsdWVUeXBlID0gc2VsZi50b1JhcHVpVHlwZSh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICBTZXJpYWxpc2VVdGlsLlRfQk9PTCxcbiAgICAgICAgICAgICAgICAgICAgU2VyaWFsaXNlVXRpbC5UX0ZMT0FULFxuICAgICAgICAgICAgICAgICAgICBTZXJpYWxpc2VVdGlsLlRfSU5ULFxuICAgICAgICAgICAgICAgICAgICBTZXJpYWxpc2VVdGlsLlRfU1RSLFxuICAgICAgICAgICAgICAgIF0uaW5kZXhPZih2YWx1ZVR5cGUpICE9PSAtMVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlW0pzb25hYmxlLkpTT05fRklFTERfVFlQRV0gIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuZnJvbUpzb25GaWVsZChcbiAgICAgICAgICAgICAgICB2YWx1ZVtKc29uYWJsZS5KU09OX0ZJRUxEX0RBVEFdLFxuICAgICAgICAgICAgICAgIHZhbHVlW0pzb25hYmxlLkpTT05fRklFTERfVFlQRV0sXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVHVwbGVcbiAgICAgICAgaWYgKHZhbHVlVHlwZSA9PT0gU2VyaWFsaXNlVXRpbC5UX1JBUFVJX1RVUExFKSB7XG4gICAgICAgICAgICBsZXQgVHVwbGUgPSBKU09OQUJMRV9UWVBFU1tTZXJpYWxpc2VVdGlsLlRfUkFQVUlfVFVQTEVdO1xuICAgICAgICAgICAgbGV0IHR1cGxlVHlwZSA9IHZhbHVlW0pzb25hYmxlLkpTT05fVFVQTEVfVFlQRV07XG4gICAgICAgICAgICBsZXQgbmV3VHVwbGUgPSBUdXBsZS5jcmVhdGUodHVwbGVUeXBlKTtcblxuICAgICAgICAgICAgcmV0dXJuIG5ld1R1cGxlLmZyb21Kc29uRGljdCh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgdGhlIGNhc2Ugb2YgcGF5bG9hZHMgd2l0aGluIHBheWxvYWRzXG4gICAgICAgIGlmICh2YWx1ZVR5cGUgPT09IFNlcmlhbGlzZVV0aWwuVF9SQVBVSV9QQVlMT0FEKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFBheWxvYWQoKS5mcm9tSnNvbkRpY3QodmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUGF5bG9hZCBFbmRwb2ludFxuICAgICAgICBpZiAodmFsdWVUeXBlID09PSBTZXJpYWxpc2VVdGlsLlRfUkFQVUlfUEFZTE9BRF9FTlZFTE9QRSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQYXlsb2FkRW52ZWxvcGUoKS5mcm9tSnNvbkRpY3QodmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyogU0tJUCBUX0dFTkVSSUNfQ0xBU1MgKi9cbiAgICAgICAgaWYgKHZhbHVlVHlwZSA9PT0gU2VyaWFsaXNlVXRpbC5UX0RJQ1QpIHtcbiAgICAgICAgICAgIGxldCByZXN0b3JlZERpY3QgPSB7fTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qgc3ViTmFtZSBvZiBPYmplY3Qua2V5cyh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICByZXN0b3JlZERpY3Rbc3ViTmFtZV0gPSBzZWxmLmZyb21Kc29uRmllbGQodmFsdWVbc3ViTmFtZV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzdG9yZWREaWN0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlVHlwZSA9PT0gU2VyaWFsaXNlVXRpbC5UX0xJU1QpIHtcbiAgICAgICAgICAgIGxldCByZXN0b3JlZExpc3QgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICByZXN0b3JlZExpc3QucHVzaChzZWxmLmZyb21Kc29uRmllbGQodmFsdWVbaV0pKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJlc3RvcmVkTGlzdDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEhhbmRsZSBzaW5nbGUgdmFsdWVcbiAgICAgICAgcmV0dXJuIHNlbGYuZnJvbVN0cih2YWx1ZSwgdmFsdWVUeXBlKTtcbiAgICB9XG59XG4iXX0=