You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
400 lines
52 KiB
JavaScript
400 lines
52 KiB
JavaScript
import { FlowchartConstants } from './ngx-flowchart.models';
|
|
import { of, Subject } from 'rxjs';
|
|
import { debounceTime } from 'rxjs/operators';
|
|
export class FcModelService {
|
|
constructor(modelValidation, model, modelChanged, detectChangesSubject, selectedObjects, dropNode, createEdge, edgeAddedCallback, nodeRemovedCallback, edgeRemovedCallback, canvasHtmlElement, svgHtmlElement) {
|
|
this.connectorsRectInfos = {};
|
|
this.nodesHtmlElements = {};
|
|
this.canvasHtmlElement = null;
|
|
this.dragImage = null;
|
|
this.svgHtmlElement = null;
|
|
this.debouncer = new Subject();
|
|
this.modelValidation = modelValidation;
|
|
this.model = model;
|
|
this.modelChanged = modelChanged;
|
|
this.detectChangesSubject = detectChangesSubject;
|
|
this.canvasHtmlElement = canvasHtmlElement;
|
|
this.svgHtmlElement = svgHtmlElement;
|
|
this.modelValidation.validateModel(this.model);
|
|
this.selectedObjects = selectedObjects;
|
|
this.dropNode = dropNode || (() => { });
|
|
this.createEdge = createEdge || ((event, edge) => of(Object.assign(Object.assign({}, edge), { label: 'label' })));
|
|
this.edgeAddedCallback = edgeAddedCallback || (() => { });
|
|
this.nodeRemovedCallback = nodeRemovedCallback || (() => { });
|
|
this.edgeRemovedCallback = edgeRemovedCallback || (() => { });
|
|
this.connectors = new ConnectorsModel(this);
|
|
this.nodes = new NodesModel(this);
|
|
this.edges = new EdgesModel(this);
|
|
this.debouncer
|
|
.pipe(debounceTime(100))
|
|
.subscribe(() => this.modelChanged.emit());
|
|
}
|
|
notifyModelChanged() {
|
|
this.debouncer.next();
|
|
}
|
|
detectChanges() {
|
|
setTimeout(() => {
|
|
this.detectChangesSubject.next();
|
|
}, 0);
|
|
}
|
|
selectObject(object) {
|
|
if (this.isEditable()) {
|
|
if (this.selectedObjects.indexOf(object) === -1) {
|
|
this.selectedObjects.push(object);
|
|
}
|
|
}
|
|
}
|
|
deselectObject(object) {
|
|
if (this.isEditable()) {
|
|
const index = this.selectedObjects.indexOf(object);
|
|
if (index === -1) {
|
|
throw new Error('Tried to deselect an unselected object');
|
|
}
|
|
this.selectedObjects.splice(index, 1);
|
|
}
|
|
}
|
|
toggleSelectedObject(object) {
|
|
if (this.isSelectedObject(object)) {
|
|
this.deselectObject(object);
|
|
}
|
|
else {
|
|
this.selectObject(object);
|
|
}
|
|
}
|
|
isSelectedObject(object) {
|
|
return this.selectedObjects.indexOf(object) !== -1;
|
|
}
|
|
selectAll() {
|
|
this.model.nodes.forEach(node => {
|
|
if (!node.readonly) {
|
|
this.nodes.select(node);
|
|
}
|
|
});
|
|
this.model.edges.forEach(edge => {
|
|
this.edges.select(edge);
|
|
});
|
|
this.detectChanges();
|
|
}
|
|
deselectAll() {
|
|
this.selectedObjects.splice(0, this.selectedObjects.length);
|
|
this.detectChanges();
|
|
}
|
|
isEditObject(object) {
|
|
return this.selectedObjects.length === 1 &&
|
|
this.selectedObjects.indexOf(object) !== -1;
|
|
}
|
|
inRectBox(x, y, rectBox) {
|
|
return x >= rectBox.left && x <= rectBox.right &&
|
|
y >= rectBox.top && y <= rectBox.bottom;
|
|
}
|
|
getItemInfoAtPoint(x, y) {
|
|
return {
|
|
node: this.getNodeAtPoint(x, y),
|
|
edge: this.getEdgeAtPoint(x, y)
|
|
};
|
|
}
|
|
getNodeAtPoint(x, y) {
|
|
for (const node of this.model.nodes) {
|
|
const element = this.nodes.getHtmlElement(node.id);
|
|
const nodeElementBox = element.getBoundingClientRect();
|
|
if (x >= nodeElementBox.left && x <= nodeElementBox.right
|
|
&& y >= nodeElementBox.top && y <= nodeElementBox.bottom) {
|
|
return node;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
getEdgeAtPoint(x, y) {
|
|
const element = document.elementFromPoint(x, y);
|
|
const id = element.id;
|
|
let edgeIndex = -1;
|
|
if (id) {
|
|
if (id.startsWith('fc-edge-path-')) {
|
|
edgeIndex = Number(id.substring('fc-edge-path-'.length));
|
|
}
|
|
else if (id.startsWith('fc-edge-label-')) {
|
|
edgeIndex = Number(id.substring('fc-edge-label-'.length));
|
|
}
|
|
}
|
|
if (edgeIndex > -1) {
|
|
return this.model.edges[edgeIndex];
|
|
}
|
|
return null;
|
|
}
|
|
selectAllInRect(rectBox) {
|
|
this.model.nodes.forEach((value) => {
|
|
const element = this.nodes.getHtmlElement(value.id);
|
|
const nodeElementBox = element.getBoundingClientRect();
|
|
if (!value.readonly) {
|
|
const x = nodeElementBox.left + nodeElementBox.width / 2;
|
|
const y = nodeElementBox.top + nodeElementBox.height / 2;
|
|
if (this.inRectBox(x, y, rectBox)) {
|
|
this.nodes.select(value);
|
|
}
|
|
else {
|
|
if (this.nodes.isSelected(value)) {
|
|
this.nodes.deselect(value);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
const canvasElementBox = this.canvasHtmlElement.getBoundingClientRect();
|
|
this.model.edges.forEach((value) => {
|
|
const start = this.edges.sourceCoord(value);
|
|
const end = this.edges.destCoord(value);
|
|
const x = (start.x + end.x) / 2 + canvasElementBox.left;
|
|
const y = (start.y + end.y) / 2 + canvasElementBox.top;
|
|
if (this.inRectBox(x, y, rectBox)) {
|
|
this.edges.select(value);
|
|
}
|
|
else {
|
|
if (this.edges.isSelected(value)) {
|
|
this.edges.deselect(value);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
deleteSelected() {
|
|
const edgesToDelete = this.edges.getSelectedEdges();
|
|
edgesToDelete.forEach((edge) => {
|
|
this.edges.delete(edge);
|
|
});
|
|
const nodesToDelete = this.nodes.getSelectedNodes();
|
|
nodesToDelete.forEach((node) => {
|
|
this.nodes.delete(node);
|
|
});
|
|
}
|
|
isEditable() {
|
|
return this.dropTargetId === undefined;
|
|
}
|
|
isDropSource() {
|
|
return this.dropTargetId !== undefined;
|
|
}
|
|
getDragImage() {
|
|
if (!this.dragImage) {
|
|
this.dragImage = new Image();
|
|
this.dragImage.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
|
this.dragImage.style.visibility = 'hidden';
|
|
}
|
|
return this.dragImage;
|
|
}
|
|
}
|
|
class AbstractFcModel {
|
|
constructor(modelService) {
|
|
this.modelService = modelService;
|
|
}
|
|
select(object) {
|
|
this.modelService.selectObject(object);
|
|
}
|
|
deselect(object) {
|
|
this.modelService.deselectObject(object);
|
|
}
|
|
toggleSelected(object) {
|
|
this.modelService.toggleSelectedObject(object);
|
|
}
|
|
isSelected(object) {
|
|
return this.modelService.isSelectedObject(object);
|
|
}
|
|
isEdit(object) {
|
|
return this.modelService.isEditObject(object);
|
|
}
|
|
}
|
|
class ConnectorsModel extends AbstractFcModel {
|
|
constructor(modelService) {
|
|
super(modelService);
|
|
}
|
|
getConnector(connectorId) {
|
|
const model = this.modelService.model;
|
|
for (const node of model.nodes) {
|
|
for (const connector of node.connectors) {
|
|
if (connector.id === connectorId) {
|
|
return connector;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
getConnectorRectInfo(connectorId) {
|
|
return this.modelService.connectorsRectInfos[connectorId];
|
|
}
|
|
setConnectorRectInfo(connectorId, connectorRectInfo) {
|
|
this.modelService.connectorsRectInfos[connectorId] = connectorRectInfo;
|
|
this.modelService.detectChanges();
|
|
}
|
|
_getCoords(connectorId, centered) {
|
|
const connectorRectInfo = this.getConnectorRectInfo(connectorId);
|
|
const canvas = this.modelService.canvasHtmlElement;
|
|
if (connectorRectInfo === null || connectorRectInfo === undefined || canvas === null) {
|
|
return { x: 0, y: 0 };
|
|
}
|
|
let x = connectorRectInfo.type === FlowchartConstants.leftConnectorType ?
|
|
connectorRectInfo.nodeRectInfo.left() : connectorRectInfo.nodeRectInfo.right();
|
|
let y = connectorRectInfo.nodeRectInfo.top() + connectorRectInfo.nodeRectInfo.height() / 2;
|
|
if (!centered) {
|
|
x -= connectorRectInfo.width / 2;
|
|
y -= connectorRectInfo.height / 2;
|
|
}
|
|
const coords = {
|
|
x: Math.round(x),
|
|
y: Math.round(y)
|
|
};
|
|
return coords;
|
|
}
|
|
getCoords(connectorId) {
|
|
return this._getCoords(connectorId, false);
|
|
}
|
|
getCenteredCoord(connectorId) {
|
|
return this._getCoords(connectorId, true);
|
|
}
|
|
}
|
|
class NodesModel extends AbstractFcModel {
|
|
constructor(modelService) {
|
|
super(modelService);
|
|
}
|
|
getConnectorsByType(node, type) {
|
|
return node.connectors.filter((connector) => {
|
|
return connector.type === type;
|
|
});
|
|
}
|
|
_addConnector(node, connector) {
|
|
node.connectors.push(connector);
|
|
try {
|
|
this.modelService.modelValidation.validateNode(node);
|
|
}
|
|
catch (error) {
|
|
node.connectors.splice(node.connectors.indexOf(connector), 1);
|
|
throw error;
|
|
}
|
|
}
|
|
delete(node) {
|
|
if (this.isSelected(node)) {
|
|
this.deselect(node);
|
|
}
|
|
const model = this.modelService.model;
|
|
const index = model.nodes.indexOf(node);
|
|
if (index === -1) {
|
|
if (node === undefined) {
|
|
throw new Error('Passed undefined');
|
|
}
|
|
throw new Error('Tried to delete not existing node');
|
|
}
|
|
const connectorIds = this.getConnectorIds(node);
|
|
for (let i = 0; i < model.edges.length; i++) {
|
|
const edge = model.edges[i];
|
|
if (connectorIds.indexOf(edge.source) !== -1 || connectorIds.indexOf(edge.destination) !== -1) {
|
|
this.modelService.edges.delete(edge);
|
|
i--;
|
|
}
|
|
}
|
|
model.nodes.splice(index, 1);
|
|
this.modelService.notifyModelChanged();
|
|
this.modelService.nodeRemovedCallback(node);
|
|
}
|
|
getSelectedNodes() {
|
|
const model = this.modelService.model;
|
|
return model.nodes.filter((node) => {
|
|
return this.modelService.nodes.isSelected(node);
|
|
});
|
|
}
|
|
handleClicked(node, ctrlKey) {
|
|
if (ctrlKey) {
|
|
this.modelService.nodes.toggleSelected(node);
|
|
}
|
|
else {
|
|
this.modelService.deselectAll();
|
|
this.modelService.nodes.select(node);
|
|
}
|
|
}
|
|
_addNode(node) {
|
|
const model = this.modelService.model;
|
|
try {
|
|
model.nodes.push(node);
|
|
this.modelService.modelValidation.validateNodes(model.nodes);
|
|
}
|
|
catch (error) {
|
|
model.nodes.splice(model.nodes.indexOf(node), 1);
|
|
throw error;
|
|
}
|
|
}
|
|
getConnectorIds(node) {
|
|
return node.connectors.map((connector) => {
|
|
return connector.id;
|
|
});
|
|
}
|
|
getNodeByConnectorId(connectorId) {
|
|
const model = this.modelService.model;
|
|
for (const node of model.nodes) {
|
|
const connectorIds = this.getConnectorIds(node);
|
|
if (connectorIds.indexOf(connectorId) > -1) {
|
|
return node;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
getHtmlElement(nodeId) {
|
|
return this.modelService.nodesHtmlElements[nodeId];
|
|
}
|
|
setHtmlElement(nodeId, element) {
|
|
this.modelService.nodesHtmlElements[nodeId] = element;
|
|
this.modelService.detectChanges();
|
|
}
|
|
}
|
|
class EdgesModel extends AbstractFcModel {
|
|
constructor(modelService) {
|
|
super(modelService);
|
|
}
|
|
sourceCoord(edge) {
|
|
return this.modelService.connectors.getCenteredCoord(edge.source);
|
|
}
|
|
destCoord(edge) {
|
|
return this.modelService.connectors.getCenteredCoord(edge.destination);
|
|
}
|
|
delete(edge) {
|
|
const model = this.modelService.model;
|
|
const index = model.edges.indexOf(edge);
|
|
if (index === -1) {
|
|
throw new Error('Tried to delete not existing edge');
|
|
}
|
|
if (this.isSelected(edge)) {
|
|
this.deselect(edge);
|
|
}
|
|
model.edges.splice(index, 1);
|
|
this.modelService.notifyModelChanged();
|
|
this.modelService.edgeRemovedCallback(edge);
|
|
}
|
|
getSelectedEdges() {
|
|
const model = this.modelService.model;
|
|
return model.edges.filter((edge) => {
|
|
return this.modelService.edges.isSelected(edge);
|
|
});
|
|
}
|
|
handleEdgeMouseClick(edge, ctrlKey) {
|
|
if (ctrlKey) {
|
|
this.modelService.edges.toggleSelected(edge);
|
|
}
|
|
else {
|
|
this.modelService.deselectAll();
|
|
this.modelService.edges.select(edge);
|
|
}
|
|
}
|
|
putEdge(edge) {
|
|
const model = this.modelService.model;
|
|
model.edges.push(edge);
|
|
this.modelService.notifyModelChanged();
|
|
}
|
|
_addEdge(event, sourceConnector, destConnector, label) {
|
|
this.modelService.modelValidation.validateConnector(sourceConnector);
|
|
this.modelService.modelValidation.validateConnector(destConnector);
|
|
const edge = {};
|
|
edge.source = sourceConnector.id;
|
|
edge.destination = destConnector.id;
|
|
edge.label = label;
|
|
const model = this.modelService.model;
|
|
this.modelService.modelValidation.validateEdges(model.edges.concat([edge]), model.nodes);
|
|
this.modelService.createEdge(event, edge).subscribe((created) => {
|
|
model.edges.push(created);
|
|
this.modelService.notifyModelChanged();
|
|
this.modelService.edgeAddedCallback(created);
|
|
});
|
|
}
|
|
}
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1mbG93Y2hhcnQvIiwic291cmNlcyI6WyJsaWIvbW9kZWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBU0wsa0JBQWtCLEVBQ25CLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTlDLE1BQU0sT0FBTyxjQUFjO0lBNEJ6QixZQUFZLGVBQXlDLEVBQ3pDLEtBQWMsRUFDZCxZQUErQixFQUMvQixvQkFBa0MsRUFDbEMsZUFBc0IsRUFDdEIsUUFBOEMsRUFDOUMsVUFBOEQsRUFDOUQsaUJBQXlDLEVBQ3pDLG1CQUEyQyxFQUMzQyxtQkFBMkMsRUFDM0MsaUJBQThCLEVBQzlCLGNBQTBCO1FBaEN0Qyx3QkFBbUIsR0FBeUIsRUFBRSxDQUFDO1FBQy9DLHNCQUFpQixHQUFtQixFQUFFLENBQUM7UUFDdkMsc0JBQWlCLEdBQWdCLElBQUksQ0FBQztRQUN0QyxjQUFTLEdBQXFCLElBQUksQ0FBQztRQUNuQyxtQkFBYyxHQUFlLElBQUksQ0FBQztRQVdqQixjQUFTLEdBQUcsSUFBSSxPQUFPLEVBQU8sQ0FBQztRQW1COUMsSUFBSSxDQUFDLGVBQWUsR0FBRyxlQUFlLENBQUM7UUFDdkMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7UUFDakMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLG9CQUFvQixDQUFDO1FBQ2pELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQztRQUMzQyxJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQztRQUNyQyxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxD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LENBQUMsaUJBQWlCLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDbkUsTUFBTSxJQUFJLEdBQVcsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUcsZUFBZSxDQUFDLEVBQUUsQ0FBQztRQUNqQyxJQUFJLENBQUMsV0FBVyxHQUFHLGFBQWEsQ0FBQyxFQUFFLENBQUM7UUFDcEMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUM7UUFDdEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekYsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FDakQsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNWLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzFCLElBQUksQ0FBQyxZQUFZLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUN2QyxJQUFJLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9DLENBQUMsQ0FDRixDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRmNNb2RlbFZhbGlkYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi9tb2RlbHZhbGlkYXRpb24uc2VydmljZSc7XG5pbXBvcnQge1xuICBGY0Nvbm5lY3RvcixcbiAgRmNDb25uZWN0b3JSZWN0SW5mbyxcbiAgRmNDb29yZHMsXG4gIEZjRWRnZSxcbiAgRmNJdGVtSW5mbyxcbiAgRmNNb2RlbCxcbiAgRmNOb2RlLFxuICBGY1JlY3RCb3gsXG4gIEZsb3djaGFydENvbnN0YW50c1xufSBmcm9tICcuL25neC1mbG93Y2hhcnQubW9kZWxzJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuZXhwb3J0IGNsYXNzIEZjTW9kZWxTZXJ2aWNlIHtcblxuICBtb2RlbFZhbGlkYXRpb246IEZjTW9kZWxWYWxpZGF0aW9uU2VydmljZTtcbiAgbW9kZWw6IEZjTW9kZWw7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGV0ZWN0Q2hhbmdlc1N1YmplY3Q6IFN1YmplY3Q8YW55PjtcbiAgc2VsZWN0ZWRPYmplY3RzOiBhbnlbXTtcblxuICBjb25uZWN0b3JzUmVjdEluZm9zOiBDb25uZWN0b3JSZWN0SW5mb01hcCA9IHt9O1xuICBub2Rlc0h0bWxFbGVtZW50czogSHRtbEVsZW1lbnRNYXAgPSB7fTtcbiAgY2FudmFzSHRtbEVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gbnVsbDtcbiAgZHJhZ0ltYWdlOiBIVE1MSW1hZ2VFbGVtZW50ID0gbnVsbDtcbiAgc3ZnSHRtbEVsZW1lbnQ6IFNWR0VsZW1lbnQgPSBudWxsO1xuXG4gIGRyb3BOb2RlOiAoZXZlbnQ6IEV2ZW50LCBub2RlOiBGY05vZGUpID0+IHZvaWQ7XG4gIGNyZWF0ZUVkZ2U6IChldmVudDogRXZlbnQsIGVkZ2U6IEZjRWRnZSkgPT4gT2JzZXJ2YWJsZTxGY0VkZ2U+O1xuICBlZGdlQWRkZWRDYWxsYmFjazogKGVkZ2U6IEZjRWRnZSkgPT4gdm9pZDtcbiAgbm9kZVJlbW92ZWRDYWxsYmFjazogKG5vZGU6IEZjTm9kZSkgPT4gdm9pZDtcbiAgZWRnZVJlbW92ZWRDYWxsYmFjazogKGVkZ2U6IEZjRWRnZSkgPT4gdm9pZDtcblxuICBkcm9wVGFyZ2V0SWQ6IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IG1vZGVsQ2hhbmdlZDogRXZlbnRFbWl0dGVyPGFueT47XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVib3VuY2VyID0gbmV3IFN1YmplY3Q8YW55PigpO1xuXG4gIGNvbm5lY3RvcnM6IENvbm5lY3RvcnNNb2RlbDtcbiAgbm9kZXM6IE5vZGVzTW9kZWw7XG4gIGVkZ2VzOiBFZGdlc01vZGVsO1xuXG4gIGNvbnN0cnVjdG9yKG1vZGVsVmFsaWRhdGlvbjogRmNNb2RlbFZhbGlkYXRpb25TZXJ2aWNlLFxuICAgICAgICAgICAgICBtb2RlbDogRmNNb2RlbCxcbiAgICAgICAgICAgICAgbW9kZWxDaGFuZ2VkOiBFdmVudEVtaXR0ZXI8YW55PixcbiAgICAgICAgICAgICAgZGV0ZWN0Q2hhbmdlc1N1YmplY3Q6IFN1YmplY3Q8YW55PixcbiAgICAgICAgICAgICAgc2VsZWN0ZWRPYmplY3RzOiBhbnlbXSxcbiAgICAgICAgICAgICAgZHJvcE5vZGU6IChldmVudDogRXZlbnQsIG5vZGU6IEZjTm9kZSkgPT4gdm9pZCxcbiAgICAgICAgICAgICAgY3JlYXRlRWRnZTogKGV2ZW50OiBFdmVudCwgZWRnZTogRmNFZGdlKSA9PiBPYnNlcnZhYmxlPEZjRWRnZT4sXG4gICAgICAgICAgICAgIGVkZ2VBZGRlZENhbGxiYWNrOiAoZWRnZTogRmNFZGdlKSA9PiB2b2lkLFxuICAgICAgICAgICAgICBub2RlUmVtb3ZlZENhbGxiYWNrOiAobm9kZTogRmNOb2RlKSA9PiB2b2lkLFxuICAgICAgICAgICAgICBlZGdlUmVtb3ZlZENhbGxiYWNrOiAoZWRnZTogRmNFZGdlKSA9PiB2b2lkLFxuICAgICAgICAgICAgICBjYW52YXNIdG1sRWxlbWVudDogSFRNTEVsZW1lbnQsXG4gICAgICAgICAgICAgIHN2Z0h0bWxFbGVtZW50OiBTVkdFbGVtZW50KSB7XG5cbiAgICB0aGlzLm1vZGVsVmFsaWRhdGlvbiA9IG1vZGVsVmFsaWRhdGlvbjtcbiAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gICAgdGhpcy5tb2RlbENoYW5nZWQgPSBtb2RlbENoYW5nZWQ7XG4gICAgdGhpcy5kZXRlY3RDaGFuZ2VzU3ViamVjdCA9IGRldGVjdENoYW5nZXNTdWJqZWN0O1xuICAgIHRoaXMuY2FudmFzSHRtbEVsZW1lbnQgPSBjYW52YXNIdG1sRWxlbWVudDtcbiAgICB0aGlzLnN2Z0h0bWxFbGVtZW50ID0gc3ZnSHRtbEVsZW1lbnQ7XG4gICAgdGhpcy5tb2RlbFZhbGlkYXRpb24udmFsaWRhdGVNb2RlbCh0aGlzLm1vZGVsKTtcbiAgICB0aGlzLnNlbGVjdGVkT2JqZWN0cyA9IHNlbGVjdGVkT2JqZWN0cztcblxuICAgIHRoaXMuZHJvcE5vZGUgPSBkcm9wTm9kZSB8fCAoKCkgPT4ge30pO1xuICAgIHRoaXMuY3JlYXRlRWRnZSA9IGNyZWF0ZUVkZ2UgfHwgKChldmVudCwgZWRnZSkgPT4gb2Yoey4uLmVkZ2UsIGxhYmVsOiAnbGFiZWwnfSkpO1xuICAgIHRoaXMuZWRnZUFkZGVkQ2FsbGJhY2sgPSBlZGdlQWRkZWRDYWxsYmFjayB8fCAoKCkgPT4ge30pO1xuICAgIHRoaXMubm9kZVJlbW92ZWRDYWxsYmFjayA9IG5vZGVSZW1vdmVkQ2FsbGJhY2sgfHwgKCgpID0+IHt9KTtcbiAgICB0aGlzLmVkZ2VSZW1vdmVkQ2FsbGJhY2sgPSBlZGdlUmVtb3ZlZENhbGxiYWNrIHx8ICgoKSA9PiB7fSk7XG5cbiAgICB0aGlzLmNvbm5lY3RvcnMgPSBuZXcgQ29ubmVjdG9yc01vZGVsKHRoaXMpO1xuICAgIHRoaXMubm9kZXMgPSBuZXcgTm9kZXNNb2RlbCh0aGlzKTtcbiAgICB0aGlzLmVkZ2VzID0gbmV3IEVkZ2VzTW9kZWwodGhpcyk7XG5cbiAgICB0aGlzLmRlYm91bmNlclxuICAgICAgLnBpcGUoZGVib3VuY2VUaW1lKDEwMCkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMubW9kZWxDaGFuZ2VkLmVtaXQoKSk7XG4gIH1cblxuICBwdWJsaWMgbm90aWZ5TW9kZWxDaGFuZ2VkKCkge1xuICAgIHRoaXMuZGVib3VuY2VyLm5leHQoKTtcbiAgfVxuXG4gIHB1YmxpYyBkZXRlY3RDaGFuZ2VzKCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5kZXRlY3RDaGFuZ2VzU3ViamVjdC5uZXh0KCk7XG4gICAgfSwgMCk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0T2JqZWN0KG9iamVjdDogYW55KSB7XG4gICAgaWYgKHRoaXMuaXNFZGl0YWJsZSgpKSB7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZE9iamVjdHMuaW5kZXhPZihvYmplY3QpID09PSAtMSkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkT2JqZWN0cy5wdXNoKG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGRlc2VsZWN0T2JqZWN0KG9iamVjdDogYW55KSB7XG4gICAgaWYgKHRoaXMuaXNFZGl0YWJsZSgpKSB7XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuc2VsZWN0ZWRPYmplY3RzLmluZGV4T2Yob2JqZWN0KTtcbiAgICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUcmllZCB0byBkZXNlbGVjdCBhbiB1bnNlbGVjdGVkIG9iamVjdCcpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZWxlY3RlZE9iamVjdHMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgdG9nZ2xlU2VsZWN0ZWRPYmplY3Qob2JqZWN0OiBhbnkpIHtcbiAgICBpZiAodGhpcy5pc1NlbGVjdGVkT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgIHRoaXMuZGVzZWxlY3RPYmplY3Qob2JqZWN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RPYmplY3Qob2JqZWN0KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgaXNTZWxlY3RlZE9iamVjdChvYmplY3Q6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkT2JqZWN0cy5pbmRleE9mKG9iamVjdCkgIT09IC0xO1xuICB9XG5cbiAgcHVibGljIHNlbGVjdEFsbCgpIHtcbiAgICB0aGlzLm1vZGVsLm5vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICBpZiAoIW5vZGUucmVhZG9ubHkpIHtcbiAgICAgICAgdGhpcy5ub2Rlcy5zZWxlY3Qobm9kZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5tb2RlbC5lZGdlcy5mb3JFYWNoKGVkZ2UgPT4ge1xuICAgICAgdGhpcy5lZGdlcy5zZWxlY3QoZWRnZSk7XG4gICAgfSk7XG4gICAgdGhpcy5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwdWJsaWMgZGVzZWxlY3RBbGwoKSB7XG4gICAgdGhpcy5zZWxlY3RlZE9iamVjdHMuc3BsaWNlKDAsIHRoaXMuc2VsZWN0ZWRPYmplY3RzLmxlbmd0aCk7XG4gICAgdGhpcy5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBwdWJsaWMgaXNFZGl0T2JqZWN0KG9iamVjdDogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRPYmplY3RzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgdGhpcy5zZWxlY3RlZE9iamVjdHMuaW5kZXhPZihvYmplY3QpICE9PSAtMTtcbiAgfVxuXG4gIHByaXZhdGUgaW5SZWN0Qm94KHg6IG51bWJlciwgeTogbnVtYmVyLCByZWN0Qm94OiBGY1JlY3RCb3gpOiBib29sZWFuIHtcbiAgICByZXR1cm4geCA+PSByZWN0Qm94LmxlZnQgJiYgeCA8PSByZWN0Qm94LnJpZ2h0ICYmXG4gICAgICB5ID49IHJlY3RCb3gudG9wICYmIHkgPD0gcmVjdEJveC5ib3R0b207XG4gIH1cblxuICBwdWJsaWMgZ2V0SXRlbUluZm9BdFBvaW50KHg6IG51bWJlciwgeTogbnVtYmVyKTogRmNJdGVtSW5mbyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5vZGU6IHRoaXMuZ2V0Tm9kZUF0UG9pbnQoeCwgeSksXG4gICAgICBlZGdlOiB0aGlzLmdldEVkZ2VBdFBvaW50KHgsIHkpXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBnZXROb2RlQXRQb2ludCh4OiBudW1iZXIsIHk6IG51bWJlcik6IEZjTm9kZSB7XG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMubW9kZWwubm9kZXMpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLm5vZGVzLmdldEh0bWxFbGVtZW50KG5vZGUuaWQpO1xuICAgICAgY29uc3Qgbm9kZUVsZW1lbnRCb3ggPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgaWYgKHggPj0gbm9kZUVsZW1lbnRCb3gubGVmdCAmJiB4IDw9IG5vZGVFbGVtZW50Qm94LnJpZ2h0XG4gICAgICAgICYmIHkgPj0gbm9kZUVsZW1lbnRCb3gudG9wICYmIHkgPD0gbm9kZUVsZW1lbnRCb3guYm90dG9tKSB7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRFZGdlQXRQb2ludCh4OiBudW1iZXIsIHk6IG51bWJlcik6IEZjRWRnZSB7XG4gICAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoeCwgeSk7XG4gICAgY29uc3QgaWQgPSBlbGVtZW50LmlkO1xuICAgIGxldCBlZGdlSW5kZXggPSAtMTtcbiAgICBpZiAoaWQpIHtcbiAgICAgIGlmIChpZC5zdGFydHNXaXRoKCdmYy1lZGdlLXBhdGgtJykpIHtcbiAgICAgICAgZWRnZUluZGV4ID0gTnVtYmVyKGlkLnN1YnN0cmluZygnZmMtZWRnZS1wYXRoLScubGVuZ3RoKSk7XG4gICAgICB9IGVsc2UgaWYgKGlkLnN0YXJ0c1dpdGgoJ2ZjLWVkZ2UtbGFiZWwtJykpIHtcbiAgICAgICAgZWRnZUluZGV4ID0gTnVtYmVyKGlkLnN1YnN0cmluZygnZmMtZWRnZS1sYWJlbC0nLmxlbmd0aCkpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZWRnZUluZGV4ID4gLTEpIHtcbiAgICAgIHJldHVybiB0aGlzLm1vZGVsLmVkZ2VzW2VkZ2VJbmRleF07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHVibGljIHNlbGVjdEFsbEluUmVjdChyZWN0Qm94OiBGY1JlY3RCb3gpIHtcbiAgICB0aGlzLm1vZGVsLm5vZGVzLmZvckVhY2goKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5ub2Rlcy5nZXRIdG1sRWxlbWVudCh2YWx1ZS5pZCk7XG4gICAgICBjb25zdCBub2RlRWxlbWVudEJveCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBpZiAoIXZhbHVlLnJlYWRvbmx5KSB7XG4gICAgICAgIGNvbnN0IHggPSBub2RlRWxlbWVudEJveC5sZWZ0ICsgbm9kZUVsZW1lbnRCb3gud2lkdGggLyAyO1xuICAgICAgICBjb25zdCB5ID0gbm9kZUVsZW1lbnRCb3gudG9wICsgbm9kZUVsZW1lbnRCb3guaGVpZ2h0IC8gMjtcbiAgICAgICAgaWYgKHRoaXMuaW5SZWN0Qm94KHgsIHksIHJlY3RCb3gpKSB7XG4gICAgICAgICAgdGhpcy5ub2Rlcy5zZWxlY3QodmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLm5vZGVzLmlzU2VsZWN0ZWQodmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLm5vZGVzLmRlc2VsZWN0KHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBjYW52YXNFbGVtZW50Qm94ID0gdGhpcy5jYW52YXNIdG1sRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB0aGlzLm1vZGVsLmVkZ2VzLmZvckVhY2goKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBzdGFydCA9IHRoaXMuZWRnZXMuc291cmNlQ29vcmQodmFsdWUpO1xuICAgICAgY29uc3QgZW5kID0gdGhpcy5lZGdlcy5kZXN0Q29vcmQodmFsdWUpO1xuICAgICAgY29uc3QgeCA9IChzdGFydC54ICsgZW5kLngpIC8gMiArIGNhbnZhc0VsZW1lbnRCb3gubGVmdDtcbiAgICAgIGNvbnN0IHkgPSAoc3RhcnQueSArIGVuZC55KSAvIDIgKyBjYW52YXNFbGVtZW50Qm94LnRvcDtcbiAgICAgIGlmICh0aGlzLmluUmVjdEJveCh4LCB5LCByZWN0Qm94KSkge1xuICAgICAgICB0aGlzLmVkZ2VzLnNlbGVjdCh2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5lZGdlcy5pc1NlbGVjdGVkKHZhbHVlKSkge1xuICAgICAgICAgIHRoaXMuZWRnZXMuZGVzZWxlY3QodmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZGVsZXRlU2VsZWN0ZWQoKSB7XG4gICAgY29uc3QgZWRnZXNUb0RlbGV0ZSA9IHRoaXMuZWRnZXMuZ2V0U2VsZWN0ZWRFZGdlcygpO1xuICAgIGVkZ2VzVG9EZWxldGUuZm9yRWFjaCgoZWRnZSkgPT4ge1xuICAgICAgdGhpcy5lZGdlcy5kZWxldGUoZWRnZSk7XG4gICAgfSk7XG4gICAgY29uc3Qgbm9kZXNUb0RlbGV0ZSA9IHRoaXMubm9kZXMuZ2V0U2VsZWN0ZWROb2RlcygpO1xuICAgIG5vZGVzVG9EZWxldGUuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgdGhpcy5ub2Rlcy5kZWxldGUobm9kZSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgaXNFZGl0YWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kcm9wVGFyZ2V0SWQgPT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBpc0Ryb3BTb3VyY2UoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZHJvcFRhcmdldElkICE9PSB1bmRlZmluZWQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0RHJhZ0ltYWdlKCk6IEhUTUxJbWFnZUVsZW1lbnQge1xuICAgIGlmICghdGhpcy5kcmFnSW1hZ2UpIHtcbiAgICAgIHRoaXMuZHJhZ0ltYWdlID0gbmV3IEltYWdlKCk7XG4gICAgICB0aGlzLmRyYWdJbWFnZS5zcmMgPSAnZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoQVFBQkFJQUFBQUFBQVAvLy95SDVCQUVBQUFBQUxBQUFBQUFCQUFFQUFBSUJSQUE3JztcbiAgICAgIHRoaXMuZHJhZ0ltYWdlLnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZHJhZ0ltYWdlO1xuICB9XG59XG5cbmludGVyZmFjZSBIdG1sRWxlbWVudE1hcCB7IFtpZDogc3RyaW5nXTogSFRNTEVsZW1lbnQ7IH1cblxuaW50ZXJmYWNlIENvbm5lY3RvclJlY3RJbmZvTWFwIHsgW2lkOiBzdHJpbmddOiBGY0Nvbm5lY3RvclJlY3RJbmZvOyB9XG5cbmFic3RyYWN0IGNsYXNzIEFic3RyYWN0RmNNb2RlbDxUPiB7XG5cbiAgbW9kZWxTZXJ2aWNlOiBGY01vZGVsU2VydmljZTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IobW9kZWxTZXJ2aWNlOiBGY01vZGVsU2VydmljZSkge1xuICAgIHRoaXMubW9kZWxTZXJ2aWNlID0gbW9kZWxTZXJ2aWNlO1xuICB9XG5cbiAgcHVibGljIHNlbGVjdChvYmplY3Q6IFQpIHtcbiAgICB0aGlzLm1vZGVsU2VydmljZS5zZWxlY3RPYmplY3Qob2JqZWN0KTtcbiAgfVxuXG4gIHB1YmxpYyBkZXNlbGVjdChvYmplY3Q6IFQpIHtcbiAgICB0aGlzLm1vZGVsU2VydmljZS5kZXNlbGVjdE9iamVjdChvYmplY3QpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZVNlbGVjdGVkKG9iamVjdDogVCkge1xuICAgIHRoaXMubW9kZWxTZXJ2aWNlLnRvZ2dsZVNlbGVjdGVkT2JqZWN0KG9iamVjdCk7XG4gIH1cblxuICBwdWJsaWMgaXNTZWxlY3RlZChvYmplY3Q6IFQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlbFNlcnZpY2UuaXNTZWxlY3RlZE9iamVjdChvYmplY3QpO1xuICB9XG5cbiAgcHVibGljIGlzRWRpdChvYmplY3Q6IFQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlbFNlcnZpY2UuaXNFZGl0T2JqZWN0KG9iamVjdCk7XG4gIH1cbn1cblxuY2xhc3MgQ29ubmVjdG9yc01vZGVsIGV4dGVuZHMgQWJzdHJhY3RGY01vZGVsPEZjQ29ubmVjdG9yPiB7XG5cbiAgY29uc3RydWN0b3IobW9kZWxTZXJ2aWNlOiBGY01vZGVsU2VydmljZSkge1xuICAgIHN1cGVyKG1vZGVsU2VydmljZSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q29ubmVjdG9yKGNvbm5lY3RvcklkOiBzdHJpbmcpOiBGY0Nvbm5lY3RvciB7XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLm1vZGVsU2VydmljZS5tb2RlbDtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgbW9kZWwubm9kZXMpIHtcbiAgICAgIGZvciAoY29uc3QgY29ubmVjdG9yIG9mIG5vZGUuY29ubmVjdG9ycykge1xuICAgICAgICBpZiAoY29ubmVjdG9yLmlkID09PSBjb25uZWN0b3JJZCkge1xuICAgICAgICAgIHJldHVybiBjb25uZWN0b3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0Q29ubmVjdG9yUmVjdEluZm8oY29ubmVjdG9ySWQ6IHN0cmluZyk6IEZjQ29ubmVjdG9yUmVjdEluZm8ge1xuICAgIHJldHVybiB0aGlzLm1vZGVsU2VydmljZS5jb25uZWN0b3JzUmVjdEluZm9zW2Nvbm5lY3RvcklkXTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRDb25uZWN0b3JSZWN0SW5mbyhjb25uZWN0b3JJZDogc3RyaW5nLCBjb25uZWN0b3JSZWN0SW5mbzogRmNDb25uZWN0b3JSZWN0SW5mbykge1xuICAgIHRoaXMubW9kZWxTZXJ2aWNlLmNvbm5lY3RvcnNSZWN0SW5mb3NbY29ubmVjdG9ySWRdID0gY29ubmVjdG9yUmVjdEluZm87XG4gICAgdGhpcy5tb2RlbFNlcnZpY2UuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0Q29vcmRzKGNvbm5lY3RvcklkOiBzdHJpbmcsIGNlbnRlcmVkPzogYm9vbGVhbik6IEZjQ29vcmRzIHtcbiAgICBjb25zdCBjb25uZWN0b3JSZWN0SW5mbyA9IHRoaXMuZ2V0Q29ubmVjdG9yUmVjdEluZm8oY29ubmVjdG9ySWQpO1xuICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMubW9kZWxTZXJ2aWNlLmNhbnZhc0h0bWxFbGVtZW50O1xuICAgIGlmIChjb25uZWN0b3JSZWN0SW5mbyA9PT0gbnVsbCB8fCBjb25uZWN0b3JSZWN0SW5mbyA9PT0gdW5kZWZpbmVkIHx8IGNhbnZhcyA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHt4OiAwLCB5OiAwfTtcbiAgICB9XG4gICAgbGV0IHggPSBjb25uZWN0b3JSZWN0SW5mby50eXBlID09PSBGbG93Y2hhcnRDb25zdGFudHMubGVmdENvbm5lY3RvclR5cGUgP1xuICAgICAgY29ubmVjdG9yUmVjdEluZm8ubm9kZVJlY3RJbmZvLmxlZnQoKSA6IGNvbm5lY3RvclJlY3RJbmZvLm5vZGVSZWN0SW5mby5yaWdodCgpO1xuICAgIGxldCB5ID0gY29ubmVjdG9yUmVjdEluZm8ubm9kZVJlY3RJbmZvLnRvcCgpICsgY29ubmVjdG9yUmVjdEluZm8ubm9kZVJlY3RJbmZvLmhlaWdodCgpIC8gMjtcbiAgICBpZiAoIWNlbnRlcmVkKSB7XG4gICAgICB4IC09IGNvbm5lY3RvclJlY3RJbmZvLndpZHRoIC8gMjtcbiAgICAgIHkgLT0gY29ubmVjdG9yUmVjdEluZm8uaGVpZ2h0IC8gMjtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzOiBGY0Nvb3JkcyA9IHtcbiAgICAgIHg6IE1hdGgucm91bmQoeCksXG4gICAgICB5OiBNYXRoLnJvdW5kKHkpXG4gICAgfTtcbiAgICByZXR1cm4gY29vcmRzO1xuICB9XG5cbiAgcHVibGljIGdldENvb3Jkcyhjb25uZWN0b3JJZDogc3RyaW5nKTogRmNDb29yZHMge1xuICAgIHJldHVybiB0aGlzLl9nZXRDb29yZHMoY29ubmVjdG9ySWQsIGZhbHNlKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDZW50ZXJlZENvb3JkKGNvbm5lY3RvcklkOiBzdHJpbmcpOiBGY0Nvb3JkcyB7XG4gICAgcmV0dXJuIHRoaXMuX2dldENvb3Jkcyhjb25uZWN0b3JJZCwgdHJ1ZSk7XG4gIH1cbn1cblxuY2xhc3MgTm9kZXNNb2RlbCBleHRlbmRzIEFic3RyYWN0RmNNb2RlbDxGY05vZGU+IHtcblxuICBjb25zdHJ1Y3Rvcihtb2RlbFNlcnZpY2U6IEZjTW9kZWxTZXJ2aWNlKSB7XG4gICAgc3VwZXIobW9kZWxTZXJ2aWNlKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDb25uZWN0b3JzQnlUeXBlKG5vZGU6IEZjTm9kZSwgdHlwZTogc3RyaW5nKTogQXJyYXk8RmNDb25uZWN0b3I+IHtcbiAgICByZXR1cm4gbm9kZS5jb25uZWN0b3JzLmZpbHRlcigoY29ubmVjdG9yKSA9PiB7XG4gICAgICByZXR1cm4gY29ubmVjdG9yLnR5cGUgPT09IHR5cGU7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9hZGRDb25uZWN0b3Iobm9kZTogRmNOb2RlLCBjb25uZWN0b3I6IEZjQ29ubmVjdG9yKSB7XG4gICAgbm9kZS5jb25uZWN0b3JzLnB1c2goY29ubmVjdG9yKTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5tb2RlbFNlcnZpY2UubW9kZWxWYWxpZGF0aW9uLnZhbGlkYXRlTm9kZShub2RlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbm9kZS5jb25uZWN0b3JzLnNwbGljZShub2RlLmNvbm5lY3RvcnMuaW5kZXhPZihjb25uZWN0b3IpLCAxKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBkZWxldGUobm9kZTogRmNOb2RlKSB7XG4gICAgaWYgKHRoaXMuaXNTZWxlY3RlZChub2RlKSkge1xuICAgICAgdGhpcy5kZXNlbGVjdChub2RlKTtcbiAgICB9XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLm1vZGVsU2VydmljZS5tb2RlbDtcbiAgICBjb25zdCBpbmRleCA9IG1vZGVsLm5vZGVzLmluZGV4T2Yobm9kZSk7XG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgaWYgKG5vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Bhc3NlZCB1bmRlZmluZWQnKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcignVHJpZWQgdG8gZGVsZXRlIG5vdCBleGlzdGluZyBub2RlJyk7XG4gICAgfVxuICAgIGNvbnN0IGNvbm5lY3RvcklkcyA9IHRoaXMuZ2V0Q29ubmVjdG9ySWRzKG5vZGUpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW9kZWwuZWRnZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGVkZ2UgPSBtb2RlbC5lZGdlc1tpXTtcbiAgICAgIGlmIChjb25uZWN0b3JJZHMuaW5kZXhPZihlZGdlLnNvdXJjZSkgIT09IC0xIHx8IGNvbm5lY3Rvcklkcy5pbmRleE9mKGVkZ2UuZGVzdGluYXRpb24pICE9PSAtMSkge1xuICAgICAgICB0aGlzLm1vZGVsU2VydmljZS5lZGdlcy5kZWxldGUoZWRnZSk7XG4gICAgICAgIGktLTtcbiAgICAgIH1cbiAgICB9XG4gICAgbW9kZWwubm9kZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLm1vZGVsU2VydmljZS5ub3RpZnlNb2RlbENoYW5nZWQoKTtcbiAgICB0aGlzLm1vZGVsU2VydmljZS5ub2RlUmVtb3ZlZENhbGxiYWNrKG5vZGUpO1xuICB9XG5cbiAgcHVibGljIGdldFNlbGVjdGVkTm9kZXMoKTogQXJyYXk8RmNOb2RlPiB7XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLm1vZGVsU2VydmljZS5tb2RlbDtcbiAgICByZXR1cm4gbW9kZWwubm9kZXMuZmlsdGVyKChub2RlKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5tb2RlbFNlcnZpY2Uubm9kZXMuaXNTZWxlY3RlZChub2RlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVDbGlja2VkKG5vZGU6IEZjTm9kZSwgY3RybEtleT86IGJvb2xlYW4pIHtcbiAgICBpZiAoY3RybEtleSkge1xuICAgICAgdGhpcy5tb2RlbFNlcnZpY2Uubm9kZXMudG9nZ2xlU2VsZWN0ZWQobm9kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubW9kZWxTZXJ2aWNlLmRlc2VsZWN0QWxsKCk7XG4gICAgICB0aGlzLm1vZGVsU2VydmljZS5ub2Rlcy5zZWxlY3Qobm9kZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfYWRkTm9kZShub2RlOiBGY05vZGUpIHtcbiAgICBjb25zdCBtb2RlbCA9IHRoaXMubW9kZWxTZXJ2aWNlLm1vZGVsO1xuICAgIHRyeSB7XG4gICAgICBtb2RlbC5ub2Rlcy5wdXNoKG5vZGUpO1xuICAgICAgdGhpcy5tb2RlbFNlcnZpY2UubW9kZWxWYWxpZGF0aW9uLnZhbGlkYXRlTm9kZXMobW9kZWwubm9kZXMpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBtb2RlbC5ub2Rlcy5zcGxpY2UobW9kZWwubm9kZXMuaW5kZXhPZihub2RlKSwgMSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0Q29ubmVjdG9ySWRzKG5vZGU6IEZjTm9kZSk6IEFycmF5PHN0cmluZz4ge1xuICAgIHJldHVybiBub2RlLmNvbm5lY3RvcnMubWFwKChjb25uZWN0b3IpID0+IHtcbiAgICAgIHJldHVybiBjb25uZWN0b3IuaWQ7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Tm9kZUJ5Q29ubmVjdG9ySWQoY29ubmVjdG9ySWQ6IHN0cmluZyk6IEZjTm9kZSB7XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLm1vZGVsU2VydmljZS5tb2RlbDtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgbW9kZWwubm9kZXMpIHtcbiAgICAgIGNvbnN0IGNvbm5lY3RvcklkcyA9IHRoaXMuZ2V0Q29ubmVjdG9ySWRzKG5vZGUpO1xuICAgICAgaWYgKGNvbm5lY3Rvcklkcy5pbmRleE9mKGNvbm5lY3RvcklkKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHB1YmxpYyBnZXRIdG1sRWxlbWVudChub2RlSWQ6IHN0cmluZyk6IEhUTUxFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5tb2RlbFNlcnZpY2Uubm9kZXNIdG1sRWxlbWVudHNbbm9kZUlkXTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRIdG1sRWxlbWVudChub2RlSWQ6IHN0cmluZywgZWxlbWVudDogSFRNTEVsZW1lbnQpIHtcbiAgICB0aGlzLm1vZGVsU2VydmljZS5ub2Rlc0h0bWxFbGVtZW50c1tub2RlSWRdID0gZWxlbWVudDtcbiAgICB0aGlzLm1vZGVsU2VydmljZS5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxufVxuXG5jbGFzcyBFZGdlc01vZGVsIGV4dGVuZHMgQWJzdHJhY3RGY01vZGVsPEZjRWRnZT4ge1xuXG4gIGNvbnN0cnVjdG9yKG1vZGVsU2VydmljZTogRmNNb2RlbFNlcnZpY2UpIHtcbiAgICBzdXBlcihtb2RlbFNlcnZpY2UpO1xuICB9XG5cbiAgcHVibGljIHNvdXJjZUNvb3JkKGVkZ2U6IEZjRWRnZSk6IEZjQ29vcmRzIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlbFNlcnZpY2UuY29ubmVjdG9ycy5nZXRDZW50ZXJlZENvb3JkKGVkZ2Uuc291cmNlKTtcbiAgfVxuXG4gIHB1YmxpYyBkZXN0Q29vcmQoZWRnZTogRmNFZGdlKTogRmNDb29yZHMge1xuICAgIHJldHVybiB0aGlzLm1vZGVsU2VydmljZS5jb25uZWN0b3JzLmdldENlbnRlcmVkQ29vcmQoZWRnZS5kZXN0aW5hdGlvbik7XG4gIH1cblxuICBwdWJsaWMgZGVsZXRlKGVkZ2U6IEZjRWRnZSkge1xuICAgIGNvbnN0IG1vZGVsID0gdGhpcy5tb2RlbFNlcnZpY2UubW9kZWw7XG4gICAgY29uc3QgaW5kZXggPSBtb2RlbC5lZGdlcy5pbmRleE9mKGVkZ2UpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVHJpZWQgdG8gZGVsZXRlIG5vdCBleGlzdGluZyBlZGdlJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLmlzU2VsZWN0ZWQoZWRnZSkpIHtcbiAgICAgIHRoaXMuZGVzZWxlY3QoZWRnZSk7XG4gICAgfVxuICAgIG1vZGVsLmVkZ2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgdGhpcy5tb2RlbFNlcnZpY2Uubm90aWZ5TW9kZWxDaGFuZ2VkKCk7XG4gICAgdGhpcy5tb2RlbFNlcnZpY2UuZWRnZVJlbW92ZWRDYWxsYmFjayhlZGdlKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRTZWxlY3RlZEVkZ2VzKCk6IEFycmF5PEZjRWRnZT4ge1xuICAgIGNvbnN0IG1vZGVsID0gdGhpcy5tb2RlbFNlcnZpY2UubW9kZWw7XG4gICAgcmV0dXJuIG1vZGVsLmVkZ2VzLmZpbHRlcigoZWRnZSkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMubW9kZWxTZXJ2aWNlLmVkZ2VzLmlzU2VsZWN0ZWQoZWRnZSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgaGFuZGxlRWRnZU1vdXNlQ2xpY2soZWRnZTogRmNFZGdlLCBjdHJsS2V5PzogYm9vbGVhbikge1xuICAgIGlmIChjdHJsS2V5KSB7XG4gICAgICB0aGlzLm1vZGVsU2VydmljZS5lZGdlcy50b2dnbGVTZWxlY3RlZChlZGdlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tb2RlbFNlcnZpY2UuZGVzZWxlY3RBbGwoKTtcbiAgICAgIHRoaXMubW9kZWxTZXJ2aWNlLmVkZ2VzLnNlbGVjdChlZGdlKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcHV0RWRnZShlZGdlOiBGY0VkZ2UpIHtcbiAgICBjb25zdCBtb2RlbCA9IHRoaXMubW9kZWxTZXJ2aWNlLm1vZGVsO1xuICAgIG1vZGVsLmVkZ2VzLnB1c2goZWRnZSk7XG4gICAgdGhpcy5tb2RlbFNlcnZpY2Uubm90aWZ5TW9kZWxDaGFuZ2VkKCk7XG4gIH1cblxuICBwdWJsaWMgX2FkZEVkZ2UoZXZlbnQ6IEV2ZW50LCBzb3VyY2VDb25uZWN0b3I6IEZjQ29ubmVjdG9yLCBkZXN0Q29ubmVjdG9yOiBGY0Nvbm5lY3RvciwgbGFiZWw6IHN0cmluZykge1xuICAgIHRoaXMubW9kZWxTZXJ2aWNlLm1vZGVsVmFsaWRhdGlvbi52YWxpZGF0ZUNvbm5lY3Rvcihzb3VyY2VDb25uZWN0b3IpO1xuICAgIHRoaXMubW9kZWxTZXJ2aWNlLm1vZGVsVmFsaWRhdGlvbi52YWxpZGF0ZUNvbm5lY3RvcihkZXN0Q29ubmVjdG9yKTtcbiAgICBjb25zdCBlZGdlOiBGY0VkZ2UgPSB7fTtcbiAgICBlZGdlLnNvdXJjZSA9IHNvdXJjZUNvbm5lY3Rvci5pZDtcbiAgICBlZGdlLmRlc3RpbmF0aW9uID0gZGVzdENvbm5lY3Rvci5pZDtcbiAgICBlZGdlLmxhYmVsID0gbGFiZWw7XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLm1vZGVsU2VydmljZS5tb2RlbDtcbiAgICB0aGlzLm1vZGVsU2VydmljZS5tb2RlbFZhbGlkYXRpb24udmFsaWRhdGVFZGdlcyhtb2RlbC5lZGdlcy5jb25jYXQoW2VkZ2VdKSwgbW9kZWwubm9kZXMpO1xuICAgIHRoaXMubW9kZWxTZXJ2aWNlLmNyZWF0ZUVkZ2UoZXZlbnQsIGVkZ2UpLnN1YnNjcmliZShcbiAgICAgIChjcmVhdGVkKSA9PiB7XG4gICAgICAgIG1vZGVsLmVkZ2VzLnB1c2goY3JlYXRlZCk7XG4gICAgICAgIHRoaXMubW9kZWxTZXJ2aWNlLm5vdGlmeU1vZGVsQ2hhbmdlZCgpO1xuICAgICAgICB0aGlzLm1vZGVsU2VydmljZS5lZGdlQWRkZWRDYWxsYmFjayhjcmVhdGVkKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG59XG4iXX0=
|