UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

316 lines (265 loc) 39.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports.AddDataButtonFactory = AddDataButtonFactory; exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _propTypes = _interopRequireDefault(require("prop-types")); var _reactSortableHoc = require("react-sortable-hoc"); var _styledComponents = _interopRequireDefault(require("styled-components")); var _reselect = require("reselect"); var _reactIntl = require("react-intl"); var _localization = require("../../localization"); var _dataUtils = require("../../utils/data-utils"); var _layerPanel = _interopRequireDefault(require("./layer-panel/layer-panel")); var _sourceDataCatalog = _interopRequireDefault(require("./common/source-data-catalog")); var _icons = require("../common/icons"); var _itemSelector = _interopRequireDefault(require("../common/item-selector/item-selector")); var _styledComponents2 = require("../common/styled-components"); var _defaultSettings = require("../../constants/default-settings"); var _templateObject; function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var LayerBlendingSelector = function LayerBlendingSelector(_ref) { var layerBlending = _ref.layerBlending, updateLayerBlending = _ref.updateLayerBlending, intl = _ref.intl; var labeledLayerBlendings = Object.keys(_defaultSettings.LAYER_BLENDINGS).reduce(function (acc, current) { return _objectSpread(_objectSpread({}, acc), {}, (0, _defineProperty2["default"])({}, intl.formatMessage({ id: _defaultSettings.LAYER_BLENDINGS[current].label }), current)); }, {}); var onChange = (0, _react.useCallback)(function (blending) { return updateLayerBlending(labeledLayerBlendings[blending]); }, [updateLayerBlending, labeledLayerBlendings]); return /*#__PURE__*/_react["default"].createElement(_styledComponents2.SidePanelSection, null, /*#__PURE__*/_react["default"].createElement(_styledComponents2.PanelLabel, null, /*#__PURE__*/_react["default"].createElement(_localization.FormattedMessage, { id: "layerBlending.title" })), /*#__PURE__*/_react["default"].createElement(_itemSelector["default"], { selectedItems: intl.formatMessage({ id: _defaultSettings.LAYER_BLENDINGS[layerBlending].label }), options: Object.keys(labeledLayerBlendings), multiSelect: false, searchable: false, onChange: onChange })); }; // make sure the element is always visible while is being dragged // item being dragged is appended in body, here to reset its global style var SortableStyledItem = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n z-index: ", ";\n\n &.sorting {\n pointer-events: none;\n }\n\n &.sorting-layers .layer-panel__header {\n background-color: ", ";\n font-family: ", ";\n font-weight: ", ";\n font-size: ", ";\n line-height: ", ";\n *,\n *:before,\n *:after {\n box-sizing: border-box;\n }\n .layer__drag-handle {\n opacity: 1;\n color: ", ";\n }\n }\n"])), function (props) { return props.theme.dropdownWrapperZ + 1; }, function (props) { return props.theme.panelBackgroundHover; }, function (props) { return props.theme.fontFamily; }, function (props) { return props.theme.fontWeight; }, function (props) { return props.theme.fontSize; }, function (props) { return props.theme.lineHeight; }, function (props) { return props.theme.textColorHl; }); function AddDataButtonFactory() { var AddDataButton = function AddDataButton(_ref2) { var onClick = _ref2.onClick, isInactive = _ref2.isInactive; return /*#__PURE__*/_react["default"].createElement(_styledComponents2.Button, { className: "add-data-button", onClick: onClick, isInactive: !isInactive, width: "105px", secondary: true }, /*#__PURE__*/_react["default"].createElement(_icons.Add, { height: "12px" }), /*#__PURE__*/_react["default"].createElement(_localization.FormattedMessage, { id: 'layerManager.addData' })); }; return AddDataButton; } LayerManagerFactory.deps = [AddDataButtonFactory, _layerPanel["default"], _sourceDataCatalog["default"]]; function LayerManagerFactory(AddDataButton, LayerPanel, SourceDataCatalog) { // By wrapping layer panel using a sortable element we don't have to implement the drag and drop logic into the panel itself; // Developers can provide any layer panel implementation and it will still be sortable var SortableItem = (0, _reactSortableHoc.SortableElement)(function (_ref3) { var children = _ref3.children, isSorting = _ref3.isSorting; return /*#__PURE__*/_react["default"].createElement(SortableStyledItem, { className: (0, _classnames["default"])('sortable-layer-items', { sorting: isSorting }) }, children); }); var WrappedSortableContainer = (0, _reactSortableHoc.SortableContainer)(function (_ref4) { var children = _ref4.children; return /*#__PURE__*/_react["default"].createElement("div", null, children); }); var LayerManager = /*#__PURE__*/function (_Component) { (0, _inherits2["default"])(LayerManager, _Component); var _super = _createSuper(LayerManager); function LayerManager() { var _this; (0, _classCallCheck2["default"])(this, LayerManager); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _super.call.apply(_super, [this].concat(args)); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { isSorting: false }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "layerClassSelector", function (props) { return props.layerClasses; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "layerTypeOptionsSelector", (0, _reselect.createSelector)(_this.layerClassSelector, function (layerClasses) { return Object.keys(layerClasses).map(function (key) { var layer = new layerClasses[key](); return { id: key, label: layer.name, icon: layer.layerIcon, requireData: layer.requireData }; }); })); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_addEmptyNewLayer", function () { var visStateActions = _this.props.visStateActions; visStateActions.addLayer(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_handleSort", function (_ref5) { var oldIndex = _ref5.oldIndex, newIndex = _ref5.newIndex; var visStateActions = _this.props.visStateActions; visStateActions.reorderLayer((0, _dataUtils.arrayMove)(_this.props.layerOrder, oldIndex, newIndex)); _this.setState({ isSorting: false }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onSortStart", function () { _this.setState({ isSorting: true }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_updateBeforeSortStart", function (_ref6) { var index = _ref6.index; // if layer config is active, close it var _this$props = _this.props, layerOrder = _this$props.layerOrder, layers = _this$props.layers, visStateActions = _this$props.visStateActions; var layerIdx = layerOrder[index]; if (layers[layerIdx].config.isConfigActive) { visStateActions.layerConfigChange(layers[layerIdx], { isConfigActive: false }); } }); return _this; } (0, _createClass2["default"])(LayerManager, [{ key: "render", value: function render() { var _this2 = this; var _this$props2 = this.props, layers = _this$props2.layers, datasets = _this$props2.datasets, intl = _this$props2.intl, layerOrder = _this$props2.layerOrder, showAddDataModal = _this$props2.showAddDataModal, showDatasetTable = _this$props2.showDatasetTable, removeDataset = _this$props2.removeDataset, uiStateActions = _this$props2.uiStateActions, visStateActions = _this$props2.visStateActions; var openModal = uiStateActions.toggleModal; var defaultDataset = Object.keys(datasets)[0]; var layerTypeOptions = this.layerTypeOptionsSelector(this.props); var layerActions = { layerColorUIChange: visStateActions.layerColorUIChange, layerConfigChange: visStateActions.layerConfigChange, layerVisualChannelConfigChange: visStateActions.layerVisualChannelConfigChange, layerTypeChange: visStateActions.layerTypeChange, layerVisConfigChange: visStateActions.layerVisConfigChange, layerTextLabelChange: visStateActions.layerTextLabelChange, removeLayer: visStateActions.removeLayer, duplicateLayer: visStateActions.duplicateLayer }; var panelProps = { datasets: datasets, openModal: openModal, layerTypeOptions: layerTypeOptions }; return /*#__PURE__*/_react["default"].createElement("div", { className: "layer-manager" }, /*#__PURE__*/_react["default"].createElement(SourceDataCatalog, { datasets: datasets, showDatasetTable: showDatasetTable, removeDataset: removeDataset, showDeleteDataset: true }), /*#__PURE__*/_react["default"].createElement(AddDataButton, { onClick: showAddDataModal, isInactive: !defaultDataset }), /*#__PURE__*/_react["default"].createElement(_styledComponents2.SidePanelDivider, null), /*#__PURE__*/_react["default"].createElement(_styledComponents2.SidePanelSection, null, /*#__PURE__*/_react["default"].createElement(WrappedSortableContainer, { onSortEnd: this._handleSort, onSortStart: this._onSortStart, updateBeforeSortStart: this._updateBeforeSortStart, lockAxis: "y", helperClass: "sorting-layers", useDragHandle: true }, layerOrder.map(function (layerIdx, index) { return !layers[layerIdx].config.hidden && /*#__PURE__*/_react["default"].createElement(SortableItem, { key: "layer-".concat(layerIdx), index: index, isSorting: _this2.state.isSorting }, /*#__PURE__*/_react["default"].createElement(LayerPanel, (0, _extends2["default"])({}, panelProps, layerActions, { sortData: layerIdx, key: layers[layerIdx].id, idx: layerIdx, layer: layers[layerIdx] }))); }))), /*#__PURE__*/_react["default"].createElement(_styledComponents2.SidePanelSection, null, defaultDataset ? /*#__PURE__*/_react["default"].createElement(_styledComponents2.Button, { className: "add-layer-button", onClick: this._addEmptyNewLayer, width: "105px" }, /*#__PURE__*/_react["default"].createElement(_icons.Add, { height: "12px" }), /*#__PURE__*/_react["default"].createElement(_localization.FormattedMessage, { id: 'layerManager.addLayer' })) : null), /*#__PURE__*/_react["default"].createElement(LayerBlendingSelector, { layerBlending: this.props.layerBlending, updateLayerBlending: visStateActions.updateLayerBlending, intl: intl })); } }]); return LayerManager; }(_react.Component); (0, _defineProperty2["default"])(LayerManager, "propTypes", { datasets: _propTypes["default"].object.isRequired, layerBlending: _propTypes["default"].string.isRequired, layerClasses: _propTypes["default"].object.isRequired, layers: _propTypes["default"].arrayOf(_propTypes["default"].any).isRequired, visStateActions: _propTypes["default"].object.isRequired, // functions removeDataset: _propTypes["default"].func.isRequired, showDatasetTable: _propTypes["default"].func.isRequired }); return (0, _reactIntl.injectIntl)(LayerManager); } var _default = LayerManagerFactory; exports["default"] = _default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3NpZGUtcGFuZWwvbGF5ZXItbWFuYWdlci5qcyJdLCJuYW1lcyI6WyJMYXllckJsZW5kaW5nU2VsZWN0b3IiLCJsYXllckJsZW5kaW5nIiwidXBkYXRlTGF5ZXJCbGVuZGluZyIsImludGwiLCJsYWJlbGVkTGF5ZXJCbGVuZGluZ3MiLCJPYmplY3QiLCJrZXlzIiwiTEFZRVJfQkxFTkRJTkdTIiwicmVkdWNlIiwiYWNjIiwiY3VycmVudCIsImZvcm1hdE1lc3NhZ2UiLCJpZCIsImxhYmVsIiwib25DaGFuZ2UiLCJibGVuZGluZyIsIlNvcnRhYmxlU3R5bGVkSXRlbSIsInN0eWxlZCIsImRpdiIsInByb3BzIiwidGhlbWUiLCJkcm9wZG93bldyYXBwZXJaIiwicGFuZWxCYWNrZ3JvdW5kSG92ZXIiLCJmb250RmFtaWx5IiwiZm9udFdlaWdodCIsImZvbnRTaXplIiwibGluZUhlaWdodCIsInRleHRDb2xvckhsIiwiQWRkRGF0YUJ1dHRvbkZhY3RvcnkiLCJBZGREYXRhQnV0dG9uIiwib25DbGljayIsImlzSW5hY3RpdmUiLCJMYXllck1hbmFnZXJGYWN0b3J5IiwiZGVwcyIsIkxheWVyUGFuZWxGYWN0b3J5IiwiU291cmNlRGF0YUNhdGFsb2dGYWN0b3J5IiwiTGF5ZXJQYW5lbCIsIlNvdXJjZURhdGFDYXRhbG9nIiwiU29ydGFibGVJdGVtIiwiY2hpbGRyZW4iLCJpc1NvcnRpbmciLCJzb3J0aW5nIiwiV3JhcHBlZFNvcnRhYmxlQ29udGFpbmVyIiwiTGF5ZXJNYW5hZ2VyIiwibGF5ZXJDbGFzc2VzIiwibGF5ZXJDbGFzc1NlbGVjdG9yIiwibWFwIiwia2V5IiwibGF5ZXIiLCJuYW1lIiwiaWNvbiIsImxheWVySWNvbiIsInJlcXVpcmVEYXRhIiwidmlzU3RhdGVBY3Rpb25zIiwiYWRkTGF5ZXIiLCJvbGRJbmRleCIsIm5ld0luZGV4IiwicmVvcmRlckxheWVyIiwibGF5ZXJPcmRlciIsInNldFN0YXRlIiwiaW5kZXgiLCJsYXllcnMiLCJsYXllcklkeCIsImNvbmZpZyIsImlzQ29uZmlnQWN0aXZlIiwibGF5ZXJDb25maWdDaGFuZ2UiLCJkYXRhc2V0cyIsInNob3dBZGREYXRhTW9kYWwiLCJzaG93RGF0YXNldFRhYmxlIiwicmVtb3ZlRGF0YXNldCIsInVpU3RhdGVBY3Rpb25zIiwib3Blbk1vZGFsIiwidG9nZ2xlTW9kYWwiLCJkZWZhdWx0RGF0YXNldCIsImxheWVyVHlwZU9wdGlvbnMiLCJsYXllclR5cGVPcHRpb25zU2VsZWN0b3IiLCJsYXllckFjdGlvbnMiLCJsYXllckNvbG9yVUlDaGFuZ2UiLCJsYXllclZpc3VhbENoYW5uZWxDb25maWdDaGFuZ2UiLCJsYXllclR5cGVDaGFuZ2UiLCJsYXllclZpc0NvbmZpZ0NoYW5nZSIsImxheWVyVGV4dExhYmVsQ2hhbmdlIiwicmVtb3ZlTGF5ZXIiLCJkdXBsaWNhdGVMYXllciIsInBhbmVsUHJvcHMiLCJfaGFuZGxlU29ydCIsIl9vblNvcnRTdGFydCIsIl91cGRhdGVCZWZvcmVTb3J0U3RhcnQiLCJoaWRkZW4iLCJzdGF0ZSIsIl9hZGRFbXB0eU5ld0xheWVyIiwiQ29tcG9uZW50IiwiUHJvcFR5cGVzIiwib2JqZWN0IiwiaXNSZXF1aXJlZCIsInN0cmluZyIsImFycmF5T2YiLCJhbnkiLCJmdW5jIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvQkE7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBT0E7Ozs7Ozs7Ozs7OztBQUVBLElBQU1BLHFCQUFxQixHQUFHLFNBQXhCQSxxQkFBd0IsT0FBZ0Q7QUFBQSxNQUE5Q0MsYUFBOEMsUUFBOUNBLGFBQThDO0FBQUEsTUFBL0JDLG1CQUErQixRQUEvQkEsbUJBQStCO0FBQUEsTUFBVkMsSUFBVSxRQUFWQSxJQUFVO0FBQzVFLE1BQU1DLHFCQUFxQixHQUFHQyxNQUFNLENBQUND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QkFBVU0sSUFBVixDQUFlSixVQVBiO0FBUWpCMUIsSUFBQUEsZ0JBQWdCLEVBQUV3QixzQkFBVU0sSUFBVixDQUFlSjtBQVJoQixHQWhCb0Q7QUE2SnpFLFNBQU8sMkJBQVduRCxZQUFYLENBQVA7QUFDRDs7ZUFFY1gsbUIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMjEgVWJlciBUZWNobm9sb2dpZXMsIEluYy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4vLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4vLyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4vLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuLy8gVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgUmVhY3QsIHtDb21wb25lbnQsIHVzZUNhbGxiYWNrfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgY2xhc3NuYW1lcyBmcm9tICdjbGFzc25hbWVzJztcblxuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCB7U29ydGFibGVDb250YWluZXIsIFNvcnRhYmxlRWxlbWVudH0gZnJvbSAncmVhY3Qtc29ydGFibGUtaG9jJztcbmltcG9ydCBzdHlsZWQgZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IHtjcmVhdGVTZWxlY3Rvcn0gZnJvbSAncmVzZWxlY3QnO1xuaW1wb3J0IHtpbmplY3RJbnRsfSBmcm9tICdyZWFjdC1pbnRsJztcbmltcG9ydCB7Rm9ybWF0dGVkTWVzc2FnZX0gZnJvbSAnbG9jYWxpemF0aW9uJztcbmltcG9ydCB7YXJyYXlNb3ZlfSBmcm9tICd1dGlscy9kYXRhLXV0aWxzJztcblxuaW1wb3J0IExheWVyUGFuZWxGYWN0b3J5IGZyb20gJy4vbGF5ZXItcGFuZWwvbGF5ZXItcGFuZWwnO1xuaW1wb3J0IFNvdXJjZURhdGFDYXRhbG9nRmFjdG9yeSBmcm9tICcuL2NvbW1vbi9zb3VyY2UtZGF0YS1jYXRhbG9nJztcbmltcG9ydCB7QWRkfSBmcm9tICdjb21wb25lbnRzL2NvbW1vbi9pY29ucyc7XG5pbXBvcnQgSXRlbVNlbGVjdG9yIGZyb20gJ2NvbXBvbmVudHMvY29tbW9uL2l0ZW0tc2VsZWN0b3IvaXRlbS1zZWxlY3Rvcic7XG5pbXBvcnQge1xuICBCdXR0b24sXG4gIFBhbmVsTGFiZWwsXG4gIFNpZGVQYW5lbERpdmlkZXIsXG4gIFNpZGVQYW5lbFNlY3Rpb25cbn0gZnJvbSAnY29tcG9uZW50cy9jb21tb24vc3R5bGVkLWNvbXBvbmVudHMnO1xuXG5pbXBvcnQge0xBWUVSX0JMRU5ESU5HU30gZnJvbSAnY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MnO1xuXG5jb25zdCBMYXllckJsZW5kaW5nU2VsZWN0b3IgPSAoe2xheWVyQmxlbmRpbmcsIHVwZGF0ZUxheWVyQmxlbmRpbmcsIGludGx9KSA9PiB7XG4gIGNvbnN0IGxhYmVsZWRMYXllckJsZW5kaW5ncyA9IE9iamVjdC5rZXlzKExBWUVSX0JMRU5ESU5HUykucmVkdWNlKFxuICAgIChhY2MsIGN1cnJlbnQpID0+ICh7XG4gICAgICAuLi5hY2MsXG4gICAgICBbaW50bC5mb3JtYXRNZXNzYWdlKHtpZDogTEFZRVJfQkxFTkRJTkdTW2N1cnJlbnRdLmxhYmVsfSldOiBjdXJyZW50XG4gICAgfSksXG4gICAge31cbiAgKTtcblxuICBjb25zdCBvbkNoYW5nZSA9IHVzZUNhbGxiYWNrKGJsZW5kaW5nID0+IHVwZGF0ZUxheWVyQmxlbmRpbmcobGFiZWxlZExheWVyQmxlbmRpbmdzW2JsZW5kaW5nXSksIFtcbiAgICB1cGRhdGVMYXllckJsZW5kaW5nLFxuICAgIGxhYmVsZWRMYXllckJsZW5kaW5nc1xuICBdKTtcblxuICByZXR1cm4gKFxuICAgIDxTaWRlUGFuZWxTZWN0aW9uPlxuICAgICAgPFBhbmVsTGFiZWw+XG4gICAgICAgIDxGb3JtYXR0ZWRNZXNzYWdlIGlkPVwibGF5ZXJCbGVuZGluZy50aXRsZVwiIC8+XG4gICAgICA8L1BhbmVsTGFiZWw+XG4gICAgICA8SXRlbVNlbGVjdG9yXG4gICAgICAgIHNlbGVjdGVkSXRlbXM9e2ludGwuZm9ybWF0TWVzc2FnZSh7aWQ6IExBWUVSX0JMRU5ESU5HU1tsYXllckJsZW5kaW5nXS5sYWJlbH0pfVxuICAgICAgICBvcHRpb25zPXtPYmplY3Qua2V5cyhsYWJlbGVkTGF5ZXJCbGVuZGluZ3MpfVxuICAgICAgICBtdWx0aVNlbGVjdD17ZmFsc2V9XG4gICAgICAgIHNlYXJjaGFibGU9e2ZhbHNlfVxuICAgICAgICBvbkNoYW5nZT17b25DaGFuZ2V9XG4gICAgICAvPlxuICAgIDwvU2lkZVBhbmVsU2VjdGlvbj5cbiAgKTtcbn07XG5cbi8vIG1ha2Ugc3VyZSB0aGUgZWxlbWVudCBpcyBhbHdheXMgdmlzaWJsZSB3aGlsZSBpcyBiZWluZyBkcmFnZ2VkXG4vLyBpdGVtIGJlaW5nIGRyYWdnZWQgaXMgYXBwZW5kZWQgaW4gYm9keSwgaGVyZSB0byByZXNldCBpdHMgZ2xvYmFsIHN0eWxlXG5jb25zdCBTb3J0YWJsZVN0eWxlZEl0ZW0gPSBzdHlsZWQuZGl2YFxuICB6LWluZGV4OiAke3Byb3BzID0+IHByb3BzLnRoZW1lLmRyb3Bkb3duV3JhcHBlclogKyAxfTtcblxuICAmLnNvcnRpbmcge1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICB9XG5cbiAgJi5zb3J0aW5nLWxheWVycyAubGF5ZXItcGFuZWxfX2hlYWRlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5wYW5lbEJhY2tncm91bmRIb3Zlcn07XG4gICAgZm9udC1mYW1pbHk6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZm9udEZhbWlseX07XG4gICAgZm9udC13ZWlnaHQ6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZm9udFdlaWdodH07XG4gICAgZm9udC1zaXplOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLmZvbnRTaXplfTtcbiAgICBsaW5lLWhlaWdodDogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5saW5lSGVpZ2h0fTtcbiAgICAqLFxuICAgICo6YmVmb3JlLFxuICAgICo6YWZ0ZXIge1xuICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICB9XG4gICAgLmxheWVyX19kcmFnLWhhbmRsZSB7XG4gICAgICBvcGFjaXR5OiAxO1xuICAgICAgY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUudGV4dENvbG9ySGx9O1xuICAgIH1cbiAgfVxuYDtcblxuZXhwb3J0IGZ1bmN0aW9uIEFkZERhdGFCdXR0b25GYWN0b3J5KCkge1xuICBjb25zdCBBZGREYXRhQnV0dG9uID0gKHtvbkNsaWNrLCBpc0luYWN0aXZlfSkgPT4gKFxuICAgIDxCdXR0b25cbiAgICAgIGNsYXNzTmFtZT1cImFkZC1kYXRhLWJ1dHRvblwiXG4gICAgICBvbkNsaWNrPXtvbkNsaWNrfVxuICAgICAgaXNJbmFjdGl2ZT17IWlzSW5hY3RpdmV9XG4gICAgICB3aWR0aD1cIjEwNXB4XCJcbiAgICAgIHNlY29uZGFyeVxuICAgID5cbiAgICAgIDxBZGQgaGVpZ2h0PVwiMTJweFwiIC8+XG4gICAgICA8Rm9ybWF0dGVkTWVzc2FnZSBpZD17J2xheWVyTWFuYWdlci5hZGREYXRhJ30gLz5cbiAgICA8L0J1dHRvbj5cbiAgKTtcblxuICByZXR1cm4gQWRkRGF0YUJ1dHRvbjtcbn1cblxuTGF5ZXJNYW5hZ2VyRmFjdG9yeS5kZXBzID0gW0FkZERhdGFCdXR0b25GYWN0b3J5LCBMYXllclBhbmVsRmFjdG9yeSwgU291cmNlRGF0YUNhdGFsb2dGYWN0b3J5XTtcblxuZnVuY3Rpb24gTGF5ZXJNYW5hZ2VyRmFjdG9yeShBZGREYXRhQnV0dG9uLCBMYXllclBhbmVsLCBTb3VyY2VEYXRhQ2F0YWxvZykge1xuICAvLyBCeSB3cmFwcGluZyBsYXllciBwYW5lbCB1c2luZyBhIHNvcnRhYmxlIGVsZW1lbnQgd2UgZG9uJ3QgaGF2ZSB0byBpbXBsZW1lbnQgdGhlIGRyYWcgYW5kIGRyb3AgbG9naWMgaW50byB0aGUgcGFuZWwgaXRzZWxmO1xuICAvLyBEZXZlbG9wZXJzIGNhbiBwcm92aWRlIGFueSBsYXllciBwYW5lbCBpbXBsZW1lbnRhdGlvbiBhbmQgaXQgd2lsbCBzdGlsbCBiZSBzb3J0YWJsZVxuICBjb25zdCBTb3J0YWJsZUl0ZW0gPSBTb3J0YWJsZUVsZW1lbnQoKHtjaGlsZHJlbiwgaXNTb3J0aW5nfSkgPT4ge1xuICAgIHJldHVybiAoXG4gICAgICA8U29ydGFibGVTdHlsZWRJdGVtIGNsYXNzTmFtZT17Y2xhc3NuYW1lcygnc29ydGFibGUtbGF5ZXItaXRlbXMnLCB7c29ydGluZzogaXNTb3J0aW5nfSl9PlxuICAgICAgICB7Y2hpbGRyZW59XG4gICAgICA8L1NvcnRhYmxlU3R5bGVkSXRlbT5cbiAgICApO1xuICB9KTtcblxuICBjb25zdCBXcmFwcGVkU29ydGFibGVDb250YWluZXIgPSBTb3J0YWJsZUNvbnRhaW5lcigoe2NoaWxkcmVufSkgPT4ge1xuICAgIHJldHVybiA8ZGl2PntjaGlsZHJlbn08L2Rpdj47XG4gIH0pO1xuXG4gIGNsYXNzIExheWVyTWFuYWdlciBleHRlbmRzIENvbXBvbmVudCB7XG4gICAgc3RhdGljIHByb3BUeXBlcyA9IHtcbiAgICAgIGRhdGFzZXRzOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICBsYXllckJsZW5kaW5nOiBQcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgICBsYXllckNsYXNzZXM6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgIGxheWVyczogUHJvcFR5cGVzLmFycmF5T2YoUHJvcFR5cGVzLmFueSkuaXNSZXF1aXJlZCxcbiAgICAgIHZpc1N0YXRlQWN0aW9uczogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgLy8gZnVuY3Rpb25zXG4gICAgICByZW1vdmVEYXRhc2V0OiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgICAgc2hvd0RhdGFzZXRUYWJsZTogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZFxuICAgIH07XG4gICAgc3RhdGUgPSB7XG4gICAgICBpc1NvcnRpbmc6IGZhbHNlXG4gICAgfTtcblxuICAgIGxheWVyQ2xhc3NTZWxlY3RvciA9IHByb3BzID0+IHByb3BzLmxheWVyQ2xhc3NlcztcbiAgICBsYXllclR5cGVPcHRpb25zU2VsZWN0b3IgPSBjcmVhdGVTZWxlY3Rvcih0aGlzLmxheWVyQ2xhc3NTZWxlY3RvciwgbGF5ZXJDbGFzc2VzID0+XG4gICAgICBPYmplY3Qua2V5cyhsYXllckNsYXNzZXMpLm1hcChrZXkgPT4ge1xuICAgICAgICBjb25zdCBsYXllciA9IG5ldyBsYXllckNsYXNzZXNba2V5XSgpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGlkOiBrZXksXG4gICAgICAgICAgbGFiZWw6IGxheWVyLm5hbWUsXG4gICAgICAgICAgaWNvbjogbGF5ZXIubGF5ZXJJY29uLFxuICAgICAgICAgIHJlcXVpcmVEYXRhOiBsYXllci5yZXF1aXJlRGF0YVxuICAgICAgICB9O1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgX2FkZEVtcHR5TmV3TGF5ZXIgPSAoKSA9PiB7XG4gICAgICBjb25zdCB7dmlzU3RhdGVBY3Rpb25zfSA9IHRoaXMucHJvcHM7XG4gICAgICB2aXNTdGF0ZUFjdGlvbnMuYWRkTGF5ZXIoKTtcbiAgICB9O1xuXG4gICAgX2hhbmRsZVNvcnQgPSAoe29sZEluZGV4LCBuZXdJbmRleH0pID0+IHtcbiAgICAgIGNvbnN0IHt2aXNTdGF0ZUFjdGlvbnN9ID0gdGhpcy5wcm9wcztcbiAgICAgIHZpc1N0YXRlQWN0aW9ucy5yZW9yZGVyTGF5ZXIoYXJyYXlNb3ZlKHRoaXMucHJvcHMubGF5ZXJPcmRlciwgb2xkSW5kZXgsIG5ld0luZGV4KSk7XG4gICAgICB0aGlzLnNldFN0YXRlKHtpc1NvcnRpbmc6IGZhbHNlfSk7XG4gICAgfTtcblxuICAgIF9vblNvcnRTdGFydCA9ICgpID0+IHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe2lzU29ydGluZzogdHJ1ZX0pO1xuICAgIH07XG5cbiAgICBfdXBkYXRlQmVmb3JlU29ydFN0YXJ0ID0gKHtpbmRleH0pID0+IHtcbiAgICAgIC8vIGlmIGxheWVyIGNvbmZpZyBpcyBhY3RpdmUsIGNsb3NlIGl0XG4gICAgICBjb25zdCB7bGF5ZXJPcmRlciwgbGF5ZXJzLCB2aXNTdGF0ZUFjdGlvbnN9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IGxheWVySWR4ID0gbGF5ZXJPcmRlcltpbmRleF07XG4gICAgICBpZiAobGF5ZXJzW2xheWVySWR4XS5jb25maWcuaXNDb25maWdBY3RpdmUpIHtcbiAgICAgICAgdmlzU3RhdGVBY3Rpb25zLmxheWVyQ29uZmlnQ2hhbmdlKGxheWVyc1tsYXllcklkeF0sIHtpc0NvbmZpZ0FjdGl2ZTogZmFsc2V9KTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmVuZGVyKCkge1xuICAgICAgY29uc3Qge1xuICAgICAgICBsYXllcnMsXG4gICAgICAgIGRhdGFzZXRzLFxuICAgICAgICBpbnRsLFxuICAgICAgICBsYXllck9yZGVyLFxuICAgICAgICBzaG93QWRkRGF0YU1vZGFsLFxuICAgICAgICBzaG93RGF0YXNldFRhYmxlLFxuICAgICAgICByZW1vdmVEYXRhc2V0LFxuICAgICAgICB1aVN0YXRlQWN0aW9ucyxcbiAgICAgICAgdmlzU3RhdGVBY3Rpb25zXG4gICAgICB9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IHt0b2dnbGVNb2RhbDogb3Blbk1vZGFsfSA9IHVpU3RhdGVBY3Rpb25zO1xuICAgICAgY29uc3QgZGVmYXVsdERhdGFzZXQgPSBPYmplY3Qua2V5cyhkYXRhc2V0cylbMF07XG4gICAgICBjb25zdCBsYXllclR5cGVPcHRpb25zID0gdGhpcy5sYXllclR5cGVPcHRpb25zU2VsZWN0b3IodGhpcy5wcm9wcyk7XG5cbiAgICAgIGNvbnN0IGxheWVyQWN0aW9ucyA9IHtcbiAgICAgICAgbGF5ZXJDb2xvclVJQ2hhbmdlOiB2aXNTdGF0ZUFjdGlvbnMubGF5ZXJDb2xvclVJQ2hhbmdlLFxuICAgICAgICBsYXllckNvbmZpZ0NoYW5nZTogdmlzU3RhdGVBY3Rpb25zLmxheWVyQ29uZmlnQ2hhbmdlLFxuICAgICAgICBsYXllclZpc3VhbENoYW5uZWxDb25maWdDaGFuZ2U6IHZpc1N0YXRlQWN0aW9ucy5sYXllclZpc3VhbENoYW5uZWxDb25maWdDaGFuZ2UsXG4gICAgICAgIGxheWVyVHlwZUNoYW5nZTogdmlzU3RhdGVBY3Rpb25zLmxheWVyVHlwZUNoYW5nZSxcbiAgICAgICAgbGF5ZXJWaXNDb25maWdDaGFuZ2U6IHZpc1N0YXRlQWN0aW9ucy5sYXllclZpc0NvbmZpZ0NoYW5nZSxcbiAgICAgICAgbGF5ZXJUZXh0TGFiZWxDaGFuZ2U6IHZpc1N0YXRlQWN0aW9ucy5sYXllclRleHRMYWJlbENoYW5nZSxcbiAgICAgICAgcmVtb3ZlTGF5ZXI6IHZpc1N0YXRlQWN0aW9ucy5yZW1vdmVMYXllcixcbiAgICAgICAgZHVwbGljYXRlTGF5ZXI6IHZpc1N0YXRlQWN0aW9ucy5kdXBsaWNhdGVMYXllclxuICAgICAgfTtcblxuICAgICAgY29uc3QgcGFuZWxQcm9wcyA9IHtcbiAgICAgICAgZGF0YXNldHMsXG4gICAgICAgIG9wZW5Nb2RhbCxcbiAgICAgICAgbGF5ZXJUeXBlT3B0aW9uc1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIChcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJsYXllci1tYW5hZ2VyXCI+XG4gICAgICAgICAgPFNvdXJjZURhdGFDYXRhbG9nXG4gICAgICAgICAgICBkYXRhc2V0cz17ZGF0YXNldHN9XG4gICAgICAgICAgICBzaG93RGF0YXNldFRhYmxlPXtzaG93RGF0YXNldFRhYmxlfVxuICAgICAgICAgICAgcmVtb3ZlRGF0YXNldD17cmVtb3ZlRGF0YXNldH1cbiAgICAgICAgICAgIHNob3dEZWxldGVEYXRhc2V0XG4gICAgICAgICAgLz5cbiAgICAgICAgICA8QWRkRGF0YUJ1dHRvbiBvbkNsaWNrPXtzaG93QWRkRGF0YU1vZGFsfSBpc0luYWN0aXZlPXshZGVmYXVsdERhdGFzZXR9IC8+XG4gICAgICAgICAgPFNpZGVQYW5lbERpdmlkZXIgLz5cbiAgICAgICAgICA8U2lkZVBhbmVsU2VjdGlvbj5cbiAgICAgICAgICAgIDxXcmFwcGVkU29ydGFibGVDb250YWluZXJcbiAgICAgICAgICAgICAgb25Tb3J0RW5kPXt0aGlzLl9oYW5kbGVTb3J0fVxuICAgICAgICAgICAgICBvblNvcnRTdGFydD17dGhpcy5fb25Tb3J0U3RhcnR9XG4gICAgICAgICAgICAgIHVwZGF0ZUJlZm9yZVNvcnRTdGFydD17dGhpcy5fdXBkYXRlQmVmb3JlU29ydFN0YXJ0fVxuICAgICAgICAgICAgICBsb2NrQXhpcz1cInlcIlxuICAgICAgICAgICAgICBoZWxwZXJDbGFzcz1cInNvcnRpbmctbGF5ZXJzXCJcbiAgICAgICAgICAgICAgdXNlRHJhZ0hhbmRsZVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7bGF5ZXJPcmRlci5tYXAoXG4gICAgICAgICAgICAgICAgKGxheWVySWR4LCBpbmRleCkgPT5cbiAgICAgICAgICAgICAgICAgICFsYXllcnNbbGF5ZXJJZHhdLmNvbmZpZy5oaWRkZW4gJiYgKFxuICAgICAgICAgICAgICAgICAgICA8U29ydGFibGVJdGVtXG4gICAgICAgICAgICAgICAgICAgICAga2V5PXtgbGF5ZXItJHtsYXllcklkeH1gfVxuICAgICAgICAgICAgICAgICAgICAgIGluZGV4PXtpbmRleH1cbiAgICAgICAgICAgICAgICAgICAgICBpc1NvcnRpbmc9e3RoaXMuc3RhdGUuaXNTb3J0aW5nfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgPExheWVyUGFuZWxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsuLi5wYW5lbFByb3BzfVxuICAgICAgICAgICAgICAgICAgICAgICAgey4uLmxheWVyQWN0aW9uc31cbiAgICAgICAgICAgICAgICAgICAgICAgIHNvcnREYXRhPXtsYXllcklkeH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGtleT17bGF5ZXJzW2xheWVySWR4XS5pZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlkeD17bGF5ZXJJZHh9XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXllcj17bGF5ZXJzW2xheWVySWR4XX1cbiAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICA8L1NvcnRhYmxlSXRlbT5cbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDwvV3JhcHBlZFNvcnRhYmxlQ29udGFpbmVyPlxuICAgICAgICAgIDwvU2lkZVBhbmVsU2VjdGlvbj5cbiAgICAgICAgICA8U2lkZVBhbmVsU2VjdGlvbj5cbiAgICAgICAgICAgIHtkZWZhdWx0RGF0YXNldCA/IChcbiAgICAgICAgICAgICAgPEJ1dHRvbiBjbGFzc05hbWU9XCJhZGQtbGF5ZXItYnV0dG9uXCIgb25DbGljaz17dGhpcy5fYWRkRW1wdHlOZXdMYXllcn0gd2lkdGg9XCIxMDVweFwiPlxuICAgICAgICAgICAgICAgIDxBZGQgaGVpZ2h0PVwiMTJweFwiIC8+XG4gICAgICAgICAgICAgICAgPEZvcm1hdHRlZE1lc3NhZ2UgaWQ9eydsYXllck1hbmFnZXIuYWRkTGF5ZXInfSAvPlxuICAgICAgICAgICAgICA8L0J1dHRvbj5cbiAgICAgICAgICAgICkgOiBudWxsfVxuICAgICAgICAgIDwvU2lkZVBhbmVsU2VjdGlvbj5cbiAgICAgICAgICA8TGF5ZXJCbGVuZGluZ1NlbGVjdG9yXG4gICAgICAgICAgICBsYXllckJsZW5kaW5nPXt0aGlzLnByb3BzLmxheWVyQmxlbmRpbmd9XG4gICAgICAgICAgICB1cGRhdGVMYXllckJsZW5kaW5nPXt2aXNTdGF0ZUFjdGlvbnMudXBkYXRlTGF5ZXJCbGVuZGluZ31cbiAgICAgICAgICAgIGludGw9e2ludGx9XG4gICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gaW5qZWN0SW50bChMYXllck1hbmFnZXIpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBMYXllck1hbmFnZXJGYWN0b3J5O1xuIl19