UNPKG

react-planner-viewer

Version:

react-planner-viewer is a React Component for view plans builded with react-planner in 2D mode

400 lines (326 loc) 48.5 kB
import { List, Map } from 'immutable'; import { SELECT_TOOL_DRAWING_LINE, BEGIN_DRAWING_LINE, UPDATE_DRAWING_LINE, END_DRAWING_LINE, BEGIN_DRAGGING_LINE, UPDATE_DRAGGING_LINE, END_DRAGGING_LINE, SELECT_LINE, MODE_IDLE, MODE_WAITING_DRAWING_LINE, MODE_DRAWING_LINE, MODE_DRAGGING_LINE } from '../constants'; import * as Geometry from '../utils/geometry'; import { addLine, replaceLineVertex, removeLine, select, unselect, addLineAvoidingIntersections, unselectAll, detectAndUpdateAreas, mergeEqualsVertices } from '../utils/layer-operations'; import { nearestSnap, addPointSnap, addLineSnap, addLineSegmentSnap } from '../utils/snap'; import { sceneSnapElements } from '../utils/snap-scene'; import { samePoints } from "../utils/geometry"; export default function (state, action) { switch (action.type) { case SELECT_TOOL_DRAWING_LINE: return selectToolDrawingLine(state, action.sceneComponentType); case BEGIN_DRAWING_LINE: return beginDrawingLine(state, action.layerID, action.x, action.y); case UPDATE_DRAWING_LINE: return updateDrawingLine(state, action.x, action.y); case END_DRAWING_LINE: return endDrawingLine(state, action.x, action.y); case BEGIN_DRAGGING_LINE: return beginDraggingLine(state, action.layerID, action.lineID, action.x, action.y); case UPDATE_DRAGGING_LINE: return updateDraggingLine(state, action.x, action.y); case END_DRAGGING_LINE: return endDraggingLine(state, action.x, action.y); case SELECT_LINE: return selectLine(state, action.layerID, action.lineID); default: return state; } } function selectToolDrawingLine(state, sceneComponentType) { return state.merge({ mode: MODE_WAITING_DRAWING_LINE, drawingSupport: Map({ type: sceneComponentType }) }); } /** lines operations **/ function beginDrawingLine(state, layerID, x, y) { var catalog = state.catalog; var snapElements = sceneSnapElements(state.scene, new List(), state.snapMask); var snap = null; if (state.snapMask && !state.snapMask.isEmpty()) { snap = nearestSnap(snapElements, x, y, state.snapMask); if (snap) { ; var _snap$point = snap.point; x = _snap$point.x; y = _snap$point.y; }snapElements = snapElements.withMutations(function (snapElements) { var a = void 0, b = void 0, c = void 0; var _Geometry$horizontalL = Geometry.horizontalLine(y); a = _Geometry$horizontalL.a; b = _Geometry$horizontalL.b; c = _Geometry$horizontalL.c; addLineSnap(snapElements, a, b, c, 10, 3, null); var _Geometry$verticalLin = Geometry.verticalLine(x); a = _Geometry$verticalLin.a; b = _Geometry$verticalLin.b; c = _Geometry$verticalLin.c; addLineSnap(snapElements, a, b, c, 10, 3, null); }); } var drawingSupport = state.get('drawingSupport').set('layerID', layerID); var scene = state.scene.updateIn(['layers', layerID], function (layer) { return layer.withMutations(function (layer) { unselectAll(layer); var _addLine = addLine(layer, drawingSupport.get('type'), x, y, x, y, catalog), line = _addLine.line; select(layer, 'lines', line.id); select(layer, 'vertices', line.vertices.get(0)); select(layer, 'vertices', line.vertices.get(1)); }); }); return state.merge({ mode: MODE_DRAWING_LINE, scene: scene, snapElements: snapElements, activeSnapElement: snap ? snap.snap : null, drawingSupport: drawingSupport }); } function updateDrawingLine(state, x, y) { var snap = null; if (state.snapMask && !state.snapMask.isEmpty()) { snap = nearestSnap(state.snapElements, x, y, state.snapMask); if (snap) { ; var _snap$point2 = snap.point; x = _snap$point2.x; y = _snap$point2.y; } } var layerID = state.getIn(['drawingSupport', 'layerID']); var scene = state.scene.updateIn(['layers', layerID], function (layer) { return layer.withMutations(function (layer) { var lineID = layer.getIn(['selected', 'lines']).first(); var vertex = void 0; var _replaceLineVertex = replaceLineVertex(layer, lineID, 1, x, y); layer = _replaceLineVertex.layer; vertex = _replaceLineVertex.vertex; select(layer, 'vertices', vertex.id); return layer; }); }); return state.merge({ scene: scene, activeSnapElement: snap ? snap.snap : null }); } function endDrawingLine(state, x, y) { var catalog = state.catalog; if (state.snapMask && !state.snapMask.isEmpty()) { var snap = nearestSnap(state.snapElements, x, y, state.snapMask); if (snap) { ; var _snap$point3 = snap.point; x = _snap$point3.x; y = _snap$point3.y; } } var layerID = state.getIn(['drawingSupport', 'layerID']); var scene = state.scene.updateIn(['layers', layerID], function (layer) { return layer.withMutations(function (layer) { var lineID = layer.getIn(['selected', 'lines']).first(); var line = layer.getIn(['lines', lineID]); var v0 = layer.vertices.get(line.vertices.get(0)); unselect(layer, 'lines', lineID); unselect(layer, 'vertices', line.vertices.get(0)); unselect(layer, 'vertices', line.vertices.get(1)); removeLine(layer, lineID); addLineAvoidingIntersections(layer, line.type, v0.x, v0.y, x, y, catalog); detectAndUpdateAreas(layer, catalog); }); }); return state.merge({ mode: MODE_WAITING_DRAWING_LINE, scene: scene, snapElements: new List(), activeSnapElement: null, sceneHistory: state.sceneHistory.push(scene) }); } function beginDraggingLine(state, layerID, lineID, x, y) { var snapElements = sceneSnapElements(state.scene, new List(), state.snapMask); var layer = state.scene.layers.get(layerID); var line = layer.lines.get(lineID); var vertex0 = layer.vertices.get(line.vertices.get(0)); var vertex1 = layer.vertices.get(line.vertices.get(1)); return state.merge({ mode: MODE_DRAGGING_LINE, snapElements: snapElements, draggingSupport: Map({ layerID: layerID, lineID: lineID, startPointX: x, startPointY: y, startVertex0X: vertex0.x, startVertex0Y: vertex0.y, startVertex1X: vertex1.x, startVertex1Y: vertex1.y }) }); } function updateDraggingLine(state, x, y) { var draggingSupport = state.draggingSupport; var snapElements = state.snapElements; var layerID = draggingSupport.get('layerID'); var lineID = draggingSupport.get('lineID'); var diffX = x - draggingSupport.get('startPointX'); var diffY = y - draggingSupport.get('startPointY'); var newVertex0X = draggingSupport.get('startVertex0X') + diffX; var newVertex0Y = draggingSupport.get('startVertex0Y') + diffY; var newVertex1X = draggingSupport.get('startVertex1X') + diffX; var newVertex1Y = draggingSupport.get('startVertex1Y') + diffY; var activeSnapElement = null; var curSnap0 = null, curSnap1 = null; if (state.snapMask && !state.snapMask.isEmpty()) { curSnap0 = nearestSnap(snapElements, newVertex0X, newVertex0Y, state.snapMask); curSnap1 = nearestSnap(snapElements, newVertex1X, newVertex1Y, state.snapMask); } var deltaX = 0, deltaY = 0; if (curSnap0 && curSnap1) { if (curSnap0.point.distance < curSnap1.point.distance) { deltaX = curSnap0.point.x - newVertex0X; deltaY = curSnap0.point.y - newVertex0Y; activeSnapElement = curSnap0.snap; } else { deltaX = curSnap1.point.x - newVertex1X; deltaY = curSnap1.point.y - newVertex1Y; activeSnapElement = curSnap1.snap; } } else { if (curSnap0) { deltaX = curSnap0.point.x - newVertex0X; deltaY = curSnap0.point.y - newVertex0Y; activeSnapElement = curSnap0.snap; } if (curSnap1) { deltaX = curSnap1.point.x - newVertex1X; deltaY = curSnap1.point.y - newVertex1Y; activeSnapElement = curSnap1.snap; } } newVertex0X += deltaX; newVertex0Y += deltaY; newVertex1X += deltaX; newVertex1Y += deltaY; return state.merge({ activeSnapElement: activeSnapElement, scene: state.scene.updateIn(['layers', layerID], function (layer) { return layer.withMutations(function (layer) { var lineVertices = layer.getIn(['lines', lineID, 'vertices']); layer.updateIn(['vertices', lineVertices.get(0)], function (vertex) { return vertex.merge({ x: newVertex0X, y: newVertex0Y }); }); layer.updateIn(['vertices', lineVertices.get(1)], function (vertex) { return vertex.merge({ x: newVertex1X, y: newVertex1Y }); }); return layer; }); }) }); } function endDraggingLine(state, x, y) { var catalog = state.catalog; var draggingSupport = state.draggingSupport; var layerID = draggingSupport.get('layerID'); var layer = state.scene.layers.get(layerID); var lineID = draggingSupport.get('lineID'); var line = layer.lines.get(lineID); var vertex0 = layer.vertices.get(line.vertices.get(0)); var vertex1 = layer.vertices.get(line.vertices.get(1)); var maxV = Geometry.maxVertex(vertex0, vertex1); var minV = Geometry.minVertex(vertex0, vertex1); var lineLength = Geometry.verticesDistance(minV, maxV); var alpha = Math.atan2(maxV.y - minV.y, maxV.x - minV.x); var holesWithOffsetPosition = []; layer.lines.get(lineID).holes.forEach(function (holeID) { var hole = layer.holes.get(holeID); var pointOnLine = lineLength * hole.offset; var offsetPosition = { x: pointOnLine * Math.cos(alpha) + minV.x, y: pointOnLine * Math.sin(alpha) + minV.y }; holesWithOffsetPosition.push({ hole: hole, offsetPosition: offsetPosition }); }); return state.withMutations(function (state) { var scene = state.scene.updateIn(['layers', layerID], function (layer) { return layer.withMutations(function (layer) { var diffX = x - draggingSupport.get('startPointX'); var diffY = y - draggingSupport.get('startPointY'); var newVertex0X = draggingSupport.get('startVertex0X') + diffX; var newVertex0Y = draggingSupport.get('startVertex0Y') + diffY; var newVertex1X = draggingSupport.get('startVertex1X') + diffX; var newVertex1Y = draggingSupport.get('startVertex1Y') + diffY; if (state.snapMask && !state.snapMask.isEmpty()) { var curSnap0 = nearestSnap(state.snapElements, newVertex0X, newVertex0Y, state.snapMask); var curSnap1 = nearestSnap(state.snapElements, newVertex1X, newVertex1Y, state.snapMask); var deltaX = 0, deltaY = 0; if (curSnap0 && curSnap1) { if (curSnap0.point.distance < curSnap1.point.distance) { deltaX = curSnap0.point.x - newVertex0X; deltaY = curSnap0.point.y - newVertex0Y; } else { deltaX = curSnap1.point.x - newVertex1X; deltaY = curSnap1.point.y - newVertex1Y; } } else { if (curSnap0) { deltaX = curSnap0.point.x - newVertex0X; deltaY = curSnap0.point.y - newVertex0Y; } if (curSnap1) { deltaX = curSnap1.point.x - newVertex1X; deltaY = curSnap1.point.y - newVertex1Y; } } newVertex0X += deltaX; newVertex0Y += deltaY; newVertex1X += deltaX; newVertex1Y += deltaY; } mergeEqualsVertices(layer, line.vertices.get(0)); mergeEqualsVertices(layer, line.vertices.get(1)); removeLine(layer, lineID); if (!samePoints({ newVertex0X: newVertex0X, newVertex0Y: newVertex0Y }, { newVertex1X: newVertex1X, newVertex1Y: newVertex1Y })) { addLineAvoidingIntersections(layer, line.type, newVertex0X, newVertex0Y, newVertex1X, newVertex1Y, catalog, line.properties, holesWithOffsetPosition); } detectAndUpdateAreas(layer, catalog); }); }); state.merge({ mode: MODE_IDLE, scene: scene, draggingSupport: null, activeSnapElement: null, snapElements: new List(), sceneHistory: state.sceneHistory.push(scene) }); }); } function selectLine(state, layerID, lineID) { var scene = state.scene; scene = scene.merge({ layers: scene.layers.map(unselectAll), selectedLayer: layerID }); scene = scene.updateIn(['layers', layerID], function (layer) { return layer.withMutations(function (layer) { var line = layer.getIn(['lines', lineID]); select(layer, 'lines', lineID); select(layer, 'vertices', line.vertices.get(0)); select(layer, 'vertices', line.vertices.get(1)); }); }); return state.merge({ scene: scene, sceneHistory: state.sceneHistory.push(scene) }); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWR1Y2Vycy9saW5lcy1yZWR1Y2VyLmpzIl0sIm5hbWVzIjpbIkxpc3QiLCJNYXAiLCJTRUxFQ1RfVE9PTF9EUkFXSU5HX0xJTkUiLCJCRUdJTl9EUkFXSU5HX0xJTkUiLCJVUERBVEVfRFJBV0lOR19MSU5FIiwiRU5EX0RSQVdJTkdfTElORSIsIkJFR0lOX0RSQUdHSU5HX0xJTkUiLCJVUERBVEVfRFJBR0dJTkdfTElORSIsIkVORF9EUkFHR0lOR19MSU5FIiwiU0VMRUNUX0xJTkUiLCJNT0RFX0lETEUiLCJNT0RFX1dBSVRJTkdfRFJBV0lOR19MSU5FIiwiTU9ERV9EUkFXSU5HX0xJTkUiLCJNT0RFX0RSQUdHSU5HX0xJTkUiLCJHZW9tZXRyeSIsImFkZExpbmUiLCJyZXBsYWNlTGluZVZlcnRleCIsInJlbW92ZUxpbmUiLCJzZWxlY3QiLCJ1bnNlbGVjdCIsImFkZExpbmVBdm9pZGluZ0ludGVyc2VjdGlvbnMiLCJ1bnNlbGVjdEFsbCIsImRldGVjdEFuZFVwZGF0ZUFyZWFzIiwibWVyZ2VFcXVhbHNWZXJ0aWNlcyIsIm5lYXJlc3RTbmFwIiwiYWRkUG9pbnRTbmFwIiwiYWRkTGluZVNuYXAiLCJhZGRMaW5lU2VnbWVudFNuYXAiLCJzY2VuZVNuYXBFbGVtZW50cyIsInNhbWVQb2ludHMiLCJzdGF0ZSIsImFjdGlvbiIsInR5cGUiLCJzZWxlY3RUb29sRHJhd2luZ0xpbmUiLCJzY2VuZUNvbXBvbmVudFR5cGUiLCJiZWdpbkRyYXdpbmdMaW5lIiwibGF5ZXJJRCIsIngiLCJ5IiwidXBkYXRlRHJhd2luZ0xpbmUiLCJlbmREcmF3aW5nTGluZSIsImJlZ2luRHJhZ2dpbmdMaW5lIiwibGluZUlEIiwidXBkYXRlRHJhZ2dpbmdMaW5lIiwiZW5kRHJhZ2dpbmdMaW5lIiwic2VsZWN0TGluZSIsIm1lcmdlIiwibW9kZSIsImRyYXdpbmdTdXBwb3J0IiwiY2F0YWxvZyIsInNuYXBFbGVtZW50cyIsInNjZW5lIiwic25hcE1hc2siLCJzbmFwIiwiaXNFbXB0eSIsInBvaW50Iiwid2l0aE11dGF0aW9ucyIsImEiLCJiIiwiYyIsImhvcml6b250YWxMaW5lIiwidmVydGljYWxMaW5lIiwiZ2V0Iiwic2V0IiwidXBkYXRlSW4iLCJsYXllciIsImxpbmUiLCJpZCIsInZlcnRpY2VzIiwiYWN0aXZlU25hcEVsZW1lbnQiLCJnZXRJbiIsImZpcnN0IiwidmVydGV4IiwidjAiLCJzY2VuZUhpc3RvcnkiLCJwdXNoIiwibGF5ZXJzIiwibGluZXMiLCJ2ZXJ0ZXgwIiwidmVydGV4MSIsImRyYWdnaW5nU3VwcG9ydCIsInN0YXJ0UG9pbnRYIiwic3RhcnRQb2ludFkiLCJzdGFydFZlcnRleDBYIiwic3RhcnRWZXJ0ZXgwWSIsInN0YXJ0VmVydGV4MVgiLCJzdGFydFZlcnRleDFZIiwiZGlmZlgiLCJkaWZmWSIsIm5ld1ZlcnRleDBYIiwibmV3VmVydGV4MFkiLCJuZXdWZXJ0ZXgxWCIsIm5ld1ZlcnRleDFZIiwiY3VyU25hcDAiLCJjdXJTbmFwMSIsImRlbHRhWCIsImRlbHRhWSIsImRpc3RhbmNlIiwibGluZVZlcnRpY2VzIiwibWF4ViIsIm1heFZlcnRleCIsIm1pblYiLCJtaW5WZXJ0ZXgiLCJsaW5lTGVuZ3RoIiwidmVydGljZXNEaXN0YW5jZSIsImFscGhhIiwiTWF0aCIsImF0YW4yIiwiaG9sZXNXaXRoT2Zmc2V0UG9zaXRpb24iLCJob2xlcyIsImZvckVhY2giLCJob2xlIiwiaG9sZUlEIiwicG9pbnRPbkxpbmUiLCJvZmZzZXQiLCJvZmZzZXRQb3NpdGlvbiIsImNvcyIsInNpbiIsInByb3BlcnRpZXMiLCJtYXAiLCJzZWxlY3RlZExheWVyIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFRQSxJQUFSLEVBQWNDLEdBQWQsUUFBd0IsV0FBeEI7O0FBRUEsU0FDRUMsd0JBREYsRUFFRUMsa0JBRkYsRUFHRUMsbUJBSEYsRUFJRUMsZ0JBSkYsRUFLRUMsbUJBTEYsRUFNRUMsb0JBTkYsRUFPRUMsaUJBUEYsRUFRRUMsV0FSRixFQVNFQyxTQVRGLEVBVUVD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QyxLQUFLRSxRQUFMLENBQWNOLEdBQWQsQ0FBa0IsQ0FBbEIsQ0FBMUI7QUFDQTVDLGFBQU8rQyxLQUFQLEVBQWMsVUFBZCxFQUEwQkMsS0FBS0UsUUFBTCxDQUFjTixHQUFkLENBQWtCLENBQWxCLENBQTFCO0FBQ0QsS0FMa0QsQ0FBVDtBQUFBLEdBQXBDLENBQVI7O0FBUUEsU0FBT2hDLE1BQU1nQixLQUFOLENBQVk7QUFDakJLLGdCQURpQjtBQUVqQnVCLGtCQUFjNUMsTUFBTTRDLFlBQU4sQ0FBbUJDLElBQW5CLENBQXdCeEIsS0FBeEI7QUFGRyxHQUFaLENBQVA7QUFJRCIsImZpbGUiOiJsaW5lcy1yZWR1Y2VyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtMaXN0LCBNYXB9IGZyb20gJ2ltbXV0YWJsZSc7XG5cbmltcG9ydCB7XG4gIFNFTEVDVF9UT09MX0RSQVdJTkdfTElORSxcbiAgQkVHSU5fRFJBV0lOR19MSU5FLFxuICBVUERBVEVfRFJBV0lOR19MSU5FLFxuICBFTkRfRFJBV0lOR19MSU5FLFxuICBCRUdJTl9EUkFHR0lOR19MSU5FLFxuICBVUERBVEVfRFJBR0dJTkdfTElORSxcbiAgRU5EX0RSQUdHSU5HX0xJTkUsXG4gIFNFTEVDVF9MSU5FLFxuICBNT0RFX0lETEUsXG4gIE1PREVfV0FJVElOR19EUkFXSU5HX0xJTkUsXG4gIE1PREVfRFJBV0lOR19MSU5FLFxuICBNT0RFX0RSQUdHSU5HX0xJTkVcbn0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuaW1wb3J0ICogYXMgR2VvbWV0cnkgZnJvbSAnLi4vdXRpbHMvZ2VvbWV0cnknO1xuaW1wb3J0IHtcbiAgYWRkTGluZSxcbiAgcmVwbGFjZUxpbmVWZXJ0ZXgsXG4gIHJlbW92ZUxpbmUsXG4gIHNlbGVjdCxcbiAgdW5zZWxlY3QsXG4gIGFkZExpbmVBdm9pZGluZ0ludGVyc2VjdGlvbnMsXG4gIHVuc2VsZWN0QWxsLFxuICBkZXRlY3RBbmRVcGRhdGVBcmVhcywgbWVyZ2VFcXVhbHNWZXJ0aWNlcyxcbn0gZnJvbSAnLi4vdXRpbHMvbGF5ZXItb3BlcmF0aW9ucyc7XG5pbXBvcnQge25lYXJlc3RTbmFwLCBhZGRQb2ludFNuYXAsIGFkZExpbmVTbmFwLCBhZGRMaW5lU2VnbWVudFNuYXB9IGZyb20gJy4uL3V0aWxzL3NuYXAnO1xuaW1wb3J0IHtzY2VuZVNuYXBFbGVtZW50c30gZnJvbSAnLi4vdXRpbHMvc25hcC1zY2VuZSc7XG5pbXBvcnQge3NhbWVQb2ludHN9IGZyb20gXCIuLi91dGlscy9nZW9tZXRyeVwiO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RhdGUsIGFjdGlvbikge1xuICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgY2FzZSBTRUxFQ1RfVE9PTF9EUkFXSU5HX0xJTkU6XG4gICAgICByZXR1cm4gc2VsZWN0VG9vbERyYXdpbmdMaW5lKHN0YXRlLCBhY3Rpb24uc2NlbmVDb21wb25lbnRUeXBlKTtcblxuICAgIGNhc2UgQkVHSU5fRFJBV0lOR19MSU5FOlxuICAgICAgcmV0dXJuIGJlZ2luRHJhd2luZ0xpbmUoc3RhdGUsIGFjdGlvbi5sYXllcklELCBhY3Rpb24ueCwgYWN0aW9uLnkpO1xuXG4gICAgY2FzZSBVUERBVEVfRFJBV0lOR19MSU5FOlxuICAgICAgcmV0dXJuIHVwZGF0ZURyYXdpbmdMaW5lKHN0YXRlLCBhY3Rpb24ueCwgYWN0aW9uLnkpO1xuXG4gICAgY2FzZSBFTkRfRFJBV0lOR19MSU5FOlxuICAgICAgcmV0dXJuIGVuZERyYXdpbmdMaW5lKHN0YXRlLCBhY3Rpb24ueCwgYWN0aW9uLnkpO1xuXG4gICAgY2FzZSBCRUdJTl9EUkFHR0lOR19MSU5FOlxuICAgICAgcmV0dXJuIGJlZ2luRHJhZ2dpbmdMaW5lKHN0YXRlLCBhY3Rpb24ubGF5ZXJJRCwgYWN0aW9uLmxpbmVJRCwgYWN0aW9uLngsIGFjdGlvbi55KTtcblxuICAgIGNhc2UgVVBEQVRFX0RSQUdHSU5HX0xJTkU6XG4gICAgICByZXR1cm4gdXBkYXRlRHJhZ2dpbmdMaW5lKHN0YXRlLCBhY3Rpb24ueCwgYWN0aW9uLnkpO1xuXG4gICAgY2FzZSBFTkRfRFJBR0dJTkdfTElORTpcbiAgICAgIHJldHVybiBlbmREcmFnZ2luZ0xpbmUoc3RhdGUsIGFjdGlvbi54LCBhY3Rpb24ueSk7XG5cbiAgICBjYXNlIFNFTEVDVF9MSU5FOlxuICAgICAgcmV0dXJuIHNlbGVjdExpbmUoc3RhdGUsIGFjdGlvbi5sYXllcklELCBhY3Rpb24ubGluZUlEKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gc3RhdGU7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2VsZWN0VG9vbERyYXdpbmdMaW5lKHN0YXRlLCBzY2VuZUNvbXBvbmVudFR5cGUpIHtcbiAgcmV0dXJuIHN0YXRlLm1lcmdlKHtcbiAgICBtb2RlOiBNT0RFX1dBSVRJTkdfRFJBV0lOR19MSU5FLFxuICAgIGRyYXdpbmdTdXBwb3J0OiBNYXAoe1xuICAgICAgdHlwZTogc2NlbmVDb21wb25lbnRUeXBlXG4gICAgfSlcbiAgfSk7XG59XG5cbi8qKiBsaW5lcyBvcGVyYXRpb25zICoqL1xuZnVuY3Rpb24gYmVnaW5EcmF3aW5nTGluZShzdGF0ZSwgbGF5ZXJJRCwgeCwgeSkge1xuICBsZXQgY2F0YWxvZyA9IHN0YXRlLmNhdGFsb2c7XG5cbiAgbGV0IHNuYXBFbGVtZW50cyA9IHNjZW5lU25hcEVsZW1lbnRzKHN0YXRlLnNjZW5lLCBuZXcgTGlzdCgpLCBzdGF0ZS5zbmFwTWFzayk7XG4gIGxldCBzbmFwID0gbnVsbDtcblxuICBpZiAoc3RhdGUuc25hcE1hc2sgJiYgIXN0YXRlLnNuYXBNYXNrLmlzRW1wdHkoKSkge1xuICAgIHNuYXAgPSBuZWFyZXN0U25hcChzbmFwRWxlbWVudHMsIHgsIHksIHN0YXRlLnNuYXBNYXNrKTtcbiAgICBpZiAoc25hcCkgKHt4LCB5fSA9IHNuYXAucG9pbnQpO1xuXG4gICAgc25hcEVsZW1lbnRzID0gc25hcEVsZW1lbnRzLndpdGhNdXRhdGlvbnMoc25hcEVsZW1lbnRzID0+IHtcbiAgICAgIGxldCBhLCBiLCBjO1xuICAgICAgKHthLCBiLCBjfSA9IEdlb21ldHJ5Lmhvcml6b250YWxMaW5lKHkpKTtcbiAgICAgIGFkZExpbmVTbmFwKHNuYXBFbGVtZW50cywgYSwgYiwgYywgMTAsIDMsIG51bGwpO1xuICAgICAgKHthLCBiLCBjfSA9IEdlb21ldHJ5LnZlcnRpY2FsTGluZSh4KSk7XG4gICAgICBhZGRMaW5lU25hcChzbmFwRWxlbWVudHMsIGEsIGIsIGMsIDEwLCAzLCBudWxsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGxldCBkcmF3aW5nU3VwcG9ydCA9IHN0YXRlLmdldCgnZHJhd2luZ1N1cHBvcnQnKS5zZXQoJ2xheWVySUQnLCBsYXllcklEKTtcbiAgbGV0IHNjZW5lID0gc3RhdGUuc2NlbmUudXBkYXRlSW4oWydsYXllcnMnLCBsYXllcklEXSwgbGF5ZXIgPT4gbGF5ZXIud2l0aE11dGF0aW9ucyhsYXllciA9PiB7XG4gICAgdW5zZWxlY3RBbGwobGF5ZXIpO1xuICAgIGxldCB7bGluZX0gPSBhZGRMaW5lKGxheWVyLCBkcmF3aW5nU3VwcG9ydC5nZXQoJ3R5cGUnKSwgeCwgeSwgeCwgeSwgY2F0YWxvZyk7XG4gICAgc2VsZWN0KGxheWVyLCAnbGluZXMnLCBsaW5lLmlkKTtcbiAgICBzZWxlY3QobGF5ZXIsICd2ZXJ0aWNlcycsIGxpbmUudmVydGljZXMuZ2V0KDApKTtcbiAgICBzZWxlY3QobGF5ZXIsICd2ZXJ0aWNlcycsIGxpbmUudmVydGljZXMuZ2V0KDEpKTtcbiAgfSkpO1xuXG4gIHJldHVybiBzdGF0ZS5tZXJnZSh7XG4gICAgbW9kZTogTU9ERV9EUkFXSU5HX0xJTkUsXG4gICAgc2NlbmUsXG4gICAgc25hcEVsZW1lbnRzLFxuICAgIGFjdGl2ZVNuYXBFbGVtZW50OiBzbmFwID8gc25hcC5zbmFwIDogbnVsbCxcbiAgICBkcmF3aW5nU3VwcG9ydFxuICB9KTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRHJhd2luZ0xpbmUoc3RhdGUsIHgsIHkpIHtcblxuICBsZXQgc25hcCA9IG51bGw7XG4gIGlmIChzdGF0ZS5zbmFwTWFzayAmJiAhc3RhdGUuc25hcE1hc2suaXNFbXB0eSgpKSB7XG4gICAgc25hcCA9IG5lYXJlc3RTbmFwKHN0YXRlLnNuYXBFbGVtZW50cywgeCwgeSwgc3RhdGUuc25hcE1hc2spO1xuICAgIGlmIChzbmFwKSAoe3gsIHl9ID0gc25hcC5wb2ludCk7XG4gIH1cblxuICBsZXQgbGF5ZXJJRCA9IHN0YXRlLmdldEluKFsnZHJhd2luZ1N1cHBvcnQnLCAnbGF5ZXJJRCddKTtcbiAgbGV0IHNjZW5lID0gc3RhdGUuc2NlbmUudXBkYXRlSW4oWydsYXllcnMnLCBsYXllcklEXSwgbGF5ZXIgPT4gbGF5ZXIud2l0aE11dGF0aW9ucyhsYXllciA9PiB7XG4gICAgbGV0IGxpbmVJRCA9IGxheWVyLmdldEluKFsnc2VsZWN0ZWQnLCAnbGluZXMnXSkuZmlyc3QoKTtcbiAgICBsZXQgdmVydGV4O1xuICAgICh7bGF5ZXIsIHZlcnRleH0gPSByZXBsYWNlTGluZVZlcnRleChsYXllciwgbGluZUlELCAxLCB4LCB5KSk7XG4gICAgc2VsZWN0KGxheWVyLCAndmVydGljZXMnLCB2ZXJ0ZXguaWQpO1xuICAgIHJldHVybiBsYXllcjtcbiAgfSkpO1xuXG4gIHJldHVybiBzdGF0ZS5tZXJnZSh7XG4gICAgc2NlbmUsXG4gICAgYWN0aXZlU25hcEVsZW1lbnQ6IHNuYXAgPyBzbmFwLnNuYXAgOiBudWxsLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gZW5kRHJhd2luZ0xpbmUoc3RhdGUsIHgsIHkpIHtcblxuICBsZXQgY2F0YWxvZyA9IHN0YXRlLmNhdGFsb2c7XG5cbiAgaWYgKHN0YXRlLnNuYXBNYXNrICYmICFzdGF0ZS5zbmFwTWFzay5pc0VtcHR5KCkpIHtcbiAgICBsZXQgc25hcCA9IG5lYXJlc3RTbmFwKHN0YXRlLnNuYXBFbGVtZW50cywgeCwgeSwgc3RhdGUuc25hcE1hc2spO1xuICAgIGlmIChzbmFwKSAoe3gsIHl9ID0gc25hcC5wb2ludCk7XG4gIH1cblxuICBsZXQgbGF5ZXJJRCA9IHN0YXRlLmdldEluKFsnZHJhd2luZ1N1cHBvcnQnLCAnbGF5ZXJJRCddKTtcbiAgbGV0IHNjZW5lID0gc3RhdGUuc2NlbmUudXBkYXRlSW4oWydsYXllcnMnLCBsYXllcklEXSwgbGF5ZXIgPT4gbGF5ZXIud2l0aE11dGF0aW9ucyhsYXllciA9PiB7XG4gICAgbGV0IGxpbmVJRCA9IGxheWVyLmdldEluKFsnc2VsZWN0ZWQnLCAnbGluZXMnXSkuZmlyc3QoKTtcbiAgICBsZXQgbGluZSA9IGxheWVyLmdldEluKFsnbGluZXMnLCBsaW5lSURdKTtcbiAgICBsZXQgdjAgPSBsYXllci52ZXJ0aWNlcy5nZXQobGluZS52ZXJ0aWNlcy5nZXQoMCkpO1xuXG4gICAgdW5zZWxlY3QobGF5ZXIsICdsaW5lcycsIGxpbmVJRCk7XG4gICAgdW5zZWxlY3QobGF5ZXIsICd2ZXJ0aWNlcycsIGxpbmUudmVydGljZXMuZ2V0KDApKTtcbiAgICB1bnNlbGVjdChsYXllciwgJ3ZlcnRpY2VzJywgbGluZS52ZXJ0aWNlcy5nZXQoMSkpO1xuICAgIHJlbW92ZUxpbmUobGF5ZXIsIGxpbmVJRCk7XG4gICAgYWRkTGluZUF2b2lkaW5nSW50ZXJzZWN0aW9ucyhsYXllciwgbGluZS50eXBlLCB2MC54LCB2MC55LCB4LCB5LCBjYXRhbG9nKTtcbiAgICBkZXRlY3RBbmRVcGRhdGVBcmVhcyhsYXllciwgY2F0YWxvZyk7XG4gIH0pKTtcblxuICByZXR1cm4gc3RhdGUubWVyZ2Uoe1xuICAgIG1vZGU6IE1PREVfV0FJVElOR19EUkFXSU5HX0xJTkUsXG4gICAgc2NlbmUsXG4gICAgc25hcEVsZW1lbnRzOiBuZXcgTGlzdCgpLFxuICAgIGFjdGl2ZVNuYXBFbGVtZW50OiBudWxsLFxuICAgIHNjZW5lSGlzdG9yeTogc3RhdGUuc2NlbmVIaXN0b3J5LnB1c2goc2NlbmUpXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBiZWdpbkRyYWdnaW5nTGluZShzdGF0ZSwgbGF5ZXJJRCwgbGluZUlELCB4LCB5KSB7XG5cbiAgbGV0IHNuYXBFbGVtZW50cyA9IHNjZW5lU25hcEVsZW1lbnRzKHN0YXRlLnNjZW5lLCBuZXcgTGlzdCgpLCBzdGF0ZS5zbmFwTWFzayk7XG5cbiAgbGV0IGxheWVyID0gc3RhdGUuc2NlbmUubGF5ZXJzLmdldChsYXllcklEKTtcbiAgbGV0IGxpbmUgPSBsYXllci5saW5lcy5nZXQobGluZUlEKTtcblxuICBsZXQgdmVydGV4MCA9IGxheWVyLnZlcnRpY2VzLmdldChsaW5lLnZlcnRpY2VzLmdldCgwKSk7XG4gIGxldCB2ZXJ0ZXgxID0gbGF5ZXIudmVydGljZXMuZ2V0KGxpbmUudmVydGljZXMuZ2V0KDEpKTtcblxuICByZXR1cm4gc3RhdGUubWVyZ2Uoe1xuICAgIG1vZGU6IE1PREVfRFJBR0dJTkdfTElORSxcbiAgICBzbmFwRWxlbWVudHMsXG4gICAgZHJhZ2dpbmdTdXBwb3J0OiBNYXAoe1xuICAgICAgbGF5ZXJJRCwgbGluZUlELFxuICAgICAgc3RhcnRQb2ludFg6IHgsXG4gICAgICBzdGFydFBvaW50WTogeSxcbiAgICAgIHN0YXJ0VmVydGV4MFg6IHZlcnRleDAueCxcbiAgICAgIHN0YXJ0VmVydGV4MFk6IHZlcnRleDAueSxcbiAgICAgIHN0YXJ0VmVydGV4MVg6IHZlcnRleDEueCxcbiAgICAgIHN0YXJ0VmVydGV4MVk6IHZlcnRleDEueSxcbiAgICB9KVxuICB9KVxufVxuXG5mdW5jdGlvbiB1cGRhdGVEcmFnZ2luZ0xpbmUoc3RhdGUsIHgsIHkpIHtcblxuICBsZXQgZHJhZ2dpbmdTdXBwb3J0ID0gc3RhdGUuZHJhZ2dpbmdTdXBwb3J0O1xuICBsZXQgc25hcEVsZW1lbnRzID0gc3RhdGUuc25hcEVsZW1lbnRzO1xuXG4gIGxldCBsYXllcklEID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnbGF5ZXJJRCcpO1xuICBsZXQgbGluZUlEID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnbGluZUlEJyk7XG4gIGxldCBkaWZmWCA9IHggLSBkcmFnZ2luZ1N1cHBvcnQuZ2V0KCdzdGFydFBvaW50WCcpO1xuICBsZXQgZGlmZlkgPSB5IC0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRQb2ludFknKTtcbiAgbGV0IG5ld1ZlcnRleDBYID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRWZXJ0ZXgwWCcpICsgZGlmZlg7XG4gIGxldCBuZXdWZXJ0ZXgwWSA9IGRyYWdnaW5nU3VwcG9ydC5nZXQoJ3N0YXJ0VmVydGV4MFknKSArIGRpZmZZO1xuICBsZXQgbmV3VmVydGV4MVggPSBkcmFnZ2luZ1N1cHBvcnQuZ2V0KCdzdGFydFZlcnRleDFYJykgKyBkaWZmWDtcbiAgbGV0IG5ld1ZlcnRleDFZID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRWZXJ0ZXgxWScpICsgZGlmZlk7XG5cblxuICBsZXQgYWN0aXZlU25hcEVsZW1lbnQgPSBudWxsO1xuICBsZXQgY3VyU25hcDAgPSBudWxsLCBjdXJTbmFwMSA9IG51bGw7XG4gIGlmIChzdGF0ZS5zbmFwTWFzayAmJiAhc3RhdGUuc25hcE1hc2suaXNFbXB0eSgpKSB7XG4gICAgY3VyU25hcDAgPSBuZWFyZXN0U25hcChzbmFwRWxlbWVudHMsIG5ld1ZlcnRleDBYLCBuZXdWZXJ0ZXgwWSwgc3RhdGUuc25hcE1hc2spO1xuICAgIGN1clNuYXAxID0gbmVhcmVzdFNuYXAoc25hcEVsZW1lbnRzLCBuZXdWZXJ0ZXgxWCwgbmV3VmVydGV4MVksIHN0YXRlLnNuYXBNYXNrKTtcbiAgfVxuXG4gIGxldCBkZWx0YVggPSAwLCBkZWx0YVkgPSAwO1xuICBpZiAoY3VyU25hcDAgJiYgY3VyU25hcDEpIHtcbiAgICBpZiAoY3VyU25hcDAucG9pbnQuZGlzdGFuY2UgPCBjdXJTbmFwMS5wb2ludC5kaXN0YW5jZSkge1xuICAgICAgZGVsdGFYID0gY3VyU25hcDAucG9pbnQueCAtIG5ld1ZlcnRleDBYO1xuICAgICAgZGVsdGFZID0gY3VyU25hcDAucG9pbnQueSAtIG5ld1ZlcnRleDBZO1xuICAgICAgYWN0aXZlU25hcEVsZW1lbnQgPSBjdXJTbmFwMC5zbmFwO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWx0YVggPSBjdXJTbmFwMS5wb2ludC54IC0gbmV3VmVydGV4MVg7XG4gICAgICBkZWx0YVkgPSBjdXJTbmFwMS5wb2ludC55IC0gbmV3VmVydGV4MVk7XG4gICAgICBhY3RpdmVTbmFwRWxlbWVudCA9IGN1clNuYXAxLnNuYXA7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChjdXJTbmFwMCkge1xuICAgICAgZGVsdGFYID0gY3VyU25hcDAucG9pbnQueCAtIG5ld1ZlcnRleDBYO1xuICAgICAgZGVsdGFZID0gY3VyU25hcDAucG9pbnQueSAtIG5ld1ZlcnRleDBZO1xuICAgICAgYWN0aXZlU25hcEVsZW1lbnQgPSBjdXJTbmFwMC5zbmFwO1xuICAgIH1cbiAgICBpZiAoY3VyU25hcDEpIHtcbiAgICAgIGRlbHRhWCA9IGN1clNuYXAxLnBvaW50LnggLSBuZXdWZXJ0ZXgxWDtcbiAgICAgIGRlbHRhWSA9IGN1clNuYXAxLnBvaW50LnkgLSBuZXdWZXJ0ZXgxWTtcbiAgICAgIGFjdGl2ZVNuYXBFbGVtZW50ID0gY3VyU25hcDEuc25hcDtcbiAgICB9XG4gIH1cblxuICBuZXdWZXJ0ZXgwWCArPSBkZWx0YVg7XG4gIG5ld1ZlcnRleDBZICs9IGRlbHRhWTtcbiAgbmV3VmVydGV4MVggKz0gZGVsdGFYO1xuICBuZXdWZXJ0ZXgxWSArPSBkZWx0YVk7XG5cbiAgcmV0dXJuIHN0YXRlLm1lcmdlKHtcbiAgICBhY3RpdmVTbmFwRWxlbWVudCxcbiAgICBzY2VuZTogc3RhdGUuc2NlbmUudXBkYXRlSW4oWydsYXllcnMnLCBsYXllcklEXSwgbGF5ZXIgPT4gbGF5ZXIud2l0aE11dGF0aW9ucyhsYXllciA9PiB7XG4gICAgICBsZXQgbGluZVZlcnRpY2VzID0gbGF5ZXIuZ2V0SW4oWydsaW5lcycsIGxpbmVJRCwgJ3ZlcnRpY2VzJ10pO1xuICAgICAgbGF5ZXIudXBkYXRlSW4oWyd2ZXJ0aWNlcycsIGxpbmVWZXJ0aWNlcy5nZXQoMCldLCB2ZXJ0ZXggPT4gdmVydGV4Lm1lcmdlKHt4OiBuZXdWZXJ0ZXgwWCwgeTogbmV3VmVydGV4MFl9KSk7XG4gICAgICBsYXllci51cGRhdGVJbihbJ3ZlcnRpY2VzJywgbGluZVZlcnRpY2VzLmdldCgxKV0sIHZlcnRleCA9PiB2ZXJ0ZXgubWVyZ2Uoe3g6IG5ld1ZlcnRleDFYLCB5OiBuZXdWZXJ0ZXgxWX0pKTtcbiAgICAgIHJldHVybiBsYXllcjtcbiAgICB9KSlcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGVuZERyYWdnaW5nTGluZShzdGF0ZSwgeCwgeSkge1xuICBsZXQgY2F0YWxvZyA9IHN0YXRlLmNhdGFsb2c7XG4gIGxldCB7ZHJhZ2dpbmdTdXBwb3J0fSA9IHN0YXRlO1xuICBsZXQgbGF5ZXJJRCA9IGRyYWdnaW5nU3VwcG9ydC5nZXQoJ2xheWVySUQnKTtcbiAgbGV0IGxheWVyID0gc3RhdGUuc2NlbmUubGF5ZXJzLmdldChsYXllcklEKTtcbiAgbGV0IGxpbmVJRCA9IGRyYWdnaW5nU3VwcG9ydC5nZXQoJ2xpbmVJRCcpO1xuICBsZXQgbGluZSA9IGxheWVyLmxpbmVzLmdldChsaW5lSUQpO1xuXG4gIGxldCB2ZXJ0ZXgwID0gbGF5ZXIudmVydGljZXMuZ2V0KGxpbmUudmVydGljZXMuZ2V0KDApKTtcbiAgbGV0IHZlcnRleDEgPSBsYXllci52ZXJ0aWNlcy5nZXQobGluZS52ZXJ0aWNlcy5nZXQoMSkpO1xuXG4gIGxldCBtYXhWID0gR2VvbWV0cnkubWF4VmVydGV4KHZlcnRleDAsIHZlcnRleDEpO1xuICBsZXQgbWluViA9IEdlb21ldHJ5Lm1pblZlcnRleCh2ZXJ0ZXgwLCB2ZXJ0ZXgxKTtcblxuICBsZXQgbGluZUxlbmd0aCA9IEdlb21ldHJ5LnZlcnRpY2VzRGlzdGFuY2UobWluVixtYXhWKTtcbiAgbGV0IGFscGhhID0gTWF0aC5hdGFuMihtYXhWLnkgLSBtaW5WLnksIG1heFYueCAtIG1pblYueCk7XG5cbiAgbGV0IGhvbGVzV2l0aE9mZnNldFBvc2l0aW9uID0gW107XG4gIGxheWVyLmxpbmVzLmdldChsaW5lSUQpLmhvbGVzLmZvckVhY2goaG9sZUlEID0+IHtcbiAgICBsZXQgaG9sZSA9IGxheWVyLmhvbGVzLmdldChob2xlSUQpO1xuICAgIGxldCBwb2ludE9uTGluZSA9IGxpbmVMZW5ndGggKiBob2xlLm9mZnNldDtcblxuICAgIGxldCBvZmZzZXRQb3NpdGlvbiA9IHtcbiAgICAgIHg6IHBvaW50T25MaW5lICogTWF0aC5jb3MoYWxwaGEpICsgbWluVi54LFxuICAgICAgeTogcG9pbnRPbkxpbmUgKiBNYXRoLnNpbihhbHBoYSkgKyBtaW5WLnlcbiAgICB9O1xuXG4gICAgaG9sZXNXaXRoT2Zmc2V0UG9zaXRpb24ucHVzaCh7aG9sZSwgb2Zmc2V0UG9zaXRpb259KTtcbiAgfSk7XG5cbiAgcmV0dXJuIHN0YXRlLndpdGhNdXRhdGlvbnMoc3RhdGUgPT4ge1xuICAgIGxldCBzY2VuZSA9IHN0YXRlLnNjZW5lLnVwZGF0ZUluKFsnbGF5ZXJzJywgbGF5ZXJJRF0sIGxheWVyID0+IGxheWVyLndpdGhNdXRhdGlvbnMobGF5ZXIgPT4ge1xuXG4gICAgICBsZXQgZGlmZlggPSB4IC0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRQb2ludFgnKTtcbiAgICAgIGxldCBkaWZmWSA9IHkgLSBkcmFnZ2luZ1N1cHBvcnQuZ2V0KCdzdGFydFBvaW50WScpO1xuICAgICAgbGV0IG5ld1ZlcnRleDBYID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRWZXJ0ZXgwWCcpICsgZGlmZlg7XG4gICAgICBsZXQgbmV3VmVydGV4MFkgPSBkcmFnZ2luZ1N1cHBvcnQuZ2V0KCdzdGFydFZlcnRleDBZJykgKyBkaWZmWTtcbiAgICAgIGxldCBuZXdWZXJ0ZXgxWCA9IGRyYWdnaW5nU3VwcG9ydC5nZXQoJ3N0YXJ0VmVydGV4MVgnKSArIGRpZmZYO1xuICAgICAgbGV0IG5ld1ZlcnRleDFZID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRWZXJ0ZXgxWScpICsgZGlmZlk7XG5cbiAgICAgIGlmIChzdGF0ZS5zbmFwTWFzayAmJiAhc3RhdGUuc25hcE1hc2suaXNFbXB0eSgpKSB7XG5cbiAgICAgICAgbGV0IGN1clNuYXAwID0gbmVhcmVzdFNuYXAoc3RhdGUuc25hcEVsZW1lbnRzLCBuZXdWZXJ0ZXgwWCwgbmV3VmVydGV4MFksIHN0YXRlLnNuYXBNYXNrKTtcbiAgICAgICAgbGV0IGN1clNuYXAxID0gbmVhcmVzdFNuYXAoc3RhdGUuc25hcEVsZW1lbnRzLCBuZXdWZXJ0ZXgxWCwgbmV3VmVydGV4MVksIHN0YXRlLnNuYXBNYXNrKTtcblxuICAgICAgICBsZXQgZGVsdGFYID0gMCwgZGVsdGFZID0gMDtcbiAgICAgICAgaWYgKGN1clNuYXAwICYmIGN1clNuYXAxKSB7XG4gICAgICAgICAgaWYgKGN1clNuYXAwLnBvaW50LmRpc3RhbmNlIDwgY3VyU25hcDEucG9pbnQuZGlzdGFuY2UpIHtcbiAgICAgICAgICAgIGRlbHRhWCA9IGN1clNuYXAwLnBvaW50LnggLSBuZXdWZXJ0ZXgwWDtcbiAgICAgICAgICAgIGRlbHRhWSA9IGN1clNuYXAwLnBvaW50LnkgLSBuZXdWZXJ0ZXgwWTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsdGFYID0gY3VyU25hcDEucG9pbnQueCAtIG5ld1ZlcnRleDFYO1xuICAgICAgICAgICAgZGVsdGFZID0gY3VyU25hcDEucG9pbnQueSAtIG5ld1ZlcnRleDFZO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoY3VyU25hcDApIHtcbiAgICAgICAgICAgIGRlbHRhWCA9IGN1clNuYXAwLnBvaW50LnggLSBuZXdWZXJ0ZXgwWDtcbiAgICAgICAgICAgIGRlbHRhWSA9IGN1clNuYXAwLnBvaW50LnkgLSBuZXdWZXJ0ZXgwWTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGN1clNuYXAxKSB7XG4gICAgICAgICAgICBkZWx0YVggPSBjdXJTbmFwMS5wb2ludC54IC0gbmV3VmVydGV4MVg7XG4gICAgICAgICAgICBkZWx0YVkgPSBjdXJTbmFwMS5wb2ludC55IC0gbmV3VmVydGV4MVk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbmV3VmVydGV4MFggKz0gZGVsdGFYO1xuICAgICAgICBuZXdWZXJ0ZXgwWSArPSBkZWx0YVk7XG4gICAgICAgIG5ld1ZlcnRleDFYICs9IGRlbHRhWDtcbiAgICAgICAgbmV3VmVydGV4MVkgKz0gZGVsdGFZO1xuICAgICAgfVxuXG4gICAgICBtZXJnZUVxdWFsc1ZlcnRpY2VzKGxheWVyLCBsaW5lLnZlcnRpY2VzLmdldCgwKSk7XG4gICAgICBtZXJnZUVxdWFsc1ZlcnRpY2VzKGxheWVyLCBsaW5lLnZlcnRpY2VzLmdldCgxKSk7XG5cbiAgICAgIHJlbW92ZUxpbmUobGF5ZXIsIGxpbmVJRCk7XG5cbiAgICAgIGlmKCFzYW1lUG9pbnRzKHtuZXdWZXJ0ZXgwWCwgbmV3VmVydGV4MFl9LCB7bmV3VmVydGV4MVgsIG5ld1ZlcnRleDFZfSkpIHtcbiAgICAgICAgYWRkTGluZUF2b2lkaW5nSW50ZXJzZWN0aW9ucyhsYXllciwgbGluZS50eXBlLFxuICAgICAgICAgIG5ld1ZlcnRleDBYLCBuZXdWZXJ0ZXgwWSwgbmV3VmVydGV4MVgsIG5ld1ZlcnRleDFZLFxuICAgICAgICAgIGNhdGFsb2csIGxpbmUucHJvcGVydGllcywgaG9sZXNXaXRoT2Zmc2V0UG9zaXRpb24pO1xuICAgICAgfVxuXG4gICAgICBkZXRlY3RBbmRVcGRhdGVBcmVhcyhsYXllciwgY2F0YWxvZyk7XG4gICAgfSkpO1xuXG4gICAgc3RhdGUubWVyZ2Uoe1xuICAgICAgbW9kZTogTU9ERV9JRExFLFxuICAgICAgc2NlbmUsXG4gICAgICBkcmFnZ2luZ1N1cHBvcnQ6IG51bGwsXG4gICAgICBhY3RpdmVTbmFwRWxlbWVudDogbnVsbCxcbiAgICAgIHNuYXBFbGVtZW50czogbmV3IExpc3QoKSxcbiAgICAgIHNjZW5lSGlzdG9yeTogc3RhdGUuc2NlbmVIaXN0b3J5LnB1c2goc2NlbmUpXG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBzZWxlY3RMaW5lKHN0YXRlLCBsYXllcklELCBsaW5lSUQpIHtcbiAgbGV0IHNjZW5lID0gc3RhdGUuc2NlbmU7XG5cbiAgc2NlbmUgPSBzY2VuZS5tZXJnZSh7XG4gICAgbGF5ZXJzOiBzY2VuZS5sYXllcnMubWFwKHVuc2VsZWN0QWxsKSxcbiAgICBzZWxlY3RlZExheWVyOiBsYXllcklEXG4gIH0pO1xuXG4gIHNjZW5lID0gc2NlbmUudXBkYXRlSW4oWydsYXllcnMnLCBsYXllcklEXSwgbGF5ZXIgPT4gbGF5ZXIud2l0aE11dGF0aW9ucyhsYXllciA9PiB7XG4gICAgICBsZXQgbGluZSA9IGxheWVyLmdldEluKFsnbGluZXMnLCBsaW5lSURdKTtcbiAgICAgIHNlbGVjdChsYXllciwgJ2xpbmVzJywgbGluZUlEKTtcbiAgICAgIHNlbGVjdChsYXllciwgJ3ZlcnRpY2VzJywgbGluZS52ZXJ0aWNlcy5nZXQoMCkpO1xuICAgICAgc2VsZWN0KGxheWVyLCAndmVydGljZXMnLCBsaW5lLnZlcnRpY2VzLmdldCgxKSk7XG4gICAgfSlcbiAgKTtcblxuICByZXR1cm4gc3RhdGUubWVyZ2Uoe1xuICAgIHNjZW5lLFxuICAgIHNjZW5lSGlzdG9yeTogc3RhdGUuc2NlbmVIaXN0b3J5LnB1c2goc2NlbmUpXG4gIH0pXG59XG4iXX0=