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,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