matrix-react-sdk
Version:
SDK for matrix.org using React
247 lines (206 loc) • 35.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _SpecPermalinkConstructor = require("./utils/permalinks/SpecPermalinkConstructor");
var _Permalinks = require("./utils/permalinks/Permalinks");
/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
function matrixLinkify(linkify) {
// Text tokens
const TT = linkify.scanner.TOKENS; // Multi tokens
const MT = linkify.parser.TOKENS;
const MultiToken = MT.Base;
const S_START = linkify.parser.start;
if (TT.UNDERSCORE === undefined) {
throw new Error("linkify-matrix requires linkifyjs 2.1.1: this version is too old.");
}
const ROOMALIAS = function (value) {
MultiToken.call(this, value);
this.type = 'roomalias';
this.isLink = true;
};
ROOMALIAS.prototype = new MultiToken();
const S_HASH = S_START.jump(TT.POUND);
const S_HASH_NAME = new linkify.parser.State();
const S_HASH_NAME_COLON = new linkify.parser.State();
const S_HASH_NAME_COLON_DOMAIN = new linkify.parser.State(ROOMALIAS);
const S_HASH_NAME_COLON_DOMAIN_DOT = new linkify.parser.State();
const S_ROOMALIAS = new linkify.parser.State(ROOMALIAS);
const S_ROOMALIAS_COLON = new linkify.parser.State();
const S_ROOMALIAS_COLON_NUM = new linkify.parser.State(ROOMALIAS);
const roomnameTokens = [TT.DOT, TT.PLUS, TT.NUM, TT.DOMAIN, TT.TLD, TT.UNDERSCORE, TT.POUND, // because 'localhost' is tokenised to the localhost token,
// usernames @localhost:foo.com are otherwise not matched!
TT.LOCALHOST];
S_HASH.on(roomnameTokens, S_HASH_NAME);
S_HASH_NAME.on(roomnameTokens, S_HASH_NAME);
S_HASH_NAME.on(TT.DOMAIN, S_HASH_NAME);
S_HASH_NAME.on(TT.COLON, S_HASH_NAME_COLON);
S_HASH_NAME_COLON.on(TT.DOMAIN, S_HASH_NAME_COLON_DOMAIN);
S_HASH_NAME_COLON.on(TT.LOCALHOST, S_ROOMALIAS); // accept #foo:localhost
S_HASH_NAME_COLON.on(TT.TLD, S_ROOMALIAS); // accept #foo:com (mostly for (TLD|DOMAIN)+ mixing)
S_HASH_NAME_COLON_DOMAIN.on(TT.DOT, S_HASH_NAME_COLON_DOMAIN_DOT);
S_HASH_NAME_COLON_DOMAIN_DOT.on(TT.DOMAIN, S_HASH_NAME_COLON_DOMAIN);
S_HASH_NAME_COLON_DOMAIN_DOT.on(TT.TLD, S_ROOMALIAS);
S_ROOMALIAS.on(TT.DOT, S_HASH_NAME_COLON_DOMAIN_DOT); // accept repeated TLDs (e.g .org.uk)
S_ROOMALIAS.on(TT.COLON, S_ROOMALIAS_COLON); // do not accept trailing `:`
S_ROOMALIAS_COLON.on(TT.NUM, S_ROOMALIAS_COLON_NUM); // but do accept :NUM (port specifier)
const USERID = function (value) {
MultiToken.call(this, value);
this.type = 'userid';
this.isLink = true;
};
USERID.prototype = new MultiToken();
const S_AT = S_START.jump(TT.AT);
const S_AT_NAME = new linkify.parser.State();
const S_AT_NAME_COLON = new linkify.parser.State();
const S_AT_NAME_COLON_DOMAIN = new linkify.parser.State(USERID);
const S_AT_NAME_COLON_DOMAIN_DOT = new linkify.parser.State();
const S_USERID = new linkify.parser.State(USERID);
const S_USERID_COLON = new linkify.parser.State();
const S_USERID_COLON_NUM = new linkify.parser.State(USERID);
const usernameTokens = [TT.DOT, TT.UNDERSCORE, TT.PLUS, TT.NUM, TT.DOMAIN, TT.TLD, // as in roomnameTokens
TT.LOCALHOST];
S_AT.on(usernameTokens, S_AT_NAME);
S_AT_NAME.on(usernameTokens, S_AT_NAME);
S_AT_NAME.on(TT.DOMAIN, S_AT_NAME);
S_AT_NAME.on(TT.COLON, S_AT_NAME_COLON);
S_AT_NAME_COLON.on(TT.DOMAIN, S_AT_NAME_COLON_DOMAIN);
S_AT_NAME_COLON.on(TT.LOCALHOST, S_USERID); // accept @foo:localhost
S_AT_NAME_COLON.on(TT.TLD, S_USERID); // accept @foo:com (mostly for (TLD|DOMAIN)+ mixing)
S_AT_NAME_COLON_DOMAIN.on(TT.DOT, S_AT_NAME_COLON_DOMAIN_DOT);
S_AT_NAME_COLON_DOMAIN_DOT.on(TT.DOMAIN, S_AT_NAME_COLON_DOMAIN);
S_AT_NAME_COLON_DOMAIN_DOT.on(TT.TLD, S_USERID);
S_USERID.on(TT.DOT, S_AT_NAME_COLON_DOMAIN_DOT); // accept repeated TLDs (e.g .org.uk)
S_USERID.on(TT.COLON, S_USERID_COLON); // do not accept trailing `:`
S_USERID_COLON.on(TT.NUM, S_USERID_COLON_NUM); // but do accept :NUM (port specifier)
const GROUPID = function (value) {
MultiToken.call(this, value);
this.type = 'groupid';
this.isLink = true;
};
GROUPID.prototype = new MultiToken();
const S_PLUS = S_START.jump(TT.PLUS);
const S_PLUS_NAME = new linkify.parser.State();
const S_PLUS_NAME_COLON = new linkify.parser.State();
const S_PLUS_NAME_COLON_DOMAIN = new linkify.parser.State(GROUPID);
const S_PLUS_NAME_COLON_DOMAIN_DOT = new linkify.parser.State();
const S_GROUPID = new linkify.parser.State(GROUPID);
const S_GROUPID_COLON = new linkify.parser.State();
const S_GROUPID_COLON_NUM = new linkify.parser.State(GROUPID);
const groupIdTokens = [TT.DOT, TT.UNDERSCORE, TT.PLUS, TT.NUM, TT.DOMAIN, TT.TLD, // as in roomnameTokens
TT.LOCALHOST];
S_PLUS.on(groupIdTokens, S_PLUS_NAME);
S_PLUS_NAME.on(groupIdTokens, S_PLUS_NAME);
S_PLUS_NAME.on(TT.DOMAIN, S_PLUS_NAME);
S_PLUS_NAME.on(TT.COLON, S_PLUS_NAME_COLON);
S_PLUS_NAME_COLON.on(TT.DOMAIN, S_PLUS_NAME_COLON_DOMAIN);
S_PLUS_NAME_COLON.on(TT.LOCALHOST, S_GROUPID); // accept +foo:localhost
S_PLUS_NAME_COLON.on(TT.TLD, S_GROUPID); // accept +foo:com (mostly for (TLD|DOMAIN)+ mixing)
S_PLUS_NAME_COLON_DOMAIN.on(TT.DOT, S_PLUS_NAME_COLON_DOMAIN_DOT);
S_PLUS_NAME_COLON_DOMAIN_DOT.on(TT.DOMAIN, S_PLUS_NAME_COLON_DOMAIN);
S_PLUS_NAME_COLON_DOMAIN_DOT.on(TT.TLD, S_GROUPID);
S_GROUPID.on(TT.DOT, S_PLUS_NAME_COLON_DOMAIN_DOT); // accept repeated TLDs (e.g .org.uk)
S_GROUPID.on(TT.COLON, S_GROUPID_COLON); // do not accept trailing `:`
S_GROUPID_COLON.on(TT.NUM, S_GROUPID_COLON_NUM); // but do accept :NUM (port specifier)
} // stubs, overwritten in MatrixChat's componentDidMount
matrixLinkify.onUserClick = function (e, userId) {
e.preventDefault();
};
matrixLinkify.onAliasClick = function (e, roomAlias) {
e.preventDefault();
};
matrixLinkify.onGroupClick = function (e, groupId) {
e.preventDefault();
};
const escapeRegExp = function (string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}; // Recognise URLs from both our local and official Element deployments.
// Anyone else really should be using matrix.to.
matrixLinkify.ELEMENT_URL_PATTERN = "^(?:https?://)?(?:" + escapeRegExp(window.location.host + window.location.pathname) + "|" + "(?:www\\.)?(?:riot|vector)\\.im/(?:app|beta|staging|develop)/|" + "(?:app|beta|staging|develop)\\.element\\.io/" + ")(#.*)";
matrixLinkify.MATRIXTO_URL_PATTERN = "^(?:https?://)?(?:www\\.)?matrix\\.to/#/(([#@!+]).*)";
matrixLinkify.MATRIXTO_MD_LINK_PATTERN = '\\[([^\\]]*)\\]\\((?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!+][^\\)]*)\\)';
matrixLinkify.MATRIXTO_BASE_URL = _SpecPermalinkConstructor.baseUrl;
matrixLinkify.options = {
events: function (href, type) {
switch (type) {
case "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 && permalink.userId) {
return {
click: function (e) {
matrixLinkify.onUserClick(e, permalink.userId);
}
};
}
} catch (e) {// OK fine, it's not actually a permalink
}
break;
}
case "userid":
return {
click: function (e) {
matrixLinkify.onUserClick(e, href);
}
};
case "roomalias":
return {
click: function (e) {
matrixLinkify.onAliasClick(e, href);
}
};
case "groupid":
return {
click: function (e) {
matrixLinkify.onGroupClick(e, href);
}
};
}
},
formatHref: function (href, type) {
switch (type) {
case 'roomalias':
case 'userid':
case 'groupid':
default:
{
return (0, _Permalinks.tryTransformEntityToPermalink)(href);
}
}
},
linkAttributes: {
rel: 'noreferrer noopener'
},
target: function (href, type) {
if (type === 'url') {
try {
const transformed = (0, _Permalinks.tryTransformPermalinkToLocalHref)(href);
if (transformed !== href || decodeURIComponent(href).match(matrixLinkify.ELEMENT_URL_PATTERN)) {
return null;
} else {
return '_blank';
}
} catch (e) {// malformed URI
}
}
return null;
}
};
var _default = matrixLinkify;
exports.default = _default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9saW5raWZ5LW1hdHJpeC5qcyJdLCJuYW1lcyI6WyJtYXRyaXhMaW5raWZ5IiwibGlua2lmeSIsIlRUIiwic2Nhbm5lciIsIlRPS0VOUyIsIk1UIiwicGFyc2VyIiwiTXVsdGlUb2tlbiIsIkJhc2UiLCJTX1NUQVJUIiwic3RhcnQiLCJVTkRFUlNDT1JFIiwidW5kZWZpbmVkIiwiRXJyb3IiLCJST09NQUxJQVMiLCJ2YWx1ZSIsImNhbGwiLCJ0eXBlIiwiaXNMaW5rIiwicHJvdG90eXBlIiwiU19IQVNIIiwianVtcCIsIlBPVU5EIiwiU19IQVNIX05BTUUiLCJTdGF0ZSIsIlNfSEFTSF9OQU1FX0NPTE9OIiwiU19IQVNIX05BTUVfQ09MT05fRE9NQUlOIiwiU19IQVNIX05BTUVfQ09MT05fRE9NQUlOX0RPVCIsIlNfUk9PTUFMSUFTIiwiU19ST09NQUxJQVNfQ09MT04iLCJTX1JPT01BTElBU19DT0xPTl9OVU0iLCJyb29tbmFtZVRva2VucyIsIkRPVCIsIlBMVVMiLCJOVU0iLCJET01BSU4iLCJUTEQiLCJMT0NBTEhPU1QiLCJvbiIsIkNPTE9OIiwiVVNFUklEIiwiU19BVCIsIkFUIiwiU19BVF9OQU1FIiwiU19BVF9OQU1FX0NPTE9OIiwiU19BVF9OQU1FX0NPTE9OX0RPTUFJTiIsIlNfQVRfTkFNRV9DT0xPTl9ET01BSU5fRE9UIiwiU19VU0VSSUQiLCJTX1VTRVJJRF9DT0xPTiIsIlNfVVNFUklEX0NPTE9OX05VTSIsInVzZXJuYW1lVG9rZW5zIiwiR1JPVVBJRCIsIlNfUExVUyIsIlNfUExVU19OQU1FIiwiU19QTFVTX05BTUVfQ09MT04iLCJTX1BMVVNfTkFNRV9DT0xPTl9ET01BSU4iLCJTX1BMVVNfTkFNRV9DT0xPTl9ET01BSU5fRE9UIiwiU19HUk9VUElEIiwiU19HUk9VUElEX0NPTE9OIiwiU19HUk9VUElEX0NPTE9OX05VTSIsImdyb3VwSWRUb2tlbnMiLCJvblVzZXJDbGljayIsImUiLCJ1c2VySWQiLCJwcmV2ZW50RGVmYXVsdCIsIm9uQWxpYXNDbGljayIsInJvb21BbGlhcyIsIm9uR3JvdXBDbGljayIsImdyb3VwSWQiLCJlc2NhcGVSZWdFeHAiLCJzdHJpbmciLCJyZXBsYWNlIiwiRUxFTUVOVF9VUkxfUEFUVEVSTiIsIndpbmRvdyIsImxvY2F0aW9uIiwiaG9zdCIsInBhdGhuYW1lIiwiTUFUUklYVE9fVVJMX1BBVFRFUk4iLCJNQVRSSVhUT19NRF9MSU5LX1BBVFRFUk4iLCJNQVRSSVhUT19CQVNFX1VSTCIsImJhc2VVcmwiLCJvcHRpb25zIiwiZXZlbnRzIiwiaHJlZiIsInBlcm1hbGluayIsImNsaWNrIiwiZm9ybWF0SHJlZiIsImxpbmtBdHRyaWJ1dGVzIiwicmVsIiwidGFyZ2V0IiwidHJhbnNmb3JtZWQiLCJkZWNvZGVVUklDb21wb25lbnQiLCJtYXRjaCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQWlCQTs7QUFDQTs7QUFsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFTQSxTQUFTQSxhQUFULENBQXVCQyxPQUF2QixFQUFnQztBQUM1QjtBQUNBLFFBQU1DLEVBQUUsR0FBR0QsT0FBTyxDQUFDRSxPQUFSLENBQWdCQyxNQUEzQixDQUY0QixDQUc1Qjs7QUFDQSxRQUFNQyxFQUFFLEdBQUdKLE9BQU8sQ0FBQ0ssTUFBUixDQUFlRixNQUExQjtBQUNBLFFBQU1HLFVBQVUsR0FBR0YsRUFBRSxDQUFDRyxJQUF0QjtBQUNBLFFBQU1DLE9BQU8sR0FBR1IsT0FBTyxDQUFDSyxNQUFSLENBQWVJLEtBQS9COztBQUVBLE1BQUlSLEVBQUUsQ0FBQ1MsVUFBSCxLQUFrQkMsU0FBdEIsRUFBaUM7QUFDN0IsVUFBTSxJQUFJQyxLQUFKLENBQVUsbUVBQVYsQ0FBTjtBQUNIOztBQUVELFFBQU1DLFNBQVMsR0FBRyxVQUFTQyxLQUFULEVBQWdCO0FBQzlCUixJQUFBQSxVQUFVLENBQUNTLElBQVgsQ0FBZ0IsSUFBaEIsRUFBc0JELEtB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O0FBQ2Y5RCxZQUFBQSxhQUFhLENBQUNtRSxZQUFkLENBQTJCTCxDQUEzQixFQUE4QnFCLElBQTlCO0FBQ0g7QUFIRSxTQUFQO0FBOUJSO0FBb0NILEdBdENtQjtBQXdDcEJHLEVBQUFBLFVBQVUsRUFBRSxVQUFTSCxJQUFULEVBQWVsRSxJQUFmLEVBQXFCO0FBQzdCLFlBQVFBLElBQVI7QUFDSSxXQUFLLFdBQUw7QUFDQSxXQUFLLFFBQUw7QUFDQSxXQUFLLFNBQUw7QUFDQTtBQUFTO0FBQ0wsaUJBQU8sK0NBQThCa0UsSUFBOUIsQ0FBUDtBQUNIO0FBTkw7QUFRSCxHQWpEbUI7QUFtRHBCSSxFQUFBQSxjQUFjLEVBQUU7QUFDWkMsSUFBQUEsR0FBRyxFQUFFO0FBRE8sR0FuREk7QUF1RHBCQyxFQUFBQSxNQUFNLEVBQUUsVUFBU04sSUFBVCxFQUFlbEUsSUFBZixFQUFxQjtBQUN6QixRQUFJQSxJQUFJLEtBQUssS0FBYixFQUFvQjtBQUNoQixVQUFJO0FBQ0EsY0FBTXlFLFdBQVcsR0FBRyxrREFBaUNQLElBQWpDLENBQXBCOztBQUNBLFlBQUlPLFdBQVcsS0FBS1AsSUFBaEIsSUFBd0JRLGtCQUFrQixDQUFDUixJQUFELENBQWxCLENBQXlCUyxLQUF6QixDQUErQjVGLGFBQWEsQ0FBQ3dFLG1CQUE3QyxDQUE1QixFQUErRjtBQUMzRixpQkFBTyxJQUFQO0FBQ0gsU0FGRCxNQUVPO0FBQ0gsaUJBQU8sUUFBUDtBQUNIO0FBQ0osT0FQRCxDQU9FLE9BQU9WLENBQVAsRUFBVSxDQUNSO0FBQ0g7QUFDSjs7QUFDRCxXQUFPLElBQVA7QUFDSDtBQXJFbUIsQ0FBeEI7ZUF3RWU5RCxhIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDE1LCAyMDE2IE9wZW5NYXJrZXQgTHRkXG5Db3B5cmlnaHQgMjAxOSBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCB7YmFzZVVybH0gZnJvbSBcIi4vdXRpbHMvcGVybWFsaW5rcy9TcGVjUGVybWFsaW5rQ29uc3RydWN0b3JcIjtcbmltcG9ydCB7XG4gICAgcGFyc2VQZXJtYWxpbmssXG4gICAgdHJ5VHJhbnNmb3JtRW50aXR5VG9QZXJtYWxpbmssXG4gICAgdHJ5VHJhbnNmb3JtUGVybWFsaW5rVG9Mb2NhbEhyZWYsXG59IGZyb20gXCIuL3V0aWxzL3Blcm1hbGlua3MvUGVybWFsaW5rc1wiO1xuXG5mdW5jdGlvbiBtYXRyaXhMaW5raWZ5KGxpbmtpZnkpIHtcbiAgICAvLyBUZXh0IHRva2Vuc1xuICAgIGNvbnN0IFRUID0gbGlua2lmeS5zY2FubmVyLlRPS0VOUztcbiAgICAvLyBNdWx0aSB0b2tlbnNcbiAgICBjb25zdCBNVCA9IGxpbmtpZnkucGFyc2VyLlRPS0VOUztcbiAgICBjb25zdCBNdWx0aVRva2VuID0gTVQuQmFzZTtcbiAgICBjb25zdCBTX1NUQVJUID0gbGlua2lmeS5wYXJzZXIuc3RhcnQ7XG5cbiAgICBpZiAoVFQuVU5ERVJTQ09SRSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImxpbmtpZnktbWF0cml4IHJlcXVpcmVzIGxpbmtpZnlqcyAyLjEuMTogdGhpcyB2ZXJzaW9uIGlzIHRvbyBvbGQuXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IFJPT01BTElBUyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIE11bHRpVG9rZW4uY2FsbCh0aGlzLCB2YWx1ZSk7XG4gICAgICAgIHRoaXMudHlwZSA9ICdyb29tYWxpYXMnO1xuICAgICAgICB0aGlzLmlzTGluayA9IHRydWU7XG4gICAgfTtcbiAgICBST09NQUxJQVMucHJvdG90eXBlID0gbmV3IE11bHRpVG9rZW4oKTtcblxuICAgIGNvbnN0IFNfSEFTSCA9IFNfU1RBUlQuanVtcChUVC5QT1VORCk7XG4gICAgY29uc3QgU19IQVNIX05BTUUgPSBuZXcgbGlua2lmeS5wYXJzZXIuU3RhdGUoKTtcbiAgICBjb25zdCBTX0hBU0hfTkFNRV9DT0xPTiA9IG5ldyBsaW5raWZ5LnBhcnNlci5TdGF0ZSgpO1xuICAgIGNvbnN0IFNfSEFTSF9OQU1FX0NPTE9OX0RPTUFJTiA9IG5ldyBsaW5raWZ5LnBhcnNlci5TdGF0ZShST09NQUxJQVMpO1xuICAgIGNvbnN0IFNfSEFTSF9OQU1FX0NPTE9OX0RPTUFJTl9ET1QgPSBuZXcgbGlua2lmeS5wYXJzZXIuU3RhdGUoKTtcbiAgICBjb25zdCBTX1JPT01BTElBUyA9IG5ldyBsaW5raWZ5LnBhcnNlci5TdGF0ZShST09NQUxJQVMpO1xuICAgIGNvbnN0IFNfUk9PTUFMSUFTX0NPTE9OID0gbmV3IGxpbmtpZnkucGFyc2VyLlN0YXRlKCk7XG4gICAgY29uc3QgU19ST09NQUxJQVNfQ09MT05fTlVNID0gbmV3IGxpbmtpZnkucGFyc2VyLlN0YXRlKFJPT01BTElBUyk7XG5cbiAgICBjb25zdCByb29tbmFtZVRva2VucyA9IFtcbiAgICAgICAgVFQuRE9ULFxuICAgICAgICBUVC5QTFVTLFxuICAgICAgICBUVC5OVU0sXG4gICAgICAgIFRULkRPTUFJTixcbiAgICAgICAgVFQuVExELFxuICAgICAgICBUVC5VTkRFUlNDT1JFLFxuICAgICAgICBUVC5QT1VORCxcblxuICAgICAgICAvLyBiZWNhdXNlICdsb2NhbGhvc3QnIGlzIHRva2VuaXNlZCB0byB0aGUgbG9jYWxob3N0IHRva2VuLFxuICAgICAgICAvLyB1c2VybmFtZXMgQGxvY2FsaG9zdDpmb28uY29tIGFyZSBvdGhlcndpc2Ugbm90IG1hdGNoZWQhXG4gICAgICAgIFRULkxPQ0FMSE9TVCxcbiAgICBdO1xuXG4gICAgU19IQVNILm9uKHJvb21uYW1lVG9rZW5zLCBTX0hBU0hfTkFNRSk7XG4gICAgU19IQVNIX05BTUUub24ocm9vbW5hbWVUb2tlbnMsIFNfSEFTSF9OQU1FKTtcbiAgICBTX0hBU0hfTkFNRS5vbihUVC5ET01BSU4sIFNfSEFTSF9OQU1FKTtcblxuICAgIFNfSEFTSF9OQU1FLm9uKFRULkNPTE9OLCBTX0hBU0hfTkFNRV9DT0xPTik7XG5cbiAgICBTX0hBU0hfTkFNRV9DT0xPTi5vbihUVC5ET01BSU4sIFNfSEFTSF9OQU1FX0NPTE9OX0RPTUFJTik7XG4gICAgU19IQVNIX05BTUVfQ09MT04ub24oVFQuTE9DQUxIT1NULCBTX1JPT01BTElBUyk7IC8vIGFjY2VwdCAjZm9vOmxvY2FsaG9zdFxuICAgIFNfSEFTSF9OQU1FX0NPTE9OLm9uKFRULlRMRCwgU19ST09NQUxJQVMpOyAvLyBhY2NlcHQgI2Zvbzpjb20gKG1vc3RseSBmb3IgKFRMRHxET01BSU4pKyBtaXhpbmcpXG4gICAgU19IQVNIX05BTUVfQ09MT05fRE9NQUlOLm9uKFRULkRPVCwgU19IQVNIX05BTUVfQ09MT05fRE9NQUlOX0RPVCk7XG4gICAgU19IQVNIX05BTUVfQ09MT05fRE9NQUlOX0RPVC5vbihUVC5ET01BSU4sIFNfSEFTSF9OQU1FX0NPTE9OX0RPTUFJTik7XG4gICAgU19IQVNIX05BTUVfQ09MT05fRE9NQUlOX0RPVC5vbihUVC5UTEQsIFNfUk9PTUFMSUFTKTtcblxuICAgIFNfUk9PTUFMSUFTLm9uKFRULkRPVCwgU19IQVNIX05BTUVfQ09MT05fRE9NQUlOX0RPVCk7IC8vIGFjY2VwdCByZXBlYXRlZCBUTERzIChlLmcgLm9yZy51aylcbiAgICBTX1JPT01BTElBUy5vbihUVC5DT0xPTiwgU19ST09NQUxJQVNfQ09MT04pOyAvLyBkbyBub3QgYWNjZXB0IHRyYWlsaW5nIGA6YFxuICAgIFNfUk9PTUFMSUFTX0NPTE9OLm9uKFRULk5VTSwgU19ST09NQUxJQVNfQ09MT05fTlVNKTsgLy8gYnV0IGRvIGFjY2VwdCA6TlVNIChwb3J0IHNwZWNpZmllcilcblxuXG4gICAgY29uc3QgVVNFUklEID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgTXVsdGlUb2tlbi5jYWxsKHRoaXMsIHZhbHVlKTtcbiAgICAgICAgdGhpcy50eXBlID0gJ3VzZXJpZCc7XG4gICAgICAgIHRoaXMuaXNMaW5rID0gdHJ1ZTtcbiAgICB9O1xuICAgIFVTRVJJRC5wcm90b3R5cGUgPSBuZXcgTXVsdGlUb2tlbigpO1xuXG4gICAgY29uc3QgU19BVCA9IFNfU1RBUlQuanVtcChUVC5BVCk7XG4gICAgY29uc3QgU19BVF9OQU1FID0gbmV3IGxpbmtpZnkucGFyc2VyLlN0YXRlKCk7XG4gICAgY29uc3QgU19BVF9OQU1FX0NPTE9OID0gbmV3IGxpbmtpZnkucGFyc2VyLlN0YXRlKCk7XG4gICAgY29uc3QgU19BVF9OQU1FX0NPTE9OX0RPTUFJTiA9IG5ldyBsaW5raWZ5LnBhcnNlci5TdGF0ZShVU0VSSUQpO1xuICAgIGNvbnN0IFNfQVRfTkFNRV9DT0xPTl9ET01BSU5fRE9UID0gbmV3IGxpbmtpZnkucGFyc2VyLlN0YXRlKCk7XG4gICAgY29uc3QgU19VU0VSSUQgPSBuZXcgbGlua2lmeS5wYXJzZXIuU3RhdGUoVVNFUklEKTtcbiAgICBjb25zdCBTX1VTRVJJRF9DT0xPTiA9IG5ldyBsaW5raWZ5LnBhcnNlci5TdGF0ZSgpO1xuICAgIGNvbnN0IFNfVVNFUklEX0NPTE9OX05VTSA9IG5ldyBsaW5raWZ5LnBhcnNlci5TdGF0ZShVU0VSSUQpO1xuXG4gICAgY29uc3QgdXNlcm5hbWVUb2tlbnMgPSBbXG4gICAgICAgIFRULkRPVCxcbiAgICAgICAgVFQuVU5ERVJTQ09SRSxcbiAgICAgICAgVFQuUExVUyxcbiAgICAgICAgVFQuTlVNLFxuICAgICAgICBUVC5ET01BSU4sXG4gICAgICAgIFRULlRMRCxcblxuICAgICAgICAvLyBhcyBpbiByb29tbmFtZVRva2Vuc1xuICAgICAgICBUVC5MT0NBTEhPU1QsXG4gICAgXTtcblxuICAgIFNfQVQub24odXNlcm5hbWVUb2tlbnMsIFNfQVRfTkFNRSk7XG4gICAgU19BVF9OQU1FLm9uKHVzZXJuYW1lVG9rZW5zLCBTX0FUX05BTUUpO1xuICAgIFNfQVRfTkFNRS5vbihUVC5ET01BSU4sIFNfQVRfTkFNRSk7XG5cbiAgICBTX0FUX05BTUUub24oVFQuQ09MT04sIFNfQVRfTkFNRV9DT0xPTik7XG5cbiAgICBTX0FUX05BTUVfQ09MT04ub24oVFQuRE9NQUlOLCBTX0FUX05BTUVfQ09MT05fRE9NQUlOKTtcbiAgICBTX0FUX05BTUVfQ09MT04ub24oVFQuTE9DQUxIT1NULCBTX1VTRVJJRCk7IC8vIGFjY2VwdCBAZm9vOmxvY2FsaG9zdFxuICAgIFNfQVRfTkFNRV9DT0xPTi5vbihUVC5UTEQsIFNfVVNFUklEKTsgLy8gYWNjZXB0IEBmb286Y29tIChtb3N0bHkgZm9yIChUTER8RE9NQUlOKSsgbWl4aW5nKVxuICAgIFNfQVRfTkFNRV9DT0xPTl9ET01BSU4ub24oVFQuRE9ULCBTX0FUX05BTUVfQ09MT05fRE9NQUlOX0RPVCk7XG4gICAgU19BVF9OQU1FX0NPTE9OX0RPTUFJTl9ET1Qub24oVFQuRE9NQUlOLCBTX0FUX05BTUVfQ09MT05fRE9NQUlOKTtcbiAgICBTX0FUX05BTUVfQ09MT05fRE9NQUlOX0RPVC5vbihUVC5UTEQsIFNfVVNFUklEKTtcblxuICAgIFNfVVNFUklELm9uKFRULkRPVCwgU19BVF9OQU1FX0NPTE9OX0RPTUFJTl9ET1QpOyAvLyBhY2NlcHQgcmVwZWF0ZWQgVExEcyAoZS5nIC5vcmcudWspXG4gICAgU19VU0VSSUQub24oVFQuQ09MT04sIFNfVVNFUklEX0NPTE9OKTsgLy8gZG8gbm90IGFjY2VwdCB0cmFpbGluZyBgOmBcbiAgICBTX1VTRVJJRF9DT0xPTi5vbihUVC5OVU0sIFNfVVNFUklEX0NPTE9OX05VTSk7IC8vIGJ1dCBkbyBhY2NlcHQgOk5VTSAocG9ydCBzcGVjaWZpZXIpXG5cblxuICAgIGNvbnN0IEdST1VQSUQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICBNdWx0aVRva2VuLmNhbGwodGhpcywgdmFsdWUpO1xuICAgICAgICB0aGlzLnR5cGUgPSAnZ3JvdXBpZCc7XG4gICAgICAgIHRoaXMuaXNMaW5rID0gdHJ1ZTtcbiAgICB9O1xuICAgIEdST1VQSUQucHJvdG90eXBlID0gbmV3IE11bHRpVG9rZW4oKTtcblxuICAgIGNvbnN0IFNfUExVUyA9IFNfU1RBUlQuanVtcChUVC5QTFVTKTtcbiAgICBjb25zdCBTX1BMVVNfTkFNRSA9IG5ldyBsaW5raWZ5LnBhcnNlci5TdGF0ZSgpO1xuICAgIGNvbnN0IFNfUExVU19OQU1FX0NPTE9OID0gbmV3IGxpbmtpZnkucGFyc2VyLlN0YXRlKCk7XG4gICAgY29uc3QgU19QTFVTX05BTUVfQ09MT05fRE9NQUlOID0gbmV3IGxpbmtpZnkucGFyc2VyLlN0YXRlKEdST1VQSUQpO1xuICAgIGNvbnN0IFNfUExVU19OQU1FX0NPTE9OX0RPTUFJTl9ET1QgPSBuZXcgbGlua2lmeS5wYXJzZXIuU3RhdGUoKTtcbiAgICBjb25zdCBTX0dST1VQSUQgPSBuZXcgbGlua2lmeS5wYXJzZXIuU3RhdGUoR1JPVVBJRCk7XG4gICAgY29uc3QgU19HUk9VUElEX0NPTE9OID0gbmV3IGxpbmtpZnkucGFyc2VyLlN0YXRlKCk7XG4gICAgY29uc3QgU19HUk9VUElEX0NPTE9OX05VTSA9IG5ldyBsaW5raWZ5LnBhcnNlci5TdGF0ZShHUk9VUElEKTtcblxuICAgIGNvbnN0IGdyb3VwSWRUb2tlbnMgPSBbXG4gICAgICAgIFRULkRPVCxcbiAgICAgICAgVFQuVU5ERVJTQ09SRSxcbiAgICAgICAgVFQuUExVUyxcbiAgICAgICAgVFQuTlVNLFxuICAgICAgICBUVC5ET01BSU4sXG4gICAgICAgIFRULlRMRCxcblxuICAgICAgICAvLyBhcyBpbiByb29tbmFtZVRva2Vuc1xuICAgICAgICBUVC5MT0NBTEhPU1QsXG4gICAgXTtcblxuICAgIFNfUExVUy5vbihncm91cElkVG9rZW5zLCBTX1BMVVNfTkFNRSk7XG4gICAgU19QTFVTX05BTUUub24oZ3JvdXBJZFRva2VucywgU19QTFVTX05BTUUpO1xuICAgIFNfUExVU19OQU1FLm9uKFRULkRPTUFJTiwgU19QTFVTX05BTUUpO1xuXG4gICAgU19QTFVTX05BTUUub24oVFQuQ09MT04sIFNfUExVU19OQU1FX0NPTE9OKTtcblxuICAgIFNfUExVU19OQU1FX0NPTE9OLm9uKFRULkRPTUFJTiwgU19QTFVTX05BTUVfQ09MT05fRE9NQUlOKTtcbiAgICBTX1BMVVNfTkFNRV9DT0xPTi5vbihUVC5MT0NBTEhPU1QsIFNfR1JPVVBJRCk7IC8vIGFjY2VwdCArZm9vOmxvY2FsaG9zdFxuICAgIFNfUExVU19OQU1FX0NPTE9OLm9uKFRULlRMRCwgU19HUk9VUElEKTsgLy8gYWNjZXB0ICtmb286Y29tIChtb3N0bHkgZm9yIChUTER8RE9NQUlOKSsgbWl4aW5nKVxuICAgIFNfUExVU19OQU1FX0NPTE9OX0RPTUFJTi5vbihUVC5ET1QsIFNfUExVU19OQU1FX0NPTE9OX0RPTUFJTl9ET1QpO1xuICAgIFNfUExVU19OQU1FX0NPTE9OX0RPTUFJTl9ET1Qub24oVFQuRE9NQUlOLCBTX1BMVVNfTkFNRV9DT0xPTl9ET01BSU4pO1xuICAgIFNfUExVU19OQU1FX0NPTE9OX0RPTUFJTl9ET1Qub24oVFQuVExELCBTX0dST1VQSUQpO1xuXG4gICAgU19HUk9VUElELm9uKFRULkRPVCwgU19QTFVTX05BTUVfQ09MT05fRE9NQUlOX0RPVCk7IC8vIGFjY2VwdCByZXBlYXRlZCBUTERzIChlLmcgLm9yZy51aylcbiAgICBTX0dST1VQSUQub24oVFQuQ09MT04sIFNfR1JPVVBJRF9DT0xPTik7IC8vIGRvIG5vdCBhY2NlcHQgdHJhaWxpbmcgYDpgXG4gICAgU19HUk9VUElEX0NPTE9OLm9uKFRULk5VTSwgU19HUk9VUElEX0NPTE9OX05VTSk7IC8vIGJ1dCBkbyBhY2NlcHQgOk5VTSAocG9ydCBzcGVjaWZpZXIpXG59XG5cbi8vIHN0dWJzLCBvdmVyd3JpdHRlbiBpbiBNYXRyaXhDaGF0J3MgY29tcG9uZW50RGlkTW91bnRcbm1hdHJpeExpbmtpZnkub25Vc2VyQ2xpY2sgPSBmdW5jdGlvbihlLCB1c2VySWQpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9O1xubWF0cml4TGlua2lmeS5vbkFsaWFzQ2xpY2sgPSBmdW5jdGlvbihlLCByb29tQWxpYXMpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9O1xubWF0cml4TGlua2lmeS5vbkdyb3VwQ2xpY2sgPSBmdW5jdGlvbihlLCBncm91cElkKSB7IGUucHJldmVudERlZmF1bHQoKTsgfTtcblxuY29uc3QgZXNjYXBlUmVnRXhwID0gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgXCJcXFxcJCZcIik7XG59O1xuXG4vLyBSZWNvZ25pc2UgVVJMcyBmcm9tIGJvdGggb3VyIGxvY2FsIGFuZCBvZmZpY2lhbCBFbGVtZW50IGRlcGxveW1lbnRzLlxuLy8gQW55b25lIGVsc2UgcmVhbGx5IHNob3VsZCBiZSB1c2luZyBtYXRyaXgudG8uXG5tYXRyaXhMaW5raWZ5LkVMRU1FTlRfVVJMX1BBVFRFUk4gPVxuICAgIFwiXig/Omh0dHBzPzovLyk/KD86XCIgK1xuICAgICAgICBlc2NhcGVSZWdFeHAod2luZG93LmxvY2F0aW9uLmhvc3QgKyB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUpICsgXCJ8XCIgK1xuICAgICAgICBcIig/Ond3d1xcXFwuKT8oPzpyaW90fHZlY3RvcilcXFxcLmltLyg/OmFwcHxiZXRhfHN0YWdpbmd8ZGV2ZWxvcCkvfFwiICtcbiAgICAgICAgXCIoPzphcHB8YmV0YXxzdGFnaW5nfGRldmVsb3ApXFxcXC5lbGVtZW50XFxcXC5pby9cIiArXG4gICAgXCIpKCMuKilcIjtcblxubWF0cml4TGlua2lmeS5NQVRSSVhUT19VUkxfUEFUVEVSTiA9IFwiXig/Omh0dHBzPzovLyk/KD86d3d3XFxcXC4pP21hdHJpeFxcXFwudG8vIy8oKFsjQCErXSkuKilcIjtcbm1hdHJpeExpbmtpZnkuTUFUUklYVE9fTURfTElOS19QQVRURVJOID1cbiAgICAnXFxcXFsoW15cXFxcXV0qKVxcXFxdXFxcXCgoPzpodHRwcz86Ly8pPyg/Ond3d1xcXFwuKT9tYXRyaXhcXFxcLnRvLyMvKFsjQCErXVteXFxcXCldKilcXFxcKSc7XG5tYXRyaXhMaW5raWZ5Lk1BVFJJWFRPX0JBU0VfVVJMPSBiYXNlVXJsO1xuXG5tYXRyaXhMaW5raWZ5Lm9wdGlvbnMgPSB7XG4gICAgZXZlbnRzOiBmdW5jdGlvbihocmVmLCB0eXBlKSB7XG4gICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgY2FzZSBcInVybFwiOiB7XG4gICAgICAgICAgICAgICAgLy8gaW50ZXJjZXB0IGxvY2FsIHBlcm1hbGlua3MgdG8gdXNlcnMgYW5kIHNob3cgdGhlbSBsaWtlIHVzZXJpZHMgKGluIHVzZXJpbmZvIG9mIGN1cnJlbnQgcm9vbSlcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwZXJtYWxpbmsgPSBwYXJzZVBlcm1hbGluayhocmVmKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBlcm1hbGluayAmJiBwZXJtYWxpbmsudXNlcklkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdHJpeExpbmtpZnkub25Vc2VyQ2xpY2soZSwgcGVybWFsaW5rLnVzZXJJZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE9LIGZpbmUsIGl0J3Mgbm90IGFjdHVhbGx5IGEgcGVybWFsaW5rXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcInVzZXJpZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXhMaW5raWZ5Lm9uVXNlckNsaWNrKGUsIGhyZWYpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjYXNlIFwicm9vbWFsaWFzXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdHJpeExpbmtpZnkub25BbGlhc0NsaWNrKGUsIGhyZWYpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjYXNlIFwiZ3JvdXBpZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXhMaW5raWZ5Lm9uR3JvdXBDbGljayhlLCBocmVmKTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGZvcm1hdEhyZWY6IGZ1bmN0aW9uKGhyZWYsIHR5cGUpIHtcbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICBjYXNlICdyb29tYWxpYXMnOlxuICAgICAgICAgICAgY2FzZSAndXNlcmlkJzpcbiAgICAgICAgICAgIGNhc2UgJ2dyb3VwaWQnOlxuICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnlUcmFuc2Zvcm1FbnRpdHlUb1Blcm1hbGluayhocmVmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBsaW5rQXR0cmlidXRlczoge1xuICAgICAgICByZWw6ICdub3JlZmVycmVyIG5vb3BlbmVyJyxcbiAgICB9LFxuXG4gICAgdGFyZ2V0OiBmdW5jdGlvbihocmVmLCB0eXBlKSB7XG4gICAgICAgIGlmICh0eXBlID09PSAndXJsJykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZCA9IHRyeVRyYW5zZm9ybVBlcm1hbGlua1RvTG9jYWxIcmVmKGhyZWYpO1xuICAgICAgICAgICAgICAgIGlmICh0cmFuc2Zvcm1lZCAhPT0gaHJlZiB8fCBkZWNvZGVVUklDb21wb25lbnQoaHJlZikubWF0Y2gobWF0cml4TGlua2lmeS5FTEVNRU5UX1VSTF9QQVRURVJOKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ19ibGFuayc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIC8vIG1hbGZvcm1lZCBVUklcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgbWF0cml4TGlua2lmeTtcbiJdfQ==