matrix-react-sdk
Version:
SDK for matrix.org using React
223 lines (210 loc) • 30.5 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.editMessage = editMessage;
exports.sendMessage = sendMessage;
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _matrix = require("matrix-js-sdk/src/matrix");
var _PosthogAnalytics = require("../../../../../PosthogAnalytics");
var _SettingsStore = _interopRequireDefault(require("../../../../../settings/SettingsStore"));
var _sendTimePerformanceMetrics = require("../../../../../sendTimePerformanceMetrics");
var _localRoom = require("../../../../../utils/local-room");
var _effects = require("../../../../../effects");
var _utils = require("../../../../../effects/utils");
var _dispatcher = _interopRequireDefault(require("../../../../../dispatcher/dispatcher"));
var _ConfirmRedactDialog = require("../../../dialogs/ConfirmRedactDialog");
var _editing = require("./editing");
var _createMessageContent = require("./createMessageContent");
var _isContentModified = require("./isContentModified");
var _SlashCommands = require("../../../../../SlashCommands");
var _commands = require("../../../../../editor/commands");
var _actions = require("../../../../../dispatcher/actions");
var _Reply = require("../../../../../utils/Reply");
var _SendMessageComposer = require("../../SendMessageComposer");
const _excluded = ["roomContext", "mxClient"];
/*
Copyright 2024 New Vector Ltd.
Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
async function sendMessage(message, isHTML, _ref) {
let {
roomContext,
mxClient
} = _ref,
params = (0, _objectWithoutProperties2.default)(_ref, _excluded);
const {
relation,
replyToEvent,
permalinkCreator
} = params;
const {
room
} = roomContext;
const roomId = room?.roomId;
if (!roomId) {
return;
}
const posthogEvent = {
eventName: "Composer",
isEditing: false,
messageType: "Text",
isReply: Boolean(replyToEvent),
// TODO thread
inThread: relation?.rel_type === _matrix.THREAD_RELATION_TYPE.name
};
// TODO thread
/*if (posthogEvent.inThread) {
const threadRoot = room.findEventById(relation?.event_id);
posthogEvent.startsThread = threadRoot?.getThread()?.events.length === 1;
}*/
_PosthogAnalytics.PosthogAnalytics.instance.trackEvent(posthogEvent);
let content = null;
// Slash command handling here approximates what can be found in SendMessageComposer.sendMessage()
// but note that the /me and // special cases are handled by the call to createMessageContent
if (message.startsWith("/") && !message.startsWith("//") && !message.startsWith(_createMessageContent.EMOTE_PREFIX)) {
const {
cmd,
args
} = (0, _SlashCommands.getCommand)(message);
if (cmd) {
const threadId = relation?.rel_type === _matrix.THREAD_RELATION_TYPE.name ? relation?.event_id : null;
let commandSuccessful;
[content, commandSuccessful] = await (0, _commands.runSlashCommand)(mxClient, cmd, args, roomId, threadId ?? null);
if (!commandSuccessful) {
return; // errored
}
if (content && (cmd.category === _SlashCommands.CommandCategories.messages || cmd.category === _SlashCommands.CommandCategories.effects)) {
(0, _SendMessageComposer.attachRelation)(content, relation);
if (replyToEvent) {
(0, _Reply.addReplyToMessageContent)(content, replyToEvent, {
permalinkCreator,
// Exclude the legacy fallback for custom event types such as those used by /fireworks
includeLegacyFallback: content.msgtype?.startsWith("m.") ?? true
});
}
} else {
// instead of setting shouldSend to false as in SendMessageComposer, just return
return;
}
} else {
const sendAnyway = await (0, _commands.shouldSendAnyway)(message);
// re-focus the composer after QuestionDialog is closed
_dispatcher.default.dispatch({
action: _actions.Action.FocusAComposer,
context: roomContext.timelineRenderingType
});
// if !sendAnyway bail to let the user edit the composer and try again
if (!sendAnyway) return;
}
}
// if content is null, we haven't done any slash command processing, so generate some content
content ??= await (0, _createMessageContent.createMessageContent)(message, isHTML, params);
// TODO replace emotion end of message ?
// TODO quick reaction
// don't bother sending an empty message
if (!content.body.trim()) {
return;
}
if (_SettingsStore.default.getValue("Performance.addSendMessageTimingMetadata")) {
(0, _sendTimePerformanceMetrics.decorateStartSendingTime)(content);
}
const threadId = relation?.event_id && relation?.rel_type === _matrix.THREAD_RELATION_TYPE.name ? relation.event_id : null;
const prom = (0, _localRoom.doMaybeLocalRoomAction)(roomId, actualRoomId => mxClient.sendMessage(actualRoomId, threadId, content), mxClient);
if (replyToEvent) {
// Clear reply_to_event as we put the message into the queue
// if the send fails, retry will handle resending.
_dispatcher.default.dispatch({
action: "reply_to_event",
event: null,
context: roomContext.timelineRenderingType
});
}
_dispatcher.default.dispatch({
action: "message_sent"
});
_effects.CHAT_EFFECTS.forEach(effect => {
if (content && (0, _utils.containsEmoji)(content, effect.emojis)) {
// For initial threads launch, chat effects are disabled
// see #19731
const isNotThread = relation?.rel_type !== _matrix.THREAD_RELATION_TYPE.name;
if (isNotThread) {
_dispatcher.default.dispatch({
action: `effects.${effect.command}`
});
}
}
});
if (_SettingsStore.default.getValue("Performance.addSendMessageTimingMetadata")) {
prom.then(resp => {
(0, _sendTimePerformanceMetrics.sendRoundTripMetric)(mxClient, roomId, resp.event_id);
});
}
// TODO save history
// TODO save local state
//if (shouldSend && SettingsStore.getValue("scrollToBottomOnMessageSent")) {
if (_SettingsStore.default.getValue("scrollToBottomOnMessageSent")) {
_dispatcher.default.dispatch({
action: "scroll_to_bottom",
timelineRenderingType: roomContext.timelineRenderingType
});
}
return prom;
}
async function editMessage(html, {
roomContext,
mxClient,
editorStateTransfer
}) {
const editedEvent = editorStateTransfer.getEvent();
_PosthogAnalytics.PosthogAnalytics.instance.trackEvent({
eventName: "Composer",
isEditing: true,
messageType: "Text",
inThread: Boolean(editedEvent?.getThread()),
isReply: Boolean(editedEvent.replyEventId)
});
// TODO emoji
// Replace emoticon at the end of the message
/* if (SettingsStore.getValue('MessageComposerInput.autoReplaceEmoji')) {
const caret = this.editorRef.current?.getCaret();
const position = this.model.positionForOffset(caret.offset, caret.atNodeEnd);
this.editorRef.current?.replaceEmoticon(position, REGEX_EMOTICON);
}*/
const editContent = await (0, _createMessageContent.createMessageContent)(html, true, {
editedEvent
});
const newContent = editContent["m.new_content"];
const shouldSend = true;
if (newContent?.body === "") {
(0, _editing.cancelPreviousPendingEdit)(mxClient, editorStateTransfer);
(0, _ConfirmRedactDialog.createRedactEventDialog)({
mxEvent: editedEvent,
onCloseDialog: () => {
(0, _editing.endEditing)(roomContext);
}
});
return;
}
let response;
const roomId = editedEvent.getRoomId();
// If content is modified then send an updated event into the room
if ((0, _isContentModified.isContentModified)(newContent, editorStateTransfer) && roomId) {
// TODO Slash Commands
if (shouldSend) {
(0, _editing.cancelPreviousPendingEdit)(mxClient, editorStateTransfer);
const event = editorStateTransfer.getEvent();
const threadId = event.threadRootId || null;
response = mxClient.sendMessage(roomId, threadId, editContent);
_dispatcher.default.dispatch({
action: "message_sent"
});
}
}
(0, _editing.endEditing)(roomContext);
return response;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbWF0cml4IiwicmVxdWlyZSIsIl9Qb3N0aG9nQW5hbHl0aWNzIiwiX1NldHRpbmdzU3RvcmUiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX3NlbmRUaW1lUGVyZm9ybWFuY2VNZXRyaWNzIiwiX2xvY2FsUm9vbSIsIl9lZmZlY3RzIiwiX3V0aWxzIiwiX2Rpc3BhdGNoZXIiLCJfQ29uZmlybVJlZGFjdERpYWxvZyIsIl9lZGl0aW5nIiwiX2NyZWF0ZU1lc3NhZ2VDb250ZW50IiwiX2lzQ29udGVudE1vZGlmaWVkIiwiX1NsYXNoQ29tbWFuZHMiLCJfY29tbWFuZHMiLCJfYWN0aW9ucyIsIl9SZXBseSIsIl9TZW5kTWVzc2FnZUNvbXBvc2VyIiwiX2V4Y2x1ZGVkIiwic2VuZE1lc3NhZ2UiLCJtZXNzYWdlIiwiaXNIVE1MIiwiX3JlZiIsInJvb21Db250ZXh0IiwibXhDbGllbnQiLCJwYXJhbXMiLCJfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMyIiwiZGVmYXVsdCIsInJlbGF0aW9uIiwicmVwbHlUb0V2ZW50IiwicGVybWFsaW5rQ3JlYXRvciIsInJvb20iLCJyb29tSWQiLCJwb3N0aG9nRXZlbnQiLCJldmVudE5hbWUiLCJpc0VkaXRpbmciLCJtZXNzYWdlVHlwZSIsImlzUmVwbHkiLCJCb29sZWFuIiwiaW5UaHJlYWQiLCJyZWxfdHlwZSIsIlRIUkVBRF9SRUxBVElPTl9UWVBFIiwibmFtZSIsIlBvc3Rob2dBbmFseXRpY3MiLCJpbnN0YW5jZSIsInRyYWNrRXZlbnQiLCJjb250ZW50Iiwic3RhcnRzV2l0aCIsIkVNT1RFX1BSRUZJWCIsImNtZCIsImFyZ3MiLCJnZXRDb21tYW5kIiwidGhyZWFkSWQiLCJldmVudF9pZCIsImNvbW1hbmRTdWNjZXNzZnVsIiwicnVuU2xhc2hDb21tYW5kIiwiY2F0ZWdvcnkiLCJDb21tYW5kQ2F0ZWdvcmllcyIsIm1lc3NhZ2VzIiwiZWZmZWN0cyIsImF0dGFjaFJlbGF0aW9uIiwiYWRkUmVwbHlUb01lc3NhZ2VDb250ZW50IiwiaW5jbHVkZUxlZ2FjeUZhbGxiYWNrIiwibXNndHlwZSIsInNlbmRBbnl3YXkiLCJzaG91bGRTZW5kQW55d2F5IiwiZGlzIiwiZGlzcGF0Y2giLCJhY3Rpb24iLCJBY3Rpb24iLCJGb2N1c0FDb21wb3NlciIsImNvbnRleHQiLCJ0aW1lbGluZVJlbmRlcmluZ1R5cGUiLCJjcmVhdGVNZXNzYWdlQ29udGVudCIsImJvZHkiLCJ0cmltIiwiU2V0dGluZ3NTdG9yZSIsImdldFZhbHVlIiwiZGVjb3JhdGVTdGFydFNlbmRpbmdUaW1lIiwicHJvbSIsImRvTWF5YmVMb2NhbFJvb21BY3Rpb24iLCJhY3R1YWxSb29tSWQiLCJldmVudCIsIkNIQVRfRUZGRUNUUyIsImZvckVhY2giLCJlZmZlY3QiLCJjb250YWluc0Vtb2ppIiwiZW1vamlzIiwiaXNOb3RUaHJlYWQiLCJjb21tYW5kIiwidGhlbiIsInJlc3AiLCJzZW5kUm91bmRUcmlwTWV0cmljIiwiZWRpdE1lc3NhZ2UiLCJodG1sIiwiZWRpdG9yU3RhdGVUcmFuc2ZlciIsImVkaXRlZEV2ZW50IiwiZ2V0RXZlbnQiLCJnZXRUaHJlYWQiLCJyZXBseUV2ZW50SWQiLCJlZGl0Q29udGVudCIsIm5ld0NvbnRlbnQiLCJzaG91bGRTZW5kIiwiY2FuY2VsUHJldmlvdXNQZW5kaW5nRWRpdCIsImNyZWF0ZVJlZGFjdEV2ZW50RGlhbG9nIiwibXhFdmVudCIsIm9uQ2xvc2VEaWFsb2ciLCJlbmRFZGl0aW5nIiwicmVzcG9uc2UiLCJnZXRSb29tSWQiLCJpc0NvbnRlbnRNb2RpZmllZCIsInRocmVhZFJvb3RJZCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3Jvb21zL3d5c2l3eWdfY29tcG9zZXIvdXRpbHMvbWVzc2FnZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IDIwMjQgTmV3IFZlY3RvciBMdGQuXG5Db3B5cmlnaHQgMjAyMiwgMjAyMyBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgeyBDb21wb3NlciBhcyBDb21wb3NlckV2ZW50IH0gZnJvbSBcIkBtYXRyaXgtb3JnL2FuYWx5dGljcy1ldmVudHMvdHlwZXMvdHlwZXNjcmlwdC9Db21wb3NlclwiO1xuaW1wb3J0IHtcbiAgICBJRXZlbnRSZWxhdGlvbixcbiAgICBNYXRyaXhFdmVudCxcbiAgICBJU2VuZEV2ZW50UmVzcG9uc2UsXG4gICAgTWF0cml4Q2xpZW50LFxuICAgIFRIUkVBRF9SRUxBVElPTl9UWVBFLFxufSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgeyBSb29tTWVzc2FnZUV2ZW50Q29udGVudCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy90eXBlc1wiO1xuXG5pbXBvcnQgeyBQb3N0aG9nQW5hbHl0aWNzIH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL1Bvc3Rob2dBbmFseXRpY3NcIjtcbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gXCIuLi8uLi8uLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgeyBkZWNvcmF0ZVN0YXJ0U2VuZGluZ1RpbWUsIHNlbmRSb3VuZFRyaXBNZXRyaWMgfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vc2VuZFRpbWVQZXJmb3JtYW5jZU1ldHJpY3NcIjtcbmltcG9ydCB7IFJvb21QZXJtYWxpbmtDcmVhdG9yIH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL3V0aWxzL3Blcm1hbGlua3MvUGVybWFsaW5rc1wiO1xuaW1wb3J0IHsgZG9NYXliZUxvY2FsUm9vbUFjdGlvbiB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi91dGlscy9sb2NhbC1yb29tXCI7XG5pbXBvcnQgeyBDSEFUX0VGRkVDVFMgfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vZWZmZWN0c1wiO1xuaW1wb3J0IHsgY29udGFpbnNFbW9qaSB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9lZmZlY3RzL3V0aWxzXCI7XG5pbXBvcnQgeyBJUm9vbVN0YXRlIH0gZnJvbSBcIi4uLy4uLy4uLy4uL3N0cnVjdHVyZXMvUm9vbVZpZXdcIjtcbmltcG9ydCBkaXMgZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2Rpc3BhdGNoZXIvZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgY3JlYXRlUmVkYWN0RXZlbnREaWFsb2cgfSBmcm9tIFwiLi4vLi4vLi4vZGlhbG9ncy9Db25maXJtUmVkYWN0RGlhbG9nXCI7XG5pbXBvcnQgeyBlbmRFZGl0aW5nLCBjYW5jZWxQcmV2aW91c1BlbmRpbmdFZGl0IH0gZnJvbSBcIi4vZWRpdGluZ1wiO1xuaW1wb3J0IEVkaXRvclN0YXRlVHJhbnNmZXIgZnJvbSBcIi4uLy4uLy4uLy4uLy4uL3V0aWxzL0VkaXRvclN0YXRlVHJhbnNmZXJcIjtcbmltcG9ydCB7IGNyZWF0ZU1lc3NhZ2VDb250ZW50LCBFTU9URV9QUkVGSVggfSBmcm9tIFwiLi9jcmVhdGVNZXNzYWdlQ29udGVudFwiO1xuaW1wb3J0IHsgaXNDb250ZW50TW9kaWZpZWQgfSBmcm9tIFwiLi9pc0NvbnRlbnRNb2RpZmllZFwiO1xuaW1wb3J0IHsgQ29tbWFuZENhdGVnb3JpZXMsIGdldENvbW1hbmQgfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vU2xhc2hDb21tYW5kc1wiO1xuaW1wb3J0IHsgcnVuU2xhc2hDb21tYW5kLCBzaG91bGRTZW5kQW55d2F5IH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2VkaXRvci9jb21tYW5kc1wiO1xuaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2Rpc3BhdGNoZXIvYWN0aW9uc1wiO1xuaW1wb3J0IHsgYWRkUmVwbHlUb01lc3NhZ2VDb250ZW50IH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL3V0aWxzL1JlcGx5XCI7XG5pbXBvcnQgeyBhdHRhY2hSZWxhdGlvbiB9IGZyb20gXCIuLi8uLi9TZW5kTWVzc2FnZUNvbXBvc2VyXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VuZE1lc3NhZ2VQYXJhbXMge1xuICAgIG14Q2xpZW50OiBNYXRyaXhDbGllbnQ7XG4gICAgcmVsYXRpb24/OiBJRXZlbnRSZWxhdGlvbjtcbiAgICByZXBseVRvRXZlbnQ/OiBNYXRyaXhFdmVudDtcbiAgICByb29tQ29udGV4dDogSVJvb21TdGF0ZTtcbiAgICBwZXJtYWxpbmtDcmVhdG9yPzogUm9vbVBlcm1hbGlua0NyZWF0b3I7XG4gICAgaW5jbHVkZVJlcGx5TGVnYWN5RmFsbGJhY2s/OiBib29sZWFuO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2VuZE1lc3NhZ2UoXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIGlzSFRNTDogYm9vbGVhbixcbiAgICB7IHJvb21Db250ZXh0LCBteENsaWVudCwgLi4ucGFyYW1zIH06IFNlbmRNZXNzYWdlUGFyYW1zLFxuKTogUHJvbWlzZTxJU2VuZEV2ZW50UmVzcG9uc2UgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCB7IHJlbGF0aW9uLCByZXBseVRvRXZlbnQsIHBlcm1hbGlua0NyZWF0b3IgfSA9IHBhcmFtcztcbiAgICBjb25zdCB7IHJvb20gfSA9IHJvb21Db250ZXh0O1xuICAgIGNvbnN0IHJvb21JZCA9IHJvb20/LnJvb21JZDtcblxuICAgIGlmICghcm9vbUlkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwb3N0aG9nRXZlbnQ6IENvbXBvc2VyRXZlbnQgPSB7XG4gICAgICAgIGV2ZW50TmFtZTogXCJDb21wb3NlclwiLFxuICAgICAgICBpc0VkaXRpbmc6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlVHlwZTogXCJUZXh0XCIsXG4gICAgICAgIGlzUmVwbHk6IEJvb2xlYW4ocmVwbHlUb0V2ZW50KSxcbiAgICAgICAgLy8gVE9ETyB0aHJlYWRcbiAgICAgICAgaW5UaHJlYWQ6IHJlbGF0aW9uPy5yZWxfdHlwZSA9PT0gVEhSRUFEX1JFTEFUSU9OX1RZUEUubmFtZSxcbiAgICB9O1xuXG4gICAgLy8gVE9ETyB0aHJlYWRcbiAgICAvKmlmIChwb3N0aG9nRXZlbnQuaW5UaHJlYWQpIHtcbiAgICAgICAgY29uc3QgdGhyZWFkUm9vdCA9IHJvb20uZmluZEV2ZW50QnlJZChyZWxhdGlvbj8uZXZlbnRfaWQpO1xuICAgICAgICBwb3N0aG9nRXZlbnQuc3RhcnRzVGhyZWFkID0gdGhyZWFkUm9vdD8uZ2V0VGhyZWFkKCk/LmV2ZW50cy5sZW5ndGggPT09IDE7XG4gICAgfSovXG4gICAgUG9zdGhvZ0FuYWx5dGljcy5pbnN0YW5jZS50cmFja0V2ZW50PENvbXBvc2VyRXZlbnQ+KHBvc3Rob2dFdmVudCk7XG5cbiAgICBsZXQgY29udGVudDogUm9vbU1lc3NhZ2VFdmVudENvbnRlbnQgfCBudWxsID0gbnVsbDtcblxuICAgIC8vIFNsYXNoIGNvbW1hbmQgaGFuZGxpbmcgaGVyZSBhcHByb3hpbWF0ZXMgd2hhdCBjYW4gYmUgZm91bmQgaW4gU2VuZE1lc3NhZ2VDb21wb3Nlci5zZW5kTWVzc2FnZSgpXG4gICAgLy8gYnV0IG5vdGUgdGhhdCB0aGUgL21lIGFuZCAvLyBzcGVjaWFsIGNhc2VzIGFyZSBoYW5kbGVkIGJ5IHRoZSBjYWxsIHRvIGNyZWF0ZU1lc3NhZ2VDb250ZW50XG4gICAgaWYgKG1lc3NhZ2Uuc3RhcnRzV2l0aChcIi9cIikgJiYgIW1lc3NhZ2Uuc3RhcnRzV2l0aChcIi8vXCIpICYmICFtZXNzYWdlLnN0YXJ0c1dpdGgoRU1PVEVfUFJFRklYKSkge1xuICAgICAgICBjb25zdCB7IGNtZCwgYXJncyB9ID0gZ2V0Q29tbWFuZChtZXNzYWdlKTtcbiAgICAgICAgaWYgKGNtZCkge1xuICAgICAgICAgICAgY29uc3QgdGhyZWFkSWQgPSByZWxhdGlvbj8ucmVsX3R5cGUgPT09IFRIUkVBRF9SRUxBVElPTl9UWVBFLm5hbWUgPyByZWxhdGlvbj8uZXZlbnRfaWQgOiBudWxsO1xuICAgICAgICAgICAgbGV0IGNvbW1hbmRTdWNjZXNzZnVsOiBib29sZWFuO1xuICAgICAgICAgICAgW2NvbnRlbnQsIGNvbW1hbmRTdWNjZXNzZnVsXSA9IGF3YWl0IHJ1blNsYXNoQ29tbWFuZChteENsaWVudCwgY21kLCBhcmdzLCByb29tSWQsIHRocmVhZElkID8/IG51bGwpO1xuXG4gICAgICAgICAgICBpZiAoIWNvbW1hbmRTdWNjZXNzZnVsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBlcnJvcmVkXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBjb250ZW50ICYmXG4gICAgICAgICAgICAgICAgKGNtZC5jYXRlZ29yeSA9PT0gQ29tbWFuZENhdGVnb3JpZXMubWVzc2FnZXMgfHwgY21kLmNhdGVnb3J5ID09PSBDb21tYW5kQ2F0ZWdvcmllcy5lZmZlY3RzKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgYXR0YWNoUmVsYXRpb24oY29udGVudCwgcmVsYXRpb24pO1xuICAgICAgICAgICAgICAgIGlmIChyZXBseVRvRXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgYWRkUmVwbHlUb01lc3NhZ2VDb250ZW50KGNvbnRlbnQsIHJlcGx5VG9FdmVudCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGVybWFsaW5rQ3JlYXRvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4Y2x1ZGUgdGhlIGxlZ2FjeSBmYWxsYmFjayBmb3IgY3VzdG9tIGV2ZW50IHR5cGVzIHN1Y2ggYXMgdGhvc2UgdXNlZCBieSAvZmlyZXdvcmtzXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmNsdWRlTGVnYWN5RmFsbGJhY2s6IGNvbnRlbnQubXNndHlwZT8uc3RhcnRzV2l0aChcIm0uXCIpID8/IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gaW5zdGVhZCBvZiBzZXR0aW5nIHNob3VsZFNlbmQgdG8gZmFsc2UgYXMgaW4gU2VuZE1lc3NhZ2VDb21wb3NlciwganVzdCByZXR1cm5cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzZW5kQW55d2F5ID0gYXdhaXQgc2hvdWxkU2VuZEFueXdheShtZXNzYWdlKTtcbiAgICAgICAgICAgIC8vIHJlLWZvY3VzIHRoZSBjb21wb3NlciBhZnRlciBRdWVzdGlvbkRpYWxvZyBpcyBjbG9zZWRcbiAgICAgICAgICAgIGRpcy5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiBBY3Rpb24uRm9jdXNBQ29tcG9zZXIsXG4gICAgICAgICAgICAgICAgY29udGV4dDogcm9vbUNvbnRleHQudGltZWxpbmVSZW5kZXJpbmdUeXBlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBpZiAhc2VuZEFueXdheSBiYWlsIHRvIGxldCB0aGUgdXNlciBlZGl0IHRoZSBjb21wb3NlciBhbmQgdHJ5IGFnYWluXG4gICAgICAgICAgICBpZiAoIXNlbmRBbnl3YXkpIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIGlmIGNvbnRlbnQgaXMgbnVsbCwgd2UgaGF2ZW4ndCBkb25lIGFueSBzbGFzaCBjb21tYW5kIHByb2Nlc3NpbmcsIHNvIGdlbmVyYXRlIHNvbWUgY29udGVudFxuICAgIGNvbnRlbnQgPz89IGF3YWl0IGNyZWF0ZU1lc3NhZ2VDb250ZW50KG1lc3NhZ2UsIGlzSFRNTCwgcGFyYW1zKTtcblxuICAgIC8vIFRPRE8gcmVwbGFjZSBlbW90aW9uIGVuZCBvZiBtZXNzYWdlID9cblxuICAgIC8vIFRPRE8gcXVpY2sgcmVhY3Rpb25cblxuICAgIC8vIGRvbid0IGJvdGhlciBzZW5kaW5nIGFuIGVtcHR5IG1lc3NhZ2VcbiAgICBpZiAoIWNvbnRlbnQuYm9keS50cmltKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFwiUGVyZm9ybWFuY2UuYWRkU2VuZE1lc3NhZ2VUaW1pbmdNZXRhZGF0YVwiKSkge1xuICAgICAgICBkZWNvcmF0ZVN0YXJ0U2VuZGluZ1RpbWUoY29udGVudCk7XG4gICAgfVxuXG4gICAgY29uc3QgdGhyZWFkSWQgPSByZWxhdGlvbj8uZXZlbnRfaWQgJiYgcmVsYXRpb24/LnJlbF90eXBlID09PSBUSFJFQURfUkVMQVRJT05fVFlQRS5uYW1lID8gcmVsYXRpb24uZXZlbnRfaWQgOiBudWxsO1xuXG4gICAgY29uc3QgcHJvbSA9IGRvTWF5YmVMb2NhbFJvb21BY3Rpb24oXG4gICAgICAgIHJvb21JZCxcbiAgICAgICAgKGFjdHVhbFJvb21JZDogc3RyaW5nKSA9PiBteENsaWVudC5zZW5kTWVzc2FnZShhY3R1YWxSb29tSWQsIHRocmVhZElkLCBjb250ZW50ISksXG4gICAgICAgIG14Q2xpZW50LFxuICAgICk7XG5cbiAgICBpZiAocmVwbHlUb0V2ZW50KSB7XG4gICAgICAgIC8vIENsZWFyIHJlcGx5X3RvX2V2ZW50IGFzIHdlIHB1dCB0aGUgbWVzc2FnZSBpbnRvIHRoZSBxdWV1ZVxuICAgICAgICAvLyBpZiB0aGUgc2VuZCBmYWlscywgcmV0cnkgd2lsbCBoYW5kbGUgcmVzZW5kaW5nLlxuICAgICAgICBkaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgYWN0aW9uOiBcInJlcGx5X3RvX2V2ZW50XCIsXG4gICAgICAgICAgICBldmVudDogbnVsbCxcbiAgICAgICAgICAgIGNvbnRleHQ6IHJvb21Db250ZXh0LnRpbWVsaW5lUmVuZGVyaW5nVHlwZSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZGlzLmRpc3BhdGNoKHsgYWN0aW9uOiBcIm1lc3NhZ2Vfc2VudFwiIH0pO1xuICAgIENIQVRfRUZGRUNUUy5mb3JFYWNoKChlZmZlY3QpID0+IHtcbiAgICAgICAgaWYgKGNvbnRlbnQgJiYgY29udGFpbnNFbW9qaShjb250ZW50LCBlZmZlY3QuZW1vamlzKSkge1xuICAgICAgICAgICAgLy8gRm9yIGluaXRpYWwgdGhyZWFkcyBsYXVuY2gsIGNoYXQgZWZmZWN0cyBhcmUgZGlzYWJsZWRcbiAgICAgICAgICAgIC8vIHNlZSAjMTk3MzFcbiAgICAgICAgICAgIGNvbnN0IGlzTm90VGhyZWFkID0gcmVsYXRpb24/LnJlbF90eXBlICE9PSBUSFJFQURfUkVMQVRJT05fVFlQRS5uYW1lO1xuICAgICAgICAgICAgaWYgKGlzTm90VGhyZWFkKSB7XG4gICAgICAgICAgICAgICAgZGlzLmRpc3BhdGNoKHsgYWN0aW9uOiBgZWZmZWN0cy4ke2VmZmVjdC5jb21tYW5kfWAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcIlBlcmZvcm1hbmNlLmFkZFNlbmRNZXNzYWdlVGltaW5nTWV0YWRhdGFcIikpIHtcbiAgICAgICAgcHJvbS50aGVuKChyZXNwKSA9PiB7XG4gICAgICAgICAgICBzZW5kUm91bmRUcmlwTWV0cmljKG14Q2xpZW50LCByb29tSWQsIHJlc3AuZXZlbnRfaWQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBUT0RPIHNhdmUgaGlzdG9yeVxuICAgIC8vIFRPRE8gc2F2ZSBsb2NhbCBzdGF0ZVxuXG4gICAgLy9pZiAoc2hvdWxkU2VuZCAmJiBTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFwic2Nyb2xsVG9Cb3R0b21Pbk1lc3NhZ2VTZW50XCIpKSB7XG4gICAgaWYgKFNldHRpbmdzU3RvcmUuZ2V0VmFsdWUoXCJzY3JvbGxUb0JvdHRvbU9uTWVzc2FnZVNlbnRcIikpIHtcbiAgICAgICAgZGlzLmRpc3BhdGNoKHtcbiAgICAgICAgICAgIGFjdGlvbjogXCJzY3JvbGxfdG9fYm90dG9tXCIsXG4gICAgICAgICAgICB0aW1lbGluZVJlbmRlcmluZ1R5cGU6IHJvb21Db250ZXh0LnRpbWVsaW5lUmVuZGVyaW5nVHlwZSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb207XG59XG5cbmludGVyZmFjZSBFZGl0TWVzc2FnZVBhcmFtcyB7XG4gICAgbXhDbGllbnQ6IE1hdHJpeENsaWVudDtcbiAgICByb29tQ29udGV4dDogSVJvb21TdGF0ZTtcbiAgICBlZGl0b3JTdGF0ZVRyYW5zZmVyOiBFZGl0b3JTdGF0ZVRyYW5zZmVyO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZWRpdE1lc3NhZ2UoXG4gICAgaHRtbDogc3RyaW5nLFxuICAgIHsgcm9vbUNvbnRleHQsIG14Q2xpZW50LCBlZGl0b3JTdGF0ZVRyYW5zZmVyIH06IEVkaXRNZXNzYWdlUGFyYW1zLFxuKTogUHJvbWlzZTxJU2VuZEV2ZW50UmVzcG9uc2UgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBlZGl0ZWRFdmVudCA9IGVkaXRvclN0YXRlVHJhbnNmZXIuZ2V0RXZlbnQoKTtcblxuICAgIFBvc3Rob2dBbmFseXRpY3MuaW5zdGFuY2UudHJhY2tFdmVudDxDb21wb3NlckV2ZW50Pih7XG4gICAgICAgIGV2ZW50TmFtZTogXCJDb21wb3NlclwiLFxuICAgICAgICBpc0VkaXRpbmc6IHRydWUsXG4gICAgICAgIG1lc3NhZ2VUeXBlOiBcIlRleHRcIixcbiAgICAgICAgaW5UaHJlYWQ6IEJvb2xlYW4oZWRpdGVkRXZlbnQ/LmdldFRocmVhZCgpKSxcbiAgICAgICAgaXNSZXBseTogQm9vbGVhbihlZGl0ZWRFdmVudC5yZXBseUV2ZW50SWQpLFxuICAgIH0pO1xuXG4gICAgLy8gVE9ETyBlbW9qaVxuICAgIC8vIFJlcGxhY2UgZW1vdGljb24gYXQgdGhlIGVuZCBvZiB0aGUgbWVzc2FnZVxuICAgIC8qICAgIGlmIChTZXR0aW5nc1N0b3JlLmdldFZhbHVlKCdNZXNzYWdlQ29tcG9zZXJJbnB1dC5hdXRvUmVwbGFjZUVtb2ppJykpIHtcbiAgICAgICAgY29uc3QgY2FyZXQgPSB0aGlzLmVkaXRvclJlZi5jdXJyZW50Py5nZXRDYXJldCgpO1xuICAgICAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMubW9kZWwucG9zaXRpb25Gb3JPZmZzZXQoY2FyZXQub2Zmc2V0LCBjYXJldC5hdE5vZGVFbmQpO1xuICAgICAgICB0aGlzLmVkaXRvclJlZi5jdXJyZW50Py5yZXBsYWNlRW1vdGljb24ocG9zaXRpb24sIFJFR0VYX0VNT1RJQ09OKTtcbiAgICB9Ki9cbiAgICBjb25zdCBlZGl0Q29udGVudCA9IGF3YWl0IGNyZWF0ZU1lc3NhZ2VDb250ZW50KGh0bWwsIHRydWUsIHsgZWRpdGVkRXZlbnQgfSk7XG4gICAgY29uc3QgbmV3Q29udGVudCA9IGVkaXRDb250ZW50W1wibS5uZXdfY29udGVudFwiXSE7XG5cbiAgICBjb25zdCBzaG91bGRTZW5kID0gdHJ1ZTtcblxuICAgIGlmIChuZXdDb250ZW50Py5ib2R5ID09PSBcIlwiKSB7XG4gICAgICAgIGNhbmNlbFByZXZpb3VzUGVuZGluZ0VkaXQobXhDbGllbnQsIGVkaXRvclN0YXRlVHJhbnNmZXIpO1xuICAgICAgICBjcmVhdGVSZWRhY3RFdmVudERpYWxvZyh7XG4gICAgICAgICAgICBteEV2ZW50OiBlZGl0ZWRFdmVudCxcbiAgICAgICAgICAgIG9uQ2xvc2VEaWFsb2c6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBlbmRFZGl0aW5nKHJvb21Db250ZXh0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHJlc3BvbnNlOiBQcm9taXNlPElTZW5kRXZlbnRSZXNwb25zZT4gfCB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCByb29tSWQgPSBlZGl0ZWRFdmVudC5nZXRSb29tSWQoKTtcblxuICAgIC8vIElmIGNvbnRlbnQgaXMgbW9kaWZpZWQgdGhlbiBzZW5kIGFuIHVwZGF0ZWQgZXZlbnQgaW50byB0aGUgcm9vbVxuICAgIGlmIChpc0NvbnRlbnRNb2RpZmllZChuZXdDb250ZW50LCBlZGl0b3JTdGF0ZVRyYW5zZmVyKSAmJiByb29tSWQpIHtcbiAgICAgICAgLy8gVE9ETyBTbGFzaCBDb21tYW5kc1xuXG4gICAgICAgIGlmIChzaG91bGRTZW5kKSB7XG4gICAgICAgICAgICBjYW5jZWxQcmV2aW91c1BlbmRpbmdFZGl0KG14Q2xpZW50LCBlZGl0b3JTdGF0ZVRyYW5zZmVyKTtcblxuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSBlZGl0b3JTdGF0ZVRyYW5zZmVyLmdldEV2ZW50KCk7XG4gICAgICAgICAgICBjb25zdCB0aHJlYWRJZCA9IGV2ZW50LnRocmVhZFJvb3RJZCB8fCBudWxsO1xuXG4gICAgICAgICAgICByZXNwb25zZSA9IG14Q2xpZW50LnNlbmRNZXNzYWdlKHJvb21JZCwgdGhyZWFkSWQsIGVkaXRDb250ZW50KTtcbiAgICAgICAgICAgIGRpcy5kaXNwYXRjaCh7IGFjdGlvbjogXCJtZXNzYWdlX3NlbnRcIiB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGVuZEVkaXRpbmcocm9vbUNvbnRleHQpO1xuICAgIHJldHVybiByZXNwb25zZTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBU0EsSUFBQUEsT0FBQSxHQUFBQyxPQUFBO0FBU0EsSUFBQUMsaUJBQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLGNBQUEsR0FBQUMsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFJLDJCQUFBLEdBQUFKLE9BQUE7QUFFQSxJQUFBSyxVQUFBLEdBQUFMLE9BQUE7QUFDQSxJQUFBTSxRQUFBLEdBQUFOLE9BQUE7QUFDQSxJQUFBTyxNQUFBLEdBQUFQLE9BQUE7QUFFQSxJQUFBUSxXQUFBLEdBQUFMLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBUyxvQkFBQSxHQUFBVCxPQUFBO0FBQ0EsSUFBQVUsUUFBQSxHQUFBVixPQUFBO0FBRUEsSUFBQVcscUJBQUEsR0FBQVgsT0FBQTtBQUNBLElBQUFZLGtCQUFBLEdBQUFaLE9BQUE7QUFDQSxJQUFBYSxjQUFBLEdBQUFiLE9BQUE7QUFDQSxJQUFBYyxTQUFBLEdBQUFkLE9BQUE7QUFDQSxJQUFBZSxRQUFBLEdBQUFmLE9BQUE7QUFDQSxJQUFBZ0IsTUFBQSxHQUFBaEIsT0FBQTtBQUNBLElBQUFpQixvQkFBQSxHQUFBakIsT0FBQTtBQUEyRCxNQUFBa0IsU0FBQTtBQXBDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF5Q08sZUFBZUMsV0FBV0EsQ0FDN0JDLE9BQWUsRUFDZkMsTUFBZSxFQUFBQyxJQUFBLEVBRXdCO0VBQUEsSUFEdkM7TUFBRUMsV0FBVztNQUFFQztJQUF1QyxDQUFDLEdBQUFGLElBQUE7SUFBM0JHLE1BQU0sT0FBQUMseUJBQUEsQ0FBQUMsT0FBQSxFQUFBTCxJQUFBLEVBQUFKLFNBQUE7RUFFbEMsTUFBTTtJQUFFVSxRQUFRO0lBQUVDLFlBQVk7SUFBRUM7RUFBaUIsQ0FBQyxHQUFHTCxNQUFNO0VBQzNELE1BQU07SUFBRU07RUFBSyxDQUFDLEdBQUdSLFdBQVc7RUFDNUIsTUFBTVMsTUFBTSxHQUFHRCxJQUFJLEVBQUVDLE1BQU07RUFFM0IsSUFBSSxDQUFDQSxNQUFNLEVBQUU7SUFDVDtFQUNKO0VBRUEsTUFBTUMsWUFBMkIsR0FBRztJQUNoQ0MsU0FBUyxFQUFFLFVBQVU7SUFDckJDLFNBQVMsRUFBRSxLQUFLO0lBQ2hCQyxXQUFXLEVBQUUsTUFBTTtJQUNuQkMsT0FBTyxFQUFFQyxPQUFPLENBQUNULFlBQVksQ0FBQztJQUM5QjtJQUNBVSxRQUFRLEVBQUVYLFFBQVEsRUFBRVksUUFBUSxLQUFLQyw0QkFBb0IsQ0FBQ0M7RUFDMUQsQ0FBQzs7RUFFRDtFQUNBO0FBQ0o7QUFDQTtBQUNBO0VBQ0lDLGtDQUFnQixDQUFDQyxRQUFRLENBQUNDLFVBQVUsQ0FBZ0JaLFlBQVksQ0FBQztFQUVqRSxJQUFJYSxPQUF1QyxHQUFHLElBQUk7O0VBRWxEO0VBQ0E7RUFDQSxJQUFJMUIsT0FBTyxDQUFDMkIsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMzQixPQUFPLENBQUMyQixVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQzNCLE9BQU8sQ0FBQzJCLFVBQVUsQ0FBQ0Msa0NBQVksQ0FBQyxFQUFFO0lBQzNGLE1BQU07TUFBRUMsR0FBRztNQUFFQztJQUFLLENBQUMsR0FBRyxJQUFBQyx5QkFBVSxFQUFDL0IsT0FBTyxDQUFDO0lBQ3pDLElBQUk2QixHQUFHLEVBQUU7TUFDTCxNQUFNRyxRQUFRLEdBQUd4QixRQUFRLEVBQUVZLFFBQVEsS0FBS0MsNEJBQW9CLENBQUNDLElBQUksR0FBR2QsUUFBUSxFQUFFeUIsUUFBUSxHQUFHLElBQUk7TUFDN0YsSUFBSUMsaUJBQTBCO01BQzlCLENBQUNSLE9BQU8sRUFBRVEsaUJBQWlCLENBQUMsR0FBRyxNQUFNLElBQUFDLHlCQUFlLEVBQUMvQixRQUFRLEVBQUV5QixHQUFHLEVBQUVDLElBQUksRUFBRWxCLE1BQU0sRUFBRW9CLFFBQVEsSUFBSSxJQUFJLENBQUM7TUFFbkcsSUFBSSxDQUFDRSxpQkFBaUIsRUFBRTtRQUNwQixPQUFPLENBQUM7TUFDWjtNQUVBLElBQ0lSLE9BQU8sS0FDTkcsR0FBRyxDQUFDTyxRQUFRLEtBQUtDLGdDQUFpQixDQUFDQyxRQUFRLElBQUlULEdBQUcsQ0FBQ08sUUFBUSxLQUFLQyxnQ0FBaUIsQ0FBQ0UsT0FBTyxDQUFDLEVBQzdGO1FBQ0UsSUFBQUMsbUNBQWMsRUFBQ2QsT0FBTyxFQUFFbEIsUUFBUSxDQUFDO1FBQ2pDLElBQUlDLFlBQVksRUFBRTtVQUNkLElBQUFnQywrQkFBd0IsRUFBQ2YsT0FBTyxFQUFFakIsWUFBWSxFQUFFO1lBQzVDQyxnQkFBZ0I7WUFDaEI7WUFDQWdDLHFCQUFxQixFQUFFaEIsT0FBTyxDQUFDaUIsT0FBTyxFQUFFaEIsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJO1VBQ2hFLENBQUMsQ0FBQztRQUNOO01BQ0osQ0FBQyxNQUFNO1FBQ0g7UUFDQTtNQUNKO0lBQ0osQ0FBQyxNQUFNO01BQ0gsTUFBTWlCLFVBQVUsR0FBRyxNQUFNLElBQUFDLDBCQUFnQixFQUFDN0MsT0FBTyxDQUFDO01BQ2xEO01BQ0E4QyxtQkFBRyxDQUFDQyxRQUFRLENBQUM7UUFDVEMsTUFBTSxFQUFFQyxlQUFNLENBQUNDLGNBQWM7UUFDN0JDLE9BQU8sRUFBRWhELFdBQVcsQ0FBQ2lEO01BQ3pCLENBQUMsQ0FBQztNQUNGO01BQ0EsSUFBSSxDQUFDUixVQUFVLEVBQUU7SUFDckI7RUFDSjs7RUFFQTtFQUNBbEIsT0FBTyxLQUFLLE1BQU0sSUFBQTJCLDBDQUFvQixFQUFDckQsT0FBTyxFQUFFQyxNQUFNLEVBQUVJLE1BQU0sQ0FBQzs7RUFFL0Q7O0VBRUE7O0VBRUE7RUFDQSxJQUFJLENBQUNxQixPQUFPLENBQUM0QixJQUFJLENBQUNDLElBQUksQ0FBQyxDQUFDLEVBQUU7SUFDdEI7RUFDSjtFQUVBLElBQUlDLHNCQUFhLENBQUNDLFFBQVEsQ0FBQywwQ0FBMEMsQ0FBQyxFQUFFO0lBQ3BFLElBQUFDLG9EQUF3QixFQUFDaEMsT0FBTyxDQUFDO0VBQ3JDO0VBRUEsTUFBTU0sUUFBUSxHQUFHeEIsUUFBUSxFQUFFeUIsUUFBUSxJQUFJekIsUUFBUSxFQUFFWSxRQUFRLEtBQUtDLDRCQUFvQixDQUFDQyxJQUFJLEdBQUdkLFFBQVEsQ0FBQ3lCLFFBQVEsR0FBRyxJQUFJO0VBRWxILE1BQU0wQixJQUFJLEdBQUcsSUFBQUMsaUNBQXNCLEVBQy9CaEQsTUFBTSxFQUNMaUQsWUFBb0IsSUFBS3pELFFBQVEsQ0FBQ0wsV0FBVyxDQUFDOEQsWUFBWSxFQUFFN0IsUUFBUSxFQUFFTixPQUFRLENBQUMsRUFDaEZ0QixRQUNKLENBQUM7RUFFRCxJQUFJSyxZQUFZLEVBQUU7SUFDZDtJQUNBO0lBQ0FxQyxtQkFBRyxDQUFDQyxRQUFRLENBQUM7TUFDVEMsTUFBTSxFQUFFLGdCQUFnQjtNQUN4QmMsS0FBSyxFQUFFLElBQUk7TUFDWFgsT0FBTyxFQUFFaEQsV0FBVyxDQUFDaUQ7SUFDekIsQ0FBQyxDQUFDO0VBQ047RUFFQU4sbUJBQUcsQ0FBQ0MsUUFBUSxDQUFDO0lBQUVDLE1BQU0sRUFBRTtFQUFlLENBQUMsQ0FBQztFQUN4Q2UscUJBQVksQ0FBQ0MsT0FBTyxDQUFFQyxNQUFNLElBQUs7SUFDN0IsSUFBSXZDLE9BQU8sSUFBSSxJQUFBd0Msb0JBQWEsRUFBQ3hDLE9BQU8sRUFBRXVDLE1BQU0sQ0FBQ0UsTUFBTSxDQUFDLEVBQUU7TUFDbEQ7TUFDQTtNQUNBLE1BQU1DLFdBQVcsR0FBRzVELFFBQVEsRUFBRVksUUFBUSxLQUFLQyw0QkFBb0IsQ0FBQ0MsSUFBSTtNQUNwRSxJQUFJOEMsV0FBVyxFQUFFO1FBQ2J0QixtQkFBRyxDQUFDQyxRQUFRLENBQUM7VUFBRUMsTUFBTSxFQUFFLFdBQVdpQixNQUFNLENBQUNJLE9BQU87UUFBRyxDQUFDLENBQUM7TUFDekQ7SUFDSjtFQUNKLENBQUMsQ0FBQztFQUNGLElBQUliLHNCQUFhLENBQUNDLFFBQVEsQ0FBQywwQ0FBMEMsQ0FBQyxFQUFFO0lBQ3BFRSxJQUFJLENBQUNXLElBQUksQ0FBRUMsSUFBSSxJQUFLO01BQ2hCLElBQUFDLCtDQUFtQixFQUFDcEUsUUFBUSxFQUFFUSxNQUFNLEVBQUUyRCxJQUFJLENBQUN0QyxRQUFRLENBQUM7SUFDeEQsQ0FBQyxDQUFDO0VBQ047O0VBRUE7RUFDQTs7RUFFQTtFQUNBLElBQUl1QixzQkFBYSxDQUFDQyxRQUFRLENBQUMsNkJBQTZCLENBQUMsRUFBRTtJQUN2RFgsbUJBQUcsQ0FBQ0MsUUFBUSxDQUFDO01BQ1RDLE1BQU0sRUFBRSxrQkFBa0I7TUFDMUJJLHFCQUFxQixFQUFFakQsV0FBVyxDQUFDaUQ7SUFDdkMsQ0FBQyxDQUFDO0VBQ047RUFFQSxPQUFPTyxJQUFJO0FBQ2Y7QUFRTyxlQUFlYyxXQUFXQSxDQUM3QkMsSUFBWSxFQUNaO0VBQUV2RSxXQUFXO0VBQUVDLFFBQVE7RUFBRXVFO0FBQXVDLENBQUMsRUFDMUI7RUFDdkMsTUFBTUMsV0FBVyxHQUFHRCxtQkFBbUIsQ0FBQ0UsUUFBUSxDQUFDLENBQUM7RUFFbER0RCxrQ0FBZ0IsQ0FBQ0MsUUFBUSxDQUFDQyxVQUFVLENBQWdCO0lBQ2hEWCxTQUFTLEVBQUUsVUFBVTtJQUNyQkMsU0FBUyxFQUFFLElBQUk7SUFDZkMsV0FBVyxFQUFFLE1BQU07SUFDbkJHLFFBQVEsRUFBRUQsT0FBTyxDQUFDMEQsV0FBVyxFQUFFRSxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQzNDN0QsT0FBTyxFQUFFQyxPQUFPLENBQUMwRCxXQUFXLENBQUNHLFlBQVk7RUFDN0MsQ0FBQyxDQUFDOztFQUVGO0VBQ0E7RUFDQTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0VBQ0ksTUFBTUMsV0FBVyxHQUFHLE1BQU0sSUFBQTNCLDBDQUFvQixFQUFDcUIsSUFBSSxFQUFFLElBQUksRUFBRTtJQUFFRTtFQUFZLENBQUMsQ0FBQztFQUMzRSxNQUFNSyxVQUFVLEdBQUdELFdBQVcsQ0FBQyxlQUFlLENBQUU7RUFFaEQsTUFBTUUsVUFBVSxHQUFHLElBQUk7RUFFdkIsSUFBSUQsVUFBVSxFQUFFM0IsSUFBSSxLQUFLLEVBQUUsRUFBRTtJQUN6QixJQUFBNkIsa0NBQXlCLEVBQUMvRSxRQUFRLEVBQUV1RSxtQkFBbUIsQ0FBQztJQUN4RCxJQUFBUyw0Q0FBdUIsRUFBQztNQUNwQkMsT0FBTyxFQUFFVCxXQUFXO01BQ3BCVSxhQUFhLEVBQUVBLENBQUEsS0FBTTtRQUNqQixJQUFBQyxtQkFBVSxFQUFDcEYsV0FBVyxDQUFDO01BQzNCO0lBQ0osQ0FBQyxDQUFDO0lBQ0Y7RUFDSjtFQUVBLElBQUlxRixRQUFpRDtFQUVyRCxNQUFNNUUsTUFBTSxHQUFHZ0UsV0FBVyxDQUFDYSxTQUFTLENBQUMsQ0FBQzs7RUFFdEM7RUFDQSxJQUFJLElBQUFDLG9DQUFpQixFQUFDVCxVQUFVLEVBQUVOLG1CQUFtQixDQUFDLElBQUkvRCxNQUFNLEVBQUU7SUFDOUQ7O0lBRUEsSUFBSXNFLFVBQVUsRUFBRTtNQUNaLElBQUFDLGtDQUF5QixFQUFDL0UsUUFBUSxFQUFFdUUsbUJBQW1CLENBQUM7TUFFeEQsTUFBTWIsS0FBSyxHQUFHYSxtQkFBbUIsQ0FBQ0UsUUFBUSxDQUFDLENBQUM7TUFDNUMsTUFBTTdDLFFBQVEsR0FBRzhCLEtBQUssQ0FBQzZCLFlBQVksSUFBSSxJQUFJO01BRTNDSCxRQUFRLEdBQUdwRixRQUFRLENBQUNMLFdBQVcsQ0FBQ2EsTUFBTSxFQUFFb0IsUUFBUSxFQUFFZ0QsV0FBVyxDQUFDO01BQzlEbEMsbUJBQUcsQ0FBQ0MsUUFBUSxDQUFDO1FBQUVDLE1BQU0sRUFBRTtNQUFlLENBQUMsQ0FBQztJQUM1QztFQUNKO0VBRUEsSUFBQXVDLG1CQUFVLEVBQUNwRixXQUFXLENBQUM7RUFDdkIsT0FBT3FGLFFBQVE7QUFDbkIiLCJpZ25vcmVMaXN0IjpbXX0=