tc-ui-toolkit
Version:
React components used to develop tools for the desktop app translationCore
253 lines (200 loc) • 27.2 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
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 _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _deepEqual = _interopRequireDefault(require("deep-equal"));
var windowSelectionHelpers = _interopRequireWildcard(require("../helpers/windowSelectionHelpers"));
var selectionHelpers = _interopRequireWildcard(require("../helpers/selectionHelpers"));
var stringHelpers = _interopRequireWildcard(require("../helpers/stringHelpers"));
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; }
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 { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
var DBL_CLK_TIME = 1500; // time in ms
var DBL_CLK_DISTANCE = 10; // in pixels
var RenderSelectionTextComponent = /*#__PURE__*/function (_Component) {
(0, _inherits2["default"])(RenderSelectionTextComponent, _Component);
var _super = _createSuper(RenderSelectionTextComponent);
function RenderSelectionTextComponent() {
(0, _classCallCheck2["default"])(this, RenderSelectionTextComponent);
return _super.apply(this, arguments);
}
(0, _createClass2["default"])(RenderSelectionTextComponent, [{
key: "UNSAFE_componentWillMount",
value: function UNSAFE_componentWillMount() {
// track when the selections change to prevent false clicks of removals
this.renderTimestamp = Date.now();
}
}, {
key: "UNSAFE_componentWillReceiveProps",
value: function UNSAFE_componentWillReceiveProps(nextProps) {
// track when the selections change to prevent false clicks of removals
if (!(0, _deepEqual["default"])(this.props.selections, nextProps.selections)) {
this.renderTimestamp = Date.now();
}
}
/**
* get new selected text and update selections
* @param {String} verseText - current verse text
*/
}, {
key: "getSelectionText",
value: function getSelectionText(verseText) {
var selection = windowSelectionHelpers.getSelectionFromCurrentWindowSelection(verseText, this.doubleClick);
this.addSelection(selection);
}
/**
* keep track of mouse down events for double click calculation
* @param {Object} event - mouse event from callback
*/
}, {
key: "recordMouseDown",
value: function recordMouseDown(event) {
this.lastMouseDnEvent = this.mouseDnEvent; // need two mouse down events for double click calcs
this.mouseDnEvent = _objectSpread({}, event); // shallow copy
if (this.lastMouseDnEvent) {
// if we had a previous mouse down, check if this is a double click
var delta = this.mouseDnEvent.timeStamp - this.lastMouseDnEvent.timeStamp;
var isDblClkTime = delta < DBL_CLK_TIME; // both clicks must be within time limit
var deltaX = this.mouseDnEvent.clientX - this.lastMouseDnEvent.clientX;
var isDblClkX = Math.abs(deltaX) < DBL_CLK_DISTANCE; // both clicks X change must be within limit
var deltaY = this.mouseDnEvent.clientY - this.lastMouseDnEvent.clientY;
var isDblClkY = Math.abs(deltaY) < DBL_CLK_DISTANCE; // both clicks Y change must be within limit
this.doubleClick = isDblClkTime && isDblClkX && isDblClkY;
if (this.doubleClick) {
console.log("recordMouseDown() - Double Click detected");
}
}
}
}, {
key: "addSelection",
value: function addSelection(selection) {
var _this$props = this.props,
selections = _this$props.selections,
verseText = _this$props.verseText,
translate = _this$props.translate,
openAlertDialog = _this$props.openAlertDialog,
changeSelectionsInLocalState = _this$props.changeSelectionsInLocalState;
selections = selectionHelpers.addSelectionToSelections(selection, selections, verseText); // this is a good place to preview selections before saved in state
if (selections.length <= this.props.maximumSelections) {
changeSelectionsInLocalState(selections);
} else {
var message = translate('select_too_many', {
maximum: this.props.maximumSelections
});
openAlertDialog(message);
}
}
}, {
key: "removeSelection",
value: function removeSelection(selection) {
var _this$props2 = this.props,
selections = _this$props2.selections,
verseText = _this$props2.verseText,
changeSelectionsInLocalState = _this$props2.changeSelectionsInLocalState;
var newSelections = selectionHelpers.removeSelectionFromSelections(selection, selections, verseText);
changeSelectionsInLocalState(newSelections);
}
}, {
key: "inDisplayBox",
value: function inDisplayBox(insideDisplayBox) {
var verseText = this.props.verseText;
this.setState({
inBox: insideDisplayBox
});
if (!insideDisplayBox && Math.abs(window.getSelection().extentOffset - window.getSelection().baseOffset) > 0) {
this.getSelectionText(verseText);
}
}
}, {
key: "verseTextSpans",
value: function verseTextSpans(selections, verseText) {
var _this = this;
var verseTextSpans; // return
var stringSplices = selectionHelpers.selectionsToStringSplices(verseText, selections);
verseTextSpans = stringSplices.map(function (stringSplice, index) {
var selectMode = _this.props.mode === 'select'; // use selectMode to conditionally use highlight and remove
var style = {
color: 'black'
};
var callback = function callback() {};
if (stringSplice.selected) {
style.backgroundColor = 'var(--highlight-color)';
if (selectMode) {
style.cursor = 'pointer'; // only show hand if in select mode
callback = function callback() {
var timePassed = Date.now() - _this.renderTimestamp; // see how long between now and last selection
var isRealClick = timePassed > 100; // if the click happened quicker than 100ms, it was likely false click
if (isRealClick) {
_this.removeSelection(stringSplice);
} // actually remove since it was likely a real click
};
}
}
var targetLanguageFontClassName = _this.props.targetLanguageFontClassName;
return /*#__PURE__*/_react["default"].createElement("span", {
key: index,
className: targetLanguageFontClassName,
style: style,
onClick: callback
}, stringSplice.text);
});
return verseTextSpans;
}
}, {
key: "render",
value: function render() {
var _this2 = this;
var _this$props3 = this.props,
verseText = _this$props3.verseText,
selections = _this$props3.selections,
targetLanguageFontClassName = _this$props3.targetLanguageFontClassName; // normalize whitespace for text rendering in order to display highlights with more than one space since html selections show one space
verseText = stringHelpers.normalizeString(verseText);
var verseTextSpans = /*#__PURE__*/_react["default"].createElement("span", {
className: targetLanguageFontClassName
}, verseText);
if (selections && selections.length > 0) {
verseTextSpans = this.verseTextSpans(selections, verseText);
}
return /*#__PURE__*/_react["default"].createElement("div", {
onMouseUp: function onMouseUp() {
return _this2.getSelectionText(verseText);
},
onMouseDown: function onMouseDown(e) {
return _this2.recordMouseDown(e);
},
onMouseLeave: function onMouseLeave() {
return _this2.inDisplayBox(false);
},
onMouseEnter: function onMouseEnter() {
return _this2.inDisplayBox(true);
}
}, verseTextSpans);
}
}]);
return RenderSelectionTextComponent;
}(_react.Component);
RenderSelectionTextComponent.propTypes = {
mode: _propTypes["default"].string.isRequired,
verseText: _propTypes["default"].string.isRequired,
selections: _propTypes["default"].array.isRequired,
translate: _propTypes["default"].func.isRequired,
maximumSelections: _propTypes["default"].number.isRequired,
changeSelectionsInLocalState: _propTypes["default"].func.isRequired,
openAlertDialog: _propTypes["default"].func.isRequired,
targetLanguageFontClassName: _propTypes["default"].string
};
var _default = RenderSelectionTextComponent;
exports["default"] = _default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9WZXJzZUNoZWNrL1JlbmRlclNlbGVjdGlvblRleHRDb21wb25lbnQvaW5kZXguanMiXSwibmFtZXMiOlsiREJMX0NMS19USU1FIiwiREJMX0NMS19ESVNUQU5DRSIsIlJlbmRlclNlbGVjdGlvblRleHRDb21wb25lbnQiLCJyZW5kZXJUaW1lc3RhbXAiLCJEYXRlIiwibm93IiwibmV4dFByb3BzIiwicHJvcHMiLCJzZWxlY3Rpb25zIiwidmVyc2VUZXh0Iiwic2VsZWN0aW9uIiwid2luZG93U2VsZWN0aW9uSGVscGVycyIsImdldFNlbGVjdGlvbkZyb21DdXJyZW50V2luZG93U2VsZWN0aW9uIiwiZG91YmxlQ2xpY2siLCJhZGRTZWxlY3Rpb24iLCJldmVudCIsImxhc3RNb3VzZURuRXZlbnQiLCJtb3VzZURuRXZlbnQiLCJkZWx0YSIsInRpbWVTdGFtcCIsImlzRGJsQ2xrVGltZSIsImRlbHRhWCIsImNsaWVudFgiLCJpc0RibENsa1giLCJNYXRoIiwiYWJzIiwiZGVsdGFZIiwiY2xpZW50WSIsImlzRGJsQ2xrWSIsImNvbnNvbGUiLCJsb2ciLCJ0cmFuc2xhdGUiLCJvcGVuQWxlcnREaWFsb2ciLCJjaGFuZ2VTZWxlY3Rpb25zSW5Mb2NhbFN0YXRlIiwic2VsZWN0aW9uSGVscGVycyIsImFkZFNlbGVjdGlvblRvU2VsZWN0aW9ucyIsImxlbmd0aCIsIm1heGltdW1TZWxlY3Rpb25zIiwibWVzc2FnZSIsIm1heGltdW0iLCJuZXdTZWxlY3Rpb25zIiwicmVtb3ZlU2VsZWN0aW9uRnJvbVNlbGVjdGlvbnMiLCJpbnNpZGVEaXNwbGF5Qm94Iiwic2V0U3RhdGUiLCJpbkJveCIsIndpbmRvdyIsImdldFNlbGVjdGlvbiIsImV4dGVudE9mZnNldCIsImJhc2VPZmZzZXQiLCJnZXRTZWxlY3Rpb25UZXh0IiwidmVyc2VUZXh0U3BhbnMiLCJzdHJpbmdTcGxpY2VzIiwic2VsZWN0aW9uc1RvU3RyaW5nU3BsaWNlcyIsIm1hcCIsInN0cmluZ1NwbGljZSIsImluZGV4Iiwic2VsZWN0TW9kZSIsIm1vZGUiLCJzdHlsZSIsImNvbG9yIiwiY2FsbGJhY2siLCJzZWxlY3RlZCIsImJhY2tncm91bmRDb2xvciIsImN1cnNvciIsInRpbWVQYXNzZWQiLCJpc1JlYWxDbGljayIsInJlbW92ZVNlbGVjdGlvbiIsInRhcmdldExhbmd1YWdlRm9udENsYXNzTmFtZSIsInRleHQiLCJzdHJpbmdIZWxwZXJzIiwibm9ybWFsaXplU3RyaW5nIiwiZSIsInJlY29yZE1vdXNlRG93biIsImluRGlzcGxheUJveCIsIkNvbXBvbmVudCIsInByb3BUeXBlcyIsIlByb3BUeXBlcyIsInN0cmluZyIsImlzUmVxdWlyZWQiLCJhcnJheSIsImZ1bmMiLCJudW1iZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7QUFFQSxJQUFNQSxZQUFZLEdBQUcsSUFBckIsQyxDQUEyQjs7QUFDM0IsSUFBTUMsZ0JBQWdCLEdBQUcsRUFBekIsQyxDQUE2Qjs7SUFFdkJDLDRCOzs7Ozs7Ozs7Ozs7Z0RBQ3dCO0FBQzFCO0FBQ0EsV0FBS0MsZUFBTCxHQUF1QkMsSUFBSSxDQUFDQyxHQUFMLEVBQXZCO0FBQ0Q7OztxREFFZ0NDLFMsRUFBVztBQUMxQztBQUNBLFVBQUksQ0FBQywyQkFBUSxLQUFLQyxLQUFMLENBQVdDLFVBQW5CLEVBQStCRixTQUFTLENBQUNFLFVBQXpDLENBQUwsRUFBMkQ7QUFDekQsYUFBS0wsZUFBTCxHQUF1QkMsSUFBSSxDQUFDQyxHQUFMLEVBQXZCO0FBQ0Q7QUFDRjtBQUVEOzs7Ozs7O3FDQUlpQkksUyxFQUFXO0FBQzFCLFVBQU1DLFNBQVMsR0FBR0Msc0JBQXNCLENBQUNDLHNDQUF2QixDQUE4REgsU0FBOUQsRUFBeUUsS0FBS0ksV0FBOUUsQ0FBbEI7QUFDQSxXQUFLQyxZQUFMLENBQWtCSixTQUFsQjtBQUNEO0FBRUQ7Ozs7Ozs7b0NBSWdCSyxLLEVBQU87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aEIsU0FLR3ZCLGNBTEgsQ0FERjtBQVNEOzs7RUEvSXdDd0IsZ0I7O0FBa0ozQ3hFLDRCQUE0QixDQUFDeUUsU0FBN0IsR0FBeUM7QUFDdkNsQixFQUFBQSxJQUFJLEVBQUVtQixzQkFBVUMsTUFBVixDQUFpQkMsVUFEZ0I7QUFFdkNyRSxFQUFBQSxTQUFTLEVBQUVtRSxzQkFBVUMsTUFBVixDQUFpQkMsVUFGVztBQUd2Q3RFLEVBQUFBLFVBQVUsRUFBRW9FLHNCQUFVRyxLQUFWLENBQWdCRCxVQUhXO0FBSXZDL0MsRUFBQUEsU0FBUyxFQUFFNkMsc0JBQVVJLElBQVYsQ0FBZUYsVUFKYTtBQUt2Q3pDLEVBQUFBLGlCQUFpQixFQUFFdUMsc0JBQVVLLE1BQVYsQ0FBaUJILFVBTEc7QUFNdkM3QyxFQUFBQSw0QkFBNEIsRUFBRTJDLHNCQUFVSSxJQUFWLENBQWVGLFVBTk47QUFPdkM5QyxFQUFBQSxlQUFlLEVBQUU0QyxzQkFBVUksSUFBVixDQUFlRixVQVBPO0FBUXZDWCxFQUFBQSwyQkFBMkIsRUFBRVMsc0JBQVVDO0FBUkEsQ0FBekM7ZUFXZTNFLDRCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0LCB7IENvbXBvbmVudCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgaXNFcXVhbCBmcm9tICdkZWVwLWVxdWFsJztcbi8vIGhlbHBlcnNcbmltcG9ydCAqIGFzIHdpbmRvd1NlbGVjdGlvbkhlbHBlcnMgZnJvbSAnLi4vaGVscGVycy93aW5kb3dTZWxlY3Rpb25IZWxwZXJzJztcbmltcG9ydCAqIGFzIHNlbGVjdGlvbkhlbHBlcnMgZnJvbSAnLi4vaGVscGVycy9zZWxlY3Rpb25IZWxwZXJzJztcbmltcG9ydCAqIGFzIHN0cmluZ0hlbHBlcnMgZnJvbSAnLi4vaGVscGVycy9zdHJpbmdIZWxwZXJzJztcblxuY29uc3QgREJMX0NMS19USU1FID0gMTUwMDsgLy8gdGltZSBpbiBtc1xuY29uc3QgREJMX0NMS19ESVNUQU5DRSA9IDEwOyAvLyBpbiBwaXhlbHNcblxuY2xhc3MgUmVuZGVyU2VsZWN0aW9uVGV4dENvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudCB7XG4gIFVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQoKSB7XG4gICAgLy8gdHJhY2sgd2hlbiB0aGUgc2VsZWN0aW9ucyBjaGFuZ2UgdG8gcHJldmVudCBmYWxzZSBjbGlja3Mgb2YgcmVtb3ZhbHNcbiAgICB0aGlzLnJlbmRlclRpbWVzdGFtcCA9IERhdGUubm93KCk7XG4gIH1cblxuICBVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAvLyB0cmFjayB3aGVuIHRoZSBzZWxlY3Rpb25zIGNoYW5nZSB0byBwcmV2ZW50IGZhbHNlIGNsaWNrcyBvZiByZW1vdmFsc1xuICAgIGlmICghaXNFcXVhbCh0aGlzLnByb3BzLnNlbGVjdGlvbnMsIG5leHRQcm9wcy5zZWxlY3Rpb25zKSkge1xuICAgICAgdGhpcy5yZW5kZXJUaW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgbmV3IHNlbGVjdGVkIHRleHQgYW5kIHVwZGF0ZSBzZWxlY3Rpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB2ZXJzZVRleHQgLSBjdXJyZW50IHZlcnNlIHRleHRcbiAgICovXG4gIGdldFNlbGVjdGlvblRleHQodmVyc2VUZXh0KSB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93U2VsZWN0aW9uSGVscGVycy5nZXRTZWxlY3Rpb25Gcm9tQ3VycmVudFdpbmRvd1NlbGVjdGlvbih2ZXJzZVRleHQsIHRoaXMuZG91YmxlQ2xpY2spO1xuICAgIHRoaXMuYWRkU2VsZWN0aW9uKHNlbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICoga2VlcCB0cmFjayBvZiBtb3VzZSBkb3duIGV2ZW50cyBmb3IgZG91YmxlIGNsaWNrIGNhbGN1bGF0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCAtIG1vdXNlIGV2ZW50IGZyb20gY2FsbGJhY2tcbiAgICovXG4gIHJlY29yZE1vdXNlRG93bihldmVudCkge1xuICAgIHRoaXMubGFzdE1vdXNlRG5FdmVudCA9IHRoaXMubW91c2VEbkV2ZW50OyAvLyBuZWVkIHR3byBtb3VzZSBkb3duIGV2ZW50cyBmb3IgZG91YmxlIGNsaWNrIGNhbGNzXG4gICAgdGhpcy5tb3VzZURuRXZlbnQgPSB7IC4uLmV2ZW50IH07IC8vIHNoYWxsb3cgY29weVxuXG4gICAgaWYgKHRoaXMubGFzdE1vdXNlRG5FdmVudCkgeyAvLyBpZiB3ZSBoYWQgYSBwcmV2aW91cyBtb3VzZSBkb3duLCBjaGVjayBpZiB0aGlzIGlzIGEgZG91YmxlIGNsaWNrXG4gICAgICBjb25zdCBkZWx0YSA9IHRoaXMubW91c2VEbkV2ZW50LnRpbWVTdGFtcCAtIHRoaXMubGFzdE1vdXNlRG5FdmVudC50aW1lU3RhbXA7XG4gICAgICBjb25zdCBpc0RibENsa1RpbWUgPSBkZWx0YSA8IERCTF9DTEtfVElNRTsgLy8gYm90aCBjbGlja3MgbXVzdCBiZSB3aXRoaW4gdGltZSBsaW1pdFxuXG4gICAgICBjb25zdCBkZWx0YVggPSB0aGlzLm1vdXNlRG5FdmVudC5jbGllbnRYIC0gdGhpcy5sYXN0TW91c2VEbkV2ZW50LmNsaWVudFg7XG4gICAgICBjb25zdCBpc0RibENsa1ggPSBNYXRoLmFicyhkZWx0YVgpIDwgREJMX0NMS19ESVNUQU5DRTsgLy8gYm90aCBjbGlja3MgWCBjaGFuZ2UgbXVzdCBiZSB3aXRoaW4gbGltaXRcblxuICAgICAgY29uc3QgZGVsdGFZID0gdGhpcy5tb3VzZURuRXZlbnQuY2xpZW50WSAtIHRoaXMubGFzdE1vdXNlRG5FdmVudC5jbGllbnRZO1xuICAgICAgY29uc3QgaXNEYmxDbGtZID0gTWF0aC5hYnMoZGVsdGFZKSA8IERCTF9DTEtfRElTVEFOQ0U7IC8vIGJvdGggY2xpY2tzIFkgY2hhbmdlIG11c3QgYmUgd2l0aGluIGxpbWl0XG5cbiAgICAgIHRoaXMuZG91YmxlQ2xpY2sgPSBpc0RibENsa1RpbWUgJiYgaXNEYmxDbGtYICYmIGlzRGJsQ2xrWTtcblxuICAgICAgaWYgKHRoaXMuZG91YmxlQ2xpY2spIHtcbiAgICAgICAgY29uc29sZS5sb2coYHJlY29yZE1vdXNlRG93bigpIC0gRG91YmxlIENsaWNrIGRldGVjdGVkYCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYWRkU2VsZWN0aW9uKHNlbGVjdGlvbikge1xuICAgIGxldCB7XG4gICAgICBzZWxlY3Rpb25zLFxuICAgICAgdmVyc2VUZXh0LFxuICAgICAgdHJhbnNsYXRlLFxuICAgICAgb3BlbkFsZXJ0RGlhbG9nLFxuICAgICAgY2hhbmdlU2VsZWN0aW9uc0luTG9jYWxTdGF0ZSxcbiAgICB9ID0gdGhpcy5wcm9wcztcbiAgICBzZWxlY3Rpb25zID0gc2VsZWN0aW9uSGVscGVycy5hZGRTZWxlY3Rpb25Ub1NlbGVjdGlvbnMoc2VsZWN0aW9uLCBzZWxlY3Rpb25zLCB2ZXJzZVRleHQpO1xuXG4gICAgLy8gdGhpcyBpcyBhIGdvb2QgcGxhY2UgdG8gcHJldmlldyBzZWxlY3Rpb25zIGJlZm9yZSBzYXZlZCBpbiBzdGF0ZVxuICAgIGlmIChzZWxlY3Rpb25zLmxlbmd0aCA8PSB0aGlzLnByb3BzLm1heGltdW1TZWxlY3Rpb25zKSB7XG4gICAgICBjaGFuZ2VTZWxlY3Rpb25zSW5Mb2NhbFN0YXRlKHNlbGVjdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gdHJhbnNsYXRlKCdzZWxlY3RfdG9vX21hbnknLCB7IG1heGltdW06IHRoaXMucHJvcHMubWF4aW11bVNlbGVjdGlvbnMgfSk7XG4gICAgICBvcGVuQWxlcnREaWFsb2cobWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlU2VsZWN0aW9uKHNlbGVjdGlvbikge1xuICAgIGNvbnN0IHtcbiAgICAgIHNlbGVjdGlvbnMsXG4gICAgICB2ZXJzZVRleHQsXG4gICAgICBjaGFuZ2VTZWxlY3Rpb25zSW5Mb2NhbFN0YXRlLFxuICAgIH0gPSB0aGlzLnByb3BzO1xuICAgIGNvbnN0IG5ld1NlbGVjdGlvbnMgPSBzZWxlY3Rpb25IZWxwZXJzLnJlbW92ZVNlbGVjdGlvbkZyb21TZWxlY3Rpb25zKHNlbGVjdGlvbiwgc2VsZWN0aW9ucywgdmVyc2VUZXh0KTtcbiAgICBjaGFuZ2VTZWxlY3Rpb25zSW5Mb2NhbFN0YXRlKG5ld1NlbGVjdGlvbnMpO1xuICB9XG5cbiAgaW5EaXNwbGF5Qm94KGluc2lkZURpc3BsYXlCb3gpIHtcbiAgICBjb25zdCB7IHZlcnNlVGV4dCB9ID0gdGhpcy5wcm9wcztcbiAgICB0aGlzLnNldFN0YXRlKHsgaW5Cb3g6IGluc2lkZURpc3BsYXlCb3ggfSk7XG5cbiAgICBpZiAoIWluc2lkZURpc3BsYXlCb3ggJiYgTWF0aC5hYnMod2luZG93LmdldFNlbGVjdGlvbigpLmV4dGVudE9mZnNldCAtIHdpbmRvdy5nZXRTZWxlY3Rpb24oKS5iYXNlT2Zmc2V0KSA+IDApIHtcbiAgICAgIHRoaXMuZ2V0U2VsZWN0aW9uVGV4dCh2ZXJzZVRleHQpO1xuICAgIH1cbiAgfVxuXG4gIHZlcnNlVGV4dFNwYW5zKHNlbGVjdGlvbnMsIHZlcnNlVGV4dCkge1xuICAgIGxldCB2ZXJzZVRleHRTcGFuczsgLy8gcmV0dXJuXG4gICAgY29uc3Qgc3RyaW5nU3BsaWNlcyA9IHNlbGVjdGlvbkhlbHBlcnMuc2VsZWN0aW9uc1RvU3RyaW5nU3BsaWNlcyh2ZXJzZVRleHQsIHNlbGVjdGlvbnMpO1xuXG4gICAgdmVyc2VUZXh0U3BhbnMgPSBzdHJpbmdTcGxpY2VzLm1hcCgoc3RyaW5nU3BsaWNlLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3Qgc2VsZWN0TW9kZSA9ICh0aGlzLnByb3BzLm1vZGUgPT09ICdzZWxlY3QnKTsgLy8gdXNlIHNlbGVjdE1vZGUgdG8gY29uZGl0aW9uYWxseSB1c2UgaGlnaGxpZ2h0IGFuZCByZW1vdmVcbiAgICAgIGxldCBzdHlsZSA9IHsgY29sb3I6ICdibGFjaycgfTtcblxuICAgICAgbGV0IGNhbGxiYWNrID0gKCkgPT4ge307XG5cbiAgICAgIGlmIChzdHJpbmdTcGxpY2Uuc2VsZWN0ZWQpIHtcbiAgICAgICAgc3R5bGUuYmFja2dyb3VuZENvbG9yID0gJ3ZhcigtLWhpZ2hsaWdodC1jb2xvciknO1xuXG4gICAgICAgIGlmIChzZWxlY3RNb2RlKSB7XG4gICAgICAgICAgc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInOyAvLyBvbmx5IHNob3cgaGFuZCBpZiBpbiBzZWxlY3QgbW9kZVxuICAgICAgICAgIGNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGltZVBhc3NlZCA9IERhdGUubm93KCkgLSB0aGlzLnJlbmRlclRpbWVzdGFtcDsgLy8gc2VlIGhvdyBsb25nIGJldHdlZW4gbm93IGFuZCBsYXN0IHNlbGVjdGlvblxuICAgICAgICAgICAgY29uc3QgaXNSZWFsQ2xpY2sgPSB0aW1lUGFzc2VkID4gMTAwOyAvLyBpZiB0aGUgY2xpY2sgaGFwcGVuZWQgcXVpY2tlciB0aGFuIDEwMG1zLCBpdCB3YXMgbGlrZWx5IGZhbHNlIGNsaWNrXG5cbiAgICAgICAgICAgIGlmIChpc1JlYWxDbGljaykge1xuICAgICAgICAgICAgICB0aGlzLnJlbW92ZVNlbGVjdGlvbihzdHJpbmdTcGxpY2UpO1xuICAgICAgICAgICAgfSAvLyBhY3R1YWxseSByZW1vdmUgc2luY2UgaXQgd2FzIGxpa2VseSBhIHJlYWwgY2xpY2tcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgdGFyZ2V0TGFuZ3VhZ2VGb250Q2xhc3NOYW1lIH0gPSB0aGlzLnByb3BzO1xuXG4gICAgICByZXR1cm4gKFxuICAgICAgICA8c3BhbiBrZXk9e2luZGV4fSBjbGFzc05hbWU9e3RhcmdldExhbmd1YWdlRm9udENsYXNzTmFtZX0gc3R5bGU9e3N0eWxlfSBvbkNsaWNrPXtjYWxsYmFja30+XG4gICAgICAgICAge3N0cmluZ1NwbGljZS50ZXh0fVxuICAgICAgICA8L3NwYW4+XG4gICAgICApO1xuICAgIH0pO1xuICAgIHJldHVybiB2ZXJzZVRleHRTcGFucztcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBsZXQge1xuICAgICAgdmVyc2VUZXh0LCBzZWxlY3Rpb25zLCB0YXJnZXRMYW5ndWFnZUZvbnRDbGFzc05hbWUsXG4gICAgfSA9IHRoaXMucHJvcHM7XG4gICAgLy8gbm9ybWFsaXplIHdoaXRlc3BhY2UgZm9yIHRleHQgcmVuZGVyaW5nIGluIG9yZGVyIHRvIGRpc3BsYXkgaGlnaGxpZ2h0cyB3aXRoIG1vcmUgdGhhbiBvbmUgc3BhY2Ugc2luY2UgaHRtbCBzZWxlY3Rpb25zIHNob3cgb25lIHNwYWNlXG4gICAgdmVyc2VUZXh0ID0gc3RyaW5nSGVscGVycy5ub3JtYWxpemVTdHJpbmcodmVyc2VUZXh0KTtcbiAgICBsZXQgdmVyc2VUZXh0U3BhbnMgPSA8c3BhbiBjbGFzc05hbWU9e3RhcmdldExhbmd1YWdlRm9udENsYXNzTmFtZX0+e3ZlcnNlVGV4dH08L3NwYW4+O1xuXG4gICAgaWYgKHNlbGVjdGlvbnMgJiYgc2VsZWN0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICB2ZXJzZVRleHRTcGFucyA9IHRoaXMudmVyc2VUZXh0U3BhbnMoc2VsZWN0aW9ucywgdmVyc2VUZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXZcbiAgICAgICAgb25Nb3VzZVVwPXsoKSA9PiB0aGlzLmdldFNlbGVjdGlvblRleHQodmVyc2VUZXh0KX1cbiAgICAgICAgb25Nb3VzZURvd249eyhlKSA9PiB0aGlzLnJlY29yZE1vdXNlRG93bihlKX1cbiAgICAgICAgb25Nb3VzZUxlYXZlPXsoKSA9PiB0aGlzLmluRGlzcGxheUJveChmYWxzZSl9XG4gICAgICAgIG9uTW91c2VFbnRlcj17KCkgPT4gdGhpcy5pbkRpc3BsYXlCb3godHJ1ZSl9PlxuICAgICAgICB7dmVyc2VUZXh0U3BhbnN9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cblJlbmRlclNlbGVjdGlvblRleHRDb21wb25lbnQucHJvcFR5cGVzID0ge1xuICBtb2RlOiBQcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gIHZlcnNlVGV4dDogUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICBzZWxlY3Rpb25zOiBQcm9wVHlwZXMuYXJyYXkuaXNSZXF1aXJlZCxcbiAgdHJhbnNsYXRlOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICBtYXhpbXVtU2VsZWN0aW9uczogUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkLFxuICBjaGFuZ2VTZWxlY3Rpb25zSW5Mb2NhbFN0YXRlOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICBvcGVuQWxlcnREaWFsb2c6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gIHRhcmdldExhbmd1YWdlRm9udENsYXNzTmFtZTogUHJvcFR5cGVzLnN0cmluZyxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFJlbmRlclNlbGVjdGlvblRleHRDb21wb25lbnQ7XG4iXX0=