UNPKG

@synerty/vortexjs

Version:

Custom observable data serialisation and routing based on Angular 2+

251 lines 31.8 kB
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=