UNPKG

matrix-react-sdk

Version:
319 lines (264 loc) 35.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.default = exports.generateCompletionDomId = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _lodash = require("lodash"); var _Autocompleter = _interopRequireWildcard(require("../../../autocomplete/Autocompleter")); var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore")); var _replaceableComponent = require("../../../utils/replaceableComponent"); var _dec, _class, _temp; const COMPOSER_SELECTED = 0; const MAX_PROVIDER_MATCHES = 20; const generateCompletionDomId = number => `mx_Autocomplete_Completion_${number}`; exports.generateCompletionDomId = generateCompletionDomId; let Autocomplete = (_dec = (0, _replaceableComponent.replaceableComponent)("views.rooms.Autocomplete"), _dec(_class = (_temp = class Autocomplete extends _react.default.PureComponent /*:: <IProps, IState>*/ { constructor(props) { super(props); (0, _defineProperty2.default)(this, "autocompleter", void 0); (0, _defineProperty2.default)(this, "queryRequested", void 0); (0, _defineProperty2.default)(this, "debounceCompletionsRequest", void 0); (0, _defineProperty2.default)(this, "containerRef", /*#__PURE__*/(0, _react.createRef)()); (0, _defineProperty2.default)(this, "hide", () => { this.setState({ hide: true, selectionOffset: 0, completions: [], completionList: [] }); }); (0, _defineProperty2.default)(this, "onCompletionClicked", (selectionOffset /*: number*/ ) => /*: boolean*/ { if (this.countCompletions() === 0 || selectionOffset === COMPOSER_SELECTED) { return false; } this.props.onConfirm(this.state.completionList[selectionOffset - 1]); this.hide(); return true; }); this.autocompleter = new _Autocompleter.default(props.room); this.state = { // list of completionResults, each containing completions completions: [], // array of completions, so we can look up current selection by offset quickly completionList: [], // how far down the completion list we are (THIS IS 1-INDEXED!) selectionOffset: COMPOSER_SELECTED, // whether we should show completions if they're available shouldShowCompletions: true, hide: false, forceComplete: false }; } componentDidMount() { this.applyNewProps(); } applyNewProps(oldQuery /*: string*/ , oldRoom /*: Room*/ ) { if (oldRoom && this.props.room.roomId !== oldRoom.roomId) { this.autocompleter.destroy(); this.autocompleter = new _Autocompleter.default(this.props.room); } // Query hasn't changed so don't try to complete it if (oldQuery === this.props.query) { return; } this.complete(this.props.query, this.props.selection); } componentWillUnmount() { this.autocompleter.destroy(); } complete(query /*: string*/ , selection /*: ISelectionRange*/ ) { this.queryRequested = query; if (this.debounceCompletionsRequest) { clearTimeout(this.debounceCompletionsRequest); } if (query === "") { this.setState({ // Clear displayed completions completions: [], completionList: [], // Reset selected completion selectionOffset: COMPOSER_SELECTED, // Hide the autocomplete box hide: true }); return Promise.resolve(null); } let autocompleteDelay = _SettingsStore.default.getValue("autocompleteDelay"); // Don't debounce if we are already showing completions if (this.state.completions.length > 0 || this.state.forceComplete) { autocompleteDelay = 0; } return new Promise(resolve => { this.debounceCompletionsRequest = setTimeout(() => { resolve(this.processQuery(query, selection)); }, autocompleteDelay); }); } processQuery(query /*: string*/ , selection /*: ISelectionRange*/ ) { return this.autocompleter.getCompletions(query, selection, this.state.forceComplete, MAX_PROVIDER_MATCHES).then(completions => { // Only ever process the completions for the most recent query being processed if (query !== this.queryRequested) { return; } this.processCompletions(completions); }); } processCompletions(completions /*: IProviderCompletions[]*/ ) { const completionList = (0, _lodash.flatMap)(completions, provider => provider.completions); // Reset selection when completion list becomes empty. let selectionOffset = COMPOSER_SELECTED; if (completionList.length > 0) { /* If the currently selected completion is still in the completion list, try to find it and jump to it. If not, select composer. */ const currentSelection = this.state.selectionOffset === 0 ? null : this.state.completionList[this.state.selectionOffset - 1].completion; selectionOffset = completionList.findIndex(completion => completion.completion === currentSelection); if (selectionOffset === -1) { selectionOffset = COMPOSER_SELECTED; } else { selectionOffset++; // selectionOffset is 1-indexed! } } let hide = this.state.hide; // If `completion.command.command` is truthy, then a provider has matched with the query const anyMatches = completions.some(completion => !!completion.command.command); hide = !anyMatches; this.setState({ completions, completionList, selectionOffset, hide, // Force complete is turned off each time since we can't edit the query in that case forceComplete: false }); } hasSelection() /*: boolean*/ { return this.countCompletions() > 0 && this.state.selectionOffset !== 0; } countCompletions() /*: number*/ { return this.state.completionList.length; } // called from MessageComposerInput moveSelection(delta /*: number*/ ) { const completionCount = this.countCompletions(); if (completionCount === 0) return; // there are no items to move the selection through // Note: selectionOffset 0 represents the unsubstituted text, while 1 means first pill selected const index = (this.state.selectionOffset + delta + completionCount + 1) % (completionCount + 1); this.setSelection(index); } onEscape(e /*: KeyboardEvent*/ ) /*: boolean*/ { const completionCount = this.countCompletions(); if (completionCount === 0) { // autocomplete is already empty, so don't preventDefault return; } e.preventDefault(); // selectionOffset = 0, so we don't end up completing when autocomplete is hidden this.hide(); } forceComplete() { return new Promise(resolve => { this.setState({ forceComplete: true, hide: false }, () => { this.complete(this.props.query, this.props.selection).then(() => { resolve(this.countCompletions()); }); }); }); } setSelection(selectionOffset /*: number*/ ) { this.setState({ selectionOffset, hide: false }); if (this.props.onSelectionChange) { this.props.onSelectionChange(this.state.completionList[selectionOffset - 1], selectionOffset - 1); } } componentDidUpdate(prevProps /*: IProps*/ ) { this.applyNewProps(prevProps.query, prevProps.room); // this is the selected completion, so scroll it into view if needed const selectedCompletion = this.refs[`completion${this.state.selectionOffset}`]; if (selectedCompletion) { selectedCompletion.scrollIntoView({ behavior: "auto", block: "nearest" }); } else if (this.containerRef.current) { this.containerRef.current.scrollTo({ top: 0 }); } } render() { let position = 1; const renderedCompletions = this.state.completions.map((completionResult, i) => { const completions = completionResult.completions.map((completion, j) => { const selected = position === this.state.selectionOffset; const className = (0, _classnames.default)('mx_Autocomplete_Completion', { selected }); const componentPosition = position; position++; const onClick = () => { this.onCompletionClicked(componentPosition); }; return /*#__PURE__*/_react.default.cloneElement(completion.component, { "key": j, "ref": `completion${componentPosition}`, "id": generateCompletionDomId(componentPosition - 1), // 0 index the completion IDs className, onClick, "aria-selected": selected }); }); return completions.length > 0 ? /*#__PURE__*/_react.default.createElement("div", { key: i, className: "mx_Autocomplete_ProviderSection" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_Autocomplete_provider_name" }, completionResult.provider.getName()), completionResult.provider.renderCompletions(completions)) : null; }).filter(completion => !!completion); return !this.state.hide && renderedCompletions.length > 0 ? /*#__PURE__*/_react.default.createElement("div", { className: "mx_Autocomplete", ref: this.containerRef }, renderedCompletions) : null; } }, _temp)) || _class); exports.default = Autocomplete; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3Jvb21zL0F1dG9jb21wbGV0ZS50c3giXSwibmFtZXMiOlsiQ09NUE9TRVJfU0VMRUNURUQiLCJNQVhfUFJPVklERVJfTUFUQ0hFUyIsImdlbmVyYXRlQ29tcGxldGlvbkRvbUlkIiwibnVtYmVyIiwiQXV0b2NvbXBsZXRlIiwiUmVhY3QiLCJQdXJlQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsInNldFN0YXRlIiwiaGlkZSIsInNlbGVjdGlvbk9mZnNldCIsImNvbXBsZXRpb25zIiwiY29tcGxldGlvbkxpc3QiLCJjb3VudENvbXBsZXRpb25zIiwib25Db25maXJtIiwic3RhdGUiLCJhdXRvY29tcGxldGVyIiwiQXV0b2NvbXBsZXRlciIsInJvb20iLCJzaG91bGRTaG93Q29tcGxldGlvbnMiLCJmb3JjZUNvbXBsZXRlIiwiY29tcG9uZW50RGlkTW91bnQiLCJhcHBseU5ld1Byb3BzIiwib2xkUXVlcnkiLCJvbGRSb29tIiwicm9vbUlkIiwiZGVzdHJveSIsInF1ZXJ5IiwiY29tcGxldGUiLCJzZWxlY3Rpb24iLCJjb21wb25lbnRXaWxsVW5tb3VudCIsInF1ZXJ5UmVxdWVzdGVkIiwiZGVib3VuY2VDb21wbGV0aW9uc1JlcXVlc3QiLCJjbGVhclRpbWVvdXQiLCJQcm9taXNlIiwicmVzb2x2ZSIsImF1dG9jb21wbGV0ZURlbGF5IiwiU2V0dGluZ3NTdG9yZSIsImdldFZhbHVlIiwibGVuZ3RoIiwic2V0VGltZW91dCIsInByb2Nlc3NRdWVyeSIsImdldENvbXBsZXRpb25zIiwidGhlbiIsInByb2Nlc3NDb21wbGV0aW9ucyIsInByb3ZpZGVyIiwiY3VycmVudFNlbGVjdGlvbiIsImNvbXBsZXRpb24iLCJmaW5kSW5kZXgiLCJhbnlNYXRjaGVzIiwic29tZSIsImNvbW1hbmQiLCJoYXNTZWxlY3Rpb24iLCJtb3ZlU2VsZWN0aW9uIiwiZGVsdGEiLCJjb21wbGV0aW9uQ291bnQiLCJpbmRleCIsInNldFNlbGVjdGlvbiIsIm9uRXNjYXBlIiwiZSIsInByZXZlbnREZWZhdWx0Iiwib25TZWxlY3Rpb25DaGFuZ2UiLCJjb21wb25lbnREaWRVcGRhdGUiLCJwcmV2UHJvcHMiLCJzZWxlY3RlZENvbXBsZXRpb24iLCJyZWZzIiwic2Nyb2xsSW50b1ZpZXciLCJiZWhhdmlvciIsImJsb2NrIiwiY29udGFpbmVyUmVmIiwiY3VycmVudCIsInNjcm9sbFRvIiwidG9wIiwicmVuZGVyIiwicG9zaXRpb24iLCJyZW5kZXJlZENvbXBsZXRpb25zIiwibWFwIiwiY29tcGxldGlvblJlc3VsdCIsImkiLCJqIiwic2VsZWN0ZWQiLCJjbGFzc05hbWUiLCJjb21wb25lbnRQb3NpdGlvbiIsIm9uQ2xpY2siLCJvbkNvbXBsZXRpb25DbGlja2VkIiwiY2xvbmVFbGVtZW50IiwiY29tcG9uZW50IiwiZ2V0TmFtZSIsInJlbmRlckNvbXBsZXRpb25zIiwiZmlsdGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBaUJBOztBQUNBOztBQUNBOztBQUNBOztBQUdBOztBQUVBOzs7O0FBRUEsTUFBTUEsaUJBQWlCLEdBQUcsQ0FBMUI7QUFDQSxNQUFNQyxvQkFBb0IsR0FBRyxFQUE3Qjs7QUFFTyxNQUFNQyx1QkFBdUIsR0FBSUMsTUFBRCxJQUFhLDhCQUE2QkEsTUFBTyxFQUFqRjs7O0lBd0JjQyxZLFdBRHBCLGdEQUFxQiwwQkFBckIsQyx5QkFBRCxNQUNxQkEsWUFEckIsU0FDMENDLGVBQU1DO0FBRGhEO0FBQzhFO0FBTTFFQyxFQUFBQSxXQUFXLENBQUNDLEtBQUQsRUFBUTtBQUNmLFVBQU1BLEtBQU47QUFEZTtBQUFBO0FBQUE7QUFBQSxxRUFGSSx1QkFFSjtBQUFBLGdEQTJKWixNQUFNO0FBQ1QsV0FBS0MsUUFBTCxDQUFjO0FBQ1ZDLFFBQUFBLElBQUksRUFBRSxJQURJO0FBRVZDLFFBQUFBLGVBQWUsRUFBRSxDQUZQO0FBR1ZDLFFBQUFBLFdBQVcsRUFBRSxFQUhIO0FBSVZDLFFBQUFBLGNBQWMs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QUFOLENBQW1CdEMsVUFBVSxDQUFDdUMsU0FBOUIsRUFBeUM7QUFDNUMsaUJBQU9QLENBRHFDO0FBRTVDLGlCQUFRLGFBQVlHLGlCQUFrQixFQUZNO0FBRzVDLGdCQUFNakYsdUJBQXVCLENBQUNpRixpQkFBaUIsR0FBRyxDQUFyQixDQUhlO0FBR1U7QUFDdERELFVBQUFBLFNBSjRDO0FBSzVDRSxVQUFBQSxPQUw0QztBQU01QywyQkFBaUJIO0FBTjJCLFNBQXpDLENBQVA7QUFRSCxPQWxCbUIsQ0FBcEI7QUFxQkEsYUFBT3JFLFdBQVcsQ0FBQzRCLE1BQVosR0FBcUIsQ0FBckIsZ0JBQ0g7QUFBSyxRQUFBLEdBQUcsRUFBRXVDLENBQVY7QUFBYSxRQUFBLFNBQVMsRUFBQztBQUF2QixzQkFDSTtBQUFLLFFBQUEsU0FBUyxFQUFDO0FBQWYsU0FBaURELGdCQUFnQixDQUFDaEMsUUFBakIsQ0FBMEIwQyxPQUExQixFQUFqRCxDQURKLEVBRU1WLGdCQUFnQixDQUFDaEMsUUFBakIsQ0FBMEIyQyxpQkFBMUIsQ0FBNEM3RSxXQUE1QyxDQUZOLENBREcsR0FLSCxJQUxKO0FBTUgsS0E1QjJCLEVBNEJ6QjhFLE1BNUJ5QixDQTRCakIxQyxVQUFELElBQWdCLENBQUMsQ0FBQ0EsVUE1QkEsQ0FBNUI7QUE4QkEsV0FBTyxDQUFDLEtBQUtoQyxLQUFMLENBQVdOLElBQVosSUFBb0JrRSxtQkFBbUIsQ0FBQ3BDLE1BQXBCLEdBQTZCLENBQWpELGdCQUNIO0FBQUssTUFBQSxTQUFTLEVBQUMsaUJBQWY7QUFBaUMsTUFBQSxHQUFHLEVBQUUsS0FBSzhCO0FBQTNDLE9BQ01NLG1CQUROLENBREcsR0FJSCxJQUpKO0FBS0g7O0FBN1B5RSxDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDE2IEF2aXJhbCBEYXNndXB0YVxuQ29weXJpZ2h0IDIwMTcgTmV3IFZlY3RvciBMdGRcblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4qL1xuXG5pbXBvcnQgUmVhY3QsIHtjcmVhdGVSZWYsIEtleWJvYXJkRXZlbnR9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IHtmbGF0TWFwfSBmcm9tIFwibG9kYXNoXCI7XG5pbXBvcnQge0lDb21wbGV0aW9uLCBJU2VsZWN0aW9uUmFuZ2UsIElQcm92aWRlckNvbXBsZXRpb25zfSBmcm9tICcuLi8uLi8uLi9hdXRvY29tcGxldGUvQXV0b2NvbXBsZXRlcic7XG5pbXBvcnQge1Jvb219IGZyb20gJ21hdHJpeC1qcy1zZGsvc3JjL21vZGVscy9yb29tJztcblxuaW1wb3J0IFNldHRpbmdzU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL1NldHRpbmdzU3RvcmVcIjtcbmltcG9ydCBBdXRvY29tcGxldGVyIGZyb20gJy4uLy4uLy4uL2F1dG9jb21wbGV0ZS9BdXRvY29tcGxldGVyJztcbmltcG9ydCB7cmVwbGFjZWFibGVDb21wb25lbnR9IGZyb20gXCIuLi8uLi8uLi91dGlscy9yZXBsYWNlYWJsZUNvbXBvbmVudFwiO1xuXG5jb25zdCBDT01QT1NFUl9TRUxFQ1RFRCA9IDA7XG5jb25zdCBNQVhfUFJPVklERVJfTUFUQ0hFUyA9IDIwO1xuXG5leHBvcnQgY29uc3QgZ2VuZXJhdGVDb21wbGV0aW9uRG9tSWQgPSAobnVtYmVyKSA9PiBgbXhfQXV0b2NvbXBsZXRlX0NvbXBsZXRpb25fJHtudW1iZXJ9YDtcblxuaW50ZXJmYWNlIElQcm9wcyB7XG4gICAgLy8gdGhlIHF1ZXJ5IHN0cmluZyBmb3Igd2hpY2ggdG8gc2hvdyBhdXRvY29tcGxldGUgc3VnZ2VzdGlvbnNcbiAgICBxdWVyeTogc3RyaW5nO1xuICAgIC8vIG1ldGhvZCBpbnZva2VkIHdpdGggcmFuZ2UgYW5kIHRleHQgY29udGVudCB3aGVuIGNvbXBsZXRpb24gaXMgY29uZmlybWVkXG4gICAgb25Db25maXJtOiAoSUNvbXBsZXRpb24pID0+IHZvaWQ7XG4gICAgLy8gbWV0aG9kIGludm9rZWQgd2hlbiBzZWxlY3RlZCAoaWYgYW55KSBjb21wbGV0aW9uIGNoYW5nZXNcbiAgICBvblNlbGVjdGlvbkNoYW5nZT86IChJQ29tcGxldGlvbiwgbnVtYmVyKSA9PiB2b2lkO1xuICAgIHNlbGVjdGlvbjogSVNlbGVjdGlvblJhbmdlO1xuICAgIC8vIFRoZSByb29tIGluIHdoaWNoIHdlJ3JlIGF1dG9jb21wbGV0aW5nXG4gICAgcm9vbTogUm9vbTtcbn1cblxuaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgY29tcGxldGlvbnM6IElQcm92aWRlckNvbXBsZXRpb25zW107XG4gICAgY29tcGxldGlvbkxpc3Q6IElDb21wbGV0aW9uW107XG4gICAgc2VsZWN0aW9uT2Zmc2V0OiBudW1iZXI7XG4gICAgc2hvdWxkU2hvd0NvbXBsZXRpb25zOiBib29sZWFuO1xuICAgIGhpZGU6IGJvb2xlYW47XG4gICAgZm9yY2VDb21wbGV0ZTogYm9vbGVhbjtcbn1cblxuQHJlcGxhY2VhYmxlQ29tcG9uZW50KFwidmlld3Mucm9vbXMuQXV0b2NvbXBsZXRlXCIpXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBdXRvY29tcGxldGUgZXh0ZW5kcyBSZWFjdC5QdXJlQ29tcG9uZW50PElQcm9wcywgSVN0YXRlPiB7XG4gICAgYXV0b2NvbXBsZXRlcjogQXV0b2NvbXBsZXRlcjtcbiAgICBxdWVyeVJlcXVlc3RlZDogc3RyaW5nO1xuICAgIGRlYm91bmNlQ29tcGxldGlvbnNSZXF1ZXN0OiBOb2RlSlMuVGltZW91dDtcbiAgICBwcml2YXRlIGNvbnRhaW5lclJlZiA9IGNyZWF0ZVJlZjxIVE1MRGl2RWxlbWVudD4oKTtcblxuICAgIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcblxuICAgICAgICB0aGlzLmF1dG9jb21wbGV0ZXIgPSBuZXcgQXV0b2NvbXBsZXRlcihwcm9wcy5yb29tKTtcblxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgLy8gbGlzdCBvZiBjb21wbGV0aW9uUmVzdWx0cywgZWFjaCBjb250YWluaW5nIGNvbXBsZXRpb25zXG4gICAgICAgICAgICBjb21wbGV0aW9uczogW10sXG5cbiAgICAgICAgICAgIC8vIGFycmF5IG9mIGNvbXBsZXRpb25zLCBzbyB3ZSBjYW4gbG9vayB1cCBjdXJyZW50IHNlbGVjdGlvbiBieSBvZmZzZXQgcXVpY2tseVxuICAgICAgICAgICAgY29tcGxldGlvbkxpc3Q6IFtdLFxuXG4gICAgICAgICAgICAvLyBob3cgZmFyIGRvd24gdGhlIGNvbXBsZXRpb24gbGlzdCB3ZSBhcmUgKFRISVMgSVMgMS1JTkRFWEVEISlcbiAgICAgICAgICAgIHNlbGVjdGlvbk9mZnNldDogQ09NUE9TRVJfU0VMRUNURUQsXG5cbiAgICAgICAgICAgIC8vIHdoZXRoZXIgd2Ugc2hvdWxkIHNob3cgY29tcGxldGlvbnMgaWYgdGhleSdyZSBhdmFpbGFibGVcbiAgICAgICAgICAgIHNob3VsZFNob3dDb21wbGV0aW9uczogdHJ1ZSxcblxuICAgICAgICAgICAgaGlkZTogZmFsc2UsXG5cbiAgICAgICAgICAgIGZvcmNlQ29tcGxldGU6IGZhbHNlLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLmFwcGx5TmV3UHJvcHMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFwcGx5TmV3UHJvcHMob2xkUXVlcnk/OiBzdHJpbmcsIG9sZFJvb20/OiBSb29tKSB7XG4gICAgICAgIGlmIChvbGRSb29tICYmIHRoaXMucHJvcHMucm9vbS5yb29tSWQgIT09IG9sZFJvb20ucm9vbUlkKSB7XG4gICAgICAgICAgICB0aGlzLmF1dG9jb21wbGV0ZXIuZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5hdXRvY29tcGxldGVyID0gbmV3IEF1dG9jb21wbGV0ZXIodGhpcy5wcm9wcy5yb29tKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFF1ZXJ5IGhhc24ndCBjaGFuZ2VkIHNvIGRvbid0IHRyeSB0byBjb21wbGV0ZSBpdFxuICAgICAgICBpZiAob2xkUXVlcnkgPT09IHRoaXMucHJvcHMucXVlcnkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29tcGxldGUodGhpcy5wcm9wcy5xdWVyeSwgdGhpcy5wcm9wcy5zZWxlY3Rpb24pO1xuICAgIH1cblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICB0aGlzLmF1dG9jb21wbGV0ZXIuZGVzdHJveSgpO1xuICAgIH1cblxuICAgIGNvbXBsZXRlKHF1ZXJ5OiBzdHJpbmcsIHNlbGVjdGlvbjogSVNlbGVjdGlvblJhbmdlKSB7XG4gICAgICAgIHRoaXMucXVlcnlSZXF1ZXN0ZWQgPSBxdWVyeTtcbiAgICAgICAgaWYgKHRoaXMuZGVib3VuY2VDb21wbGV0aW9uc1JlcXVlc3QpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmRlYm91bmNlQ29tcGxldGlvbnNSZXF1ZXN0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocXVlcnkgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIC8vIENsZWFyIGRpc3BsYXllZCBjb21wbGV0aW9uc1xuICAgICAgICAgICAgICAgIGNvbXBsZXRpb25zOiBbXSxcbiAgICAgICAgICAgICAgICBjb21wbGV0aW9uTGlzdDogW10sXG4gICAgICAgICAgICAgICAgLy8gUmVzZXQgc2VsZWN0ZWQgY29tcGxldGlvblxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbk9mZnNldDogQ09NUE9TRVJfU0VMRUNURUQsXG4gICAgICAgICAgICAgICAgLy8gSGlkZSB0aGUgYXV0b2NvbXBsZXRlIGJveFxuICAgICAgICAgICAgICAgIGhpZGU6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGF1dG9jb21wbGV0ZURlbGF5ID0gU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcImF1dG9jb21wbGV0ZURlbGF5XCIpO1xuXG4gICAgICAgIC8vIERvbid0IGRlYm91bmNlIGlmIHdlIGFyZSBhbHJlYWR5IHNob3dpbmcgY29tcGxldGlvbnNcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuY29tcGxldGlvbnMubGVuZ3RoID4gMCB8fCB0aGlzLnN0YXRlLmZvcmNlQ29tcGxldGUpIHtcbiAgICAgICAgICAgIGF1dG9jb21wbGV0ZURlbGF5ID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kZWJvdW5jZUNvbXBsZXRpb25zUmVxdWVzdCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcy5wcm9jZXNzUXVlcnkocXVlcnksIHNlbGVjdGlvbikpO1xuICAgICAgICAgICAgfSwgYXV0b2NvbXBsZXRlRGVsYXkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcm9jZXNzUXVlcnkocXVlcnk6IHN0cmluZywgc2VsZWN0aW9uOiBJU2VsZWN0aW9uUmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0b2NvbXBsZXRlci5nZXRDb21wbGV0aW9ucyhcbiAgICAgICAgICAgIHF1ZXJ5LCBzZWxlY3Rpb24sIHRoaXMuc3RhdGUuZm9yY2VDb21wbGV0ZSwgTUFYX1BST1ZJREVSX01BVENIRVMsXG4gICAgICAgICkudGhlbigoY29tcGxldGlvbnMpID0+IHtcbiAgICAgICAgICAgIC8vIE9ubHkgZXZlciBwcm9jZXNzIHRoZSBjb21wbGV0aW9ucyBmb3IgdGhlIG1vc3QgcmVjZW50IHF1ZXJ5IGJlaW5nIHByb2Nlc3NlZFxuICAgICAgICAgICAgaWYgKHF1ZXJ5ICE9PSB0aGlzLnF1ZXJ5UmVxdWVzdGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ29tcGxldGlvbnMoY29tcGxldGlvbnMpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcm9jZXNzQ29tcGxldGlvbnMoY29tcGxldGlvbnM6IElQcm92aWRlckNvbXBsZXRpb25zW10pIHtcbiAgICAgICAgY29uc3QgY29tcGxldGlvbkxpc3QgPSBmbGF0TWFwKGNvbXBsZXRpb25zLCAocHJvdmlkZXIpID0+IHByb3ZpZGVyLmNvbXBsZXRpb25zKTtcblxuICAgICAgICAvLyBSZXNldCBzZWxlY3Rpb24gd2hlbiBjb21wbGV0aW9uIGxpc3QgYmVjb21lcyBlbXB0eS5cbiAgICAgICAgbGV0IHNlbGVjdGlvbk9mZnNldCA9IENPTVBPU0VSX1NFTEVDVEVEO1xuICAgICAgICBpZiAoY29tcGxldGlvbkxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLyogSWYgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBjb21wbGV0aW9uIGlzIHN0aWxsIGluIHRoZSBjb21wbGV0aW9uIGxpc3QsXG4gICAgICAgICAgICAgdHJ5IHRvIGZpbmQgaXQgYW5kIGp1bXAgdG8gaXQuIElmIG5vdCwgc2VsZWN0IGNvbXBvc2VyLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBjdXJyZW50U2VsZWN0aW9uID0gdGhpcy5zdGF0ZS5zZWxlY3Rpb25PZmZzZXQgPT09IDAgPyBudWxsIDpcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmNvbXBsZXRpb25MaXN0W3RoaXMuc3RhdGUuc2VsZWN0aW9uT2Zmc2V0IC0gMV0uY29tcGxldGlvbjtcbiAgICAgICAgICAgIHNlbGVjdGlvbk9mZnNldCA9IGNvbXBsZXRpb25MaXN0LmZpbmRJbmRleChcbiAgICAgICAgICAgICAgICAoY29tcGxldGlvbikgPT4gY29tcGxldGlvbi5jb21wbGV0aW9uID09PSBjdXJyZW50U2VsZWN0aW9uKTtcbiAgICAgICAgICAgIGlmIChzZWxlY3Rpb25PZmZzZXQgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uT2Zmc2V0ID0gQ09NUE9TRVJfU0VMRUNURUQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNlbGVjdGlvbk9mZnNldCsrOyAvLyBzZWxlY3Rpb25PZmZzZXQgaXMgMS1pbmRleGVkIVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGhpZGUgPSB0aGlzLnN0YXRlLmhpZGU7XG4gICAgICAgIC8vIElmIGBjb21wbGV0aW9uLmNvbW1hbmQuY29tbWFuZGAgaXMgdHJ1dGh5LCB0aGVuIGEgcHJvdmlkZXIgaGFzIG1hdGNoZWQgd2l0aCB0aGUgcXVlcnlcbiAgICAgICAgY29uc3QgYW55TWF0Y2hlcyA9IGNvbXBsZXRpb25zLnNvbWUoKGNvbXBsZXRpb24pID0+ICEhY29tcGxldGlvbi5jb21tYW5kLmNvbW1hbmQpO1xuICAgICAgICBoaWRlID0gIWFueU1hdGNoZXM7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBjb21wbGV0aW9ucyxcbiAgICAgICAgICAgIGNvbXBsZXRpb25MaXN0LFxuICAgICAgICAgICAgc2VsZWN0aW9uT2Zmc2V0LFxuICAgICAgICAgICAgaGlkZSxcbiAgICAgICAgICAgIC8vIEZvcmNlIGNvbXBsZXRlIGlzIHR1cm5lZCBvZmYgZWFjaCB0aW1lIHNpbmNlIHdlIGNhbid0IGVkaXQgdGhlIHF1ZXJ5IGluIHRoYXQgY2FzZVxuICAgICAgICAgICAgZm9yY2VDb21wbGV0ZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGhhc1NlbGVjdGlvbigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY291bnRDb21wbGV0aW9ucygpID4gMCAmJiB0aGlzLnN0YXRlLnNlbGVjdGlvbk9mZnNldCAhPT0gMDtcbiAgICB9XG5cbiAgICBjb3VudENvbXBsZXRpb25zKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRlLmNvbXBsZXRpb25MaXN0Lmxlbmd0aDtcbiAgICB9XG5cbiAgICAvLyBjYWxsZWQgZnJvbSBNZXNzYWdlQ29tcG9zZXJJbnB1dFxuICAgIG1vdmVTZWxlY3Rpb24oZGVsdGE6IG51bWJlcikge1xuICAgICAgICBjb25zdCBjb21wbGV0aW9uQ291bnQgPSB0aGlzLmNvdW50Q29tcGxldGlvbnMoKTtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25Db3VudCA9PT0gMCkgcmV0dXJuOyAvLyB0aGVyZSBhcmUgbm8gaXRlbXMgdG8gbW92ZSB0aGUgc2VsZWN0aW9uIHRocm91Z2hcblxuICAgICAgICAvLyBOb3RlOiBzZWxlY3Rpb25PZmZzZXQgMCByZXByZXNlbnRzIHRoZSB1bnN1YnN0aXR1dGVkIHRleHQsIHdoaWxlIDEgbWVhbnMgZmlyc3QgcGlsbCBzZWxlY3RlZFxuICAgICAgICBjb25zdCBpbmRleCA9ICh0aGlzLnN0YXRlLnNlbGVjdGlvbk9mZnNldCArIGRlbHRhICsgY29tcGxldGlvbkNvdW50ICsgMSkgJSAoY29tcGxldGlvbkNvdW50ICsgMSk7XG4gICAgICAgIHRoaXMuc2V0U2VsZWN0aW9uKGluZGV4KTtcbiAgICB9XG5cbiAgICBvbkVzY2FwZShlOiBLZXlib2FyZEV2ZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGNvbXBsZXRpb25Db3VudCA9IHRoaXMuY291bnRDb21wbGV0aW9ucygpO1xuICAgICAgICBpZiAoY29tcGxldGlvbkNvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAvLyBhdXRvY29tcGxldGUgaXMgYWxyZWFkeSBlbXB0eSwgc28gZG9uJ3QgcHJldmVudERlZmF1bHRcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAvLyBzZWxlY3Rpb25PZmZzZXQgPSAwLCBzbyB3ZSBkb24ndCBlbmQgdXAgY29tcGxldGluZyB3aGVuIGF1dG9jb21wbGV0ZSBpcyBoaWRkZW5cbiAgICAgICAgdGhpcy5oaWRlKCk7XG4gICAgfVxuXG4gICAgaGlkZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBoaWRlOiB0cnVlLFxuICAgICAgICAgICAgc2VsZWN0aW9uT2Zmc2V0OiAwLFxuICAgICAgICAgICAgY29tcGxldGlvbnM6IFtdLFxuICAgICAgICAgICAgY29tcGxldGlvbkxpc3Q6IFtdLFxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgZm9yY2VDb21wbGV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBmb3JjZUNvbXBsZXRlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGhpZGU6IGZhbHNlLFxuICAgICAgICAgICAgfSwgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY29tcGxldGUodGhpcy5wcm9wcy5xdWVyeSwgdGhpcy5wcm9wcy5zZWxlY3Rpb24pLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRoaXMuY291bnRDb21wbGV0aW9ucygpKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbkNvbXBsZXRpb25DbGlja2VkID0gKHNlbGVjdGlvbk9mZnNldDogbnVtYmVyKTogYm9vbGVhbiA9PiB7XG4gICAgICAgIGlmICh0aGlzLmNvdW50Q29tcGxldGlvbnMoKSA9PT0gMCB8fCBzZWxlY3Rpb25PZmZzZXQgPT09IENPTVBPU0VSX1NFTEVDVEVEKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnByb3BzLm9uQ29uZmlybSh0aGlzLnN0YXRlLmNvbXBsZXRpb25MaXN0W3NlbGVjdGlvbk9mZnNldCAtIDFdKTtcbiAgICAgICAgdGhpcy5oaWRlKCk7XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIHNldFNlbGVjdGlvbihzZWxlY3Rpb25PZmZzZXQ6IG51bWJlcikge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtzZWxlY3Rpb25PZmZzZXQsIGhpZGU6IGZhbHNlfSk7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uU2VsZWN0aW9uQ2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uU2VsZWN0aW9uQ2hhbmdlKHRoaXMuc3RhdGUuY29tcGxldGlvbkxpc3Rbc2VsZWN0aW9uT2Zmc2V0IC0gMV0sIHNlbGVjdGlvbk9mZnNldCAtIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wczogSVByb3BzKSB7XG4gICAgICAgIHRoaXMuYXBwbHlOZXdQcm9wcyhwcmV2UHJvcHMucXVlcnksIHByZXZQcm9wcy5yb29tKTtcbiAgICAgICAgLy8gdGhpcyBpcyB0aGUgc2VsZWN0ZWQgY29tcGxldGlvbiwgc28gc2Nyb2xsIGl0IGludG8gdmlldyBpZiBuZWVkZWRcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRDb21wbGV0aW9uID0gdGhpcy5yZWZzW2Bjb21wbGV0aW9uJHt0aGlzLnN0YXRlLnNlbGVjdGlvbk9mZnNldH1gXSBhcyBIVE1MRWxlbWVudDtcblxuICAgICAgICBpZiAoc2VsZWN0ZWRDb21wbGV0aW9uKSB7XG4gICAgICAgICAgICBzZWxlY3RlZENvbXBsZXRpb24uc2Nyb2xsSW50b1ZpZXcoe1xuICAgICAgICAgICAgICAgIGJlaGF2aW9yOiBcImF1dG9cIixcbiAgICAgICAgICAgICAgICBibG9jazogXCJuZWFyZXN0XCIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbnRhaW5lclJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lclJlZi5jdXJyZW50LnNjcm9sbFRvKHsgdG9wOiAwIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgcG9zaXRpb24gPSAxO1xuICAgICAgICBjb25zdCByZW5kZXJlZENvbXBsZXRpb25zID0gdGhpcy5zdGF0ZS5jb21wbGV0aW9ucy5tYXAoKGNvbXBsZXRpb25SZXN1bHQsIGkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXBsZXRpb25zID0gY29tcGxldGlvblJlc3VsdC5jb21wbGV0aW9ucy5tYXAoKGNvbXBsZXRpb24sIGopID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzZWxlY3RlZCA9IHBvc2l0aW9uID09PSB0aGlzLnN0YXRlLnNlbGVjdGlvbk9mZnNldDtcbiAgICAgICAgICAgICAgICBjb25zdCBjbGFzc05hbWUgPSBjbGFzc05hbWVzKCdteF9BdXRvY29tcGxldGVfQ29tcGxldGlvbicsIHtzZWxlY3RlZH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbXBvbmVudFBvc2l0aW9uID0gcG9zaXRpb247XG4gICAgICAgICAgICAgICAgcG9zaXRpb24rKztcblxuICAgICAgICAgICAgICAgIGNvbnN0IG9uQ2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25Db21wbGV0aW9uQ2xpY2tlZChjb21wb25lbnRQb3NpdGlvbik7XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jbG9uZUVsZW1lbnQoY29tcGxldGlvbi5jb21wb25lbnQsIHtcbiAgICAgICAgICAgICAgICAgICAgXCJrZXlcIjogaixcbiAgICAgICAgICAgICAgICAgICAgXCJyZWZcIjogYGNvbXBsZXRpb24ke2NvbXBvbmVudFBvc2l0aW9ufWAsXG4gICAgICAgICAgICAgICAgICAgIFwiaWRcIjogZ2VuZXJhdGVDb21wbGV0aW9uRG9tSWQoY29tcG9uZW50UG9zaXRpb24gLSAxKSwgLy8gMCBpbmRleCB0aGUgY29tcGxldGlvbiBJRHNcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrLFxuICAgICAgICAgICAgICAgICAgICBcImFyaWEtc2VsZWN0ZWRcIjogc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcblxuXG4gICAgICAgICAgICByZXR1cm4gY29tcGxldGlvbnMubGVuZ3RoID4gMCA/IChcbiAgICAgICAgICAgICAgICA8ZGl2IGtleT17aX0gY2xhc3NOYW1lPVwibXhfQXV0b2NvbXBsZXRlX1Byb3ZpZGVyU2VjdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X0F1dG9jb21wbGV0ZV9wcm92aWRlcl9uYW1lXCI+eyBjb21wbGV0aW9uUmVzdWx0LnByb3ZpZGVyLmdldE5hbWUoKSB9PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIHsgY29tcGxldGlvblJlc3VsdC5wcm92aWRlci5yZW5kZXJDb21wbGV0aW9ucyhjb21wbGV0aW9ucykgfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgKSA6IG51bGw7XG4gICAgICAgIH0pLmZpbHRlcigoY29tcGxldGlvbikgPT4gISFjb21wbGV0aW9uKTtcblxuICAgICAgICByZXR1cm4gIXRoaXMuc3RhdGUuaGlkZSAmJiByZW5kZXJlZENvbXBsZXRpb25zLmxlbmd0aCA+IDAgPyAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X0F1dG9jb21wbGV0ZVwiIHJlZj17dGhpcy5jb250YWluZXJSZWZ9PlxuICAgICAgICAgICAgICAgIHsgcmVuZGVyZWRDb21wbGV0aW9ucyB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKSA6IG51bGw7XG4gICAgfVxufVxuIl19