UNPKG

matrix-react-sdk

Version:
242 lines (230 loc) 34.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.options = exports.linkify = exports._linkifyString = exports._linkifyElement = exports.Type = exports.ELEMENT_URL_PATTERN = void 0; var _linkifyjs = _interopRequireWildcard(require("linkifyjs")); var linkifyjs = _linkifyjs; var _linkifyElement2 = _interopRequireDefault(require("linkify-element")); var _linkifyString2 = _interopRequireDefault(require("linkify-string")); var _matrix = require("matrix-js-sdk/src/matrix"); var _Permalinks = require("./utils/permalinks/Permalinks"); var _dispatcher = _interopRequireDefault(require("./dispatcher/dispatcher")); var _actions = require("./dispatcher/actions"); var _MatrixClientPeg = require("./MatrixClientPeg"); var _UrlUtils = require("./utils/UrlUtils"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /* Copyright 2024 New Vector Ltd. Copyright 2019 The Matrix.org Foundation C.I.C. Copyright 2015, 2016 OpenMarket Ltd SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ let Type = exports.Type = /*#__PURE__*/function (Type) { Type["URL"] = "url"; Type["UserId"] = "userid"; Type["RoomAlias"] = "roomalias"; return Type; }({}); function matrixOpaqueIdLinkifyParser({ scanner, parser, token, name }) { const { DOT, // IPV4 necessity NUM, COLON, SYM, SLASH, EQUALS, HYPHEN, UNDERSCORE } = scanner.tokens; // Contains NUM, WORD, UWORD, EMOJI, TLD, UTLD, SCHEME, SLASH_SCHEME and LOCALHOST plus custom protocols (e.g. "matrix") const { domain } = scanner.tokens.groups; // Tokens we need that are not contained in the domain group const additionalLocalpartTokens = [DOT, SYM, SLASH, EQUALS, UNDERSCORE, HYPHEN]; const additionalDomainpartTokens = [HYPHEN]; const matrixToken = linkifyjs.createTokenClass(name, { isLink: true }); const matrixTokenState = new linkifyjs.State(matrixToken); // linkify doesn't appear to type this correctly const matrixTokenWithPort = linkifyjs.createTokenClass(name, { isLink: true }); const matrixTokenWithPortState = new linkifyjs.State(matrixTokenWithPort); // linkify doesn't appear to type this correctly const INITIAL_STATE = parser.start.tt(token); // Localpart const LOCALPART_STATE = new linkifyjs.State(); INITIAL_STATE.ta(domain, LOCALPART_STATE); INITIAL_STATE.ta(additionalLocalpartTokens, LOCALPART_STATE); LOCALPART_STATE.ta(domain, LOCALPART_STATE); LOCALPART_STATE.ta(additionalLocalpartTokens, LOCALPART_STATE); // Domainpart const DOMAINPART_STATE_DOT = LOCALPART_STATE.tt(COLON); DOMAINPART_STATE_DOT.ta(domain, matrixTokenState); DOMAINPART_STATE_DOT.ta(additionalDomainpartTokens, matrixTokenState); matrixTokenState.ta(domain, matrixTokenState); matrixTokenState.ta(additionalDomainpartTokens, matrixTokenState); matrixTokenState.tt(DOT, DOMAINPART_STATE_DOT); // Port suffixes matrixTokenState.tt(COLON).tt(NUM, matrixTokenWithPortState); } function onUserClick(event, userId) { event.preventDefault(); _dispatcher.default.dispatch({ action: _actions.Action.ViewUser, member: new _matrix.User(userId) }); } function onAliasClick(event, roomAlias) { event.preventDefault(); _dispatcher.default.dispatch({ action: _actions.Action.ViewRoom, room_alias: roomAlias, metricsTrigger: "Timeline", metricsViaKeyboard: false }); } const escapeRegExp = function (s) { return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); }; // Recognise URLs from both our local and official Element deployments. // Anyone else really should be using matrix.to. vector:// allowed to support Element Desktop relative links. const ELEMENT_URL_PATTERN = exports.ELEMENT_URL_PATTERN = "^(?:vector://|https?://)?(?:" + escapeRegExp(window.location.host + window.location.pathname) + "|" + "(?:www\\.)?(?:riot|vector)\\.im/(?:app|beta|staging|develop)/|" + "(?:app|beta|staging|develop)\\.element\\.io/" + ")(#.*)"; const options = exports.options = { events: function (href, type) { switch (type) { case Type.URL: { // intercept local permalinks to users and show them like userids (in userinfo of current room) try { const permalink = (0, _Permalinks.parsePermalink)(href); if (permalink?.userId) { return { click: function (e) { onUserClick(e, permalink.userId); } }; } else { // for events, rooms etc. (anything other than users) const localHref = (0, _Permalinks.tryTransformPermalinkToLocalHref)(href); if (localHref !== href) { // it could be converted to a localHref -> therefore handle locally return { click: function (e) { e.preventDefault(); window.location.hash = localHref; } }; } } } catch (e) { // OK fine, it's not actually a permalink } break; } case Type.UserId: return { click: function (e) { const userId = (0, _Permalinks.parsePermalink)(href)?.userId ?? href; if (userId) onUserClick(e, userId); } }; case Type.RoomAlias: return { click: function (e) { const alias = (0, _Permalinks.parsePermalink)(href)?.roomIdOrAlias ?? href; if (alias) onAliasClick(e, alias); } }; } return {}; }, formatHref: function (href, type) { switch (type) { case "url": if (href.startsWith("mxc://") && _MatrixClientPeg.MatrixClientPeg.get()) { return (0, _matrix.getHttpUriForMxc)(_MatrixClientPeg.MatrixClientPeg.get().baseUrl, href, undefined, undefined, undefined, false, true); } // fallthrough case Type.RoomAlias: case Type.UserId: default: { return (0, _Permalinks.tryTransformEntityToPermalink)(_MatrixClientPeg.MatrixClientPeg.safeGet(), href) ?? ""; } } }, attributes: { rel: "noreferrer noopener" }, ignoreTags: ["pre", "code"], className: "linkified", target: function (href, type) { if (type === Type.URL) { try { const transformed = (0, _Permalinks.tryTransformPermalinkToLocalHref)(href); if (transformed !== href || // if it could be converted to handle locally for matrix symbols e.g. @user:server.tdl and matrix.to decodeURIComponent(href).match(ELEMENT_URL_PATTERN) // for https links to Element domains ) { return ""; } else { return "_blank"; } } catch (e) { // malformed URI } } return ""; } }; // Run the plugins (0, _linkifyjs.registerPlugin)(Type.RoomAlias, ({ scanner, parser }) => { const token = scanner.tokens.POUND; matrixOpaqueIdLinkifyParser({ scanner, parser, token, name: Type.RoomAlias }); }); (0, _linkifyjs.registerPlugin)(Type.UserId, ({ scanner, parser }) => { const token = scanner.tokens.AT; matrixOpaqueIdLinkifyParser({ scanner, parser, token, name: Type.UserId }); }); // Linkify supports some common protocols but not others, register all permitted url schemes if unsupported // https://github.com/Hypercontext/linkifyjs/blob/f4fad9df1870259622992bbfba38bfe3d0515609/packages/linkifyjs/src/scanner.js#L133-L141 // This also handles registering the `matrix:` protocol scheme const linkifySupportedProtocols = ["file", "mailto", "http", "https", "ftp", "ftps"]; const optionalSlashProtocols = ["bitcoin", "geo", "im", "magnet", "mailto", "matrix", "news", "openpgp4fpr", "sip", "sms", "smsto", "tel", "urn", "xmpp"]; _UrlUtils.PERMITTED_URL_SCHEMES.forEach(scheme => { if (!linkifySupportedProtocols.includes(scheme)) { (0, _linkifyjs.registerCustomProtocol)(scheme, optionalSlashProtocols.includes(scheme)); } }); (0, _linkifyjs.registerCustomProtocol)("mxc", false); const linkify = exports.linkify = linkifyjs; const _linkifyElement = exports._linkifyElement = _linkifyElement2.default; const _linkifyString = exports._linkifyString = _linkifyString2.default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbGlua2lmeWpzIiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJyZXF1aXJlIiwibGlua2lmeWpzIiwiX2xpbmtpZnlFbGVtZW50MiIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfbGlua2lmeVN0cmluZzIiLCJfbWF0cml4IiwiX1Blcm1hbGlua3MiLCJfZGlzcGF0Y2hlciIsIl9hY3Rpb25zIiwiX01hdHJpeENsaWVudFBlZyIsIl9VcmxVdGlscyIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIlR5cGUiLCJleHBvcnRzIiwibWF0cml4T3BhcXVlSWRMaW5raWZ5UGFyc2VyIiwic2Nhbm5lciIsInBhcnNlciIsInRva2VuIiwibmFtZSIsIkRPVCIsIk5VTSIsIkNPTE9OIiwiU1lNIiwiU0xBU0giLCJFUVVBTFMiLCJIWVBIRU4iLCJVTkRFUlNDT1JFIiwidG9rZW5zIiwiZG9tYWluIiwiZ3JvdXBzIiwiYWRkaXRpb25hbExvY2FscGFydFRva2VucyIsImFkZGl0aW9uYWxEb21haW5wYXJ0VG9rZW5zIiwibWF0cml4VG9rZW4iLCJjcmVhdGVUb2tlbkNsYXNzIiwiaXNMaW5rIiwibWF0cml4VG9rZW5TdGF0ZSIsIlN0YXRlIiwibWF0cml4VG9rZW5XaXRoUG9ydCIsIm1hdHJpeFRva2VuV2l0aFBvcnRTdGF0ZSIsIklOSVRJQUxfU1RBVEUiLCJzdGFydCIsInR0IiwiTE9DQUxQQVJUX1NUQVRFIiwidGEiLCJET01BSU5QQVJUX1NUQVRFX0RPVCIsIm9uVXNlckNsaWNrIiwiZXZlbnQiLCJ1c2VySWQiLCJwcmV2ZW50RGVmYXVsdCIsImRpcyIsImRpc3BhdGNoIiwiYWN0aW9uIiwiQWN0aW9uIiwiVmlld1VzZXIiLCJtZW1iZXIiLCJVc2VyIiwib25BbGlhc0NsaWNrIiwicm9vbUFsaWFzIiwiVmlld1Jvb20iLCJyb29tX2FsaWFzIiwibWV0cmljc1RyaWdnZXIiLCJtZXRyaWNzVmlhS2V5Ym9hcmQiLCJlc2NhcGVSZWdFeHAiLCJzIiwicmVwbGFjZSIsIkVMRU1FTlRfVVJMX1BBVFRFUk4iLCJ3aW5kb3ciLCJsb2NhdGlvbiIsImhvc3QiLCJwYXRobmFtZSIsIm9wdGlvbnMiLCJldmVudHMiLCJocmVmIiwidHlwZSIsIlVSTCIsInBlcm1hbGluayIsInBhcnNlUGVybWFsaW5rIiwiY2xpY2siLCJsb2NhbEhyZWYiLCJ0cnlUcmFuc2Zvcm1QZXJtYWxpbmtUb0xvY2FsSHJlZiIsImhhc2giLCJVc2VySWQiLCJSb29tQWxpYXMiLCJhbGlhcyIsInJvb21JZE9yQWxpYXMiLCJmb3JtYXRIcmVmIiwic3RhcnRzV2l0aCIsIk1hdHJpeENsaWVudFBlZyIsImdldEh0dHBVcmlGb3JNeGMiLCJiYXNlVXJsIiwidW5kZWZpbmVkIiwidHJ5VHJhbnNmb3JtRW50aXR5VG9QZXJtYWxpbmsiLCJzYWZlR2V0IiwiYXR0cmlidXRlcyIsInJlbCIsImlnbm9yZVRhZ3MiLCJjbGFzc05hbWUiLCJ0YXJnZXQiLCJ0cmFuc2Zvcm1lZCIsImRlY29kZVVSSUNvbXBvbmVudCIsIm1hdGNoIiwicmVnaXN0ZXJQbHVnaW4iLCJQT1VORCIsIkFUIiwibGlua2lmeVN1cHBvcnRlZFByb3RvY29scyIsIm9wdGlvbmFsU2xhc2hQcm90b2NvbHMiLCJQRVJNSVRURURfVVJMX1NDSEVNRVMiLCJmb3JFYWNoIiwic2NoZW1lIiwiaW5jbHVkZXMiLCJyZWdpc3RlckN1c3RvbVByb3RvY29sIiwibGlua2lmeSIsIl9saW5raWZ5RWxlbWVudCIsImxpbmtpZnlFbGVtZW50IiwiX2xpbmtpZnlTdHJpbmciLCJsaW5raWZ5U3RyaW5nIl0sInNvdXJjZXMiOlsiLi4vc3JjL2xpbmtpZnktbWF0cml4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE5IFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5Db3B5cmlnaHQgMjAxNSwgMjAxNiBPcGVuTWFya2V0IEx0ZFxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgKiBhcyBsaW5raWZ5anMgZnJvbSBcImxpbmtpZnlqc1wiO1xuaW1wb3J0IHsgRXZlbnRMaXN0ZW5lcnMsIE9wdHMsIHJlZ2lzdGVyQ3VzdG9tUHJvdG9jb2wsIHJlZ2lzdGVyUGx1Z2luIH0gZnJvbSBcImxpbmtpZnlqc1wiO1xuaW1wb3J0IGxpbmtpZnlFbGVtZW50IGZyb20gXCJsaW5raWZ5LWVsZW1lbnRcIjtcbmltcG9ydCBsaW5raWZ5U3RyaW5nIGZyb20gXCJsaW5raWZ5LXN0cmluZ1wiO1xuaW1wb3J0IHsgZ2V0SHR0cFVyaUZvck14YywgVXNlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcblxuaW1wb3J0IHtcbiAgICBwYXJzZVBlcm1hbGluayxcbiAgICB0cnlUcmFuc2Zvcm1FbnRpdHlUb1Blcm1hbGluayxcbiAgICB0cnlUcmFuc2Zvcm1QZXJtYWxpbmtUb0xvY2FsSHJlZixcbn0gZnJvbSBcIi4vdXRpbHMvcGVybWFsaW5rcy9QZXJtYWxpbmtzXCI7XG5pbXBvcnQgZGlzIGZyb20gXCIuL2Rpc3BhdGNoZXIvZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSBcIi4vZGlzcGF0Y2hlci9hY3Rpb25zXCI7XG5pbXBvcnQgeyBWaWV3VXNlclBheWxvYWQgfSBmcm9tIFwiLi9kaXNwYXRjaGVyL3BheWxvYWRzL1ZpZXdVc2VyUGF5bG9hZFwiO1xuaW1wb3J0IHsgVmlld1Jvb21QYXlsb2FkIH0gZnJvbSBcIi4vZGlzcGF0Y2hlci9wYXlsb2Fkcy9WaWV3Um9vbVBheWxvYWRcIjtcbmltcG9ydCB7IE1hdHJpeENsaWVudFBlZyB9IGZyb20gXCIuL01hdHJpeENsaWVudFBlZ1wiO1xuaW1wb3J0IHsgUEVSTUlUVEVEX1VSTF9TQ0hFTUVTIH0gZnJvbSBcIi4vdXRpbHMvVXJsVXRpbHNcIjtcblxuZXhwb3J0IGVudW0gVHlwZSB7XG4gICAgVVJMID0gXCJ1cmxcIixcbiAgICBVc2VySWQgPSBcInVzZXJpZFwiLFxuICAgIFJvb21BbGlhcyA9IFwicm9vbWFsaWFzXCIsXG59XG5cbmZ1bmN0aW9uIG1hdHJpeE9wYXF1ZUlkTGlua2lmeVBhcnNlcih7XG4gICAgc2Nhbm5lcixcbiAgICBwYXJzZXIsXG4gICAgdG9rZW4sXG4gICAgbmFtZSxcbn06IHtcbiAgICBzY2FubmVyOiBsaW5raWZ5anMuU2Nhbm5lckluaXQ7XG4gICAgcGFyc2VyOiBsaW5raWZ5anMuUGFyc2VySW5pdDtcbiAgICB0b2tlbjogXCIjXCIgfCBcIitcIiB8IFwiQFwiO1xuICAgIG5hbWU6IFR5cGU7XG59KTogdm9pZCB7XG4gICAgY29uc3Qge1xuICAgICAgICBET1QsXG4gICAgICAgIC8vIElQVjQgbmVjZXNzaXR5XG4gICAgICAgIE5VTSxcbiAgICAgICAgQ09MT04sXG4gICAgICAgIFNZTSxcbiAgICAgICAgU0xBU0gsXG4gICAgICAgIEVRVUFMUyxcbiAgICAgICAgSFlQSEVOLFxuICAgICAgICBVTkRFUlNDT1JFLFxuICAgIH0gPSBzY2FubmVyLnRva2VucztcblxuICAgIC8vIENvbnRhaW5zIE5VTSwgV09SRCwgVVdPUkQsIEVNT0pJLCBUTEQsIFVUTEQsIFNDSEVNRSwgU0xBU0hfU0NIRU1FIGFuZCBMT0NBTEhPU1QgcGx1cyBjdXN0b20gcHJvdG9jb2xzIChlLmcuIFwibWF0cml4XCIpXG4gICAgY29uc3QgeyBkb21haW4gfSA9IHNjYW5uZXIudG9rZW5zLmdyb3VwcztcblxuICAgIC8vIFRva2VucyB3ZSBuZWVkIHRoYXQgYXJlIG5vdCBjb250YWluZWQgaW4gdGhlIGRvbWFpbiBncm91cFxuICAgIGNvbnN0IGFkZGl0aW9uYWxMb2NhbHBhcnRUb2tlbnMgPSBbRE9ULCBTWU0sIFNMQVNILCBFUVVBTFMsIFVOREVSU0NPUkUsIEhZUEhFTl07XG4gICAgY29uc3QgYWRkaXRpb25hbERvbWFpbnBhcnRUb2tlbnMgPSBbSFlQSEVOXTtcblxuICAgIGNvbnN0IG1hdHJpeFRva2VuID0gbGlua2lmeWpzLmNyZWF0ZVRva2VuQ2xhc3MobmFtZSwgeyBpc0xpbms6IHRydWUgfSk7XG4gICAgY29uc3QgbWF0cml4VG9rZW5TdGF0ZSA9IG5ldyBsaW5raWZ5anMuU3RhdGUobWF0cml4VG9rZW4pIGFzIGFueSBhcyBsaW5raWZ5anMuU3RhdGU8bGlua2lmeWpzLk11bHRpVG9rZW4+OyAvLyBsaW5raWZ5IGRvZXNuJ3QgYXBwZWFyIHRvIHR5cGUgdGhpcyBjb3JyZWN0bHlcblxuICAgIGNvbnN0IG1hdHJpeFRva2VuV2l0aFBvcnQgPSBsaW5raWZ5anMuY3JlYXRlVG9rZW5DbGFzcyhuYW1lLCB7IGlzTGluazogdHJ1ZSB9KTtcbiAgICBjb25zdCBtYXRyaXhUb2tlbldpdGhQb3J0U3RhdGUgPSBuZXcgbGlua2lmeWpzLlN0YXRlKFxuICAgICAgICBtYXRyaXhUb2tlbldpdGhQb3J0LFxuICAgICkgYXMgYW55IGFzIGxpbmtpZnlqcy5TdGF0ZTxsaW5raWZ5anMuTXVsdGlUb2tlbj47IC8vIGxpbmtpZnkgZG9lc24ndCBhcHBlYXIgdG8gdHlwZSB0aGlzIGNvcnJlY3RseVxuXG4gICAgY29uc3QgSU5JVElBTF9TVEFURSA9IHBhcnNlci5zdGFydC50dCh0b2tlbik7XG5cbiAgICAvLyBMb2NhbHBhcnRcbiAgICBjb25zdCBMT0NBTFBBUlRfU1RBVEUgPSBuZXcgbGlua2lmeWpzLlN0YXRlPGxpbmtpZnlqcy5NdWx0aVRva2VuPigpO1xuICAgIElOSVRJQUxfU1RBVEUudGEoZG9tYWluLCBMT0NBTFBBUlRfU1RBVEUpO1xuICAgIElOSVRJQUxfU1RBVEUudGEoYWRkaXRpb25hbExvY2FscGFydFRva2VucywgTE9DQUxQQVJUX1NUQVRFKTtcbiAgICBMT0NBTFBBUlRfU1RBVEUudGEoZG9tYWluLCBMT0NBTFBBUlRfU1RBVEUpO1xuICAgIExPQ0FMUEFSVF9TVEFURS50YShhZGRpdGlvbmFsTG9jYWxwYXJ0VG9rZW5zLCBMT0NBTFBBUlRfU1RBVEUpO1xuXG4gICAgLy8gRG9tYWlucGFydFxuICAgIGNvbnN0IERPTUFJTlBBUlRfU1RBVEVfRE9UID0gTE9DQUxQQVJUX1NUQVRFLnR0KENPTE9OKTtcbiAgICBET01BSU5QQVJUX1NUQVRFX0RPVC50YShkb21haW4sIG1hdHJpeFRva2VuU3RhdGUpO1xuICAgIERPTUFJTlBBUlRfU1RBVEVfRE9ULnRhKGFkZGl0aW9uYWxEb21haW5wYXJ0VG9rZW5zLCBtYXRyaXhUb2tlblN0YXRlKTtcbiAgICBtYXRyaXhUb2tlblN0YXRlLnRhKGRvbWFpbiwgbWF0cml4VG9rZW5TdGF0ZSk7XG4gICAgbWF0cml4VG9rZW5TdGF0ZS50YShhZGRpdGlvbmFsRG9tYWlucGFydFRva2VucywgbWF0cml4VG9rZW5TdGF0ZSk7XG4gICAgbWF0cml4VG9rZW5TdGF0ZS50dChET1QsIERPTUFJTlBBUlRfU1RBVEVfRE9UKTtcblxuICAgIC8vIFBvcnQgc3VmZml4ZXNcbiAgICBtYXRyaXhUb2tlblN0YXRlLnR0KENPTE9OKS50dChOVU0sIG1hdHJpeFRva2VuV2l0aFBvcnRTdGF0ZSk7XG59XG5cbmZ1bmN0aW9uIG9uVXNlckNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50LCB1c2VySWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZGlzLmRpc3BhdGNoPFZpZXdVc2VyUGF5bG9hZD4oe1xuICAgICAgICBhY3Rpb246IEFjdGlvbi5WaWV3VXNlcixcbiAgICAgICAgbWVtYmVyOiBuZXcgVXNlcih1c2VySWQpLFxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBvbkFsaWFzQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIHJvb21BbGlhczogc3RyaW5nKTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBkaXMuZGlzcGF0Y2g8Vmlld1Jvb21QYXlsb2FkPih7XG4gICAgICAgIGFjdGlvbjogQWN0aW9uLlZpZXdSb29tLFxuICAgICAgICByb29tX2FsaWFzOiByb29tQWxpYXMsXG4gICAgICAgIG1ldHJpY3NUcmlnZ2VyOiBcIlRpbWVsaW5lXCIsXG4gICAgICAgIG1ldHJpY3NWaWFLZXlib2FyZDogZmFsc2UsXG4gICAgfSk7XG59XG5cbmNvbnN0IGVzY2FwZVJlZ0V4cCA9IGZ1bmN0aW9uIChzOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBzLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKTtcbn07XG5cbi8vIFJlY29nbmlzZSBVUkxzIGZyb20gYm90aCBvdXIgbG9jYWwgYW5kIG9mZmljaWFsIEVsZW1lbnQgZGVwbG95bWVudHMuXG4vLyBBbnlvbmUgZWxzZSByZWFsbHkgc2hvdWxkIGJlIHVzaW5nIG1hdHJpeC50by4gdmVjdG9yOi8vIGFsbG93ZWQgdG8gc3VwcG9ydCBFbGVtZW50IERlc2t0b3AgcmVsYXRpdmUgbGlua3MuXG5leHBvcnQgY29uc3QgRUxFTUVOVF9VUkxfUEFUVEVSTiA9XG4gICAgXCJeKD86dmVjdG9yOi8vfGh0dHBzPzovLyk/KD86XCIgK1xuICAgIGVzY2FwZVJlZ0V4cCh3aW5kb3cubG9jYXRpb24uaG9zdCArIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSkgK1xuICAgIFwifFwiICtcbiAgICBcIig/Ond3d1xcXFwuKT8oPzpyaW90fHZlY3RvcilcXFxcLmltLyg/OmFwcHxiZXRhfHN0YWdpbmd8ZGV2ZWxvcCkvfFwiICtcbiAgICBcIig/OmFwcHxiZXRhfHN0YWdpbmd8ZGV2ZWxvcClcXFxcLmVsZW1lbnRcXFxcLmlvL1wiICtcbiAgICBcIikoIy4qKVwiO1xuXG5leHBvcnQgY29uc3Qgb3B0aW9uczogT3B0cyA9IHtcbiAgICBldmVudHM6IGZ1bmN0aW9uIChocmVmOiBzdHJpbmcsIHR5cGU6IHN0cmluZyk6IEV2ZW50TGlzdGVuZXJzIHtcbiAgICAgICAgc3dpdGNoICh0eXBlIGFzIFR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgVHlwZS5VUkw6IHtcbiAgICAgICAgICAgICAgICAvLyBpbnRlcmNlcHQgbG9jYWwgcGVybWFsaW5rcyB0byB1c2VycyBhbmQgc2hvdyB0aGVtIGxpa2UgdXNlcmlkcyAoaW4gdXNlcmluZm8gb2YgY3VycmVudCByb29tKVxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBlcm1hbGluayA9IHBhcnNlUGVybWFsaW5rKGhyZWYpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGVybWFsaW5rPy51c2VySWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uIChlOiBNb3VzZUV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVXNlckNsaWNrKGUsIHBlcm1hbGluay51c2VySWQhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBldmVudHMsIHJvb21zIGV0Yy4gKGFueXRoaW5nIG90aGVyIHRoYW4gdXNlcnMpXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2NhbEhyZWYgPSB0cnlUcmFuc2Zvcm1QZXJtYWxpbmtUb0xvY2FsSHJlZihocmVmKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbEhyZWYgIT09IGhyZWYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpdCBjb3VsZCBiZSBjb252ZXJ0ZWQgdG8gYSBsb2NhbEhyZWYgLT4gdGhlcmVmb3JlIGhhbmRsZSBsb2NhbGx5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uIChlOiBNb3VzZUV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaGFzaCA9IGxvY2FsSHJlZjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBPSyBmaW5lLCBpdCdzIG5vdCBhY3R1YWxseSBhIHBlcm1hbGlua1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgVHlwZS5Vc2VySWQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uIChlOiBNb3VzZUV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1c2VySWQgPSBwYXJzZVBlcm1hbGluayhocmVmKT8udXNlcklkID8/IGhyZWY7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlcklkKSBvblVzZXJDbGljayhlLCB1c2VySWQpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjYXNlIFR5cGUuUm9vbUFsaWFzOlxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbiAoZTogTW91c2VFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWxpYXMgPSBwYXJzZVBlcm1hbGluayhocmVmKT8ucm9vbUlkT3JBbGlhcyA/PyBocmVmO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFsaWFzKSBvbkFsaWFzQ2xpY2soZSwgYWxpYXMpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge307XG4gICAgfSxcblxuICAgIGZvcm1hdEhyZWY6IGZ1bmN0aW9uIChocmVmOiBzdHJpbmcsIHR5cGU6IFR5cGUgfCBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgXCJ1cmxcIjpcbiAgICAgICAgICAgICAgICBpZiAoaHJlZi5zdGFydHNXaXRoKFwibXhjOi8vXCIpICYmIE1hdHJpeENsaWVudFBlZy5nZXQoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0SHR0cFVyaUZvck14YyhcbiAgICAgICAgICAgICAgICAgICAgICAgIE1hdHJpeENsaWVudFBlZy5nZXQoKSEuYmFzZVVybCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhyZWYsXG4gICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZmFsbHRocm91Z2hcbiAgICAgICAgICAgIGNhc2UgVHlwZS5Sb29tQWxpYXM6XG4gICAgICAgICAgICBjYXNlIFR5cGUuVXNlcklkOlxuICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnlUcmFuc2Zvcm1FbnRpdHlUb1Blcm1hbGluayhNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLCBocmVmKSA/PyBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgcmVsOiBcIm5vcmVmZXJyZXIgbm9vcGVuZXJcIixcbiAgICB9LFxuXG4gICAgaWdub3JlVGFnczogW1wicHJlXCIsIFwiY29kZVwiXSxcblxuICAgIGNsYXNzTmFtZTogXCJsaW5raWZpZWRcIixcblxuICAgIHRhcmdldDogZnVuY3Rpb24gKGhyZWY6IHN0cmluZywgdHlwZTogVHlwZSB8IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGlmICh0eXBlID09PSBUeXBlLlVSTCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZCA9IHRyeVRyYW5zZm9ybVBlcm1hbGlua1RvTG9jYWxIcmVmKGhyZWYpO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWQgIT09IGhyZWYgfHwgLy8gaWYgaXQgY291bGQgYmUgY29udmVydGVkIHRvIGhhbmRsZSBsb2NhbGx5IGZvciBtYXRyaXggc3ltYm9scyBlLmcuIEB1c2VyOnNlcnZlci50ZGwgYW5kIG1hdHJpeC50b1xuICAgICAgICAgICAgICAgICAgICBkZWNvZGVVUklDb21wb25lbnQoaHJlZikubWF0Y2goRUxFTUVOVF9VUkxfUEFUVEVSTikgLy8gZm9yIGh0dHBzIGxpbmtzIHRvIEVsZW1lbnQgZG9tYWluc1xuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJfYmxhbmtcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gbWFsZm9ybWVkIFVSSVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgIH0sXG59O1xuXG4vLyBSdW4gdGhlIHBsdWdpbnNcbnJlZ2lzdGVyUGx1Z2luKFR5cGUuUm9vbUFsaWFzLCAoeyBzY2FubmVyLCBwYXJzZXIgfSkgPT4ge1xuICAgIGNvbnN0IHRva2VuID0gc2Nhbm5lci50b2tlbnMuUE9VTkQgYXMgXCIjXCI7XG4gICAgbWF0cml4T3BhcXVlSWRMaW5raWZ5UGFyc2VyKHtcbiAgICAgICAgc2Nhbm5lcixcbiAgICAgICAgcGFyc2VyLFxuICAgICAgICB0b2tlbixcbiAgICAgICAgbmFtZTogVHlwZS5Sb29tQWxpYXMsXG4gICAgfSk7XG59KTtcblxucmVnaXN0ZXJQbHVnaW4oVHlwZS5Vc2VySWQsICh7IHNjYW5uZXIsIHBhcnNlciB9KSA9PiB7XG4gICAgY29uc3QgdG9rZW4gPSBzY2FubmVyLnRva2Vucy5BVCBhcyBcIkBcIjtcbiAgICBtYXRyaXhPcGFxdWVJZExpbmtpZnlQYXJzZXIoe1xuICAgICAgICBzY2FubmVyLFxuICAgICAgICBwYXJzZXIsXG4gICAgICAgIHRva2VuLFxuICAgICAgICBuYW1lOiBUeXBlLlVzZXJJZCxcbiAgICB9KTtcbn0pO1xuXG4vLyBMaW5raWZ5IHN1cHBvcnRzIHNvbWUgY29tbW9uIHByb3RvY29scyBidXQgbm90IG90aGVycywgcmVnaXN0ZXIgYWxsIHBlcm1pdHRlZCB1cmwgc2NoZW1lcyBpZiB1bnN1cHBvcnRlZFxuLy8gaHR0cHM6Ly9naXRodWIuY29tL0h5cGVyY29udGV4dC9saW5raWZ5anMvYmxvYi9mNGZhZDlkZjE4NzAyNTk2MjI5OTJiYmZiYTM4YmZlM2QwNTE1NjA5L3BhY2thZ2VzL2xpbmtpZnlqcy9zcmMvc2Nhbm5lci5qcyNMMTMzLUwxNDFcbi8vIFRoaXMgYWxzbyBoYW5kbGVzIHJlZ2lzdGVyaW5nIHRoZSBgbWF0cml4OmAgcHJvdG9jb2wgc2NoZW1lXG5jb25zdCBsaW5raWZ5U3VwcG9ydGVkUHJvdG9jb2xzID0gW1wiZmlsZVwiLCBcIm1haWx0b1wiLCBcImh0dHBcIiwgXCJodHRwc1wiLCBcImZ0cFwiLCBcImZ0cHNcIl07XG5jb25zdCBvcHRpb25hbFNsYXNoUHJvdG9jb2xzID0gW1xuICAgIFwiYml0Y29pblwiLFxuICAgIFwiZ2VvXCIsXG4gICAgXCJpbVwiLFxuICAgIFwibWFnbmV0XCIsXG4gICAgXCJtYWlsdG9cIixcbiAgICBcIm1hdHJpeFwiLFxuICAgIFwibmV3c1wiLFxuICAgIFwib3BlbnBncDRmcHJcIixcbiAgICBcInNpcFwiLFxuICAgIFwic21zXCIsXG4gICAgXCJzbXN0b1wiLFxuICAgIFwidGVsXCIsXG4gICAgXCJ1cm5cIixcbiAgICBcInhtcHBcIixcbl07XG5cblBFUk1JVFRFRF9VUkxfU0NIRU1FUy5mb3JFYWNoKChzY2hlbWUpID0+IHtcbiAgICBpZiAoIWxpbmtpZnlTdXBwb3J0ZWRQcm90b2NvbHMuaW5jbHVkZXMoc2NoZW1lKSkge1xuICAgICAgICByZWdpc3RlckN1c3RvbVByb3RvY29sKHNjaGVtZSwgb3B0aW9uYWxTbGFzaFByb3RvY29scy5pbmNsdWRlcyhzY2hlbWUpKTtcbiAgICB9XG59KTtcblxucmVnaXN0ZXJDdXN0b21Qcm90b2NvbChcIm14Y1wiLCBmYWxzZSk7XG5cbmV4cG9ydCBjb25zdCBsaW5raWZ5ID0gbGlua2lmeWpzO1xuZXhwb3J0IGNvbnN0IF9saW5raWZ5RWxlbWVudCA9IGxpbmtpZnlFbGVtZW50O1xuZXhwb3J0IGNvbnN0IF9saW5raWZ5U3RyaW5nID0gbGlua2lmeVN0cmluZztcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVNBLElBQUFBLFVBQUEsR0FBQUMsdUJBQUEs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