You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
753 lines
59 KiB
753 lines
59 KiB
/******/ (() => { // webpackBootstrap
|
|
/******/ var __webpack_modules__ = ({
|
|
|
|
/***/ "./src/chat/chat.js":
|
|
/*!**************************!*\
|
|
!*** ./src/chat/chat.js ***!
|
|
\**************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
/* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */
|
|
const OmUtil = __webpack_require__(/*! ../main/omutils */ "../main/omutils");
|
|
const Settings = __webpack_require__(/*! ../main/settings */ "../main/settings");
|
|
const CSSEmoticon = __webpack_require__(/*! ./cssemoticons */ "./src/chat/cssemoticons.js");
|
|
|
|
const msgIdPrefix = 'chat-msg-id-'
|
|
, closedSize = 20
|
|
, closedSizePx = closedSize + "px"
|
|
, doneTypingInterval = 5000 //time in ms, 5 second for example
|
|
, SEND_ENTER = 'enter', SEND_CTRL = 'ctrl'
|
|
, audio = new Audio('./public/chat_message.mp3')
|
|
;
|
|
let chatPanel, ctrlBlk, tabs, openedHeight = "345px", openedWidth = "300px", allPrefix = "All"
|
|
, roomPrefix = "Room ", typingTimer, roomMode = false
|
|
, editor = $('#chatMessage .wysiwyg-editor'), muted = false, sendOn, DEF_SEND
|
|
, userId, inited = false, newMsgNotification
|
|
;
|
|
|
|
function __setCssVar(key, _val) {
|
|
const val = ('' + _val).endsWith('px') ? _val : _val + 'px';
|
|
if (roomMode) {
|
|
if (typeof(Room) == 'object' && typeof(Room.setCssVar) === 'function') {
|
|
Room.setCssVar(key, val);
|
|
}
|
|
} else {
|
|
OmUtil.setCssVar(key, val);
|
|
}
|
|
}
|
|
function __setCssWidth(val) {
|
|
__setCssVar('--chat-width', val)
|
|
}
|
|
function __setCssHeight(val) {
|
|
__setCssVar('--chat-height', val)
|
|
}
|
|
function _load() {
|
|
const s = Settings.load();
|
|
if (typeof(s.chat) === 'undefined') {
|
|
s.chat = {
|
|
muted: false
|
|
, sendOn: DEF_SEND
|
|
};
|
|
Settings.save(s)
|
|
}
|
|
muted = s.chat.muted === true;
|
|
sendOn = s.chat.sendOn === SEND_ENTER ? SEND_ENTER : SEND_CTRL;
|
|
return s;
|
|
}
|
|
function _updateAudioBtn() {
|
|
const btn = $('#chat .audio');
|
|
btn.removeClass('sound' + (muted ? '' : '-mute')).addClass('sound' + (muted ? '-mute' : ''))
|
|
.attr('title', btn.data(muted ? 'sound-enabled' : 'sound-muted'));
|
|
}
|
|
function _updateSendBtn() {
|
|
const btn = $('#chat .send-btn')
|
|
, ctrl = sendOn === SEND_CTRL;
|
|
if (ctrl) {
|
|
btn.addClass('send-ctrl');
|
|
editor.off('keydown', _sendOnEnter).keydown('Ctrl+return', _sendOnEnter);
|
|
} else {
|
|
btn.removeClass('send-ctrl');
|
|
editor.off('keydown', _sendOnEnter).keydown('return', _sendOnEnter);
|
|
}
|
|
btn.attr('title', btn.data(ctrl ? 'send-ctrl' : 'send-enter'));
|
|
}
|
|
function _sendOnEnter() {
|
|
$('#chat .send').trigger('click');
|
|
}
|
|
function doneTyping () {
|
|
typingTimer = null;
|
|
chatActivity('typing_stop', $('.room-block .room-container').data('room-id'));
|
|
}
|
|
function _emtClick() {
|
|
_editorAppend($(this).data('emt'));
|
|
}
|
|
function initToolbar() {
|
|
const emots = CSSEmoticon.emoticons;
|
|
const rowSize = 20, emotMenuList = $('#emotMenuList');
|
|
emotMenuList.html('');
|
|
let row;
|
|
for (let i = 0; i < emots.length; ++i) {
|
|
if (i % rowSize === 0) {
|
|
row = $('<tr></tr>');
|
|
emotMenuList.append(row);
|
|
}
|
|
row.append($('<td>').append(
|
|
$('<div>').addClass('emt').html(CSSEmoticon.emoticonize(emots[i]))
|
|
.data('emt', emots[i]).click(_emtClick)
|
|
));
|
|
}
|
|
const emtBtn = $('#emoticons');
|
|
emtBtn.html('');
|
|
emtBtn.append(' ' + CSSEmoticon.emoticonize(':)'));
|
|
const a = $('#chat .audio');
|
|
const sbtn = $('#chat .send-btn');
|
|
{ //scope
|
|
_load();
|
|
_updateAudioBtn();
|
|
_updateSendBtn()
|
|
}
|
|
a.off().click(function() {
|
|
const s = _load();
|
|
muted = s.chat.muted = !s.chat.muted;
|
|
_updateAudioBtn();
|
|
Settings.save(s);
|
|
});
|
|
sbtn.off().click(function() {
|
|
const s = _load();
|
|
sendOn = s.chat.sendOn = s.chat.sendOn !== SEND_CTRL ? SEND_CTRL : SEND_ENTER;
|
|
_updateSendBtn();
|
|
Settings.save(s);
|
|
});
|
|
$('#chat #hyperlink').parent().find('button').off().click(function() {
|
|
_insertLink();
|
|
});
|
|
CSSEmoticon.animate();
|
|
}
|
|
function isClosed() {
|
|
return chatPanel.hasClass('closed');
|
|
}
|
|
function activateTab(id) {
|
|
if (isClosed()) {
|
|
tabs.find('.nav.nav-tabs .nav-link').each(function() {
|
|
const self = $(this)
|
|
, tabId = self.attr('aria-controls')
|
|
, tab = $('#' + tabId);
|
|
|
|
if (tabId === id) {
|
|
self.addClass('active');
|
|
tab.addClass('active');
|
|
self.attr('aria-selected', true);
|
|
} else {
|
|
self.removeClass('active');
|
|
tab.removeClass('active');
|
|
self.attr('aria-selected', false);
|
|
}
|
|
});
|
|
} else {
|
|
$('#chatTabs li a[aria-controls="' + id + '"]').tab('show');
|
|
}
|
|
$('#activeChatTab').val(id).trigger('change');
|
|
}
|
|
function _reinit(opts) {
|
|
userId = opts.userId;
|
|
allPrefix = opts.all;
|
|
roomPrefix = opts.room;
|
|
DEF_SEND = opts.sendOnEnter === true ? SEND_ENTER : SEND_CTRL;
|
|
sendOn = DEF_SEND;
|
|
chatPanel = $('#chatPanel');
|
|
clearTimeout(chatPanel.data('timeout'));
|
|
ctrlBlk = $('#chatPopup .control.block');
|
|
newMsgNotification = ctrlBlk.data('new-msg');
|
|
editor = $('#chatMessage .wysiwyg-editor');
|
|
initToolbar();
|
|
tabs = $("#chatTabs");
|
|
tabs.off().on('shown.bs.tab', function (e) {
|
|
const ct = $(e.target).attr('aria-controls');
|
|
_scrollDown($('#' + ct));
|
|
$('#activeChatTab').val(ct).trigger('change');
|
|
});
|
|
tabs.delegate(".btn.close-chat", "click", function() {
|
|
const panelId = $(this).closest("a").attr("aria-controls");
|
|
_removeTab(panelId);
|
|
$('#chatTabs li:last-child a').tab('show');
|
|
});
|
|
if (roomMode) {
|
|
_removeResize();
|
|
} else {
|
|
ctrlBlk.attr('title', '');
|
|
chatPanel.removeClass('room opened').addClass('closed')
|
|
.off('mouseenter mouseleave').resizable({
|
|
handles: 'n, ' + (Settings.isRtl ? 'e' : 'w')
|
|
, disabled: isClosed()
|
|
, minHeight: 195
|
|
, minWidth: 260
|
|
, stop: function(_, ui) {
|
|
chatPanel.css({'top': '', 'left': ''});
|
|
openedHeight = ui.size.height + 'px';
|
|
__setCssHeight(openedHeight);
|
|
__setCssWidth(ui.size.width);
|
|
}
|
|
});
|
|
__setCssHeight(closedSize);
|
|
}
|
|
ctrlBlk.off().click(_toggle);
|
|
$('#chatMessage').off().on('input propertychange paste', function () {
|
|
const room = $('.room-block .room-container');
|
|
if (room.length) {
|
|
if (!!typingTimer) {
|
|
clearTimeout(typingTimer);
|
|
} else {
|
|
chatActivity('typing_start', room.data('room-id'));
|
|
}
|
|
typingTimer = setTimeout(doneTyping, doneTypingInterval);
|
|
}
|
|
});
|
|
$('#chat .chat-toolbar .link-field').off().on('keypress', function(evt) {
|
|
if (evt.keyCode === 13) {
|
|
$(this).parent().find('button').trigger('click');
|
|
}
|
|
return evt.keyCode !== 13;
|
|
});
|
|
inited = true;
|
|
}
|
|
function _removeTab(id) {
|
|
$('#chatTabs li a[aria-controls="' + id + '"]').parent().remove();
|
|
$('#' + id).remove();
|
|
}
|
|
function _addTab(id, label) {
|
|
if (!inited) {
|
|
_reinit({});
|
|
}
|
|
if ($('#chat').length < 1 || $('#' + id).length) {
|
|
return;
|
|
}
|
|
if (!label) {
|
|
label = id === "chatTab-all" ? allPrefix : roomPrefix + id.substr(9);
|
|
}
|
|
const link = $('<a class="nav-link" data-bs-toggle="tab" role="tab">')
|
|
.attr('aria-controls', id)
|
|
.attr('href', '#' + id).text(label)
|
|
, li = $('<li class="nav-item">').append(link);
|
|
if (id.indexOf("chatTab-u") === 0) {
|
|
link.append(OmUtil.tmpl('#chat-close-block'));
|
|
}
|
|
tabs.find('.nav.nav-tabs').append(li);
|
|
const msgArea = OmUtil.tmpl('#chat-msg-area-template', id);
|
|
tabs.find('.tab-content').append(msgArea);
|
|
msgArea.append($('<div class="clear icons actions float-start">').addClass('short')
|
|
.append(OmUtil.tmpl('#chat-actions-short-template')));
|
|
msgArea.append($('<div class="clear icons actions float-start">').addClass('short-mod')
|
|
.append(OmUtil.tmpl('#chat-actions-short-template'))
|
|
.append(OmUtil.tmpl('#chat-actions-accept-template')));
|
|
msgArea.append($('<div class="clear icons actions float-start">').addClass('full')
|
|
.append(OmUtil.tmpl('#chat-actions-short-template'))
|
|
.append(OmUtil.tmpl('#chat-actions-others-template').children().clone()));
|
|
msgArea.append($('<div class="clear icons actions float-start">').addClass('full-mod')
|
|
.append(OmUtil.tmpl('#chat-actions-short-template'))
|
|
.append(OmUtil.tmpl('#chat-actions-others-template').children().clone())
|
|
.append(OmUtil.tmpl('#chat-actions-accept-template')));
|
|
const actions = __hideActions();
|
|
actions.find('.user').off().click(function() {
|
|
const e = $(this).parent();
|
|
showUserInfo(e.data("userId"));
|
|
});
|
|
actions.find('.add').off().click(function() {
|
|
const e = $(this).parent();
|
|
addContact(e.data("userId"));
|
|
});
|
|
actions.find('.new-email').off().click(function() {
|
|
const e = $(this).parent();
|
|
privateMessage(e.data("userId"));
|
|
});
|
|
actions.find('.invite').off().click(function() {
|
|
const e = $(this).parent();
|
|
inviteUser(e.data("userId"));
|
|
});
|
|
actions.find('.accept').off().click(function() {
|
|
const e = $(this).parent()
|
|
, msgId = e.data('msgId');
|
|
chatActivity('accept', e.data('roomId'), msgId);
|
|
__hideActions();
|
|
$('#chat-msg-id-' + msgId).remove();
|
|
});
|
|
activateTab(id);
|
|
}
|
|
function __hideActions() {
|
|
return $('#chat .tab-content .messageArea .icons').hide();
|
|
}
|
|
function __getActions(row) {
|
|
return row.closest('.messageArea').find('.actions.' + row.data('actions'));
|
|
}
|
|
function _addMessage(m) {
|
|
if ($('#chat').length > 0 && m && m.type === "chat") {
|
|
let msg, cm, notify = false;
|
|
while (!!(cm = m.msg.pop())) {
|
|
let area = $('#' + cm.scope);
|
|
if (cm.from.id !== userId && (isClosed() || !area.is(':visible'))) {
|
|
notify = true;
|
|
}
|
|
const actions = ('full' === cm.actions ? 'full' : 'short') + (cm.needModeration ? '-mod' : '');
|
|
msg = OmUtil.tmpl('#chat-msg-template', msgIdPrefix + cm.id)
|
|
const row = msg.find('.user-row')
|
|
.data('userId', cm.from.id)
|
|
.data('actions', actions)
|
|
.mouseenter(function() {
|
|
__hideActions();
|
|
__getActions($(this))
|
|
.data('userId', $(this).data('userId'))
|
|
.data('roomId', $(this).data('roomId'))
|
|
.data('msgId', $(this).data('msgId'))
|
|
.css('top', ($(this).closest('.msg-row')[0].offsetTop + 20) + 'px')
|
|
.show();
|
|
});
|
|
if (cm.needModeration) {
|
|
row.parent().addClass('need-moderation');
|
|
row.data('roomId', cm.scope.substring(9))
|
|
.data('msgId', cm.id);
|
|
}
|
|
area.mouseleave(function() {
|
|
__hideActions();
|
|
});
|
|
msg.find('.from').data('user-id', cm.from.id).html(cm.from.displayName || cm.from.name);
|
|
msg.find('.time').html(cm.time).attr('title', cm.sent);
|
|
if (!area.length) {
|
|
_addTab(cm.scope, cm.scopeName);
|
|
area = $('#' + cm.scope);
|
|
}
|
|
if (m.mode === "accept") {
|
|
$('#chat-msg-id-' + cm.id).remove();
|
|
}
|
|
const btm = area[0].scrollHeight - (area.scrollTop() + area.innerHeight()) < 3; //approximately equal
|
|
if (area.data('lastDate') !== cm.date) {
|
|
area.append(OmUtil.tmpl('#chat-date-template').html(cm.date).mouseenter(function() {
|
|
__hideActions();
|
|
}));
|
|
area.data('lastDate', cm.date);
|
|
}
|
|
area.append(msg);
|
|
msg.find('.user-row')[0].style.cssText = `
|
|
background-image: url(${(!!cm.from.img ? cm.from.img : './profile/' + cm.from.id + '?anticache=' + Date.now())});
|
|
background-position-x: ${Settings.isRtl ? 'right' : 'left'};
|
|
`;
|
|
|
|
msg.find('.msg').html(CSSEmoticon.emoticonize(!!cm.message ? cm.message : ""));
|
|
if (btm) {
|
|
_scrollDown(area);
|
|
}
|
|
}
|
|
if (notify) {
|
|
ctrlBlk.addClass('bg-warning');
|
|
if (chatPanel.is(':visible') && !muted) {
|
|
OmUtil.notify(newMsgNotification, 'new_chat_msg', () => {
|
|
// impossible to use Notification API from iFrame
|
|
audio.play()
|
|
.then(function() {
|
|
// Automatic playback started!
|
|
}).catch(function() {
|
|
// Automatic playback failed.
|
|
});
|
|
});
|
|
}
|
|
}
|
|
CSSEmoticon.animate();
|
|
}
|
|
}
|
|
function _setOpened() {
|
|
__setCssWidth(openedWidth);
|
|
chatPanel.resizable({
|
|
handles: (Settings.isRtl ? 'e' : 'w')
|
|
, minWidth: 165
|
|
, stop: function(_, ui) {
|
|
chatPanel.css({'left': '', 'width': '', 'height': ''});
|
|
openedWidth = ui.size.width + 'px';
|
|
__setCssWidth(openedWidth);
|
|
}
|
|
});
|
|
}
|
|
function _removeResize() {
|
|
if (chatPanel.resizable('instance') !== undefined) {
|
|
chatPanel.resizable('destroy');
|
|
}
|
|
}
|
|
function _open(handler) {
|
|
if (isClosed()) {
|
|
ctrlBlk.removeClass('bg-warning');
|
|
let opts;
|
|
if (roomMode) {
|
|
opts = {width: openedWidth};
|
|
} else {
|
|
opts = {height: openedHeight};
|
|
chatPanel.resizable("option", "disabled", false);
|
|
}
|
|
chatPanel.removeClass('closed').animate(opts, 1000, function() {
|
|
__hideActions();
|
|
chatPanel.removeClass('closed');
|
|
chatPanel.css({'height': '', 'width': ''});
|
|
if (typeof(handler) === 'function') {
|
|
handler();
|
|
}
|
|
ctrlBlk.attr('title', ctrlBlk.data('ttl-undock'));
|
|
if (roomMode) {
|
|
_setOpened();
|
|
if (typeof(window.WbArea) === 'object') {
|
|
window.WbArea.resize();
|
|
}
|
|
} else {
|
|
__setCssHeight(openedHeight);
|
|
}
|
|
_setAreaHeight();
|
|
});
|
|
}
|
|
}
|
|
function _close(handler) {
|
|
if (!isClosed()) {
|
|
let opts;
|
|
if (roomMode) {
|
|
opts = {width: closedSizePx};
|
|
} else {
|
|
opts = {height: closedSizePx};
|
|
chatPanel.resizable("option", "disabled", true);
|
|
}
|
|
chatPanel.animate(opts, 1000, function() {
|
|
chatPanel.addClass('closed').css({'height': '', 'width': ''});
|
|
if (roomMode) {
|
|
__setCssWidth(closedSizePx);
|
|
_removeResize();
|
|
if (typeof(window.WbArea) === 'object') {
|
|
window.WbArea.resize();
|
|
}
|
|
} else {
|
|
__setCssHeight(closedSizePx);
|
|
}
|
|
if (typeof(handler) === 'function') {
|
|
handler();
|
|
}
|
|
ctrlBlk.attr('title', ctrlBlk.data('ttl-dock'));
|
|
});
|
|
}
|
|
}
|
|
function _toggle() {
|
|
if (isClosed()) {
|
|
_open();
|
|
} else {
|
|
_close();
|
|
}
|
|
}
|
|
function _editorAppend(_emoticon) {
|
|
editor.html(editor.html() + ' ' + _emoticon + ' ').trigger('change');
|
|
}
|
|
function _clean() {
|
|
editor.html('').trigger('change');
|
|
}
|
|
function _setRoomMode(_mode) {
|
|
roomMode = _mode;
|
|
if (inited && !roomMode) {
|
|
// remove all private chats on room exit
|
|
$('li[aria-controls^="chatTab-u"]').remove();
|
|
$('div[id^="chatTab-u"]').remove();
|
|
}
|
|
_reinit({userId: userId, all: allPrefix, room: roomPrefix, sendOnEnter: sendOn === SEND_ENTER});
|
|
}
|
|
function _scrollDown(area) {
|
|
area.animate({
|
|
scrollTop: area[0].scrollHeight
|
|
}, 300);
|
|
}
|
|
function _setAreaHeight() {
|
|
$('#chat .messageArea').each(function() {
|
|
_scrollDown($(this));
|
|
});
|
|
}
|
|
function _insertLink() {
|
|
const text = $('#chat #hyperlink').parent().find('input').val();
|
|
if ('' === text) {
|
|
return;
|
|
}
|
|
let url = text.trim();
|
|
if ('' === url) {
|
|
return;
|
|
}
|
|
if (!/^(https?:)?\/\//i.test(url)) {
|
|
url = 'http://' + url;
|
|
}
|
|
const a = $('<div>').append($('<a></a>').attr('target', '_blank').attr('href', url).text(url)).html();
|
|
if (window.getSelection) {
|
|
const sel = window.getSelection();
|
|
if (sel.rangeCount) {
|
|
const range = sel.getRangeAt(0);
|
|
if ($(range.startContainer).parents('.wysiwyg-editor').length > 0) {
|
|
range.deleteContents();
|
|
range.insertNode(a);
|
|
} else {
|
|
_editorAppend(a);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function _typingActivity(uid, active) {
|
|
if (typeof(Room) !== 'object') {
|
|
return;
|
|
}
|
|
const c = Room.getClient(uid);
|
|
if (!c) {
|
|
return;
|
|
}
|
|
const u = c.find('.typing-activity');
|
|
if (!u) {
|
|
return;
|
|
}
|
|
if (active) {
|
|
u.addClass("typing");
|
|
} else {
|
|
u.removeClass("typing");
|
|
}
|
|
}
|
|
|
|
$(function() {
|
|
Wicket.Event.subscribe("/websocket/message", function(_, msg) {
|
|
try {
|
|
if (msg instanceof Blob) {
|
|
return; //ping
|
|
}
|
|
const m = JSON.parse(msg);
|
|
if (m) {
|
|
switch(m.type) {
|
|
case "chat":
|
|
if ('clean' === m.action) {
|
|
$('#' + m.scope).html('');
|
|
} else {
|
|
_addMessage(m);
|
|
}
|
|
break;
|
|
case "typing":
|
|
_typingActivity(m.uid, m.active);
|
|
break;
|
|
}
|
|
}
|
|
} catch (err) {
|
|
//no-op
|
|
}
|
|
});
|
|
function _cancelAskNotification() {
|
|
$(document).off('click', _askNotification)
|
|
}
|
|
function _askNotification() {
|
|
OmUtil.requestNotifyPermission(_cancelAskNotification, _cancelAskNotification);
|
|
}
|
|
$(document).on('click', _askNotification);
|
|
});
|
|
|
|
module.exports = {
|
|
SEND_ENTER: SEND_ENTER
|
|
, SEND_CTRL: SEND_CTRL
|
|
|
|
, reinit: _reinit
|
|
, removeTab: _removeTab
|
|
, addTab: _addTab
|
|
, addMessage: _addMessage
|
|
, open: _open
|
|
, setOpened: function() {
|
|
_open(function() {
|
|
_setOpened();
|
|
});
|
|
}
|
|
, close: _close
|
|
, toggle: _toggle
|
|
, setRoomMode: _setRoomMode
|
|
, clean: _clean
|
|
, reload: () => {
|
|
_load();
|
|
_updateAudioBtn();
|
|
_updateSendBtn();
|
|
}
|
|
, validate: function() {
|
|
return !!editor && editor.text().trim().length > 0;
|
|
}
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./src/chat/cssemoticons.js":
|
|
/*!**********************************!*\
|
|
!*** ./src/chat/cssemoticons.js ***!
|
|
\**********************************/
|
|
/***/ ((module) => {
|
|
|
|
/*
|
|
* Based on
|
|
*
|
|
* jQuery CSSEmoticons plugin 0.2.9
|
|
*
|
|
* Copyright (c) 2010 Steve Schwartz (JangoSteve)
|
|
*
|
|
* Dual licensed under the MIT and GPL licenses:
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
* http://www.gnu.org/licenses/gpl.html
|
|
*
|
|
* Date: Sun Oct 22 1:00:00 2010 -0500
|
|
*/
|
|
const escapeCharacters = [")", "(", "*", "[", "]", "{", "}", "|", "^", "<", ">", "\\", "?", "+", "=", "."]
|
|
, specialRegex = new RegExp('(\\' + escapeCharacters.join('|\\') + ')', 'g')
|
|
// One of these characters must be present before the matched emoticon, or the matched emoticon must be the first character in the container HTML
|
|
// This is to ensure that the characters in the middle of HTML properties or URLs are not matched as emoticons
|
|
// Below matches ^ (first character in container HTML), \s (whitespace like space or tab), or \0 (NULL character)
|
|
// (<\\S+.*>) matches <\\S+.*> (matches an HTML tag like <span> or <div>), but haven't quite gotten it working yet, need to push this fix now
|
|
, preMatch = '(^|[\\s\\0])'
|
|
, emoticons = []
|
|
, matchers = []
|
|
, defaults = {animate: true, delay: 500, exclude: 'pre,code,.no-emoticons'};
|
|
|
|
function createMatcher(m) {
|
|
const str = m.text.replace(specialRegex, '\\$1');
|
|
m.regexp = new RegExp(preMatch + '(' + str + ')', 'g');
|
|
return m;
|
|
}
|
|
function addMatchers(arr) {
|
|
for (let i = 0; i < arr.length; ++i) {
|
|
const o = arr[i]
|
|
let m = typeof(o) === 'object' ? JSON.parse(JSON.stringify(o)) : {text: o, cssClass: ' '};
|
|
emoticons.push(m.text);
|
|
|
|
matchers.push(createMatcher(m));
|
|
if (m.text.indexOf('=') > -1) {
|
|
m = JSON.parse(JSON.stringify(m));
|
|
m.text = m.text.replace(/=/g, '=').replace(/[+]/g, '+');
|
|
matchers.push(createMatcher(m));
|
|
}
|
|
if (m.text.indexOf('\'') > -1) {
|
|
m = JSON.parse(JSON.stringify(m));
|
|
m.text = m.text.replace(/'/g, ''');
|
|
matchers.push(createMatcher(m));
|
|
}
|
|
}
|
|
}
|
|
addMatchers([
|
|
":-)", ":o)", ":c)", ":^)", ":-D", ":-(", ":-9", ";-)", ":-P", ":-p", ":-Þ", ":-b", ":-O", ":-/", ":-X", ":-#", ":'(", "B-)", "8-)", ";*(", ":-*", ":-\\",
|
|
"?-)" // <== This is my own invention, it's a smiling pirate (with an eye-patch)!
|
|
]);
|
|
addMatchers([ // separate these out so that we can add a letter-spacing between the characters for better proportions
|
|
":)", ":]", "=]", "=)", "8)", ":}", ":D", ":(", ":[", ":{", "=(", ";)", ";]", ";D", ":P", ":p", "=P", "=p", ":b", ":Þ", ":O", ":/", "=/", ":S", ":#", ":X", "B)", ":|", ":\\", "=\\", ":*", ":>", ":<"
|
|
]);
|
|
addMatchers([ // emoticons to be treated with a special class, hash specifies the additional class to add, along with standard css-emoticon class
|
|
{text: ">:)", cssClass: "red-emoticon small-emoticon spaced-emoticon"},
|
|
{text: ">;)", cssClass: "red-emoticon small-emoticon spaced-emoticon"},
|
|
{text: ">:(", cssClass: "red-emoticon small-emoticon spaced-emoticon"},
|
|
{text: ">: )", cssClass: "red-emoticon small-emoticon"},
|
|
{text: ">; )", cssClass: "red-emoticon small-emoticon"},
|
|
{text: ">: (", cssClass: "red-emoticon small-emoticon"},
|
|
{text: ";(", cssClass: "red-emoticon spaced-emoticon"},
|
|
{text: "<3", cssClass: "pink-emoticon counter-rotated"},
|
|
{text: "O_O", cssClass: "no-rotate"},
|
|
{text: "o_o", cssClass: "no-rotate"},
|
|
{text: "0_o", cssClass: "no-rotate"},
|
|
{text: "O_o", cssClass: "no-rotate"},
|
|
{text: "T_T", cssClass: "no-rotate"},
|
|
{text: "^_^", cssClass: "no-rotate"},
|
|
{text: "O:)", cssClass: "small-emoticon spaced-emoticon"},
|
|
{text: "O: )", cssClass: "small-emoticon"},
|
|
{text: "8D", cssClass: "small-emoticon spaced-emoticon"},
|
|
{text: "XD", cssClass: "small-emoticon spaced-emoticon"},
|
|
{text: "xD", cssClass: "small-emoticon spaced-emoticon"},
|
|
{text: "=D", cssClass: "small-emoticon spaced-emoticon"},
|
|
{text: "8O", cssClass: "small-emoticon spaced-emoticon"},
|
|
{text: "[+=..]", cssClass: "no-rotate nintendo-controller"}
|
|
]);
|
|
|
|
module.exports = {
|
|
emoticons: emoticons
|
|
, matchers: matchers
|
|
, defaults: defaults
|
|
, emoticonize: function(str, options) {
|
|
const opts = $.extend({}, defaults, options);
|
|
|
|
let cssClass = 'css-emoticon';
|
|
if (opts.animate) {
|
|
cssClass += ' un-transformed-emoticon animated-emoticon';
|
|
}
|
|
for (let i = 0; i < matchers.length; ++i) {
|
|
const m = matchers[i];
|
|
const css = cssClass + " " + m.cssClass;
|
|
str = str.replace(m.regexp, "$1<span class='" + css + "'>$2</span>");
|
|
}
|
|
return str;
|
|
}
|
|
, animate: function(options) {
|
|
const opts = $.extend({}, defaults, options);
|
|
// animate emoticons
|
|
if (opts.animate) {
|
|
setTimeout(function () {
|
|
$('.un-transformed-emoticon').removeClass('un-transformed-emoticon');
|
|
}, opts.delay);
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "../main/omutils":
|
|
/*!*************************!*\
|
|
!*** external "OmUtil" ***!
|
|
\*************************/
|
|
/***/ ((module) => {
|
|
|
|
"use strict";
|
|
module.exports = OmUtil;
|
|
|
|
/***/ }),
|
|
|
|
/***/ "../main/settings":
|
|
/*!***************************!*\
|
|
!*** external "Settings" ***!
|
|
\***************************/
|
|
/***/ ((module) => {
|
|
|
|
"use strict";
|
|
module.exports = Settings;
|
|
|
|
/***/ })
|
|
|
|
/******/ });
|
|
/************************************************************************/
|
|
/******/ // The module cache
|
|
/******/ var __webpack_module_cache__ = {};
|
|
/******/
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
/******/ // Check if module is in cache
|
|
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
/******/ if (cachedModule !== undefined) {
|
|
/******/ return cachedModule.exports;
|
|
/******/ }
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
/******/ // no module.id needed
|
|
/******/ // no module.loaded needed
|
|
/******/ exports: {}
|
|
/******/ };
|
|
/******/
|
|
/******/ // Execute the module function
|
|
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
/******/
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/ }
|
|
/******/
|
|
/************************************************************************/
|
|
var __webpack_exports__ = {};
|
|
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
|
|
(() => {
|
|
/*!***************************!*\
|
|
!*** ./src/chat/index.js ***!
|
|
\***************************/
|
|
/* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */
|
|
Object.assign(window, {
|
|
Chat: __webpack_require__(/*! ./chat */ "./src/chat/chat.js")
|
|
});
|
|
|
|
})();
|
|
|
|
/******/ })()
|
|
;
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTtBQUNBLGVBQWUsbUJBQU8sQ0FBQyx3Q0FBaUI7QUFDeEMsaUJBQWlCLG1CQUFPLENBQUMsMENBQWtCO0FBQzNDLG9CQUFvQixtQkFBTyxDQUFDLGtEQUFnQjs7QUFFNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixrQkFBa0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0Isc0JBQXNCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRkFBbUY7QUFDbkY7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLHVGQUF1RjtBQUNuSCw2QkFBNkI7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0Isc0NBQXNDO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLElBQUk7QUFDSixXQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQiwwQkFBMEI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsSUFBSTtBQUNKLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsMEJBQTBCO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUscUZBQXFGO0FBQy9GO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7OztBQzVpQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQsS0FBSztBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDO0FBQ0Esb0VBQW9FO0FBQ3BFOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1Qyx5QkFBeUI7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRCxvRkFBb0Y7QUFDeEk7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLHdCQUF3QixXQUFXLE1BQU0sTUFBTSxrSEFBa0gsU0FBUztBQUM1TTtBQUNBO0FBQ0EsRUFBRSxXQUFXLDZEQUE2RDtBQUMxRSxFQUFFLFlBQVksNERBQTREO0FBQzFFLEVBQUUsV0FBVyw2REFBNkQ7QUFDMUUsRUFBRSxXQUFXLDhDQUE4QztBQUMzRCxFQUFFLGFBQWEsNENBQTRDO0FBQzNELEVBQUUsV0FBVyw4Q0FBOEM7QUFDM0QsRUFBRSxRQUFRLDZDQUE2QztBQUN2RCxFQUFFLFdBQVcsOENBQThDO0FBQzNELEVBQUUsbUNBQW1DO0FBQ3JDLEVBQUUsbUNBQW1DO0FBQ3JDLEVBQUUsbUNBQW1DO0FBQ3JDLEVBQUUsbUNBQW1DO0FBQ3JDLEVBQUUsbUNBQW1DO0FBQ3JDLEVBQUUsbUNBQW1DO0FBQ3JDLEVBQUUsd0RBQXdEO0FBQzFELEVBQUUseUNBQXlDO0FBQzNDLEVBQUUsdURBQXVEO0FBQ3pELEVBQUUsdURBQXVEO0FBQ3pELEVBQUUsdURBQXVEO0FBQ3pELEVBQUUsdURBQXVEO0FBQ3pELEVBQUUsdURBQXVEO0FBQ3pELEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCOztBQUUxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixxQkFBcUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUMzR0E7Ozs7Ozs7Ozs7O0FDQUE7Ozs7OztVQ0FBO1VBQ0E7O1VBRUE7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7O1VBRUE7VUFDQTs7VUFFQTtVQUNBO1VBQ0E7Ozs7Ozs7OztBQ3RCQTtBQUNBO0FBQ0EsT0FBTyxtQkFBTyxDQUFDLGtDQUFRO0FBQ3ZCLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9vbS1mcm9udGVuZC8uL3NyYy9jaGF0L2NoYXQuanMiLCJ3ZWJwYWNrOi8vb20tZnJvbnRlbmQvLi9zcmMvY2hhdC9jc3NlbW90aWNvbnMuanMiLCJ3ZWJwYWNrOi8vb20tZnJvbnRlbmQvZXh0ZXJuYWwgdmFyIFwiT21VdGlsXCIiLCJ3ZWJwYWNrOi8vb20tZnJvbnRlbmQvZXh0ZXJuYWwgdmFyIFwiU2V0dGluZ3NcIiIsIndlYnBhY2s6Ly9vbS1mcm9udGVuZC93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9vbS1mcm9udGVuZC8uL3NyYy9jaGF0L2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIikgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wICovXG5jb25zdCBPbVV0aWwgPSByZXF1aXJlKCcuLi9tYWluL29tdXRpbHMnKTtcbmNvbnN0IFNldHRpbmdzID0gcmVxdWlyZSgnLi4vbWFpbi9zZXR0aW5ncycpO1xuY29uc3QgQ1NTRW1vdGljb24gPSByZXF1aXJlKCcuL2Nzc2Vtb3RpY29ucycpO1xuXG5jb25zdCBtc2dJZFByZWZpeCA9ICdjaGF0LW1zZy1pZC0nXG5cdCwgY2xvc2VkU2l6ZSA9IDIwXG5cdCwgY2xvc2VkU2l6ZVB4ID0gY2xvc2VkU2l6ZSArIFwicHhcIlxuXHQsIGRvbmVUeXBpbmdJbnRlcnZhbCA9IDUwMDAgLy90aW1lIGluIG1zLCA1IHNlY29uZCBmb3IgZXhhbXBsZVxuXHQsIFNFTkRfRU5URVIgPSAnZW50ZXInLCBTRU5EX0NUUkwgPSAnY3RybCdcblx0LCBhdWRpbyA9IG5ldyBBdWRpbygnLi9wdWJsaWMvY2hhdF9tZXNzYWdlLm1wMycpXG5cdDtcbmxldCBjaGF0UGFuZWwsIGN0cmxCbGssIHRhYnMsIG9wZW5lZEhlaWdodCA9IFwiMzQ1cHhcIiwgb3BlbmVkV2lkdGggPSBcIjMwMHB4XCIsIGFsbFByZWZpeCA9IFwiQWxsXCJcblx0LCByb29tUHJlZml4ID0gXCJSb29tIFwiLCB0eXBpbmdUaW1lciwgcm9vbU1vZGUgPSBmYWxzZVxuXHQsIGVkaXRvciA9ICQoJyNjaGF0TWVzc2FnZSAud3lzaXd5Zy1lZGl0b3InKSwgbXV0ZWQgPSBmYWxzZSwgc2VuZE9uLCBERUZfU0VORFxuXHQsIHVzZXJJZCwgaW5pdGVkID0gZmFsc2UsIG5ld01zZ05vdGlmaWNhdGlvblxuXHQ7XG5cbmZ1bmN0aW9uIF9fc2V0Q3NzVmFyKGtleSwgX3ZhbCkge1xuXHRjb25zdCB2YWwgPSAoJycgKyBfdmFsKS5lbmRzV2l0aCgncHgnKSA/IF92YWwgOiBfdmFsICsgJ3B4Jztcblx0aWYgKHJvb21Nb2RlKSB7XG5cdFx0aWYgKHR5cGVvZihSb29tKSA9PSAnb2JqZWN0JyAmJiB0eXBlb2YoUm9vbS5zZXRDc3NWYXIpID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRSb29tLnNldENzc1ZhcihrZXksIHZhbCk7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdE9tVXRpbC5zZXRDc3NWYXIoa2V5LCB2YWwpO1xuXHR9XG59XG5mdW5jdGlvbiBfX3NldENzc1dpZHRoKHZhbCkge1xuXHRfX3NldENzc1ZhcignLS1jaGF0LXdpZHRoJywgdmFsKVxufVxuZnVuY3Rpb24gX19zZXRDc3NIZWlnaHQodmFsKSB7XG5cdF9fc2V0Q3NzVmFyKCctLWNoYXQtaGVpZ2h0JywgdmFsKVxufVxuZnVuY3Rpb24gX2xvYWQoKSB7XG5cdGNvbnN0IHMgPSBTZXR0aW5ncy5sb2FkKCk7XG5cdGlmICh0eXBlb2Yocy5jaGF0KSA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRzLmNoYXQgPSB7XG5cdFx0XHRtdXRlZDogZmFsc2Vcblx0XHRcdCwgc2VuZE9uOiBERUZfU0VORFxuXHRcdH07XG5cdFx0U2V0dGluZ3Muc2F2ZShzKVxuXHR9XG5cdG11dGVkID0gcy5jaGF0Lm11dGVkID09PSB0cnVlO1xuXHRzZW5kT24gPSBzLmNoYXQuc2VuZE9uID09PSBTRU5EX0VOVEVSID8gU0VORF9FTlRFUiA6IFNFTkRfQ1RSTDtcblx0cmV0dXJuIHM7XG59XG5mdW5jdGlvbiBfdXBkYXRlQXVkaW9CdG4oKSB7XG5cdGNvbnN0IGJ0biA9ICQoJyNjaGF0IC5hdWRpbycpO1xuXHRidG4ucmVtb3ZlQ2xhc3MoJ3NvdW5kJyArIChtdXRlZCA/ICcnIDogJy1tdXRlJykpLmFkZENsYXNzKCdzb3VuZCcgKyAobXV0ZWQgPyAnLW11dGUnIDogJycpKVxuXHRcdFx0LmF0dHIoJ3RpdGxlJywgYnRuLmRhdGEobXV0ZWQgPyAnc291bmQtZW5hYmxlZCcgOiAnc291bmQtbXV0ZWQnKSk7XG59XG5mdW5jdGlvbiBfdXBkYXRlU2VuZEJ0bigpIHtcblx0Y29uc3QgYnRuID0gJCgnI2NoYXQgLnNlbmQtYnRuJylcblx0XHQsIGN0cmwgPSBzZW5kT24gPT09IFNFTkRfQ1RSTDtcblx0aWYgKGN0cmwpIHtcblx0XHRidG4uYWRkQ2xhc3MoJ3NlbmQtY3RybCcpO1xuXHRcdGVkaXRvci5vZmYoJ2tleWRvd24nLCBfc2VuZE9uRW50ZXIpLmtleWRvd24oJ0N0cmwrcmV0dXJuJywgX3NlbmRPbkVudGVyKTtcblx0fSBlbHNlIHtcblx0XHRidG4ucmVtb3ZlQ2xhc3MoJ3NlbmQtY3RybCcpO1xuXHRcdGVkaXRvci5vZmYoJ2tleWRvd24nLCBfc2VuZE9uRW50ZXIpLmtleWRvd24oJ3JldHVybicsIF9zZW5kT25FbnRlcik7XG5cdH1cblx0YnRuLmF0dHIoJ3RpdGxlJywgYnRuLmRhdGEoY3RybCA/ICdzZW5kLWN0cmwnIDogJ3NlbmQtZW50ZXInKSk7XG59XG5mdW5jdGlvbiBfc2VuZE9uRW50ZXIoKSB7XG5cdCQoJyNjaGF0IC5zZW5kJykudHJpZ2dlcignY2xpY2snKTtcbn1cbmZ1bmN0aW9uIGRvbmVUeXBpbmcgKCkge1xuXHR0eXBpbmdUaW1lciA9IG51bGw7XG5cdGNoYXRBY3Rpdml0eSgndHlwaW5nX3N0b3AnLCAkKCcucm9vbS1ibG9jayAucm9vbS1jb250YWluZXInKS5kYXRhKCdyb29tLWlkJykpO1xufVxuZnVuY3Rpb24gX2VtdENsaWNrKCkge1xuXHRfZWRpdG9yQXBwZW5kKCQodGhpcykuZGF0YSgnZW10JykpO1xufVxuZnVuY3Rpb24gaW5pdFRvb2xiYXIoKSB7XG5cdGNvbnN0IGVtb3RzID0gQ1NTRW1vdGljb24uZW1vdGljb25zO1xuXHRjb25zdCByb3dTaXplID0gMjAsIGVtb3RNZW51TGlzdCA9ICQoJyNlbW90TWVudUxpc3QnKTtcblx0ZW1vdE1lbnVMaXN0Lmh0bWwoJycpO1xuXHRsZXQgcm93O1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IGVtb3RzLmxlbmd0aDsgKytpKSB7XG5cdFx0aWYgKGkgJSByb3dTaXplID09PSAwKSB7XG5cdFx0XHRyb3cgPSAkKCc8dHI+PC90cj4nKTtcblx0XHRcdGVtb3RNZW51TGlzdC5hcHBlbmQocm93KTtcblx0XHR9XG5cdFx0cm93LmFwcGVuZCgkKCc8dGQ+JykuYXBwZW5kKFxuXHRcdFx0XHQkKCc8ZGl2PicpLmFkZENsYXNzKCdlbXQnKS5odG1sKENTU0Vtb3RpY29uLmVtb3RpY29uaXplKGVtb3RzW2ldKSlcblx0XHRcdFx0XHQuZGF0YSgnZW10JywgZW1vdHNbaV0pLmNsaWNrKF9lbXRDbGljaylcblx0XHRcdCkpO1xuXHR9XG5cdGNvbnN0IGVtdEJ0biA9ICQoJyNlbW90aWNvbnMnKTtcblx0ZW10QnRuLmh0bWwoJycpO1xuXHRlbXRCdG4uYXBwZW5kKCcgJyArIENTU0Vtb3RpY29uLmVtb3RpY29uaXplKCc6KScpKTtcblx0Y29uc3QgYSA9ICQoJyNjaGF0IC5hdWRpbycpO1xuXHRjb25zdCBzYnRuID0gJCgnI2NoYXQgLnNlbmQtYnRuJyk7XG5cdHsgLy9zY29wZVxuXHRcdF9sb2FkKCk7XG5cdFx0X3VwZGF0ZUF1ZGlvQnRuKCk7XG5cdFx0X3VwZGF0ZVNlbmRCdG4oKVxuXHR9XG5cdGEub2ZmKCkuY2xpY2soZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3QgcyA9IF9sb2FkKCk7XG5cdFx0bXV0ZWQgPSBzLmNoYXQubXV0ZWQgPSAhcy5jaGF0Lm11dGVkO1xuXHRcdF91cGRhdGVBdWRpb0J0bigpO1xuXHRcdFNldHRpbmdzLnNhdmUocyk7XG5cdH0pO1xuXHRzYnRuLm9mZigpLmNsaWNrKGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IHMgPSBfbG9hZCgpO1xuXHRcdHNlbmRPbiA9IHMuY2hhdC5zZW5kT24gPSBzLmNoYXQuc2VuZE9uICE9PSBTRU5EX0NUUkwgPyBTRU5EX0NUUkwgOiBTRU5EX0VOVEVSO1xuXHRcdF91cGRhdGVTZW5kQnRuKCk7XG5cdFx0U2V0dGluZ3Muc2F2ZShzKTtcblx0fSk7XG5cdCQoJyNjaGF0ICNoeXBlcmxpbmsnKS5wYXJlbnQoKS5maW5kKCdidXR0b24nKS5vZmYoKS5jbGljayhmdW5jdGlvbigpIHtcblx0XHRfaW5zZXJ0TGluaygpO1xuXHR9KTtcblx0Q1NTRW1vdGljb24uYW5pbWF0ZSgpO1xufVxuZnVuY3Rpb24gaXNDbG9zZWQoKSB7XG5cdHJldHVybiBjaGF0UGFuZWwuaGFzQ2xhc3MoJ2Nsb3NlZCcpO1xufVxuZnVuY3Rpb24gYWN0aXZhdGVUYWIoaWQpIHtcblx0aWYgKGlzQ2xvc2VkKCkpIHtcblx0XHR0YWJzLmZpbmQoJy5uYXYubmF2LXRhYnMgLm5hdi1saW5rJykuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGNvbnN0IHNlbGYgPSAkKHRoaXMpXG5cdFx0XHRcdCwgdGFiSWQgPSBzZWxmLmF0dHIoJ2FyaWEtY29udHJvbHMnKVxuXHRcdFx0XHQsIHRhYiA9ICQoJyMnICsgdGFiSWQpO1xuXG5cdFx0XHRpZiAodGFiSWQgPT09IGlkKSB7XG5cdFx0XHRcdHNlbGYuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuXHRcdFx0XHR0YWIuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuXHRcdFx0XHRzZWxmLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCB0cnVlKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNlbGYucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuXHRcdFx0XHR0YWIucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuXHRcdFx0XHRzZWxmLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCBmYWxzZSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0gZWxzZSB7XG5cdFx0JCgnI2NoYXRUYWJzIGxpIGFbYXJpYS1jb250cm9scz1cIicgKyBpZCArICdcIl0nKS50YWIoJ3Nob3cnKTtcblx0fVxuXHQkKCcjYWN0aXZlQ2hhdFRhYicpLnZhbChpZCkudHJpZ2dlcignY2hhbmdlJyk7XG59XG5mdW5jdGlvbiBfcmVpbml0KG9wdHMpIHtcblx0dXNlcklkID0gb3B0cy51c2VySWQ7XG5cdGFsbFByZWZpeCA9IG9wdHMuYWxsO1xuXHRyb29tUHJlZml4ID0gb3B0cy5yb29tO1xuXHRERUZfU0VORCA9IG9wdHMuc2VuZE9uRW50ZXIgPT09IHRydWUgPyBTRU5EX0VOVEVSIDogU0VORF9DVFJMO1xuXHRzZW5kT24gPSBERUZfU0VORDtcblx0Y2hhdFBhbmVsID0gJCgnI2NoYXRQYW5lbCcpO1xuXHRjbGVhclRpbWVvdXQoY2hhdFBhbmVsLmRhdGEoJ3RpbWVvdXQnKSk7XG5cdGN0cmxCbGsgPSAkKCcjY2hhdFBvcHVwIC5jb250cm9sLmJsb2NrJyk7XG5cdG5ld01zZ05vdGlmaWNhdGlvbiA9IGN0cmxCbGsuZGF0YSgnbmV3LW1zZycpO1xuXHRlZGl0b3IgPSAkKCcjY2hhdE1lc3NhZ2UgLnd5c2l3eWctZWRpdG9yJyk7XG5cdGluaXRUb29sYmFyKCk7XG5cdHRhYnMgPSAkKFwiI2NoYXRUYWJzXCIpO1xuXHR0YWJzLm9mZigpLm9uKCdzaG93bi5icy50YWInLCBmdW5jdGlvbiAoZSkge1xuXHRcdGNvbnN0IGN0ID0gJChlLnRhcmdldCkuYXR0cignYXJpYS1jb250cm9scycpO1xuXHRcdF9zY3JvbGxEb3duKCQoJyMnICsgY3QpKTtcblx0XHQkKCcjYWN0aXZlQ2hhdFRhYicpLnZhbChjdCkudHJpZ2dlcignY2hhbmdlJyk7XG5cdH0pO1xuXHR0YWJzLmRlbGVnYXRlKFwiLmJ0bi5jbG9zZS1jaGF0XCIsIFwiY2xpY2tcIiwgZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3QgcGFuZWxJZCA9ICQodGhpcykuY2xvc2VzdChcImFcIikuYXR0cihcImFyaWEtY29udHJvbHNcIik7XG5cdFx0X3JlbW92ZVRhYihwYW5lbElkKTtcblx0XHQkKCcjY2hhdFRhYnMgbGk6bGFzdC1jaGlsZCBhJykudGFiKCdzaG93Jyk7XG5cdH0pO1xuXHRpZiAocm9vbU1vZGUpIHtcblx0XHRfcmVtb3ZlUmVzaXplKCk7XG5cdH0gZWxzZSB7XG5cdFx0Y3RybEJsay5hdHRyKCd0aXRsZScsICcnKTtcblx0XHRjaGF0UGFuZWwucmVtb3ZlQ2xhc3MoJ3Jvb20gb3BlbmVkJykuYWRkQ2xhc3MoJ2Nsb3NlZCcpXG5cdFx0XHQub2ZmKCdtb3VzZWVudGVyIG1vdXNlbGVhdmUnKS5yZXNpemFibGUoe1xuXHRcdFx0XHRoYW5kbGVzOiAnbiwgJyArIChTZXR0aW5ncy5pc1J0bCA/ICdlJyA6ICd3Jylcblx0XHRcdFx0LCBkaXNhYmxlZDogaXNDbG9zZWQoKVxuXHRcdFx0XHQsIG1pbkhlaWdodDogMTk1XG5cdFx0XHRcdCwgbWluV2lkdGg6IDI2MFxuXHRcdFx0XHQsIHN0b3A6IGZ1bmN0aW9uKF8sIHVpKSB7XG5cdFx0XHRcdFx0Y2hhdFBhbmVsLmNzcyh7J3RvcCc6ICcnLCAnbGVmdCc6ICcnfSk7XG5cdFx0XHRcdFx0b3BlbmVkSGVpZ2h0ID0gdWkuc2l6ZS5oZWlnaHQgKyAncHgnO1xuXHRcdFx0XHRcdF9fc2V0Q3NzSGVpZ2h0KG9wZW5lZEhlaWdodCk7XG5cdFx0XHRcdFx0X19zZXRDc3NXaWR0aCh1aS5zaXplLndpZHRoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0X19zZXRDc3NIZWlnaHQoY2xvc2VkU2l6ZSk7XG5cdH1cblx0Y3RybEJsay5vZmYoKS5jbGljayhfdG9nZ2xlKTtcblx0JCgnI2NoYXRNZXNzYWdlJykub2ZmKCkub24oJ2lucHV0IHByb3BlcnR5Y2hhbmdlIHBhc3RlJywgZnVuY3Rpb24gKCkge1xuXHRcdGNvbnN0IHJvb20gPSAkKCcucm9vbS1ibG9jayAucm9vbS1jb250YWluZXInKTtcblx0XHRpZiAocm9vbS5sZW5ndGgpIHtcblx0XHRcdGlmICghIXR5cGluZ1RpbWVyKSB7XG5cdFx0XHRcdGNsZWFyVGltZW91dCh0eXBpbmdUaW1lcik7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjaGF0QWN0aXZpdHkoJ3R5cGluZ19zdGFydCcsIHJvb20uZGF0YSgncm9vbS1pZCcpKTtcblx0XHRcdH1cblx0XHRcdHR5cGluZ1RpbWVyID0gc2V0VGltZW91dChkb25lVHlwaW5nLCBkb25lVHlwaW5nSW50ZXJ2YWwpO1xuXHRcdH1cblx0fSk7XG5cdCQoJyNjaGF0IC5jaGF0LXRvb2xiYXIgLmxpbmstZmllbGQnKS5vZmYoKS5vbigna2V5cHJlc3MnLCBmdW5jdGlvbihldnQpIHtcblx0XHRpZiAoZXZ0LmtleUNvZGUgPT09IDEzKSB7XG5cdFx0XHQkKHRoaXMpLnBhcmVudCgpLmZpbmQoJ2J1dHRvbicpLnRyaWdnZXIoJ2NsaWNrJyk7XG5cdFx0fVxuXHRcdHJldHVybiBldnQua2V5Q29kZSAhPT0gMTM7XG5cdH0pO1xuXHRpbml0ZWQgPSB0cnVlO1xufVxuZnVuY3Rpb24gX3JlbW92ZVRhYihpZCkge1xuXHQkKCcjY2hhdFRhYnMgbGkgYVthcmlhLWNvbnRyb2xzPVwiJyArIGlkICsgJ1wiXScpLnBhcmVudCgpLnJlbW92ZSgpO1xuXHQkKCcjJyArIGlkKS5yZW1vdmUoKTtcbn1cbmZ1bmN0aW9uIF9hZGRUYWIoaWQsIGxhYmVsKSB7XG5cdGlmICghaW5pdGVkKSB7XG5cdFx0X3JlaW5pdCh7fSk7XG5cdH1cblx0aWYgKCQoJyNjaGF0JykubGVuZ3RoIDwgMSB8fCAkKCcjJyArIGlkKS5sZW5ndGgpIHtcblx0XHRyZXR1cm47XG5cdH1cblx0aWYgKCFsYWJlbCkge1xuXHRcdGxhYmVsID0gaWQgPT09IFwiY2hhdFRhYi1hbGxcIiA/IGFsbFByZWZpeCA6IHJvb21QcmVmaXggKyBpZC5zdWJzdHIoOSk7XG5cdH1cblx0Y29uc3QgbGluayA9ICQoJzxhIGNsYXNzPVwibmF2LWxpbmtcIiBkYXRhLWJzLXRvZ2dsZT1cInRhYlwiIHJvbGU9XCJ0YWJcIj4nKVxuXHRcdC5hdHRyKCdhcmlhLWNvbnRyb2xzJywgaWQpXG5cdFx0LmF0dHIoJ2hyZWYnLCAnIycgKyBpZCkudGV4dChsYWJlbClcblx0XHQsIGxpID0gJCgnPGxpIGNsYXNzPVwibmF2LWl0ZW1cIj4nKS5hcHBlbmQobGluayk7XG5cdGlmIChpZC5pbmRleE9mKFwiY2hhdFRhYi11XCIpID09PSAwKSB7XG5cdFx0bGluay5hcHBlbmQoT21VdGlsLnRtcGwoJyNjaGF0LWNsb3NlLWJsb2NrJykpO1xuXHR9XG5cdHRhYnMuZmluZCgnLm5hdi5uYXYtdGFicycpLmFwcGVuZChsaSk7XG5cdGNvbnN0IG1zZ0FyZWEgPSBPbVV0aWwudG1wbCgnI2NoYXQtbXNnLWFyZWEtdGVtcGxhdGUnLCBpZCk7XG5cdHRhYnMuZmluZCgnLnRhYi1jb250ZW50JykuYXBwZW5kKG1zZ0FyZWEpO1xuXHRtc2dBcmVhLmFwcGVuZCgkKCc8ZGl2IGNsYXNzPVwiY2xlYXIgaWNvbnMgYWN0aW9ucyBmbG9hdC1zdGFydFwiPicpLmFkZENsYXNzKCdzaG9ydCcpXG5cdFx0XHQuYXBwZW5kKE9tVXRpbC50bXBsKCcjY2hhdC1hY3Rpb25zLXNob3J0LXRlbXBsYXRlJykpKTtcblx0bXNnQXJlYS5hcHBlbmQoJCgnPGRpdiBjbGFzcz1cImNsZWFyIGljb25zIGFjdGlvbnMgZmxvYXQtc3RhcnRcIj4nKS5hZGRDbGFzcygnc2hvcnQtbW9kJylcblx0XHRcdC5hcHBlbmQoT21VdGlsLnRtcGwoJyNjaGF0LWFjdGlvbnMtc2hvcnQtdGVtcGxhdGUnKSlcblx0XHRcdC5hcHBlbmQoT21VdGlsLnRtcGwoJyNjaGF0LWFjdGlvbnMtYWNjZXB0LXRlbXBsYXRlJykpKTtcblx0bXNnQXJlYS5hcHBlbmQoJCgnPGRpdiBjbGFzcz1cImNsZWFyIGljb25zIGFjdGlvbnMgZmxvYXQtc3RhcnRcIj4nKS5hZGRDbGFzcygnZnVsbCcpXG5cdFx0XHQuYXBwZW5kKE9tVXRpbC50bXBsKCcjY2hhdC1hY3Rpb25zLXNob3J0LXRlbXBsYXRlJykpXG5cdFx0XHQuYXBwZW5kKE9tVXRpbC50bXBsKCcjY2hhdC1hY3Rpb25zLW90aGVycy10ZW1wbGF0ZScpLmNoaWxkcmVuKCkuY2xvbmUoKSkpO1xuXHRtc2dBcmVhLmFwcGVuZCgkKCc8ZGl2IGNsYXNzPVwiY2xlYXIgaWNvbnMgYWN0aW9ucyBmbG9hdC1zdGFydFwiPicpLmFkZENsYXNzKCdmdWxsLW1vZCcpXG5cdFx0XHQuYXBwZW5kKE9tVXRpbC50bXBsKCcjY2hhdC1hY3Rpb25zLXNob3J0LXRlbXBsYXRlJykpXG5cdFx0XHQuYXBwZW5kKE9tVXRpbC50bXBsKCcjY2hhdC1hY3Rpb25zLW90aGVycy10ZW1wbGF0ZScpLmNoaWxkcmVuKCkuY2xvbmUoKSlcblx0XHRcdC5hcHBlbmQoT21VdGlsLnRtcGwoJyNjaGF0LWFjdGlvbnMtYWNjZXB0LXRlbXBsYXRlJykpKTtcblx0Y29uc3QgYWN0aW9ucyA9IF9faGlkZUFjdGlvbnMoKTtcblx0YWN0aW9ucy5maW5kKCcudXNlcicpLm9mZigpLmNsaWNrKGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IGUgPSAkKHRoaXMpLnBhcmVudCgpO1xuXHRcdHNob3dVc2VySW5mbyhlLmRhdGEoXCJ1c2VySWRcIikpO1xuXHR9KTtcblx0YWN0aW9ucy5maW5kKCcuYWRkJykub2ZmKCkuY2xpY2soZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3QgZSA9ICQodGhpcykucGFyZW50KCk7XG5cdFx0YWRkQ29udGFjdChlLmRhdGEoXCJ1c2VySWRcIikpO1xuXHR9KTtcblx0YWN0aW9ucy5maW5kKCcubmV3LWVtYWlsJykub2ZmKCkuY2xpY2soZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3QgZSA9ICQodGhpcykucGFyZW50KCk7XG5cdFx0cHJpdmF0ZU1lc3NhZ2UoZS5kYXRhKFwidXNlcklkXCIpKTtcblx0fSk7XG5cdGFjdGlvbnMuZmluZCgnLmludml0ZScpLm9mZigpLmNsaWNrKGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IGUgPSAkKHRoaXMpLnBhcmVudCgpO1xuXHRcdGludml0ZVVzZXIoZS5kYXRhKFwidXNlcklkXCIpKTtcblx0fSk7XG5cdGFjdGlvbnMuZmluZCgnLmFjY2VwdCcpLm9mZigpLmNsaWNrKGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IGUgPSAkKHRoaXMpLnBhcmVudCgpXG5cdFx0XHQsIG1zZ0lkID0gZS5kYXRhKCdtc2dJZCcpO1xuXHRcdGNoYXRBY3Rpdml0eSgnYWNjZXB0JywgZS5kYXRhKCdyb29tSWQnKSwgbXNnSWQpO1xuXHRcdF9faGlkZUFjdGlvbnMoKTtcblx0XHQkKCcjY2hhdC1tc2ctaWQtJyArIG1zZ0lkKS5yZW1vdmUoKTtcblx0fSk7XG5cdGFjdGl2YXRlVGFiKGlkKTtcbn1cbmZ1bmN0aW9uIF9faGlkZUFjdGlvbnMoKSB7XG5cdHJldHVybiAkKCcjY2hhdCAudGFiLWNvbnRlbnQgLm1lc3NhZ2VBcmVhIC5pY29ucycpLmhpZGUoKTtcbn1cbmZ1bmN0aW9uIF9fZ2V0QWN0aW9ucyhyb3cpIHtcblx0cmV0dXJuIHJvdy5jbG9zZXN0KCcubWVzc2FnZUFyZWEnKS5maW5kKCcuYWN0aW9ucy4nICsgcm93LmRhdGEoJ2FjdGlvbnMnKSk7XG59XG5mdW5jdGlvbiBfYWRkTWVzc2FnZShtKSB7XG5cdGlmICgkKCcjY2hhdCcpLmxlbmd0aCA+IDAgJiYgbSAmJiBtLnR5cGUgPT09IFwiY2hhdFwiKSB7XG5cdFx0bGV0IG1zZywgY20sIG5vdGlmeSA9IGZhbHNlO1xuXHRcdHdoaWxlICghIShjbSA9IG0ubXNnLnBvcCgpKSkge1xuXHRcdFx0bGV0IGFyZWEgPSAkKCcjJyArIGNtLnNjb3BlKTtcblx0XHRcdGlmIChjbS5mcm9tLmlkICE9PSB1c2VySWQgJiYgKGlzQ2xvc2VkKCkgfHwgIWFyZWEuaXMoJzp2aXNpYmxlJykpKSB7XG5cdFx0XHRcdG5vdGlmeSA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBhY3Rpb25zID0gKCdmdWxsJyA9PT0gY20uYWN0aW9ucyA/ICdmdWxsJyA6ICdzaG9ydCcpICsgKGNtLm5lZWRNb2RlcmF0aW9uID8gJy1tb2QnIDogJycpO1xuXHRcdFx0bXNnID0gT21VdGlsLnRtcGwoJyNjaGF0LW1zZy10ZW1wbGF0ZScsIG1zZ0lkUHJlZml4ICsgY20uaWQpXG5cdFx0XHRjb25zdCByb3cgPSBtc2cuZmluZCgnLnVzZXItcm93Jylcblx0XHRcdFx0LmRhdGEoJ3VzZXJJZCcsIGNtLmZyb20uaWQpXG5cdFx0XHRcdC5kYXRhKCdhY3Rpb25zJywgYWN0aW9ucylcblx0XHRcdFx0Lm1vdXNlZW50ZXIoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0X19oaWRlQWN0aW9ucygpO1xuXHRcdFx0XHRcdF9fZ2V0QWN0aW9ucygkKHRoaXMpKVxuXHRcdFx0XHRcdFx0LmRhdGEoJ3VzZXJJZCcsICQodGhpcykuZGF0YSgndXNlcklkJykpXG5cdFx0XHRcdFx0XHQuZGF0YSgncm9vbUlkJywgJCh0aGlzKS5kYXRhKCdyb29tSWQnKSlcblx0XHRcdFx0XHRcdC5kYXRhKCdtc2dJZCcsICQodGhpcykuZGF0YSgnbXNnSWQnKSlcblx0XHRcdFx0XHRcdC5jc3MoJ3RvcCcsICgkKHRoaXMpLmNsb3Nlc3QoJy5tc2ctcm93JylbMF0ub2Zmc2V0VG9wICsgMjApICsgJ3B4Jylcblx0XHRcdFx0XHRcdC5zaG93KCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0aWYgKGNtLm5lZWRNb2RlcmF0aW9uKSB7XG5cdFx0XHRcdHJvdy5wYXJlbnQoKS5hZGRDbGFzcygnbmVlZC1tb2RlcmF0aW9uJyk7XG5cdFx0XHRcdHJvdy5kYXRhKCdyb29tSWQnLCBjbS5zY29wZS5zdWJzdHJpbmcoOSkpXG5cdFx0XHRcdFx0LmRhdGEoJ21zZ0lkJywgY20uaWQpO1xuXHRcdFx0fVxuXHRcdFx0YXJlYS5tb3VzZWxlYXZlKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRfX2hpZGVBY3Rpb25zKCk7XG5cdFx0XHR9KTtcblx0XHRcdG1zZy5maW5kKCcuZnJvbScpLmRhdGEoJ3VzZXItaWQnLCBjbS5mcm9tLmlkKS5odG1sKGNtLmZyb20uZGlzcGxheU5hbWUgfHwgY20uZnJvbS5uYW1lKTtcblx0XHRcdG1zZy5maW5kKCcudGltZScpLmh0bWwoY20udGltZSkuYXR0cigndGl0bGUnLCBjbS5zZW50KTtcblx0XHRcdGlmICghYXJlYS5sZW5ndGgpIHtcblx0XHRcdFx0X2FkZFRhYihjbS5zY29wZSwgY20uc2NvcGVOYW1lKTtcblx0XHRcdFx0YXJlYSA9ICQoJyMnICsgY20uc2NvcGUpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKG0ubW9kZSA9PT0gXCJhY2NlcHRcIikge1xuXHRcdFx0XHQkKCcjY2hhdC1tc2ctaWQtJyArIGNtLmlkKS5yZW1vdmUoKTtcblx0XHRcdH1cblx0XHRcdGNvbnN0IGJ0bSA9IGFyZWFbMF0uc2Nyb2xsSGVpZ2h0IC0gKGFyZWEuc2Nyb2xsVG9wKCkgKyBhcmVhLmlubmVySGVpZ2h0KCkpIDwgMzsgLy9hcHByb3hpbWF0ZWx5IGVxdWFsXG5cdFx0XHRpZiAoYXJlYS5kYXRhKCdsYXN0RGF0ZScpICE9PSBjbS5kYXRlKSB7XG5cdFx0XHRcdGFyZWEuYXBwZW5kKE9tVXRpbC50bXBsKCcjY2hhdC1kYXRlLXRlbXBsYXRlJykuaHRtbChjbS5kYXRlKS5tb3VzZWVudGVyKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdF9faGlkZUFjdGlvbnMoKTtcblx0XHRcdFx0fSkpO1xuXHRcdFx0XHRhcmVhLmRhdGEoJ2xhc3REYXRlJywgY20uZGF0ZSk7XG5cdFx0XHR9XG5cdFx0XHRhcmVhLmFwcGVuZChtc2cpO1xuXHRcdFx0bXNnLmZpbmQoJy51c2VyLXJvdycpWzBdLnN0eWxlLmNzc1RleHQgPSBgXG5cdFx0XHRcdGJhY2tncm91bmQtaW1hZ2U6IHVybCgkeyghIWNtLmZyb20uaW1nID8gY20uZnJvbS5pbWcgOiAnLi9wcm9maWxlLycgKyBjbS5mcm9tLmlkICsgJz9hbnRpY2FjaGU9JyArIERhdGUubm93KCkpfSk7XG5cdFx0XHRcdGJhY2tncm91bmQtcG9zaXRpb24teDogJHtTZXR0aW5ncy5pc1J0bCA/ICdyaWdodCcgOiAnbGVmdCd9O1xuXHRcdFx0YDtcblxuXHRcdFx0bXNnLmZpbmQoJy5tc2cnKS5odG1sKENTU0Vtb3RpY29uLmVtb3RpY29uaXplKCEhY20ubWVzc2FnZSA/IGNtLm1lc3NhZ2UgOiBcIlwiKSk7XG5cdFx0XHRpZiAoYnRtKSB7XG5cdFx0XHRcdF9zY3JvbGxEb3duKGFyZWEpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAobm90aWZ5KSB7XG5cdFx0XHRjdHJsQmxrLmFkZENsYXNzKCdiZy13YXJuaW5nJyk7XG5cdFx0XHRpZiAoY2hhdFBhbmVsLmlzKCc6dmlzaWJsZScpICYmICFtdXRlZCkge1xuXHRcdFx0XHRPbVV0aWwubm90aWZ5KG5ld01zZ05vdGlmaWNhdGlvbiwgJ25ld19jaGF0X21zZycsICgpID0+IHtcblx0XHRcdFx0XHQvLyBpbXBvc3NpYmxlIHRvIHVzZSBOb3RpZmljYXRpb24gQVBJIGZyb20gaUZyYW1lXG5cdFx0XHRcdFx0YXVkaW8ucGxheSgpXG5cdFx0XHRcdFx0XHQudGhlbihmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0Ly8gQXV0b21hdGljIHBsYXliYWNrIHN0YXJ0ZWQhXG5cdFx0XHRcdFx0XHR9KS5jYXRjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0Ly8gQXV0b21hdGljIHBsYXliYWNrIGZhaWxlZC5cblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Q1NTRW1vdGljb24uYW5pbWF0ZSgpO1xuXHR9XG59XG5mdW5jdGlvbiBfc2V0T3BlbmVkKCkge1xuXHRfX3NldENzc1dpZHRoKG9wZW5lZFdpZHRoKTtcblx0Y2hhdFBhbmVsLnJlc2l6YWJsZSh7XG5cdFx0aGFuZGxlczogKFNldHRpbmdzLmlzUnRsID8gJ2UnIDogJ3cnKVxuXHRcdCwgbWluV2lkdGg6IDE2NVxuXHRcdCwgc3RvcDogZnVuY3Rpb24oXywgdWkpIHtcblx0XHRcdGNoYXRQYW5lbC5jc3MoeydsZWZ0JzogJycsICd3aWR0aCc6ICcnLCAnaGVpZ2h0JzogJyd9KTtcblx0XHRcdG9wZW5lZFdpZHRoID0gdWkuc2l6ZS53aWR0aCArICdweCc7XG5cdFx0XHRfX3NldENzc1dpZHRoKG9wZW5lZFdpZHRoKTtcblx0XHR9XG5cdH0pO1xufVxuZnVuY3Rpb24gX3JlbW92ZVJlc2l6ZSgpIHtcblx0aWYgKGNoYXRQYW5lbC5yZXNpemFibGUoJ2luc3RhbmNlJykgIT09IHVuZGVmaW5lZCkge1xuXHRcdGNoYXRQYW5lbC5yZXNpemFibGUoJ2Rlc3Ryb3knKTtcblx0fVxufVxuZnVuY3Rpb24gX29wZW4oaGFuZGxlcikge1xuXHRpZiAoaXNDbG9zZWQoKSkge1xuXHRcdGN0cmxCbGsucmVtb3ZlQ2xhc3MoJ2JnLXdhcm5pbmcnKTtcblx0XHRsZXQgb3B0cztcblx0XHRpZiAocm9vbU1vZGUpIHtcblx0XHRcdG9wdHMgPSB7d2lkdGg6IG9wZW5lZFdpZHRofTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0b3B0cyA9IHtoZWlnaHQ6IG9wZW5lZEhlaWdodH07XG5cdFx0XHRjaGF0UGFuZWwucmVzaXphYmxlKFwib3B0aW9uXCIsIFwiZGlzYWJsZWRcIiwgZmFsc2UpO1xuXHRcdH1cblx0XHRjaGF0UGFuZWwucmVtb3ZlQ2xhc3MoJ2Nsb3NlZCcpLmFuaW1hdGUob3B0cywgMTAwMCwgZnVuY3Rpb24oKSB7XG5cdFx0XHRfX2hpZGVBY3Rpb25zKCk7XG5cdFx0XHRjaGF0UGFuZWwucmVtb3ZlQ2xhc3MoJ2Nsb3NlZCcpO1xuXHRcdFx0Y2hhdFBhbmVsLmNzcyh7J2hlaWdodCc6ICcnLCAnd2lkdGgnOiAnJ30pO1xuXHRcdFx0aWYgKHR5cGVvZihoYW5kbGVyKSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRoYW5kbGVyKCk7XG5cdFx0XHR9XG5cdFx0XHRjdHJsQmxrLmF0dHIoJ3RpdGxlJywgY3RybEJsay5kYXRhKCd0dGwtdW5kb2NrJykpO1xuXHRcdFx0aWYgKHJvb21Nb2RlKSB7XG5cdFx0XHRcdF9zZXRPcGVuZWQoKTtcblx0XHRcdFx0aWYgKHR5cGVvZih3aW5kb3cuV2JBcmVhKSA9PT0gJ29iamVjdCcpIHtcblx0XHRcdFx0XHR3aW5kb3cuV2JBcmVhLnJlc2l6ZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRfX3NldENzc0hlaWdodChvcGVuZWRIZWlnaHQpO1xuXHRcdFx0fVxuXHRcdFx0X3NldEFyZWFIZWlnaHQoKTtcblx0XHR9KTtcblx0fVxufVxuZnVuY3Rpb24gX2Nsb3NlKGhhbmRsZXIpIHtcblx0aWYgKCFpc0Nsb3NlZCgpKSB7XG5cdFx0bGV0IG9wdHM7XG5cdFx0aWYgKHJvb21Nb2RlKSB7XG5cdFx0XHRvcHRzID0ge3dpZHRoOiBjbG9zZWRTaXplUHh9O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvcHRzID0ge2hlaWdodDogY2xvc2VkU2l6ZVB4fTtcblx0XHRcdGNoYXRQYW5lbC5yZXNpemFibGUoXCJvcHRpb25cIiwgXCJkaXNhYmxlZFwiLCB0cnVlKTtcblx0XHR9XG5cdFx0Y2hhdFBhbmVsLmFuaW1hdGUob3B0cywgMTAwMCwgZnVuY3Rpb24oKSB7XG5cdFx0XHRjaGF0UGFuZWwuYWRkQ2xhc3MoJ2Nsb3NlZCcpLmNzcyh7J2hlaWdodCc6ICcnLCAnd2lkdGgnOiAnJ30pO1xuXHRcdFx0aWYgKHJvb21Nb2RlKSB7XG5cdFx0XHRcdF9fc2V0Q3NzV2lkdGgoY2xvc2VkU2l6ZVB4KTtcblx0XHRcdFx0X3JlbW92ZVJlc2l6ZSgpO1xuXHRcdFx0XHRpZiAodHlwZW9mKHdpbmRvdy5XYkFyZWEpID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRcdHdpbmRvdy5XYkFyZWEucmVzaXplKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdF9fc2V0Q3NzSGVpZ2h0KGNsb3NlZFNpemVQeCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAodHlwZW9mKGhhbmRsZXIpID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRcdGhhbmRsZXIoKTtcblx0XHRcdH1cblx0XHRcdGN0cmxCbGsuYXR0cigndGl0bGUnLCBjdHJsQmxrLmRhdGEoJ3R0bC1kb2NrJykpO1xuXHRcdH0pO1xuXHR9XG59XG5mdW5jdGlvbiBfdG9nZ2xlKCkge1xuXHRpZiAoaXNDbG9zZWQoKSkge1xuXHRcdF9vcGVuKCk7XG5cdH0gZWxzZSB7XG5cdFx0X2Nsb3NlKCk7XG5cdH1cbn1cbmZ1bmN0aW9uIF9lZGl0b3JBcHBlbmQoX2Vtb3RpY29uKSB7XG5cdGVkaXRvci5odG1sKGVkaXRvci5odG1sKCkgKyAnICcgKyBfZW1vdGljb24gKyAnICcpLnRyaWdnZXIoJ2NoYW5nZScpO1xufVxuZnVuY3Rpb24gX2NsZWFuKCkge1xuXHRlZGl0b3IuaHRtbCgnJykudHJpZ2dlcignY2hhbmdlJyk7XG59XG5mdW5jdGlvbiBfc2V0Um9vbU1vZGUoX21vZGUpIHtcblx0cm9vbU1vZGUgPSBfbW9kZTtcblx0aWYgKGluaXRlZCAmJiAhcm9vbU1vZGUpIHtcblx0XHQvLyByZW1vdmUgYWxsIHByaXZhdGUgY2hhdHMgb24gcm9vbSBleGl0XG5cdFx0JCgnbGlbYXJpYS1jb250cm9sc149XCJjaGF0VGFiLXVcIl0nKS5yZW1vdmUoKTtcblx0XHQkKCdkaXZbaWRePVwiY2hhdFRhYi11XCJdJykucmVtb3ZlKCk7XG5cdH1cblx0X3JlaW5pdCh7dXNlcklkOiB1c2VySWQsIGFsbDogYWxsUHJlZml4LCByb29tOiByb29tUHJlZml4LCBzZW5kT25FbnRlcjogc2VuZE9uID09PSBTRU5EX0VOVEVSfSk7XG59XG5mdW5jdGlvbiBfc2Nyb2xsRG93bihhcmVhKSB7XG5cdGFyZWEuYW5pbWF0ZSh7XG5cdFx0c2Nyb2xsVG9wOiBhcmVhWzBdLnNjcm9sbEhlaWdodFxuXHR9LCAzMDApO1xufVxuZnVuY3Rpb24gX3NldEFyZWFIZWlnaHQoKSB7XG5cdCQoJyNjaGF0IC5tZXNzYWdlQXJlYScpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0X3Njcm9sbERvd24oJCh0aGlzKSk7XG5cdH0pO1xufVxuZnVuY3Rpb24gX2luc2VydExpbmsoKSB7XG5cdGNvbnN0IHRleHQgPSAkKCcjY2hhdCAjaHlwZXJsaW5rJykucGFyZW50KCkuZmluZCgnaW5wdXQnKS52YWwoKTtcblx0aWYgKCcnID09PSB0ZXh0KSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGxldCB1cmwgPSB0ZXh0LnRyaW0oKTtcblx0aWYgKCcnID09PSB1cmwpIHtcblx0XHRyZXR1cm47XG5cdH1cblx0aWYgKCEvXihodHRwcz86KT9cXC9cXC8vaS50ZXN0KHVybCkpIHtcblx0XHR1cmwgPSAnaHR0cDovLycgKyB1cmw7XG5cdH1cblx0Y29uc3QgYSA9ICQoJzxkaXY+JykuYXBwZW5kKCQoJzxhPjwvYT4nKS5hdHRyKCd0YXJnZXQnLCAnX2JsYW5rJykuYXR0cignaHJlZicsIHVybCkudGV4dCh1cmwpKS5odG1sKCk7XG5cdGlmICh3aW5kb3cuZ2V0U2VsZWN0aW9uKSB7XG5cdFx0Y29uc3Qgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuXHRcdGlmIChzZWwucmFuZ2VDb3VudCkge1xuXHRcdFx0Y29uc3QgcmFuZ2UgPSBzZWwuZ2V0UmFuZ2VBdCgwKTtcblx0XHRcdGlmICgkKHJhbmdlLnN0YXJ0Q29udGFpbmVyKS5wYXJlbnRzKCcud3lzaXd5Zy1lZGl0b3InKS5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdHJhbmdlLmRlbGV0ZUNvbnRlbnRzKCk7XG5cdFx0XHRcdHJhbmdlLmluc2VydE5vZGUoYSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRfZWRpdG9yQXBwZW5kKGEpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufVxuZnVuY3Rpb24gX3R5cGluZ0FjdGl2aXR5KHVpZCwgYWN0aXZlKSB7XG5cdGlmICh0eXBlb2YoUm9vbSkgIT09ICdvYmplY3QnKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGNvbnN0IGMgPSBSb29tLmdldENsaWVudCh1aWQpO1xuXHRpZiAoIWMpIHtcblx0XHRyZXR1cm47XG5cdH1cblx0Y29uc3QgdSA9IGMuZmluZCgnLnR5cGluZy1hY3Rpdml0eScpO1xuXHRpZiAoIXUpIHtcblx0XHRyZXR1cm47XG5cdH1cblx0aWYgKGFjdGl2ZSkge1xuXHRcdHUuYWRkQ2xhc3MoXCJ0eXBpbmdcIik7XG5cdH0gZWxzZSB7XG5cdFx0dS5yZW1vdmVDbGFzcyhcInR5cGluZ1wiKTtcblx0fVxufVxuXG4kKGZ1bmN0aW9uKCkge1xuXHRXaWNrZXQuRXZlbnQuc3Vic2NyaWJlKFwiL3dlYnNvY2tldC9tZXNzYWdlXCIsIGZ1bmN0aW9uKF8sIG1zZykge1xuXHRcdHRyeSB7XG5cdFx0XHRpZiAobXNnIGluc3RhbmNlb2YgQmxvYikge1xuXHRcdFx0XHRyZXR1cm47IC8vcGluZ1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgbSA9IEpTT04ucGFyc2UobXNnKTtcblx0XHRcdGlmIChtKSB7XG5cdFx0XHRcdHN3aXRjaChtLnR5cGUpIHtcblx0XHRcdFx0XHRjYXNlIFwiY2hhdFwiOlxuXHRcdFx0XHRcdFx0aWYgKCdjbGVhbicgPT09IG0uYWN0aW9uKSB7XG5cdFx0XHRcdFx0XHRcdCQoJyMnICsgbS5zY29wZSkuaHRtbCgnJyk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRfYWRkTWVzc2FnZShtKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgXCJ0eXBpbmdcIjpcblx0XHRcdFx0XHRcdF90eXBpbmdBY3Rpdml0eShtLnVpZCwgbS5hY3RpdmUpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdC8vbm8tb3Bcblx0XHR9XG5cdH0pO1xuXHRmdW5jdGlvbiBfY2FuY2VsQXNrTm90aWZpY2F0aW9uKCkge1xuXHRcdCQoZG9jdW1lbnQpLm9mZignY2xpY2snLCBfYXNrTm90aWZpY2F0aW9uKVxuXHR9XG5cdGZ1bmN0aW9uIF9hc2tOb3RpZmljYXRpb24oKSB7XG5cdFx0T21VdGlsLnJlcXVlc3ROb3RpZnlQZXJtaXNzaW9uKF9jYW5jZWxBc2tOb3RpZmljYXRpb24sIF9jYW5jZWxBc2tOb3RpZmljYXRpb24pO1xuXHR9XG5cdCQoZG9jdW1lbnQpLm9uKCdjbGljaycsIF9hc2tOb3RpZmljYXRpb24pO1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRTRU5EX0VOVEVSOiBTRU5EX0VOVEVSXG5cdCwgU0VORF9DVFJMOiBTRU5EX0NUUkxcblxuXHQsIHJlaW5pdDogX3JlaW5pdFxuXHQsIHJlbW92ZVRhYjogX3JlbW92ZVRhYlxuXHQsIGFkZFRhYjogX2FkZFRhYlxuXHQsIGFkZE1lc3NhZ2U6IF9hZGRNZXNzYWdlXG5cdCwgb3BlbjogX29wZW5cblx0LCBzZXRPcGVuZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdF9vcGVuKGZ1bmN0aW9uKCkge1xuXHRcdFx0X3NldE9wZW5lZCgpO1xuXHRcdH0pO1xuXHR9XG5cdCwgY2xvc2U6IF9jbG9zZVxuXHQsIHRvZ2dsZTogX3RvZ2dsZVxuXHQsIHNldFJvb21Nb2RlOiBfc2V0Um9vbU1vZGVcblx0LCBjbGVhbjogX2NsZWFuXG5cdCwgcmVsb2FkOiAoKSA9PiB7XG5cdFx0X2xvYWQoKTtcblx0XHRfdXBkYXRlQXVkaW9CdG4oKTtcblx0XHRfdXBkYXRlU2VuZEJ0bigpO1xuXHR9XG5cdCwgdmFsaWRhdGU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiAhIWVkaXRvciAmJiBlZGl0b3IudGV4dCgpLnRyaW0oKS5sZW5ndGggPiAwO1xuXHR9XG59O1xuIiwiLypcbiAqIEJhc2VkIG9uXG4gKlxuICogalF1ZXJ5IENTU0Vtb3RpY29ucyBwbHVnaW4gMC4yLjlcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTAgU3RldmUgU2Nod2FydHogKEphbmdvU3RldmUpXG4gKlxuICogRHVhbCBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGFuZCBHUEwgbGljZW5zZXM6XG4gKiAgIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG4gKiAgIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwuaHRtbFxuICpcbiAqIERhdGU6IFN1biBPY3QgMjIgMTowMDowMCAyMDEwIC0wNTAwXG4gKi9cbmNvbnN0IGVzY2FwZUNoYXJhY3RlcnMgPSBbXCIpXCIsIFwiKFwiLCBcIipcIiwgXCJbXCIsIFwiXVwiLCBcIntcIiwgXCJ9XCIsIFwifFwiLCBcIl5cIiwgXCI8XCIsIFwiPlwiLCBcIlxcXFxcIiwgXCI/XCIsIFwiK1wiLCBcIj1cIiwgXCIuXCJdXG5cdCwgc3BlY2lhbFJlZ2V4ID0gbmV3IFJlZ0V4cCgnKFxcXFwnICsgZXNjYXBlQ2hhcmFjdGVycy5qb2luKCd8XFxcXCcpICsgJyknLCAnZycpXG5cdC8vIE9uZSBvZiB0aGVzZSBjaGFyYWN0ZXJzIG11c3QgYmUgcHJlc2VudCBiZWZvcmUgdGhlIG1hdGNoZWQgZW1vdGljb24sIG9yIHRoZSBtYXRjaGVkIGVtb3RpY29uIG11c3QgYmUgdGhlIGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgY29udGFpbmVyIEhUTUxcblx0Ly8gIFRoaXMgaXMgdG8gZW5zdXJlIHRoYXQgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIG1pZGRsZSBvZiBIVE1MIHByb3BlcnRpZXMgb3IgVVJMcyBhcmUgbm90IG1hdGNoZWQgYXMgZW1vdGljb25zXG5cdC8vICBCZWxvdyBtYXRjaGVzIF4gKGZpcnN0IGNoYXJhY3RlciBpbiBjb250YWluZXIgSFRNTCksIFxccyAod2hpdGVzcGFjZSBsaWtlIHNwYWNlIG9yIHRhYiksIG9yIFxcMCAoTlVMTCBjaGFyYWN0ZXIpXG5cdC8vICg8XFxcXFMrLio+KSBtYXRjaGVzIDxcXFxcUysuKj4gKG1hdGNoZXMgYW4gSFRNTCB0YWcgbGlrZSA8c3Bhbj4gb3IgPGRpdj4pLCBidXQgaGF2ZW4ndCBxdWl0ZSBnb3R0ZW4gaXQgd29ya2luZyB5ZXQsIG5lZWQgdG8gcHVzaCB0aGlzIGZpeCBub3dcblx0LCBwcmVNYXRjaCA9ICcoXnxbXFxcXHNcXFxcMF0pJ1xuXHQsIGVtb3RpY29ucyA9IFtdXG5cdCwgbWF0Y2hlcnMgPSBbXVxuXHQsIGRlZmF1bHRzID0ge2FuaW1hdGU6IHRydWUsIGRlbGF5OiA1MDAsIGV4Y2x1ZGU6ICdwcmUsY29kZSwubm8tZW1vdGljb25zJ307XG5cbmZ1bmN0aW9uIGNyZWF0ZU1hdGNoZXIobSkge1xuXHRjb25zdCBzdHIgPSBtLnRleHQucmVwbGFjZShzcGVjaWFsUmVnZXgsICdcXFxcJDEnKTtcblx0bS5yZWdleHAgPSBuZXcgUmVnRXhwKHByZU1hdGNoICsgJygnICsgc3RyICsgJyknLCAnZycpO1xuXHRyZXR1cm4gbTtcbn1cbmZ1bmN0aW9uIGFkZE1hdGNoZXJzKGFycikge1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7ICsraSkge1xuXHRcdGNvbnN0IG8gPSBhcnJbaV1cblx0XHRsZXQgbSA9IHR5cGVvZihvKSA9PT0gJ29iamVjdCcgPyBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG8pKSA6IHt0ZXh0OiBvLCBjc3NDbGFzczogJyAnfTtcblx0XHRlbW90aWNvbnMucHVzaChtLnRleHQpO1xuXG5cdFx0bWF0Y2hlcnMucHVzaChjcmVhdGVNYXRjaGVyKG0pKTtcblx0XHRpZiAobS50ZXh0LmluZGV4T2YoJz0nKSA+IC0xKSB7XG5cdFx0XHRtID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShtKSk7XG5cdFx0XHRtLnRleHQgPSBtLnRleHQucmVwbGFjZSgvPS9nLCAnJiM2MTsnKS5yZXBsYWNlKC9bK10vZywgJyYjNDM7Jyk7XG5cdFx0XHRtYXRjaGVycy5wdXNoKGNyZWF0ZU1hdGNoZXIobSkpO1xuXHRcdH1cblx0XHRpZiAobS50ZXh0LmluZGV4T2YoJ1xcJycpID4gLTEpIHtcblx0XHRcdG0gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG0pKTtcblx0XHRcdG0udGV4dCA9IG0udGV4dC5yZXBsYWNlKC8nL2csICcmIzM5OycpO1xuXHRcdFx0bWF0Y2hlcnMucHVzaChjcmVhdGVNYXRjaGVyKG0pKTtcblx0XHR9XG5cdH1cbn1cbmFkZE1hdGNoZXJzKFtcblx0XCI6LSlcIiwgXCI6bylcIiwgXCI6YylcIiwgXCI6XilcIiwgXCI6LURcIiwgXCI6LShcIiwgXCI6LTlcIiwgXCI7LSlcIiwgXCI6LVBcIiwgXCI6LXBcIiwgXCI6LcOeXCIsIFwiOi1iXCIsIFwiOi1PXCIsIFwiOi0vXCIsIFwiOi1YXCIsIFwiOi0jXCIsIFwiOicoXCIsIFwiQi0pXCIsIFwiOC0pXCIsIFwiOyooXCIsIFwiOi0qXCIsIFwiOi1cXFxcXCIsXG5cdFwiPy0pXCIgLy8gPD09IFRoaXMgaXMgbXkgb3duIGludmVudGlvbiwgaXQncyBhIHNtaWxpbmcgcGlyYXRlICh3aXRoIGFuIGV5ZS1wYXRjaCkhXG5dKTtcbmFkZE1hdGNoZXJzKFsgLy8gc2VwYXJhdGUgdGhlc2Ugb3V0IHNvIHRoYXQgd2UgY2FuIGFkZCBhIGxldHRlci1zcGFjaW5nIGJldHdlZW4gdGhlIGNoYXJhY3RlcnMgZm9yIGJldHRlciBwcm9wb3J0aW9uc1xuXHRcIjopXCIsIFwiOl1cIiwgXCI9XVwiLCBcIj0pXCIsIFwiOClcIiwgXCI6fVwiLCBcIjpEXCIsIFwiOihcIiwgXCI6W1wiLCBcIjp7XCIsIFwiPShcIiwgXCI7KVwiLCBcIjtdXCIsIFwiO0RcIiwgXCI6UFwiLCBcIjpwXCIsIFwiPVBcIiwgXCI9cFwiLCBcIjpiXCIsIFwiOsOeXCIsIFwiOk9cIiwgXCI6L1wiLCBcIj0vXCIsIFwiOlNcIiwgXCI6I1wiLCBcIjpYXCIsIFwiQilcIiwgXCI6fFwiLCBcIjpcXFxcXCIsIFwiPVxcXFxcIiwgXCI6KlwiLCBcIjomZ3Q7XCIsIFwiOiZsdDtcIlxuXSk7XG5hZGRNYXRjaGVycyhbIC8vIGVtb3RpY29ucyB0byBiZSB0cmVhdGVkIHdpdGggYSBzcGVjaWFsIGNsYXNzLCBoYXNoIHNwZWNpZmllcyB0aGUgYWRkaXRpb25hbCBjbGFzcyB0byBhZGQsIGFsb25nIHdpdGggc3RhbmRhcmQgY3NzLWVtb3RpY29uIGNsYXNzXG5cdHt0ZXh0OiBcIiZndDs6KVwiLCBjc3NDbGFzczogXCJyZWQtZW1vdGljb24gc21hbGwtZW1vdGljb24gc3BhY2VkLWVtb3RpY29uXCJ9LFxuXHR7dGV4dDogXCImZ3Q7OylcIiwgY3NzQ2xhc3M6IFwicmVkLWVtb3RpY29uIHNtYWxsLWVtb3RpY29uIHNwYWNlZC1lbW90aWNvblwifSxcblx0e3RleHQ6IFwiJmd0OzooXCIsIGNzc0NsYXNzOiBcInJlZC1lbW90aWNvbiBzbWFsbC1lbW90aWNvbiBzcGFjZWQtZW1vdGljb25cIn0sXG5cdHt0ZXh0OiBcIiZndDs6IClcIiwgY3NzQ2xhc3M6IFwicmVkLWVtb3RpY29uIHNtYWxsLWVtb3RpY29uXCJ9LFxuXHR7dGV4dDogXCImZ3Q7OyApXCIsIGNzc0NsYXNzOiBcInJlZC1lbW90aWNvbiBzbWFsbC1lbW90aWNvblwifSxcblx0e3RleHQ6IFwiJmd0OzogKFwiLCBjc3NDbGFzczogXCJyZWQtZW1vdGljb24gc21hbGwtZW1vdGljb25cIn0sXG5cdHt0ZXh0OiBcIjsoXCIsIGNzc0NsYXNzOiBcInJlZC1lbW90aWNvbiBzcGFjZWQtZW1vdGljb25cIn0sXG5cdHt0ZXh0OiBcIiZsdDszXCIsIGNzc0NsYXNzOiBcInBpbmstZW1vdGljb24gY291bnRlci1yb3RhdGVkXCJ9LFxuXHR7dGV4dDogXCJPX09cIiwgY3NzQ2xhc3M6IFwibm8tcm90YXRlXCJ9LFxuXHR7dGV4dDogXCJvX29cIiwgY3NzQ2xhc3M6IFwibm8tcm90YXRlXCJ9LFxuXHR7dGV4dDogXCIwX29cIiwgY3NzQ2xhc3M6IFwibm8tcm90YXRlXCJ9LFxuXHR7dGV4dDogXCJPX29cIiwgY3NzQ2xhc3M6IFwibm8tcm90YXRlXCJ9LFxuXHR7dGV4dDogXCJUX1RcIiwgY3NzQ2xhc3M6IFwibm8tcm90YXRlXCJ9LFxuXHR7dGV4dDogXCJeX15cIiwgY3NzQ2xhc3M6IFwibm8tcm90YXRlXCJ9LFxuXHR7dGV4dDogXCJPOilcIiwgY3NzQ2xhc3M6IFwic21hbGwtZW1vdGljb24gc3BhY2VkLWVtb3RpY29uXCJ9LFxuXHR7dGV4dDogXCJPOiApXCIsIGNzc0NsYXNzOiBcInNtYWxsLWVtb3RpY29uXCJ9LFxuXHR7dGV4dDogXCI4RFwiLCBjc3NDbGFzczogXCJzbWFsbC1lbW90aWNvbiBzcGFjZWQtZW1vdGljb25cIn0sXG5cdHt0ZXh0OiBcIlhEXCIsIGNzc0NsYXNzOiBcInNtYWxsLWVtb3RpY29uIHNwYWNlZC1lbW90aWNvblwifSxcblx0e3RleHQ6IFwieERcIiwgY3NzQ2xhc3M6IFwic21hbGwtZW1vdGljb24gc3BhY2VkLWVtb3RpY29uXCJ9LFxuXHR7dGV4dDogXCI9RFwiLCBjc3NDbGFzczogXCJzbWFsbC1lbW90aWNvbiBzcGFjZWQtZW1vdGljb25cIn0sXG5cdHt0ZXh0OiBcIjhPXCIsIGNzc0NsYXNzOiBcInNtYWxsLWVtb3RpY29uIHNwYWNlZC1lbW90aWNvblwifSxcblx0e3RleHQ6IFwiWys9Li5dXCIsIGNzc0NsYXNzOiBcIm5vLXJvdGF0ZSBuaW50ZW5kby1jb250cm9sbGVyXCJ9XG5dKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGVtb3RpY29uczogZW1vdGljb25zXG5cdCwgbWF0Y2hlcnM6IG1hdGNoZXJzXG5cdCwgZGVmYXVsdHM6IGRlZmF1bHRzXG5cdCwgZW1vdGljb25pemU6IGZ1bmN0aW9uKHN0ciwgb3B0aW9ucykge1xuXHRcdGNvbnN0IG9wdHMgPSAkLmV4dGVuZCh7fSwgZGVmYXVsdHMsIG9wdGlvbnMpO1xuXG5cdFx0bGV0IGNzc0NsYXNzID0gJ2Nzcy1lbW90aWNvbic7XG5cdFx0aWYgKG9wdHMuYW5pbWF0ZSkge1xuXHRcdFx0Y3NzQ2xhc3MgKz0gJyB1bi10cmFuc2Zvcm1lZC1lbW90aWNvbiBhbmltYXRlZC1lbW90aWNvbic7XG5cdFx0fVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbWF0Y2hlcnMubGVuZ3RoOyArK2kpIHtcblx0XHRcdGNvbnN0IG0gPSBtYXRjaGVyc1tpXTtcblx0XHRcdGNvbnN0IGNzcyA9IGNzc0NsYXNzICsgXCIgXCIgKyBtLmNzc0NsYXNzO1xuXHRcdFx0c3RyID0gc3RyLnJlcGxhY2UobS5yZWdleHAsIFwiJDE8c3BhbiBjbGFzcz0nXCIgKyBjc3MgKyBcIic+JDI8L3NwYW4+XCIpO1xuXHRcdH1cblx0XHRyZXR1cm4gc3RyO1xuXHR9XG5cdCwgYW5pbWF0ZTogZnVuY3Rpb24ob3B0aW9ucykge1xuXHRcdGNvbnN0IG9wdHMgPSAkLmV4dGVuZCh7fSwgZGVmYXVsdHMsIG9wdGlvbnMpO1xuXHRcdC8vIGFuaW1hdGUgZW1vdGljb25zXG5cdFx0aWYgKG9wdHMuYW5pbWF0ZSkge1xuXHRcdFx0c2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdCQoJy51bi10cmFuc2Zvcm1lZC1lbW90aWNvbicpLnJlbW92ZUNsYXNzKCd1bi10cmFuc2Zvcm1lZC1lbW90aWNvbicpO1xuXHRcdFx0fSwgb3B0cy5kZWxheSk7XG5cdFx0fVxuXHR9XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBPbVV0aWw7IiwibW9kdWxlLmV4cG9ydHMgPSBTZXR0aW5nczsiLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHR2YXIgY2FjaGVkTW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcblx0aWYgKGNhY2hlZE1vZHVsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuXHR9XG5cdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG5cdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuXHRcdC8vIG5vIG1vZHVsZS5pZCBuZWVkZWRcblx0XHQvLyBubyBtb2R1bGUubG9hZGVkIG5lZWRlZFxuXHRcdGV4cG9ydHM6IHt9XG5cdH07XG5cblx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdKG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiLyogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKSBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAgKi9cbk9iamVjdC5hc3NpZ24od2luZG93LCB7XG5cdENoYXQ6IHJlcXVpcmUoJy4vY2hhdCcpXG59KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==
|