UNPKG

gy-foo

Version:

A library that contains all models for the gy-web-project.

522 lines 59.2 kB
import { __read, __values } from "tslib"; import { Entity } from './entity.model'; import { ModeFlags } from '../enums/modeFlags.enum'; import { Field } from './field.model'; var Occurrence = /** @class */ (function () { /** * Creates a new Occrruence * @param occ An Occrrence object or an object that looks like an Occurence */ function Occurrence(occ, modeFlag) { if (occ) { if (occ instanceof Occurrence) { this.pk = occ.getPk(); this.structure = occ.getStructure(); this.data = occ.getData() ? this.convertValues(occ.getData(), occ.getStructure()) : {}; this.meta = occ.getMeta() || {}; this.modified = occ.isModified(); this.locked = occ.isLocked(); } else { this.pk = occ.pk; this.structure = occ.structure; this.data = occ.data ? this.convertValues(occ.data, occ.structure) : {}; this.meta = occ.meta || {}; this.modified = occ.modified ? occ.modified : false; this.locked = occ.locked ? occ.locked : false; } } else { this.pk = null; this.data = {}; this.structure = {}; this.meta = {}; this.modified = false; this.locked = false; } this.setMode(modeFlag); } /** * Converts the SubEntities in data to Entities * @param data data to convert * @param structure structure of current occ * @returns new data object */ Occurrence.prototype.convertValues = function (data, structure) { var e_1, _a; try { for (var _b = __values(Object.keys(structure)), _c = _b.next(); !_c.done; _c = _b.next()) { var key = _c.value; var value = data[key.toUpperCase()]; if (value) { data[key.toUpperCase()] = new Entity(value.occs ? value : { occs: value, structure: structure[key.toUpperCase()] }); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } return data; }; // ------------------------------------------------------------------------------------------------------ // Get Functions // ------------------------------------------------------------------------------------------------------ /** * Gets the pk of this Occurrence */ Occurrence.prototype.getPk = function () { return this.pk; }; /** * Gets the structure of this Occurrence */ Occurrence.prototype.getStructure = function () { return this.structure; }; /** * Gets the value of the given field * @param field the name of the field * @returns the value of the field */ Occurrence.prototype.getValue = function (field) { return this.data[field.toUpperCase()]; }; /** * Returns the Mode of this Occurrence. Possible values are: 'add', 'cpy', 'del' and ''; * @returns returns the mode of the occ (ModeFlags) */ Occurrence.prototype.getMode = function () { return this.data._mode || ''; }; /** * Gets the data of this Occurence * @param col get data with or without collections. Default is true (all data). */ Occurrence.prototype.getData = function (col) { var _this = this; return col === false ? Object.keys(this.data) .filter(function (field) { return !_this.structure[field.toUpperCase()]; }) .reduce(function (prev, field) { var _a; return Object.assign(prev, (_a = {}, _a[field] = _this.data[field], _a)); }, {}) : this.data; }; /** * Gets the Subentity from this Occurrence * @param name the name of the Subentity * @returns returns the subEntity */ Occurrence.prototype.getSubEnt = function (name) { if (!this.hasCollection(name)) { return (this.data[name.toUpperCase()] = new Entity()); } return this.data[name.toUpperCase()]; }; /** * Gets the Occurences of the given SubEntity * @param name the name of the Subentity * @returns data from SubEntity */ Occurrence.prototype.getCollection = function (name) { return this.data[name.toUpperCase()] ? this.data[name.toUpperCase()].occs : []; }; /** * Gets a list of all fields of this Occurrence * @param col if true all Subentitys will be included in this list, default false * @returns returns an array of all field Names */ Occurrence.prototype.getFields = function (col) { var _this = this; return Object.keys(this.data).filter(function (value) { return col || !_this.structure[value.toUpperCase()]; }); }; /** * Has the Occurrence been modified? * @param checkSubEnt check Subentities (default: true) */ Occurrence.prototype.isModified = function (checkSubEnt) { if (checkSubEnt === void 0) { checkSubEnt = true; } return this.modified || (!checkSubEnt || !this.hasAnyCollection() ? this.modified : this.checkSubEntityModified()); }; /** * is this occurence locked and can not be edited? */ Occurrence.prototype.isLocked = function () { return this.locked; }; /** * Gets the structure of the given subentity * @param name the name of the subentity */ Occurrence.prototype.getSubEntityStructure = function (name) { return this.structure[name.toUpperCase()]; }; /** * Gets the Meta informations of this occurence * @param entity the name of a subentity, whose meta information should be read */ Occurrence.prototype.getMeta = function () { return this.meta; }; /** * Gets the Meta informations of this occurence for the given entityname * @param entity the name of a subentity, whose meta information should be read */ Occurrence.prototype.getMetaFieldList = function (entity) { return this.meta[entity.toUpperCase()] ? this.meta[entity.toUpperCase()].reduce(function (acc, val) { return Object.assign(acc, val); }, {}) || {} : {}; }; /** * Gets the Meta information for one field, if given * @param field the name of the field * @param entity the name of a subentity, where the field should be looked up */ Occurrence.prototype.getMetaField = function (field, entity) { var fieldname = field.startsWith('_') ? field : field.toUpperCase(); var metaList = this.meta[entity.toUpperCase()] ? this.meta[entity.toUpperCase()].find(function (value) { return fieldname in value; }) : undefined; return metaList ? metaList[fieldname] : {}; }; // ------------------------------------------------------------------------------------------------------ // Set Functions // ------------------------------------------------------------------------------------------------------ /** * Sets the _mode value of this Occurrence * @param mode boolean, that defines the mode. Add if this Occurrence should be added to the Database, * cpy if this is a Copy of a Occurrrence and del if this Occurrence should be deleted in the DB. * If missing, the _mode flag will be deleted. * @param col set the mode for all subentitys. */ Occurrence.prototype.setMode = function (mode, col) { var _this = this; if (mode) { if (mode.del) { this.data._mode = ModeFlags.DEL; } else if (mode.cpy) { this.data._mode = ModeFlags.CPY; } else if (mode.add) { this.data._mode = ModeFlags.ADD; } else if (this.data._mode) { delete this.data._mode; } } else if (this.data._mode) { delete this.data._mode; } if (col) { Object.keys(this.structure).forEach(function (subEnt) { if (_this.data.hasOwnProperty(subEnt)) { _this.getCollection(subEnt).forEach(function (occ) { return occ.setMode(mode, col); }); } }); } }; /** * sets the pk property * @param pk pk that should be set */ Occurrence.prototype.addPk = function (pk) { if (this.pk) { return; } this.pk = pk; }; /** * Sets the given field on the given value * @param field the name of the field * @param value the new value * @param isUserChange is this change a userChange and should set the modified Flag? (default: false) */ Occurrence.prototype.setValue = function (field, value, isUserChange) { if (isUserChange === void 0) { isUserChange = false; } if (isUserChange && this.isLocked()) { return; } if (!field.startsWith('_')) { field = field.toUpperCase(); } var undovalue = this.data[field]; this.data[field] = value; if (isUserChange && undovalue != value) { this.modified = true; } }; /** * Sets the given list of fields on the given values * @param values list of fields and values in the form {fieldname1: value1, fieldname2: value2, ...} * @param isUserChange is this change a userChange and should set the modified Flag? (default: false) */ Occurrence.prototype.setValues = function (values, isUserChange) { var _this = this; if (isUserChange === void 0) { isUserChange = false; } if (!values || (isUserChange && this.isLocked())) { return; } Object.entries(values).forEach(function (_a) { var _b = __read(_a, 2), field = _b[0], value = _b[1]; return _this.setValue(field, value, isUserChange && !_this.modified); }); this.data = this.convertValues(this.data, this.structure); }; /** * Changes all Occurrences of the given Subentity * @param name name ot the subentity * @param occs list of the new Occurences */ Occurrence.prototype.setCollection = function (name, occs) { if (this.hasCollection(name.toUpperCase())) { this.data[name.toUpperCase()].occs = occs; } else if (this.getSubEntityStructure(name)) { this.data[name.toUpperCase()] = new Entity({ occs: occs, structure: this.getSubEntityStructure(name) }); } }; /** * Sets the structure of this Occurrence * @param value the new value of the structure */ Occurrence.prototype.setStructure = function (value) { this.structure = Object.assign(this.structure, value); }; /** * Sets the modified flag * @param modified occ is modified? * @param setSubEntites should the modified flag be set also in the subentites? */ Occurrence.prototype.setModified = function (modified, setSubEntites) { var _this = this; if (setSubEntites === void 0) { setSubEntites = false; } this.modified = modified; if (setSubEntites) { Object.keys(this.structure).forEach(function (entName) { _this.getSubEnt(entName).setModified(modified, setSubEntites); }); } }; /** * Sets the Meta information for one field * @param field the name of the field * @param entity the name of a subentity, where the field should be looked up * @param value the new value of the definition */ Occurrence.prototype.setMetaField = function (field, entity, value) { var _a, _b, _c, _d; if (value) { var fldvalue = new Field(value); var fldname_1 = field.toUpperCase(); var entityname = entity.toUpperCase(); if (!this.meta) { this.meta = (_a = {}, _a[entityname] = [(_b = {}, _b[fldname_1] = fldvalue, _b)], _a); } else if (!this.meta[entityname]) { this.meta[entityname] = [(_c = {}, _c[fldname_1] = fldvalue, _c)]; } else { var metaList = this.meta[entityname].find(function (fldlst) { return fldname_1 in fldlst; }); if (!metaList) { this.meta[entityname].push((_d = {}, _d[fldname_1] = fldvalue, _d)); } else { Object.assign(metaList[fldname_1], fldvalue); } } } }; /** * Sets the Meta information for one entity * @param entity the name of a subentity, whose meta information should be set * @param values the new values of the definition */ Occurrence.prototype.setMetaFieldList = function (entity, values) { var _a; var _this = this; if (values) { var fldlsts = Array.isArray(values) ? values : [values]; var entityname = entity.toUpperCase(); if (!this.meta) { this.meta = (_a = {}, _a[entityname] = fldlsts, _a); } else if (!this.meta[entityname]) { this.meta[entityname] = fldlsts; } else { fldlsts.forEach(function (fldlst) { return Object.entries(fldlst).forEach(function (_a) { var _b = __read(_a, 2), field = _b[0], value = _b[1]; return _this.setMetaField(field, entity, value); }); }); } } }; /** * Sets the Meta information * @param metaValue the new values of the definition */ Occurrence.prototype.setMeta = function (metaValue) { var _this = this; if (metaValue) { if (!this.meta) { this.meta = metaValue; } else { Object.entries(metaValue).forEach(function (_a) { var _b = __read(_a, 2), entity = _b[0], fieldlsts = _b[1]; _this.setMetaFieldList(entity, fieldlsts); }); } } }; // ------------------------------------------------------------------------------------------------------ // Copy Functions // ------------------------------------------------------------------------------------------------------ /** * Copies the given Occurrence into this Occurrence * @param occ the Occurrence that should be copied * @param cpy the Copy mode should be set * @param isUserChange is this change a userChange and should set the modified Flag? (default: false) */ Occurrence.prototype.copy = function (occ, cpy, isUserChange) { if (isUserChange === void 0) { isUserChange = false; } this.pk = occ.pk; this.data = occ.data; this.structure = occ.structure; this.meta = occ.meta; this.modified = isUserChange; this.locked = false; this.setMode({ cpy: cpy }); }; /** * Makes a copy of this Occurrence into a new instance. * @returns new Occurrence */ Occurrence.prototype.copyOccFlat = function () { return new Occurrence({ pk: this.pk, structure: this.structure, meta: this.meta, data: { _pk: this.data._pk, _hash: this.data._hash }, modified: this.modified, }); }; // ------------------------------------------------------------------------------------------------------ // SubEntity/Structure Functions // ------------------------------------------------------------------------------------------------------ /** * Checks if this Occurrence has the given Subentity * @param name the name of the Subentity * @returns true or false */ Occurrence.prototype.hasCollection = function (name) { return this.data[name.toUpperCase()]; }; /** * Checks if the Occ is type OCC or COL * @returns true or false */ Occurrence.prototype.hasAnyCollection = function () { var e_2, _a; try { for (var _b = __values(Object.keys(this.structure)), _c = _b.next(); !_c.done; _c = _b.next()) { var subEnt = _c.value; if (this.data.hasOwnProperty(subEnt)) { return true; } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_2) throw e_2.error; } } return false; }; /** * Changes the given Subentity * @param name the name of the Subentity * @param SubEnt the new Entity * @param isUserChange is this a users change (should modified flag been set) (default: false) */ Occurrence.prototype.changeSubEnt = function (name, SubEnt, isUserChange) { if (isUserChange === void 0) { isUserChange = false; } this.data[name.toUpperCase()] = SubEnt; if (isUserChange) { this.getSubEnt(name).setModified(true, false); } }; // ------------------------------------------------------------------------------------------------------ // Delete Functions // ------------------------------------------------------------------------------------------------------ /** * Deletes a Subenetity from this Occurrence * @param name name of the subentity */ Occurrence.prototype.deleteSubEnt = function (name) { delete this.data[name.toUpperCase()]; }; /** * Deletes a field from this Occurrence * @param name name of field */ Occurrence.prototype.deleteValue = function (name) { delete this.data[name.toUpperCase()]; }; // ------------------------------------------------------------------------------------------------------ // Check Functions // ------------------------------------------------------------------------------------------------------ /** * checks if some subentity is modified */ Occurrence.prototype.checkSubEntityModified = function () { var e_3, _a; try { for (var _b = __values(Object.keys(this.structure)), _c = _b.next(); !_c.done; _c = _b.next()) { var entName = _c.value; if (this.hasCollection(entName) && this.getSubEnt(entName).isModified()) { return true; } } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_3) throw e_3.error; } } return false; }; // ------------------------------------------------------------------------------------------------------ // Additional // ------------------------------------------------------------------------------------------------------ /** * Compares this Occurrence with the given Occ. First the PK will be compared and then the hash value. * @param occ the second occ */ Occurrence.prototype.equals = function (occ) { return this.getPk() === occ.getPk() && this.getValue('_hash') === occ.getValue('_hash'); }; /** * Gets a string representation of this Occurrence. This is mainly for debug purpose. */ Occurrence.prototype.toString = function () { return JSON.stringify({ pk: this.pk, _hash: this.data._hash }); }; return Occurrence; }()); export { Occurrence }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2NjdXJyZW5jZS5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2d5LWZvby8iLCJzb3VyY2VzIjpbImxpYi9tb2RlbHMvb2NjdXJyZW5jZS5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXhDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVwRCxPQUFPLEVBQUUsS0FBSyxFQUFZLE1BQU0sZUFBZSxDQUFDO0FBRWhEO0lBUUU7OztPQUdHO0lBQ0gsb0JBQ0UsR0FTYyxFQUNkLFFBQTBEO1FBRTFELElBQUksR0FBRyxFQUFFO1lBQ1AsSUFBSSxHQUFHLFlBQVksVUFBVSxFQUFFO2dCQUM3QixJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDdEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUN2RixJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7Z0JBQ2hDLElBQUksQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNqQyxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQzthQUM5QjtpQkFBTTtnQkFDTCxJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2pCLElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQztnQkFDL0Is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LENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMxRixDQUFDO0lBRUQ7O09BRUc7SUFDSCw2QkFBUSxHQUFSO1FBQ0UsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBQ0gsaUJBQUM7QUFBRCxDQUFDLEFBdGZELElBc2ZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRW50aXR5IH0gZnJvbSAnLi9lbnRpdHkubW9kZWwnO1xuaW1wb3J0IHsgRW50aXR5U3RydWN0dXJlIH0gZnJvbSAnLi9lbnRpdHlTdHJ1Y3R1cmUubW9kZWwnO1xuaW1wb3J0IHsgTW9kZUZsYWdzIH0gZnJvbSAnLi4vZW51bXMvbW9kZUZsYWdzLmVudW0nO1xuaW1wb3J0IHsgRmllbGRMaXN0IH0gZnJvbSAnLi9maWVsZExpc3QubW9kZWwnO1xuaW1wb3J0IHsgRmllbGQsIEZpZWxkRGVmIH0gZnJvbSAnLi9maWVsZC5tb2RlbCc7XG5cbmV4cG9ydCBjbGFzcyBPY2N1cnJlbmNlIHtcbiAgcHJpdmF0ZSBwazogc3RyaW5nO1xuICBwcml2YXRlIGRhdGE6IHsgW2ZpZWxkOiBzdHJpbmddOiBhbnkgfTtcbiAgcHJpdmF0ZSBtZXRhPzogeyBbZW50aXR5OiBzdHJpbmddOiBGaWVsZExpc3RbXSB9O1xuICBwcml2YXRlIHN0cnVjdHVyZTogRW50aXR5U3RydWN0dXJlO1xuICBwcml2YXRlIG1vZGlmaWVkOiBib29sZWFuO1xuICBwcml2YXRlIGxvY2tlZDogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBPY2NycnVlbmNlXG4gICAqIEBwYXJhbSBvY2MgQW4gT2NjcnJlbmNlIG9iamVjdCBvciBhbiBvYmplY3QgdGhhdCBsb29rcyBsaWtlIGFuIE9jY3VyZW5jZVxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgb2NjPzpcbiAgICAgIHwge1xuICAgICAgICAgIHBrOiBzdHJpbmc7XG4gICAgICAgICAgc3RydWN0dXJlOiBFbnRpdHlTdHJ1Y3R1cmU7XG4gICAgICAgICAgZGF0YT86IHsgW2ZpZWxkOiBzdHJpbmddOiBhbnkgfTtcbiAgICAgICAgICBtZXRhPzogeyBbZW50aXR5OiBzdHJpbmddOiBGaWVsZExpc3RbXSB9O1xuICAgICAgICAgIG1vZGlmaWVkPzogYm9vbGVhbjtcbiAgICAgICAgICBsb2NrZWQ/OiBib29sZWFuO1xuICAgICAgICB9XG4gICAgICB8IE9jY3VycmVuY2UsXG4gICAgbW9kZUZsYWc/OiB7IGFkZD86IGJvb2xlYW47IGNweT86IGJvb2xlYW47IGRlbD86IGJvb2xlYW4gfVxuICApIHtcbiAgICBpZiAob2NjKSB7XG4gICAgICBpZiAob2NjIGluc3RhbmNlb2YgT2NjdXJyZW5jZSkge1xuICAgICAgICB0aGlzLnBrID0gb2NjLmdldFBrKCk7XG4gICAgICAgIHRoaXMuc3RydWN0dXJlID0gb2NjLmdldFN0cnVjdHVyZSgpO1xuICAgICAgICB0aGlzLmRhdGEgPSBvY2MuZ2V0RGF0YSgpID8gdGhpcy5jb252ZXJ0VmFsdWVzKG9jYy5nZXREYXRhKCksIG9jYy5nZXRTdHJ1Y3R1cmUoKSkgOiB7fTtcbiAgICAgICAgdGhpcy5tZXRhID0gb2NjLmdldE1ldGEoKSB8fCB7fTtcbiAgICAgICAgdGhpcy5tb2RpZmllZCA9IG9jYy5pc01vZGlmaWVkKCk7XG4gICAgICAgIHRoaXMubG9ja2VkID0gb2NjLmlzTG9ja2VkKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnBrID0gb2NjLnBrO1xuICAgICAgICB0aGlzLnN0cnVjdHVyZSA9IG9jYy5zdHJ1Y3R1cmU7XG4gICAgICAgIHRoaXMuZGF0YSA9IG9jYy5kYXRhID8gdGhpcy5jb252ZXJ0VmFsdWVzKG9jYy5kYXRhLCBvY2Muc3RydWN0dXJlKSA6IHt9O1xuICAgICAgICB0aGlzLm1ldGEgPSBvY2MubWV0YSB8fCB7fTtcbiAgICAgICAgdGhpcy5tb2RpZmllZCA9IG9jYy5tb2RpZmllZCA/IG9jYy5tb2RpZmllZCA6IGZhbHNlO1xuICAgICAgICB0aGlzLmxvY2tlZCA9IG9jYy5sb2NrZWQgPyBvY2MubG9ja2VkIDogZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGsgPSBudWxsO1xuICAgICAgdGhpcy5kYXRhID0ge307XG4gICAgICB0aGlzLnN0cnVjdHVyZSA9IHt9O1xuICAgICAgdGhpcy5tZXRhID0ge307XG4gICAgICB0aGlzLm1vZGlmaWVkID0gZmFsc2U7XG4gICAgICB0aGlzLmxvY2tlZCA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLnNldE1vZGUobW9kZUZsYWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBTdWJFbnRpdGllcyBpbiBkYXRhIHRvIEVudGl0aWVzXG4gICAqIEBwYXJhbSBkYXRhIGRhdGEgdG8gY29udmVydFxuICAgKiBAcGFyYW0gc3RydWN0dXJlIHN0cnVjdHVyZSBvZiBjdXJyZW50IG9jY1xuICAgKiBAcmV0dXJucyBuZXcgZGF0YSBvYmplY3RcbiAgICovXG4gIHByaXZhdGUgY29udmVydFZhbHVlcyhkYXRhOiB7IFtmaWVsZDogc3RyaW5nXTogYW55IH0sIHN0cnVjdHVyZTogRW50aXR5U3RydWN0dXJlKTogeyBbZmllbGQ6IHN0cmluZ106IGFueSB9IHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzdHJ1Y3R1cmUpKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGRhdGFba2V5LnRvVXBwZXJDYXNlKCldO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIGRhdGFba2V5LnRvVXBwZXJDYXNlKCldID0gbmV3IEVudGl0eShcbiAgICAgICAgICB2YWx1ZS5vY2NzID8gdmFsdWUgOiB7IG9jY3M6IHZhbHVlLCBzdHJ1Y3R1cmU6IHN0cnVjdHVyZVtrZXkudG9VcHBlckNhc2UoKV0gfVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0IEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvKipcbiAgICogR2V0cyB0aGUgcGsgb2YgdGhpcyBPY2N1cnJlbmNlXG4gICAqL1xuICBnZXRQaygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnBrO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHN0cnVjdHVyZSBvZiB0aGlzIE9jY3VycmVuY2VcbiAgICovXG4gIGdldFN0cnVjdHVyZSgpOiBFbnRpdHlTdHJ1Y3R1cmUge1xuICAgIHJldHVybiB0aGlzLnN0cnVjdHVyZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZmllbGRcbiAgICogQHBhcmFtIGZpZWxkIHRoZSBuYW1lIG9mIHRoZSBmaWVsZFxuICAgKiBAcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkXG4gICAqL1xuICBnZXRWYWx1ZShmaWVsZDogc3RyaW5nKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5kYXRhW2ZpZWxkLnRvVXBwZXJDYXNlKCldO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIE1vZGUgb2YgdGhpcyBPY2N1cnJlbmNlLiBQb3NzaWJsZSB2YWx1ZXMgYXJlOiAnYWRkJywgJ2NweScsICdkZWwnIGFuZCAnJztcbiAgICogQHJldHVybnMgcmV0dXJucyB0aGUgbW9kZSBvZiB0aGUgb2NjIChNb2RlRmxhZ3MpXG4gICAqL1xuICBnZXRNb2RlKCk6IE1vZGVGbGFncyB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YS5fbW9kZSB8fCAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBkYXRhIG9mIHRoaXMgT2NjdXJlbmNlXG4gICAqIEBwYXJhbSBjb2wgZ2V0IGRhdGEgd2l0aCBvciB3aXRob3V0IGNvbGxlY3Rpb25zLiBEZWZhdWx0IGlzIHRydWUgKGFsbCBkYXRhKS5cbiAgICovXG4gIGdldERhdGEoY29sPzogYm9vbGVhbik6IG9iamVjdCB7XG4gICAgcmV0dXJuIGNvbCA9PT0gZmFsc2VcbiAgICAgID8gT2JqZWN0LmtleXModGhpcy5kYXRhKVxuICAgICAgICAgIC5maWx0ZXIoKGZpZWxkOiBhbnkpID0+ICF0aGlzLnN0cnVjdHVyZVtmaWVsZC50b1VwcGVyQ2FzZSgpXSlcbiAgICAgICAgICAucmVkdWNlKChwcmV2LCBmaWVsZCkgPT4gT2JqZWN0LmFzc2lnbihwcmV2LCB7IFtmaWVsZF06IHRoaXMuZGF0YVtmaWVsZF0gfSksIHt9KVxuICAgICAgOiB0aGlzLmRhdGE7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgU3ViZW50aXR5IGZyb20gdGhpcyBPY2N1cnJlbmNlXG4gICAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBTdWJlbnRpdHlcbiAgICogQHJldHVybnMgcmV0dXJucyB0aGUgc3ViRW50aXR5XG4gICAqL1xuICBnZXRTdWJFbnQobmFtZTogc3RyaW5nKTogRW50aXR5IHtcbiAgICBpZiAoIXRoaXMuaGFzQ29sbGVjdGlvbihuYW1lKSkge1xuICAgICAgcmV0dXJuICh0aGlzLmRhdGFbbmFtZS50b1VwcGVyQ2FzZSgpXSA9IG5ldyBFbnRpdHkoKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmRhdGFbbmFtZS50b1VwcGVyQ2FzZSgpXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBPY2N1cmVuY2VzIG9mIHRoZSBnaXZlbiBTdWJFbnRpdHlcbiAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIFN1YmVudGl0eVxuICAgKiBAcmV0dXJucyBkYXRhIGZyb20gU3ViRW50aXR5XG4gICAqL1xuICBnZXRDb2xsZWN0aW9uKG5hbWU6IHN0cmluZyk6IE9jY3VycmVuY2VbXSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVtuYW1lLnRvVXBwZXJDYXNlKCldID8gdGhpcy5kYXRhW25hbWUudG9VcHBlckNhc2UoKV0ub2NjcyA6IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYSBsaXN0IG9mIGFsbCBmaWVsZHMgb2YgdGhpcyBPY2N1cnJlbmNlXG4gICAqIEBwYXJhbSBjb2wgaWYgdHJ1ZSBhbGwgU3ViZW50aXR5cyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoaXMgbGlzdCwgZGVmYXVsdCBmYWxzZVxuICAgKiBAcmV0dXJucyByZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBmaWVsZCBOYW1lc1xuICAgKi9cbiAgZ2V0RmllbGRzKGNvbD86IGJvb2xlYW4pOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkuZmlsdGVyKCh2YWx1ZSkgPT4gY29sIHx8ICF0aGlzLnN0cnVjdHVyZVt2YWx1ZS50b1VwcGVyQ2FzZSgpXSk7XG4gIH1cblxuICAvKipcbiAgICogSGFzIHRoZSBPY2N1cnJlbmNlIGJlZW4gbW9kaWZpZWQ/XG4gICAqIEBwYXJhbSBjaGVja1N1YkVudCBjaGVjayBTdWJlbnRpdGllcyAoZGVmYXVsdDogdHJ1ZSlcbiAgICovXG4gIGlzTW9kaWZpZWQoY2hlY2tTdWJFbnQ6IGJvb2xlYW4gPSB0cnVlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubW9kaWZpZWQgfHwgKCFjaGVja1N1YkVudCB8fCAhdGhpcy5oYXNBbnlDb2xsZWN0aW9uKCkgPyB0aGlzLm1vZGlmaWVkIDogdGhpcy5jaGVja1N1YkVudGl0eU1vZGlmaWVkKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIGlzIHRoaXMgb2NjdXJlbmNlIGxvY2tlZCBhbmQgY2FuIG5vdCBiZSBlZGl0ZWQ/XG4gICAqL1xuICBpc0xvY2tlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sb2NrZWQ7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgc3RydWN0dXJlIG9mIHRoZSBnaXZlbiBzdWJlbnRpdHlcbiAgICogQHBhcmFtIG5hbWUgdGhlIG5hbWUgb2YgdGhlIHN1YmVudGl0eVxuICAgKi9cbiAgZ2V0U3ViRW50aXR5U3RydWN0dXJlKG5hbWU6IHN0cmluZyk6IEVudGl0eVN0cnVjdHVyZSB7XG4gICAgcmV0dXJuIHRoaXMuc3RydWN0dXJlW25hbWUudG9VcHBlckNhc2UoKV07XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgTWV0YSBpbmZvcm1hdGlvbnMgb2YgdGhpcyBvY2N1cmVuY2VcbiAgICogQHBhcmFtIGVudGl0eSB0aGUgbmFtZSBvZiBhIHN1YmVudGl0eSwgd2hvc2UgbWV0YSBpbmZvcm1hdGlvbiBzaG91bGQgYmUgcmVhZFxuICAgKi9cbiAgZ2V0TWV0YSgpOiB7IFtlbnRpdHk6IHN0cmluZ106IEZpZWxkTGlzdFtdIH0ge1xuICAgIHJldHVybiB0aGlzLm1ldGE7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgTWV0YSBpbmZvcm1hdGlvbnMgb2YgdGhpcyBvY2N1cmVuY2UgZm9yIHRoZSBnaXZlbiBlbnRpdHluYW1lXG4gICAqIEBwYXJhbSBlbnRpdHkgdGhlIG5hbWUgb2YgYSBzdWJlbnRpdHksIHdob3NlIG1ldGEgaW5mb3JtYXRpb24gc2hvdWxkIGJlIHJlYWRcbiAgICovXG4gIGdldE1ldGFGaWVsZExpc3QoZW50aXR5OiBzdHJpbmcpOiBGaWVsZExpc3Qge1xuICAgIHJldHVybiB0aGlzLm1ldGFbZW50aXR5LnRvVXBwZXJDYXNlKCldXG4gICAgICA/IHRoaXMubWV0YVtlbnRpdHkudG9VcHBlckNhc2UoKV0ucmVkdWNlKChhY2MsIHZhbCkgPT4gT2JqZWN0LmFzc2lnbihhY2MsIHZhbCksIHt9KSB8fCB7fVxuICAgICAgOiB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBNZXRhIGluZm9ybWF0aW9uIGZvciBvbmUgZmllbGQsIGlmIGdpdmVuXG4gICAqIEBwYXJhbSBmaWVsZCB0aGUgbmFtZSBvZiB0aGUgZmllbGRcbiAgICogQHBhcmFtIGVudGl0eSB0aGUgbmFtZSBvZiBhIHN1YmVudGl0eSwgd2hlcmUgdGhlIGZpZWxkIHNob3VsZCBiZSBsb29rZWQgdXBcbiAgICovXG4gIGdldE1ldGFGaWVsZChmaWVsZDogc3RyaW5nLCBlbnRpdHk6IHN0cmluZyk6IEZpZWxkIHwge30ge1xuICAgIGNvbnN0IGZpZWxkbmFtZSA9IGZpZWxkLnN0YXJ0c1dpdGgoJ18nKSA/IGZpZWxkIDogZmllbGQudG9VcHBlckNhc2UoKTtcbiAgICBjb25zdCBtZXRhTGlzdCA9IHRoaXMubWV0YVtlbnRpdHkudG9VcHBlckNhc2UoKV1cbiAgICAgID8gdGhpcy5tZXRhW2VudGl0eS50b1VwcGVyQ2FzZSgpXS5maW5kKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgIHJldHVybiBmaWVsZG5hbWUgaW4gdmFsdWU7XG4gICAgICAgIH0pXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gbWV0YUxpc3QgPyBtZXRhTGlzdFtmaWVsZG5hbWVdIDoge307XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldCBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBfbW9kZSB2YWx1ZSBvZiB0aGlzIE9jY3VycmVuY2VcbiAgICogQHBhcmFtIG1vZGUgYm9vbGVhbiwgdGhhdCBkZWZpbmVzIHRoZSBtb2RlLiBBZGQgaWYgdGhpcyBPY2N1cnJlbmNlIHNob3VsZCBiZSBhZGRlZCB0byB0aGUgRGF0YWJhc2UsXG4gICAqIGNweSBpZiB0aGlzIGlzIGEgQ29weSBvZiBhIE9jY3VycnJlbmNlIGFuZCBkZWwgaWYgdGhpcyBPY2N1cnJlbmNlIHNob3VsZCBiZSBkZWxldGVkIGluIHRoZSBEQi5cbiAgICogSWYgbWlzc2luZywgdGhlIF9tb2RlIGZsYWcgd2lsbCBiZSBkZWxldGVkLlxuICAgKiBAcGFyYW0gY29sIHNldCB0aGUgbW9kZSBmb3IgYWxsIHN1YmVudGl0eXMuXG4gICAqL1xuICBzZXRNb2RlKG1vZGU/OiB7IGFkZD86IGJvb2xlYW47IGNweT86IGJvb2xlYW47IGRlbD86IGJvb2xlYW4gfSwgY29sPzogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmIChtb2RlKSB7XG4gICAgICBpZiAobW9kZS5kZWwpIHtcbiAgICAgICAgdGhpcy5kYXRhLl9tb2RlID0gTW9kZUZsYWdzLkRFTDtcbiAgICAgIH0gZWxzZSBpZiAobW9kZS5jcHkpIHtcbiAgICAgICAgdGhpcy5kYXRhLl9tb2RlID0gTW9kZUZsYWdzLkNQWTtcbiAgICAgIH0gZWxzZSBpZiAobW9kZS5hZGQpIHtcbiAgICAgICAgdGhpcy5kYXRhLl9tb2RlID0gTW9kZUZsYWdzLkFERDtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhLl9tb2RlKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmRhdGEuX21vZGU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0aGlzLmRhdGEuX21vZGUpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLmRhdGEuX21vZGU7XG4gICAgfVxuICAgIGlmIChjb2wpIHtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuc3RydWN0dXJlKS5mb3JFYWNoKChzdWJFbnQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuZGF0YS5oYXNPd25Qcm9wZXJ0eShzdWJFbnQpKSB7XG4gICAgICAgICAgdGhpcy5nZXRDb2xsZWN0aW9uKHN1YkVudCkuZm9yRWFjaCgob2NjOiBPY2N1cnJlbmNlKSA9PiBvY2Muc2V0TW9kZShtb2RlLCBjb2wpKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIHNldHMgdGhlIHBrIHByb3BlcnR5XG4gICAqIEBwYXJhbSBwayBwayB0aGF0IHNob3VsZCBiZSBzZXRcbiAgICovXG4gIGFkZFBrKHBrOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5waykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnBrID0gcGs7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZ2l2ZW4gZmllbGQgb24gdGhlIGdpdmVuIHZhbHVlXG4gICAqIEBwYXJhbSBmaWVsZCB0aGUgbmFtZSBvZiB0aGUgZmllbGRcbiAgICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWVcbiAgICogQHBhcmFtIGlzVXNlckNoYW5nZSBpcyB0aGlzIGNoYW5nZSBhIHVzZXJDaGFuZ2UgYW5kIHNob3VsZCBzZXQgdGhlIG1vZGlmaWVkIEZsYWc/IChkZWZhdWx0OiBmYWxzZSlcbiAgICovXG4gIHNldFZhbHVlKGZpZWxkOiBzdHJpbmcsIHZhbHVlOiBhbnksIGlzVXNlckNoYW5nZTogYm9vbGVhbiA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKGlzVXNlckNoYW5nZSAmJiB0aGlzLmlzTG9ja2VkKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFmaWVsZC5zdGFydHNXaXRoKCdfJykpIHtcbiAgICAgIGZpZWxkID0gZmllbGQudG9VcHBlckNhc2UoKTtcbiAgICB9XG5cbiAgICBjb25zdCB1bmRvdmFsdWUgPSB0aGlzLmRhdGFbZmllbGRdO1xuICAgIHRoaXMuZGF0YVtmaWVsZF0gPSB2YWx1ZTtcblxuICAgIGlmIChpc1VzZXJDaGFuZ2UgJiYgdW5kb3ZhbHVlICE9IHZhbHVlKSB7XG4gICAgICB0aGlzLm1vZGlmaWVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZ2l2ZW4gbGlzdCBvZiBmaWVsZHMgb24gdGhlIGdpdmVuIHZhbHVlc1xuICAgKiBAcGFyYW0gdmFsdWVzIGxpc3Qgb2YgZmllbGRzIGFuZCB2YWx1ZXMgaW4gdGhlIGZvcm0ge2ZpZWxkbmFtZTE6IHZhbHVlMSwgZmllbGRuYW1lMjogdmFsdWUyLCAuLi59XG4gICAqIEBwYXJhbSBpc1VzZXJDaGFuZ2UgaXMgdGhpcyBjaGFuZ2UgYSB1c2VyQ2hhbmdlIGFuZCBzaG91bGQgc2V0IHRoZSBtb2RpZmllZCBGbGFnPyAoZGVmYXVsdDogZmFsc2UpXG4gICAqL1xuICBzZXRWYWx1ZXModmFsdWVzOiB7IFtmaWVsZDogc3RyaW5nXTogYW55IH0sIGlzVXNlckNoYW5nZTogYm9vbGVhbiA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKCF2YWx1ZXMgfHwgKGlzVXNlckNoYW5nZSAmJiB0aGlzLmlzTG9ja2VkKCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIE9iamVjdC5lbnRyaWVzKHZhbHVlcykuZm9yRWFjaCgoW2ZpZWxkLCB2YWx1ZV0pID0+IHRoaXMuc2V0VmFsdWUoZmllbGQsIHZhbHVlLCBpc1VzZXJDaGFuZ2UgJiYgIXRoaXMubW9kaWZpZWQpKTtcbiAgICB0aGlzLmRhdGEgPSB0aGlzLmNvbnZlcnRWYWx1ZXModGhpcy5kYXRhLCB0aGlzLnN0cnVjdHVyZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hhbmdlcyBhbGwgT2NjdXJyZW5jZXMgb2YgdGhlIGdpdmVuIFN1YmVudGl0eVxuICAgKiBAcGFyYW0gbmFtZSBuYW1lIG90IHRoZSBzdWJlbnRpdHlcbiAgICogQHBhcmFtIG9jY3MgbGlzdCBvZiB0aGUgbmV3IE9jY3VyZW5jZXNcbiAgICovXG4gIHNldENvbGxlY3Rpb24obmFtZTogc3RyaW5nLCBvY2NzOiBPY2N1cnJlbmNlW10pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oYXNDb2xsZWN0aW9uKG5hbWUudG9VcHBlckNhc2UoKSkpIHtcbiAgICAgIHRoaXMuZGF0YVtuYW1lLnRvVXBwZXJDYXNlKCldLm9jY3MgPSBvY2NzO1xuICAgIH0gZWxzZSBpZiAodGhpcy5nZXRTdWJFbnRpdHlTdHJ1Y3R1cmUobmFtZSkpIHtcbiAgICAgIHRoaXMuZGF0YVtuYW1lLnRvVXBwZXJDYXNlKCldID0gbmV3IEVudGl0eSh7IG9jY3MsIHN0cnVjdHVyZTogdGhpcy5nZXRTdWJFbnRpdHlTdHJ1Y3R1cmUobmFtZSkgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHN0cnVjdHVyZSBvZiB0aGlzIE9jY3VycmVuY2VcbiAgICogQHBhcmFtIHZhbHVlIHRoZSBuZXcgdmFsdWUgb2YgdGhlIHN0cnVjdHVyZVxuICAgKi9cbiAgc2V0U3RydWN0dXJlKHZhbHVlOiBFbnRpdHlTdHJ1Y3R1cmUpOiB2b2lkIHtcbiAgICB0aGlzLnN0cnVjdHVyZSA9IE9iamVjdC5hc3NpZ24odGhpcy5zdHJ1Y3R1cmUsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBtb2RpZmllZCBmbGFnXG4gICAqIEBwYXJhbSBtb2RpZmllZCBvY2MgaXMgbW9kaWZpZWQ/XG4gICAqIEBwYXJhbSBzZXRTdWJFbnRpdGVzIHNob3VsZCB0aGUgbW9kaWZpZWQg