UNPKG

kre-form

Version:

本项目由 Angular8+ 编写的表单设计器和表单应用,所有的配置都是 JSON 结构体组成,PC 端是基于 ANT 组件库封装

595 lines 51.9 kB
/** * @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 >&lt;</span\n >\n <span\n (click)=\"handleRedo()\"\n [ngClass]=\"{ on: graph.history.canRedo() }\"\n class=\"toolbar-btn-off\"\n >&gt;</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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1mbG93LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BrcmUtZm9ybS9hYmMvc3JjL2xpYi9kYXRhLWZsb3cvIiwic291cmNlcyI6WyJkYXRhLWZsb3cuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUlULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxHQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBUSxNQUFNLFVBQVUsQ0FBQztBQUVyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQU96RCxNQUFNLE9BQU8saUJBQWlCOzs7O0lBbUM1QixZQUFvQixPQUF5QjtRQUF6QixZQUFPLEdBQVAsT0FBTyxDQUFrQjtRQWpDbkMsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBQ3RDLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBQy9DLFNBQUksR0FBRzs7WUFFTCxLQUFLLEVBQUU7Z0JBQ0w7b0JBQ0UsRUFBRSxFQUFFLE9BQU87O29CQUNYLENBQUMsRUFBRSxFQUFFOztvQkFDTCxDQUFDLEVBQUUsRUFBRTs7b0JBQ0wsS0FBSyxFQUFFLEVBQUU7O29CQUNULE1BQU0sRUFBRSxFQUFFOztvQkFDVixLQUFLLEVBQUUsT0FBTztpQkFDZjtnQkFDRDtvQkFDRSxFQUFFLEVBQUUsT0FBTzs7b0JBQ1gsQ0FBQyxFQUFFLEdBQUc7O29CQUNOLENBQUMsRUFBRSxHQUFHOztvQkFDTixLQUFLLEVBQUUsRUFBRTs7b0JBQ1QsTUFBTSxFQUFFLEVBQUU7O29CQUNWLEtBQUssRUFBRSxPQUFPO2lCQUNmO2FBQ0Y7O1lBRUQsS0FBSyxFQUFFO2dCQUNMO29CQUNFLE1BQU0sRUFBRSxPQUFPOztvQkFDZixNQUFNLEVBQUUsT0FBTztpQkFDaEI7YUFDRjtTQUNGLENBQUM7UUFDRixV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SUFGUCxxQ0FBc0I7O0lBQ3RCLHdDQUFnRDs7SUFDaEQsdUNBQStDOztJQUMvQyxpQ0EyQkU7O0lBQ0Ysa0NBQWlCOztJQUNqQixrQ0FBYTs7SUFDYixvQ0FBdUI7Ozs7O0lBQ1gsb0NBQWlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBPbkluaXQsXG4gIFZpZXdDaGlsZCxcbiAgVGVtcGxhdGVSZWYsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEdyYXBoLCBTaGFwZSwgQWRkb24sIE5vZGUgfSBmcm9tIFwiQGFudHYveDZcIjtcbmltcG9ydCB7IG5vZGVDZW50ZXIgfSBmcm9tIFwiQGFudHYveDYvbGliL3JlZ2lzdHJ5L25vZGUtYW5jaG9yL25vZGUtY2VudGVyXCI7XG5pbXBvcnQgeyBOek1lc3NhZ2VTZXJ2aWNlIH0gZnJvbSBcIm5nLXpvcnJvLWFudGQvbWVzc2FnZVwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwiZGF0YS1mbG93XCIsXG4gIHRlbXBsYXRlVXJsOiBcIi4vZGF0YS1mbG93LmNvbXBvbmVudC5odG1sXCIsXG4gIHN0eWxlVXJsczogW1wiLi9kYXRhLWZsb3cuY29tcG9uZW50Lmxlc3NcIl0sXG59KVxuZXhwb3J0IGNsYXNzIERhdGFGbG93Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgbWVudUxpc3Q6IFtdO1xuICBAT3V0cHV0KCkgZHJhd2VyRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIG1vZGFsRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgZGF0YSA9IHtcbiAgICAvLyDoioLngrlcbiAgICBub2RlczogW1xuICAgICAge1xuICAgICAgICBpZDogXCJub2RlMVwiLCAvLyBTdHJpbmfvvIzlj6/pgInvvIzoioLngrnnmoTllK/kuIDmoIfor4ZcbiAgICAgICAgeDogNDAsIC8vIE51bWJlcu+8jOW/hemAie+8jOiKgueCueS9jee9rueahCB4IOWAvFxuICAgICAgICB5OiA0MCwgLy8gTnVtYmVy77yM5b+F6YCJ77yM6IqC54K55L2N572u55qEIHkg5YC8XG4gICAgICAgIHdpZHRoOiA4MCwgLy8gTnVtYmVy77yM5Y+v6YCJ77yM6IqC54K55aSn5bCP55qEIHdpZHRoIOWAvFxuICAgICAgICBoZWlnaHQ6IDQwLCAvLyBOdW1iZXLvvIzlj6/pgInvvIzoioLngrnlpKflsI/nmoQgaGVpZ2h0IOWAvFxuICAgICAgICBsYWJlbDogXCJoZWxsb1wiLCAvLyBTdHJpbmfvvIzoioLngrnmoIfnrb5cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiBcIm5vZGUyXCIsIC8vIFN0cmluZ++8jOiKgueCueeahOWUr+S4gOagh+ivhlxuICAgICAgICB4OiAxNjAsIC8vIE51bWJlcu+8jOW/hemAie+8jOiKgueCueS9jee9rueahCB4IOWAvFxuICAgICAgICB5OiAxODAsIC8vIE51bWJlcu+8jOW/hemAie+8jOiKgueCueS9jee9rueahCB5IOWAvFxuICAgICAgICB3aWR0aDogODAsIC8vIE51bWJlcu+8jOWPr+mAie+8jOiKgueCueWkp+Wwj+eahCB3aWR0aCDlgLxcbiAgICAgICAgaGVpZ2h0OiA0MCwgLy8gTnVtYmVy77yM5Y+v6YCJ77yM6IqC54K55aSn5bCP55qEIGhlaWdodCDlgLxcbiAgICAgICAgbGFiZWw6IFwid29ybGRcIiwgLy8gU3RyaW5n77yM6IqC54K55qCH562+XG4gICAgICB9LFxuICAgIF0sXG4gICAgLy8g6L65XG4gICAgZWRnZXM6IFtcbiAgICAgIHtcbiAgICAgICAgc291cmNlOiBcIm5vZGUxXCIsIC8vIFN0cmluZ++8jOW/hemhu++8jOi1t+Wni+iKgueCuSBpZFxuICAgICAgICB0YXJnZXQ6IFwibm9kZTJcIiwgLy8gU3RyaW5n77yM5b+F6aG777yM55uu5qCH6IqC54K5IGlkXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG4gIHRpdGxlID0gXCJteS1hcHBcIjtcbiAgZ3JhcGg6IEdyYXBoO1xuICBzdGVuY2lsOiBBZGRvbi5TdGVuY2lsO1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG1lc3NhZ2U6IE56TWVzc2FnZVNlcnZpY2UpIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5ncmFwaFNoYXBlKCk7XG4gICAgdGhpcy5ncmFocEluaXQoKTtcbiAgICB0aGlzLmdldEhpc3RvcnlHcmFocCgpO1xuICAgIHRoaXMuZ3JhcGhFdmVudCgpO1xuICAgIC8vIGNvbnNvbGUubG9nKFwi6IqC54K5XCIsIHRoaXMuZ3JhcGguZ2V0Tm9kZXMoKSk7XG4gICAgLy8gY29uc29sZS5sb2coXCJjZWxsLS0tLS1cIik7XG4gICAgLy8gY29uc29sZS5sb2coXCLoioLngrnlkozovrlcIiwgdGhpcy5ncmFwaC5nZXRDZWxscygpKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcIuagueiKgueCue+8jOWNs+ayoeaciei+k+WFpei+ueeahOiKgueCuVwiLCB0aGlzLmdyYXBoLmdldFJvb3ROb2RlcygpKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcIuWPtuWtkOiKgueCue+8jOWNs+ayoeaciei+k+WHuui+ueeahOiKgueCuVwiLCB0aGlzLmdyYXBoLmdldExlYWZOb2RlcygpKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcIuaVsOmHj1wiLCB0aGlzLmdyYXBoLmdldENlbGxDb3VudCgpKTtcbiAgICAvLyBjb25zb2xlLmxvZyh0aGlzLmdyYXBoKTtcbiAgICAvLyBjb25zb2xlLmxvZyh0aGlzLnN0ZW5jaWwuZ3JhcGhzLmdyb3VwMS5nZXROb2RlcygpKTtcbiAgICBsZXQgbm9kZXMgPSB0aGlzLmdyYXBoLmdldExlYWZOb2RlcygpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBub2RlOiBhbnkgPSBub2Rlc1tpXTtcbiAgICAgIGlmIChub2RlW1wibGFiZWxcIl0gIT09IFwi6L6T5Ye6XCIpIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlLmVycm9yKFwi55WM6Z2i5b+F6aG75YyF5ZCr6L6T5Ye6XCIpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBncmFocEluaXQoKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgLy8gI3JlZ2lvbiDliJ3lp4vljJbnlLvluINcbiAgICB0aGlzLmdyYXBoID0gbmV3IEdyYXBoKHtcbiAgICAgIGNvbnRhaW5lcjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJncmFwaC1jb250YWluZXJcIikhLFxuICAgICAgZ3JpZDogdHJ1ZSxcbiAgICAgIGhpc3Rvcnk6IHRydWUsXG4gICAgICBtaW5pbWFwOiB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIGNvbnRhaW5lcjogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtaW5pbWFwXCIpISxcbiAgICAgICAgd2lkdGg6IDE5OCxcbiAgICAgICAgaGVpZ2h0OiAxOTgsXG4gICAgICAgIHBhZGRpbmc6IDEwLFxuICAgICAgfSxcbiAgICAgIG1vdXNld2hlZWw6IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgem9vbUF0TW91c2VQb3NpdGlvbjogdHJ1ZSxcbiAgICAgICAgbW9kaWZpZXJzOiBcImN0cmxcIixcbiAgICAgICAgbWluU2NhbGU6IDAuNSxcbiAgICAgICAgbWF4U2NhbGU6IDMsXG4gICAgICB9LFxuICAgICAgY29ubmVjdGluZzoge1xuICAgICAgICByb3V0ZXI6IFwibWFuaGF0dGFuXCIsXG4gICAgICAgIGNvbm5lY3Rvcjoge1xuICAgICAgICAgIG5hbWU6IFwicm91bmRlZFwiLFxuICAgICAgICAgIGFyZ3M6IHtcbiAgICAgICAgICAgIHJhZGl1czogOCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBhbmNob3I6IFwiY2VudGVyXCIsXG4gICAgICAgIGNvbm5lY3Rpb25Qb2ludDogXCJhbmNob3JcIixcbiAgICAgICAgYWxsb3dCbGFuazogZmFsc2UsXG4gICAgICAgIHNuYXA6IHtcbiAgICAgICAgICByYWRpdXM6IDIwLFxuICAgICAgICB9LFxuICAgICAgICBjcmVhdGVFZGdlKCkge1xuICAgICAgICAgIHJldHVybiBuZXcgU2hhcGUuRWRnZSh7XG4gICAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBcIiNBMkIxQzNcIixcbiAgICAgICAgICAgICAgICBzdHJva2VXaWR0aDogMixcbiAgICAgICAgICAgICAgICB0YXJnZXRNYXJrZXI6IHtcbiAgICAgICAgICAgICAgICAgIG5hbWU6IFwiYmxvY2tcIixcbiAgICAgICAgICAgICAgICAgIHdpZHRoOiAxMixcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogOCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHpJbmRleDogMCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgLy8g5Zyo56e75Yqo6L6555qE5pe25YCZ5Yik5pat6L+e5o6l5piv5ZCm5pyJ5pWIXG4gICAgICAgIHZhbGlkYXRlQ29ubmVjdGlvbih7XG4gICAgICAgICAgc291cmNlVmlldyxcbiAgICAgICAgICB0YXJnZXRWaWV3LFxuICAgICAgICAgIHNvdXJjZU1hZ25ldCxcbiAgICAgICAgICB0YXJnZXRNYWduZXQsXG4gICAgICAgICAgc291cmNlQ2VsbCxcbiAgICAgICAgICB0YXJnZXRDZWxsLFxuICAgICAgICB9KSB7XG4gICAgICAgICAgaWYgKHRhcmdldE1hZ25ldCAmJiB0YXJnZXRDZWxsKSB7XG4gICAgICAgICAgICBjb25zdCBpbmNvbWluZ0VkZ2VzID1cbiAgICAgICAgICAgICAgdGhhdC5ncmFwaCEuZ2V0SW5jb21pbmdFZGdlcyh0YXJnZXRDZWxsKSB8fCBbXTtcbiAgICAgICAgICAgIGlmIChpbmNvbWluZ0VkZ2VzLmxlbmd0aCA+PSB0YXJnZXRWaWV3IS5jZWxsLmdldERhdGEoKS5vdXQpIHtcbiAgICAgICAgICAgICAgdGhhdC5tZXNzYWdlLmVycm9yKFwi6LaF5Ye6b3V05pWw6YePXCIpO1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8g5LiN5YWB6K646L+e5o6l5Yiw6Ieq5bexXG4gICAgICAgICAgaWYgKHNvdXJjZVZpZXcgPT09IHRhcmdldFZpZXcpIHtcbiAgICAgICAgICAgIC8vIHRoYXQubWVzc2FnZS5lcnJvcihcIuS4jeWFgeiuuOi/nuaOpeWIsOiHquW3sVwiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyDlj6rog73ku47ovpPlh7rpk77mjqXmoanliJvlu7rov57mjqVcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhc291cmNlTWFnbmV0IHx8XG4gICAgICAgICAgICBzb3VyY2VNYWduZXQuZ2V0QXR0cmlidXRlKFwicG9ydC1ncm91cFwiKSA9PT0gXCJsZWZ0XCJcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIHRoYXQubWVzc2FnZS5lcnJvcihcIuWPquiDveS7jui+k+WHuumTvuaOpeahqeWIm+W7uui/nuaOpVwiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyDlj6rog73ov57mjqXliLDovpPlhaXpk77mjqXmoalcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhdGFyZ2V0TWFnbmV0IHx8XG4gICAgICAgICAgICB0YXJnZXRNYWduZXQuZ2V0QXR0cmlidXRlKFwicG9ydC1ncm91cFwiKSA9PT0gXCJyaWdodFwiXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyB0aGF0Lm1lc3NhZ2UuZXJyb3IoXCLlj6rog73ov57mjqXliLDovpPlhaXpk77mjqXmoalcIik7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiAhIXRhcmdldE1hZ25ldDtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBoaWdobGlnaHRpbmc6IHtcbiAgICAgICAgbWFnbmV0QWRzb3JiZWQ6IHtcbiAgICAgICAgICBuYW1lOiBcInN0cm9rZVwiLFxuICAgICAgICAgIGFyZ3M6IHtcbiAgICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICAgIGZpbGw6IFwiIzVGOTVGRlwiLFxuICAgICAgICAgICAgICBzdHJva2U6IFwiIzVGOTVGRlwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlc2l6aW5nOiB0cnVlLFxuICAgICAgcm90YXRpbmc6IHRydWUsXG4gICAgICBzZWxlY3Rpbmc6IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgcnViYmVyYmFuZDogdHJ1ZSxcbiAgICAgICAgc2hvd05vZGVTZWxlY3Rpb25Cb3g6IHRydWUsXG4gICAgICB9LFxuICAgICAgc25hcGxpbmU6IHRydWUsXG4gICAgICBrZXlib2FyZDogdHJ1ZSxcbiAgICAgIGNsaXBib2FyZDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIHRoaXMuc3RlbmNpbCA9IG5ldyBBZGRvbi5TdGVuY2lsKHtcbiAgICAgIHRhcmdldDogdGhpcy5ncmFwaCxcbiAgICAgIHN0ZW5jaWxHcmFwaFdpZHRoOiAyMDAsXG4gICAgICBzdGVuY2lsR3JhcGhIZWlnaHQ6IDE4MCxcbiAgICAgIGNvbGxhcHNhYmxlOiB0cnVlLFxuICAgICAgZ3JvdXBzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0aXRsZTogXCLmlbDmja7lpITnkIZcIixcbiAgICAgICAgICBuYW1lOiBcImdyb3VwMVwiLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdGl0bGU6IFwi6L6T5YWl6L6T5Ye6XCIsXG4gICAgICAgICAgbmFtZTogXCJncm91cDJcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBsYXlvdXRPcHRpb25zOiB7XG4gICAgICAgIGNvbHVtbnM6IDIsXG4gICAgICAgIGNvbHVtbldpZHRoOiA4MCxcbiAgICAgICAgcm93SGVpZ2h0OiA1NSxcbiAgICAgIH0sXG4gICAgICB2YWxpZGF0ZU5vZGUoY3VycmVudG5vZGU6IGFueSkge1xuICAgICAgICBjb25zdCBub2RlcyA9IHRoYXQuZ3JhcGguZ2V0Tm9kZXMoKTtcbiAgICAgICAgaWYgKG5vZGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbm9kZTogYW55ID0gbm9kZXNbaV07XG4gICAgICAgICAgICBpZiAoY3VycmVudG5vZGVbXCJsYWJlbFwiXSA9PT0gXCLovpPlh7pcIiAmJiBub2RlW1wibGFiZWxcIl0gPT09IFwi6L6T5Ye6XCIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0sXG4gICAgICBnZXREcm9wTm9kZShub2RlOiBhbnkpIHtcbiAgICAgICAgY29uc3Qgc2l6ZSA9IG5vZGUuc2l6ZSgpO1xuICAgICAgICBpZiAobm9kZVtcImxhYmVsXCJdID09PSBcIui+k+WFpVwiKSB7XG4gICAgICAgICAgdGhhdC5nZXRNb2RhbChub2RlW1wibGFiZWxcIl0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlW1wibGFiZWxcIl0gPT09IFwi6L6T5Ye6XCIpIHtcbiAgICAgICAgICByMi5hdHRyKFwiYm9keS9maWxsXCIsIFwiI2NjY1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBub2RlLmNsb25lKCkuc2l6ZShzaXplLndpZHRoICogMS4xLCBzaXplLmhlaWdodCAqIDEuMSk7XG4gICAgICB9LFxuICAgIH0pO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic3RlbmNpbFwiKSEuYXBwZW5kQ2hpbGQodGhpcy5zdGVuY2lsLmNvbnRhaW5lcik7XG5cbiAgICAvLyAjcmVnaW9uIOWIneWni+WMluWbvuW9olxuICAgIC8vIOW4uOinhOW3puWPs+S4pOS4quahqVxuICAgIGNvbnN0IHBvcnRzID0ge1xuICAgICAgZ3JvdXBzOiB7XG4gICAgICAgIHJpZ2h0OiB7XG4gICAgICAgICAgcG9zaXRpb246IFwicmlnaHRcIixcbiAgICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgY2lyY2xlOiB7XG4gICAgICAgICAgICAgIHI6IDQsXG4gICAgICAgICAgICAgIG1hZ25ldDogdHJ1ZSxcbiAgICAgICAgICAgICAgc3Ryb2tlOiBcIiM1Rjk1RkZcIixcbiAgICAgICAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgICAgICAgIGZpbGw6IFwiI2ZmZlwiLFxuICAgICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICAgIHZpc2liaWxpdHk6IFwiaGlkZGVuXCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGxlZnQ6IHtcbiAgICAgICAgICBwb3NpdGlvbjogXCJsZWZ0XCIsXG4gICAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICAgIGNpcmNsZToge1xuICAgICAgICAgICAgICByOiA0LFxuICAgICAgICAgICAgICBtYWduZXQ6IHRydWUsXG4gICAgICAgICAgICAgIHN0cm9rZTogXCIjNUY5NUZGXCIsXG4gICAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICAgICAgICBmaWxsOiBcIiNmZmZcIixcbiAgICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBcImhpZGRlblwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGl0ZW1zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogXCJwb3J0MVwiLFxuICAgICAgICAgIGdyb3VwOiBcImxlZnRcIixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiBcInBvcnQyXCIsXG4gICAgICAgICAgZ3JvdXA6IFwicmlnaHRcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIC8vIOi+k+WFpeWPquacieW3puS+p+S4gOS4quahqVxuICAgIGNvbnN0IHBvcnRzMiA9IHtcbiAgICAgIGdyb3Vwczoge1xuICAgICAgICBsZWZ0OiB7XG4gICAgICAgICAgcG9zaXRpb246IFwibGVmdFwiLFxuICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICBjaXJjbGU6IHtcbiAgICAgICAgICAgICAgcjogNCxcbiAgICAgICAgICAgICAgbWFnbmV0OiB0cnVlLFxuICAgICAgICAgICAgICBzdHJva2U6IFwiIzVGOTVGRlwiLFxuICAgICAgICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgICAgICAgZmlsbDogXCIjZmZmXCIsXG4gICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJpbGl0eTogXCJoaWRkZW5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBpdGVtczogW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6IFwicG9ydDFcIixcbiAgICAgICAgICBncm91cDogXCJsZWZ0XCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG5cbiAgICAvLyDovpPlh7rlj6rmnInlj7PkvqfkuIDkuKrmoalcbiAgICBjb25zdCBwb3J0czMgPSB7XG4gICAgICBncm91cHM6IHtcbiAgICAgICAgcmlnaHQ6IHtcbiAgICAgICAgICBwb3NpdGlvbjogXCJyaWdodFwiLFxuICAgICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgICBjaXJjbGU6IHtcbiAgICAgICAgICAgICAgcjogNCxcbiAgICAgICAgICAgICAgbWFnbmV0OiB0cnVlLFxuICAgICAgICAgICAgICBzdHJva2U6IFwiIzVGOTVGRlwiLFxuICAgICAgICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgICAgICAgZmlsbDogXCIjZmZmXCIsXG4gICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgdmlzaWJpbGl0eTogXCJoaWRkZW5cIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBpdGVtczogW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6IFwicG9ydDJcIixcbiAgICAgICAgICBncm91cDogXCJyaWdodFwiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuXG4gICAgY29uc3QgcjEgPSB0aGlzLmdyYXBoLmNyZWF0ZU5vZGUoe1xuICAgICAgc2hhcGU6IFwiY3VzdG9tLXJlY3RcIixcbiAgICAgIGlkOiBcImluXCIsXG4gICAgICBsYWJlbDogXCLovpPlhaVcIixcbiAgICAgIHBvcnRzOiB7IC4uLnBvcnRzMyB9LFxuICAgICAgZGF0YToge1xuICAgICAgICBpbjogMCxcbiAgICAgICAgb3V0OiAzLCAvL+WPquiDveWHuuWOuzPmnaHnur9cbiAgICAgIH0sXG4gICAgfSk7XG4gICAgY29uc3QgcjIgPSB0aGlzLmdyYXBoLmNyZWF0ZU5vZGUoe1xuICAgICAgc2hhcGU6IFwiY3VzdG9tLXJlY3RcIixcbiAgICAgIGlkOiBcIm91dFwiLFxuICAgICAgbGFiZWw6IFwi6L6T5Ye6XCIsXG4gICAgICBwb3J0czogeyAuLi5wb3J0czIgfSxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgaW46IDIsXG4gICAgICAgIG91dDogMixcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBub2RlQXJyOiBhbnlbXSA9IFtdO1xuICAgIHRoaXMubWVudUxpc3QuZm9yRWFjaCgoZWxlbWVudDogYW55LCBpKSA9PiB7XG4gICAgICBub2RlQXJyLnB1c2goXG4gICAgICAgIHRoaXMuZ3JhcGguY3JlYXRlTm9kZSh7XG4gICAgICAgICAgc2hhcGU6IFwiY3VzdG9tLXJlY3RcIixcbiAgICAgICAgICBsYWJlbDogZWxlbWVudC50aXRsZSxcbiAgICAgICAgICBwb3J0czogeyAuLi5wb3J0cyB9LFxuICAgICAgICAgIGRhdGE6IGVsZW1lbnQuZGF0YSxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnN0ZW5jaWwubG9hZChbcjEsIHIyXSwgXCJncm91cDFcIik7XG4gICAgdGhpcy5zdGVuY2lsLmxvYWQoWy4uLm5vZGVBcnJdLCBcImdyb3VwMlwiKTtcbiAgfVxuXG4gIGdyYXBoRXZlbnQoKSB7XG4gICAgLy8gZGVsZXRlXG4gICAgdGhpcy5ncmFwaC5iaW5kS2V5KFwiYmFja3NwYWNlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNlbGxzID0gdGhpcy5ncmFwaC5nZXRTZWxlY3RlZENlbGxzKCk7XG4gICAgICBpZiAoY2VsbHMubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuZ3JhcGgucmVtb3ZlQ2VsbHMoY2VsbHMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8g5o6n5Yi26L+e5o6l5qGp5pi+56S6L+makOiXj1xuICAgIGNvbnN0IHNob3dQb3J0cyA9IChwb3J0czogTm9kZUxpc3RPZjxTVkdFbGVtZW50Piwgc2hvdzogYm9vbGVhbikgPT4ge1xuICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHBvcnRzLmxlbmd0aDsgaSA8IGxlbjsgaSA9IGkgKyAxKSB7XG4gICAgICAgIHBvcnRzW2ldLnN0eWxlLnZpc2liaWxpdHkgPSBzaG93ID8gXCJ2aXNpYmxlXCIgOiBcImhpZGRlblwiO1xuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5ncmFwaC5vbihcIm5vZGU6bW91c2VlbnRlclwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImdyYXBoLWNvbnRhaW5lclwiKSE7XG4gICAgICBjb25zdCBwb3J0cyA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICBcIi54Ni1wb3J0LWJvZHlcIlxuICAgICAgKSBhcyBOb2RlTGlzdE9mPFNWR0VsZW1lbnQ+O1xuICAgICAgc2hvd1BvcnRzKHBvcnRzLCB0cnVlKTtcbiAgICB9KTtcbiAgICB0aGlzLmdyYXBoLm9uKFwibm9kZTptb3VzZWxlYXZlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiZ3JhcGgtY29udGFpbmVyXCIpITtcbiAgICAgIGNvbnN0IHBvcnRzID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIFwiLng2LXBvcnQtYm9keVwiXG4gICAgICApIGFzIE5vZGVMaXN0T2Y8U1ZHRWxlbWVudD47XG4gICAgICBzaG93UG9ydHMocG9ydHMsIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIC8vIHRoaXMuZ3JhcGgub24oXG4gICAgLy8gICBcImVkZ2U6Y29ubmVjdGVkXCIsXG4gICAgLy8gICAoeyBpc05ldywgY3VycmVudE1hZ25ldCwgY3VycmVudENlbGwgfSkgPT4ge31cbiAgICAvLyApO1xuXG4gICAgLy8gdGhpcy5ncmFwaC5vbihcImVkZ2U6YWRkZWRcIiwgKHsgY2VsbCwgaW5kZXgsIG9wdGlvbnMgfSkgPT4ge30pO1xuXG4gICAgLy8gdGhpcy5ncmFwaC5vbihcbiAgICAvLyAgIFwiZWRnZTpjaGFuZ2U6KlwiLFxuICAgIC8vICAgKGFyZ3M6IHtcbiAgICAvLyAgICAga2V5OiBzdHJpbmc7IC8vIOmAmui/hyBrZXkg5p2l56Gu5a6a5pS55Y+Y6aG5XG4gICAgLy8gICAgIGN1cnJlbnQ6IGFueTsgLy8g5b2T5YmN5YC877yM57G75Z6L5qC55o2uIGtleSDmjIfku6PnmoTnsbvlnovnoa7lrppcbiAgICAvLyAgICAgcHJldmlvdXM6IGFueTsgLy8g5pS55Y+Y5LmL5YmN55qE5YC877yM57G75Z6L5qC55o2uIGtleSDmjIfku6PnmoTnsbvlnovnoa7lrppcbiAgICAvLyAgICAgb3B0aW9uczogYW55OyAvLyDpgI/kvKDnmoQgb3B0aW9uc1xuICAgIC8vICAgfSkgPT4ge1xuICAgIC8vICAgICBjb25zb2xlLmxvZyhcImtleTpcIiwgYXJncy5rZXkpO1xuICAgIC8vICAgfVxuICAgIC8vICk7XG5cbiAgICAvLyB0aGlzLmdyYXBoLm9uKFwiZWRnZTpjaGFuZ2VkXCIsICh7IGVkZ2UsIG9wdGlvbnMgfSkgPT4ge30pO1xuXG4gICAgdGhpcy5ncmFwaC5vbihcIm5vZGU6Y2xpY2tcIiwgKHsgY2VsbCwgdmlldyB9KSA9PiB7XG4gICAgICBsZXQgbm9kZTogYW55ID0gdmlldy5jZWxsO1xuICAgICAgY29uc29sZS5sb2cobm9kZS5sYWJlbCk7XG4gICAgICBpZiAobm9kZS5sYWJlbCA9PT0gXCLovpPlhaVcIikge1xuICAgICAgICB0aGlzLmdldE1vZGFsKG5vZGUubGFiZWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5nZXREcmF3ZXIobm9kZS5sYWJlbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBnZXRIaXN0b3J5R3JhaHAoKSB7XG4gICAgbGV0IGpzb24gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShcImdyYXBoSlNPTlwiKTtcbiAgICBpZiAoanNvbikge1xuICAgICAgdGhpcy5ncmFwaC5mcm9tSlNPTihKU09OLnBhcnNlKGpzb24pKTtcbiAgICB9XG4gIH1cblxuICBnZXRNb2RhbChsYWJlbDogYW55KSB7XG4gICAgdGhpcy5tb2RhbEV2Z