react-planner-viewer
Version:
react-planner-viewer is a React Component for view plans builded with react-planner in 2D mode
340 lines (263 loc) • 44 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (state, action) {
switch (action.type) {
case _constants.SELECT_TOOL_DRAWING_HOLE:
return selectToolDrawingHole(state, action.sceneComponentType);
case _constants.UPDATE_DRAWING_HOLE:
return updateDrawingHole(state, action.layerID, action.x, action.y);
case _constants.END_DRAWING_HOLE:
return endDrawingHole(state, action.layerID, action.x, action.y);
case _constants.BEGIN_DRAGGING_HOLE:
return beginDraggingHole(state, action.layerID, action.holeID, action.x, action.y);
case _constants.UPDATE_DRAGGING_HOLE:
return updateDraggingHole(state, action.x, action.y);
case _constants.END_DRAGGING_HOLE:
return endDraggingHole(state, action.x, action.y);
case _constants.SELECT_HOLE:
return selectHole(state, action.layerID, action.holeID);
default:
return state;
}
};
var _immutable = require('immutable');
var _constants = require('../constants');
var _geometry = require('../utils/geometry');
var Geometry = _interopRequireWildcard(_geometry);
var _layerOperations = require('../utils/layer-operations');
var _snap = require('../utils/snap');
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function selectToolDrawingHole(state, sceneComponentType) {
var snapElements = new _immutable.List().withMutations(function (snapElements) {
var _state$getIn = state.getIn(['scene', 'layers', state.scene.selectedLayer]),
lines = _state$getIn.lines,
vertices = _state$getIn.vertices;
lines.forEach(function (line) {
var _vertices$get = vertices.get(line.vertices.get(0)),
x1 = _vertices$get.x,
y1 = _vertices$get.y;
var _vertices$get2 = vertices.get(line.vertices.get(1)),
x2 = _vertices$get2.x,
y2 = _vertices$get2.y;
(0, _snap.addLineSegmentSnap)(snapElements, x1, y1, x2, y2, 20, 1, line.id);
});
});
return state.merge({
mode: _constants.MODE_DRAWING_HOLE,
snapElements: snapElements,
drawingSupport: (0, _immutable.Map)({
type: sceneComponentType
})
});
}
/** holes operations **/
function updateDrawingHole(state, layerID, x, y) {
var catalog = state.catalog;
//calculate snap and overwrite coords if needed
//force snap to segment
var snap = (0, _snap.nearestSnap)(state.snapElements, x, y, state.snapMask.merge({ SNAP_SEGMENT: true }));
if (snap) {
;
var _snap$point = snap.point;
x = _snap$point.x;
y = _snap$point.y;
}var scene = state.scene.updateIn(['layers', layerID], function (layer) {
return layer.withMutations(function (layer) {
var selectedHole = layer.getIn(['selected', 'holes']).first();
if (selectedHole) {
(0, _layerOperations.unselect)(layer, 'holes', selectedHole);
(0, _layerOperations.removeHole)(layer, selectedHole);
}
if (snap) {
var lineID = snap.snap.related.get(0);
var line = layer.getIn(['lines', lineID]);
var _layer$vertices$get = layer.vertices.get(line.vertices.get(0)),
x1 = _layer$vertices$get.x,
y1 = _layer$vertices$get.y;
var _layer$vertices$get2 = layer.vertices.get(line.vertices.get(1)),
x2 = _layer$vertices$get2.x,
y2 = _layer$vertices$get2.y;
// I need min and max vertices on this line segment
var minVertex = Geometry.minVertex({ x: x1, y: y1 }, { x: x2, y: y2 });
var maxVertex = Geometry.maxVertex({ x: x1, y: y1 }, { x: x2, y: y2 });
var width = catalog.factoryElement(state.drawingSupport.get('type'), {}, {}).properties.get('width').get('length');
// Now I need min and max possible coordinates for the hole on the line. They depend on the width of the hole
// let width = hole.properties.get('width').get('length');
var lineLength = Geometry.pointsDistance(x1, y1, x2, y2);
var alpha = Math.atan2(Math.abs(y2 - y1), Math.abs(x2 - x1));
var cosWithThreshold = function cosWithThreshold(alpha) {
var cos = Math.cos(alpha);
return cos < 0.0000001 ? 0 : cos;
};
var sinWithThreshold = function sinWithThreshold(alpha) {
var sin = Math.sin(alpha);
return sin < 0.0000001 ? 0 : sin;
};
var cosAlpha = cosWithThreshold(alpha);
var sinAlpha = sinWithThreshold(alpha);
var minLeftVertexHole = {
x: minVertex.x + width / 2 * cosAlpha,
y: minVertex.y + width / 2 * sinAlpha
};
var maxRightVertexHole = {
x: minVertex.x + lineLength * cosAlpha - width / 2 * cosAlpha,
y: minVertex.y + lineLength * sinAlpha - width / 2 * sinAlpha
};
var offset = void 0;
if (x < minLeftVertexHole.x) {
offset = Geometry.pointPositionOnLineSegment(minVertex.x, minVertex.y, maxVertex.x, maxVertex.y, minLeftVertexHole.x, minLeftVertexHole.y);
} else if (x > maxRightVertexHole.x) {
offset = Geometry.pointPositionOnLineSegment(minVertex.x, minVertex.y, maxVertex.x, maxVertex.y, maxRightVertexHole.x, maxRightVertexHole.y);
} else {
if (x === minLeftVertexHole.x && x === maxRightVertexHole.x) {
if (y < minLeftVertexHole.y) {
offset = Geometry.pointPositionOnLineSegment(minVertex.x, minVertex.y, maxVertex.x, maxVertex.y, minLeftVertexHole.x, minLeftVertexHole.y);
offset = minVertex.x === x1 && minVertex.y === y1 ? offset : 1 - offset;
} else if (y > maxRightVertexHole.y) {
offset = Geometry.pointPositionOnLineSegment(minVertex.x, minVertex.y, maxVertex.x, maxVertex.y, maxRightVertexHole.x, maxRightVertexHole.y);
offset = minVertex.x === x1 && minVertex.y === y1 ? offset : 1 - offset;
} else {
offset = Geometry.pointPositionOnLineSegment(x1, y1, x2, y2, x, y);
}
} else {
offset = Geometry.pointPositionOnLineSegment(x1, y1, x2, y2, x, y);
}
}
// let offset = Geometry.pointPositionOnLineSegment(x1, y1, x2, y2, x, y);
var _addHole = (0, _layerOperations.addHole)(layer, state.drawingSupport.get('type'), lineID, offset, catalog),
hole = _addHole.hole;
(0, _layerOperations.select)(layer, 'holes', hole.id);
}
});
});
return state.set('scene', scene);
}
function endDrawingHole(state, layerID, x, y) {
var catalog = state.catalog;
state = updateDrawingHole(state, layerID, x, y, catalog);
var scene = state.scene.updateIn(['layers', layerID], function (layer) {
return (0, _layerOperations.unselectAll)(layer);
});
return state.merge({
scene: scene,
sceneHistory: state.sceneHistory.push(scene)
});
}
function beginDraggingHole(state, layerID, holeID, x, y) {
var layer = state.getIn(['scene', 'layers', layerID]);
var hole = layer.getIn(['holes', holeID]);
var line = layer.getIn(['lines', hole.line]);
var v0 = layer.getIn(['vertices', line.vertices.get(0)]);
var v1 = layer.getIn(['vertices', line.vertices.get(1)]);
var snapElements = (0, _snap.addLineSegmentSnap)((0, _immutable.List)(), v0.x, v0.y, v1.x, v1.y, 9999999, 1, null);
return state.merge({
mode: _constants.MODE_DRAGGING_HOLE,
snapElements: snapElements,
draggingSupport: (0, _immutable.Map)({
layerID: layerID,
holeID: holeID,
startPointX: x,
startPointY: y
})
});
}
function updateDraggingHole(state, x, y) {
//calculate snap and overwrite coords if needed
//force snap to segment
var snap = (0, _snap.nearestSnap)(state.snapElements, x, y, state.snapMask.merge({ SNAP_SEGMENT: true }));
if (!snap) return state;
var draggingSupport = state.draggingSupport,
scene = state.scene;
var layerID = draggingSupport.get('layerID');
var holeID = draggingSupport.get('holeID');
var startPointX = draggingSupport.get('startPointX');
var startPointY = draggingSupport.get('startPointY');
var layer = state.getIn(['scene', 'layers', layerID]);
var hole = layer.getIn(['holes', holeID]);
var line = layer.getIn(['lines', hole.line]);
var v0 = layer.getIn(['vertices', line.vertices.get(0)]);
var v1 = layer.getIn(['vertices', line.vertices.get(1)]);
// I need min and max vertices on this line segment
var _snap$point2 = snap.point;
x = _snap$point2.x;
y = _snap$point2.y;
var minVertex = Geometry.minVertex(v0, v1);
var maxVertex = Geometry.maxVertex(v0, v1);
// Now I need min and max possible coordinates for the hole on the line. They depend on the width of the hole
var width = hole.properties.get('width').get('length');
var lineLength = Geometry.pointsDistance(v0.x, v0.y, v1.x, v1.y);
var alpha = Math.atan2(Math.abs(v1.y - v0.y), Math.abs(v1.x - v0.x));
var cosWithThreshold = function cosWithThreshold(alpha) {
var cos = Math.cos(alpha);
return cos < 0.0000001 ? 0 : cos;
};
var sinWithThreshold = function sinWithThreshold(alpha) {
var sin = Math.sin(alpha);
return sin < 0.0000001 ? 0 : sin;
};
var cosAlpha = cosWithThreshold(alpha);
var sinAlpha = sinWithThreshold(alpha);
var minLeftVertexHole = {
x: minVertex.x + width / 2 * cosAlpha,
y: minVertex.y + width / 2 * sinAlpha
};
var maxRightVertexHole = {
x: minVertex.x + lineLength * cosAlpha - width / 2 * cosAlpha,
y: minVertex.y + lineLength * sinAlpha - width / 2 * sinAlpha
};
// Now I need to verify if the snap vertex (with coordinates x and y) is on the line segment
var offset = void 0;
if (x < minLeftVertexHole.x) {
// Snap point is previous the the line
offset = Geometry.pointPositionOnLineSegment(minVertex.x, minVertex.y, maxVertex.x, maxVertex.y, minLeftVertexHole.x, minLeftVertexHole.y);
} else {
// Snap point is after the line or on the line
if (x > maxRightVertexHole.x) {
offset = Geometry.pointPositionOnLineSegment(minVertex.x, minVertex.y, maxVertex.x, maxVertex.y, maxRightVertexHole.x, maxRightVertexHole.y);
} else if (x === minLeftVertexHole.x && x === maxRightVertexHole.x) {
// I am on a vertical line, I need to check y coordinates
if (y < minLeftVertexHole.y) {
offset = Geometry.pointPositionOnLineSegment(minVertex.x, minVertex.y, maxVertex.x, maxVertex.y, minLeftVertexHole.x, minLeftVertexHole.y);
offset = minVertex === v0 ? offset : 1 - offset;
} else if (y > maxRightVertexHole.y) {
offset = Geometry.pointPositionOnLineSegment(minVertex.x, minVertex.y, maxVertex.x, maxVertex.y, maxRightVertexHole.x, maxRightVertexHole.y);
offset = minVertex === v0 ? offset : 1 - offset;
} else {
offset = Geometry.pointPositionOnLineSegment(minVertex.x, minVertex.y, maxVertex.x, maxVertex.y, x, y);
offset = minVertex === v0 ? offset : 1 - offset;
}
} else {
offset = Geometry.pointPositionOnLineSegment(minVertex.x, minVertex.y, maxVertex.x, maxVertex.y, x, y);
}
}
hole = hole.set('offset', offset);
return state.merge({
scene: scene.mergeIn(['layers', layerID, 'holes', holeID], hole)
});
}
function endDraggingHole(state, x, y) {
state = updateDraggingHole(state, x, y);
return state.merge({
mode: _constants.MODE_IDLE,
sceneHistory: state.sceneHistory.push(state.scene)
});
}
function selectHole(state, layerID, holeID) {
var scene = state.scene;
scene = scene.merge({
layers: scene.layers.map(_layerOperations.unselectAll),
selectedLayer: layerID
});
scene = scene.updateIn(['layers', layerID], function (layer) {
return layer.withMutations(function (layer) {
(0, _layerOperations.select)(layer, 'holes', holeID);
});
});
return state.merge({
scene: scene,
sceneHistory: state.sceneHistory.push(scene)
});
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWR1Y2Vycy9ob2xlcy1yZWR1Y2VyLmpzIl0sIm5hbWVzIjpbInN0YXRlIiwiYWN0aW9uIiwidHlwZSIsInNlbGVjdFRvb2xEcmF3aW5nSG9sZSIsInNjZW5lQ29tcG9uZW50VHlwZSIsInVwZGF0ZURyYXdpbmdIb2xlIiwibGF5ZXJJRCIsIngiLCJ5IiwiZW5kRHJhd2luZ0hvbGUiLCJiZWdpbkRyYWdnaW5nSG9sZSIsImhvbGVJRCIsInVwZGF0ZURyYWdnaW5nSG9sZSIsImVuZERyYWdnaW5nSG9sZSIsInNlbGVjdEhvbGUiLCJHZW9tZXRyeSIsInNuYXBFbGVtZW50cyIsIndpdGhNdXRhdGlvbnMiLCJnZXRJbiIsInNjZW5lIiwic2VsZWN0ZWRMYXllciIsImxpbmVzIiwidmVydGljZXMiLCJmb3JFYWNoIiwiZ2V0IiwibGluZSIsIngxIiwieTEiLCJ4MiIsInkyIiwiaWQiLCJtZXJnZSIsIm1vZGUiLCJkcmF3aW5nU3VwcG9ydCIsImNhdGFsb2ciLCJzbmFwIiwic25hcE1hc2siLCJTTkFQX1NFR01FTlQiLCJwb2ludCIsInVwZGF0ZUluIiwibGF5ZXIiLCJzZWxlY3RlZEhvbGUiLCJmaXJzdCIsImxpbmVJRCIsInJlbGF0ZWQiLCJtaW5WZXJ0ZXgiLCJtYXhWZXJ0ZXgiLCJ3aWR0aCIsImZhY3RvcnlFbGVtZW50IiwicHJvcGVydGllcyIsImxpbmVMZW5ndGgiLCJwb2ludHNEaXN0YW5jZSIsImFscGhhIiwiTWF0aCIsImF0YW4yIiwiYWJzIiwiY29zV2l0aFRocmVzaG9sZCIsImNvcyIsInNpbldpdGhUaHJlc2hvbGQiLCJzaW4iLCJjb3NBbHBoYSIsInNpbkFscGhhIiwibWluTGVmdFZlcnRleEhvbGUiLCJtYXhSaWdodFZlcnRleEhvbGUiLCJvZmZzZXQiLCJwb2ludFBvc2l0aW9uT25MaW5lU2VnbWVudCIsImhvbGUiLCJzZXQiLCJzY2VuZUhpc3RvcnkiLCJwdXNoIiwidjAiLCJ2MSIsImRyYWdnaW5nU3VwcG9ydCIsInN0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dGVudCI6WyJpbXBvcnQge0xpc3QsIE1hcH0gZnJvbSAnaW1tdXRhYmxlJztcblxuaW1wb3J0IHtcbiAgU0VMRUNUX1RPT0xfRFJBV0lOR19IT0xFLFxuICBVUERBVEVfRFJBV0lOR19IT0xFLFxuICBFTkRfRFJBV0lOR19IT0xFLFxuICBCRUdJTl9EUkFHR0lOR19IT0xFLFxuICBVUERBVEVfRFJBR0dJTkdfSE9MRSxcbiAgRU5EX0RSQUdHSU5HX0hPTEUsXG4gIFNFTEVDVF9IT0xFLFxuXG4gIE1PREVfSURMRSxcbiAgTU9ERV9EUkFXSU5HX0hPTEUsXG4gIE1PREVfRFJBR0dJTkdfSE9MRSxcbn0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuaW1wb3J0ICogYXMgR2VvbWV0cnkgZnJvbSAnLi4vdXRpbHMvZ2VvbWV0cnknO1xuaW1wb3J0IHtcbiAgc2VsZWN0LFxuICB1bnNlbGVjdCxcbiAgdW5zZWxlY3RBbGwsXG4gIGFkZEhvbGUsXG4gIHJlbW92ZUhvbGUsXG59IGZyb20gJy4uL3V0aWxzL2xheWVyLW9wZXJhdGlvbnMnO1xuaW1wb3J0IHtcbiAgbmVhcmVzdFNuYXAsXG4gIGFkZFBvaW50U25hcCxcbiAgYWRkTGluZVNuYXAsXG4gIGFkZExpbmVTZWdtZW50U25hcCxcbiAgU05BUF9QT0lOVCxcbiAgU05BUF9MSU5FLFxuICBTTkFQX1NFR01FTlRcbn0gZnJvbSAnLi4vdXRpbHMvc25hcCc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzdGF0ZSwgYWN0aW9uKSB7XG4gIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICBjYXNlIFNFTEVDVF9UT09MX0RSQVdJTkdfSE9MRTpcbiAgICAgIHJldHVybiBzZWxlY3RUb29sRHJhd2luZ0hvbGUoc3RhdGUsIGFjdGlvbi5zY2VuZUNvbXBvbmVudFR5cGUpO1xuXG4gICAgY2FzZSBVUERBVEVfRFJBV0lOR19IT0xFOlxuICAgICAgcmV0dXJuIHVwZGF0ZURyYXdpbmdIb2xlKHN0YXRlLCBhY3Rpb24ubGF5ZXJJRCwgYWN0aW9uLngsIGFjdGlvbi55KTtcblxuICAgIGNhc2UgRU5EX0RSQVdJTkdfSE9MRTpcbiAgICAgIHJldHVybiBlbmREcmF3aW5nSG9sZShzdGF0ZSwgYWN0aW9uLmxheWVySUQsIGFjdGlvbi54LCBhY3Rpb24ueSk7XG5cbiAgICBjYXNlIEJFR0lOX0RSQUdHSU5HX0hPTEU6XG4gICAgICByZXR1cm4gYmVnaW5EcmFnZ2luZ0hvbGUoc3RhdGUsIGFjdGlvbi5sYXllcklELCBhY3Rpb24uaG9sZUlELCBhY3Rpb24ueCwgYWN0aW9uLnkpO1xuXG4gICAgY2FzZSBVUERBVEVfRFJBR0dJTkdfSE9MRTpcbiAgICAgIHJldHVybiB1cGRhdGVEcmFnZ2luZ0hvbGUoc3RhdGUsIGFjdGlvbi54LCBhY3Rpb24ueSk7XG5cbiAgICBjYXNlIEVORF9EUkFHR0lOR19IT0xFOlxuICAgICAgcmV0dXJuIGVuZERyYWdnaW5nSG9sZShzdGF0ZSwgYWN0aW9uLngsIGFjdGlvbi55KTtcblxuICAgIGNhc2UgU0VMRUNUX0hPTEU6XG4gICAgICByZXR1cm4gc2VsZWN0SG9sZShzdGF0ZSwgYWN0aW9uLmxheWVySUQsIGFjdGlvbi5ob2xlSUQpO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzZWxlY3RUb29sRHJhd2luZ0hvbGUoc3RhdGUsIHNjZW5lQ29tcG9uZW50VHlwZSkge1xuXG4gIGxldCBzbmFwRWxlbWVudHMgPSAobmV3IExpc3QoKSkud2l0aE11dGF0aW9ucyhzbmFwRWxlbWVudHMgPT4ge1xuICAgIGxldCB7bGluZXMsIHZlcnRpY2VzfSA9IHN0YXRlLmdldEluKFsnc2NlbmUnLCAnbGF5ZXJzJywgc3RhdGUuc2NlbmUuc2VsZWN0ZWRMYXllcl0pO1xuXG4gICAgbGluZXMuZm9yRWFjaChsaW5lID0+IHtcbiAgICAgIGxldCB7eDogeDEsIHk6IHkxfSA9IHZlcnRpY2VzLmdldChsaW5lLnZlcnRpY2VzLmdldCgwKSk7XG4gICAgICBsZXQge3g6IHgyLCB5OiB5Mn0gPSB2ZXJ0aWNlcy5nZXQobGluZS52ZXJ0aWNlcy5nZXQoMSkpO1xuXG4gICAgICBhZGRMaW5lU2VnbWVudFNuYXAoc25hcEVsZW1lbnRzLCB4MSwgeTEsIHgyLCB5MiwgMjAsIDEsIGxpbmUuaWQpO1xuICAgIH0pXG4gIH0pO1xuXG4gIHJldHVybiBzdGF0ZS5tZXJnZSh7XG4gICAgbW9kZTogTU9ERV9EUkFXSU5HX0hPTEUsXG4gICAgc25hcEVsZW1lbnRzLFxuICAgIGRyYXdpbmdTdXBwb3J0OiBNYXAoe1xuICAgICAgdHlwZTogc2NlbmVDb21wb25lbnRUeXBlXG4gICAgfSlcbiAgfSk7XG59XG5cbi8qKiBob2xlcyBvcGVyYXRpb25zICoqL1xuZnVuY3Rpb24gdXBkYXRlRHJhd2luZ0hvbGUoc3RhdGUsIGxheWVySUQsIHgsIHkpIHtcbiAgbGV0IGNhdGFsb2cgPSBzdGF0ZS5jYXRhbG9nO1xuXG4gIC8vY2FsY3VsYXRlIHNuYXAgYW5kIG92ZXJ3cml0ZSBjb29yZHMgaWYgbmVlZGVkXG4gIC8vZm9yY2Ugc25hcCB0byBzZWdtZW50XG4gIGxldCBzbmFwID0gbmVhcmVzdFNuYXAoc3RhdGUuc25hcEVsZW1lbnRzLCB4LCB5LCBzdGF0ZS5zbmFwTWFzay5tZXJnZSh7U05BUF9TRUdNRU5UOiB0cnVlfSkpO1xuICBpZiAoc25hcCkgKHt4LCB5fSA9IHNuYXAucG9pbnQpO1xuXG4gIGxldCBzY2VuZSA9IHN0YXRlLnNjZW5lLnVwZGF0ZUluKFsnbGF5ZXJzJywgbGF5ZXJJRF0sIGxheWVyID0+IGxheWVyLndpdGhNdXRhdGlvbnMobGF5ZXIgPT4ge1xuICAgIGxldCBzZWxlY3RlZEhvbGUgPSBsYXllci5nZXRJbihbJ3NlbGVjdGVkJywgJ2hvbGVzJ10pLmZpcnN0KCk7XG4gICAgaWYgKHNlbGVjdGVkSG9sZSkge1xuICAgICAgdW5zZWxlY3QobGF5ZXIsICdob2xlcycsIHNlbGVjdGVkSG9sZSk7XG4gICAgICByZW1vdmVIb2xlKGxheWVyLCBzZWxlY3RlZEhvbGUpO1xuICAgIH1cblxuICAgIGlmIChzbmFwKSB7XG4gICAgICBsZXQgbGluZUlEID0gc25hcC5zbmFwLnJlbGF0ZWQuZ2V0KDApO1xuICAgICAgbGV0IGxpbmUgPSBsYXllci5nZXRJbihbJ2xpbmVzJywgbGluZUlEXSk7XG4gICAgICBsZXQge3g6IHgxLCB5OiB5MX0gPSBsYXllci52ZXJ0aWNlcy5nZXQobGluZS52ZXJ0aWNlcy5nZXQoMCkpO1xuICAgICAgbGV0IHt4OiB4MiwgeTogeTJ9ID0gbGF5ZXIudmVydGljZXMuZ2V0KGxpbmUudmVydGljZXMuZ2V0KDEpKTtcblxuICAgICAgLy8gSSBuZWVkIG1pbiBhbmQgbWF4IHZlcnRpY2VzIG9uIHRoaXMgbGluZSBzZWdtZW50XG4gICAgICBsZXQgbWluVmVydGV4ID0gR2VvbWV0cnkubWluVmVydGV4KHt4OiB4MSwgeTogeTF9LCB7eDogeDIsIHk6IHkyfSk7XG4gICAgICBsZXQgbWF4VmVydGV4ID0gR2VvbWV0cnkubWF4VmVydGV4KHt4OiB4MSwgeTogeTF9LCB7eDogeDIsIHk6IHkyfSk7XG4gICAgICBsZXQgd2lkdGggPSBjYXRhbG9nLmZhY3RvcnlFbGVtZW50KHN0YXRlLmRyYXdpbmdTdXBwb3J0LmdldCgndHlwZScpLCB7fSwge30pLnByb3BlcnRpZXMuZ2V0KCd3aWR0aCcpLmdldCgnbGVuZ3RoJyk7XG5cblxuICAgICAgLy8gTm93IEkgbmVlZCBtaW4gYW5kIG1heCBwb3NzaWJsZSBjb29yZGluYXRlcyBmb3IgdGhlIGhvbGUgb24gdGhlIGxpbmUuIFRoZXkgZGVwZW5kIG9uIHRoZSB3aWR0aCBvZiB0aGUgaG9sZVxuXG4gICAgICAvLyBsZXQgd2lkdGggPSBob2xlLnByb3BlcnRpZXMuZ2V0KCd3aWR0aCcpLmdldCgnbGVuZ3RoJyk7XG4gICAgICBsZXQgbGluZUxlbmd0aCA9IEdlb21ldHJ5LnBvaW50c0Rpc3RhbmNlKHgxLCB5MSwgeDIsIHkyKTtcbiAgICAgIGxldCBhbHBoYSA9IE1hdGguYXRhbjIoTWF0aC5hYnMoeTIgLSB5MSksIE1hdGguYWJzKHgyIC0geDEpKTtcblxuICAgICAgbGV0IGNvc1dpdGhUaHJlc2hvbGQgPSAoYWxwaGEpID0+IHtcbiAgICAgICAgbGV0IGNvcyA9IE1hdGguY29zKGFscGhhKTtcbiAgICAgICAgcmV0dXJuIGNvcyA8IDAuMDAwMDAwMSA/IDAgOiBjb3M7XG4gICAgICB9O1xuXG4gICAgICBsZXQgc2luV2l0aFRocmVzaG9sZCA9IChhbHBoYSkgPT4ge1xuICAgICAgICBsZXQgc2luID0gTWF0aC5zaW4oYWxwaGEpO1xuICAgICAgICByZXR1cm4gc2luIDwgMC4wMDAwMDAxID8gMCA6IHNpbjtcbiAgICAgIH07XG5cbiAgICAgIGxldCBjb3NBbHBoYSA9IGNvc1dpdGhUaHJlc2hvbGQoYWxwaGEpO1xuICAgICAgbGV0IHNpbkFscGhhID0gc2luV2l0aFRocmVzaG9sZChhbHBoYSk7XG5cbiAgICAgIGxldCBtaW5MZWZ0VmVydGV4SG9sZSA9IHtcbiAgICAgICAgeDogbWluVmVydGV4LnggKyB3aWR0aCAvIDIgKiBjb3NBbHBoYSxcbiAgICAgICAgeTogbWluVmVydGV4LnkgKyB3aWR0aCAvIDIgKiBzaW5BbHBoYVxuICAgICAgfTtcblxuICAgICAgbGV0IG1heFJpZ2h0VmVydGV4SG9sZSA9IHtcbiAgICAgICAgeDogbWluVmVydGV4LnggKyBsaW5lTGVuZ3RoICogY29zQWxwaGEgLSB3aWR0aCAvIDIgKiBjb3NBbHBoYSxcbiAgICAgICAgeTogbWluVmVydGV4LnkgKyBsaW5lTGVuZ3RoICogc2luQWxwaGEgLSB3aWR0aCAvIDIgKiBzaW5BbHBoYVxuICAgICAgfTtcblxuICAgICAgbGV0IG9mZnNldDtcbiAgICAgIGlmICh4IDwgbWluTGVmdFZlcnRleEhvbGUueCkge1xuICAgICAgICBvZmZzZXQgPSBHZW9tZXRyeS5wb2ludFBvc2l0aW9uT25MaW5lU2VnbWVudChtaW5WZXJ0ZXgueCwgbWluVmVydGV4LnksXG4gICAgICAgICAgbWF4VmVydGV4LngsIG1heFZlcnRleC55LFxuICAgICAgICAgIG1pbkxlZnRWZXJ0ZXhIb2xlLngsIG1pbkxlZnRWZXJ0ZXhIb2xlLnkpO1xuICAgICAgfSBlbHNlIGlmICh4ID4gbWF4UmlnaHRWZXJ0ZXhIb2xlLngpIHtcbiAgICAgICAgb2Zmc2V0ID0gR2VvbWV0cnkucG9pbnRQb3NpdGlvbk9uTGluZVNlZ21lbnQobWluVmVydGV4LngsIG1pblZlcnRleC55LFxuICAgICAgICAgIG1heFZlcnRleC54LCBtYXhWZXJ0ZXgueSxcbiAgICAgICAgICBtYXhSaWdodFZlcnRleEhvbGUueCwgbWF4UmlnaHRWZXJ0ZXhIb2xlLnkpO1xuICAgICAgfSBlbHNlIHtcblxuICAgICAgICBpZiAoeCA9PT0gbWluTGVmdFZlcnRleEhvbGUueCAmJiB4ID09PSBtYXhSaWdodFZlcnRleEhvbGUueCkge1xuXG4gICAgICAgICAgaWYgKHkgPCBtaW5MZWZ0VmVydGV4SG9sZS55KSB7XG4gICAgICAgICAgICBvZmZzZXQgPSBHZW9tZXRyeS5wb2ludFBvc2l0aW9uT25MaW5lU2VnbWVudChtaW5WZXJ0ZXgueCwgbWluVmVydGV4LnksXG4gICAgICAgICAgICAgIG1heFZlcnRleC54LCBtYXhWZXJ0ZXgueSxcbiAgICAgICAgICAgICAgbWluTGVmdFZlcnRleEhvbGUueCwgbWluTGVmdFZlcnRleEhvbGUueSk7XG4gICAgICAgICAgICBvZmZzZXQgPSBtaW5WZXJ0ZXgueCA9PT0geDEgJiYgbWluVmVydGV4LnkgPT09IHkxID8gb2Zmc2V0IDogMSAtIG9mZnNldDtcbiAgICAgICAgICB9IGVsc2UgaWYgKHkgPiBtYXhSaWdodFZlcnRleEhvbGUueSkge1xuICAgICAgICAgICAgb2Zmc2V0ID0gR2VvbWV0cnkucG9pbnRQb3NpdGlvbk9uTGluZVNlZ21lbnQobWluVmVydGV4LngsIG1pblZlcnRleC55LFxuICAgICAgICAgICAgICBtYXhWZXJ0ZXgueCwgbWF4VmVydGV4LnksXG4gICAgICAgICAgICAgIG1heFJpZ2h0VmVydGV4SG9sZS54LCBtYXhSaWdodFZlcnRleEhvbGUueSk7XG4gICAgICAgICAgICBvZmZzZXQgPSBtaW5WZXJ0ZXgueCA9PT0geDEgJiYgbWluVmVydGV4LnkgPT09IHkxID8gb2Zmc2V0IDogMSAtIG9mZnNldDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb2Zmc2V0ID0gR2VvbWV0cnkucG9pbnRQb3NpdGlvbk9uTGluZVNlZ21lbnQoeDEsIHkxLCB4MiwgeTIsIHgsIHkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvZmZzZXQgPSBHZW9tZXRyeS5wb2ludFBvc2l0aW9uT25MaW5lU2VnbWVudCh4MSwgeTEsIHgyLCB5MiwgeCwgeSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbGV0IG9mZnNldCA9IEdlb21ldHJ5LnBvaW50UG9zaXRpb25PbkxpbmVTZWdtZW50KHgxLCB5MSwgeDIsIHkyLCB4LCB5KTtcbiAgICAgIGxldCB7aG9sZX0gPSBhZGRIb2xlKGxheWVyLCBzdGF0ZS5kcmF3aW5nU3VwcG9ydC5nZXQoJ3R5cGUnKSwgbGluZUlELCBvZmZzZXQsIGNhdGFsb2cpO1xuICAgICAgc2VsZWN0KGxheWVyLCAnaG9sZXMnLCBob2xlLmlkKTtcbiAgICB9XG4gIH0pKTtcblxuICByZXR1cm4gc3RhdGUuc2V0KCdzY2VuZScsIHNjZW5lKTtcbn1cblxuZnVuY3Rpb24gZW5kRHJhd2luZ0hvbGUoc3RhdGUsIGxheWVySUQsIHgsIHkpIHtcbiAgbGV0IGNhdGFsb2cgPSBzdGF0ZS5jYXRhbG9nO1xuXG4gIHN0YXRlID0gdXBkYXRlRHJhd2luZ0hvbGUoc3RhdGUsIGxheWVySUQsIHgsIHksIGNhdGFsb2cpO1xuICBsZXQgc2NlbmUgPSBzdGF0ZS5zY2VuZS51cGRhdGVJbihbJ2xheWVycycsIGxheWVySURdLCBsYXllciA9PiB1bnNlbGVjdEFsbChsYXllcikpO1xuICByZXR1cm4gc3RhdGUubWVyZ2Uoe1xuICAgIHNjZW5lLFxuICAgIHNjZW5lSGlzdG9yeTogc3RhdGUuc2NlbmVIaXN0b3J5LnB1c2goc2NlbmUpXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBiZWdpbkRyYWdnaW5nSG9sZShzdGF0ZSwgbGF5ZXJJRCwgaG9sZUlELCB4LCB5KSB7XG4gIGxldCBsYXllciA9IHN0YXRlLmdldEluKFsnc2NlbmUnLCAnbGF5ZXJzJywgbGF5ZXJJRF0pO1xuICBsZXQgaG9sZSA9IGxheWVyLmdldEluKFsnaG9sZXMnLCBob2xlSURdKTtcbiAgbGV0IGxpbmUgPSBsYXllci5nZXRJbihbJ2xpbmVzJywgaG9sZS5saW5lXSk7XG4gIGxldCB2MCA9IGxheWVyLmdldEluKFsndmVydGljZXMnLCBsaW5lLnZlcnRpY2VzLmdldCgwKV0pO1xuICBsZXQgdjEgPSBsYXllci5nZXRJbihbJ3ZlcnRpY2VzJywgbGluZS52ZXJ0aWNlcy5nZXQoMSldKTtcblxuICBsZXQgc25hcEVsZW1lbnRzID0gYWRkTGluZVNlZ21lbnRTbmFwKExpc3QoKSwgdjAueCwgdjAueSwgdjEueCwgdjEueSwgOTk5OTk5OSwgMSwgbnVsbCk7XG5cbiAgcmV0dXJuIHN0YXRlLm1lcmdlKHtcbiAgICBtb2RlOiBNT0RFX0RSQUdHSU5HX0hPTEUsXG4gICAgc25hcEVsZW1lbnRzLFxuICAgIGRyYWdnaW5nU3VwcG9ydDogTWFwKHtcbiAgICAgIGxheWVySUQsXG4gICAgICBob2xlSUQsXG4gICAgICBzdGFydFBvaW50WDogeCxcbiAgICAgIHN0YXJ0UG9pbnRZOiB5LFxuICAgIH0pXG4gIH0pO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVEcmFnZ2luZ0hvbGUoc3RhdGUsIHgsIHkpIHtcblxuICAvL2NhbGN1bGF0ZSBzbmFwIGFuZCBvdmVyd3JpdGUgY29vcmRzIGlmIG5lZWRlZFxuICAvL2ZvcmNlIHNuYXAgdG8gc2VnbWVudFxuICBsZXQgc25hcCA9IG5lYXJlc3RTbmFwKHN0YXRlLnNuYXBFbGVtZW50cywgeCwgeSwgc3RhdGUuc25hcE1hc2subWVyZ2Uoe1NOQVBfU0VHTUVOVDogdHJ1ZX0pKTtcbiAgaWYgKCFzbmFwKSByZXR1cm4gc3RhdGU7XG5cbiAgbGV0IHtkcmFnZ2luZ1N1cHBvcnQsIHNjZW5lfSA9IHN0YXRlO1xuXG4gIGxldCBsYXllcklEID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnbGF5ZXJJRCcpO1xuICBsZXQgaG9sZUlEID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnaG9sZUlEJyk7XG4gIGxldCBzdGFydFBvaW50WCA9IGRyYWdnaW5nU3VwcG9ydC5nZXQoJ3N0YXJ0UG9pbnRYJyk7XG4gIGxldCBzdGFydFBvaW50WSA9IGRyYWdnaW5nU3VwcG9ydC5nZXQoJ3N0YXJ0UG9pbnRZJyk7XG5cbiAgbGV0IGxheWVyID0gc3RhdGUuZ2V0SW4oWydzY2VuZScsICdsYXllcnMnLCBsYXllcklEXSk7XG4gIGxldCBob2xlID0gbGF5ZXIuZ2V0SW4oWydob2xlcycsIGhvbGVJRF0pO1xuICBsZXQgbGluZSA9IGxheWVyLmdldEluKFsnbGluZXMnLCBob2xlLmxpbmVdKTtcbiAgbGV0IHYwID0gbGF5ZXIuZ2V0SW4oWyd2ZXJ0aWNlcycsIGxpbmUudmVydGljZXMuZ2V0KDApXSk7XG4gIGxldCB2MSA9IGxheWVyLmdldEluKFsndmVydGljZXMnLCBsaW5lLnZlcnRpY2VzLmdldCgxKV0pO1xuXG4gICh7eCwgeX0gPSBzbmFwLnBvaW50KTtcblxuICAvLyBJIG5lZWQgbWluIGFuZCBtYXggdmVydGljZXMgb24gdGhpcyBsaW5lIHNlZ21lbnRcbiAgbGV0IG1pblZlcnRleCA9IEdlb21ldHJ5Lm1pblZlcnRleCh2MCwgdjEpO1xuICBsZXQgbWF4VmVydGV4ID0gR2VvbWV0cnkubWF4VmVydGV4KHYwLCB2MSk7XG5cbiAgLy8gTm93IEkgbmVlZCBtaW4gYW5kIG1heCBwb3NzaWJsZSBjb29yZGluYXRlcyBmb3IgdGhlIGhvbGUgb24gdGhlIGxpbmUuIFRoZXkgZGVwZW5kIG9uIHRoZSB3aWR0aCBvZiB0aGUgaG9sZVxuXG4gIGxldCB3aWR0aCA9IGhvbGUucHJvcGVydGllcy5nZXQoJ3dpZHRoJykuZ2V0KCdsZW5ndGgnKTtcbiAgbGV0IGxpbmVMZW5ndGggPSBHZW9tZXRyeS5wb2ludHNEaXN0YW5jZSh2MC54LCB2MC55LCB2MS54LCB2MS55KTtcbiAgbGV0IGFscGhhID0gTWF0aC5hdGFuMihNYXRoLmFicyh2MS55IC0gdjAueSksIE1hdGguYWJzKHYxLnggLSB2MC54KSk7XG5cbiAgbGV0IGNvc1dpdGhUaHJlc2hvbGQgPSAoYWxwaGEpID0+IHtcbiAgICBsZXQgY29zID0gTWF0aC5jb3MoYWxwaGEpO1xuICAgIHJldHVybiBjb3MgPCAwLjAwMDAwMDEgPyAwIDogY29zO1xuICB9O1xuXG4gIGxldCBzaW5XaXRoVGhyZXNob2xkID0gKGFscGhhKSA9PiB7XG4gICAgbGV0IHNpbiA9IE1hdGguc2luKGFscGhhKTtcbiAgICByZXR1cm4gc2luIDwgMC4wMDAwMDAxID8gMCA6IHNpbjtcbiAgfTtcblxuICBsZXQgY29zQWxwaGEgPSBjb3NXaXRoVGhyZXNob2xkKGFscGhhKTtcbiAgbGV0IHNpbkFscGhhID0gc2luV2l0aFRocmVzaG9sZChhbHBoYSk7XG5cbiAgbGV0IG1pbkxlZnRWZXJ0ZXhIb2xlID0ge1xuICAgIHg6IG1pblZlcnRleC54ICsgd2lkdGggLyAyICogY29zQWxwaGEsXG4gICAgeTogbWluVmVydGV4LnkgKyB3aWR0aCAvIDIgKiBzaW5BbHBoYVxuICB9O1xuXG4gIGxldCBtYXhSaWdodFZlcnRleEhvbGUgPSB7XG4gICAgeDogbWluVmVydGV4LnggKyBsaW5lTGVuZ3RoICogY29zQWxwaGEgLSB3aWR0aCAvIDIgKiBjb3NBbHBoYSxcbiAgICB5OiBtaW5WZXJ0ZXgueSArIGxpbmVMZW5ndGggKiBzaW5BbHBoYSAtIHdpZHRoIC8gMiAqIHNpbkFscGhhXG4gIH07XG5cbiAgLy8gTm93IEkgbmVlZCB0byB2ZXJpZnkgaWYgdGhlIHNuYXAgdmVydGV4ICh3aXRoIGNvb3JkaW5hdGVzIHggYW5kIHkpIGlzIG9uIHRoZSBsaW5lIHNlZ21lbnRcblxuICBsZXQgb2Zmc2V0O1xuXG4gIGlmICh4IDwgbWluTGVmdFZlcnRleEhvbGUueCkge1xuICAgIC8vIFNuYXAgcG9pbnQgaXMgcHJldmlvdXMgdGhlIHRoZSBsaW5lXG4gICAgb2Zmc2V0ID0gR2VvbWV0cnkucG9pbnRQb3NpdGlvbk9uTGluZVNlZ21lbnQobWluVmVydGV4LngsIG1pblZlcnRleC55LFxuICAgICAgbWF4VmVydGV4LngsIG1heFZlcnRleC55LFxuICAgICAgbWluTGVmdFZlcnRleEhvbGUueCwgbWluTGVmdFZlcnRleEhvbGUueSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gU25hcCBwb2ludCBpcyBhZnRlciB0aGUgbGluZSBvciBvbiB0aGUgbGluZVxuICAgIGlmICh4ID4gbWF4UmlnaHRWZXJ0ZXhIb2xlLngpIHtcbiAgICAgIG9mZnNldCA9IEdlb21ldHJ5LnBvaW50UG9zaXRpb25PbkxpbmVTZWdtZW50KG1pblZlcnRleC54LCBtaW5WZXJ0ZXgueSxcbiAgICAgICAgbWF4VmVydGV4LngsIG1heFZlcnRleC55LFxuICAgICAgICBtYXhSaWdodFZlcnRleEhvbGUueCwgbWF4UmlnaHRWZXJ0ZXhIb2xlLnkpO1xuICAgIH0gZWxzZSBpZiAoeCA9PT0gbWluTGVmdFZlcnRleEhvbGUueCAmJiB4ID09PSBtYXhSaWdodFZlcnRleEhvbGUueCkge1xuICAgICAgLy8gSSBhbSBvbiBhIHZlcnRpY2FsIGxpbmUsIEkgbmVlZCB0byBjaGVjayB5IGNvb3JkaW5hdGVzXG4gICAgICBpZiAoeSA8IG1pbkxlZnRWZXJ0ZXhIb2xlLnkpIHtcbiAgICAgICAgb2Zmc2V0ID0gR2VvbWV0cnkucG9pbnRQb3NpdGlvbk9uTGluZVNlZ21lbnQobWluVmVydGV4LngsIG1pblZlcnRleC55LFxuICAgICAgICAgIG1heFZlcnRleC54LCBtYXhWZXJ0ZXgueSxcbiAgICAgICAgICBtaW5MZWZ0VmVydGV4SG9sZS54LCBtaW5MZWZ0VmVydGV4SG9sZS55KTtcblxuICAgICAgICBvZmZzZXQgPSBtaW5WZXJ0ZXggPT09IHYwID8gb2Zmc2V0IDogMSAtIG9mZnNldDtcblxuICAgICAgfSBlbHNlIGlmICh5ID4gbWF4UmlnaHRWZXJ0ZXhIb2xlLnkpIHtcbiAgICAgICAgb2Zmc2V0ID0gR2VvbWV0cnkucG9pbnRQb3NpdGlvbk9uTGluZVNlZ21lbnQobWluVmVydGV4LngsIG1pblZlcnRleC55LFxuICAgICAgICAgIG1heFZlcnRleC54LCBtYXhWZXJ0ZXgueSxcbiAgICAgICAgICBtYXhSaWdodFZlcnRleEhvbGUueCwgbWF4UmlnaHRWZXJ0ZXhIb2xlLnkpO1xuXG4gICAgICAgIG9mZnNldCA9IG1pblZlcnRleCA9PT0gdjAgPyBvZmZzZXQgOiAxIC0gb2Zmc2V0O1xuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvZmZzZXQgPSBHZW9tZXRyeS5wb2ludFBvc2l0aW9uT25MaW5lU2VnbWVudChtaW5WZXJ0ZXgueCwgbWluVmVydGV4LnksXG4gICAgICAgICAgbWF4VmVydGV4LngsIG1heFZlcnRleC55LFxuICAgICAgICAgIHgsIHkpO1xuXG4gICAgICAgIG9mZnNldCA9IG1pblZlcnRleCA9PT0gdjAgPyBvZmZzZXQgOiAxIC0gb2Zmc2V0O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvZmZzZXQgPSBHZW9tZXRyeS5wb2ludFBvc2l0aW9uT25MaW5lU2VnbWVudChtaW5WZXJ0ZXgueCwgbWluVmVydGV4LnksXG4gICAgICAgIG1heFZlcnRleC54LCBtYXhWZXJ0ZXgueSxcbiAgICAgICAgeCwgeSk7XG4gICAgfVxuICB9XG5cbiAgaG9sZSA9IGhvbGUuc2V0KCdvZmZzZXQnLCBvZmZzZXQpO1xuXG4gIHJldHVybiBzdGF0ZS5tZXJnZSh7XG4gICAgc2NlbmU6IHNjZW5lLm1lcmdlSW4oWydsYXllcnMnLCBsYXllcklELCAnaG9sZXMnLCBob2xlSURdLCBob2xlKVxuICB9KTtcblxufVxuXG5mdW5jdGlvbiBlbmREcmFnZ2luZ0hvbGUoc3RhdGUsIHgsIHkpIHtcbiAgc3RhdGUgPSB1cGRhdGVEcmFnZ2luZ0hvbGUoc3RhdGUsIHgsIHkpO1xuICByZXR1cm4gc3RhdGUubWVyZ2Uoe1xuICAgIG1vZGU6IE1PREVfSURMRSxcbiAgICBzY2VuZUhpc3Rvcnk6IHN0YXRlLnNjZW5lSGlzdG9yeS5wdXNoKHN0YXRlLnNjZW5lKVxuICB9KTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0SG9sZShzdGF0ZSwgbGF5ZXJJRCwgaG9sZUlEKSB7XG4gIGxldCBzY2VuZSA9IHN0YXRlLnNjZW5lO1xuXG4gIHNjZW5lID0gc2NlbmUubWVyZ2Uoe1xuICAgIGxheWVyczogc2NlbmUubGF5ZXJzLm1hcCh1bnNlbGVjdEFsbCksXG4gICAgc2VsZWN0ZWRMYXllcjogbGF5ZXJJRFxuICB9KTtcblxuICBzY2VuZSA9IHNjZW5lLnVwZGF0ZUluKFsnbGF5ZXJzJywgbGF5ZXJJRF0sIGxheWVyID0+IGxheWVyLndpdGhNdXRhdGlvbnMobGF5ZXIgPT4ge1xuICAgIHNlbGVjdChsYXllciwgJ2hvbGVzJywgaG9sZUlEKTtcbiAgfSkpO1xuXG4gIHJldHVybiBzdGF0ZS5tZXJnZSh7XG4gICAgc2NlbmUsXG4gICAgc2NlbmVIaXN0b3J5OiBzdGF0ZS5zY2VuZUhpc3RvcnkucHVzaChzY2VuZSlcbiAgfSlcbn1cbiJdfQ==