@senx/warpview
Version:
WarpView Elements
381 lines • 47.4 kB
JavaScript
/*
* Copyright 2021 SenX S.A.S.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { DataModel } from '../model/dataModel';
import { Logger } from './logger';
import moment from 'moment-timezone';
import { JsonLib } from './jsonLib';
// @dynamic
export class GTSLib {
static cleanArray(actual) {
return actual.filter((i) => !!i);
}
static unique(arr) {
const u = {};
const a = [];
for (let i = 0, l = arr.length; i < l; ++i) {
if (!u.hasOwnProperty(arr[i])) {
a.push(arr[i]);
u[arr[i]] = 1;
}
}
return a;
}
static isArray(value) {
return value && typeof value === 'object' && value instanceof Array && typeof value.length === 'number'
&& typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));
}
static formatElapsedTime(elapsed) {
if (elapsed < 1000) {
return elapsed.toFixed(3) + ' ns';
}
if (elapsed < 1000000) {
return (elapsed / 1000).toFixed(3) + ' μs';
}
if (elapsed < 1000000000) {
return (elapsed / 1000000).toFixed(3) + ' ms';
}
if (elapsed < 1000000000000) {
return (elapsed / 1000000000).toFixed(3) + ' s ';
}
// Max exec time for nice output: 999.999 minutes (should be OK, timeout should happen before that).
return (elapsed / 60000000000).toFixed(3) + ' m ';
}
static isValidResponse(data) {
let response;
try {
response = new JsonLib().parse(data);
}
catch (e) {
this.LOG.error(['isValidResponse'], 'Response non JSON compliant', data);
return false;
}
if (!GTSLib.isArray(response)) {
this.LOG.error(['isValidResponse'], 'Response isn\'t an Array', response);
return false;
}
return true;
}
static isEmbeddedImage(item) {
return !(typeof item !== 'string' || !/^data:image/.test(item));
}
static isEmbeddedImageObject(item) {
return !((item === null) || (item.image === null) ||
(item.caption === null) || !GTSLib.isEmbeddedImage(item.image));
}
static isPositionArray(item) {
if (!item || !item.positions) {
return false;
}
if (GTSLib.isPositionsArrayWithValues(item) || GTSLib.isPositionsArrayWithTwoValues(item)) {
return true;
}
(item.positions || []).forEach(p => {
if (p.length < 2 || p.length > 3) {
return false;
}
for (const j in p) {
if (typeof p[j] !== 'number') {
return false;
}
}
});
return true;
}
static isPositionsArrayWithValues(item) {
if ((item === null) || (item.positions === null)) {
return false;
}
(item.positions || []).forEach(p => {
if (p.length !== 3) {
return false;
}
for (const j in p) {
if (typeof p[j] !== 'number') {
return false;
}
}
});
return true;
}
static isPositionsArrayWithTwoValues(item) {
if ((item === null) || (item.positions === null)) {
return false;
}
(item.positions || []).forEach(p => {
if (p.length !== 4) {
return false;
}
for (const j in p) {
if (typeof p[j] !== 'number') {
return false;
}
}
});
return true;
}
static gtsFromJSON(json, id) {
return { gts: { c: json.c, l: json.l, a: json.a, v: json.v, id } };
}
static uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
// tslint:disable-next-line:no-bitwise
const r = Math.random() * 16 | 0;
// tslint:disable-next-line:no-bitwise
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
static gtsFromJSONList(jsonList, prefixId) {
const gtsList = [];
let id;
(jsonList || []).forEach((item, i) => {
let gts = item;
if (item.gts) {
gts = item.gts;
}
if ((prefixId !== undefined) && (prefixId !== '')) {
id = prefixId + '-' + i;
}
else {
id = i;
}
if (GTSLib.isArray(gts)) {
gtsList.push(GTSLib.gtsFromJSONList(gts, id));
}
if (GTSLib.isGts(gts)) {
gtsList.push(GTSLib.gtsFromJSON(gts, id));
}
if (GTSLib.isEmbeddedImage(gts)) {
gtsList.push({ image: gts, caption: 'Image', id });
}
if (GTSLib.isEmbeddedImageObject(gts)) {
gtsList.push({ image: gts.image, caption: gts.caption, id });
}
});
return {
content: gtsList || [],
};
}
static flatDeep(arrays) {
const result = [];
if (!GTSLib.isArray(arrays)) {
arrays = [arrays];
}
GTSLib.flatten(arrays, result);
return result;
}
static flatten(arr, result = []) {
const size = arr.length;
for (let i = 0; i < size; i++) {
const value = arr[i];
if (Array.isArray(value)) {
GTSLib.flatten(value, result);
}
else {
result.push(value);
}
}
return result;
}
static flattenGtsIdArray(a, r) {
const res = [];
if (GTSLib.isGts(a)) {
a = [a];
}
(a || []).forEach(d => {
if (GTSLib.isArray(d)) {
const walk = GTSLib.flattenGtsIdArray(d, r);
res.push(walk.res);
r = walk.r;
}
else if (d && d.v) {
d.id = r;
res.push(d);
r++;
}
});
return { res, r };
}
static sanitizeNames(input) {
return (input || '').replace(/{/g, '{')
.replace(/}/g, '}')
.replace(/,/g, ',')
.replace(/>/g, '>')
.replace(/</g, '<')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
static serializeGtsMetadata(gts) {
const serializedLabels = [];
const serializedAttributes = [];
if (gts.l) {
Object.keys(gts.l).forEach((key) => {
serializedLabels.push(this.sanitizeNames(key + '=' + gts.l[key]));
});
}
if (gts.a) {
Object.keys(gts.a).forEach((key) => {
serializedAttributes.push(this.sanitizeNames(key + '=' + gts.a[key]));
});
}
// tslint:disable-next-line:max-line-length
return `${this.sanitizeNames(gts.c)}{${serializedLabels.join(',')}${serializedAttributes.length > 0 ? ',' : ''}${serializedAttributes.join(',')}}`;
}
static isGts(item) {
return !!item && (item.c === '' || !!item.c) && !!item.v && GTSLib.isArray(item.v);
}
static isGtsToPlot(gts) {
if (!GTSLib.isGts(gts) || gts.v.length === 0) {
return false;
}
// We look at the first non-null value, if it's a String or Boolean it's an annotation GTS,
// if it's a number it's a GTS to plot
return (gts.v || []).some(v => {
// noinspection JSPotentiallyInvalidConstructorUsage
return typeof v[v.length - 1] === 'number' || !!v[v.length - 1].constructor.prototype.toFixed;
});
}
static isGtsToPlotOnMap(gts) {
if (!GTSLib.isGts(gts) || gts.v.length === 0) {
return false;
}
// We look at the first non-null value, if it's a String or Boolean it's an annotation GTS,
// if it's a number it's a GTS to plot
return (gts.v || []).some(v => {
return v.length >= 3;
});
}
static isSingletonGTS(gts) {
if (!GTSLib.isGts(gts) || gts.v.length === 0) {
return false;
}
return (gts.v || []).length === 1;
}
static isGtsToAnnotate(gts) {
if (!GTSLib.isGts(gts) || gts.v.length === 0) {
return false;
}
// We look at the first non-null value, if it's a String or Boolean it's an annotation GTS,
// if it's a number it's a GTS to plot
return (gts.v || []).some(v => {
if (v[v.length - 1] !== null) {
// noinspection JSPotentiallyInvalidConstructorUsage
return typeof (v[v.length - 1]) !== 'number' &&
(!!v[v.length - 1].constructor && v[v.length - 1].constructor.name !== 'Big') &&
v[v.length - 1].constructor.prototype.toFixed === undefined;
}
});
}
static gtsSort(gts) {
if (gts.isSorted) {
return;
}
gts.v = gts.v.sort((a, b) => a[0] - b[0]);
gts.isSorted = true;
}
static getData(data) {
if (typeof data === 'string') {
if (data.startsWith('[') || data.startsWith('{')) {
return GTSLib.getData(new JsonLib().parse(data));
}
else {
return { data: new JsonLib().parse(`[${data}]`) };
}
}
else if (data && data.hasOwnProperty('data')) {
if (!GTSLib.isArray(data.data)) {
data.data = [data.data];
}
return data;
}
else if (GTSLib.isArray(data) && data.length > 0 && data[0].data) {
return data[0];
}
else if (GTSLib.isArray(data)) {
return { data: data };
}
return new DataModel();
}
static getDivider(timeUnit) {
let timestampDivider = 1000; // default for µs timeunit
if (timeUnit === 'ms') {
timestampDivider = 1;
}
if (timeUnit === 'ns') {
timestampDivider = 1000000;
}
return timestampDivider;
}
static formatLabel(data) {
const serializedGTS = data.split('{');
let display = `<span class="gtsInfo"><span class='gts-classname'>${serializedGTS[0]}</span>`;
if (serializedGTS.length > 1) {
display += `<span class='gts-separator'>{</span>`;
const labels = serializedGTS[1].substr(0, serializedGTS[1].length - 1).split(',');
if (labels.length > 0) {
labels.forEach((l, i) => {
const label = l.split('=');
if (l.length > 1) {
display += `<span><span class='gts-labelname'>${label[0]}</span>
<span class='gts-separator'>=</span><span class='gts-labelvalue'>${label[1]}</span>`;
if (i !== labels.length - 1) {
display += `<span>, </span>`;
}
}
});
}
display += `<span class='gts-separator'>}</span>`;
}
if (serializedGTS.length > 2) {
display += `<span class='gts-separator'>{</span>`;
const labels = serializedGTS[2].substr(0, serializedGTS[2].length - 1).split(',');
if (labels.length > 0) {
labels.forEach((l, i) => {
const label = l.split('=');
if (l.length > 1) {
display += `<span><span class='gts-attrname'>${label[0]}</span>
<span class='gts-separator'>=</span><span class='gts-attrvalue'>${label[1]}</span>`;
if (i !== labels.length - 1) {
display += `<span>, </span>`;
}
}
});
}
display += `<span class='gts-separator'>}</span>`;
}
display += '</span>';
return display;
}
static toISOString(timestamp, divider, timeZone) {
if (timeZone !== 'UTC') {
return moment.tz(timestamp / divider, timeZone).format();
}
else {
return moment.utc(timestamp / divider).toISOString();
}
}
static toTimestamp(date, divider, timeZone) {
if (timeZone !== 'UTC') {
return moment.tz(date, timeZone).utc().valueOf() * divider;
}
else {
return moment.utc(date).valueOf() * divider;
}
}
}
GTSLib.LOG = new Logger(GTSLib);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3RzLmxpYi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3dhcnB2aWV3LW5nL3NyYy9saWIvdXRpbHMvZ3RzLmxpYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFFN0MsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUNoQyxPQUFPLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUNyQyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBRWxDLFdBQVc7QUFDWCxNQUFNLE9BQU8sTUFBTTtJQUdqQixNQUFNLENBQUMsVUFBVSxDQUFDLE1BQWE7UUFDN0IsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRztRQUNmLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNiLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNiLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUU7WUFDMUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQzdCLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2YsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNmO1NBQ0Y7UUFDRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRCxN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RTs0QkFDM0IsT0FBTyxJQUFJLGlCQUFpQixDQUFDO3lCQUM5QjtxQkFDRjtnQkFDSCxDQUFDLENBQUMsQ0FBQzthQUNKO1lBQ0QsT0FBTyxJQUFJLHNDQUFzQyxDQUFDO1NBQ25EO1FBQ0QsT0FBTyxJQUFJLFNBQVMsQ0FBQztRQUNyQixPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFpQixFQUFFLE9BQWUsRUFBRSxRQUFnQjtRQUNyRSxJQUFJLFFBQVEsS0FBSyxLQUFLLEVBQUU7WUFDdEIsT0FBTyxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsR0FBRyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDMUQ7YUFBTTtZQUNMLE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDdEQ7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFZLEVBQUUsT0FBZSxFQUFFLFFBQWdCO1FBQ2hFLElBQUksUUFBUSxLQUFLLEtBQUssRUFBRTtZQUN0QixPQUFPLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLE9BQU8sQ0FBQztTQUM1RDthQUFNO1lBQ0wsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLE9BQU8sQ0FBQztTQUM3QztJQUNILENBQUM7O0FBdlhjLFVBQUcsR0FBVyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiAgQ29weXJpZ2h0IDIwMjEgIFNlblggUy5BLlMuXG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiAgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHtEYXRhTW9kZWx9IGZyb20gJy4uL21vZGVsL2RhdGFNb2RlbCc7XG5pbXBvcnQge0dUU30gZnJvbSAnLi4vbW9kZWwvR1RTJztcbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudC10aW1lem9uZSc7XG5pbXBvcnQge0pzb25MaWJ9IGZyb20gJy4vanNvbkxpYic7XG5cbi8vIEBkeW5hbWljXG5leHBvcnQgY2xhc3MgR1RTTGliIHtcbiAgcHJpdmF0ZSBzdGF0aWMgTE9HOiBMb2dnZXIgPSBuZXcgTG9nZ2VyKEdUU0xpYik7XG5cbiAgc3RhdGljIGNsZWFuQXJyYXkoYWN0dWFsOiBhbnlbXSkge1xuICAgIHJldHVybiBhY3R1YWwuZmlsdGVyKChpKSA9PiAhIWkpO1xuICB9XG5cbiAgc3RhdGljIHVuaXF1ZShhcnIpIHtcbiAgICBjb25zdCB1ID0ge307XG4gICAgY29uc3QgYSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwLCBsID0gYXJyLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgICAgaWYgKCF1Lmhhc093blByb3BlcnR5KGFycltpXSkpIHtcbiAgICAgICAgYS5wdXNoKGFycltpXSk7XG4gICAgICAgIHVbYXJyW2ldXSA9IDE7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhO1xuICB9XG5cbiAgc3RhdGljIGlzQXJyYXkodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5ICYmIHR5cGVvZiB2YWx1ZS5sZW5ndGggPT09ICdudW1iZXInXG4gICAgICAmJiB0eXBlb2YgdmFsdWUuc3BsaWNlID09PSAnZnVuY3Rpb24nICYmICEodmFsdWUucHJvcGVydHlJc0VudW1lcmFibGUoJ2xlbmd0aCcpKTtcbiAgfVxuXG4gIHN0YXRpYyBmb3JtYXRFbGFwc2VkVGltZShlbGFwc2VkOiBudW1iZXIpIHtcbiAgICBpZiAoZWxhcHNlZCA8IDEwMDApIHtcbiAgICAgIHJldHVybiBlbGFwc2VkLnRvRml4ZWQoMykgKyAnIG5zJztcbiAgICB9XG4gICAgaWYgKGVsYXBzZWQgPCAxMDAwMDAwKSB7XG4gICAgICByZXR1cm4gKGVsYXBzZWQgLyAxMDAwKS50b0ZpeGVkKDMpICsgJyDOvHMnO1xuICAgIH1cbiAgICBpZiAoZWxhcHNlZCA8IDEwMDAwMDAwMDApIHtcbiAgICAgIHJldHVybiAoZWxhcHNlZCAvIDEwMDAwMDApLnRvRml4ZWQoMykgKyAnIG1zJztcbiAgICB9XG4gICAgaWYgKGVsYXBzZWQgPCAxMDAwMDAwMDAwMDAwKSB7XG4gICAgICByZXR1cm4gKGVsYXBzZWQgLyAxMDAwMDAwMDAwKS50b0ZpeGVkKDMpICsgJyBzICc7XG4gICAgfVxuICAgIC8vIE1heCBleGVjIHRpbWUgZm9yIG5pY2Ugb3V0cHV0OiA5OTkuOTk5IG1pbnV0ZXMgKHNob3VsZCBiZSBPSywgdGltZW91dCBzaG91bGQgaGFwcGVuIGJlZm9yZSB0aGF0KS5cbiAgICByZXR1cm4gKGVsYXBzZWQgLyA2MDAwMDAwMDAwMCkudG9GaXhlZCgzKSArICcgbSAnO1xuICB9XG5cbiAgc3RhdGljIGlzVmFsaWRSZXNwb25zZShkYXRhKSB7XG4gICAgbGV0IHJlc3BvbnNlO1xuICAgIHRyeSB7XG4gICAgICByZXNwb25zZSA9IG5ldyBKc29uTGliKCkucGFyc2UoZGF0YSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5MT0cuZXJyb3IoWydpc1ZhbGlkUmVzcG9uc2UnXSwgJ1Jlc3BvbnNlIG5vbiBKU09OIGNvbXBsaWFudCcsIGRhdGEpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIUdUU0xpYi5pc0FycmF5KHJlc3BvbnNlKSkge1xuICAgICAgdGhpcy5MT0cuZXJyb3IoWydpc1ZhbGlkUmVzcG9uc2UnXSwgJ1Jlc3BvbnNlIGlzblxcJ3QgYW4gQXJyYXknLCByZXNwb25zZSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgc3RhdGljIGlzRW1iZWRkZWRJbWFnZShpdGVtKSB7XG4gICAgcmV0dXJuICEodHlwZW9mIGl0ZW0gIT09ICdzdHJpbmcnIHx8ICEvXmRhdGE6aW1hZ2UvLnRlc3QoaXRlbSkpO1xuICB9XG5cbiAgc3RhdGljIGlzRW1iZWRkZWRJbWFnZU9iamVjdChpdGVtKSB7XG4gICAgcmV0dXJuICEoKGl0ZW0gPT09IG51bGwpIHx8IChpdGVtLmltYWdlID09PSBudWxsKSB8fFxuICAgICAgKGl0ZW0uY2FwdGlvbiA9PT0gbnVsbCkgfHwgIUdUU0xpYi5pc0VtYmVkZGVkSW1hZ2UoaXRlbS5pbWFnZSkpO1xuICB9XG5cbiAgc3RhdGljIGlzUG9zaXRpb25BcnJheShpdGVtKSB7XG4gICAgaWYgKCFpdGVtIHx8ICFpdGVtLnBvc2l0aW9ucykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoR1RTTGliLmlzUG9zaXRpb25zQXJyYXlXaXRoVmFsdWVzKGl0ZW0pIHx8IEdUU0xpYi5pc1Bvc2l0aW9uc0FycmF5V2l0aFR3b1ZhbHVlcyhpdGVtKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIChpdGVtLnBvc2l0aW9ucyB8fCBbXSkuZm9yRWFjaChwID0+IHtcbiAgICAgIGlmIChwLmxlbmd0aCA8IDIgfHwgcC5sZW5ndGggPiAzKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgaiBpbiBwKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcFtqXSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHN0YXRpYyBpc1Bvc2l0aW9uc0FycmF5V2l0aFZhbHVlcyhpdGVtKSB7XG4gICAgaWYgKChpdGVtID09PSBudWxsKSB8fCAoaXRlbS5wb3NpdGlvbnMgPT09IG51bGwpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIChpdGVtLnBvc2l0aW9ucyB8fCBbXSkuZm9yRWFjaChwID0+IHtcbiAgICAgIGlmIChwLmxlbmd0aCAhPT0gMykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGogaW4gcCkge1xuICAgICAgICBpZiAodHlwZW9mIHBbal0gIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzdGF0aWMgaXNQb3NpdGlvbnNBcnJheVdpdGhUd29WYWx1ZXMoaXRlbSkge1xuICAgIGlmICgoaXRlbSA9PT0gbnVsbCkgfHwgKGl0ZW0ucG9zaXRpb25zID09PSBudWxsKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAoaXRlbS5wb3NpdGlvbnMgfHwgW10pLmZvckVhY2gocCA9PiB7XG4gICAgICBpZiAocC5sZW5ndGggIT09IDQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBqIGluIHApIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwW2pdICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgc3RhdGljIGd0c0Zyb21KU09OKGpzb24sIGlkKSB7XG4gICAgcmV0dXJuIHtndHM6IHtjOiBqc29uLmMsIGw6IGpzb24ubCwgYToganNvbi5hLCB2OiBqc29uLnYsIGlkfX07XG4gIH1cblxuICBzdGF0aWMgdXVpZHY0KCkge1xuICAgIHJldHVybiAneHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4Jy5yZXBsYWNlKC9beHldL2csIGMgPT4ge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWJpdHdpc2VcbiAgICAgIGNvbnN0IHIgPSBNYXRoLnJhbmRvbSgpICogMTYgfCAwO1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWJpdHdpc2VcbiAgICAgIGNvbnN0IHYgPSBjID09PSAneCcgPyByIDogKHIgJiAweDMgfCAweDgpO1xuICAgICAgcmV0dXJuIHYudG9TdHJpbmcoMTYpO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGd0c0Zyb21KU09OTGlzdChqc29uTGlzdCwgcHJlZml4SWQpIHtcbiAgICBjb25zdCBndHNMaXN0ID0gW107XG4gICAgbGV0IGlkO1xuICAgIChqc29uTGlzdCB8fCBbXSkuZm9yRWFjaCgoaXRlbSwgaSkgPT4ge1xuICAgICAgbGV0IGd0cyA9IGl0ZW07XG4gICAgICBpZiAoaXRlbS5ndHMpIHtcbiAgICAgICAgZ3RzID0gaXRlbS5ndHM7XG4gICAgICB9XG4gICAgICBpZiAoKHByZWZpeElkICE9PSB1bmRlZmluZWQpICYmIChwcmVmaXhJZCAhPT0gJycpKSB7XG4gICAgICAgIGlkID0gcHJlZml4SWQgKyAnLScgKyBpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWQgPSBpO1xuICAgICAgfVxuICAgICAgaWYgKEdUU0xpYi5pc0FycmF5KGd0cykpIHtcbiAgICAgICAgZ3RzTGlzdC5wdXNoKEdUU0xpYi5ndHNGcm9tSlNPTkxpc3QoZ3RzLCBpZCkpO1xuICAgICAgfVxuICAgICAgaWYgKEdUU0xpYi5pc0d0cyhndHMpKSB7XG4gICAgICAgIGd0c0xpc3QucHVzaChHVFNMaWIuZ3RzRnJvbUpTT04oZ3RzLCBpZCkpO1xuICAgICAgfVxuICAgICAgaWYgKEdUU0xpYi5pc0VtYmVkZGVkSW1hZ2UoZ3RzKSkge1xuICAgICAgICBndHNMaXN0LnB1c2goe2ltYWdlOiBndHMsIGNhcHRpb246ICdJbWFnZScsIGlkfSk7XG4gICAgICB9XG4gICAgICBpZiAoR1RTTGliLmlzRW1iZWRkZWRJbWFnZU9iamVjdChndHMpKSB7XG4gICAgICAgIGd0c0xpc3QucHVzaCh7aW1hZ2U6IGd0cy5pbWFnZSwgY2FwdGlvbjogZ3RzLmNhcHRpb24sIGlkfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IGd0c0xpc3QgfHwgW10sXG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBmbGF0RGVlcChhcnJheXM6IGFueVtdKTogYW55W10ge1xuICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuICAgIGlmICghR1RTTGliLmlzQXJyYXkoYXJyYXlzKSkge1xuICAgICAgYXJyYXlzID0gW2FycmF5c107XG4gICAgfVxuICAgIEdUU0xpYi5mbGF0dGVuKGFycmF5cywgcmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgc3RhdGljIGZsYXR0ZW4oYXJyLCByZXN1bHQgPSBbXSkge1xuICAgIGNvbnN0IHNpemUgPSBhcnIubGVuZ3RoO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGFycltpXTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBHVFNMaWIuZmxhdHRlbih2YWx1ZSwgcmVzdWx0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHN0YXRpYyBmbGF0dGVuR3RzSWRBcnJheShhOiBhbnlbXSwgcjogbnVtYmVyKTogeyByZXM6IGFueVtdLCByOiBudW1iZXIgfSB7XG4gICAgY29uc3QgcmVzID0gW107XG4gICAgaWYgKEdUU0xpYi5pc0d0cyhhKSkge1xuICAgICAgYSA9IFthXTtcbiAgICB9XG4gICAgKGEgfHwgW10pLmZvckVhY2goZCA9PiB7XG4gICAgICBpZiAoR1RTTGliLmlzQXJyYXkoZCkpIHtcbiAgICAgICAgY29uc3Qgd2FsayA9IEdUU0xpYi5mbGF0dGVuR3RzSWRBcnJheShkLCByKTtcbiAgICAgICAgcmVzLnB1c2god2Fsay5yZXMpO1xuICAgICAgICByID0gd2Fsay5yO1xuICAgICAgfSBlbHNlIGlmIChkICYmIGQudikge1xuICAgICAgICBkLmlkID0gcjtcbiAgICAgICAgcmVzLnB1c2goZCk7XG4gICAgICAgIHIrKztcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4ge3Jlcywgcn07XG4gIH1cblxuICBzdGF0aWMgc2FuaXRpemVOYW1lcyhpbnB1dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gKGlucHV0IHx8ICcnKS5yZXBsYWNlKC97L2csICcmIzEyMzsnKVxuICAgICAgLnJlcGxhY2UoL30vZywgJyYjMTI1OycpXG4gICAgICAucmVwbGFjZSgvLC9nLCAnJiM0NDsnKVxuICAgICAgLnJlcGxhY2UoLz4vZywgJyYjNjI7JylcbiAgICAgIC5yZXBsYWNlKC88L2csICcmIzYwOycpXG4gICAgICAucmVwbGFjZSgvXCIvZywgJyYjMzQ7JylcbiAgICAgIC5yZXBsYWNlKC8nL2csICcmIzM5OycpO1xuICB9XG5cbiAgc3RhdGljIHNlcmlhbGl6ZUd0c01ldGFkYXRhKGd0cykge1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRMYWJlbHMgPSBbXTtcbiAgICBjb25zdCBzZXJpYWxpemVkQXR0cmlidXRlcyA9IFtdO1xuICAgIGlmIChndHMubCkge1xuICAgICAgT2JqZWN0LmtleXMoZ3RzLmwpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICBzZXJpYWxpemVkTGFiZWxzLnB1c2godGhpcy5zYW5pdGl6ZU5hbWVzKGtleSArICc9JyArIGd0cy5sW2tleV0pKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoZ3RzLmEpIHtcbiAgICAgIE9iamVjdC5rZXlzKGd0cy5hKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgc2VyaWFsaXplZEF0dHJpYnV0ZXMucHVzaCh0aGlzLnNhbml0aXplTmFtZXMoa2V5ICsgJz0nICsgZ3RzLmFba2V5XSkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbiAgICByZXR1cm4gYCR7dGhpcy5zYW5pdGl6ZU5hbWVzKGd0cy5jKX17JHtzZXJpYWxpemVkTGFiZWxzLmpvaW4oJywnKX0ke3NlcmlhbGl6ZWRBdHRyaWJ1dGVzLmxlbmd0aCA+IDAgPyAnLCcgOiAnJ30ke3NlcmlhbGl6ZWRBdHRyaWJ1dGVzLmpvaW4oJywnKX19YDtcbiAgfVxuXG4gIHN0YXRpYyBpc0d0cyhpdGVtKSB7XG4gICAgcmV0dXJuICEhaXRlbSAmJiAoaXRlbS5jID09PSAnJyB8fCAhIWl0ZW0uYykgJiYgISFpdGVtLnYgJiYgR1RTTGliLmlzQXJyYXkoaXRlbS52KTtcbiAgfVxuXG4gIHN0YXRpYyBpc0d0c1RvUGxvdChndHMpIHtcbiAgICBpZiAoIUdUU0xpYi5pc0d0cyhndHMpIHx8IGd0cy52Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBXZSBsb29rIGF0IHRoZSBmaXJzdCBub24tbnVsbCB2YWx1ZSwgaWYgaXQncyBhIFN0cmluZyBvciBCb29sZWFuIGl0J3MgYW4gYW5ub3RhdGlvbiBHVFMsXG4gICAgLy8gaWYgaXQncyBhIG51bWJlciBpdCdzIGEgR1RTIHRvIHBsb3RcbiAgICByZXR1cm4gKGd0cy52IHx8IFtdKS5zb21lKHYgPT4ge1xuICAgICAgLy8gbm9pbnNwZWN0aW9uIEpTUG90ZW50aWFsbHlJbnZhbGlkQ29uc3RydWN0b3JVc2FnZVxuICAgICAgcmV0dXJuIHR5cGVvZiB2W3YubGVuZ3RoIC0gMV0gPT09ICdudW1iZXInIHx8ICEhdlt2Lmxlbmd0aCAtIDFdLmNvbnN0cnVjdG9yLnByb3RvdHlwZS50b0ZpeGVkO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzR3RzVG9QbG90T25NYXAoZ3RzKSB7XG4gICAgaWYgKCFHVFNMaWIuaXNHdHMoZ3RzKSB8fCBndHMudi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gV2UgbG9vayBhdCB0aGUgZmlyc3Qgbm9uLW51bGwgdmFsdWUsIGlmIGl0J3MgYSBTdHJpbmcgb3IgQm9vbGVhbiBpdCdzIGFuIGFubm90YXRpb24gR1RTLFxuICAgIC8vIGlmIGl0J3MgYSBudW1iZXIgaXQncyBhIEdUUyB0byBwbG90XG4gICAgcmV0dXJuIChndHMudiB8fCBbXSkuc29tZSh2ID0+IHtcbiAgICAgIHJldHVybiB2Lmxlbmd0aCA+PSAzO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGlzU2luZ2xldG9uR1RTKGd0cykge1xuICAgIGlmICghR1RTTGliLmlzR3RzKGd0cykgfHwgZ3RzLnYubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiAoZ3RzLnYgfHwgW10pLmxlbmd0aCA9PT0gMTtcbiAgfVxuXG4gIHN0YXRpYyBpc0d0c1RvQW5ub3RhdGUoZ3RzKSB7XG4gICAgaWYgKCFHVFNMaWIuaXNHdHMoZ3RzKSB8fCBndHMudi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gV2UgbG9vayBhdCB0aGUgZmlyc3Qgbm9uLW51bGwgdmFsdWUsIGlmIGl0J3MgYSBTdHJpbmcgb3IgQm9vbGVhbiBpdCdzIGFuIGFubm90YXRpb24gR1RTLFxuICAgIC8vIGlmIGl0J3MgYSBudW1iZXIgaXQncyBhIEdUUyB0byBwbG90XG4gICAgcmV0dXJuIChndHMudiB8fCBbXSkuc29tZSh2ID0+IHtcbiAgICAgIGlmICh2W3YubGVuZ3RoIC0gMV0gIT09IG51bGwpIHtcbiAgICAgICAgLy8gbm9pbnNwZWN0aW9uIEpTUG90ZW50aWFsbHlJbnZhbGlkQ29uc3RydWN0b3JVc2FnZVxuICAgICAgICByZXR1cm4gdHlwZW9mICh2W3YubGVuZ3RoIC0gMV0pICE9PSAnbnVtYmVyJyAmJlxuICAgICAgICAgICghIXZbdi5sZW5ndGggLSAxXS5jb25zdHJ1Y3RvciAmJiB2W3YubGVuZ3RoIC0gMV0uY29uc3RydWN0b3IubmFtZSAhPT0gJ0JpZycpICYmXG4gICAgICAgICAgdlt2Lmxlbmd0aCAtIDFdLmNvbnN0cnVjdG9yLnByb3RvdHlwZS50b0ZpeGVkID09PSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ3RzU29ydChndHMpIHtcbiAgICBpZiAoZ3RzLmlzU29ydGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGd0cy52ID0gZ3RzLnYuc29ydCgoYSwgYikgPT4gYVswXSAtIGJbMF0pO1xuICAgIGd0cy5pc1NvcnRlZCA9IHRydWU7XG4gIH1cblxuICBzdGF0aWMgZ2V0RGF0YShkYXRhOiBhbnkpOiBEYXRhTW9kZWwge1xuICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChkYXRhLnN0YXJ0c1dpdGgoJ1snKSB8fCBkYXRhLnN0YXJ0c1dpdGgoJ3snKSkge1xuICAgICAgICByZXR1cm4gR1RTTGliLmdldERhdGEobmV3IEpzb25MaWIoKS5wYXJzZShkYXRhIGFzIHN0cmluZykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHtkYXRhOiBuZXcgSnNvbkxpYigpLnBhcnNlKGBbJHtkYXRhfV1gKX07XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChkYXRhICYmIGRhdGEuaGFzT3duUHJvcGVydHkoJ2RhdGEnKSkge1xuICAgICAgaWYgKCFHVFNMaWIuaXNBcnJheShkYXRhLmRhdGEpKSB7XG4gICAgICAgIGRhdGEuZGF0YSA9IFtkYXRhLmRhdGFdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGEgYXMgRGF0YU1vZGVsO1xuICAgIH0gZWxzZSBpZiAoR1RTTGliLmlzQXJyYXkoZGF0YSkgJiYgZGF0YS5sZW5ndGggPiAwICYmIGRhdGFbMF0uZGF0YSkge1xuICAgICAgcmV0dXJuIGRhdGFbMF0gYXMgRGF0YU1vZGVsO1xuICAgIH0gZWxzZSBpZiAoR1RTTGliLmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHJldHVybiB7ZGF0YTogZGF0YSBhcyBHVFNbXX0gYXMgRGF0YU1vZGVsO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERhdGFNb2RlbCgpO1xuICB9XG5cbiAgc3RhdGljIGdldERpdmlkZXIodGltZVVuaXQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgbGV0IHRpbWVzdGFtcERpdmlkZXIgPSAxMDAwOyAvLyBkZWZhdWx0IGZvciDCtXMgdGltZXVuaXRcbiAgICBpZiAodGltZVVuaXQgPT09ICdtcycpIHtcbiAgICAgIHRpbWVzdGFtcERpdmlkZXIgPSAxO1xuICAgIH1cbiAgICBpZiAodGltZVVuaXQgPT09ICducycpIHtcbiAgICAgIHRpbWVzdGFtcERpdmlkZXIgPSAxMDAwMDAwO1xuICAgIH1cbiAgICByZXR1cm4gdGltZXN0YW1wRGl2aWRlcjtcbiAgfVxuXG4gIHN0YXRpYyBmb3JtYXRMYWJlbChkYXRhOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRHVFMgPSBkYXRhLnNwbGl0KCd7Jyk7XG4gICAgbGV0IGRpc3BsYXkgPSBgPHNwYW4gY2xhc3M9XCJndHNJbmZvXCI+PHNwYW4gY2xhc3M9J2d0cy1jbGFzc25hbWUnPiR7c2VyaWFsaXplZEdUU1swXX08L3NwYW4+YDtcbiAgICBpZiAoc2VyaWFsaXplZEdUUy5sZW5ndGggPiAxKSB7XG4gICAgICBkaXNwbGF5ICs9IGA8c3BhbiBjbGFzcz0nZ3RzLXNlcGFyYXRvcic+ezwvc3Bhbj5gO1xuICAgICAgY29uc3QgbGFiZWxzID0gc2VyaWFsaXplZEdUU1sxXS5zdWJzdHIoMCwgc2VyaWFsaXplZEdUU1sxXS5sZW5ndGggLSAxKS5zcGxpdCgnLCcpO1xuICAgICAgaWYgKGxhYmVscy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGxhYmVscy5mb3JFYWNoKChsLCBpKSA9PiB7XG4gICAgICAgICAgY29uc3QgbGFiZWwgPSBsLnNwbGl0KCc9Jyk7XG4gICAgICAgICAgaWYgKGwubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgZGlzcGxheSArPSBgPHNwYW4+PHNwYW4gY2xhc3M9J2d0cy1sYWJlbG5hbWUnPiR7bGFiZWxbMF19PC9zcGFuPlxuPHNwYW4gY2xhc3M9J2d0cy1zZXBhcmF0b3InPj08L3NwYW4+PHNwYW4gY2xhc3M9J2d0cy1sYWJlbHZhbHVlJz4ke2xhYmVsWzFdfTwvc3Bhbj5gO1xuICAgICAgICAgICAgaWYgKGkgIT09IGxhYmVscy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgIGRpc3BsYXkgKz0gYDxzcGFuPiwgPC9zcGFuPmA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGRpc3BsYXkgKz0gYDxzcGFuIGNsYXNzPSdndHMtc2VwYXJhdG9yJz59PC9zcGFuPmA7XG4gICAgfVxuICAgIGlmIChzZXJpYWxpemVkR1RTLmxlbmd0aCA+IDIpIHtcbiAgICAgIGRpc3BsYXkgKz0gYDxzcGFuIGNsYXNzPSdndHMtc2VwYXJhdG9yJz57PC9zcGFuPmA7XG4gICAgICBjb25zdCBsYWJlbHMgPSBzZXJpYWxpemVkR1RTWzJdLnN1YnN0cigwLCBzZXJpYWxpemVkR1RTWzJdLmxlbmd0aCAtIDEpLnNwbGl0KCcsJyk7XG4gICAgICBpZiAobGFiZWxzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbGFiZWxzLmZvckVhY2goKGwsIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBsYWJlbCA9IGwuc3BsaXQoJz0nKTtcbiAgICAgICAgICBpZiAobC5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBkaXNwbGF5ICs9IGA8c3Bhbj48c3BhbiBjbGFzcz0nZ3RzLWF0dHJuYW1lJz4ke2xhYmVsWzBdfTwvc3Bhbj5cbjxzcGFuIGNsYXNzPSdndHMtc2VwYXJhdG9yJz49PC9zcGFuPjxzcGFuIGNsYXNzPSdndHMtYXR0cnZhbHVlJz4ke2xhYmVsWzFdfTwvc3Bhbj5gO1xuICAgICAgICAgICAgaWYgKGkgIT09IGxhYmVscy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgIGRpc3BsYXkgKz0gYDxzcGFuPiwgPC9zcGFuPmA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGRpc3BsYXkgKz0gYDxzcGFuIGNsYXNzPSdndHMtc2VwYXJhdG9yJz59PC9zcGFuPmA7XG4gICAgfVxuICAgIGRpc3BsYXkgKz0gJzwvc3Bhbj4nO1xuICAgIHJldHVybiBkaXNwbGF5O1xuICB9XG5cbiAgc3RhdGljIHRvSVNPU3RyaW5nKHRpbWVzdGFtcDogbnVtYmVyLCBkaXZpZGVyOiBudW1iZXIsIHRpbWVab25lOiBzdHJpbmcpIHtcbiAgICBpZiAodGltZVpvbmUgIT09ICdVVEMnKSB7XG4gICAgICByZXR1cm4gbW9tZW50LnR6KHRpbWVzdGFtcCAvIGRpdmlkZXIsIHRpbWVab25lKS5mb3JtYXQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG1vbWVudC51dGModGltZXN0YW1wIC8gZGl2aWRlcikudG9JU09TdHJpbmcoKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdG9UaW1lc3RhbXAoZGF0ZTogc3RyaW5nLCBkaXZpZGVyOiBudW1iZXIsIHRpbWVab25lOiBzdHJpbmcpIHtcbiAgICBpZiAodGltZVpvbmUgIT09ICdVVEMnKSB7XG4gICAgICByZXR1cm4gbW9tZW50LnR6KGRhdGUsIHRpbWVab25lKS51dGMoKS52YWx1ZU9mKCkgKiBkaXZpZGVyO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbW9tZW50LnV0YyhkYXRlKS52YWx1ZU9mKCkgKiBkaXZpZGVyO1xuICAgIH1cbiAgfVxufVxuIl19