kre-form
Version:
本项目由 Angular8+ 编写的表单设计器和表单应用,所有的配置都是 JSON 结构体组成,PC 端是基于 ANT 组件库封装
595 lines • 51.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Input, Output, EventEmitter, } from "@angular/core";
import { Graph, Shape, Addon } from "@antv/x6";
import { NzMessageService } from "ng-zorro-antd/message";
export class DataFlowComponent {
/**
* @param {?} message
*/
constructor(message) {
this.message = message;
this.drawerEvent = new EventEmitter();
this.modalEvent = new EventEmitter();
this.data = {
// 节点
nodes: [
{
id: "node1",
// String,可选,节点的唯一标识
x: 40,
// Number,必选,节点位置的 x 值
y: 40,
// Number,必选,节点位置的 y 值
width: 80,
// Number,可选,节点大小的 width 值
height: 40,
// Number,可选,节点大小的 height 值
label: "hello",
},
{
id: "node2",
// String,节点的唯一标识
x: 160,
// Number,必选,节点位置的 x 值
y: 180,
// Number,必选,节点位置的 y 值
width: 80,
// Number,可选,节点大小的 width 值
height: 40,
// Number,可选,节点大小的 height 值
label: "world",
},
],
// 边
edges: [
{
source: "node1",
// String,必须,起始节点 id
target: "node2",
},
],
};
this.title = "my-app";
}
/**
* @return {?}
*/
ngOnInit() {
this.graphShape();
this.grahpInit();
this.getHistoryGrahp();
this.graphEvent();
// console.log("节点", this.graph.getNodes());
// console.log("cell-----");
// console.log("节点和边", this.graph.getCells());
// console.log("根节点,即没有输入边的节点", this.graph.getRootNodes());
// console.log("叶子节点,即没有输出边的节点", this.graph.getLeafNodes());
// console.log("数量", this.graph.getCellCount());
// console.log(this.graph);
// console.log(this.stencil.graphs.group1.getNodes());
/** @type {?} */
let nodes = this.graph.getLeafNodes();
for (let i = 0; i < nodes.length; i++) {
/** @type {?} */
let node = nodes[i];
if (node["label"] !== "输出") {
this.message.error("界面必须包含输出");
break;
}
}
}
/**
* @return {?}
*/
grahpInit() {
/** @type {?} */
const that = this;
// #region 初始化画布
this.graph = new Graph({
container: (/** @type {?} */ (document.getElementById("graph-container"))),
grid: true,
history: true,
minimap: {
enabled: true,
container: (/** @type {?} */ (document.getElementById("minimap"))),
width: 198,
height: 198,
padding: 10,
},
mousewheel: {
enabled: true,
zoomAtMousePosition: true,
modifiers: "ctrl",
minScale: 0.5,
maxScale: 3,
},
connecting: {
router: "manhattan",
connector: {
name: "rounded",
args: {
radius: 8,
},
},
anchor: "center",
connectionPoint: "anchor",
allowBlank: false,
snap: {
radius: 20,
},
/**
* @return {?}
*/
createEdge() {
return new Shape.Edge({
attrs: {
line: {
stroke: "#A2B1C3",
strokeWidth: 2,
targetMarker: {
name: "block",
width: 12,
height: 8,
},
},
},
zIndex: 0,
});
},
// 在移动边的时候判断连接是否有效
/**
* @param {?} __0
* @return {?}
*/
validateConnection({ sourceView, targetView, sourceMagnet, targetMagnet, sourceCell, targetCell, }) {
if (targetMagnet && targetCell) {
/** @type {?} */
const incomingEdges = (/** @type {?} */ (that.graph)).getIncomingEdges(targetCell) || [];
if (incomingEdges.length >= (/** @type {?} */ (targetView)).cell.getData().out) {
that.message.error("超出out数量");
return false;
}
}
// 不允许连接到自己
if (sourceView === targetView) {
// that.message.error("不允许连接到自己");
return false;
}
// 只能从输出链接桩创建连接
if (!sourceMagnet ||
sourceMagnet.getAttribute("port-group") === "left") {
// that.message.error("只能从输出链接桩创建连接");
return false;
}
// 只能连接到输入链接桩
if (!targetMagnet ||
targetMagnet.getAttribute("port-group") === "right") {
// that.message.error("只能连接到输入链接桩");
return false;
}
return !!targetMagnet;
},
},
highlighting: {
magnetAdsorbed: {
name: "stroke",
args: {
attrs: {
fill: "#5F95FF",
stroke: "#5F95FF",
},
},
},
},
resizing: true,
rotating: true,
selecting: {
enabled: true,
rubberband: true,
showNodeSelectionBox: true,
},
snapline: true,
keyboard: true,
clipboard: true,
});
this.stencil = new Addon.Stencil({
target: this.graph,
stencilGraphWidth: 200,
stencilGraphHeight: 180,
collapsable: true,
groups: [
{
title: "数据处理",
name: "group1",
},
{
title: "输入输出",
name: "group2",
},
],
layoutOptions: {
columns: 2,
columnWidth: 80,
rowHeight: 55,
},
/**
* @param {?} currentnode
* @return {?}
*/
validateNode(currentnode) {
/** @type {?} */
const nodes = that.graph.getNodes();
if (nodes.length > 0) {
for (let i = 0; i < nodes.length; i++) {
/** @type {?} */
let node = nodes[i];
if (currentnode["label"] === "输出" && node["label"] === "输出") {
return false;
}
}
}
return true;
},
/**
* @param {?} node
* @return {?}
*/
getDropNode(node) {
/** @type {?} */
const size = node.size();
if (node["label"] === "输入") {
that.getModal(node["label"]);
}
if (node["label"] === "输出") {
r2.attr("body/fill", "#ccc");
}
return node.clone().size(size.width * 1.1, size.height * 1.1);
},
});
(/** @type {?} */ (document.getElementById("stencil"))).appendChild(this.stencil.container);
// #region 初始化图形
// 常规左右两个桩
/** @type {?} */
const ports = {
groups: {
right: {
position: "right",
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: {
visibility: "hidden",
},
},
},
},
left: {
position: "left",
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: {
visibility: "hidden",
},
},
},
},
},
items: [
{
id: "port1",
group: "left",
},
{
id: "port2",
group: "right",
},
],
};
// 输入只有左侧一个桩
/** @type {?} */
const ports2 = {
groups: {
left: {
position: "left",
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: {
visibility: "hidden",
},
},
},
},
},
items: [
{
id: "port1",
group: "left",
},
],
};
// 输出只有右侧一个桩
/** @type {?} */
const ports3 = {
groups: {
right: {
position: "right",
attrs: {
circle: {
r: 4,
magnet: true,
stroke: "#5F95FF",
strokeWidth: 1,
fill: "#fff",
style: {
visibility: "hidden",
},
},
},
},
},
items: [
{
id: "port2",
group: "right",
},
],
};
/** @type {?} */
const r1 = this.graph.createNode({
shape: "custom-rect",
id: "in",
label: "输入",
ports: Object.assign({}, ports3),
data: {
in: 0,
out: 3,
},
});
/** @type {?} */
const r2 = this.graph.createNode({
shape: "custom-rect",
id: "out",
label: "输出",
ports: Object.assign({}, ports2),
data: {
in: 2,
out: 2,
},
});
/** @type {?} */
const nodeArr = [];
this.menuList.forEach((/**
* @param {?} element
* @param {?} i
* @return {?}
*/
(element, i) => {
nodeArr.push(this.graph.createNode({
shape: "custom-rect",
label: element.title,
ports: Object.assign({}, ports),
data: element.data,
}));
}));
this.stencil.load([r1, r2], "group1");
this.stencil.load([...nodeArr], "group2");
}
/**
* @return {?}
*/
graphEvent() {
// delete
this.graph.bindKey("backspace", (/**
* @return {?}
*/
() => {
/** @type {?} */
const cells = this.graph.getSelectedCells();
if (cells.length) {
this.graph.removeCells(cells);
}
}));
// 控制连接桩显示/隐藏
/** @type {?} */
const showPorts = (/**
* @param {?} ports
* @param {?} show
* @return {?}
*/
(ports, show) => {
for (let i = 0, len = ports.length; i < len; i = i + 1) {
ports[i].style.visibility = show ? "visible" : "hidden";
}
});
this.graph.on("node:mouseenter", (/**
* @return {?}
*/
() => {
/** @type {?} */
const container = (/** @type {?} */ (document.getElementById("graph-container")));
/** @type {?} */
const ports = (/** @type {?} */ (container.querySelectorAll(".x6-port-body")));
showPorts(ports, true);
}));
this.graph.on("node:mouseleave", (/**
* @return {?}
*/
() => {
/** @type {?} */
const container = (/** @type {?} */ (document.getElementById("graph-container")));
/** @type {?} */
const ports = (/** @type {?} */ (container.querySelectorAll(".x6-port-body")));
showPorts(ports, false);
}));
// this.graph.on(
// "edge:connected",
// ({ isNew, currentMagnet, currentCell }) => {}
// );
// this.graph.on("edge:added", ({ cell, index, options }) => {});
// this.graph.on(
// "edge:change:*",
// (args: {
// key: string; // 通过 key 来确定改变项
// current: any; // 当前值,类型根据 key 指代的类型确定
// previous: any; // 改变之前的值,类型根据 key 指代的类型确定
// options: any; // 透传的 options
// }) => {
// console.log("key:", args.key);
// }
// );
// this.graph.on("edge:changed", ({ edge, options }) => {});
this.graph.on("node:click", (/**
* @param {?} __0
* @return {?}
*/
({ cell, view }) => {
/** @type {?} */
let node = view.cell;
console.log(node.label);
if (node.label === "输入") {
this.getModal(node.label);
}
else {
this.getDrawer(node.label);
}
}));
}
/**
* @return {?}
*/
getHistoryGrahp() {
/** @type {?} */
let json = localStorage.getItem("graphJSON");
if (json) {
this.graph.fromJSON(JSON.parse(json));
}
}
/**
* @param {?} label
* @return {?}
*/
getModal(label) {
this.modalEvent.emit(label);
}
/**
* @param {?} label
* @return {?}
*/
getDrawer(label) {
this.drawerEvent.emit(label);
}
/**
* @return {?}
*/
graphShape() {
Graph.registerNode("custom-rect", {
inherit: "rect",
width: 66,
height: 30,
attrs: {
body: {
strokeWidth: 1,
stroke: "#eee",
fill: "#fff",
},
text: {
fontSize: 12,
color: "#262626",
},
},
}, true);
}
/**
* @return {?}
*/
handleZoomIn() {
this.graph.zoom(0.1);
console.log(this.graph.zoom());
}
/**
* @return {?}
*/
handleZoomOut() {
this.graph.zoom(-0.1);
}
/**
* @return {?}
*/
handleUndo() {
this.graph.history.undo();
}
/**
* @return {?}
*/
handleRedo() {
this.graph.history.redo();
}
/**
* @return {?}
*/
handleReal() {
this.graph.scale(1);
this.graph.centerContent();
}
/**
* @return {?}
*/
handleFit() {
this.graph.zoomToFit({ padding: 12 });
}
}
DataFlowComponent.decorators = [
{ type: Component, args: [{
selector: "data-flow",
template: "<div class=\"wrap\">\n <div class=\"main\">\n <div class=\"edit-container\">\n <div id=\"container\">\n <div id=\"stencil\"></div>\n <div class=\"graph-wrap\">\n <div class=\"toolbar-wrap\">\n <span (click)=\"handleZoomIn()\" class=\"toolbar-btn\">+</span>\n <span class=\"number\">{{ graph.zoom() | percent }}</span>\n <span (click)=\"handleZoomOut()\" class=\"toolbar-btn\">-</span>\n <span class=\"line\">|</span>\n <span\n (click)=\"handleUndo()\"\n [ngClass]=\"{ on: graph.history.canUndo() }\"\n class=\"toolbar-btn-off\"\n ><</span\n >\n <span\n (click)=\"handleRedo()\"\n [ngClass]=\"{ on: graph.history.canRedo() }\"\n class=\"toolbar-btn-off\"\n >></span\n >\n\n <span (click)=\"handleReal()\">\u5B9E\u9645\u5C3A\u5BF8</span>\n <span (click)=\"handleFit()\">\u9002\u5E94\u753B\u5E03</span>\n </div>\n <div id=\"graph-container\"></div>\n <div id=\"minimap\"></div>\n </div>\n </div>\n </div>\n <div class=\"board\"></div>\n </div>\n</div>\n",
styles: [":host #stencil{width:180px;height:100%;position:relative}:host .graph-wrap{width:calc(100% - 180px)}:host .graph-wrap .toolbar-wrap{height:42px;line-height:42px}:host .graph-wrap .toolbar-wrap span{color:#111;margin:0 10px}:host .graph-wrap .toolbar-wrap .number{display:inline-block;width:42px}:host .graph-wrap .toolbar-wrap .line{color:#eee}:host .graph-wrap .toolbar-wrap .toolbar-btn{cursor:pointer;font-weight:700;padding:0 10px}:host .graph-wrap .toolbar-wrap .toolbar-btn-off{font-weight:700;padding:0 10px;cursor:default;color:#eee}:host .graph-wrap .toolbar-wrap .on{cursor:pointer;color:#111}:host .graph-wrap #graph-container{width:100%;height:100%}:host .graph-wrap #minimap{position:absolute;right:1rem;top:1rem;background-color:#bc8f8f}:host #container{display:flex;height:500px}:host ::ng-deep .x6-widget-stencil-title{display:none}:host ::ng-deep .x6-widget-stencil.collapsable>.x6-widget-stencil-content{top:0}"]
}] }
];
/** @nocollapse */
DataFlowComponent.ctorParameters = () => [
{ type: NzMessageService }
];
DataFlowComponent.propDecorators = {
menuList: [{ type: Input }],
drawerEvent: [{ type: Output }],
modalEvent: [{ type: Output }]
};
if (false) {
/** @type {?} */
DataFlowComponent.prototype.menuList;
/** @type {?} */
DataFlowComponent.prototype.drawerEvent;
/** @type {?} */
DataFlowComponent.prototype.modalEvent;
/** @type {?} */
DataFlowComponent.prototype.data;
/** @type {?} */
DataFlowComponent.prototype.title;
/** @type {?} */
DataFlowComponent.prototype.graph;
/** @type {?} */
DataFlowComponent.prototype.stencil;
/**
* @type {?}
* @private
*/
DataFlowComponent.prototype.message;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1mbG93LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BrcmUtZm9ybS9hYmMvIiwic291cmNlcyI6WyJsaWIvZGF0YS1mbG93L2RhdGEtZmxvdy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBSVQsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEdBQ2IsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFRLE1BQU0sVUFBVSxDQUFDO0FBRXJELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBT3pELE1BQU0sT0FBTyxpQkFBaUI7Ozs7SUFtQzVCLFlBQW9CLE9BQXlCO1FBQXpCLFlBQU8sR0FBUCxPQUFPLENBQWtCO1FBakNuQyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDdEMsZUFBVSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDL0MsU0FBSSxHQUFHOztZQUVMLEtBQUssRUFBRTtnQkFDTDtvQkFDRSxFQUFFLEVBQUUsT0FBTzs7b0JBQ1gsQ0FBQyxFQUFFLEVBQUU7O29CQUNMLENBQUMsRUFBRSxFQUFFOztvQkFDTCxLQUFLLEVBQUUsRUFBRTs7b0JBQ1QsTUFBTSxFQUFFLEVBQUU7O29CQUNWLEtBQUssRUFBRSxPQUFPO2lCQUNmO2dCQUNEO29CQUNFLEVBQUUsRUFBRSxPQUFPOztvQkFDWCxDQUFDLEVBQUUsR0FBRzs7b0JBQ04sQ0FBQyxFQUFFLEdBQUc7O29CQUNOLEtBQUssRUFBRSxFQUFFOztvQkFDVCxNQUFNLEVBQUUsRUFBRTs7b0JBQ1YsS0FBSyxFQUFFLE9BQU87aUJBQ2Y7YUFDRjs7WUFFRCxLQUFLLEVBQUU7Z0JBQ0w7b0JBQ0UsTUFBTSxFQUFFLE9BQU87O29CQUNmLE1BQU0sRUFBRSxPQUFPO2lCQUNoQjthQUNGO1NBQ0YsQ0FBQztRQUNGLFVBQUss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LHFDQUFzQjs7SUFDdEIsd0NBQWdEOztJQUNoRCx1Q0FBK0M7O0lBQy9DLGlDQTJCRTs7SUFDRixrQ0FBaUI7O0lBQ2pCLGtDQUFhOztJQUNiLG9DQUF1Qjs7Ozs7SUFDWCxvQ0FBaUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIE9uSW5pdCxcbiAgVmlld0NoaWxkLFxuICBUZW1wbGF0ZVJlZixcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgRXZlbnRFbWl0dGVyLFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgR3JhcGgsIFNoYXBlLCBBZGRvbiwgTm9kZSB9IGZyb20gXCJAYW50di94NlwiO1xuaW1wb3J0IHsgbm9kZUNlbnRlciB9IGZyb20gXCJAYW50di94Ni9saWIvcmVnaXN0cnkvbm9kZS1hbmNob3Ivbm9kZS1jZW50ZXJcIjtcbmltcG9ydCB7IE56TWVzc2FnZVNlcnZpY2UgfSBmcm9tIFwibmctem9ycm8tYW50ZC9tZXNzYWdlXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogXCJkYXRhLWZsb3dcIixcbiAgdGVtcGxhdGVVcmw6IFwiLi9kYXRhLWZsb3cuY29tcG9uZW50Lmh0bWxcIixcbiAgc3R5bGVVcmxzOiBbXCIuL2RhdGEtZmxvdy5jb21wb25lbnQubGVzc1wiXSxcbn0pXG5leHBvcnQgY2xhc3MgRGF0YUZsb3dDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBtZW51TGlzdDogW107XG4gIEBPdXRwdXQoKSBkcmF3ZXJFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgbW9kYWxFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBkYXRhID0ge1xuICAgIC8vIOiKgueCuVxuICAgIG5vZGVzOiBbXG4gICAgICB7XG4gICAgICAgIGlkOiBcIm5vZGUxXCIsIC8vIFN0cmluZ++8jOWPr+mAie+8jOiKgueCueeahOWUr+S4gOagh+ivhlxuICAgICAgICB4OiA0MCwgLy8gTnVtYmVy77yM5b+F6YCJ77yM6IqC54K55L2N572u55qEIHgg5YC8XG4gICAgICAgIHk6IDQwLCAvLyBOdW1iZXLvvIzlv4XpgInvvIzoioLngrnkvY3nva7nmoQgeSDlgLxcbiAgICAgICAgd2lkdGg6IDgwLCAvLyBOdW1iZXLvvIzlj6/pgInvvIzoioLngrnlpKflsI/nmoQgd2lkdGgg5YC8XG4gICAgICAgIGhlaWdodDogNDAsIC8vIE51bWJlcu+8jOWPr+mAie+8jOiKgueCueWkp+Wwj+eahCBoZWlnaHQg5YC8XG4gICAgICAgIGxhYmVsOiBcImhlbGxvXCIsIC8vIFN0cmluZ++8jOiKgueCueagh+etvlxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaWQ6IFwibm9kZTJcIiwgLy8gU3RyaW5n77yM6IqC54K555qE5ZSv5LiA5qCH6K+GXG4gICAgICAgIHg6IDE2MCwgLy8gTnVtYmVy77yM5b+F6YCJ77yM6IqC54K55L2N572u55qEIHgg5YC8XG4gICAgICAgIHk6IDE4MCwgLy8gTnVtYmVy77yM5b+F6YCJ77yM6IqC54K55L2N572u55qEIHkg5YC8XG4gICAgICAgIHdpZHRoOiA4MCwgLy8gTnVtYmVy77yM5Y+v6YCJ77yM6IqC54K55aSn5bCP55qEIHdpZHRoIOWAvFxuICAgICAgICBoZWlnaHQ6IDQwLCAvLyBOdW1iZXLvvIzlj6/pgInvvIzoioLngrnlpKflsI/nmoQgaGVpZ2h0IOWAvFxuICAgICAgICBsYWJlbDogXCJ3b3JsZFwiLCAvLyBTdHJpbmfvvIzoioLngrnmoIfnrb5cbiAgICAgIH0sXG4gICAgXSxcbiAgICAvLyDovrlcbiAgICBlZGdlczogW1xuICAgICAge1xuICAgICAgICBzb3VyY2U6IFwibm9kZTFcIiwgLy8gU3RyaW5n77yM5b+F6aG777yM6LW35aeL6IqC54K5IGlkXG4gICAgICAgIHRhcmdldDogXCJub2RlMlwiLCAvLyBTdHJpbmfvvIzlv4XpobvvvIznm67moIfoioLngrkgaWRcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcbiAgdGl0bGUgPSBcIm15LWFwcFwiO1xuICBncmFwaDogR3JhcGg7XG4gIHN0ZW5jaWw6IEFkZG9uLlN0ZW5jaWw7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbWVzc2FnZTogTnpNZXNzYWdlU2VydmljZSkge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmdyYXBoU2hhcGUoKTtcbiAgICB0aGlzLmdyYWhwSW5pdCgpO1xuICAgIHRoaXMuZ2V0SGlzdG9yeUdyYWhwKCk7XG4gICAgdGhpcy5ncmFwaEV2ZW50KCk7XG4gICAgLy8gY29uc29sZS5sb2coXCLoioLngrlcIiwgdGhpcy5ncmFwaC5nZXROb2RlcygpKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcImNlbGwtLS0tLVwiKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcIuiKgueCueWSjOi+uVwiLCB0aGlzLmdyYXBoLmdldENlbGxzKCkpO1xuICAgIC8vIGNvbnNvbGUubG9nKFwi5qC56IqC54K577yM5Y2z5rKh5pyJ6L6T5YWl6L6555qE6IqC54K5XCIsIHRoaXMuZ3JhcGguZ2V0Um9vdE5vZGVzKCkpO1xuICAgIC8vIGNvbnNvbGUubG9nKFwi5Y+25a2Q6IqC54K577yM5Y2z5rKh5pyJ6L6T5Ye66L6555qE6IqC54K5XCIsIHRoaXMuZ3JhcGguZ2V0TGVhZk5vZGVzKCkpO1xuICAgIC8vIGNvbnNvbGUubG9nKFwi5pWw6YePXCIsIHRoaXMuZ3JhcGguZ2V0Q2VsbENvdW50KCkpO1xuICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuZ3JhcGgpO1xuICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuc3RlbmNpbC5ncmFwaHMuZ3JvdXAxLmdldE5vZGVzKCkpO1xuICAgIGxldCBub2RlcyA9IHRoaXMuZ3JhcGguZ2V0TGVhZk5vZGVzKCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IG5vZGU6IGFueSA9IG5vZGVzW2ldO1xuICAgICAgaWYgKG5vZGVbXCJsYWJlbFwiXSAhPT0gXCLovpPlh7pcIikge1xuICAgICAgICB0aGlzLm1lc3NhZ2UuZXJyb3IoXCLnlYzpnaLlv4XpobvljIXlkKvovpPlh7pcIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdyYWhwSW5pdCgpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAvLyAjcmVnaW9uIOWIneWni+WMlueUu+W4g1xuICAgIHRoaXMuZ3JhcGggPSBuZXcgR3JhcGgoe1xuICAgICAgY29udGFpbmVyOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImdyYXBoLWNvbnRhaW5lclwiKSEsXG4gICAgICBncmlkOiB0cnVlLFxuICAgICAgaGlzdG9yeTogdHJ1ZSxcbiAgICAgIG1pbmltYXA6IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgY29udGFpbmVyOiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIm1pbmltYXBcIikhLFxuICAgICAgICB3aWR0aDogMTk4LFxuICAgICAgICBoZWlnaHQ6IDE5OCxcbiAgICAgICAgcGFkZGluZzogMTAsXG4gICAgICB9LFxuICAgICAgbW91c2V3aGVlbDoge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB6b29tQXRNb3VzZVBvc2l0aW9uOiB0cnVlLFxuICAgICAgICBtb2RpZmllcnM6IFwiY3RybFwiLFxuICAgICAgICBtaW5TY2FsZTogMC41LFxuICAgICAgICBtYXhTY2FsZTogMyxcbiAgICAgIH0sXG4gICAgICBjb25uZWN0aW5nOiB7XG4gICAgICAgIHJvdXRlcjogXCJtYW5oYXR0YW5cIixcbiAgICAgICAgY29ubmVjdG9yOiB7XG4gICAgICAgICAgbmFtZTogXCJyb3VuZGVkXCIsXG4gICAgICAgICAgYXJnczoge1xuICAgICAgICAgICAgcmFkaXVzOiA4LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFuY2hvcjogXCJjZW50ZXJcIixcbiAgICAgICAgY29ubmVjdGlvblBvaW50OiBcImFuY2hvclwiLFxuICAgICAgICBhbGxvd0JsYW5rOiBmYWxzZSxcbiAgICAgICAgc25hcDoge1xuICAgICAgICAgIHJhZGl1czogMjAsXG4gICAgICAgIH0sXG4gICAgICAgIGNyZWF0ZUVkZ2UoKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBTaGFwZS5FZGdlKHtcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgIGxpbmU6IHtcbiAgICAgICAgICAgICAgICBzdHJva2U6IFwiI0EyQjFDM1wiLFxuICAgICAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgICAgICAgICAgIHRhcmdldE1hcmtlcjoge1xuICAgICAgICAgICAgICAgICAgbmFtZTogXCJibG9ja1wiLFxuICAgICAgICAgICAgICAgICAgd2lkdGg6IDEyLFxuICAgICAgICAgICAgICAgICAgaGVpZ2h0OiA4LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgekluZGV4OiAwLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICAvLyDlnKjnp7vliqjovrnnmoTml7blgJnliKTmlq3ov57mjqXmmK/lkKbmnInmlYhcbiAgICAgICAgdmFsaWRhdGVDb25uZWN0aW9uKHtcbiAgICAgICAgICBzb3VyY2VWaWV3LFxuICAgICAgICAgIHRhcmdldFZpZXcsXG4gICAgICAgICAgc291cmNlTWFnbmV0LFxuICAgICAgICAgIHRhcmdldE1hZ25ldCxcbiAgICAgICAgICBzb3VyY2VDZWxsLFxuICAgICAgICAgIHRhcmdldENlbGwsXG4gICAgICAgIH0pIHtcbiAgICAgICAgICBpZiAodGFyZ2V0TWFnbmV0ICYmIHRhcmdldENlbGwpIHtcbiAgICAgICAgICAgIGNvbnN0IGluY29taW5nRWRnZXMgPVxuICAgICAgICAgICAgICB0aGF0LmdyYXBoIS5nZXRJbmNvbWluZ0VkZ2VzKHRhcmdldENlbGwpIHx8IFtdO1xuICAgICAgICAgICAgaWYgKGluY29taW5nRWRnZXMubGVuZ3RoID49IHRhcmdldFZpZXchLmNlbGwuZ2V0RGF0YSgpLm91dCkge1xuICAgICAgICAgICAgICB0aGF0Lm1lc3NhZ2UuZXJyb3IoXCLotoXlh7pvdXTmlbDph49cIik7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyDkuI3lhYHorrjov57mjqXliLDoh6rlt7FcbiAgICAgICAgICBpZiAoc291cmNlVmlldyA9PT0gdGFyZ2V0Vmlldykge1xuICAgICAgICAgICAgLy8gdGhhdC5tZXNzYWdlLmVycm9yKFwi5LiN5YWB6K646L+e5o6l5Yiw6Ieq5bexXCIpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIOWPquiDveS7jui+k+WHuumTvuaOpeahqeWIm+W7uui/nuaOpVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFzb3VyY2VNYWduZXQgfHxcbiAgICAgICAgICAgIHNvdXJjZU1hZ25ldC5nZXRBdHRyaWJ1dGUoXCJwb3J0LWdyb3VwXCIpID09PSBcImxlZnRcIlxuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gdGhhdC5tZXNzYWdlLmVycm9yKFwi5Y+q6IO95LuO6L6T5Ye66ZO+5o6l5qGp5Yib5bu66L+e5o6lXCIpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIOWPquiDvei/nuaOpeWIsOi+k+WFpemTvuaOpeahqVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICF0YXJnZXRNYWduZXQgfHxcbiAgICAgICAgICAgIHRhcmdldE1hZ25ldC5nZXRBdHRyaWJ1dGUoXCJwb3J0LWdyb3VwXCIpID09PSBcInJpZ2h0XCJcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIHRoYXQubWVzc2FnZS5lcnJvcihcIuWPquiDvei/nuaOpeWIsOi+k+WFpemTvuaOpeahqVwiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuICEhdGFyZ2V0TWFnbmV0O1xuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGhpZ2hsaWdodGluZzoge1xuICAgICAgICBtYWduZXRBZHNvcmJlZDoge1xuICAgICAgICAgIG5hbWU6IFwic3Ryb2tlXCIsXG4gICAgICAgICAgYXJnczoge1xuICAgICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgICAgZmlsbDogXCIjNUY5NUZGXCIsXG4gICAgICAgICAgICAgIHN0cm9rZTogXCIjNUY5NUZGXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgcmVzaXppbmc6IHRydWUsXG4gICAgICByb3RhdGluZzogdHJ1ZSxcbiAgICAgIHNlbGVjdGluZzoge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICBydWJiZXJiYW5kOiB0cnVlLFxuICAgICAgICBzaG93Tm9kZVNlbGVjdGlvbkJveDogdHJ1ZSxcbiAgICAgIH0sXG4gICAgICBzbmFwbGluZTogdHJ1ZSxcbiAgICAgIGtleWJvYXJkOiB0cnVlLFxuICAgICAgY2xpcGJvYXJkOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zdGVuY2lsID0gbmV3IEFkZG9uLlN0ZW5jaWwoe1xuICAgICAgdGFyZ2V0OiB0aGlzLmdyYXBoLFxuICAgICAgc3RlbmNpbEdyYXBoV2lkdGg6IDIwMCxcbiAgICAgIHN0ZW5jaWxHcmFwaEhlaWdodDogMTgwLFxuICAgICAgY29sbGFwc2FibGU6IHRydWUsXG4gICAgICBncm91cHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHRpdGxlOiBcIuaVsOaNruWkhOeQhlwiLFxuICAgICAgICAgIG5hbWU6IFwiZ3JvdXAxXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0aXRsZTogXCLovpPlhaXovpPlh7pcIixcbiAgICAgICAgICBuYW1lOiBcImdyb3VwMlwiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGxheW91dE9wdGlvbnM6IHtcbiAgICAgICAgY29sdW1uczogMixcbiAgICAgICAgY29sdW1uV2lkdGg6IDgwLFxuICAgICAgICByb3dIZWlnaHQ6IDU1LFxuICAgICAgfSxcbiAgICAgIHZhbGlkYXRlTm9kZShjdXJyZW50bm9kZTogYW55KSB7XG4gICAgICAgIGNvbnN0IG5vZGVzID0gdGhhdC5ncmFwaC5nZXROb2RlcygpO1xuICAgICAgICBpZiAobm9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBub2RlOiBhbnkgPSBub2Rlc1tpXTtcbiAgICAgICAgICAgIGlmIChjdXJyZW50bm9kZVtcImxhYmVsXCJdID09PSBcIui+k+WHulwiICYmIG5vZGVbXCJsYWJlbFwiXSA9PT0gXCLovpPlh7pcIikge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSxcbiAgICAgIGdldERyb3BOb2RlKG5vZGU6IGFueSkge1xuICAgICAgICBjb25zdCBzaXplID0gbm9kZS5zaXplKCk7XG4gICAgICAgIGlmIChub2RlW1wibGFiZWxcIl0gPT09IFwi6L6T5YWlXCIpIHtcbiAgICAgICAgICB0aGF0LmdldE1vZGFsKG5vZGVbXCJsYWJlbFwiXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5vZGVbXCJsYWJlbFwiXSA9PT0gXCLovpPlh7pcIikge1xuICAgICAgICAgIHIyLmF0dHIoXCJib2R5L2ZpbGxcIiwgXCIjY2NjXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vZGUuY2xvbmUoKS5zaXplKHNpemUud2lkdGggKiAxLjEsIHNpemUuaGVpZ2h0ICogMS4xKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzdGVuY2lsXCIpIS5hcHBlbmRDaGlsZCh0aGlzLnN0ZW5jaWwuY29udGFpbmVyKTtcblxuICAgIC8vICNyZWdpb24g5Yid5aeL5YyW5Zu+5b2iXG4gICAgLy8g5bi46KeE5bem5Y+z5Lik5Liq5qGpXG4gICAgY29uc3QgcG9ydHMgPSB7XG4gICAgICBncm91cHM6IHtcbiAgICAgICAgcmlnaHQ6IHtcbiAgICAgICAgICBwb3NpdGlvbjogXCJyaWdodFwiLFxuICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICBjaXJjbGU6IHtcbiAgICAgICAgICAgICAgcjogNCxcbiAgICAgICAgICAgICAgbWFnbmV0OiB0cnVlLFxuICAgICAgICAgICAgICBzdHJva2U6IFwiIzVGOTVGRlwiLFxuICAgICAgICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgICAgICAgZmlsbDogXCIjZmZmXCIsXG4gICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJpbGl0eTogXCJoaWRkZW5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgbGVmdDoge1xuICAgICAgICAgIHBvc2l0aW9uOiBcImxlZnRcIixcbiAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgY2lyY2xlOiB7XG4gICAgICAgICAgICAgIHI6IDQsXG4gICAgICAgICAgICAgIG1hZ25ldDogdHJ1ZSxcbiAgICAgICAgICAgICAgc3Ryb2tlOiBcIiM1Rjk1RkZcIixcbiAgICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgICAgICAgIGZpbGw6IFwiI2ZmZlwiLFxuICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHZpc2liaWxpdHk6IFwiaGlkZGVuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgaXRlbXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiBcInBvcnQxXCIsXG4gICAgICAgICAgZ3JvdXA6IFwibGVmdFwiLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6IFwicG9ydDJcIixcbiAgICAgICAgICBncm91cDogXCJyaWdodFwiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuXG4gICAgLy8g6L6T5YWl5Y+q5pyJ5bem5L6n5LiA5Liq5qGpXG4gICAgY29uc3QgcG9ydHMyID0ge1xuICAgICAgZ3JvdXBzOiB7XG4gICAgICAgIGxlZnQ6IHtcbiAgICAgICAgICBwb3NpdGlvbjogXCJsZWZ0XCIsXG4gICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgIGNpcmNsZToge1xuICAgICAgICAgICAgICByOiA0LFxuICAgICAgICAgICAgICBtYWduZXQ6IHRydWUsXG4gICAgICAgICAgICAgIHN0cm9rZTogXCIjNUY5NUZGXCIsXG4gICAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICAgICAgICBmaWxsOiBcIiNmZmZcIixcbiAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBcImhpZGRlblwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGl0ZW1zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogXCJwb3J0MVwiLFxuICAgICAgICAgIGdyb3VwOiBcImxlZnRcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIC8vIOi+k+WHuuWPquacieWPs+S+p+S4gOS4quahqVxuICAgIGNvbnN0IHBvcnRzMyA9IHtcbiAgICAgIGdyb3Vwczoge1xuICAgICAgICByaWdodDoge1xuICAgICAgICAgIHBvc2l0aW9uOiBcInJpZ2h0XCIsXG4gICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgIGNpcmNsZToge1xuICAgICAgICAgICAgICByOiA0LFxuICAgICAgICAgICAgICBtYWduZXQ6IHRydWUsXG4gICAgICAgICAgICAgIHN0cm9rZTogXCIjNUY5NUZGXCIsXG4gICAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICAgICAgICBmaWxsOiBcIiNmZmZcIixcbiAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBcImhpZGRlblwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGl0ZW1zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogXCJwb3J0MlwiLFxuICAgICAgICAgIGdyb3VwOiBcInJpZ2h0XCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG5cbiAgICBjb25zdCByMSA9IHRoaXMuZ3JhcGguY3JlYXRlTm9kZSh7XG4gICAgICBzaGFwZTogXCJjdXN0b20tcmVjdFwiLFxuICAgICAgaWQ6IFwiaW5cIixcbiAgICAgIGxhYmVsOiBcIui+k+WFpVwiLFxuICAgICAgcG9ydHM6IHsgLi4ucG9ydHMzIH0sXG4gICAgICBkYXRhOiB7XG4gICAgICAgIGluOiAwLFxuICAgICAgICBvdXQ6IDMsIC8v5Y+q6IO95Ye65Y67M+adoee6v1xuICAgICAgfSxcbiAgICB9KTtcbiAgICBjb25zdCByMiA9IHRoaXMuZ3JhcGguY3JlYXRlTm9kZSh7XG4gICAgICBzaGFwZTogXCJjdXN0b20tcmVjdFwiLFxuICAgICAgaWQ6IFwib3V0XCIsXG4gICAgICBsYWJlbDogXCLovpPlh7pcIixcbiAgICAgIHBvcnRzOiB7IC4uLnBvcnRzMiB9LFxuICAgICAgZGF0YToge1xuICAgICAgICBpbjogMixcbiAgICAgICAgb3V0OiAyLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG5vZGVBcnI6IGFueVtdID0gW107XG4gICAgdGhpcy5tZW51TGlzdC5mb3JFYWNoKChlbGVtZW50OiBhbnksIGkpID0+IHtcbiAgICAgIG5vZGVBcnIucHVzaChcbiAgICAgICAgdGhpcy5ncmFwaC5jcmVhdGVOb2RlKHtcbiAgICAgICAgICBzaGFwZTogXCJjdXN0b20tcmVjdFwiLFxuICAgICAgICAgIGxhYmVsOiBlbGVtZW50LnRpdGxlLFxuICAgICAgICAgIHBvcnRzOiB7IC4uLnBvcnRzIH0sXG4gICAgICAgICAgZGF0YTogZWxlbWVudC5kYXRhLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRoaXMuc3RlbmNpbC5sb2FkKFtyMSwgcjJdLCBcImdyb3VwMVwiKTtcbiAgICB0aGlzLnN0ZW5jaWwubG9hZChbLi4ubm9kZUFycl0sIFwiZ3JvdXAyXCIpO1xuICB9XG5cbiAgZ3JhcGhFdmVudCgpIHtcbiAgICAvLyBkZWxldGVcbiAgICB0aGlzLmdyYXBoLmJpbmRLZXkoXCJiYWNrc3BhY2VcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY2VsbHMgPSB0aGlzLmdyYXBoLmdldFNlbGVjdGVkQ2VsbHMoKTtcbiAgICAgIGlmIChjZWxscy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5ncmFwaC5yZW1vdmVDZWxscyhjZWxscyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyDmjqfliLbov57mjqXmoanmmL7npLov6ZqQ6JePXG4gICAgY29uc3Qgc2hvd1BvcnRzID0gKHBvcnRzOiBOb2RlTGlzdE9mPFNWR0VsZW1lbnQ+LCBzaG93OiBib29sZWFuKSA9PiB7XG4gICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcG9ydHMubGVuZ3RoOyBpIDwgbGVuOyBpID0gaSArIDEpIHtcbiAgICAgICAgcG9ydHNbaV0uc3R5bGUudmlzaWJpbGl0eSA9IHNob3cgPyBcInZpc2libGVcIiA6IFwiaGlkZGVuXCI7XG4gICAgICB9XG4gICAgfTtcbiAgICB0aGlzLmdyYXBoLm9uKFwibm9kZTptb3VzZWVudGVyXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZ3JhcGgtY29udGFpbmVyXCIpITtcbiAgICAgIGNvbnN0IHBvcnRzID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIFwiLng2LXBvcnQtYm9keVwiXG4gICAgICApIGFzIE5vZGVMaXN0T2Y8U1ZHRWxlbWVudD47XG4gICAgICBzaG93UG9ydHMocG9ydHMsIHRydWUpO1xuICAgIH0pO1xuICAgIHRoaXMuZ3JhcGgub24oXCJub2RlOm1vdXNlbGVhdmVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJncmFwaC1jb250YWluZXJcIikhO1xuICAgICAgY29uc3QgcG9ydHMgPSBjb250YWluZXIucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgXCIueDYtcG9ydC1ib2R5XCJcbiAgICAgICkgYXMgTm9kZUxpc3RPZjxTVkdFbGVtZW50PjtcbiAgICAgIHNob3dQb3J0cyhwb3J0cywgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgLy8gdGhpcy5ncmFwaC5vbihcbiAgICAvLyAgIFwiZWRnZTpjb25uZWN0ZWRcIixcbiAgICAvLyAgICh7IGlzTmV3LCBjdXJyZW50TWFnbmV0LCBjdXJyZW50Q2VsbCB9KSA9PiB7fVxuICAgIC8vICk7XG5cbiAgICAvLyB0aGlzLmdyYXBoLm9uKFwiZWRnZTphZGRlZFwiLCAoeyBjZWxsLCBpbmRleCwgb3B0aW9ucyB9KSA9PiB7fSk7XG5cbiAgICAvLyB0aGlzLmdyYXBoLm9uKFxuICAgIC8vICAgXCJlZGdlOmNoYW5nZToqXCIsXG4gICAgLy8gICAoYXJnczoge1xuICAgIC8vICAgICBrZXk6IHN0cmluZzsgLy8g6YCa6L+HIGtleSDmnaXnoa7lrprmlLnlj5jpoblcbiAgICAvLyAgICAgY3VycmVudDogYW55OyAvLyDlvZPliY3lgLzvvIznsbvlnovmoLnmja4ga2V5IOaMh+S7o+eahOexu+Wei+ehruWumlxuICAgIC8vICAgICBwcmV2aW91czogYW55OyAvLyDmlLnlj5jkuYvliY3nmoTlgLzvvIznsbvlnovmoLnmja4ga2V5IOaMh+S7o+eahOexu+Wei+ehruWumlxuICAgIC8vICAgICBvcHRpb25zOiBhbnk7IC8vIOmAj+S8oOeahCBvcHRpb25zXG4gICAgLy8gICB9KSA9PiB7XG4gICAgLy8gICAgIGNvbnNvbGUubG9nKFwia2V5OlwiLCBhcmdzLmtleSk7XG4gICAgLy8gICB9XG4gICAgLy8gKTtcblxuICAgIC8vIHRoaXMuZ3JhcGgub24oXCJlZGdlOmNoYW5nZWRcIiwgKHsgZWRnZSwgb3B0aW9ucyB9KSA9PiB7fSk7XG5cbiAgICB0aGlzLmdyYXBoLm9uKFwibm9kZTpjbGlja1wiLCAoeyBjZWxsLCB2aWV3IH0pID0+IHtcbiAgICAgIGxldCBub2RlOiBhbnkgPSB2aWV3LmNlbGw7XG4gICAgICBjb25zb2xlLmxvZyhub2RlLmxhYmVsKTtcbiAgICAgIGlmIChub2RlLmxhYmVsID09PSBcIui+k+WFpVwiKSB7XG4gICAgICAgIHRoaXMuZ2V0TW9kYWwobm9kZS5sYWJlbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmdldERyYXdlcihub2RlLmxhYmVsKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGdldEhpc3RvcnlHcmFocCgpIHtcbiAgICBsZXQganNvbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwiZ3JhcGhKU09OXCIpO1xuICAgIGlmIChqc29uKSB7XG4gICAgICB0aGlzLmdyYXBoLmZyb21KU09OKEpTT04ucGFyc2UoanNvbikpO1xuICAgIH1cbiAgfVxuXG4gIGdldE1vZGFsKGxhYmVsOiBhbnkpIHtcbiAgICB0aGlzLm1vZGFsRXZlbnQuZ