@linid-dm/directory-manager-client-core
Version:
Core package by providing a set of angular components for the Directory Manager app.
609 lines • 96.9 kB
JavaScript
/**
* Copyright (C) 2020-2024 Linagora
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version, provided you comply with the Additional Terms applicable for
* LinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU
* Affero General Public License, subsections (b), (c), and (e), pursuant to
* which these Appropriate Legal Notices must notably (i) retain the display of
* the "LinID™" trademark/logo at the top of the interface window, the display
* of the “You are using the Open Source and free version of LinID™, powered by
* Linagora © 2009–2013. Contribute to LinID R&D by subscribing to an Enterprise
* offer!” infobox and in the e-mails sent with the Program, notice appended to
* any type of outbound messages (e.g. e-mail and meeting requests) as well as
* in the LinID Directory Manager user interface, (ii) retain all hypertext
* links between LinID Directory Manager and https://linid.org/, as well as
* between LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA
* intellectual property rights over its trademarks and commercial brands. Other
* Additional Terms apply, see <http://www.linagora.com/licenses/> for more
* details.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License and
* its applicable Additional Terms for LinID Directory Manager along with this
* program. If not, see <http://www.gnu.org/licenses/> for the GNU Affero
* General Public License version 3 and <http://www.linagora.com/licenses/> for
* the Additional Terms applicable to the LinID Directory Manager software.
*/
import { _isNumberValue } from '@angular/cdk/coercion';
import { MatTableDataSource } from '@angular/material/table';
import _ from 'lodash';
import { EComponentName, } from '../interfaces/data.interface';
import { EEllipsisMenuActions } from '../interfaces/ui.interface';
import { getScimParentsAndChildren } from './configs.helper';
import { emptyJsTable } from './jstable.helper';
import { getRouterLinkValue } from './resources.helper';
const MAX_SAFE_INTEGER = 9007199254740991;
export function isLinkObject(attributeValue) {
if (typeof attributeValue !== 'object') {
return false;
}
// There are multiple constants because some fields are optionnals in ILink interface
const twoProps = 'id' in attributeValue && 'label' in attributeValue;
const threeProps = twoProps && 'canBeRead' in attributeValue;
const fourProps = threeProps && 'value' in attributeValue;
const fiveProps = threeProps &&
'parentId' in attributeValue &&
'parentLabel' in attributeValue;
const sixProps = fiveProps && 'parentCanBeRead' in attributeValue;
const nbFields = Object.keys(attributeValue).length;
const isSimpleLink = (nbFields === 2 && twoProps) ||
(nbFields === 3 && threeProps) ||
(nbFields === 4 && fourProps);
const isParentLink = (nbFields === 5 && fiveProps) || (nbFields === 6 && sixProps);
return isSimpleLink || isParentLink;
}
export function escapeBackSlash(value) {
return value.replace(/\\/g, '\\\\');
}
export class DataViewProperties {
constructor(object) {
this.dataSource =
object && object.dataSource
? object.dataSource
: new MatTableDataSource();
this.columns = object && object.columns ? object.columns : [];
this.displayedColumns =
object && object.displayedColumns ? object.displayedColumns : [];
this.isClickableRow =
object && object.isClickableRow ? object.isClickableRow : null;
this.accessibility =
object && object.accessibility ? object.accessibility : null;
}
getDataSource() {
return this.dataSource;
}
setDataSource(dataSource) {
this.dataSource = dataSource;
}
getColumns() {
return this.columns;
}
setColumns(columns) {
this.columns = columns;
}
getDisplayedColumns() {
return this.displayedColumns;
}
setDisplayedColumns(displayedColumns) {
this.displayedColumns = displayedColumns;
}
getIsClickableRow() {
return this.isClickableRow;
}
setIsClickableRow(isClickableRow) {
this.isClickableRow = isClickableRow;
}
getAccessibility() {
return this.accessibility;
}
setAccessibility(accessibility) {
this.accessibility = accessibility;
}
}
export function getViewPropertiesArrayAttribute(attributeConfig, isClickableRow = true) {
let dataViewProperties = new DataViewProperties();
let displayedColumns = [];
let columns = [];
const propsFieldAttribute = attributeConfig.value.field.props;
if (propsFieldAttribute) {
if (!!propsFieldAttribute.columns) {
propsFieldAttribute.columns.forEach((column) => {
displayedColumns.push(column.id);
columns.push({
id: column.id,
label: column.label,
isBackendLinkObject: column.isBackendLinkObject,
width: column.width,
type: column.type,
});
});
dataViewProperties.setDisplayedColumns(displayedColumns);
dataViewProperties.setColumns(columns);
}
if (!!propsFieldAttribute.accessibility) {
dataViewProperties.setAccessibility(propsFieldAttribute.accessibility);
}
dataViewProperties.setIsClickableRow(isClickableRow);
}
return dataViewProperties;
}
export function canDeleteEntries(actions, hasOneDeletableEntry) {
const isDeleteActionAvailable = actions && EEllipsisMenuActions.MULTIPLE_DELETE in actions;
return isDeleteActionAvailable && hasOneDeletableEntry;
}
export function getRowId(row, selectionColumnId) {
if (row.selectionIds) {
return row.selectionIds.id;
}
else {
if (selectionColumnId) {
if (isDataTableCellElement(row[selectionColumnId])) {
return row[selectionColumnId].id;
}
else if (isArrayOfDataTableCellElements(row[selectionColumnId])) {
return row[selectionColumnId][0].id;
}
else {
return row[selectionColumnId];
}
}
else {
return row.id;
}
}
}
function getRowExternalId(row, columnIdForPatchOperation) {
if (row.selectionIds) {
return row.selectionIds.externalId;
}
else {
if (columnIdForPatchOperation) {
if (isDataTableCellElement(row[columnIdForPatchOperation])) {
return row[columnIdForPatchOperation].value;
}
else if (isArrayOfDataTableCellElements(row[columnIdForPatchOperation])) {
return row[columnIdForPatchOperation][0].value;
}
else {
return row[columnIdForPatchOperation];
}
}
else {
return row.externalId;
}
}
}
export function convertDataSourceRowToLinkObject(row, columnForId, updateActionsParams) {
let linkObject = {
id: getRowId(row, columnForId),
label: getRowExternalId(row, columnForId),
};
if (updateActionsParams.edit) {
linkObject = {
...linkObject,
value: row[updateActionsParams.edit.columnId],
};
}
return linkObject;
}
export function isDataTableCellElement(cellValue) {
if (typeof cellValue !== 'object') {
return false;
}
const nbFields = Object.keys(cellValue).length;
const hasDataTableCellElementProps = 'id' in cellValue && 'value' in cellValue && 'isClickable' in cellValue;
return (nbFields === 3 || nbFields == 4) && hasDataTableCellElementProps;
}
export function isArrayOfDataTableCellElements(cellValue) {
return (Array.isArray(cellValue) &&
cellValue.length > 0 &&
cellValue.every((value) => isDataTableCellElement(value)));
}
export function getDataSourceArrayUsingDataFromBackend(data, columnIds, resourcesTypesIds, resourcesTypes, squashColumnId) {
const dataSource = data.map((link) => columnIds.reduce((acc, columnId, index) => {
let parentEndpoint = null;
let endpoint = null;
if (resourcesTypes.allIds.includes(columnId)) {
endpoint = resourcesTypes.byId[columnId].endpoint;
if (index > 0) {
const parentResourceTypeId = resourcesTypesIds[index - 1];
if (resourcesTypes.allIds.includes(parentResourceTypeId)) {
parentEndpoint =
resourcesTypes.byId[parentResourceTypeId].endpoint;
}
}
}
if (index === 0 && resourcesTypesIds.length > 1) {
acc[columnId].push(convertParentLinkToDataTableCellElement(link, endpoint));
}
else if ('value' in link && index > 0) {
acc = { ...acc, [columnId]: link.value };
}
else {
acc[columnId].push(convertLinkToDataTableCellElement(link, endpoint, parentEndpoint));
}
return acc;
}, resourcesTypesIds.reduce((acc, currResourceTypeId) => ({
...acc,
[currResourceTypeId]: [],
}), {})));
return squashColumnId
? squashArrayRows(dataSource, squashColumnId, resourcesTypesIds)
: dataSource;
}
export function squashArrayRows(dataSource, squashColumnId, columnIds) {
const squashedArray = [];
if (dataSource.length > 0) {
const handledIdsValues = [];
const remainingColumnsIds = columnIds.filter((id) => id !== squashColumnId);
const allParentColumnValues = dataSource.map((row, index) => ({
index,
value: row[squashColumnId][0].value,
}));
dataSource.forEach((row, rowIndex) => {
if (!handledIdsValues.includes(rowIndex)) {
const occurencesIndexes = allParentColumnValues
.filter((elt) => elt.value === row[squashColumnId][0].value)
.map((occurence) => occurence.index);
if (occurencesIndexes.length > 0) {
squashedArray.push({
[squashColumnId]: row[squashColumnId],
...remainingColumnsIds.reduce((acc, columnId) => ({
...acc,
[columnId]: occurencesIndexes
.reduce((acc, index) => acc.concat(dataSource[index][columnId]), [])
.sort((a, b) => a.value
.toLocaleUpperCase()
.localeCompare(b.value.toLocaleUpperCase())),
}), {}),
});
handledIdsValues.push(...occurencesIndexes);
}
else {
handledIdsValues.push(rowIndex);
squashedArray.push(row);
}
}
});
}
return squashedArray.sort((a, b) => a[squashColumnId][0].value
.toLocaleUpperCase()
.localeCompare(b[squashColumnId][0].value.toLocaleUpperCase()));
}
function convertLinkToDataTableCellElement(attributeValue, endpoint, parentEndpoint = null) {
let cellElement = {
id: attributeValue.id,
value: attributeValue.label,
isClickable: attributeValue.canBeRead,
};
let clickableCellElement;
if (attributeValue.canBeRead) {
clickableCellElement = {
...cellElement,
routerLinkValue: getRouterLinkValue(endpoint, attributeValue.label, parentEndpoint, attributeValue.parentLabel),
};
return clickableCellElement;
}
return cellElement;
}
function convertParentLinkToDataTableCellElement(attributeValue, endpoint) {
let cellElement = {
id: attributeValue.parentId,
value: attributeValue.parentLabel,
isClickable: attributeValue.parentCanBeRead,
};
let clickableCellElement;
if (attributeValue.parentCanBeRead) {
clickableCellElement = {
...cellElement,
routerLinkValue: getRouterLinkValue(endpoint, attributeValue.parentLabel),
};
return clickableCellElement;
}
return cellElement;
}
export function getDataSourceForGenericArray(data, selectedResourceTypeConfig, clickableCellsEndpoints = emptyJsTable(), onlyEditableResources = false) {
let flatResources = [];
if (!!(data && data.Resources)) {
data.Resources.forEach((dataResource) => {
if (dataResource.meta.isDeletable ||
dataResource.meta.isModifiable ||
!onlyEditableResources) {
flatResources.push(getDataEntryForGenericArray(dataResource, selectedResourceTypeConfig, clickableCellsEndpoints));
}
});
}
return flatResources;
}
export function getDataEntryForGenericArray(dataResource, resourceTypeConfig, clickableCellsEndpoints = emptyJsTable()) {
let flatResource = getFlatResource(dataResource, resourceTypeConfig);
return getDisplayedAttributeValue(flatResource, Object.keys(flatResource), resourceTypeConfig, clickableCellsEndpoints);
}
export function getFlatResource(dataResource, resourceTypeConfig) {
let flatResource = {};
const attributes = resourceTypeConfig.attributes;
const scimParentsAndChildren = getScimParentsAndChildren(attributes);
for (const scimParentId in scimParentsAndChildren) {
if (Object.prototype.hasOwnProperty.call(scimParentsAndChildren, scimParentId)) {
scimParentsAndChildren[scimParentId]
.filter((childId) => !!(dataResource[scimParentId] && dataResource[scimParentId][childId]))
.forEach((childId) => (flatResource = {
...flatResource,
[childId]: dataResource[scimParentId][childId],
}));
}
}
let scimParentIds = Object.keys(scimParentsAndChildren);
const dataResourceWithoutScimParentIds = Object.keys(dataResource).reduce((acc, fieldId) => {
if (!scimParentIds.includes(fieldId)) {
acc = { ...acc, [fieldId]: dataResource[fieldId] };
}
return acc;
}, {});
flatResource = { ...flatResource, ...dataResourceWithoutScimParentIds };
return flatResource;
}
export function getDisplayedAttributeValue(dataResource, dataResourceKeys, resourceTypeConfig, clickableCellsEndpoints = emptyJsTable()) {
let resource = {};
const attributes = resourceTypeConfig.attributes;
dataResourceKeys.forEach((key) => {
const currentAttribute = attributes.find((attributeConfig) => attributeConfig.modelRef === key);
const isSimpleAttribute = !Array.isArray(dataResource[key]) && dataResource[key] !== null;
const isAttributeArray = Array.isArray(dataResource[key]) && dataResource[key].length >= 0;
const isAttributeArrayWithDataOfOtherScimType = !!currentAttribute
? Array.isArray(dataResource[key]) &&
Object.prototype.hasOwnProperty.call(currentAttribute, 'getDataListParams') &&
!currentAttribute.props.isUsingDataFromBackend
: false;
if (isSimpleAttribute ||
isAttributeArray ||
isAttributeArrayWithDataOfOtherScimType) {
resource = {
...resource,
[key]: clickableCellsEndpoints.allIds.includes(key)
? getAttributeValueAsArrayOfDataTableCellElement(dataResource[key], clickableCellsEndpoints.byId[key])
: getAttributeValue(dataResource[key]),
};
}
});
return resource;
}
function getAttributeValueAsArrayOfDataTableCellElement(attributeValue, cellEndpoint) {
let displayedAttributeValue;
if (Array.isArray(attributeValue)) {
displayedAttributeValue = attributeValue.map((value) => convertLinkToDataTableCellElement(value, cellEndpoint));
}
else {
displayedAttributeValue = [
convertLinkToDataTableCellElement(attributeValue, cellEndpoint),
];
}
return displayedAttributeValue;
}
function getAttributeValue(attributeValue) {
let displayedAttributeValue;
if (isLinkObject(attributeValue)) {
displayedAttributeValue = attributeValue.label;
}
else if (isArrayOfLinkObjects(attributeValue)) {
displayedAttributeValue = attributeValue.map((value) => value.label);
}
else {
displayedAttributeValue = attributeValue;
}
return displayedAttributeValue;
}
export function isArrayOfLinkObjects(attributeValue) {
return (Array.isArray(attributeValue) &&
attributeValue.length > 0 &&
attributeValue.every((value) => isLinkObject(value)));
}
export function getOrderedKeysArrayAttributes(attributes, dataResource) {
const attributeIds = attributes.map((attribute) => attribute.modelRef);
let keys = _.intersection(attributeIds, Object.keys(dataResource)).filter((key) => dataResource[key] !== undefined && dataResource[key] !== null);
const orderKeysByAttributeId = keys.sort((a, b) => {
return attributeIds.indexOf(a) - attributeIds.indexOf(b);
});
return orderKeysByAttributeId;
}
export function getDisplayedColumnsIds(resourceTypeConfig) {
let displayedColumns = [];
if (!!resourceTypeConfig.props?.columns) {
displayedColumns = resourceTypeConfig.props.columns.reduce((acc, column) => [...acc, column.idForSearch || column.id], []);
}
return displayedColumns;
}
export function getOrderedKeysSimpleAttributes(attributes, dataResource) {
const attributeIds = attributes.map((attribute) => attribute.modelRef);
// Remove "schema" property from dataDetails as it is non useful for the Front-End
let keys = _.intersection(attributeIds, Object.keys(dataResource)).filter((key) => {
const attributeConfig = attributes.find((attribute) => attribute.modelRef === key);
const isInputChipsAutocomplete = !!attributeConfig &&
attributeConfig.value.field.componentName ===
EComponentName.inputChipsAutocomplete;
const isInputChipsAutocompleteWithValues = isInputChipsAutocomplete &&
!!dataResource[key] &&
dataResource[key].length > 0;
const isInput = !!attributeConfig &&
attributeConfig.value.field.componentName === EComponentName.input;
const isInputWithValueAsArray = isInput && !!dataResource[key] && Array.isArray(dataResource[key]);
const isInputWithValueAsNotEmptyArray = isInputWithValueAsArray && dataResource[key].length > 0;
return (dataResource[key] !== undefined &&
dataResource[key] !== null &&
(isInputChipsAutocompleteWithValues ||
isInputWithValueAsNotEmptyArray ||
!(isInputWithValueAsArray || isInputChipsAutocomplete)));
});
const orderKeysByAttributeId = keys.sort((a, b) => {
return attributeIds.indexOf(a) - attributeIds.indexOf(b);
});
return orderKeysByAttributeId;
}
export function canDeleteEntry(arrayActions, isSelectOnlyModeEnabled, isEditableRow) {
const isDeleteActionAvailable = arrayActions && EEllipsisMenuActions.SINGLE_DELETE in arrayActions;
return isDeleteActionAvailable && isEditableRow && !isSelectOnlyModeEnabled;
}
export function canMoveEntry(arrayActions, canAssignOrMoveEntries, isSelectOnlyModeEnabled, isEditableRow) {
const areMoveActionsAvailable = arrayActions &&
(EEllipsisMenuActions.SINGLE_UNASSIGN in arrayActions ||
EEllipsisMenuActions.SINGLE_REASSIGN in arrayActions);
return (areMoveActionsAvailable &&
canAssignOrMoveEntries &&
isEditableRow &&
!isSelectOnlyModeEnabled);
}
export function getSelectedElementIds(row, selectionColumnId) {
let externalId;
if (!!selectionColumnId) {
const cellElt = row[selectionColumnId];
if (isArrayOfDataTableCellElements(cellElt) && cellElt.length === 1) {
externalId = cellElt[0].value;
return { id: cellElt[0].id, externalId, label: externalId };
}
else if (isDataTableCellElement(cellElt)) {
externalId = cellElt.value;
return { id: cellElt.id, externalId, label: externalId };
}
}
else {
externalId = row.externalId;
return { id: row.id, externalId, label: externalId };
}
}
export function getUpdatedDisplayedColumns(arrayActions, initialDisplayedColumns, isSelectOnlyModeEnabled, canAssignOrMoveEntries, isEditableArray, updateAffectAnotherResourceType, isAttributeArray, data) {
let updateDisplayedColumns = [
...initialDisplayedColumns.filter((columnId) => data.some((row) => columnId in row)),
];
const additionnalColumnsToDisplay = ['select', 'actions'];
const hasOneDeletableEntry = data.some((row) => row.meta?.isDeletable);
const hasOneEditableEntry = data.some((row) => row.isRowEditable);
if (!isSelectOnlyModeEnabled && data.length > 0) {
const canDelete = canDeleteEntries(arrayActions, hasOneDeletableEntry);
const canMove = canMoveEntries(arrayActions, canAssignOrMoveEntries, hasOneEditableEntry);
const isEditableAttributeArray = isEditableArray &&
(canMove || canDelete || !updateAffectAnotherResourceType);
if ((isAttributeArray && isEditableAttributeArray) ||
(!isAttributeArray && canDelete)) {
updateDisplayedColumns.unshift(additionnalColumnsToDisplay[0]);
updateDisplayedColumns.push(additionnalColumnsToDisplay[1]);
}
}
else if (hasOneDeletableEntry || hasOneEditableEntry) {
updateDisplayedColumns.unshift(additionnalColumnsToDisplay[0]);
}
return updateDisplayedColumns;
}
export function canMoveEntries(arrayActions, canAssignOrMoveEntries, hasOneDeletableEntry) {
const areMoveActionsAvailable = arrayActions &&
(EEllipsisMenuActions.MULTIPLE_UNASSIGN in arrayActions ||
EEllipsisMenuActions.MULTIPLE_REASSIGN in arrayActions);
return (areMoveActionsAvailable && canAssignOrMoveEntries && hasOneDeletableEntry);
}
export function isRowEditable(isAttributeArray, updateAffectAnotherResourceType, fieldForUpdate, isEditableArray, row) {
const isUpdateAffectingAnotherResourceType = isAttributeArray && updateAffectAnotherResourceType;
const isUpdateAffectingOnlyCurrentResourceType = isAttributeArray &&
!updateAffectAnotherResourceType &&
fieldForUpdate == null;
if (isUpdateAffectingAnotherResourceType) {
return (row.meta.isModifiable &&
row.meta.modifiableAttributes.includes(fieldForUpdate));
}
else if (isUpdateAffectingOnlyCurrentResourceType) {
return isEditableArray;
}
else {
return row.meta?.isDeletable;
}
}
export function sortData(data, sort) {
const active = sort.active;
const direction = sort.direction;
if (!active || direction === '') {
return data;
}
return data.sort((a, b) => {
let valueA = sortingDataAccessor(a, active);
let valueB = sortingDataAccessor(b, active);
// If there are data in the column that can be converted to a number,
// it must be ensured that the rest of the data
// is of the same type so as not to order incorrectly.
const valueAType = typeof valueA;
const valueBType = typeof valueB;
if (valueAType !== valueBType) {
if (valueAType === 'number') {
valueA += '';
}
if (valueBType === 'number') {
valueB += '';
}
}
// If both valueA and valueB exist (truthy), then compare the two. Otherwise, check if
// one value exists while the other doesn't. In this case, existing value should come last.
// This avoids inconsistent results when comparing values to undefined/null.
// If neither value exists, return 0 (equal).
let comparatorResult = 0;
if (valueA != null && valueB != null) {
// Check if one value is greater than the other; if equal, comparatorResult should remain 0.
if (valueA > valueB) {
comparatorResult = 1;
}
else if (valueA < valueB) {
comparatorResult = -1;
}
}
else if (valueA != null) {
comparatorResult = 1;
}
else if (valueB != null) {
comparatorResult = -1;
}
return comparatorResult * (direction === 'asc' ? 1 : -1);
});
}
export function sortingDataAccessor(data, sortHeaderId) {
let value = data[sortHeaderId];
value =
Array.isArray(value) && value.length > 0
? Object.prototype.hasOwnProperty.call(value[0], 'value')
? value[0].value
: null
: value;
if (_isNumberValue(value)) {
const numberValue = Number(value);
// Numbers beyond `MAX_SAFE_INTEGER` can't be compared reliably so we
// leave them as strings. For more info: https://goo.gl/y5vbSg
return numberValue < MAX_SAFE_INTEGER ? numberValue : value;
}
return value;
}
export function getAllElementsToExport(arrayData, columns) {
const columnsLabel = getColumnsLabels(columns);
const data = !!arrayData
? arrayData.map((row) => columns.reduce((acc, column) => {
const label = columnsLabel.get(column.id);
let cellValue = row[column.id];
if (Array.isArray(cellValue) && cellValue.length > 0) {
cellValue = cellValue
.map((cellElt) => Object.prototype.hasOwnProperty.call(cellElt, 'value')
? cellElt.value
: cellElt)
.join(', ');
}
return { ...acc, [label]: cellValue };
}, {}))
: [];
return data;
}
export function getColumnsLabels(columns) {
return !!columns
? new Map(columns.map((column) => [column.id, column.label]))
: new Map();
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS10YWJsZS5oZWxwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9saWJzL2NsaWVudC1jb3JlL3NyYy9saWIvc2hhcmVkL2hlbHBlcnMvZGF0YS10YWJsZS5oZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBRUgsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXZELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzdELE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQztBQVV2QixPQUFPLEVBQ0wsY0FBYyxHQVNmLE1BQU0sOEJBQThCLENBQUM7QUFFdEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDbEUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDN0QsT0FBTyxFQUFXLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRXhELE1BQU0sZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7QUFFMUMsTUFBTSxVQUFVLFlBQVksQ0FBQyxjQUFtQjtJQUM5QyxJQUFJLE9BQU8sY0FBYyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ3ZDLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELHFGQUFxRjtJQUNyRixNQUFNLFFBQVEsR0FBRyxJQUFJLElBQUksY0FBYyxJQUFJLE9BQU8sSUFBSSxjQUFjLENBQUM7SUFDckUsTUFBTSxVQUFVLEdBQUcsUUFBUSxJQUFJLFdBQVcsSUFBSSxjQUFjLENBQUM7SUFDN0QsTUFBTSxTQUFTLEdBQUcsVUFBVSxJQUFJLE9BQU8sSUFBSSxjQUFjLENBQUM7SUFDMUQsTUFBTSxTQUFT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RjtRQUNILENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDUCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRCxNQUFNLFVBQVUsZ0JBQWdCLENBQzlCLE9BQThCO0lBRTlCLE9BQU8sQ0FBQyxDQUFDLE9BQU87UUFDZCxDQUFDLENBQUMsSUFBSSxHQUFHLENBQ0wsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQTJCLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FDeEU7UUFDSCxDQUFDLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMjAtMjAyNCBMaW5hZ29yYVxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyXG4gKiB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWVcbiAqIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55XG4gKiBsYXRlciB2ZXJzaW9uLCBwcm92aWRlZCB5b3UgY29tcGx5IHdpdGggdGhlIEFkZGl0aW9uYWwgVGVybXMgYXBwbGljYWJsZSBmb3JcbiAqIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHNvZnR3YXJlIGJ5IExJTkFHT1JBIHB1cnN1YW50IHRvIFNlY3Rpb24gNyBvZiB0aGUgR05VXG4gKiBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwgc3Vic2VjdGlvbnMgKGIpLCAoYyksIGFuZCAoZSksIHB1cnN1YW50IHRvXG4gKiB3aGljaCB0aGVzZSBBcHByb3ByaWF0ZSBMZWdhbCBOb3RpY2VzIG11c3Qgbm90YWJseSAoaSkgcmV0YWluIHRoZSBkaXNwbGF5IG9mXG4gKiB0aGUgXCJMaW5JROKEolwiIHRyYWRlbWFyay9sb2dvIGF0IHRoZSB0b3Agb2YgdGhlIGludGVyZmFjZSB3aW5kb3csIHRoZSBkaXNwbGF5XG4gKiBvZiB0aGUg4oCcWW91IGFyZSB1c2luZyB0aGUgT3BlbiBTb3VyY2UgYW5kIGZyZWUgdmVyc2lvbiBvZiBMaW5JROKEoiwgcG93ZXJlZCBieVxuICogTGluYWdvcmEgwqkgMjAwOeKAkzIwMTMuIENvbnRyaWJ1dGUgdG8gTGluSUQgUiZEIGJ5IHN1YnNjcmliaW5nIHRvIGFuIEVudGVycHJpc2VcbiAqIG9mZmVyIeKAnSBpbmZvYm94IGFuZCBpbiB0aGUgZS1tYWlscyBzZW50IHdpdGggdGhlIFByb2dyYW0sIG5vdGljZSBhcHBlbmRlZCB0b1xuICogYW55IHR5cGUgb2Ygb3V0Ym91bmQgbWVzc2FnZXMgKGUuZy4gZS1tYWlsIGFuZCBtZWV0aW5nIHJlcXVlc3RzKSBhcyB3ZWxsIGFzXG4gKiBpbiB0aGUgTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgdXNlciBpbnRlcmZhY2UsIChpaSkgcmV0YWluIGFsbCBoeXBlcnRleHRcbiAqIGxpbmtzIGJldHdlZW4gTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgYW5kIGh0dHBzOi8vbGluaWQub3JnLywgYXMgd2VsbCBhc1xuICogYmV0d2VlbiBMSU5BR09SQSBhbmQgTElOQUdPUkEuY29tLCBhbmQgKGlpaSkgcmVmcmFpbiBmcm9tIGluZnJpbmdpbmcgTElOQUdPUkFcbiAqIGludGVsbGVjdHVhbCBwcm9wZXJ0eSByaWdodHMgb3ZlciBpdHMgdHJhZGVtYXJrcyBhbmQgY29tbWVyY2lhbCBicmFuZHMuIE90aGVyXG4gKiBBZGRpdGlvbmFsIFRlcm1zIGFwcGx5LCBzZWUgPGh0dHA6Ly93d3cubGluYWdvcmEuY29tL2xpY2Vuc2VzLz4gZm9yIG1vcmVcbiAqIGRldGFpbHMuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG4gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTU1xuICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZVxuICogZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYW5kXG4gKiBpdHMgYXBwbGljYWJsZSBBZGRpdGlvbmFsIFRlcm1zIGZvciBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBhbG9uZyB3aXRoIHRoaXNcbiAqIHByb2dyYW0uIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPiBmb3IgdGhlIEdOVSBBZmZlcm9cbiAqIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAzIGFuZCA8aHR0cDovL3d3dy5saW5hZ29yYS5jb20vbGljZW5zZXMvPiBmb3JcbiAqIHRoZSBBZGRpdGlvbmFsIFRlcm1zIGFwcGxpY2FibGUgdG8gdGhlIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHNvZnR3YXJlLlxuICovXG5cbmltcG9ydCB7IF9pc051bWJlclZhbHVlIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcbmltcG9ydCB7IE1hdFNvcnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zb3J0JztcbmltcG9ydCB7IE1hdFRhYmxlRGF0YVNvdXJjZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYmxlJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQge1xuICBJQXJyYXlBY2Nlc3NpYmlsaXR5LFxuICBJQXJyYXlBdHRyaWJ1dGVVcGRhdGVQYXJhbXMsXG4gIElBdHRyaWJ1dGUsXG4gIElBdHRyaWJ1dGVBY3Rpb25zLFxuICBJQ29sdW1uLFxuICBJQ29uZmlnLFxuICBJUHJpbWl0aXZlQWN0aW9ucyxcbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9jb25maWdzLmludGVyZmFjZSc7XG5pbXBvcnQge1xuICBFQ29tcG9uZW50TmFtZSxcbiAgSUNsaWNrYWJsZURhdGFUYWJsZUNlbGxFbGVtZW50LFxuICBJRGF0YSxcbiAgSURhdGFTb3VyY2VSb3csXG4gIElEYXRhVGFibGVDZWxsRWxlbWVudCxcbiAgSURhdGFUYWJsZVJvdyxcbiAgSUdlbmVyaWNBcnJheUNvbHVtbixcbiAgSUxpbmssXG4gIElVaUVudHJ5SWRzLFxufSBmcm9tICcuLi9pbnRlcmZhY2VzL2RhdGEuaW50ZXJmYWNlJztcbmltcG9ydCB7IElSZXNvdXJjZVR5cGUgfSBmcm9tICcuLi9pbnRlcmZhY2VzL3Jlc291cmNlcy10eXBlcy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgRUVsbGlwc2lzTWVudUFjdGlvbnMgfSBmcm9tICcuLi9pbnRlcmZhY2VzL3VpLmludGVyZmFjZSc7XG5pbXBvcnQgeyBnZXRTY2ltUGFyZW50c0FuZENoaWxkcmVuIH0gZnJvbSAnLi9jb25maWdzLmhlbHBlcic7XG5pbXBvcnQgeyBKc1RhYmxlLCBlbXB0eUpzVGFibGUgfSBmcm9tICcuL2pzdGFibGUuaGVscGVyJztcbmltcG9ydCB7IGdldFJvdXRlckxpbmtWYWx1ZSB9IGZyb20gJy4vcmVzb3VyY2VzLmhlbHBlcic7XG5cbmNvbnN0IE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNMaW5rT2JqZWN0KGF0dHJpYnV0ZVZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKHR5cGVvZiBhdHRyaWJ1dGVWYWx1ZSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBUaGVyZSBhcmUgbXVsdGlwbGUgY29uc3RhbnRzIGJlY2F1c2Ugc29tZSBmaWVsZHMgYXJlIG9wdGlvbm5hbHMgaW4gSUxpbmsgaW50ZXJmYWNlXG4gIGNvbnN0IHR3b1Byb3BzID0gJ2lkJyBpbiBhdHRyaWJ1dGVWYWx1ZSAmJiAnbGFiZWwnIGluIGF0dHJpYnV0ZVZhbHVlO1xuICBjb25zdCB0aHJlZVByb3BzID0gdHdvUHJvcHMgJiYgJ2NhbkJlUmVhZCcgaW4gYXR0cmlidXRlVmFsdWU7XG4gIGNvbnN0IGZvdXJQcm9wcyA9IHRocmVlUHJvcHMgJiYgJ3ZhbHVlJyBpbiBhdHRyaWJ1dGVWYWx1ZTtcbiAgY29uc3QgZml2ZVByb3BzID1cbiAgICB0aHJlZVByb3BzICYmXG4gICAgJ3BhcmVudElkJyBpbiBhdHRyaWJ1dGVWYWx1ZSAmJlxuICAgICdwYXJlbnRMYWJlbCcgaW4gYXR0cmlidXRlVmFsdWU7XG4gIGNvbnN0IHNpeFByb3BzID0gZml2ZVByb3BzICYmICdwYXJlbnRDYW5CZVJlYWQnIGluIGF0dHJpYnV0ZVZhbHVlO1xuXG4gIGNvbnN0IG5iRmllbGRzOiBudW1iZXIgPSBPYmplY3Qua2V5cyhhdHRyaWJ1dGVWYWx1ZSkubGVuZ3RoO1xuXG4gIGNvbnN0IGlzU2ltcGxlTGluayA9XG4gICAgKG5iRmllbGRzID09PSAyICYmIHR3b1Byb3BzKSB8fFxuICAgIChuYkZpZWxkcyA9PT0gMyAmJiB0aHJlZVByb3BzKSB8fFxuICAgIChuYkZpZWxkcyA9PT0gNCAmJiBmb3VyUHJvcHMpO1xuXG4gIGNvbnN0IGlzUGFyZW50TGluayA9XG4gICAgKG5iRmllbGRzID09PSA1ICYmIGZpdmVQcm9wcykgfHwgKG5iRmllbGRzID09PSA2ICYmIHNpeFByb3BzKTtcblxuICByZXR1cm4gaXNTaW1wbGVMaW5rIHx8IGlzUGFyZW50TGluaztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZUJhY2tTbGFzaCh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1xcXFwvZywgJ1xcXFxcXFxcJyk7XG59XG5cbmV4cG9ydCBjbGFzcyBEYXRhVmlld1Byb3BlcnRpZXMge1xuICBwcml2YXRlIGRhdGFTb3VyY2U6IE1hdFRhYmxlRGF0YVNvdXJjZTxhbnk+O1xuICBwcml2YXRlIGNvbHVtbnM6IElHZW5lcmljQXJyYXlDb2x1bW5bXTtcbiAgcHJpdmF0ZSBkaXNwbGF5ZWRDb2x1bW5zOiBzdHJpbmdbXTtcbiAgcHJpdmF0ZSBpc0NsaWNrYWJsZVJvdzogYm9vbGVhbjtcbiAgcHJpdmF0ZSBhY2Nlc3NpYmlsaXR5OiBJQXJyYXlBY2Nlc3NpYmlsaXR5O1xuXG4gIGNvbnN0cnVjdG9yKG9iamVjdD86IERhdGFWaWV3UHJvcGVydGllcykge1xuICAgIHRoaXMuZGF0YVNvdXJjZSA9XG4gICAgICBvYmplY3QgJiYgb2JqZWN0LmRhdGFTb3VyY2VcbiAgICAgICAgPyBvYmplY3QuZGF0YVNvdXJjZVxuICAgICAgICA6IG5ldyBNYXRUYWJsZURhdGFTb3VyY2U8YW55PigpO1xuICAgIHRoaXMuY29sdW1ucyA9IG9iamVjdCAmJiBvYmplY3QuY29sdW1ucyA/IG9iamVjdC5jb2x1bW5zIDogW107XG4gICAgdGhpcy5kaXNwbGF5ZWRDb2x1bW5zID1cbiAgICAgIG9iamVjdCAmJiBvYmplY3QuZGlzcGxheWVkQ29sdW1ucyA/IG9iamVjdC5kaXNwbGF5ZWRDb2x1bW5zIDogW107XG4gICAgdGhpcy5pc0NsaWNrYWJsZVJvdyA9XG4gICAgICBvYmplY3QgJiYgb2JqZWN0LmlzQ2xpY2thYmxlUm93ID8gb2JqZWN0LmlzQ2xpY2thYmxlUm93IDogbnVsbDtcbiAgICB0aGlzLmFjY2Vzc2liaWxpdHkgPVxuICAgICAgb2JqZWN0ICYmIG9iamVjdC5hY2Nlc3NpYmlsaXR5ID8gb2JqZWN0LmFjY2Vzc2liaWxpdHkgOiBudWxsO1xuICB9XG5cbiAgZ2V0RGF0YVNvdXJjZSgpOiBNYXRUYWJsZURhdGFTb3VyY2U8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVNvdXJjZTtcbiAgfVxuXG4gIHNldERhdGFTb3VyY2UoZGF0YVNvdXJjZTogTWF0VGFibGVEYXRhU291cmNlPGFueT4pOiB2b2lkIHtcbiAgICB0aGlzLmRhdGFTb3VyY2UgPSBkYXRhU291cmNlO1xuICB9XG5cbiAgZ2V0Q29sdW1ucygpOiBJR2VuZXJpY0FycmF5Q29sdW1uW10ge1xuICAgIHJldHVybiB0aGlzLmNvbHVtbnM7XG4gIH1cblxuICBzZXRDb2x1bW5zKGNvbHVtbnM6IElHZW5lcmljQXJyYXlDb2x1bW5bXSk6IHZvaWQge1xuICAgIHRoaXMuY29sdW1ucyA9IGNvbHVtbnM7XG4gIH1cblxuICBnZXREaXNwbGF5ZWRDb2x1bW5zKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwbGF5ZWRDb2x1bW5zO1xuICB9XG5cbiAgc2V0RGlzcGxheWVkQ29sdW1ucyhkaXNwbGF5ZWRDb2x1bW5zOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIHRoaXMuZGlzcGxheWVkQ29sdW1ucyA9IGRpc3BsYXllZENvbHVtbnM7XG4gIH1cblxuICBnZXRJc0NsaWNrYWJsZVJvdygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pc0NsaWNrYWJsZVJvdztcbiAgfVxuXG4gIHNldElzQ2xpY2thYmxlUm93KGlzQ2xpY2thYmxlUm93OiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5pc0NsaWNrYWJsZVJvdyA9IGlzQ2xpY2thYmxlUm93O1xuICB9XG5cbiAgZ2V0QWNjZXNzaWJpbGl0eSgpOiBJQXJyYXlBY2Nlc3NpYmlsaXR5IHtcbiAgICByZXR1cm4gdGhpcy5hY2Nlc3NpYmlsaXR5O1xuICB9XG5cbiAgc2V0QWNjZXNzaWJpbGl0eShhY2Nlc3NpYmlsaXR5OiBJQXJyYXlBY2Nlc3NpYmlsaXR5KTogdm9pZCB7XG4gICAgdGhpcy5hY2Nlc3NpYmlsaXR5ID0gYWNjZXNzaWJpbGl0eTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Vmlld1Byb3BlcnRpZXNBcnJheUF0dHJpYnV0ZShcbiAgYXR0cmlidXRlQ29uZmlnOiBJQXR0cmlidXRlLFxuICBpc0NsaWNrYWJsZVJvdyA9IHRydWVcbik6IERhdGFWaWV3UHJvcGVydGllcyB7XG4gIGxldCBkYXRhVmlld1Byb3BlcnRpZXMgPSBuZXcgRGF0YVZpZXdQcm9wZXJ0aWVzKCk7XG4gIGxldCBkaXNwbGF5ZWRDb2x1bW5zOiBzdHJpbmdbXSA9IFtdO1xuICBsZXQgY29sdW1uczogSUdlbmVyaWNBcnJheUNvbHVtbltdID0gW107XG4gIGNvbnN0IHByb3BzRmllbGRBdHRyaWJ1dGUgPSBhdHRyaWJ1dGVDb25maWcudmFsdWUuZmllbGQucHJvcHM7XG5cbiAgaWYgKHByb3BzRmllbGRBdHRyaWJ1dGUpIHtcbiAgICBpZiAoISFwcm9wc0ZpZWxkQXR0cmlidXRlLmNvbHVtbnMpIHtcbiAgICAgIHByb3BzRmllbGRBdHRyaWJ1dGUuY29sdW1ucy5mb3JFYWNoKChjb2x1bW46IElDb2x1bW4pID0+IHtcbiAgICAgICAgZGlzcGxheWVkQ29sdW1ucy5wdXNoKGNvbHVtbi5pZCk7XG4gICAgICAgIGNvbHVtbnMucHVzaCh7XG4gICAgICAgICAgaWQ6IGNvbHVtbi5pZCxcbiAgICAgICAgICBsYWJlbDogY29sdW1uLmxhYmVsLFxuICAgICAgICAgIGlzQmFja2VuZExpbmtPYmplY3Q6IGNvbHVtbi5pc0JhY2tlbmRMaW5rT2JqZWN0LFxuICAgICAgICAgIHdpZHRoOiBjb2x1bW4ud2lkdGgsXG4gICAgICAgICAgdHlwZTogY29sdW1uLnR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICBkYXRhVmlld1Byb3BlcnRpZXMuc2V0RGlzcGxheWVkQ29sdW1ucyhkaXNwbGF5ZWRDb2x1bW5zKTtcbiAgICAgIGRhdGFWaWV3UHJvcGVydGllcy5zZXRDb2x1bW5zKGNvbHVtbnMpO1xuICAgIH1cbiAgICBpZiAoISFwcm9wc0ZpZWxkQXR0cmlidXRlLmFjY2Vzc2liaWxpdHkpIHtcbiAgICAgIGRhdGFWaWV3UHJvcGVydGllcy5zZXRBY2Nlc3NpYmlsaXR5KHByb3BzRmllbGRBdHRyaWJ1dGUuYWNjZXNzaWJpbGl0eSk7XG4gICAgfVxuICAgIGRhdGFWaWV3UHJvcGVydGllcy5zZXRJc0NsaWNrYWJsZVJvdyhpc0NsaWNrYWJsZVJvdyk7XG4gIH1cbiAgcmV0dXJuIGRhdGFWaWV3UHJvcGVydGllcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbkRlbGV0ZUVudHJpZXMoXG4gIGFjdGlvbnM6IElQcmltaXRpdmVBY3Rpb25zIHwgSUF0dHJpYnV0ZUFjdGlvbnMsXG4gIGhhc09uZURlbGV0YWJsZUVudHJ5OiBib29sZWFuXG4pOiBib29sZWFuIHtcbiAgY29uc3QgaXNEZWxldGVBY3Rpb25BdmFpbGFibGU6IGJvb2xlYW4gPVxuICAgIGFjdGlvbnMgJiYgRUVsbGlwc2lzTWVudUFjdGlvbnMuTVVMVElQTEVfREVMRVRFIGluIGFjdGlvbnM7XG4gIHJldHVybiBpc0RlbGV0ZUFjdGlvbkF2YWlsYWJsZSAmJiBoYXNPbmVEZWxldGFibGVFbnRyeTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvd0lkKFxuICByb3c6IElEYXRhVGFibGVSb3csXG4gIHNlbGVjdGlvbkNvbHVtbklkOiBzdHJpbmdcbik6IHN0cmluZyB7XG4gIGlmIChyb3cuc2VsZWN0aW9uSWRzKSB7XG4gICAgcmV0dXJuIHJvdy5zZWxlY3Rpb25JZHMuaWQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHNlbGVjdGlvbkNvbHVtbklkKSB7XG4gICAgICBpZiAoaXNEYXRhVGFibGVDZWxsRWxlbWVudChyb3dbc2VsZWN0aW9uQ29sdW1uSWRdKSkge1xuICAgICAgICByZXR1cm4gcm93W3NlbGVjdGlvbkNvbHVtbklkXS5pZDtcbiAgICAgIH0gZWxzZSBpZiAoaXNBcnJheU9mRGF0YVRhYmxlQ2VsbEVsZW1lbnRzKHJvd1tzZWxlY3Rpb25Db2x1bW5JZF0pKSB7XG4gICAgICAgIHJldHVybiByb3dbc2VsZWN0aW9uQ29sdW1uSWRdWzBdLmlkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJvd1tzZWxlY3Rpb25Db2x1bW5JZF07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByb3cuaWQ7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldFJvd0V4dGVybmFsSWQoXG4gIHJvdzogSURhdGFTb3VyY2VSb3csXG4gIGNvbHVtbklkRm9yUGF0Y2hPcGVyYXRpb246IHN0cmluZ1xuKTogc3RyaW5nIHtcbiAgaWYgKHJvdy5zZWxlY3Rpb25JZHMpIHtcbiAgICByZXR1cm4gcm93LnNlbGVjdGlvbklkcy5leHRlcm5hbElkO1xuICB9IGVsc2Uge1xuICAgIGlmIChjb2x1bW5JZEZvclBhdGNoT3BlcmF0aW9uKSB7XG4gICAgICBpZiAoaXNEYXRhVGFibGVDZWxsRWxlbWVudChyb3dbY29sdW1uSWRGb3JQYXRjaE9wZXJhdGlvbl0pKSB7XG4gICAgICAgIHJldHVybiByb3dbY29sdW1uSWRGb3JQYXRjaE9wZXJhdGlvbl0udmFsdWU7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBpc0FycmF5T2ZEYXRhVGFibGVDZWxsRWxlbWVudHMocm93W2NvbHVtbklkRm9yUGF0Y2hPcGVyYXRpb25dKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiByb3dbY29sdW1uSWRGb3JQYXRjaE9wZXJhdGlvbl1bMF0udmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gcm93W2NvbHVtbklkRm9yUGF0Y2hPcGVyYXRpb25dO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcm93LmV4dGVybmFsSWQ7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0RGF0YVNvdXJjZVJvd1RvTGlua09iamVjdChcbiAgcm93OiBJRGF0YVNvdXJjZVJvdyxcbiAgY29sdW1uRm9ySWQ6IHN0cmluZyxcbiAgdXBkYXRlQWN0aW9uc1BhcmFtczogSUFycmF5QXR0cmlidXRlVXBkYXRlUGFyYW1zXG4pOiBJTGluayB7XG4gIGxldCBsaW5rT2JqZWN0OiBJTGluayA9IHtcbiAgICBpZDogZ2V0Um93SWQocm93LCBjb2x1bW5Gb3JJZCksXG4gICAgbGFiZWw6IGdldFJvd0V4dGVybmFsSWQocm93LCBjb2x1bW5Gb3JJZCksXG4gIH07XG5cbiAgaWYgKHVwZGF0ZUFjdGlvbnNQYXJhbXMuZWRpdCkge1xuICAgIGxpbmtPYmplY3QgPSB7XG4gICAgICAuLi5saW5rT2JqZWN0LFxuICAgICAgdmFsdWU6IHJvd1t1cGRhdGVBY3Rpb25zUGFyYW1zLmVkaXQuY29sdW1uSWRdLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gbGlua09iamVjdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGF0YVRhYmxlQ2VsbEVsZW1lbnQoY2VsbFZhbHVlKTogYm9vbGVhbiB7XG4gIGlmICh0eXBlb2YgY2VsbFZhbHVlICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBuYkZpZWxkczogbnVtYmVyID0gT2JqZWN0LmtleXMoY2VsbFZhbHVlKS5sZW5ndGg7XG4gIGNvbnN0IGhhc0RhdGFUYWJsZUNlbGxFbGVtZW50UHJvcHM6IGJvb2xlYW4gPVxuICAgICdpZCcgaW4gY2VsbFZhbHVlICYmICd2YWx1ZScgaW4gY2VsbFZhbHVlICYmICdpc0NsaWNrYWJsZScgaW4gY2VsbFZhbHVlO1xuICByZXR1cm4gKG5iRmllbGRzID09PSAzIHx8IG5iRmllbGRzID09IDQpICYmIGhhc0RhdGFUYWJsZUNlbGxFbGVtZW50UHJvcHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0FycmF5T2ZEYXRhVGFibGVDZWxsRWxlbWVudHMoY2VsbFZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBBcnJheS5pc0FycmF5KGNlbGxWYWx1ZSkgJiZcbiAgICBjZWxsVmFsdWUubGVuZ3RoID4gMCAmJlxuICAgIGNlbGxWYWx1ZS5ldmVyeSgodmFsdWU6IGFueSkgPT4gaXNEYXRhVGFibGVDZWxsRWxlbWVudCh2YWx1ZSkpXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREYXRhU291cmNlQXJyYXlVc2luZ0RhdGFGcm9tQmFja2VuZChcbiAgZGF0YTogSUxpbmtbXSxcbiAgY29sdW1uSWRzOiBzdHJpbmdbXSxcbiAgcmVzb3VyY2VzVHlwZXNJZHM6IHN0cmluZ1tdLFxuICByZXNvdXJjZXNUeXBlczogSnNUYWJsZTxJUmVzb3VyY2VUeXBlPixcbiAgc3F1YXNoQ29sdW1uSWQ6IHN0cmluZ1xuKTogSURhdGFUYWJsZVJvd1tdIHtcbiAgY29uc3QgZGF0YVNvdXJjZTogSURhdGFUYWJsZVJvd1tdID0gZGF0YS5tYXAoKGxpbms6IElMaW5rKSA9PlxuICAgIGNvbHVtbklkcy5yZWR1Y2UoXG4gICAgICAoYWNjLCBjb2x1bW5JZCwgaW5kZXgpID0+IHtcbiAgICAgICAgbGV0IHBhcmVudEVuZHBvaW50OiBzdHJpbmcgPSBudWxsO1xuICAgICAgICBsZXQgZW5kcG9pbnQ6IHN0cmluZyA9IG51bGw7XG4gICAgICAgIGlmIChyZXNvdXJjZXNUeXBlcy5hbGxJZHMuaW5jbHVkZXMoY29sdW1uSWQpKSB7XG4gICAgICAgICAgZW5kcG9pbnQgPSByZXNvdXJjZXNUeXBlcy5ieUlkW2NvbHVtbklkXS5lbmRwb2ludDtcbiAgICAgICAgICBpZiAoaW5kZXggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRSZXNvdXJjZVR5cGVJZDogc3RyaW5nID0gcmVzb3VyY2VzVHlwZXNJZHNbaW5kZXggLSAxXTtcbiAgICAgICAgICAgIGlmIChyZXNvdXJjZXNUeXBlcy5hbGxJZHMuaW5jbHVkZXMocGFyZW50UmVzb3VyY2VUeXBlSWQpKSB7XG4gICAgICAgICAgICAgIHBhcmVudEVuZHBvaW50ID1cbiAgICAgICAgICAgICAgICByZXNvdXJjZXNUeXBlcy5ieUlkW3BhcmVudFJlc291cmNlVHlwZUlkXS5lbmRwb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGluZGV4ID09PSAwICYmIHJlc291cmNlc1R5cGVzSWRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBhY2NbY29sdW1uSWRdLnB1c2goXG4gICAgICAgICAgICBjb252ZXJ0UGFyZW50TGlua1RvRGF0YVRhYmxlQ2VsbEVsZW1lbnQobGluaywgZW5kcG9pbnQpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmICgndmFsdWUnIGluIGxpbmsgJiYgaW5kZXggPiAwKSB7XG4gICAgICAgICAgYWNjID0geyAuLi5hY2MsIFtjb2x1bW5JZF06IGxpbmsudmFsdWUgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhY2NbY29sdW1uSWRdLnB1c2goXG4gICAgICAgICAgICBjb252ZXJ0TGlua1RvRGF0YVRhYmxlQ2VsbEVsZW1lbnQobGluaywgZW5kcG9pbnQsIHBhcmVudEVuZHBvaW50KVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sXG4gICAgICByZXNvdXJjZXNUeXBlc0lkcy5yZWR1Y2UoXG4gICAgICAgIChhY2MsIGN1cnJSZXNvdXJjZVR5cGVJZCkgPT4gKHtcbiAgICAgICAgICAuLi5hY2MsXG4gICAgICAgICAgW2N1cnJSZXNvdXJjZVR5cGVJZF06IFtdLFxuICAgICAgICB9KSxcbiAgICAgICAge31cbiAgICAgIClcbiAgICApXG4gICk7XG4gIHJldHVybiBzcXVhc2hDb2x1bW5JZFxuICAgID8gc3F1YXNoQXJyYXlSb3dzKGRhdGFTb3VyY2UsIHNxdWFzaENvbHVtbklkLCByZXNvdXJjZXNUeXBlc0lkcylcbiAgICA6IGRhdGFTb3VyY2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzcXVhc2hBcnJheVJvd3MoXG4gIGRhdGFTb3VyY2U6IElEYXRhVGFibGVSb3dbXSxcbiAgc3F1YXNoQ29sdW1uSWQ6IHN0cmluZyxcbiAgY29sdW1uSWRzOiBzdHJpbmdbXVxuKTogSURhdGFUYWJsZVJvd1tdIHtcbiAgY29uc3Qgc3F1YXNoZWRBcnJheTogSURhdGFUYWJsZVJvd1tdID0gW107XG4gIGlmIChkYXRhU291cmNlLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBoYW5kbGVkSWRzVmFsdWVzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IHJlbWFpbmluZ0NvbHVtbnNJZHM6IHN0cmluZ1tdID0gY29sdW1uSWRzLmZpbHRlcihcbiAgICAgIChpZDogc3RyaW5nKSA9PiBpZCAhPT0gc3F1YXNoQ29sdW1uSWRcbiAgICApO1xuICAgIGNvbnN0IGFsbFBhcmVudENvbHVtblZhbHVlczoge1xuICAgICAgaW5kZXg6IG51bWJlcjtcbiAgICAgIHZhbHVlOiBzdHJpbmc7XG4gICAgfVtdID0gZGF0YVNvdXJjZS5tYXAoKHJvdzogSURhdGFUYWJsZVJvdywgaW5kZXg6IG51bWJlcikgPT4gKHtcbiAgICAgIGluZGV4LFxuICAgICAgdmFsdWU6IHJvd1tzcXVhc2hDb2x1bW5JZF1bMF0udmFsdWUsXG4gICAgfSkpO1xuICAgIGRhdGFTb3VyY2UuZm9yRWFjaCgocm93OiBJRGF0YVRhYmxlUm93LCByb3dJbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICBpZiAoIWhhbmRsZWRJZHNWYWx1ZXMuaW5jbHVkZXMocm93SW5kZXgpKSB7XG4gICAgICAgIGNvbnN0IG9jY3VyZW5jZXNJbmRleGVzOiBudW1iZXJbXSA9IGFsbFBhcmVudENvbHVtblZhbHVlc1xuICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAoZWx0OiB7IGluZGV4OiBudW1iZXI7IHZhbHVlOiBzdHJpbmcgfSkgPT5cbiAgICAgICAgICAgICAgZWx0LnZhbHVlID09PSByb3dbc3F1YXNoQ29sdW1uSWRdWzBdLnZhbHVlXG4gICAgICAgICAgKVxuICAgICAgICAgIC5tYXAoXG4gICAgICAgICAgICAob2NjdXJlbmNlOiB7IGluZGV4OiBudW1iZXI7IHZhbHVlOiBzdHJpbmcgfSkgPT4gb2NjdXJlbmNlLmluZGV4XG4gICAgICAgICAgKTtcbiAgICAgICAgaWYgKG9jY3VyZW5jZXNJbmRleGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBzcXVhc2hlZEFycmF5LnB1c2goe1xuICAgICAgICAgICAgW3NxdWFzaENvbHVtbklkXTogcm93W3NxdWFzaENvbHVtbklkXSxcbiAgICAgICAgICAgIC4uLnJlbWFpbmluZ0NvbHVtbnNJZHMucmVkdWNlKFxuICAgICAgICAgICAgICAoYWNjLCBjb2x1bW5JZCkgPT4gKHtcbiAgICAgICAgICAgICAgICAuLi5hY2MsXG4gICAgICAgICAgICAgICAgW2NvbHVtbklkXTogb2NjdXJlbmNlc0luZGV4ZXNcbiAgICAgICAgICAgICAgICAgIC5yZWR1Y2UoXG4gICAgICAgICAgICAgICAgICAgIChhY2MsIGluZGV4KSA9PiBhY2MuY29uY2F0KGRhdGFTb3VyY2VbaW5kZXhdW2NvbHVtbklkXSksXG4gICAgICAgICAgICAgICAgICAgIFtdXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAuc29ydCgoYTogSURhdGFUYWJsZUNlbGxFbGVtZW50LCBiOiBJRGF0YVRhYmxlQ2VsbEVsZW1lbnQpID0+XG4gICAgICAgICAgICAgICAgICAgIGEudmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAudG9Mb2NhbGVVcHBlckNhc2UoKVxuICAgICAgICAgICAgICAgICAgICAgIC5sb2NhbGVDb21wYXJlKGIudmFsdWUudG9Mb2NhbGVVcHBlckNhc2UoKSlcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB7fSBhcyB7IFtpZDogc3RyaW5nXTogSURhdGFUYWJsZUNlbGxFbGVtZW50W10gfVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBoYW5kbGVkSWRzVmFsdWVzLnB1c2goLi4ub2NjdXJlbmNlc0luZGV4ZXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhhbmRsZWRJZHNWYWx1ZXMucHVzaChyb3dJbmRleCk7XG4gICAgICAgICAgc3F1YXNoZWRBcnJheS5wdXNoKHJvdyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICByZXR1cm4gc3F1YXNoZWRBcnJheS5zb3J0KChhOiBJRGF0YVNvdXJjZVJvdywgYjogSURhdGFTb3VyY2VSb3cpID0+XG4gICAgKGFbc3F1YXNoQ29sdW1uSWRdIGFzIElEYXRhVGFibGVDZWxsRWxlbWVudFtdKVswXS52YWx1ZVxuICAgICAgLnRvTG9jYWxlVXBwZXJDYXNlKClcbiAgICAgIC5sb2NhbGVDb21wYXJlKFxuICAgICAgICAoXG4gICAgICAgICAgYltzcXVhc2hDb2x1bW5JZF0gYXMgSURhdGFUYWJsZUNlbGxFbGVtZW50W11cbiAgICAgICAgKVswXS52YWx1ZS50b0xvY2FsZVVwcGVyQ2FzZSgpXG4gICAgICApXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRMaW5rVG9EYXRhVGFibGVDZWxsRWxlbWVudChcbiAgYXR0cmlidXRlVmFsdWU6IElMaW5rLFxuICBlbmRwb2ludDogc3RyaW5nLFxuICBwYXJlbnRFbmRwb2ludDogc3RyaW5nID0gbnVsbFxuKTogSURhdGFUYWJsZUNlbGxFbGVtZW50IHwgSUNsaWNrYWJsZURhdGFUYWJsZUNlbGxFbGVtZW50IHtcbiAgbGV0IGNlbGxFbGVtZW50OiBJRGF0YVRhYmxlQ2VsbEVsZW1lbnQgPSB7XG4gICAgaWQ6IGF0dHJpYnV0ZVZhbHVlLmlkLFxuICAgIHZhbHVlOiBhdHRyaWJ1dGVWYWx1ZS5sYWJlbCxcbiAgICBpc0NsaWNrYWJsZTogYXR0cmlidXRlVmFsdWUuY2FuQmVSZWFkLFxuICB9O1xuXG4gIGxldCBjbGlja2FibGVDZWxsRWxlbWVudDogSUNsaWNrYWJsZURhdGFUYWJsZUNlbGxFbGVtZW50O1xuICBpZiAoYXR0cmlidXRlVmFsdWUuY2FuQmVSZWFkKSB7XG4gICAgY2xpY2thYmxlQ2VsbEVsZW1lbnQgPSB7XG4gICAgICAuLi5jZWxsRWxlbWVudCxcbiAgICAgIHJvdXRlckxpbmtWYWx1ZTogZ2V0Um91dGVyTGlua1ZhbHVlKFxuICAgICAgICBlbmRwb2ludCxcbiAgICAgICAgYXR0cmlidXRlVmFsdWUubGFiZWwsXG4gICAgICAgIHBhcmVudEVuZHBvaW50LFxuICAgICAgICBhdHRyaWJ1dGVWYWx1ZS5wYXJlbnRMYWJlbFxuICAgICAgKSxcbiAgICB9O1xuICAgIHJldHVybiBjbGlja2FibGVDZWxsRWxlbWVudDtcbiAgfVxuICByZXR1cm4gY2VsbEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRQYXJlbnRMaW5rVG9EYXRhVGFibGVDZWxsRWxlbWVudChcbiAgYXR0cmlidXRlVmFsdWU6IElMaW5rLFxuICBlbmRwb2ludDogc3RyaW5nXG4pOiBJRGF0YVRhYmxlQ2VsbEVsZW1lbnQgfCBJQ2xpY2thYmxlRGF0YVRhYmxlQ2VsbEVsZW1lbnQge1xuICBsZXQgY2VsbEVsZW1lbnQ6IElEYXRhVGFibGVDZWxsRWxlbWVudCA9IHtcbiAgICBpZDogYXR0cmlidXRlVmFsdWUucGFyZW50SWQsXG4gICAgdmFsdWU6IGF0dHJpYnV0ZVZhbHVlLnBhcmVudExhYmVsLFxuICAgIGlzQ2xpY2thYmxlOiBhdHRyaWJ1dGVWYWx1ZS5wYXJlbnRDYW5CZVJlYWQsXG4gIH07XG5cbiAgbGV0IGNsaWNrYWJsZUNlbGxFbGVtZW50OiBJQ2xpY2thYmxlRGF0YVRhYmxlQ2VsbEVsZW1lbnQ7XG4gIGlmIChhdHRyaWJ1dGVWYWx1ZS5wYXJlbnRDYW5CZVJlYWQpIHtcbiAgICBjbGlja2FibGVDZWxsRWxlbWVudCA9IHtcbiAgICAgIC4uLmNlbGxFbGVtZW50LFxuICAgICAgcm91dGVyTGlua1ZhbHVlOiBnZXRSb3V0ZXJMaW5rVmFsdWUoZW5kcG9pbnQsIGF0dHJpYnV0ZVZhbHVlLnBhcmVudExhYmVsKSxcbiAgICB9O1xuICAgIHJldHVybiBjbGlja2FibGVDZWxsRWxlbWVudDtcbiAgfVxuICByZXR1cm4gY2VsbEVsZW1lbnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREYXRhU291cmNlRm9yR2VuZXJpY0FycmF5KFxuICBkYXRhOiBJRGF0YSxcbiAgc2VsZWN0ZWRSZXNvdXJjZVR5cGVDb25maWc6IElDb25maWcsXG4gIGNsaWNrYWJsZUNlbGxzRW5kcG9pbnRzOiBKc1RhYmxlPHN0cmluZz4gPSBlbXB0eUpzVGFibGUoKSxcbiAgb25seUVkaXRhYmxlUmVzb3VyY2VzID0gZmFsc2Vcbik6IGFueVtdIHtcbiAgbGV0IGZsYXRSZXNvdXJjZXM6IGFueVtdID0gW107XG4gIGlmICghIShkYXRhICYmIGRhdGEuUmVzb3VyY2VzKSkge1xuICAgIGRhdGEuUmVzb3VyY2VzLmZvckVhY2goKGRhdGFSZXNvdXJjZTogYW55KSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGRhdGFSZXNvdXJjZS5tZXRhLmlzRGVsZXRhYmxlIHx8XG4gICAgICAgIGRhdGFSZXNvdXJjZS5tZXRhLmlzTW9kaWZpYWJsZSB8fFxuICAgICAgICAhb25seUVkaXRhYmxlUmVzb3VyY2VzXG4gICAgICApIHtcbiAgICAgICAgZmxhdFJlc291cmNlcy5wdXNoKFxuICAgICAgICAgIGdldERhdGFFbnRyeUZvckdlbmVyaWNBcnJheShcbiAgICAgICAgICAgIGRhdGFSZXNvdXJjZSxcbiAgICAgICAgICAgIHNlbGVjdGVkUmVzb3VyY2VUeXBlQ29uZmlnLFxuICAgICAgICAgICAgY2xpY2thYmxlQ2VsbHNFbmRwb2ludHNcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGZsYXRSZXNvdXJjZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREYXRhRW50cnlGb3JHZW5lcmljQXJyYXkoXG4gIGRhdGFSZXNvdXJjZTogYW55LFxuICByZXNvdXJjZVR5cGVDb25maWc6IElDb25maWcsXG4gIGNsaWNrYWJsZUNlbGxzRW5kcG9pbnRzOiBKc1RhYmxlPHN0cmluZz4gPSBlbXB0eUpzVGFibGUoKVxuKTogYW55IHtcbiAgbGV0IGZsYXRSZXNvdXJjZTogYW55ID0gZ2V0RmxhdFJlc291cmNlKGRhdGFSZXNvdXJjZSwgcmVzb3VyY2VUeXBlQ29uZmlnKTtcbiAgcmV0dXJuIGdldERpc3BsYXllZEF0dHJpYnV0ZVZhbHVlKFxuICAgIGZsYXRSZXNvdXJjZSxcbiAgICBPYmplY3Qua2V5cyhmbGF0UmVzb3VyY2UpLFxuICAgIHJlc291cmNlVHlwZUNvbmZpZyxcbiAgICBjbGlja2FibGVDZWxsc0VuZHBvaW50c1xuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmxhdFJlc291cmNlKFxuICBkYXRhUmVzb3VyY2U6IGFueSxcbiAgcmVzb3VyY2VUeXBlQ29uZmlnOiBJQ29uZmlnXG4pOiBhbnkge1xuICBsZXQgZmxhdFJlc291cmNlOiBhbnkgPSB7fTtcbiAgY29uc3QgYXR0cmlidXRlczogSUF0dHJpYnV0ZVtdID0gcmVzb3VyY2VUeXBlQ29uZmlnLmF0dHJpYnV0ZXM7XG4gIGNvbnN0IHNjaW1QYXJlbnRzQW5kQ2hpbGRyZW46IHtcbiAgICBbaWQ6IHN0cmluZ106IHN0cmluZ1tdO1xuICB9ID0gZ2V0U2NpbVBhcmVudHNBbmRDaGlsZHJlbihhdHRyaWJ1dGVzKTtcbiAgZm9yIChjb25zdCBzY2ltUGFyZW50SWQgaW4gc2NpbVBhcmVudHNBbmRDaGlsZHJlbikge1xuICAgIGlmIChcbiAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzY2ltUGFyZW50c0FuZENoaWxkcmVuLCBzY2ltUGFyZW50SWQpXG4gICAgKSB7XG4gICAgICBzY2ltUGFyZW50c0FuZENoaWxkcmVuW3NjaW1QYXJlbnRJZF1cbiAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAoY2hpbGRJZDogc3RyaW5nKSA9PlxuICAgICAgICAgICAgISEoXG4gICAgICAgICAgICAgIGRhdGFSZXNvdXJjZVtzY2ltUGFyZW50SWRdICYmIGRhdGFSZXNvdXJjZVtzY2ltUGFyZW50SWRdW2NoaWxkSWRdXG4gICAgICAgICAgICApXG4gICAgICAgIClcbiAgICAgICAgLmZvckVhY2goXG4gICAgICAgICAgKGNoaWxkSWQ6IHN0cmluZykgPT5cbiAgICAgICAgICAgIChmbGF0UmVzb3VyY2UgPSB7XG4gICAgICAgICAgICAgIC4uLmZsYXRSZXNvdXJjZSxcbiAgICAgICAgICAgICAgW2NoaWxkSWRdOiBkYXRhUmVzb3VyY2Vbc2NpbVBhcmVudElkXVtjaGlsZElkXSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuICB9XG4gIGxldCBzY2ltUGFyZW50SWRzOiBzdHJpbmdbXSA9IE9iamVjdC5rZXlzKHNjaW1QYXJlbnRzQW5kQ2hpbGRyZW4pO1xuICBjb25zdCBkYXRhUmVzb3VyY2VXaXRob3V0U2NpbVBhcmVudElkczoge1xuICAgIFtpZDogc3RyaW5nXTogYW55O1xuICB9ID0gT2JqZWN0LmtleXMoZGF0YVJlc291cmNlKS5yZWR1Y2UoKGFjYywgZmllbGRJZCkgPT4ge1xuICAgIGlmICghc2NpbVBhcmVudElkcy5pbmNsdWRlcyhmaWVsZElkKSkge1xuICAgICAgYWNjID0geyAuLi5hY2MsIFtmaWVsZElkXTogZGF0YVJlc291cmNlW2ZpZWxkSWRdIH07XG4gICAgfVxuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcbiAgZmxhdFJlc291cmNlID0geyAuLi5mbGF0UmVzb3VyY2UsIC4uLmRhdGFSZXNvdXJjZVdpdGhvdXRTY2ltUGFyZW50SWRzIH07XG5cbiAgcmV0dXJuIGZsYXRSZXNvdXJjZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERpc3BsYXllZEF0dHJpYnV0ZVZhbHVlKFxuICBkYXRhUmVzb3VyY2U6IGFueSxcbiAgZGF0YVJlc291cmNlS2V5czogc3RyaW5nW10sXG4gIHJlc291cmNlVHlwZUNvbmZpZzogSUNvbmZpZyxcbiAgY2xpY2thYmxlQ2VsbHNFbmRwb2ludHM6IEpzVGFibGU8c3RyaW5nPiA9IGVtcHR5SnNUYWJsZSgpXG4pOiBhbnkge1xuICBsZXQgcmVzb3VyY2U6IGFueSA9IHt9O1xuICBjb25zdCBhdHRyaWJ1dGVzOiBJQXR0cmlidXRlW10gPSByZXNvdXJjZVR5cGVDb25maWcuYXR0cmlidXRlcztcbiAgZGF0YVJlc291cmNlS2V5cy5mb3JFYWNoKChrZXk6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IGN1cnJlbnRBdHRyaWJ1dGU6IElBdHRyaWJ1dGUgPSBhdHRyaWJ1dGVzLmZpbmQoXG4gICAgICAoYXR0cmlidXRlQ29uZmlnKSA9PiBhdHRyaWJ1dGVDb25maWcubW9kZWxSZWYgPT09IGtleVxuICAgICk7XG4gICAgY29uc3QgaXNTaW1wbGVBdHRyaWJ1dGU6IGJvb2xlYW4gPVxuICAgICAgIUFycmF5LmlzQXJyYXkoZGF0YVJlc291cmNlW2tleV0pICYmIGRhdGFSZXNvdXJjZVtrZXldICE9PSBudWxsO1xuICAgIGNvbnN0IGlzQXR0cmlidXRlQXJyYXk6IGJvb2xlYW4gPVxuICAgICAgQXJyYXkuaXNBcnJheShkYXRhUmVzb3VyY2Vba2V5XSkgJiYgZGF0YVJlc291cmNlW2tleV0ubGVuZ3RoID49IDA7XG4gICAgY29uc3QgaXNBdHRyaWJ1dGVBcnJheVdpdGhEYXRhT2ZPdGhlclNjaW1UeXBlOiBib29sZWFuID0gISFjdXJyZW50QXR0cmlidXRlXG4gICAgICA/IEFycmF5LmlzQXJyYXkoZGF0YVJlc291cmNlW2tleV0pICYmXG4gICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcbiAgICAgICAgICBjdXJyZW50QXR0cmlidXRlLFxuICAgICAgICAgICdnZXREYXRhTGlzdFBhcmFtcydcbiAgICAgICAgKSAmJlxuICAgICAgICAhY3VycmVudEF0dHJpYnV0ZS5wcm9wcy5pc1VzaW5nRGF0YUZyb21CYWNrZW5kXG4gICAgICA6IGZhbHNlO1xuICAgIGlmIChcbiAgICAgIGlzU2ltcGxlQXR0cmlidXRlIHx8XG4gICAgICBpc0F0dHJpYnV0ZUFycmF5IHx8XG4gICAgICBpc0F0dHJpYnV0ZUFycmF5V2l0aERhdGFPZk90aGVyU2NpbVR5cGVcbiAgICApIHtcbiAgICAgIHJlc291cmNlID0ge1xuICAgICAgICAuLi5yZXNvdXJjZSxcbiAgICAgICAgW2tleV06IGNsaWNrYWJsZUNlbGxzRW5kcG9pbnRzLmFsbElkcy5pbmNsdWRlcyhrZXkpXG4gICAgICAgICAgPyBnZXRBdHRyaWJ1dGVWYWx1ZUFzQXJyYXlPZkRhdGFUYWJsZUNlbGxFbGVtZW50KFxuICAgICAgICAgICAgICBkYXRhUmVzb3VyY2Vba2V5XSxcbiAgICAgICAgICAgICAgY2xpY2thYmxlQ2VsbHNFbmRwb2ludHMuYnlJZFtrZXldXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiBnZXRBdHRyaWJ1dGVWYWx1ZShkYXRhUmVzb3VyY2Vba2V5XSksXG4gICAgICB9O1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXNvdXJjZTtcbn1cblxuZnVuY3Rpb24gZ2V0QXR0cmlidXRlVmFsdWVBc0FycmF5T2ZEYXRhVGFibGVDZWxsRWxlbWVudChcbiAgYXR0cmlidXRlVmFsdWU6IElMaW5rIHwgSUxpbmtbXSxcbiAgY2VsbEVuZHBvaW50OiBzdHJpbmdcbik6IElEYXRhVGFibGVDZWxsRWxlbWVudFtdIHtcbiAgbGV0IGRpc3BsYXllZEF0dHJpYnV0ZVZhbHVlOiBJRGF0YVRhYmxlQ2VsbEVsZW1lbnRbXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXR0cmlidXRlVmFsdWUpKSB7XG4gICAgZGlzcGxheWVkQXR0cmlidXRlVmFsdWUgPSBhdHRyaWJ1dGVWYWx1ZS5tYXAoKHZhbHVlOiBJTGluaykgPT5cbiAgICAgIGNvbnZlcnRMaW5rVG9EYXRhVGFibGVDZWxsRWxlbWVudCh2YWx1ZSwgY2VsbEVuZHBvaW50KVxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgZGlzcGxheWVkQXR0cmlidXRlVmFsdWUgPSBbXG4gICAgICBjb252ZXJ0TGlua1RvRGF0YVRhYmxlQ2VsbEVsZW1lbnQoYXR0cmlidXRlVmFsdWUsIGNlbGxFbmRwb2ludCksXG4gICAgXTtcbiAgfVxuICByZXR1cm4gZGlzcGxheWVkQXR0cmlidXRlVmFsdWU7XG59XG5cbmZ1bmN0aW9uIGdldEF0dHJpYnV0ZVZhbHVlKFxuICBhdHRyaWJ1dGVWYWx1ZTogc3RyaW5nIHwgc3RyaW5nW10gfCBib29sZWFuIHwgSUxpbmsgfCBJTGlua1tdXG4pIHtcbiAgbGV0IGRpc3BsYXllZEF0dHJpYnV0ZVZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSB8IGJvb2xlYW47XG4gIGlmIChpc0xpbmtPYmplY3QoYXR0cmlidXRlVmFsdWUpKSB7XG4gICAgZGlzcGxheWVkQXR0cmlidXRlVmFsdWUgPSAoYXR0cmlidXRlVmFsdWUgYXMgSUxpbmspLmxhYmVsO1xuICB9IGVsc2UgaWYgKGlzQXJyYXlPZkxpbmtPYmplY3RzKGF0dHJpYnV0ZVZhbHVlKSkge1xuICAgIGRpc3BsYXllZEF0dHJpYnV0ZVZhbHVlID0gKGF0dHJpYnV0ZVZhbHVlIGFzIElMaW5rW10pLm1hcChcbiAgICAgICh2YWx1ZTogSUxpbmspID0+IHZhbHVlLmxhYmVsXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICBkaXNwbGF5ZWRBdHRyaWJ1dGVWYWx1ZSA9IGF0dHJpYnV0ZVZhbHVlIGFzIHN0cmluZyB8IHN0cmluZ1tdIHwgYm9vbGVhbjtcbiAgfVxuICByZXR1cm4gZGlzcGxheWVkQXR0cmlidXRlVmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0FycmF5T2ZMaW5rT2JqZWN0cyhhdHRyaWJ1dGVWYWx1ZTogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgQXJyYXkuaXNBcnJheShhdHRyaWJ1dGVWYWx1ZSkgJiZcbiAgICBhdHRyaWJ1dGVWYWx1ZS5sZW5ndGggPiAwICYmXG4gICAgYXR0cmlidXRlVmFsdWUuZXZlcnkoKHZhbHVlOiBhbnkpID0+IGlzTGlua09iamVjdCh2YWx1ZSkpXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRPcmRlcmVkS2V5c0FycmF5QXR0cmlidXRlcyhcbiAgYXR0cmlidXRlczogSUF0dHJpYnV0ZVtdLFxuICBkYXRhUmVzb3VyY2U6IGFueVxuKTogc3RyaW5nW10ge1xuICBjb25zdCBhdHRyaWJ1dGVJZHM6IHN0cmluZ1tdID0gYXR0cmlidXRlcy5tYXAoXG4gICAgKGF0dHJpYnV0ZSkgPT4gYXR0cmlidXRlLm1vZGVsUmVmXG4gICk7XG4gIGxldCBrZXlzOiBzdHJpbmdbXSA9IF8uaW50ZXJzZWN0aW9uKFxuICAgIGF0dHJpYnV0ZUlkcyxcbiAgICBPYmplY3Qua2V5cyhkYXRhUmVzb3VyY2UpXG4gICkuZmlsdGVyKFxuICAgIChrZXkpID0+IGRhdGFSZXNvdXJjZVtrZXldICE9PSB1bmRlZmluZWQgJiYgZGF0YVJlc291cmNlW2tleV0gIT09IG51bGxcbiAgKTtcbiAgY29uc3Qgb3JkZXJLZXlzQnlBdHRyaWJ1dGVJZDogc3RyaW5nW10gPSBrZXlzLnNvcnQoKGEsIGIpID0+IHtcbiAgICByZXR1cm4gYXR0cmlidXRlSWRzLmluZGV4T2YoYSkgLSBhdHRyaWJ1dGVJZHMuaW5kZXhPZihiKTtcbiAgfSk7XG4gIHJldHVybiBvcmRlcktleXNCeUF0dHJpYnV0ZUlkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGlzcGxheWVkQ29sdW1uc0lkcyhyZXNvdXJjZVR5cGVDb25maWc6IElDb25maWcpOiBzdHJpbmdbXSB7XG4gIGxldCBkaXNwbGF5ZWRDb2x1bW5zOiBzdHJpbmdbXSA9IFtdO1xuICBpZiAoISFyZXNvdXJjZVR5cGVDb25maWcucHJvcHM/LmNvbHVtbnMpIHtcbiAgICBkaXNwbGF5ZWRDb2x1bW5zID0gcmVzb3VyY2VUeXBlQ29uZmlnLnByb3BzLmNvbHVtbnMucmVkdWNlKFxuICAgICAgKGFjYywgY29sdW1uKSA9PiBbLi4uYWNjLCBjb2x1bW4uaWRGb3JTZWFyY2ggfHwgY29sdW1uLmlkXSxcbiAgICAgIFtdXG4gICAgKTtcbiAgfVxuICByZXR1cm4gZGlzcGxheWVkQ29sdW1ucztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE9yZGVyZWRLZXlzU2ltcGxlQXR0cmlidXRlcyhcbiAgYXR0cmlidXRlczogSUF0dHJpYnV0ZVtdLFxuICBkYXRhUmVzb3VyY2U6IGFueVxuKTogc3RyaW5nW10ge1xuICBjb25zdCBhdHRyaWJ1dGVJZHM6IHN0cmluZ1tdID0gYXR0cmlidXRlcy5tYXAoXG4gICAgKGF0dHJpYnV0ZSkgPT4gYXR0cmlidXRlLm1vZGVsUmVmXG4gICk7XG4gIC8vIFJlbW92ZSBcInNjaGVtYVwiIHByb3BlcnR5IGZyb20gZGF0YURldGFpbHMgYXMgaXQgaXMgbm9uIHVzZWZ1bCBmb3IgdGhlIEZyb250LUVuZFxuICBsZXQga2V5czogc3RyaW5nW10gPSBfLmludGVyc2VjdGlvbihcbiAgICBhdHRyaWJ1dGVJZHMsXG4gICAgT2JqZWN0LmtleXMoZGF0YVJlc291cmNlKVxuICApLmZpbHRlcigoa2V5KSA9PiB7XG4gICAgY29uc3QgYXR0cmlidXRlQ29uZmlnID0gYXR0cmlidXRlcy5maW5kKFxuICAgICAgKGF0dHJpYnV0ZTogSUF0dHJpYnV0ZSkgPT4gYXR0cmlidXRlLm1vZGVsUmVmID09PSBrZXlcbiAgICApO1xuICAgIGNvbnN0IGlzSW5wdXRDaGlwc0F1dG9jb21wbGV0ZTogYm9vbGVhbiA9XG4gICAgICAhIWF0dHJpYnV0ZUNvbmZpZyAmJlxuICAgICAgYXR0cmlidXRlQ29uZmlnLnZhbHVlLmZpZWxkLmNvbXBvbmVudE5hbWUgPT09XG4gICAgICAgIEVDb21wb25lbnROYW1lLmlucHV0Q2hpcHNBdXRvY29tcGxldGU7XG5cbiAgICBjb25zdCBpc0lucHV0Q2hpcHNBdXRvY29tcGxldGVXaXRoVmFsdWVzOiBib29sZWFuID1cbiAgICAgIGlzSW5wdXRDaGlwc0F1dG9jb21wbGV0ZSAmJlxuICAgICAgISFkYXRhUmVzb3VyY2Vba2V5XSAmJlxuICAgICAgZGF0YVJlc291cmNlW2tleV0ubGVuZ3RoID4gMDtcblxuICAgIGNvbnN0IGlzSW5wdXQ6IGJvb2xlYW4gPVxuICAgICAgISFhdHRyaWJ1dGVDb25maWcgJiZcbiAgICAgIGF0dHJpYnV0ZUNvbmZpZy52YWx1ZS5maWVsZC5jb21wb25lbnROYW1lID09PSBFQ29tcG9uZW50TmFtZS5pbnB1dDtcblxuICAgIGNvbnN0IGlzSW5wdXRXaXRoVmFsdWVBc0FycmF5ID1cbiAgICAgIGlzSW5wdXQgJiYgISFkYXRhUmVzb3VyY2Vba2V5XSAmJiBBcnJheS5pc0FycmF5KGRhdGFSZXNvdXJjZVtrZXldKTtcblxuICAgIGNvbnN0IGlzSW5wdXRXaXRoVmFsdWVBc05vdEVtcHR5QXJyYXk6IGJvb2xlYW4gPVxuICAgICAgaXNJbnB1dFdpdGhWYWx1ZUFzQXJyYXkgJiYgZGF0YVJlc291cmNlW2tleV0ubGVuZ3RoID4gMDtcblxuICAgIHJldHVybiAoXG4gICAgICBkYXRhUmVzb3VyY2Vba2V5XSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICBkYXRhUmVzb3VyY2Vba2V5XSAhPT0gbnVsbCAmJlxuICAgICAgKGlzSW5wdXRDaGlwc0F1dG9jb21wbGV0ZVdpdGhWYWx1ZXMgfHxcbiAgICAgICAgaXNJbnB1dFdpdGhWYWx1ZUFzTm90RW1wdHlBcnJheSB8fFxuICAgICAgICAhKGlzSW5wdXRXaXRoVmFsdWVBc0FycmF5IHx8IGlzSW5wdXRDaGlwc0F1dG9jb21wbGV0ZSkpXG4gICAgKTtcbiAgfSk7XG4gIGNvbnN0IG9yZGVyS2V5c0J5QXR0cmlidXRlSWQ6IHN0cmluZ1tdID0ga2V5cy5zb3J0KChhLCBiKSA9PiB7XG4gICAgcmV0dXJuIGF0dHJpYnV0ZUlkcy5pbmRleE9mKGEpIC0gYXR0cmlidXRlSWRzLmluZGV4T2YoYik7XG4gIH0pO1xuICByZXR1cm4gb3JkZXJLZXlzQnlBdHRyaWJ1dGVJZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbkRlbGV0ZUVudHJ5KFxuICBhcnJheUFjdGlvbnM6IElQcmltaXRpdmVBY3Rpb25zIHwgSUF0dHJpYnV0ZUFjdGlvbnMsXG4gIGlzU2VsZWN0T25seU1vZGVFbmFibGVkOiBib29sZWFuLFxuICBpc0VkaXRhYmxlUm93OiBib29sZWFuXG4pOiBib29sZWFuIHtcbiAgY29uc3QgaXNEZWxldGVBY3Rpb25BdmFpbGFibGU6IGJvb2xlYW4gPVxuICAgIGFycmF5QWN0aW9ucyAmJiBFRWxsaXBzaXNNZW51QWN0aW9ucy5TSU5HTEVfREVMRVRFIGluIGFycmF5QWN0aW9ucztcbiAgcmV0dXJuIGlzRGVsZXRlQWN0aW9uQXZhaWxhYmxlICYmIGlzRWRpdGFibGVSb3cgJiYgIWlzU2VsZWN0T25seU1vZGVFbmFibGVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FuTW92ZUVudHJ5KFxuICBhcnJheUFjdGlvbnM6IElQcmltaXRpdmVBY3Rpb25zIHwgSUF0dHJpYnV0ZUFjdGlvbnMsXG4gIGNhbkFzc2lnbk9yTW92ZUVudHJpZXM6IGJvb2xlYW4sXG4gIGlzU2VsZWN0T25seU1vZGVFbmFibGVkOiBib29sZWFuLFxuICBpc0VkaXRhYmxlUm93OiBib29sZWFuXG4pOiBib29sZWFuIHtcbiAgY29uc3QgYXJlTW92ZUFjdGlvbnNBdmFpbGFibGU6IGJvb2xlYW4gPVxuICAgIGFycmF5QWN0aW9ucyAmJlxuICAgIChFRWxsaXBzaXNNZW51QWN0aW9ucy5TSU5HTEVfVU5BU1NJR04gaW4gYXJyYXlBY3Rpb25zIHx8XG4gICAgICBFRWxsaXBzaXNNZW51QWN0aW9ucy5TSU5HTEVfUkVBU1NJR04gaW4gYXJyYXlBY3Rpb25zKTtcbiAgcmV0dXJuIChcbiAgICBhcmVNb3ZlQWN0aW9uc0F2YWlsYWJsZSAmJlxuICAgIGNhbkFzc2lnbk9yTW92ZUVudHJpZXMgJiZcbiAgICBpc0VkaXRhYmxlUm93ICYmXG4gICAgIWlzU2VsZWN0T25seU1vZGVFbmFibGVkXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZWxlY3RlZEVsZW1lbnRJZHMoXG4gIHJvdzogYW55LFxuICBzZWxlY3Rpb25Db2x1bW5JZDogc3RyaW5nXG4pOiBJVWlFbnRyeUlkcyB7XG4gIGxldCBleHRlcm5hbElkOiBzdHJpbmc7XG4gIGlmICghIXNlbGVjdGlvbkNvbHVtbklkKSB7XG4gICAgY29uc3QgY2VsbEVsdDogYW55ID0gcm93W3NlbGVjdGlvbkNvbHVtbklkXTtcbiAgICBpZiAoaXNBcnJheU9mRGF0YVRhYmxlQ2VsbEVsZW1lbnRzKGNlbGxFbHQpICYmIGNlbGxFbHQubGVuZ3RoID09PSAxKSB7XG4gICAgICBleHRlcm5hbElkID0gY2VsbEVsdFswXS52YWx1ZTtcbiAgICAgIHJldHVybiB7IGlkOiBjZWxsRWx0WzBdLmlkLCBleHRlcm5hbElkLCBsYWJlbDogZXh0ZXJuYWxJZCB9O1xuICAgIH0gZWxzZSBpZiAoaXNEYXRhVGFibGVDZWxsRWxlbWVudChjZWxsRWx0KSkge1xuICAgICAgZXh0ZXJuYWxJZCA9IGNlbGxFbHQudmFsdWU7XG4gICAgICByZXR1cm4geyBpZDogY2VsbEVsdC5pZCwgZXh0ZXJuYWxJZCwgbGFiZWw6IGV4dGVybmFsSWQgfTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZXh0ZXJuYWxJZCA9IHJvdy5leHRlcm5hbElkO1xuICAgIHJldHVybiB7IGlkOiByb3cuaWQsIGV4dGVybmFsSWQsIGxhYmVsOiBleHRlcm5hbElkIH07XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVwZGF0ZWREaXNwbGF5ZWRDb2x1bW5zKFxuICBhcnJheUFjdGlvbnM6IElQcmltaXRpdmVBY3Rpb25zIHwgSUF0dHJpYnV0ZUFjdGlvbnMsXG4gIGluaXRpYWxEaXNwbGF5ZWRDb2x1bW5zOiBzdHJpbmdbXSxcbiAgaXNTZWxlY3RPbmx5TW9kZUVuYWJsZWQ6IGJvb2xlYW4sXG4gIGNhbkFzc2lnbk9yTW92ZUVudHJpZXM6IGJvb2xlYW4sXG4gIGlzRWRpdGFibGVBcnJheTogYm9vbGVhbixcbiAgdXBkYXRlQWZmZWN0QW5vdGhlclJlc291cmNlVHlwZTogYm9vbGVhbixcbiAgaXNBdHRyaWJ1dGVBcnJheTogYm9vbGVhbixcbiAgZGF0YTogYW55W10gfCBJRGF0YVRhYmxlUm93W11cbik6IHN0cmluZ1tdIHtcbiAgbGV0IHVwZGF0ZURpc3BsYXllZENvbHVtbnM6IHN0cmluZ1tdID0gW1xuICAgIC4uLmluaXRpYWxEaXNwbGF5ZWRDb2x1bW5zLmZpbHRlcigoY29sdW1uSWQ6IHN0cmluZykgPT5cbiAgICAgIGRhdGEuc29tZSgocm93OiBhbnkpID0+IGNvbHVtbklkIGluIHJvdylcbiAgICApLFxuICBdO1xuICBjb25zdCBhZGRpdGlvbm5hbENvbHVtbnNUb0Rpc3BsYXk6IHN0cmluZ1tdID0gWydzZWxlY3QnLCAnYWN0aW9ucyddO1xuXG4gIGNvbnN0IGhhc09uZURlbGV0YWJsZUVudHJ5OiBib29sZWFuID0gZGF0YS5zb21lKFxuICAgIChyb3c6IGFueSB8IElEYXRhVGFibGVSb3cpID0+IHJvdy5tZXRhPy5pc0RlbGV0YWJsZVxuICApO1xuXG4gIGNvbnN0IGhhc09uZUVkaXRhYmxlRW50cnk6IGJvb2xlYW4gPSBkYXRhLnNvbWUoXG4gICAgKHJvdzogYW55IHwgSURhdGFUYWJsZVJvdykgPT4gcm93LmlzUm93RWRpdGFibGVcbiAgKTtcblxuICBpZiAoIWlzU2VsZWN0T25seU1vZGVFbmFibGVkICYmIGRhdGEubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGNhbkRlbGV0ZTogYm9vbGVhbiA9IGNhbkRlbGV0ZUVudHJpZXMoXG4gICAgICBhcnJheUFjdGlvbnMsXG4gICAgICBoYXNPbmVEZWxldGFibGVFbnRyeVxuICAgICk7XG4gICAgY29uc3QgY2FuTW92ZTogYm9vbGVhbiA9IGNhbk1vdmVFbnRyaWVzKFxuICAgICAgYXJyYXlBY3Rpb25zLFxuICAgICAgY2FuQXNzaWduT3JNb3ZlRW50cmllcyxcbiAgICAgIGhhc09uZUVkaXRhYmxlRW50cnlcbiAgICApO1xuICAgIGNvbnN0IGlzRWRpdGFibGVBdHRyaWJ1dGVBcnJheSA9XG4gICAgICBpc0VkaXRhYmxlQXJyYXkgJiZcbiAgICAgIChjYW5Nb3ZlIHx8IGNhbkRlbGV0ZSB8fCAhdXBkYXRlQWZmZWN0QW5vdGhlclJlc291cmNlVHlwZSk7XG5cbiAgICBpZiAoXG4gICAgICAoaXNBdHRyaWJ1dGVBcnJheSAmJiBpc0VkaXRhYmxlQXR0cmlidXRlQXJyYXkpIHx8XG4gICAgICAoIWlzQXR0cmlidXRlQXJyYXkgJiYgY2FuRGVsZXRlKVxuICAgICkge1xuICAgICAgdXBkYXRlRGlzcGxheWVkQ29sdW1ucy51bnNoaWZ0KGFkZGl0aW9ubmFsQ29sdW1uc1RvRGlzcGxheVswXSk7XG4gICAgICB1cGRhdGVEaXNwbGF5ZWRDb2x1bW5zLnB1c2goYWRkaXRpb25uYWxDb2x1bW5zVG9EaXNwbGF5WzFdKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaGFzT25lRGVsZXRhYmxlRW50cnkgfHwgaGFzT25lRWRpdGFibGVFbnRyeSkge1xuICAgIHVwZGF0ZURpc3BsYXllZENvbHVtbnMudW5zaGlmdChhZGRpdGlvbm5hbENvbHVtbnNUb0Rpc3BsYXlbMF0pO1xuICB9XG4gIHJldHVybiB1cGRhdGVEaXNwbGF5ZWRDb2x1bW5zO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FuTW92ZUVudHJpZXMoXG4gIGFycmF5QWN0aW9uczogSVByaW1pdGl2ZUFjdGlvbnMgfCBJQXR0cmlidXRlQWN0aW9ucyxcbiAgY2FuQXNzaWduT3JNb3ZlRW50cmllczogYm9vbGVhbixcbiAgaGFzT25lRGVsZXRhYmxlRW50cnk6IGJvb2xlYW5cbik6IGJvb2xlYW4ge1xuICBjb25zdCBhcmVNb3ZlQWN0aW9uc0F2YWlsYWJsZTogYm9vbGVhbiA9XG4gICAgYXJyYXlBY3Rpb25zICYmXG4gICAgKEVFbGxpcHNpc01lbnVBY3Rpb25zLk1VTFRJUExFX1VOQVNTSUdOIGluIGFycmF5QWN0aW9ucyB8fFxuICAgICAgRUVsbGlwc2lzTWVudUFjdGlvbnMuTVVMVElQTEVfUkVBU1NJR04gaW4gYXJyYXlBY3Rpb25zKTtcbiAgcmV0dXJuIChcbiAgICBhcmVNb3ZlQWN0aW9uc0F2YWlsYWJsZSAmJiBjYW5Bc3NpZ25Pck1vdmVFbnRyaWVzICYmIGhhc09uZURlbGV0YWJsZUVudHJ5XG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1Jvd0VkaXRhYmxlKFxuICBpc0F0dHJpYnV0ZUFycmF5OiBib29sZWFuLFxuICB1cGRhdGVBZmZlY3RBbm90aGVyUmVzb3VyY2VUeXBlOiBib29sZWFuLFxuICBmaWVsZEZvclVwZGF0ZTogc3RyaW5nLFxuICBpc0VkaXRhYmxlQXJyYXk6IGJvb2xlYW4sXG4gIHJvdzogYW55XG4pOiBib29sZWFuIHtcbiAgY29uc3QgaXNVcGRhdGVBZmZlY3RpbmdBbm90aGVyUmVzb3VyY2VUeXBlID1cbiAgICBpc0F0dHJpYnV0ZUFycmF5ICYmIHVwZGF0ZUFmZmVjdEFub3RoZXJSZXNvdXJjZVR5cGU7XG5cbiAgY29uc3QgaXNVcGRhdGVBZmZlY3RpbmdPbmx5Q3VycmVudFJlc291cmNlVHlwZSA9XG4gICAgaXNBdHRyaWJ1dGVBcnJheSAmJlxuICAgICF1cGRhdGVBZmZlY3RBbm90aGVyUmVzb3VyY2VUeXBlICYmXG4gICAgZmllbGRGb3JVcGRhdGUgPT0gbnVsbDtcblxuICBpZiAoaXNVcGRhdGVBZmZlY3RpbmdBbm90aGVyUmVzb3VyY2VUeXBlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHJvdy5tZXRhLmlzTW9kaWZpYWJsZSAmJlxuICAgICAgcm93Lm1ldGEubW9kaWZpYWJsZUF0dHJpYnV0ZXMuaW5jbHVkZXMoZmllbGRGb3JVcGRhdGUpXG4gICAgKTtcbiAgfSBlbHNlIGlmIChpc1VwZGF0ZUFmZmVjdGluZ09ubHlDdXJyZW50UmVzb3VyY2VUeXBlKSB7XG4gICAgcmV0dXJuIGlzRWRpdGFibGVBcnJheTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcm93Lm1ldGE/LmlzRGVsZXRhYmxlO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzb3J0RGF0YShkYXRhOiBhbnlbXSwgc29ydDogTWF0U29ydCk6IGFueVtdIHtcbiAgY29uc3QgYWN0aXZlID0gc29ydC5hY3RpdmU7XG4gIGNvbnN0IGRpcmVjdGlvbiA9IHNvcnQuZGlyZWN0aW9uO1xuICBpZiAoIWFjdGl2ZSB8fCBkaXJlY3Rpb24gPT09ICcnKSB7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICByZXR1cm4gZGF0YS5zb3J0KChhLCBiKSA9PiB7XG4gICAgbGV0IHZhbHVlQSA9IHNvcnRpbmdEYXRhQWNjZXNzb3IoYSwgYWN0aXZlKTtcbiAgICBsZXQgdmFsdWVCID0gc29ydGluZ0RhdGFBY2Nlc3NvcihiLCBhY3RpdmUpO1xuXG4gICAgLy8gSWYgdGhlcmUgYXJlIGRhdGEgaW4gdGhlIGNvbHVtbiB0aGF0IGNhbiBiZSBjb252ZXJ0ZWQgdG8gYSBudW1iZXIsXG4gICAgLy8gaXQgbXVzdCBiZSBlbnN1cmVkIHRoYXQgdGhlIHJlc3Qgb2YgdGhlIGRhdGFcbiAgICAvLyBpcyBvZiB0aGUgc2FtZSB0eXBlIHNvIGFzIG5vdCB0byBvcmRlciBpbmNvcnJlY3RseS5cbiAgICBjb25zdCB2YWx1ZUFUeXBlID0gdHlwZW9mIHZhbHVlQTtcbiAgICBjb25zdCB2YWx1ZUJUeXBlID0gdHlwZW9mIHZhbHVlQjtcblxuICAgIGlmICh2YWx1ZUFUeXBlICE9PSB2YWx1ZUJUeXBlKSB7XG4gICAgICBpZiAodmFsdWVBVHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgdmFsdWVBICs9ICcnO1xuICAgICAgfVxuICAgICAgaWYgKHZhbHVlQlR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgIHZhbHVlQiArPSAnJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiBib3RoIHZhbHVlQSBhbmQgdmFsdWVCIGV4aXN0ICh0cnV0aHkpLCB0aGVuIGNvbXBhcmUgdGhlIHR3by4gT3RoZXJ3aXNlLCBjaGVjayBpZlxuICAgIC8vIG9uZSB2YWx1ZSBleGlzdHMgd2hpbGUgdGhlIG90aGVyIGRvZXNuJ3QuIEluIHRoaXMgY2FzZSwgZXhpc3RpbmcgdmFsdWUgc2hvdWxkIGNvbWUgbGFzdC5cbiAgICAvLyBUaGlzIGF2b2lkcyBpbmNvbnNpc3RlbnQgcmVzdWx0cyB3aGVuIGNvbXBhcmluZyB2YWx1ZXMgdG8gdW5kZWZpbmVkL251bGwuXG4gICAgLy8gSWYgbmVpdGhlciB2YWx1ZSBleGlzdHMsIHJldHVybiAwIChlcXVhbCkuXG4gICAgbGV0IGNvbXBhcmF0b3JSZXN1bHQgPSAwO1xuICAgIGlmICh2YWx1ZUEgIT0gbnVsbCAmJiB2YWx1ZUIgIT0gbnVsbCkge1xuICAgICAgLy8gQ2hlY2sgaWYgb25lIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgb3RoZXI7IGlmIGVxdWFsLCBjb21wYXJhdG9yUmVzdWx0IHNob3VsZCByZW1haW4gMC5cbiAgICAgIGlmICh2YWx1ZUEgPiB2YWx1ZUIpIHtcbiAgICAgICAgY29tcGFyYXRvclJlc3VsdCA9IDE7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlQSA8IHZhbHVlQikge1xuICAgICAgICBjb21wYXJhdG9yUmVzdWx0ID0gLTE7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh2YWx1ZUEgIT0gbnVsbCkge1xuICAgICAgY29tcGFyYXRvclJlc3VsdCA9IDE7XG4gICAgfSBlbHNlIGlmICh2YWx1ZUIgIT0gbnVsbCkge1xuICAgICAgY29tcGFyYXRvclJlc3VsdCA9IC0xO1xuICAgIH1cblxuICAgIHJldHVybiBjb21wYXJhdG9yUmVzdWx0ICogKGRpcmVjdGlvbiA9PT0gJ2FzYycgPyAxIDogLTEpO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNvcnRpbmdEYXRhQWNjZXNzb3IoXG4gIGRhdGE6IGFueVtdLFxuICBzb3J0SGVhZGVySWQ6IHN0cmluZ1xuKTogc3RyaW5nIHwgbnVtYmVyIHtcbiAgbGV0IHZhbHVlID0gKGRhdGEgYXMgeyBba2V5OiBzdHJpbmddOiBhbnkgfSlbc29ydEhlYWRlcklkXTtcbiAgdmFsdWUgPVxuICAgIEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA+IDBcbiAgICAgID8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlWzBdLCAndmFsdWUnKVxuICAgICAgICA/IHZhbHVlWzBdLnZhbHVlXG4gICAgICAgIDogbnVsbFxuICAgICAgOiB2YWx1ZTtcblxuICBpZiAoX2lzTnVtYmVyVmFsdWUodmFsdWUpKSB7XG4gICAgY29uc3QgbnVtYmVyVmFsdWUgPSBOdW1iZXIodmFsdWUpO1xuXG4gICAgLy8gTnVtYmVycyBiZXlvbmQgYE1BWF9TQUZFX0lOVEVHRVJgIGNhbid0IGJlIGNvbXBhcmVkIHJlbGlhYmx5IHNvIHdlXG4gICAgLy8gbGVhdmUgdGhlbSBhcyBzdHJpbmdzLiBGb3IgbW9yZSBpbmZvOiBodHRwczovL2dvby5nbC95NXZiU2dcbiAgICByZXR1cm4gbnVtYmVyVmFsdWUgPCBNQVhfU0FGRV9JTlRFR0VSID8gbnVtYmVyVmFsdWUgOiB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFsbEVsZW1lbnRzVG9FeHBvcnQoXG4gIGFycmF5RGF0YTogYW55W10sXG4gIGNvbHVtbnM6IElHZW5lcmljQXJyYXlDb2x1bW5bXVxuKTogeyBbbGFiZWw6IHN0cmluZ106IGFueSB9W10ge1xuICBjb25zdCBjb2x1bW5zTGFiZWw6IE1hcDxzdHJpbmcsIHN0cmluZz4gPSBnZXRDb2x1bW5zTGFiZWxzKGNvbHVtbnMpO1xuICBjb25zdCBkYXRhID0gISFhcnJheURhdGFcbiAgICA/IGFycmF5RGF0YS5tYXAoKHJvdykgPT5cbiAgICAgICAgY29sdW1ucy5yZWR1Y2UoXG4gICAgICAgICAgKGFjYywgY29sdW1uKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBsYWJlbDogc3RyaW5nID0gY29sdW1uc0xhYmVsLmdldChjb2x1bW4uaWQpO1xuICAgICAgICAgICAgbGV0IGNlbGxWYWx1ZSA9IHJvd1tjb2x1bW4uaWRdO1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2VsbFZhbHVlKSAmJiBjZWxsVmFsdWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBjZWxsVmFsdWUgPSBjZWxsVmFsdWVcbiAgICAgICAgICAgICAgICAubWFwKChjZWxsRWx0OiBJRGF0YVRhYmxlQ2VsbEVsZW1lbnQpID0+XG4gICAgICAgICAgICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY2VsbEVsdCwgJ3ZhbHVlJylcbiAgICAgICAgICAgICAgICAgICAgPyBjZWxsRWx0LnZhbHVlXG4gICAgICAgICAgICAgICAgICAgIDogY2VsbEVsdFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAuam9pbignLCAnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7IC4uLmFjYywgW2xhYmVsXTogY2VsbFZhbHVlIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7fSBhcyB7IFtsYWJlbDogc3RyaW5nXTogYW55IH1cbiAgICAgICAgKVxuICAgICAgKVxuICAgIDogW107XG4gIHJldHVybiBkYXRhO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29sdW1uc0xhYmVscyhcbiAgY29sdW1uczogSUdlbmVyaWNBcnJheUNvbHVtbltdXG4pOiBNYXA8c3RyaW5nLCBzdHJpbmc+IHtcbiAgcmV0dXJuICEhY29sdW1uc1xuICAgID8gbmV3IE1hcChcbiAgICAgICAgY29sdW1ucy5tYXAoKGNvbHVtbjogSUdlbmVyaWNBcnJheUNvbHVtbikgPT4gW2NvbHVtbi5pZCwgY29sdW1uLmxhYmVsXSlcbiAgICAgIClcbiAgICA6IG5ldyBNYXAoKTtcbn1cbiJdfQ==