UNPKG

react-planner-viewer

Version:

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

409 lines (330 loc) 42 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _reactSvgPanZoom = require('react-svg-pan-zoom'); var _constants = require('../../constants'); var constants = _interopRequireWildcard(_constants); var _state = require('./state'); var _state2 = _interopRequireDefault(_state); 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 _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function mode2Tool(mode) { switch (mode) { case constants.MODE_2D_PAN: return _reactSvgPanZoom.TOOL_PAN; case constants.MODE_2D_ZOOM_IN: return _reactSvgPanZoom.TOOL_ZOOM_IN; case constants.MODE_2D_ZOOM_OUT: return _reactSvgPanZoom.TOOL_ZOOM_OUT; case constants.MODE_IDLE: return _reactSvgPanZoom.TOOL_AUTO; default: return _reactSvgPanZoom.TOOL_NONE; } } function mode2PointerEvents(mode) { switch (mode) { case constants.MODE_DRAWING_LINE: case constants.MODE_DRAWING_HOLE: case constants.MODE_DRAWING_ITEM: case constants.MODE_DRAGGING_HOLE: case constants.MODE_DRAGGING_ITEM: case constants.MODE_DRAGGING_LINE: case constants.MODE_DRAGGING_VERTEX: return { pointerEvents: 'none' }; default: return {}; } } function mode2Cursor(mode) { switch (mode) { case constants.MODE_DRAGGING_HOLE: case constants.MODE_DRAGGING_LINE: case constants.MODE_DRAGGING_VERTEX: case constants.MODE_DRAGGING_ITEM: return { cursor: 'move' }; case constants.MODE_ROTATING_ITEM: return { cursor: 'ew-resize' }; case constants.MODE_WAITING_DRAWING_LINE: case constants.MODE_DRAWING_LINE: return { cursor: 'crosshair' }; default: return { cursor: 'default' }; } } function mode2DetectAutopan(mode) { switch (mode) { case constants.MODE_DRAWING_LINE: case constants.MODE_DRAGGING_LINE: case constants.MODE_DRAGGING_VERTEX: case constants.MODE_DRAGGING_HOLE: case constants.MODE_DRAGGING_ITEM: case constants.MODE_DRAWING_HOLE: case constants.MODE_DRAWING_ITEM: return true; default: return false; } } function extractElementData(node) { while (!node.attributes.getNamedItem('data-element-root') && node.tagName !== 'svg') { node = node.parentNode; } if (node.tagName === 'svg') return null; return { part: node.attributes.getNamedItem('data-part') ? node.attributes.getNamedItem('data-part').value : undefined, layer: node.attributes.getNamedItem('data-layer').value, prototype: node.attributes.getNamedItem('data-prototype').value, selected: node.attributes.getNamedItem('data-selected').value === 'true', id: node.attributes.getNamedItem('data-id').value, name: node.attributes.getNamedItem('data-name') ? node.attributes.getNamedItem('data-name').value : null }; } var Viewer2D = function (_React$Component) { _inherits(Viewer2D, _React$Component); function Viewer2D() { _classCallCheck(this, Viewer2D); return _possibleConstructorReturn(this, (Viewer2D.__proto__ || Object.getPrototypeOf(Viewer2D)).apply(this, arguments)); } _createClass(Viewer2D, [{ key: 'componentDidMount', value: function componentDidMount() { var _props = this.props, height = _props.height, width = _props.width, state = _props.state; this.Viewer.fitToViewer(); var scale = this.getScale(state.scene.width, state.scene.height, width, height); this.Viewer.setPointOnViewerCenter(this.props.state.scene.width / 2, this.props.state.scene.height / 2, scale); } }, { key: 'getScale', value: function getScale(sceneWidth, sceneHeight, width, height) { var scaleHeight = height / sceneHeight; var scaleWidth = width / sceneWidth; return Math.min(scaleHeight, scaleWidth); } }, { key: 'componentDidUpdate', value: function componentDidUpdate(prevProps) { var _props2 = this.props, nextWidth = _props2.width, nextHeight = _props2.height, nextState = _props2.state; var prevWidth = prevProps.width, prevHeight = prevProps.height, prevState = prevProps.state; var _prevState$scene = prevState.scene, prevSceneWidth = _prevState$scene.width, prevSceneHeight = _prevState$scene.height; var _nextState$scene = nextState.scene, nextSceneWidth = _nextState$scene.width, nextSceneHeight = _nextState$scene.height; var dimensionsExits = nextWidth && nextHeight && nextSceneWidth && nextSceneHeight; var sceneDimensionsChanged = nextSceneWidth != prevSceneWidth || nextSceneHeight != prevSceneHeight; var containerDimensionsChanged = nextWidth != prevWidth || nextHeight != prevHeight; if (dimensionsExits && (sceneDimensionsChanged || containerDimensionsChanged)) { this.Viewer.fitToViewer(); var scale = this.getScale(nextSceneWidth, nextSceneHeight, nextWidth, nextHeight); this.Viewer.setPointOnViewerCenter(nextSceneWidth / 2, nextSceneHeight / 2, scale); } } }, { key: 'render', value: function render() { var _this2 = this; var _props3 = this.props, state = _props3.state, width = _props3.width, height = _props3.height, onSelectArea = _props3.onSelectArea; var _context = this.context, viewer2DActions = _context.viewer2DActions, linesActions = _context.linesActions, holesActions = _context.holesActions, verticesActions = _context.verticesActions, itemsActions = _context.itemsActions, areaActions = _context.areaActions, projectActions = _context.projectActions, catalog = _context.catalog; var viewer2D = state.viewer2D, mode = state.mode, scene = state.scene; var layerID = scene.selectedLayer; var mapCursorPosition = function mapCursorPosition(_ref) { var x = _ref.x, y = _ref.y; return { x: x, y: -y + scene.height }; }; var onMouseMove = function onMouseMove(viewerEvent) { //workaround that allow imageful component to work var evt = new Event('mousemove-planner-event'); evt.viewerEvent = viewerEvent; document.dispatchEvent(evt); var _mapCursorPosition = mapCursorPosition(viewerEvent), x = _mapCursorPosition.x, y = _mapCursorPosition.y; projectActions.updateMouseCoord({ x: x, y: y }); switch (mode) { case constants.MODE_DRAWING_LINE: linesActions.updateDrawingLine(x, y, state.snapMask); break; case constants.MODE_DRAWING_HOLE: holesActions.updateDrawingHole(layerID, x, y); break; case constants.MODE_DRAWING_ITEM: itemsActions.updateDrawingItem(layerID, x, y); break; case constants.MODE_DRAGGING_HOLE: holesActions.updateDraggingHole(x, y); break; case constants.MODE_DRAGGING_LINE: linesActions.updateDraggingLine(x, y, state.snapMask); break; case constants.MODE_DRAGGING_VERTEX: verticesActions.updateDraggingVertex(x, y, state.snapMask); break; case constants.MODE_DRAGGING_ITEM: itemsActions.updateDraggingItem(x, y); break; case constants.MODE_ROTATING_ITEM: itemsActions.updateRotatingItem(x, y); break; } viewerEvent.originalEvent.stopPropagation(); }; var onMouseUp = function onMouseUp(viewerEvent) { var event = viewerEvent.originalEvent; var evt = new Event('mouseup-planner-event'); evt.viewerEvent = viewerEvent; document.dispatchEvent(evt); var _mapCursorPosition2 = mapCursorPosition(viewerEvent), x = _mapCursorPosition2.x, y = _mapCursorPosition2.y; switch (mode) { case constants.MODE_IDLE: var elementData = extractElementData(event.target); if (elementData && elementData.selected) return; switch (elementData ? elementData.prototype : 'none') { case 'areas': areaActions.selectArea(elementData.layer, elementData.id, elementData.name); onSelectArea(elementData.name); break; case 'none': projectActions.unselectAll(); onSelectArea(null); break; } break; case constants.MODE_WAITING_DRAWING_LINE: linesActions.beginDrawingLine(layerID, x, y, state.snapMask); break; case constants.MODE_DRAWING_LINE: linesActions.endDrawingLine(x, y, state.snapMask); linesActions.beginDrawingLine(layerID, x, y, state.snapMask); break; case constants.MODE_DRAWING_HOLE: holesActions.endDrawingHole(layerID, x, y); break; case constants.MODE_DRAWING_ITEM: itemsActions.endDrawingItem(layerID, x, y); break; case constants.MODE_DRAGGING_LINE: linesActions.endDraggingLine(x, y, state.snapMask); break; case constants.MODE_DRAGGING_VERTEX: verticesActions.endDraggingVertex(x, y, state.snapMask); break; case constants.MODE_DRAGGING_ITEM: itemsActions.endDraggingItem(x, y); break; case constants.MODE_DRAGGING_HOLE: holesActions.endDraggingHole(x, y); break; case constants.MODE_ROTATING_ITEM: itemsActions.endRotatingItem(x, y); break; } event.stopPropagation(); }; var onChangeValue = function onChangeValue(value) { projectActions.updateZoomScale(value.a); return viewer2DActions.updateCameraView(value); }; var onChangeTool = function onChangeTool(tool) { switch (tool) { case _reactSvgPanZoom.TOOL_NONE: projectActions.selectToolEdit(); break; case _reactSvgPanZoom.TOOL_PAN: viewer2DActions.selectToolPan(); break; case _reactSvgPanZoom.TOOL_ZOOM_IN: viewer2DActions.selectToolZoomIn(); break; case _reactSvgPanZoom.TOOL_ZOOM_OUT: viewer2DActions.selectToolZoomOut(); break; } }; var scale = this.getScale(scene.width, scene.height, width, height); return _react2.default.createElement( _reactSvgPanZoom.ReactSVGPanZoom, { ref: function ref(Viewer) { return _this2.Viewer = Viewer; }, width: width, height: height, value: viewer2D.isEmpty() ? null : viewer2D.toJS(), onChangeValue: onChangeValue, background: 'transparent', tool: mode2Tool(mode), toolbarPosition: 'none', onChangeTool: onChangeTool, detectAutoPan: mode2DetectAutopan(mode), onMouseUp: onMouseUp, SVGBackground: 'transparent', preventPanOutside: true, scaleFactorMin: scale, miniaturePosition: 'none' }, _react2.default.createElement( 'svg', { width: scene.width, height: scene.height }, _react2.default.createElement( 'g', { style: Object.assign(mode2Cursor(mode), mode2PointerEvents(mode)) }, _react2.default.createElement(_state2.default, { state: state, catalog: catalog }) ) ) ); } }]); return Viewer2D; }(_react2.default.Component); Viewer2D.propTypes = { state: _propTypes2.default.object.isRequired, width: _propTypes2.default.number.isRequired, height: _propTypes2.default.number.isRequired }; Viewer2D.contextTypes = { viewer2DActions: _propTypes2.default.object.isRequired, linesActions: _propTypes2.default.object.isRequired, holesActions: _propTypes2.default.object.isRequired, verticesActions: _propTypes2.default.object.isRequired, itemsActions: _propTypes2.default.object.isRequired, areaActions: _propTypes2.default.object.isRequired, projectActions: _propTypes2.default.object.isRequired, catalog: _propTypes2.default.object.isRequired }; exports.default = Viewer2D; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdlcjJkL3ZpZXdlcjJkLmpzeCJdLCJuYW1lcyI6WyJjb25zdGFudHMiLCJtb2RlMlRvb2wiLCJtb2RlIiwiTU9ERV8yRF9QQU4iLCJNT0RFXzJEX1pPT01fSU4iLCJNT0RFXzJEX1pPT01fT1VUIiwiTU9ERV9JRExFIiwibW9kZTJQb2ludGVyRXZlbnRzIiwiTU9ERV9EUkFXSU5HX0xJTkUiLCJNT0RFX0RSQVdJTkdfSE9MRSIsIk1PREVfRFJBV0lOR19JVEVNIiwiTU9ERV9EUkFHR0lOR19IT0xFIiwiTU9ERV9EUkFHR0lOR19JVEVNIiwiTU9ERV9EUkFHR0lOR19MSU5FIiwiTU9ERV9EUkFHR0lOR19WRVJURVgiLCJwb2ludGVyRXZlbnRzIiwibW9kZTJDdXJzb3IiLCJjdXJzb3IiLCJNT0RFX1JPVEFUSU5HX0lURU0iLCJNT0RFX1dBSVRJTkdfRFJBV0lOR19MSU5FIiwibW9kZTJEZXRlY3RBdXRvcGFuIiwiZXh0cmFjdEVsZW1lbnREYXRhIiwibm9kZSIsImF0dHJpYnV0ZXMiLCJnZXROYW1lZEl0ZW0iLCJ0YWdOYW1lIiwicGFyZW50Tm9kZSIsInBhcnQiLCJ2YWx1ZSIsInVuZGVmaW5lZCIsImxheWVyIiwicHJvdG90eXBlIiwic2VsZWN0ZWQiLCJpZCIsIm5hbWUiLCJWaWV3ZXIyRCIsInByb3BzIiwiaGVpZ2h0Iiwid2lkdGgiLCJzdGF0ZSIsIlZpZXdlciIsImZpdFRvVmlld2VyIiwic2NhbGUiLCJnZXRTY2FsZSIsInNjZW5lIiwic2V0UG9pbnRPblZpZXdlckNlbnRlciIsInNjZW5lV2lkdGgiLCJzY2VuZUhlaWdodCIsInNjYWxlSGVpZ2h0Iiwic2NhbGVXaWR0aCIsIk1hdGgiLCJtaW4iLCJwcmV2UHJvcHMiLCJuZXh0V2lkdGgiLCJuZXh0SGVpZ2h0IiwibmV4dFN0YXRlIiwicHJldldpZHRoIiwicHJldkhlaWdodCIsInByZXZTdGF0ZSIsInByZXZTY2VuZVdpZHRoIiwicHJldlNjZW5lSGVpZ2h0IiwibmV4dFNjZW5lV2lkdGgiLCJuZXh0U2NlbmVIZWlnaHQiLCJkaW1lbnNpb25zRXhpdHMiLCJzY2VuZURpbWVuc2lvbnNDaGFuZ2VkIiwiY29udGFpbmVyRGltZW5zaW9uc0NoYW5nZWQiLCJvblNlbGVjdEFyZWEiLCJjb250ZXh0Iiwidmlld2VyMkRBY3Rpb25zIiwibGluZXNBY3Rpb25zIiwiaG9sZXNBY3Rpb25zIiwidmVydGljZXNBY3Rpb25zIiwiaXRlbXNBY3Rpb25zIiwiYXJlYUFjdGlvbnMiLCJwcm9qZWN0QWN0aW9ucyIsImNhdGFsb2ciLCJ2aWV3ZXIyRCIsImxheWVySUQiLCJzZWxlY3RlZExheWVyIiwibWFwQ3Vyc29yUG9zaXRpb24iLCJ4IiwieSIsIm9uTW91c2VNb3ZlIiwiZXZ0IiwiRXZlbnQiLCJ2aWV3ZXJFdmVudCIsImRvY3VtZW50IiwiZGlzcGF0Y2hFdmVudCIsInVwZGF0ZU1vdXNlQ29vcmQiLCJ1cGRhdGVEcmF3aW5nTGluZSIsInNuYXBNYXNrIiwidXBkYXRlRHJhd2luZ0hvbGUiLCJ1cGRhdGVEcmF3aW5nSXRlbSIsInVwZGF0ZURyYWdnaW5nSG9sZSIsInVwZGF0ZURyYWdnaW5nTGluZSIsInVwZGF0ZURyYWdnaW5nVmVydGV4IiwidXBkYXRlRHJhZ2dpbmdJdGVtIiwidXBkYXRlUm90YXRpbmdJdGVtIiwib3JpZ2luYWxFdmVudCIsInN0b3BQcm9wYWdhdGlvbiIsIm9uTW91c2VVcCIsImV2ZW50IiwiZWxlbWVudERhdGEiLCJ0YXJnZXQiLCJzZWxlY3RBcmVhIiwidW5zZWxlY3RBbGwiLCJiZWdpbkRyYXdpbmdMaW5lIiwiZW5kRHJhd2luZ0xpbmUiLCJlbmREcmF3aW5nSG9sZSIsImVuZERyYXdpbmdJdGVtIiwiZW5kRHJhZ2dpbmdMaW5lIiwiZW5kRHJhZ2dpbmdWZXJ0ZXgiLCJlbmREcmFnZ2luZ0l0ZW0iLCJlbmREcmFnZ2luZ0hvbGUiLCJlbmRSb3RhdGluZ0l0ZW0iLCJvbkNoYW5nZVZhbHVlIiwidXBkYXRlWm9vbVNjYWxlIiwiYSIsInVwZGF0ZUNhbWVyYVZpZXciLCJvbkNoYW5nZVRvb2wiLCJ0b29sIiwic2VsZWN0VG9vbEVkaXQiLCJzZWxlY3RUb29sUGFuIiwic2VsZWN0VG9vbFpvb21JbiIsInNlbGVjdFRvb2xab29tT3V0IiwiaXNFbXB0eSIsInRvSlMiLCJPYmplY3QiLCJhc3NpZ24iLCJDb21wb25lbnQiLCJwcm9wVHlwZXMiLCJvYmplY3QiLCJpc1JlcXVpcmVkIiwibnVtYmVyIiwiY29udGV4dFR5cGVzIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7QUFFQTs7OztBQUNBOzs7O0FBRUE7O0FBQ0E7O0lBQVlBLFM7O0FBQ1o7Ozs7Ozs7Ozs7Ozs7O0FBRUEsU0FBU0MsU0FBVCxDQUFtQkMsSUFBbkIsRUFBeUI7QUFDdkIsVUFBUUEsSUFBUjtBQUNFLFNBQUtGLFVBQVVHLFdBQWY7QUFDRTtBQUNGLFNBQUtILFVBQVVJLGVBQWY7QUFDRTtBQUNGLFNBQUtKLFVBQVVLLGdCQUFmO0FBQ0U7QUFDRixTQUFLTCxVQUFVTSxTQUFmO0FBQ0U7QUFDRjtBQUNFO0FBVko7QUFZRDs7QUFFRCxTQUFTQyxrQkFBVCxDQUE0QkwsSUFBNUIsRUFBa0M7QUFDaEMsVUFBUUEsSUFBUjtBQUNFLFNBQUtGLFVBQVVRLGlCQUFmO0FBQ0EsU0FBS1IsVUFBVVMsaUJBQWY7QUFDQSxTQUFLVCxVQUFVVSxpQkFBZjtBQUNBLFNBQUtWLFVBQVVXLGtCQUFmO0FBQ0EsU0FBS1gsVUFBVVksa0JBQWY7QUFDQSxTQUFLWixVQUFVYSxrQkFBZjtBQUNBLFNBQUtiLFVBQVVjLG9CQUFmO0FBQ0UsYUFBTyxFQUFFQyxlQUFlLE1BQWpCLEVBQVA7O0FBRUY7QUFDRSxhQUFPLEVBQVA7QUFYSjtBQWFEOztBQUVELFNBQVNDLFdBQVQsQ0FBcUJkLElBQXJCLEVBQTJCO0FBQ3pCLFVBQVFBLElBQVI7QUFDRSxTQUFLRixVQUFVVyxrQkFBZjtBQUNBLFNBQUtYLFVBQVVhLGtCQUFmO0FBQ0EsU0FBS2IsVUFBVWMsb0JBQWY7QUFDQSxTQUFLZCxVQUFVWSxrQkFBZjtB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QjNGLFNBQU8sb0JBQVU0RixNQUFWLENBQWlCQyxVQURMO0FBRW5COUYsU0FBTyxvQkFBVStGLE1BQVYsQ0FBaUJELFVBRkw7QUFHbkIvRixVQUFRLG9CQUFVZ0csTUFBVixDQUFpQkQ7QUFITixDQUFyQjs7QUFNQWpHLFNBQVNtRyxZQUFULEdBQXdCO0FBQ3RCbEUsbUJBQWlCLG9CQUFVK0QsTUFBVixDQUFpQkMsVUFEWjtBQUV0Qi9ELGdCQUFjLG9CQUFVOEQsTUFBVixDQUFpQkMsVUFGVDtBQUd0QjlELGdCQUFjLG9CQUFVNkQsTUFBVixDQUFpQkMsVUFIVDtBQUl0QjdELG1CQUFpQixvQkFBVTRELE1BQVYsQ0FBaUJDLFVBSlo7QUFLdEI1RCxnQkFBYyxvQkFBVTJELE1BQVYsQ0FBaUJDLFVBTFQ7QUFNdEIzRCxlQUFhLG9CQUFVMEQsTUFBVixDQUFpQkMsVUFOUjtBQU90QjFELGtCQUFnQixvQkFBVXlELE1BQVYsQ0FBaUJDLFVBUFg7QUFRdEJ6RCxXQUFTLG9CQUFVd0QsTUFBVixDQUFpQkM7QUFSSixDQUF4Qjs7a0JBWWVqRyxRIiwiZmlsZSI6InZpZXdlcjJkLmpzIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcblxuaW1wb3J0IHsgUmVhY3RTVkdQYW5ab29tLCBUT09MX05PTkUsIFRPT0xfUEFOLCBUT09MX1pPT01fSU4sIFRPT0xfWk9PTV9PVVQsIFRPT0xfQVVUTyB9IGZyb20gJ3JlYWN0LXN2Zy1wYW4tem9vbSc7XG5pbXBvcnQgKiBhcyBjb25zdGFudHMgZnJvbSAnLi4vLi4vY29uc3RhbnRzJztcbmltcG9ydCBTdGF0ZSBmcm9tICcuL3N0YXRlJztcblxuZnVuY3Rpb24gbW9kZTJUb29sKG1vZGUpIHtcbiAgc3dpdGNoIChtb2RlKSB7XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV8yRF9QQU46XG4gICAgICByZXR1cm4gVE9PTF9QQU47XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV8yRF9aT09NX0lOOlxuICAgICAgcmV0dXJuIFRPT0xfWk9PTV9JTjtcbiAgICBjYXNlIGNvbnN0YW50cy5NT0RFXzJEX1pPT01fT1VUOlxuICAgICAgcmV0dXJuIFRPT0xfWk9PTV9PVVQ7XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV9JRExFOlxuICAgICAgcmV0dXJuIFRPT0xfQVVUTztcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFRPT0xfTk9ORTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtb2RlMlBvaW50ZXJFdmVudHMobW9kZSkge1xuICBzd2l0Y2ggKG1vZGUpIHtcbiAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQVdJTkdfTElORTpcbiAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQVdJTkdfSE9MRTpcbiAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQVdJTkdfSVRFTTpcbiAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQUdHSU5HX0hPTEU6XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFHR0lOR19JVEVNOlxuICAgIGNhc2UgY29uc3RhbnRzLk1PREVfRFJBR0dJTkdfTElORTpcbiAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQUdHSU5HX1ZFUlRFWDpcbiAgICAgIHJldHVybiB7IHBvaW50ZXJFdmVudHM6ICdub25lJyB9O1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7fTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtb2RlMkN1cnNvcihtb2RlKSB7XG4gIHN3aXRjaCAobW9kZSkge1xuICAgIGNhc2UgY29uc3RhbnRzLk1PREVfRFJBR0dJTkdfSE9MRTpcbiAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQUdHSU5HX0xJTkU6XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFHR0lOR19WRVJURVg6XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFHR0lOR19JVEVNOlxuICAgICAgcmV0dXJuIHsgY3Vyc29yOiAnbW92ZScgfTtcblxuICAgIGNhc2UgY29uc3RhbnRzLk1PREVfUk9UQVRJTkdfSVRFTTpcbiAgICAgIHJldHVybiB7IGN1cnNvcjogJ2V3LXJlc2l6ZScgfTtcblxuICAgIGNhc2UgY29uc3RhbnRzLk1PREVfV0FJVElOR19EUkFXSU5HX0xJTkU6XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFXSU5HX0xJTkU6XG4gICAgICByZXR1cm4geyBjdXJzb3I6ICdjcm9zc2hhaXInIH07XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB7IGN1cnNvcjogJ2RlZmF1bHQnIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gbW9kZTJEZXRlY3RBdXRvcGFuKG1vZGUpIHtcbiAgc3dpdGNoIChtb2RlKSB7XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFXSU5HX0xJTkU6XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFHR0lOR19MSU5FOlxuICAgIGNhc2UgY29uc3RhbnRzLk1PREVfRFJBR0dJTkdfVkVSVEVYOlxuICAgIGNhc2UgY29uc3RhbnRzLk1PREVfRFJBR0dJTkdfSE9MRTpcbiAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQUdHSU5HX0lURU06XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFXSU5HX0hPTEU6XG4gICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFXSU5HX0lURU06XG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXh0cmFjdEVsZW1lbnREYXRhKG5vZGUpIHtcbiAgd2hpbGUgKCFub2RlLmF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCdkYXRhLWVsZW1lbnQtcm9vdCcpICYmIG5vZGUudGFnTmFtZSAhPT0gJ3N2ZycpIHtcbiAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICB9XG4gIGlmIChub2RlLnRhZ05hbWUgPT09ICdzdmcnKSByZXR1cm4gbnVsbDtcblxuICByZXR1cm4ge1xuICAgIHBhcnQ6IG5vZGUuYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oJ2RhdGEtcGFydCcpID8gbm9kZS5hdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgnZGF0YS1wYXJ0JykudmFsdWUgOiB1bmRlZmluZWQsXG4gICAgbGF5ZXI6IG5vZGUuYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oJ2RhdGEtbGF5ZXInKS52YWx1ZSxcbiAgICBwcm90b3R5cGU6IG5vZGUuYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oJ2RhdGEtcHJvdG90eXBlJykudmFsdWUsXG4gICAgc2VsZWN0ZWQ6IG5vZGUuYXR0cmlidXRlcy5nZXROYW1lZEl0ZW0oJ2RhdGEtc2VsZWN0ZWQnKS52YWx1ZSA9PT0gJ3RydWUnLFxuICAgIGlkOiBub2RlLmF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCdkYXRhLWlkJykudmFsdWUsXG4gICAgbmFtZTogbm9kZS5hdHRyaWJ1dGVzLmdldE5hbWVkSXRlbSgnZGF0YS1uYW1lJykgPyBub2RlLmF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCdkYXRhLW5hbWUnKS52YWx1ZSA6IG51bGwsXG4gIH1cbn1cblxuY2xhc3MgVmlld2VyMkQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuXG4gIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgIGNvbnN0IHtoZWlnaHQsIHdpZHRoLHN0YXRlfSA9IHRoaXMucHJvcHM7XG4gICAgdGhpcy5WaWV3ZXIuZml0VG9WaWV3ZXIoKTtcbiAgICBjb25zdCBzY2FsZSA9IHRoaXMuZ2V0U2NhbGUoc3RhdGUuc2NlbmUud2lkdGgsIHN0YXRlLnNjZW5lLmhlaWdodCwgd2lkdGgsIGhlaWdodCk7XG4gICAgdGhpcy5WaWV3ZXIuc2V0UG9pbnRPblZpZXdlckNlbnRlcih0aGlzLnByb3BzLnN0YXRlLnNjZW5lLndpZHRoLzIsIHRoaXMucHJvcHMuc3RhdGUuc2NlbmUuaGVpZ2h0LzIsIHNjYWxlKVxuICB9XG4gIGdldFNjYWxlKHNjZW5lV2lkdGgsIHNjZW5lSGVpZ2h0LCB3aWR0aCwgaGVpZ2h0KXtcbiAgICBjb25zdCBzY2FsZUhlaWdodCA9IGhlaWdodC9zY2VuZUhlaWdodDtcbiAgICBjb25zdCBzY2FsZVdpZHRoID0gd2lkdGgvc2NlbmVXaWR0aDtcbiAgICByZXR1cm4gTWF0aC5taW4oc2NhbGVIZWlnaHQsc2NhbGVXaWR0aCk7XG4gIH1cbiAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcyl7XG4gICAgY29uc3Qge3dpZHRoOiBuZXh0V2lkdGgsIGhlaWdodDogbmV4dEhlaWdodCwgc3RhdGU6IG5leHRTdGF0ZSB9ID0gdGhpcy5wcm9wczsgXG4gICAgY29uc3Qge3dpZHRoOiBwcmV2V2lkdGgsIGhlaWdodDogcHJldkhlaWdodCwgc3RhdGU6IHByZXZTdGF0ZSB9ID0gcHJldlByb3BzOyBcbiAgICBjb25zdCB7d2lkdGg6IHByZXZTY2VuZVdpZHRoLCBoZWlnaHQ6IHByZXZTY2VuZUhlaWdodH0gPSBwcmV2U3RhdGUuc2NlbmU7XG4gICAgY29uc3Qge3dpZHRoOiBuZXh0U2NlbmVXaWR0aCwgaGVpZ2h0OiBuZXh0U2NlbmVIZWlnaHR9ID0gbmV4dFN0YXRlLnNjZW5lO1xuXG4gICAgY29uc3QgZGltZW5zaW9uc0V4aXRzID0gbmV4dFdpZHRoICYmIG5leHRIZWlnaHQgJiYgbmV4dFNjZW5lV2lkdGggJiYgbmV4dFNjZW5lSGVpZ2h0O1xuICAgIGNvbnN0IHNjZW5lRGltZW5zaW9uc0NoYW5nZWQgPSBuZXh0U2NlbmVXaWR0aCAhPSBwcmV2U2NlbmVXaWR0aCB8fCBuZXh0U2NlbmVIZWlnaHQgIT0gcHJldlNjZW5lSGVpZ2h0O1xuICAgIGNvbnN0IGNvbnRhaW5lckRpbWVuc2lvbnNDaGFuZ2VkID0gbmV4dFdpZHRoICE9IHByZXZXaWR0aCB8fCBuZXh0SGVpZ2h0ICE9IHByZXZIZWlnaHQ7XG4gXG4gICAgaWYoZGltZW5zaW9uc0V4aXRzICYmIChzY2VuZURpbWVuc2lvbnNDaGFuZ2VkIHx8IGNvbnRhaW5lckRpbWVuc2lvbnNDaGFuZ2VkKSl7XG4gICAgICB0aGlzLlZpZXdlci5maXRUb1ZpZXdlcigpO1xuICAgICAgY29uc3Qgc2NhbGUgPSB0aGlzLmdldFNjYWxlKG5leHRTY2VuZVdpZHRoLCBuZXh0U2NlbmVIZWlnaHQsIG5leHRXaWR0aCwgbmV4dEhlaWdodCk7XG4gICAgICB0aGlzLlZpZXdlci5zZXRQb2ludE9uVmlld2VyQ2VudGVyKG5leHRTY2VuZVdpZHRoLzIsIG5leHRTY2VuZUhlaWdodC8yLCBzY2FsZSlcbiAgICB9XG4gIH1cbiAgcmVuZGVyKCkge1xuXG4gICAgY29uc3QgeyBzdGF0ZSwgd2lkdGgsIGhlaWdodCwgb25TZWxlY3RBcmVhIH0gPSB0aGlzLnByb3BzO1xuICAgIGNvbnN0IHsgdmlld2VyMkRBY3Rpb25zLCBsaW5lc0FjdGlvbnMsIGhvbGVzQWN0aW9ucywgdmVydGljZXNBY3Rpb25zLCBpdGVtc0FjdGlvbnMsIGFyZWFBY3Rpb25zLCBwcm9qZWN0QWN0aW9ucywgY2F0YWxvZyB9ID0gdGhpcy5jb250ZXh0O1xuXG4gICAgbGV0IHsgdmlld2VyMkQsIG1vZGUsIHNjZW5lIH0gPSBzdGF0ZTtcblxuICAgIGxldCBsYXllcklEID0gc2NlbmUuc2VsZWN0ZWRMYXllcjtcblxuICAgIGxldCBtYXBDdXJzb3JQb3NpdGlvbiA9ICh7IHgsIHkgfSkgPT4ge1xuICAgICAgcmV0dXJuIHsgeCwgeTogLXkgKyBzY2VuZS5oZWlnaHQgfVxuICAgIH07XG5cbiAgICBsZXQgb25Nb3VzZU1vdmUgPSB2aWV3ZXJFdmVudCA9PiB7XG5cbiAgICAgIC8vd29ya2Fyb3VuZCB0aGF0IGFsbG93IGltYWdlZnVsIGNvbXBvbmVudCB0byB3b3JrXG4gICAgICB2YXIgZXZ0ID0gbmV3IEV2ZW50KCdtb3VzZW1vdmUtcGxhbm5lci1ldmVudCcpO1xuICAgICAgZXZ0LnZpZXdlckV2ZW50ID0gdmlld2VyRXZlbnQ7XG4gICAgICBkb2N1bWVudC5kaXNwYXRjaEV2ZW50KGV2dCk7XG5cbiAgICAgIGxldCB7IHgsIHkgfSA9IG1hcEN1cnNvclBvc2l0aW9uKHZpZXdlckV2ZW50KTtcblxuICAgICAgcHJvamVjdEFjdGlvbnMudXBkYXRlTW91c2VDb29yZCh7IHgsIHkgfSk7XG5cbiAgICAgIHN3aXRjaCAobW9kZSkge1xuICAgICAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQVdJTkdfTElORTpcbiAgICAgICAgICBsaW5lc0FjdGlvbnMudXBkYXRlRHJhd2luZ0xpbmUoeCwgeSwgc3RhdGUuc25hcE1hc2spO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgY29uc3RhbnRzLk1PREVfRFJBV0lOR19IT0xFOlxuICAgICAgICAgIGhvbGVzQWN0aW9ucy51cGRhdGVEcmF3aW5nSG9sZShsYXllcklELCB4LCB5KTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQVdJTkdfSVRFTTpcbiAgICAgICAgICBpdGVtc0FjdGlvbnMudXBkYXRlRHJhd2luZ0l0ZW0obGF5ZXJJRCwgeCwgeSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFHR0lOR19IT0xFOlxuICAgICAgICAgIGhvbGVzQWN0aW9ucy51cGRhdGVEcmFnZ2luZ0hvbGUoeCwgeSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFHR0lOR19MSU5FOlxuICAgICAgICAgIGxpbmVzQWN0aW9ucy51cGRhdGVEcmFnZ2luZ0xpbmUoeCwgeSwgc3RhdGUuc25hcE1hc2spO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgY29uc3RhbnRzLk1PREVfRFJBR0dJTkdfVkVSVEVYOlxuICAgICAgICAgIHZlcnRpY2VzQWN0aW9ucy51cGRhdGVEcmFnZ2luZ1ZlcnRleCh4LCB5LCBzdGF0ZS5zbmFwTWFzayk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFHR0lOR19JVEVNOlxuICAgICAgICAgIGl0ZW1zQWN0aW9ucy51cGRhdGVEcmFnZ2luZ0l0ZW0oeCwgeSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBjb25zdGFudHMuTU9ERV9ST1RBVElOR19JVEVNOlxuICAgICAgICAgIGl0ZW1zQWN0aW9ucy51cGRhdGVSb3RhdGluZ0l0ZW0oeCwgeSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHZpZXdlckV2ZW50Lm9yaWdpbmFsRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfTtcblxuXG5cbiAgICBsZXQgb25Nb3VzZVVwID0gdmlld2VyRXZlbnQgPT4ge1xuICAgICAgbGV0IGV2ZW50ID0gdmlld2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgICAgIHZhciBldnQgPSBuZXcgRXZlbnQoJ21vdXNldXAtcGxhbm5lci1ldmVudCcpO1xuICAgICAgZXZ0LnZpZXdlckV2ZW50ID0gdmlld2VyRXZlbnQ7XG4gICAgICBkb2N1bWVudC5kaXNwYXRjaEV2ZW50KGV2dCk7XG4gICAgICBsZXQgeyB4LCB5IH0gPSBtYXBDdXJzb3JQb3NpdGlvbih2aWV3ZXJFdmVudCk7XG5cbiAgICAgIHN3aXRjaCAobW9kZSkge1xuXG4gICAgICAgIGNhc2UgY29uc3RhbnRzLk1PREVfSURMRTpcbiAgICAgICAgICBsZXQgZWxlbWVudERhdGEgPSBleHRyYWN0RWxlbWVudERhdGEoZXZlbnQudGFyZ2V0KTtcblxuICAgICAgICAgIGlmIChlbGVtZW50RGF0YSAmJiBlbGVtZW50RGF0YS5zZWxlY3RlZCkgcmV0dXJuO1xuXG4gICAgICAgICAgc3dpdGNoIChlbGVtZW50RGF0YSA/IGVsZW1lbnREYXRhLnByb3RvdHlwZSA6ICdub25lJykge1xuICAgICAgICAgICAgY2FzZSAnYXJlYXMnOlxuICAgICAgICAgICAgICBhcmVhQWN0aW9ucy5zZWxlY3RBcmVhKGVsZW1lbnREYXRhLmxheWVyLCBlbGVtZW50RGF0YS5pZCwgZWxlbWVudERhdGEubmFtZSk7XG4gICAgICAgICAgICAgIG9uU2VsZWN0QXJlYShlbGVtZW50RGF0YS5uYW1lKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgJ25vbmUnOlxuICAgICAgICAgICAgICBwcm9qZWN0QWN0aW9ucy51bnNlbGVjdEFsbCgpO1xuICAgICAgICAgICAgICBvblNlbGVjdEFyZWEobnVsbCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIGNvbnN0YW50cy5NT0RFX1dBSVRJTkdfRFJBV0lOR19MSU5FOlxuICAgICAgICAgIGxpbmVzQWN0aW9ucy5iZWdpbkRyYXdpbmdMaW5lKGxheWVySUQsIHgsIHksIHN0YXRlLnNuYXBNYXNrKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQVdJTkdfTElORTpcbiAgICAgICAgICBsaW5lc0FjdGlvbnMuZW5kRHJhd2luZ0xpbmUoeCwgeSwgc3RhdGUuc25hcE1hc2spO1xuICAgICAgICAgIGxpbmVzQWN0aW9ucy5iZWdpbkRyYXdpbmdMaW5lKGxheWVySUQsIHgsIHksIHN0YXRlLnNuYXBNYXNrKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQVdJTkdfSE9MRTpcbiAgICAgICAgICBob2xlc0FjdGlvbnMuZW5kRHJhd2luZ0hvbGUobGF5ZXJJRCwgeCwgeSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBjb25zdGFudHMuTU9ERV9EUkFXSU5HX0lURU06XG4gICAgICAgICAgaXRlbXNBY3Rpb25zLmVuZERyYXdpbmdJdGVtKGxheWVySUQsIHgsIHkpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgY29uc3RhbnRzLk1PREVfRFJBR0dJTkdfTElORTpcbiAgICAgICAgICBsaW5lc0FjdGlvbnMuZW5kRHJhZ2dpbmdMaW5lKHgsIHksIHN0YXRlLnNuYXBNYXNrKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIGNvbnN0YW50cy5NT0RFX0RSQUdHSU5HX1ZFUlRFWDpcbiAgICAgICAgICB2ZXJ0aWNlc0FjdGlvbnMuZW5kRHJhZ2dpbmdWZXJ0ZXgoeCwgeSwgc3RhdGUuc25hcE1hc2spO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgY29uc3RhbnRzLk1PREVfRFJBR0dJTkdfSVRFTTpcbiAgICAgICAgICBpdGVtc0FjdGlvbnMuZW5kRHJhZ2dpbmdJdGVtKHgsIHkpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgY29uc3RhbnRzLk1PREVfRFJBR0dJTkdfSE9MRTpcbiAgICAgICAgICBob2xlc0FjdGlvbnMuZW5kRHJhZ2dpbmdIb2xlKHgsIHkpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgY29uc3RhbnRzLk1PREVfUk9UQVRJTkdfSVRFTTpcbiAgICAgICAgICBpdGVtc0FjdGlvbnMuZW5kUm90YXRpbmdJdGVtKHgsIHkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9O1xuXG4gICAgbGV0IG9uQ2hhbmdlVmFsdWUgPSAodmFsdWUpID0+IHtcbiAgICAgIHByb2plY3RBY3Rpb25zLnVwZGF0ZVpvb21TY2FsZSh2YWx1ZS5hKTtcbiAgICAgIHJldHVybiB2aWV3ZXIyREFjdGlvbnMudXBkYXRlQ2FtZXJhVmlldyh2YWx1ZSlcbiAgICB9O1xuXG4gICAgbGV0IG9uQ2hhbmdlVG9vbCA9ICh0b29sKSA9PiB7XG4gICAgICBzd2l0Y2ggKHRvb2wpIHtcbiAgICAgICAgY2FzZSBUT09MX05PTkU6XG4gICAgICAgICAgcHJvamVjdEFjdGlvbnMuc2VsZWN0VG9vbEVkaXQoKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFRPT0xfUEFOOlxuICAgICAgICAgIHZpZXdlcjJEQWN0aW9ucy5zZWxlY3RUb29sUGFuKCk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBUT09MX1pPT01fSU46XG4gICAgICAgICAgdmlld2VyMkRBY3Rpb25zLnNlbGVjdFRvb2xab29tSW4oKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFRPT0xfWk9PTV9PVVQ6XG4gICAgICAgICAgdmlld2VyMkRBY3Rpb25zLnNlbGVjdFRvb2xab29tT3V0KCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfTtcbiAgIGNvbnN0IHNjYWxlID0gdGhpcy5nZXRTY2FsZShzY2VuZS53aWR0aCwgc2NlbmUuaGVpZ2h0LCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgIHJldHVybiAoXG5cbiAgICAgIDxSZWFjdFNWR1Bhblpvb21cbiAgICAgICAgcmVmPXtWaWV3ZXIgPT4gdGhpcy5WaWV3ZXIgPSBWaWV3ZXJ9XG4gICAgICAgIHdpZHRoPXt3aWR0aH1cbiAgICAgICAgaGVpZ2h0PXtoZWlnaHR9XG4gICAgICAgIHZhbHVlPXt2aWV3ZXIyRC5pc0VtcHR5KCkgPyBudWxsIDogdmlld2VyMkQudG9KUygpfVxuICAgICAgICBvbkNoYW5nZVZhbHVlPXtvbkNoYW5nZVZhbHVlfVxuICAgICAgICBiYWNrZ3JvdW5kPXsndHJhbnNwYXJlbnQnfVxuICAgICAgICB0b29sPXttb2RlMlRvb2wobW9kZSl9XG4gICAgICAgIHRvb2xiYXJQb3NpdGlvbj17J25vbmUnfVxuICAgICAgICBvbkNoYW5nZVRvb2w9e29uQ2hhbmdlVG9vbH1cbiAgICAgICAgZGV0ZWN0QXV0b1Bhbj17bW9kZTJEZXRlY3RBdXRvcGFuKG1vZGUpfVxuICAgICAgICBvbk1vdXNlVXA9e29uTW91c2VVcH1cbiAgICAgICAgU1ZHQmFja2dyb3VuZD17J3RyYW5zcGFyZW50J31cbiAgICAgICAgcHJldmVudFBhbk91dHNpZGU9e3RydWV9XG4gICAgICAgIHNjYWxlRmFjdG9yTWluPXtzY2FsZX1cbiAgICAgICAgbWluaWF0dXJlUG9zaXRpb249J25vbmUnPlxuXG4gICAgICAgIDxzdmcgd2lkdGg9e3NjZW5lLndpZHRofSBoZWlnaHQ9e3NjZW5lLmhlaWdodH0+XG4gICAgICAgICAgPGcgc3R5bGU9e09iamVjdC5hc3NpZ24obW9kZTJDdXJzb3IobW9kZSksIG1vZGUyUG9pbnRlckV2ZW50cyhtb2RlKSl9PlxuICAgICAgICAgICAgPFN0YXRlIHN0YXRlPXtzdGF0ZX0gY2F0YWxvZz17Y2F0YWxvZ30gLz5cbiAgICAgICAgICA8L2c+XG4gICAgICAgIDwvc3ZnPlxuXG4gICAgICA8L1JlYWN0U1ZHUGFuWm9vbT5cblxuICAgICk7XG4gIH1cblxufVxuXG5WaWV3ZXIyRC5wcm9wVHlwZXMgPSB7XG4gIHN0YXRlOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gIHdpZHRoOiBQcm9wVHlwZXMubnVtYmVyLmlzUmVxdWlyZWQsXG4gIGhlaWdodDogUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkLFxufTtcblxuVmlld2VyMkQuY29udGV4dFR5cGVzID0ge1xuICB2aWV3ZXIyREFjdGlvbnM6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgbGluZXNBY3Rpb25zOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gIGhvbGVzQWN0aW9uczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICB2ZXJ0aWNlc0FjdGlvbnM6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgaXRlbXNBY3Rpb25zOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gIGFyZWFBY3Rpb25zOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gIHByb2plY3RBY3Rpb25zOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gIGNhdGFsb2c6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbn07XG5cblxuZXhwb3J0IGRlZmF1bHQgVmlld2VyMkQ7Il19