/*! Bundled by webpack from entry point: ./_Scripts/LegacyJS/site-analytics.js */
/******/ (function() { // webpackBootstrap
/******/ // The require scope
/******/ var __webpack_require__ = {};
/******/
/************************************************************************/
/******/ /* webpack/runtime/publicPath */
/******/ !function() {
/******/ __webpack_require__.p = "";
/******/ }();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other entry modules.
!function() {
/*!*************************************!*\
!*** ./_Scripts/set-public-path.ts ***!
\*************************************/
/*** IMPORTS FROM imports-loader ***/
StackExchange = window.StackExchange = (window.StackExchange || {});
StackOverflow = window.StackOverflow = (window.StackOverflow || {});
"use strict";
// This file gets auto-included into each webpack entrypoint.
// We need to set the public path at runtime based on the GlobalRoot site setting.
// (We don't know at build time where the static files will be,
// since we could be deployed on-premise.)
// The value of that site setting gets written out to the dom in Master.cshtml
// (see JavaScriptHelper.PublicPath()) so that we can read it here
__webpack_require__.p = document.getElementById("webpack-public-path").innerText;
}();
// This entry need to be wrapped in an IIFE because it need to be isolated against other entry modules.
!function() {
/*!*********************************************!*\
!*** ./_Scripts/LegacyJS/site-analytics.js ***!
\*********************************************/
/*** IMPORTS FROM imports-loader ***/
StackExchange = window.StackExchange = (window.StackExchange || {});
StackOverflow = window.StackOverflow = (window.StackOverflow || {});
StackExchange.siteAnalytics = function () {
'use strict';
var graphDisplayData = {};
var margin = { top: 10, right: 10, bottom: 30, left: 40 };
var width = 800;
var height = 300;
var stackColors = ['#f48024', '#0077cc', '#65bb5c', '#6b291b', '#ffcf10', '#f23b14'];
var hiddenLines = {};
var weekly = false;
d3.selection.prototype.tooltip = function (target, options) {
var self = this; // the enetered selection
options = $.extend({
style: { 'z-index': 10 },
reposition: function (d, i) {
return {
left: d3.event.pageX + 15,
top: d3.event.pageY - 15,
};
}
}, options);
var tooltipDiv = d3.select('.graph')
.append('div')
.attr('class', 'events-tooltip')
.style('opacity', 0)
.style('display', 'none')
.style('position', 'absolute');
var reposition = function () {
var newPosition = options.reposition.apply(tooltipDiv, arguments);
tooltipDiv.style('left', newPosition.left + 'px').style('top', newPosition.top + 'px');
return tooltipDiv;
};
for (var i in options.style) {
tooltipDiv.style(i, options.style[i]);
}
self
.style('pointer-events', 'all') // makes svg:g groups work on tooltips too...
.on('mouseover', function () {
tooltipDiv.style('opacity', .95).style('display', 'block');
reposition.apply(this, arguments);
})
.on('mousemove', reposition)
.on('mouseout', function (d) {
tooltipDiv.style('opacity', 0).style('display', 'none');
});
};
var basicFormat = function(i) {
return i.toString();
};
var simplify = function (i) {
if (i >= 1000000 && (i % 100000) == 0) return basicFormat(i / 1000000) + 'M';
if (i >= 1000 && (i % 100) == 0) return basicFormat(i / 1000) + 'k';
return basicFormat(i);
};
var timeFormat = d3.time.format('%d %b');
var simpleDate = function (d) {
var date = new Date(d);
return timeFormat(date);
};
var commify = function (number) {
var numberString = String(number.toFixed(0));
var parts = numberString.split('.');
var whole = parts[0];
var pattern = /(\d+)(\d{3})(,|$)/;
while (pattern.test(whole)) {
whole = whole.replace(pattern, '$1,$2');
}
numberString = (parts.length > 1) ? whole + '.' + parts[1] : whole;
return numberString;
}
var renderToGraph = function ($elem, svg, data, extents, color) {
var x = d3.scale.linear().domain([extents.xMin, extents.xMax]).range([0, width - (margin.right + margin.left)]);
var y = d3.scale.linear().domain([extents.yMin, extents.yMax]).range([height - (margin.top + margin.bottom), 1]);
var valueline = d3.svg.line()
.x(function(d, i) { return x(d[0]); })
.y(function(d, i) { return y(d[1]); });
svg = svg.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var range = svg.append('g').attr('class', 'range');
range.append('g').append('path').attr('stroke', color).attr('class', 'line').attr('d', valueline(data));
svg.selectAll('.range')
.data(data)
.append('g')
.attr('class', 'circles')
.selectAll('.circles')
.data(data)
.enter()
.append('circle').attr('r', 2.7)
.attr('cx', function (d, i) { return x(d[0]); })
.attr('cy', function(d, i) { return y(d[1]); })
.style('fill', function (d, i) { return color; })
.tooltip($elem, {
reposition: function (d) {
this.html(
('
' +
'
' +
'
{value}
' +
'
{date}
' +
'
').formatUnicorn({
date: $('#weekly').is(':checked') ? (function(n){return"Week of "+n.date})({date:new Date(d[0]).toDateString()}) : new Date(d[0]).toDateString(),
value: commify(d[1]),
color: color
}));
return {
left: d3.event.pageX + 10,
top: d3.event.pageY - 10
};
}
});
};
var calculateGroupMaxMins = function (data, groupName) {
var group = weekly ? data.weekly : data.daily;
var filteredOutHidden = group.filter(function(series) {
return hiddenLines[groupName].indexOf(series.label) < 0;
});
if (filteredOutHidden.length === 0) {
return { xMin: 0, xMax: 0, yMin: 0, yMax: 0 };
}
var xMin = d3.min(filteredOutHidden[0].data, function (d, idx) { return d[0]; });
var xMax = d3.max(filteredOutHidden[0].data, function (d, idx) { return d[0]; });;
var yMin = d3.min(filteredOutHidden[0].data, function (d, idx) { return d[1]; });
var yMax = d3.max(filteredOutHidden[0].data, function (d, idx) { return d[1]; });;
for (var i = 1; i < filteredOutHidden.length; i++) {
if (xMin > d3.min(filteredOutHidden[i].data, function (d, idx) { return d[0]; })) {
xMin = d3.min(filteredOutHidden[i].data, function (d, idx) { return d[0]; });
}
if (xMax < d3.max(filteredOutHidden[i].data, function (d, idx) { return d[0]; })) {
xMax = d3.max(filteredOutHidden[i].data, function (d, idx) { return d[0]; });
}
if (yMin > d3.min(filteredOutHidden[i].data, function (d, idx) { return d[1]; })) {
yMin = d3.min(filteredOutHidden[i].data, function (d, idx) { return d[1]; });
}
if (yMax < d3.max(filteredOutHidden[i].data, function (d, idx) { return d[1]; })) {
yMax = d3.max(filteredOutHidden[i].data, function (d, idx) { return d[1]; });
}
}
return { xMin: xMin, xMax: xMax, yMin: yMin, yMax: yMax };
};
var renderGroup = function ($elem, $svg, data) {
var groupName = $elem.closest('.graph').data('name');
var groupExtents = calculateGroupMaxMins(data, groupName);
var checkboxes = '';
var svg = d3.selectAll($svg.toArray());
var group = weekly ? data.weekly : data.daily;
for (var i = 0; i < group.length; i++) {
var series = group[i];
var isSeriesVisible = hiddenLines[groupName].indexOf(series.label) < 0;
var checkedAttribute = '';
if (isSeriesVisible) {
checkedAttribute = ' checked="checked"';
renderToGraph($elem, svg, series.data, groupExtents, stackColors[i]);
}
checkboxes += ' ' + series.localizedLabel + ' ';
}
var x = d3.scale.linear().domain([groupExtents.xMin, groupExtents.xMax]).range([0, width - (margin.right + margin.left)]);
var y = d3.scale.linear().domain([groupExtents.yMin, groupExtents.yMax]).range([height - (margin.top + margin.bottom), 1]);
var yAxis = d3.svg.axis().scale(y).orient('left').tickFormat(simplify);
svg.append('g').attr('class', 'y axis').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')').call(yAxis)
.append('text').attr('transform', 'rotate(-90)').attr('y', 6).attr('dy', '.71em').style('text-anchor', 'end');
var xAxis = d3.svg.axis().scale(x).orient('bottom').ticks(8).tickFormat(simpleDate);
svg.append('g').attr('class', 'x axis').attr('transform', 'translate(' + margin.left + ',' + (height - margin.bottom) + ')').call(xAxis);
$elem.append(checkboxes + ' ');
var graphCol = $('');
$elem.append(graphCol.append($svg));
};
var mergeGroups = function () {
var daily = [], weekly = [];
for (var i = 0; i < arguments.length; i++) {
daily.push.apply(daily, arguments[i].daily);
weekly.push.apply(weekly, arguments[i].weekly);
daily[i].color = weekly[i].color = stackColors[i];
}
return { daily: daily, weekly: weekly };
};
var displayGraph = function ($elem, data) {
$elem.html(''); // wipe
var $svg = $('
');
renderGroup($elem, $svg, data);
};
var reRenderAllGraphs = function(graphs) {
graphs.each(function(index, element) {
var name = $(element).data('name');
var $elem = $(element);
$elem.addSpinner();
StackExchange.helpers.removeSpinner();
displayGraph($elem, graphDisplayData[name]);
});
};
var buildGraphsAndGraphData = function(graphs) {
graphs.each(function (index, element) {
var name = $(element).data('name');
var $elem = $(element);
$elem.addSpinner();
$.ajax('/site-analytics/' + name, { data: { from: $('#from').val(), to: $('#to').val() } })
.done(function (data) {
if (name === 'traffic') {
graphDisplayData[name] = mergeGroups(data.pageViews, data.visits, data.newVisits);
} else {
graphDisplayData[name] = data;
}
if (!hiddenLines.hasOwnProperty(name)) {
hiddenLines[name] = [];
}
displayGraph($elem, graphDisplayData[name]);
})
.fail(function () {
$elem.append('' + "An error has occurred while retrieving data. Please try again in 24 hours." + '
');
})
.always(function () {
StackExchange.helpers.removeSpinner();
});
});
};
function zip(arrays) {
return arrays[0].map(function (_, i) {
return arrays.map(function (array) { return array[i] })
});
}
var getCsvForGraph = function (graphName) {
var graphData = graphDisplayData[graphName];
var header = ['date'];
var seriesData = $('#weekly').is(':checked') ? graphData.weekly : graphData.daily;
var csv = [header.concat(seriesData.map(function (d) { return d.localizedLabel; }))];
var dataPoints = seriesData.map(function(d) { return d.data; });
var joined = zip(dataPoints).map(function (d) {
var date = new Date(d[0][0]);
var merged = [$.datepicker.formatDate('yy-mm-dd', date)];
for (var i = 0; i < d.length; i++) {
merged.push(d[i][1]);
}
return merged;
});
csv = csv.concat(joined);
return d3.csv.formatRows(csv);
};
var downloadCSV = function (csv, fileName) {
// https://stackoverflow.com/q/29304414
var a = document.createElement('a');
var mimeType = 'text/csv';
if (navigator.msSaveBlob) { // IE10
return navigator.msSaveBlob(new Blob([content], { type: mimeType }), fileName);
} else if ('download' in a) { //html5 A[download]
var blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
var url = URL.createObjectURL(blob);
a.href = url;
a.setAttribute('download', fileName);
document.body.appendChild(a);
setTimeout(function () {
a.click();
document.body.removeChild(a);
}, 66);
return true;
} else { //do iframe dataURL download (old ch+FF):
var f = document.createElement('iframe');
document.body.appendChild(f);
f.src = 'data:' + mimeType + ',' + encodeURIComponent(content);
setTimeout(function () {
document.body.removeChild(f);
}, 333);
return true;
}
};
var init = function (options) {
var graphs = $('.graph');
buildGraphsAndGraphData(graphs);
graphs.on('change', 'input[type=checkbox]', function (e) {
var $graph = $(e.target).closest('.graph');
var graphName = $graph.data('name');
var series = e.target.name;
// todo: persist hidden series
e.target.checked ? hiddenLines[graphName].splice(hiddenLines[graphName].indexOf(series), 1) : hiddenLines[graphName].push(series);
displayGraph($graph, graphDisplayData[graphName]);
});
$('#weekly').change(function (e) {
// todo: persist weekly/daily view
weekly = e.target.checked;
reRenderAllGraphs(graphs);
});
$('#from').datepicker({ dateFormat: 'yy-M-dd', defaultDate: options.fromDate, maxDate: options.maxDate, minDate: options.minDate });
$('#to').datepicker({ dateFormat: 'yy-M-dd', defaultDate: options.toDate, maxDate: options.maxDate, minDate: options.minDate });
$('#from, #to').change(function() {
var graphs = $('.graph');
buildGraphsAndGraphData(graphs);
});
$(".phaseDate").click(function(e) {
var phaseDate = $(e.target).text();
var fromDate = $('#from').val();
if (fromDate !== phaseDate) {
$('#from').datepicker('setDate', phaseDate);
var graphs = $('.graph');
buildGraphsAndGraphData(graphs);
}
e.preventDefault();
});
$('.csv').click(function(e) {
var graphName = $(e.target).closest('.graph-container').find('.graph').data('name');
var from =$('#from').val();
var to = $('#to').val();
var fileName = "{graphName}_{from}_{to}".formatUnicorn({ graphName: graphName, from: from, to: to }) +
($('#weekly').is(':checked')?'_weekly':'') + '.csv';
var csv = getCsvForGraph(graphName);
downloadCSV(csv, fileName);
});
};
var renderPieChart = function (selector, data, options) {
options = options || {};
options.includeLegend = options.includeLegend || false;
options.resizeRatio = options.resizeRatio || 1;
options.includeTooltip = options.includeTooltip || false;
options.useCustomColors = options.useCustomColors || false;
var customColors = ['#ff7f0e', '#0095ff', '#68ba60'];
var pieWidth = 320 * options.resizeRatio, pieHeight = 320 * options.resizeRatio, radius = 150 * options.resizeRatio;
var color = d3.scale.category10();
var totalVisits = data.reduce(function(prev, curr, i, arr) {
return prev + curr.visits;
}, 0);
var svg = d3.selectAll(selector)
.append('svg:svg')
.data([data])
.attr('width', pieWidth + 150)
.attr('height', pieHeight)
.append('svg:g')
.attr('transform', 'translate(' + pieWidth / 2 + ',' + pieHeight / 2 + ')');
var arc = d3.svg.arc()
.outerRadius(radius);
var pie = d3.layout.pie()
.value(function (d) { return d.visits; });
var arcs = svg.selectAll('g.slice')
.data(pie)
.enter()
.append('svg:g')
.attr('class', 'slice');
arcs.append('svg:path')
.attr('fill', function (d, i) { return options.useCustomColors ? customColors[i] : color(i); })
.attr('d', arc);
arcs.filter(function(d) {
return Math.abs(d.startAngle - d.endAngle) >= Math.PI / 6;
})
.append('svg:text')
.attr('transform', function(d) {
//we have to make sure to set these before calling arc.centroid
d.innerRadius = 0;
d.outerRadius = radius;
return 'translate(' + arc.centroid(d) + ')';
})
.attr('text-anchor', 'middle')
.attr('fill', 'white')
.text(function(d) { return d.data.source; });
if (options.includeTooltip) {
arcs.tooltip($(selector), {
reposition: function(d, i) {
this.html(('' +
'
' +
'
{source}
' +
'
{value}
' +
'
').formatUnicorn({
source: d.data.source,
value: commify(d.data.visits) + ' (' + (d.data.visits / totalVisits * 100).toFixed(1) + '%)',
color: options.useCustomColors ? customColors[i] : color(i)
}));
return {
left: d3.event.pageX + 10,
top: d3.event.pageY - 10,
};
}
});
}
if (options.includeLegend) {
var legendRectSize = 18;
var legendSpacing = 4;
var legend = svg.selectAll('.legend')
.data(data)
.enter()
.append('svg:g')
.attr('class', 'legend')
.attr('transform', function(d, i) {
var rectHeight = legendRectSize + legendSpacing;
var offset = rectHeight * data.length / 2;
var horz = pieWidth / 2 + 5;
var vert = i * offset - pieHeight / 2 + 10;
return 'translate(' + horz + ',' + vert + ')';
});
legend.append('svg:rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.style('fill', function (d, i) { return options.useCustomColors ? customColors[i] : color(i); })
.style('stroke', function (d, i) { return options.useCustomColors ? customColors[i] : color(i); });
legend.append('svg:text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.attr('font-size', 10)
.text(function (d) { return d.source + ': ' + commify(d.visits) + ' (' + (d.visits / totalVisits * 100).toFixed(1) + '%)'; });
}
};
var renderTable = function (selector, data) {
var rows = '';
$.each(data, function(i, d) {
rows += '' + d.source + ' ' + commify(d.visits) + ' ';
});
$(selector).append(rows);
};
return { init: init, renderPieChart: renderPieChart, renderTable: renderTable };
}();
}();
/******/ })()
;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2l0ZS1hbmFseXRpY3MuanMiLCJtYXBwaW5ncyI6Ijs7VUFBQTtVQUNBOzs7OztXQ0RBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNBQSw2REFBNkQ7QUFDN0Qsa0ZBQWtGO0FBQ2xGLCtEQUErRDtBQUMvRCwwQ0FBMEM7QUFDMUMsOEVBQThFO0FBQzlFLGtFQUFrRTtBQUNsRSxxQkFBdUIsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLHFCQUFxQixDQUFDLENBQUMsU0FBUyxDQUFDOzs7Ozs7OztBQ05uRjs7O0FBR0Esa0VBQWtFO0FBQ2xFLGtFQUFrRTs7O0FBR2xFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQSxxQkFBcUIsZUFBZTtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxFQUFFO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsaUJBQWlCO0FBQ2pELGdDQUFnQyxpQkFBaUI7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLGlCQUFpQjtBQUMzRCx5Q0FBeUMsaUJBQWlCO0FBQzFELDZDQUE2QyxlQUFlO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUZBQWlGLE9BQU8sUUFBUTtBQUNoRyxpQ0FBaUMsTUFBTTtBQUN2QyxpQ0FBaUMsS0FBSztBQUN0QztBQUNBLHVGQUF1RixxQ0FBcUM7QUFDNUg7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHlFQUF5RSxjQUFjO0FBQ3ZGLHlFQUF5RSxjQUFjO0FBQ3ZGLHlFQUF5RSxjQUFjO0FBQ3ZGLHlFQUF5RSxjQUFjO0FBQ3ZGO0FBQ0Esd0JBQXdCLDhCQUE4QjtBQUN0RCw2RUFBNkUsY0FBYztBQUMzRiw2RUFBNkUsY0FBYztBQUMzRjtBQUNBLDZFQUE2RSxjQUFjO0FBQzNGLDZFQUE2RSxjQUFjO0FBQzNGO0FBQ0EsNkVBQTZFLGNBQWM7QUFDM0YsNkVBQTZFLGNBQWM7QUFDM0Y7QUFDQSw2RUFBNkUsY0FBYztBQUMzRiw2RUFBNkUsY0FBYztBQUMzRjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLGtCQUFrQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixzQkFBc0I7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELFFBQVEsOENBQThDO0FBQ3RHO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRCxpQkFBaUI7QUFDbEUsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0RBQStELDBCQUEwQjtBQUN6RjtBQUNBLHNEQUFzRCxnQkFBZ0I7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsY0FBYztBQUMxQztBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQyw4REFBOEQsZ0JBQWdCO0FBQzlFLFVBQVUsNEJBQTRCO0FBQ3RDLHlDQUF5QyxnQkFBZ0IsY0FBYyxHQUFHO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsVUFBVSxPQUFPO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsZ0NBQWdDLDBHQUEwRztBQUMxSSw4QkFBOEIsd0dBQXdHO0FBQ3RJO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixVQUFVLEVBQUUsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLDBDQUEwQztBQUMvRztBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxrQkFBa0I7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0Qyw4REFBOEQ7QUFDMUc7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxnQ0FBZ0MsdUJBQXVCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2RUFBNkUsT0FBTyxRQUFRO0FBQzVGLDZCQUE2QixPQUFPO0FBQ3BDLDZCQUE2QixNQUFNO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlELDhEQUE4RDtBQUMvRyxtREFBbUQsOERBQThEO0FBQ2pIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsdUdBQXVHO0FBQzVJO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vc3RhY2tvdmVyZmxvdy93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9zdGFja292ZXJmbG93L3dlYnBhY2svcnVudGltZS9wdWJsaWNQYXRoIiwid2VicGFjazovL3N0YWNrb3ZlcmZsb3cvLi9fU2NyaXB0cy9zZXQtcHVibGljLXBhdGgudHMiLCJ3ZWJwYWNrOi8vc3RhY2tvdmVyZmxvdy8uL19TY3JpcHRzL0xlZ2FjeUpTL3NpdGUtYW5hbHl0aWNzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFRoZSByZXF1aXJlIHNjb3BlXG52YXIgX193ZWJwYWNrX3JlcXVpcmVfXyA9IHt9O1xuXG4iLCJfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiOyIsIi8vIFRoaXMgZmlsZSBnZXRzIGF1dG8taW5jbHVkZWQgaW50byBlYWNoIHdlYnBhY2sgZW50cnlwb2ludC5cclxuLy8gV2UgbmVlZCB0byBzZXQgdGhlIHB1YmxpYyBwYXRoIGF0IHJ1bnRpbWUgYmFzZWQgb24gdGhlIEdsb2JhbFJvb3Qgc2l0ZSBzZXR0aW5nLlxyXG4vLyAoV2UgZG9uJ3Qga25vdyBhdCBidWlsZCB0aW1lIHdoZXJlIHRoZSBzdGF0aWMgZmlsZXMgd2lsbCBiZSxcclxuLy8gc2luY2Ugd2UgY291bGQgYmUgZGVwbG95ZWQgb24tcHJlbWlzZS4pXHJcbi8vIFRoZSB2YWx1ZSBvZiB0aGF0IHNpdGUgc2V0dGluZyBnZXRzIHdyaXR0ZW4gb3V0IHRvIHRoZSBkb20gaW4gTWFzdGVyLmNzaHRtbFxyXG4vLyAoc2VlIEphdmFTY3JpcHRIZWxwZXIuUHVibGljUGF0aCgpKSBzbyB0aGF0IHdlIGNhbiByZWFkIGl0IGhlcmVcclxuX193ZWJwYWNrX3B1YmxpY19wYXRoX18gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIndlYnBhY2stcHVibGljLXBhdGhcIikuaW5uZXJUZXh0O1xyXG4iLCIvKioqIElNUE9SVFMgRlJPTSBpbXBvcnRzLWxvYWRlciAqKiovXG5cblxuU3RhY2tFeGNoYW5nZSA9IHdpbmRvdy5TdGFja0V4Y2hhbmdlID0gKHdpbmRvdy5TdGFja0V4Y2hhbmdlIHx8IHt9KTtcblN0YWNrT3ZlcmZsb3cgPSB3aW5kb3cuU3RhY2tPdmVyZmxvdyA9ICh3aW5kb3cuU3RhY2tPdmVyZmxvdyB8fCB7fSk7XG5cblxuU3RhY2tFeGNoYW5nZS5zaXRlQW5hbHl0aWNzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgJ3VzZSBzdHJpY3QnO1xyXG5cclxuICAgIHZhciBncmFwaERpc3BsYXlEYXRhID0ge307XHJcbiAgICB2YXIgbWFyZ2luID0geyB0b3A6IDEwLCByaWdodDogMTAsIGJvdHRvbTogMzAsIGxlZnQ6IDQwIH07XHJcbiAgICB2YXIgd2lkdGggPSA4MDA7XHJcbiAgICB2YXIgaGVpZ2h0ID0gMzAwO1xyXG4gICAgdmFyIHN0YWNrQ29sb3JzID0gWycjZjQ4MDI0JywgJyMwMDc3Y2MnLCAnIzY1YmI1YycsICcjNmIyOTFiJywgJyNmZmNmMTAnLCAnI2YyM2IxNCddO1xyXG5cclxuICAgIHZhciBoaWRkZW5MaW5lcyA9IHt9O1xyXG4gICAgdmFyIHdlZWtseSA9IGZhbHNlO1xyXG5cclxuICAgIGQzLnNlbGVjdGlvbi5wcm90b3R5cGUudG9vbHRpcCA9IGZ1bmN0aW9uICh0YXJnZXQsIG9wdGlvbnMpIHtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7IC8vIHRoZSBlbmV0ZXJlZCBzZWxlY3Rpb25cclxuICAgICAgICBvcHRpb25zID0gJC5leHRlbmQoe1xyXG4gICAgICAgICAgICBzdHlsZTogeyAnei1pbmRleCc6IDEwIH0sXHJcbiAgICAgICAgICAgIHJlcG9zaXRpb246IGZ1bmN0aW9uIChkLCBpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IGQzLmV2ZW50LnBhZ2VYICsgMTUsXHJcbiAgICAgICAgICAgICAgICAgICAgdG9wOiBkMy5ldmVudC5wYWdlWSAtIDE1LFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sIG9wdGlvbnMpO1xyXG4gICAgICAgIHZhciB0b29sdGlwRGl2ID0gZDMuc2VsZWN0KCcuZ3JhcGgnKVxyXG4gICAgICAgICAgICAuYXBwZW5kKCdkaXYnKVxyXG4gICAgICAgICAgICAuYXR0cignY2xhc3MnLCAnZXZlbnRzLXRvb2x0aXAnKVxyXG4gICAgICAgICAgICAuc3R5bGUoJ29wYWNpdHknLCAwKVxyXG4gICAgICAgICAgICAuc3R5bGUoJ2Rpc3BsYXknLCAnbm9uZScpXHJcbiAgICAgICAgICAgIC5zdHlsZSgncG9zaXRpb24nLCAnYWJzb2x1dGUnKTtcclxuICAgICAgICB2YXIgcmVwb3NpdGlvbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIG5ld1Bvc2l0aW9uID0gb3B0aW9ucy5yZXBvc2l0aW9uLmFwcGx5KHRvb2x0aXBEaXYsIGFyZ3VtZW50cyk7XHJcbiAgICAgICAgICAgIHRvb2x0aXBEaXYuc3R5bGUoJ2xlZnQnLCBuZXdQb3NpdGlvbi5sZWZ0ICsgJ3B4Jykuc3R5bGUoJ3RvcCcsIG5ld1Bvc2l0aW9uLnRvcCArICdweCcpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRvb2x0aXBEaXY7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgZm9yICh2YXIgaSBpbiBvcHRpb25zLnN0eWxlKSB7XHJcbiAgICAgICAgICAgIHRvb2x0aXBEaXYuc3R5bGUoaSwgb3B0aW9ucy5zdHlsZVtpXSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzZWxmXHJcbiAgICAgICAgICAgIC5zdHlsZSgncG9pbnRlci1ldmVudHMnLCAnYWxsJykgLy8gbWFrZXMgc3ZnOmcgZ3JvdXBzIHdvcmsgb24gdG9vbHRpcHMgdG9vLi4uXHJcbiAgICAgICAgICAgIC5vbignbW91c2VvdmVyJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdG9vbHRpcERpdi5zdHlsZSgnb3BhY2l0eScsIC45NSkuc3R5bGUoJ2Rpc3BsYXknLCAnYmxvY2snKTtcclxuICAgICAgICAgICAgICAgIHJlcG9zaXRpb24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLm9uKCdtb3VzZW1vdmUnLCByZXBvc2l0aW9uKVxyXG4gICAgICAgICAgICAub24oJ21vdXNlb3V0JywgZnVuY3Rpb24gKGQpIHtcclxuICAgICAgICAgICAgICAgIHRvb2x0aXBEaXYuc3R5bGUoJ29wYWNpdHknLCAwKS5zdHlsZSgnZGlzcGxheScsICdub25lJyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgYmFzaWNGb3JtYXQgPSBmdW5jdGlvbihpKSB7XHJcbiAgICAgICAgcmV0dXJuIGkudG9TdHJpbmcoKTtcclxuICAgIH07XHJcblxyXG4gICAgdmFyIHNpbXBsaWZ5ID0gZnVuY3Rpb24gKGkpIHtcclxuICAgICAgICBpZiAoaSA+PSAxMDAwMDAwICYmIChpICUgMTAwMDAwKSA9PSAwKSByZXR1cm4gYmFzaWNGb3JtYXQoaSAvIDEwMDAwMDApICsgJ00nO1xyXG4gICAgICAgIGlmIChpID49IDEwMDAgJiYgKGkgJSAxMDApID09IDApIHJldHVybiBiYXNpY0Zvcm1hdChpIC8gMTAwMCkgKyAnayc7XHJcbiAgICAgICAgcmV0dXJuIGJhc2ljRm9ybWF0KGkpO1xyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgdGltZUZvcm1hdCA9IGQzLnRpbWUuZm9ybWF0KCclZCAlYicpO1xyXG5cclxuICAgIHZhciBzaW1wbGVEYXRlID0gZnVuY3Rpb24gKGQpIHtcclxuICAgICAgICB2YXIgZGF0ZSA9IG5ldyBEYXRlKGQpO1xyXG4gICAgICAgIHJldHVybiB0aW1lRm9ybWF0KGRhdGUpO1xyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgY29tbWlmeSA9IGZ1bmN0aW9uIChudW1iZXIpIHtcclxuICAgICAgICB2YXIgbnVtYmVyU3RyaW5nID0gU3RyaW5nKG51bWJlci50b0ZpeGVkKDApKTtcclxuICAgICAgICB2YXIgcGFydHMgPSBudW1iZXJTdHJpbmcuc3BsaXQoJy4nKTtcclxuICAgICAgICB2YXIgd2hvbGUgPSBwYXJ0c1swXTtcclxuXHJcbiAgICAgICAgdmFyIHBhdHRlcm4gPSAvKFxcZCspKFxcZHszfSkoLHwkKS87XHJcbiAgICAgICAgd2hpbGUgKHBhdHRlcm4udGVzdCh3aG9sZSkpIHtcclxuICAgICAgICAgICAgd2hvbGUgPSB3aG9sZS5yZXBsYWNlKHBhdHRlcm4sICckMSwkMicpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbnVtYmVyU3RyaW5nID0gKHBhcnRzLmxlbmd0aCA+IDEpID8gd2hvbGUgKyAnLicgKyBwYXJ0c1sxXSA6IHdob2xlO1xyXG4gICAgICAgIHJldHVybiBudW1iZXJTdHJpbmc7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHJlbmRlclRvR3JhcGggPSBmdW5jdGlvbiAoJGVsZW0sIHN2ZywgZGF0YSwgZXh0ZW50cywgY29sb3IpIHtcclxuXHJcbiAgICAgICAgdmFyIHggPSBkMy5zY2FsZS5saW5lYXIoKS5kb21haW4oW2V4dGVudHMueE1pbiwgZXh0ZW50cy54TWF4XSkucmFuZ2UoWzAsIHdpZHRoIC0gKG1hcmdpbi5yaWdodCArIG1hcmdpbi5sZWZ0KV0pO1xyXG4gICAgICAgIHZhciB5ID0gZDMuc2NhbGUubGluZWFyKCkuZG9tYWluKFtleHRlbnRzLnlNaW4sIGV4dGVudHMueU1heF0pLnJhbmdlKFtoZWlnaHQgLSAobWFyZ2luLnRvcCArIG1hcmdpbi5ib3R0b20pLCAxXSk7XHJcblxyXG4gICAgICAgIHZhciB2YWx1ZWxpbmUgPSBkMy5zdmcubGluZSgpXHJcbiAgICAgICAgICAgIC54KGZ1bmN0aW9uKGQsIGkpIHsgcmV0dXJuIHgoZFswXSk7IH0pXHJcbiAgICAgICAgICAgIC55KGZ1bmN0aW9uKGQsIGkpIHsgcmV0dXJuIHkoZFsxXSk7IH0pO1xyXG5cclxuICAgICAgICBzdmcgPSBzdmcuYXBwZW5kKCdnJykuYXR0cigndHJhbnNmb3JtJywgJ3RyYW5zbGF0ZSgnICsgbWFyZ2luLmxlZnQgKyAnLCcgKyBtYXJnaW4udG9wICsgJyknKTtcclxuICAgICAgICB2YXIgcmFuZ2UgPSBzdmcuYXBwZW5kKCdnJykuYXR0cignY2xhc3MnLCAncmFuZ2UnKTtcclxuICAgICAgICByYW5nZS5hcHBlbmQoJ2cnKS5hcHBlbmQoJ3BhdGgnKS5hdHRyKCdzdHJva2UnLCBjb2xvcikuYXR0cignY2xhc3MnLCAnbGluZScpLmF0dHIoJ2QnLCB2YWx1ZWxpbmUoZGF0YSkpO1xyXG4gICAgICAgIHN2Zy5zZWxlY3RBbGwoJy5yYW5nZScpXHJcbiAgICAgICAgICAgIC5kYXRhKGRhdGEpXHJcbiAgICAgICAgICAgIC5hcHBlbmQoJ2cnKVxyXG4gICAgICAgICAgICAuYXR0cignY2xhc3MnLCAnY2lyY2xlcycpXHJcbiAgICAgICAgICAgIC5zZWxlY3RBbGwoJy5jaXJjbGVzJylcclxuICAgICAgICAgICAgLmRhdGEoZGF0YSlcclxuICAgICAgICAgICAgLmVudGVyKClcclxuICAgICAgICAgICAgLmFwcGVuZCgnY2lyY2xlJykuYXR0cigncicsIDIuNylcclxuICAgICAgICAgICAgLmF0dHIoJ2N4JywgZnVuY3Rpb24gKGQsIGkpIHsgcmV0dXJuIHgoZFswXSk7IH0pXHJcbiAgICAgICAgICAgIC5hdHRyKCdjeScsIGZ1bmN0aW9uKGQsIGkpIHsgcmV0dXJuIHkoZFsxXSk7IH0pXHJcbiAgICAgICAgICAgIC5zdHlsZSgnZmlsbCcsIGZ1bmN0aW9uIChkLCBpKSB7IHJldHVybiBjb2xvcjsgfSlcclxuICAgICAgICAgICAgLnRvb2x0aXAoJGVsZW0sIHtcclxuICAgICAgICAgICAgICAgIHJlcG9zaXRpb246IGZ1bmN0aW9uIChkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5odG1sKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoJzxkaXY+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlcmllcy1jb2xvclwiIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjoge2NvbG9yfTtcIj4mbmJzcDs8L2Rpdj4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8cD57dmFsdWV9PC9wPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxwPntkYXRlfTwvcD4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicpLmZvcm1hdFVuaWNvcm4oe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZTogJCgnI3dlZWtseScpLmlzKCc6Y2hlY2tlZCcpID8gX3MoJ1dlZWsgb2YgJGRhdGUkJywgeyBkYXRlIDogbmV3IERhdGUoZFswXSkudG9EYXRlU3RyaW5nKCl9KSA6IG5ldyBEYXRlKGRbMF0pLnRvRGF0ZVN0cmluZygpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGNvbW1pZnkoZFsxXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcjogY29sb3JcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiBkMy5ldmVudC5wYWdlWCArIDEwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IGQzLmV2ZW50LnBhZ2VZIC0gMTBcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgdmFyIGNhbGN1bGF0ZUdyb3VwTWF4TWlucyA9IGZ1bmN0aW9uIChkYXRhLCBncm91cE5hbWUpIHtcclxuICAgICAgICB2YXIgZ3JvdXAgPSB3ZWVrbHkgPyBkYXRhLndlZWtseSA6IGRhdGEuZGFpbHk7XHJcbiAgICAgICAgdmFyIGZpbHRlcmVkT3V0SGlkZGVuID0gZ3JvdXAuZmlsdGVyKGZ1bmN0aW9uKHNlcmllcykge1xyXG4gICAgICAgICAgICByZXR1cm4gaGlkZGVuTGluZXNbZ3JvdXBOYW1lXS5pbmRleE9mKHNlcmllcy5sYWJlbCkgPCAwO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAoZmlsdGVyZWRPdXRIaWRkZW4ubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHhNaW46IDAsIHhNYXg6IDAsIHlNaW46IDAsIHlNYXg6IDAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciB4TWluID0gZDMubWluKGZpbHRlcmVkT3V0SGlkZGVuWzBdLmRhdGEsIGZ1bmN0aW9uIChkLCBpZHgpIHsgcmV0dXJuIGRbMF07IH0pO1xyXG4gICAgICAgIHZhciB4TWF4ID0gZDMubWF4KGZpbHRlcmVkT3V0SGlkZGVuWzBdLmRhdGEsIGZ1bmN0aW9uIChkLCBpZHgpIHsgcmV0dXJuIGRbMF07IH0pOztcclxuICAgICAgICB2YXIgeU1pbiA9IGQzLm1pbihmaWx0ZXJlZE91dEhpZGRlblswXS5kYXRhLCBmdW5jdGlvbiAoZCwgaWR4KSB7IHJldHVybiBkWzFdOyB9KTtcclxuICAgICAgICB2YXIgeU1heCA9IGQzLm1heChmaWx0ZXJlZE91dEhpZGRlblswXS5kYXRhLCBmdW5jdGlvbiAoZCwgaWR4KSB7IHJldHVybiBkWzFdOyB9KTs7XHJcblxyXG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgZmlsdGVyZWRPdXRIaWRkZW4ubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKHhNaW4gPiBkMy5taW4oZmlsdGVyZWRPdXRIaWRkZW5baV0uZGF0YSwgZnVuY3Rpb24gKGQsIGlkeCkgeyByZXR1cm4gZFswXTsgfSkpIHtcclxuICAgICAgICAgICAgICAgIHhNaW4gPSBkMy5taW4oZmlsdGVyZWRPdXRIaWRkZW5baV0uZGF0YSwgZnVuY3Rpb24gKGQsIGlkeCkgeyByZXR1cm4gZFswXTsgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHhNYXggPCBkMy5tYXgoZmlsdGVyZWRPdXRIaWRkZW5baV0uZGF0YSwgZnVuY3Rpb24gKGQsIGlkeCkgeyByZXR1cm4gZFswXTsgfSkpIHtcclxuICAgICAgICAgICAgICAgIHhNYXggPSBkMy5tYXgoZmlsdGVyZWRPdXRIaWRkZW5baV0uZGF0YSwgZnVuY3Rpb24gKGQsIGlkeCkgeyByZXR1cm4gZFswXTsgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHlNaW4gPiBkMy5taW4oZmlsdGVyZWRPdXRIaWRkZW5baV0uZGF0YSwgZnVuY3Rpb24gKGQsIGlkeCkgeyByZXR1cm4gZFsxXTsgfSkpIHtcclxuICAgICAgICAgICAgICAgIHlNaW4gPSBkMy5taW4oZmlsdGVyZWRPdXRIaWRkZW5baV0uZGF0YSwgZnVuY3Rpb24gKGQsIGlkeCkgeyByZXR1cm4gZFsxXTsgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHlNYXggPCBkMy5tYXgoZmlsdGVyZWRPdXRIaWRkZW5baV0uZGF0YSwgZnVuY3Rpb24gKGQsIGlkeCkgeyByZXR1cm4gZFsxXTsgfSkpIHtcclxuICAgICAgICAgICAgICAgIHlNYXggPSBkMy5tYXgoZmlsdGVyZWRPdXRIaWRkZW5baV0uZGF0YSwgZnVuY3Rpb24gKGQsIGlkeCkgeyByZXR1cm4gZFsxXTsgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB7IHhNaW46IHhNaW4sIHhNYXg6IHhNYXgsIHlNaW46IHlNaW4sIHlNYXg6IHlNYXggfTtcclxuICAgIH07XHJcblxyXG4gICAgdmFyIHJlbmRlckdyb3VwID0gZnVuY3Rpb24gKCRlbGVtLCAkc3ZnLCBkYXRhKSB7XHJcbiAgICAgICAgdmFyIGdyb3VwTmFtZSA9ICRlbGVtLmNsb3Nlc3QoJy5ncmFwaCcpLmRhdGEoJ25hbWUnKTtcclxuICAgICAgICB2YXIgZ3JvdXBFeHRlbnRzID0gY2FsY3VsYXRlR3JvdXBNYXhNaW5zKGRhdGEsIGdyb3VwTmFtZSk7XHJcbiAgICAgICAgdmFyIGNoZWNrYm94ZXMgPSAnPGRpdiBjbGFzcz1cImNvbC0yXCI+PHVsPic7XHJcbiAgICAgICAgdmFyIHN2ZyA9IGQzLnNlbGVjdEFsbCgkc3ZnLnRvQXJyYXkoKSk7XHJcblxyXG4gICAgICAgIHZhciBncm91cCA9IHdlZWtseSA/IGRhdGEud2Vla2x5IDogZGF0YS5kYWlseTtcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGdyb3VwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBzZXJpZXMgPSBncm91cFtpXTtcclxuICAgICAgICAgICAgdmFyIGlzU2VyaWVzVmlzaWJsZSA9IGhpZGRlbkxpbmVzW2dyb3VwTmFtZV0uaW5kZXhPZihzZXJpZXMubGFiZWwpIDwgMDtcclxuICAgICAgICAgICAgdmFyIGNoZWNrZWRBdHRyaWJ1dGUgPSAnJztcclxuICAgICAgICAgICAgaWYgKGlzU2VyaWVzVmlzaWJsZSkge1xyXG4gICAgICAgICAgICAgICAgY2hlY2tlZEF0dHJpYnV0ZSA9ICcgY2hlY2tlZD1cImNoZWNrZWRcIic7XHJcbiAgICAgICAgICAgICAgICByZW5kZXJUb0dyYXBoKCRlbGVtLCBzdmcsIHNlcmllcy5kYXRhLCBncm91cEV4dGVudHMsIHN0YWNrQ29sb3JzW2ldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjaGVja2JveGVzICs9ICc8bGk+PGxhYmVsIHN0eWxlPVwiY29sb3I6JyArIHN0YWNrQ29sb3JzW2ldICsgJ1wiPjxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBuYW1lPVwiJyArIHNlcmllcy5sYWJlbCArICdcIicgKyBjaGVja2VkQXR0cmlidXRlICsgJz4nICsgc2VyaWVzLmxvY2FsaXplZExhYmVsICsgJzwvbGFiZWw+PC9saT4nO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHggPSBkMy5zY2FsZS5saW5lYXIoKS5kb21haW4oW2dyb3VwRXh0ZW50cy54TWluLCBncm91cEV4dGVudHMueE1heF0pLnJhbmdlKFswLCB3aWR0aCAtIChtYXJnaW4ucmlnaHQgKyBtYXJnaW4ubGVmdCldKTtcclxuICAgICAgICB2YXIgeSA9IGQzLnNjYWxlLmxpbmVhcigpLmRvbWFpbihbZ3JvdXBFeHRlbnRzLnlNaW4sIGdyb3VwRXh0ZW50cy55TWF4XSkucmFuZ2UoW2hlaWdodCAtIChtYXJnaW4udG9wICsgbWFyZ2luLmJvdHRvbSksIDFdKTtcclxuXHJcbiAgICAgICAgdmFyIHlBeGlzID0gZDMuc3ZnLmF4aXMoKS5zY2FsZSh5KS5vcmllbnQoJ2xlZnQnKS50aWNrRm9ybWF0KHNpbXBsaWZ5KTtcclxuICAgICAgICBzdmcuYXBwZW5kKCdnJykuYXR0cignY2xhc3MnLCAneSBheGlzJykuYXR0cigndHJhbnNmb3JtJywgJ3RyYW5zbGF0ZSgnICsgbWFyZ2luLmxlZnQgKyAnLCcgKyBtYXJnaW4udG9wICsgJyknKS5jYWxsKHlBeGlzKVxyXG4gICAgICAgICAgICAuYXBwZW5kKCd0ZXh0JykuYXR0cigndHJhbnNmb3JtJywgJ3JvdGF0ZSgtOTApJykuYXR0cigneScsIDYpLmF0dHIoJ2R5JywgJy43MWVtJykuc3R5bGUoJ3RleHQtYW5jaG9yJywgJ2VuZCcpO1xyXG5cclxuICAgICAgICB2YXIgeEF4aXMgPSBkMy5zdmcuYXhpcygpLnNjYWxlKHgpLm9yaWVudCgnYm90dG9tJykudGlja3MoOCkudGlja0Zvcm1hdChzaW1wbGVEYXRlKTtcclxuICAgICAgICBzdmcuYXBwZW5kKCdnJykuYXR0cignY2xhc3MnLCAneCBheGlzJykuYXR0cigndHJhbnNmb3JtJywgJ3RyYW5zbGF0ZSgnICsgbWFyZ2luLmxlZnQgKyAnLCcgKyAoaGVpZ2h0IC0gbWFyZ2luLmJvdHRvbSkgKyAnKScpLmNhbGwoeEF4aXMpO1xyXG5cclxuICAgICAgICAkZWxlbS5hcHBlbmQoY2hlY2tib3hlcyArICc8L3VsPjwvZGl2PicpO1xyXG4gICAgICAgIHZhciBncmFwaENvbCA9ICQoJzxkaXYgY2xhc3M9XCJjb2wtMTBcIj4nKTtcclxuICAgICAgICAkZWxlbS5hcHBlbmQoZ3JhcGhDb2wuYXBwZW5kKCRzdmcpKTtcclxuICAgIH07XHJcblxyXG4gICAgdmFyIG1lcmdlR3JvdXBzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBkYWlseSA9IFtdLCB3ZWVrbHkgPSBbXTtcclxuXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgZGFpbHkucHVzaC5hcHBseShkYWlseSwgYXJndW1lbnRzW2ldLmRhaWx5KTtcclxuICAgICAgICAgICAgd2Vla2x5LnB1c2guYXBwbHkod2Vla2x5LCBhcmd1bWVudHNbaV0ud2Vla2x5KTtcclxuXHJcbiAgICAgICAgICAgIGRhaWx5W2ldLmNvbG9yID0gd2Vla2x5W2ldLmNvbG9yID0gc3RhY2tDb2xvcnNbaV07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4geyBkYWlseTogZGFpbHksIHdlZWtseTogd2Vla2x5IH07XHJcbiAgICB9O1xyXG5cclxuICAgIHZhciBkaXNwbGF5R3JhcGggPSBmdW5jdGlvbiAoJGVsZW0sIGRhdGEpIHtcclxuICAgICAgICAkZWxlbS5odG1sKCcnKTsgLy8gd2lwZVxyXG4gICAgICAgIHZhciAkc3ZnID0gJCgnPHN2ZyB3aWR0aD1cIicgKyB3aWR0aCArICdcIiBoZWlnaHQ9XCInICsgaGVpZ2h0ICsgJ1wiPicpO1xyXG4gICAgICAgIHJlbmRlckdyb3VwKCRlbGVtLCAkc3ZnLCBkYXRhKTtcclxuICAgIH07XHJcblxyXG4gICAgdmFyIHJlUmVuZGVyQWxsR3JhcGhzID0gZnVuY3Rpb24oZ3JhcGhzKSB7XHJcbiAgICAgICAgZ3JhcGhzLmVhY2goZnVuY3Rpb24oaW5kZXgsIGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdmFyIG5hbWUgPSAkKGVsZW1lbnQpLmRhdGEoJ25hbWUnKTtcclxuICAgICAgICAgICAgdmFyICRlbGVtID0gJChlbGVtZW50KTtcclxuICAgICAgICAgICAgJGVsZW0uYWRkU3Bpbm5lcigpO1xyXG4gICAgICAgICAgICBTdGFja0V4Y2hhbmdlLmhlbHBlcnMucmVtb3ZlU3Bpbm5lcigpO1xyXG4gICAgICAgICAgICBkaXNwbGF5R3JhcGgoJGVsZW0sIGdyYXBoRGlzcGxheURhdGFbbmFtZV0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgYnVpbGRHcmFwaHNBbmRHcmFwaERhdGEgPSBmdW5jdGlvbihncmFwaHMpIHtcclxuICAgICAgICBncmFwaHMuZWFjaChmdW5jdGlvbiAoaW5kZXgsIGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdmFyIG5hbWUgPSAkKGVsZW1lbnQpLmRhdGEoJ25hbWUnKTtcclxuICAgICAgICAgICAgdmFyICRlbGVtID0gJChlbGVtZW50KTtcclxuICAgICAgICAgICAgJGVsZW0uYWRkU3Bpbm5lcigpO1xyXG4gICAgICAgICAgICAkLmFqYXgoJy9zaXRlLWFuYWx5dGljcy8nICsgbmFtZSwgeyBkYXRhOiB7IGZyb206ICQoJyNmcm9tJykudmFsKCksIHRvOiAkKCcjdG8nKS52YWwoKSB9IH0pXHJcbiAgICAgICAgICAgICAgICAuZG9uZShmdW5jdGlvbiAoZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSAndHJhZmZpYycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZ3JhcGhEaXNwbGF5RGF0YVtuYW1lXSA9IG1lcmdlR3JvdXBzKGRhdGEucGFnZVZpZXdzLCBkYXRhLnZpc2l0cywgZGF0YS5uZXdWaXNpdHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGdyYXBoRGlzcGxheURhdGFbbmFtZV0gPSBkYXRhO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWhpZGRlbkxpbmVzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhpZGRlbkxpbmVzW25hbWVdID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXlHcmFwaCgkZWxlbSwgZ3JhcGhEaXNwbGF5RGF0YVtuYW1lXSk7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmZhaWwoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICRlbGVtLmFwcGVuZCgnPGRpdiBjbGFzcz1cInZhbC1tZXNzYWdlIHZhbC1lcnJvclwiPjxwPicgKyBfcygnQW4gZXJyb3IgaGFzIG9jY3VycmVkIHdoaWxlIHJldHJpZXZpbmcgZGF0YS4gUGxlYXNlIHRyeSBhZ2FpbiBpbiAyNCBob3Vycy4nKSArICc8L3A+PC9kaXY+Jyk7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmFsd2F5cyhmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgU3RhY2tFeGNoYW5nZS5oZWxwZXJzLnJlbW92ZVNwaW5uZXIoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICBmdW5jdGlvbiB6aXAoYXJyYXlzKSB7XHJcbiAgICAgICAgcmV0dXJuIGFycmF5c1swXS5tYXAoZnVuY3Rpb24gKF8sIGkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFycmF5cy5tYXAoZnVuY3Rpb24gKGFycmF5KSB7IHJldHVybiBhcnJheVtpXSB9KVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBnZXRDc3ZGb3JHcmFwaCA9IGZ1bmN0aW9uIChncmFwaE5hbWUpIHtcclxuICAgICAgICB2YXIgZ3JhcGhEYXRhID0gZ3JhcGhEaXNwbGF5RGF0YVtncmFwaE5hbWVdO1xyXG5cclxuICAgICAgICB2YXIgaGVhZGVyID0gWydkYXRlJ107XHJcbiAgICAgICAgdmFyIHNlcmllc0RhdGEgPSAkKCcjd2Vla2x5JykuaXMoJzpjaGVja2VkJykgPyBncmFwaERhdGEud2Vla2x5IDogZ3JhcGhEYXRhLmRhaWx5O1xyXG4gICAgICAgIHZhciBjc3YgPSBbaGVhZGVyLmNvbmNhdChzZXJpZXNEYXRhLm1hcChmdW5jdGlvbiAoZCkgeyByZXR1cm4gZC5sb2NhbGl6ZWRMYWJlbDsgfSkpXTtcclxuXHJcbiAgICAgICAgdmFyIGRhdGFQb2ludHMgPSBzZXJpZXNEYXRhLm1hcChmdW5jdGlvbihkKSB7IHJldHVybiBkLmRhdGE7IH0pO1xyXG5cclxuICAgICAgICB2YXIgam9pbmVkID0gemlwKGRhdGFQb2ludHMpLm1hcChmdW5jdGlvbiAoZCkge1xyXG4gICAgICAgICAgICB2YXIgZGF0ZSA9IG5ldyBEYXRlKGRbMF1bMF0pO1xyXG4gICAgICAgICAgICB2YXIgbWVyZ2VkID0gWyQuZGF0ZXBpY2tlci5mb3JtYXREYXRlKCd5eS1tbS1kZCcsIGRhdGUpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBtZXJnZWQucHVzaChkW2ldWzFdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gbWVyZ2VkO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGNzdiA9IGNzdi5jb25jYXQoam9pbmVkKTtcclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gZDMuY3N2LmZvcm1hdFJvd3MoY3N2KTtcclxuICAgIH07XHJcblxyXG4gICAgdmFyIGRvd25sb2FkQ1NWID0gZnVuY3Rpb24gKGNzdiwgZmlsZU5hbWUpIHtcclxuICAgICAgICAvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3EvMjkzMDQ0MTRcclxuXHJcbiAgICAgICAgdmFyIGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XHJcbiAgICAgICAgdmFyIG1pbWVUeXBlID0gJ3RleHQvY3N2JztcclxuXHJcbiAgICAgICAgaWYgKG5hdmlnYXRvci5tc1NhdmVCbG9iKSB7IC8vIElFMTBcclxuICAgICAgICAgICAgcmV0dXJuIG5hdmlnYXRvci5tc1NhdmVCbG9iKG5ldyBCbG9iKFtjb250ZW50XSwgeyB0eXBlOiBtaW1lVHlwZSB9KSwgZmlsZU5hbWUpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoJ2Rvd25sb2FkJyBpbiBhKSB7IC8vaHRtbDUgQVtkb3dubG9hZF1cclxuICAgICAgICAgICAgdmFyIGJsb2IgPSBuZXcgQmxvYihbY3N2XSwgeyB0eXBlOiAndGV4dC9jc3Y7Y2hhcnNldD11dGYtODsnIH0pO1xyXG4gICAgICAgICAgICB2YXIgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcclxuICAgICAgICAgICAgYS5ocmVmID0gdXJsO1xyXG4gICAgICAgICAgICBhLnNldEF0dHJpYnV0ZSgnZG93bmxvYWQnLCBmaWxlTmFtZSk7XHJcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgYS5jbGljaygpO1xyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChhKTtcclxuICAgICAgICAgICAgfSwgNjYpO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9IGVsc2UgeyAvL2RvIGlmcmFtZSBkYXRhVVJMIGRvd25sb2FkIChvbGQgY2grRkYpOlxyXG4gICAgICAgICAgICB2YXIgZiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xyXG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGYpO1xyXG4gICAgICAgICAgICBmLnNyYyA9ICdkYXRhOicgKyBtaW1lVHlwZSArICcsJyArIGVuY29kZVVSSUNvbXBvbmVudChjb250ZW50KTtcclxuXHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChmKTtcclxuICAgICAgICAgICAgfSwgMzMzKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgaW5pdCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgdmFyIGdyYXBocyA9ICQoJy5ncmFwaCcpO1xyXG4gICAgICAgIGJ1aWxkR3JhcGhzQW5kR3JhcGhEYXRhKGdyYXBocyk7XHJcblxyXG4gICAgICAgIGdyYXBocy5vbignY2hhbmdlJywgJ2lucHV0W3R5cGU9Y2hlY2tib3hdJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgdmFyICRncmFwaCA9ICQoZS50YXJnZXQpLmNsb3Nlc3QoJy5ncmFwaCcpO1xyXG4gICAgICAgICAgICB2YXIgZ3JhcGhOYW1lID0gJGdyYXBoLmRhdGEoJ25hbWUnKTtcclxuICAgICAgICAgICAgdmFyIHNlcmllcyA9IGUudGFyZ2V0Lm5hbWU7XHJcblxyXG4gICAgICAgICAgICAvLyB0b2RvOiBwZXJzaXN0IGhpZGRlbiBzZXJpZXNcclxuICAgICAgICAgICAgZS50YXJnZXQuY2hlY2tlZCA/IGhpZGRlbkxpbmVzW2dyYXBoTmFtZV0uc3BsaWNlKGhpZGRlbkxpbmVzW2dyYXBoTmFtZV0uaW5kZXhPZihzZXJpZXMpLCAxKSA6IGhpZGRlbkxpbmVzW2dyYXBoTmFtZV0ucHVzaChzZXJpZXMpO1xyXG4gICAgICAgICAgICBkaXNwbGF5R3JhcGgoJGdyYXBoLCBncmFwaERpc3BsYXlEYXRhW2dyYXBoTmFtZV0pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAkKCcjd2Vla2x5JykuY2hhbmdlKGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIC8vIHRvZG86IHBlcnNpc3Qgd2Vla2x5L2RhaWx5IHZpZXdcclxuICAgICAgICAgICAgd2Vla2x5ID0gZS50YXJnZXQuY2hlY2tlZDtcclxuICAgICAgICAgICAgcmVSZW5kZXJBbGxHcmFwaHMoZ3JhcGhzKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgJCgnI2Zyb20nKS5kYXRlcGlja2VyKHsgZGF0ZUZvcm1hdDogJ3l5LU0tZGQnLCBkZWZhdWx0RGF0ZTogb3B0aW9ucy5mcm9tRGF0ZSwgbWF4RGF0ZTogb3B0aW9ucy5tYXhEYXRlLCBtaW5EYXRlOiBvcHRpb25zLm1pbkRhdGUgfSk7XHJcbiAgICAgICAgJCgnI3RvJykuZGF0ZXBpY2tlcih7IGRhdGVGb3JtYXQ6ICd5eS1NLWRkJywgZGVmYXVsdERhdGU6IG9wdGlvbnMudG9EYXRlLCBtYXhEYXRlOiBvcHRpb25zLm1heERhdGUsIG1pbkRhdGU6IG9wdGlvbnMubWluRGF0ZSB9KTtcclxuXHJcbiAgICAgICAgJCgnI2Zyb20sICN0bycpLmNoYW5nZShmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgdmFyIGdyYXBocyA9ICQoJy5ncmFwaCcpO1xyXG4gICAgICAgICAgICBidWlsZEdyYXBoc0FuZEdyYXBoRGF0YShncmFwaHMpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAkKFwiLnBoYXNlRGF0ZVwiKS5jbGljayhmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgIHZhciBwaGFzZURhdGUgPSAkKGUudGFyZ2V0KS50ZXh0KCk7XHJcbiAgICAgICAgICAgIHZhciBmcm9tRGF0ZSA9ICQoJyNmcm9tJykudmFsKCk7XHJcbiAgICAgICAgICAgIGlmIChmcm9tRGF0ZSAhPT0gcGhhc2VEYXRlKSB7XHJcbiAgICAgICAgICAgICAgICAkKCcjZnJvbScpLmRhdGVwaWNrZXIoJ3NldERhdGUnLCBwaGFzZURhdGUpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGdyYXBocyA9ICQoJy5ncmFwaCcpO1xyXG4gICAgICAgICAgICAgICAgYnVpbGRHcmFwaHNBbmRHcmFwaERhdGEoZ3JhcGhzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICQoJy5jc3YnKS5jbGljayhmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgIHZhciBncmFwaE5hbWUgPSAkKGUudGFyZ2V0KS5jbG9zZXN0KCcuZ3JhcGgtY29udGFpbmVyJykuZmluZCgnLmdyYXBoJykuZGF0YSgnbmFtZScpO1xyXG5cclxuICAgICAgICAgICAgdmFyIGZyb20gPSQoJyNmcm9tJykudmFsKCk7XHJcbiAgICAgICAgICAgIHZhciB0byA9ICQoJyN0bycpLnZhbCgpO1xyXG4gICAgICAgICAgICB2YXIgZmlsZU5hbWUgPSBcIntncmFwaE5hbWV9X3tmcm9tfV97dG99XCIuZm9ybWF0VW5pY29ybih7IGdyYXBoTmFtZTogZ3JhcGhOYW1lLCBmcm9tOiBmcm9tLCB0bzogdG8gfSkgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKCQoJyN3ZWVrbHknKS5pcygnOmNoZWNrZWQnKT8nX3dlZWtseSc6JycpICsgJy5jc3YnO1xyXG4gICAgICAgICAgICB2YXIgY3N2ID0gZ2V0Q3N2Rm9yR3JhcGgoZ3JhcGhOYW1lKTtcclxuXHJcbiAgICAgICAgICAgIGRvd25sb2FkQ1NWKGNzdiwgZmlsZU5hbWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgcmVuZGVyUGllQ2hhcnQgPSBmdW5jdGlvbiAoc2VsZWN0b3IsIGRhdGEsIG9wdGlvbnMpIHtcclxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgICAgICBvcHRpb25zLmluY2x1ZGVMZWdlbmQgPSBvcHRpb25zLmluY2x1ZGVMZWdlbmQgfHwgZmFsc2U7XHJcbiAgICAgICAgb3B0aW9ucy5yZXNpemVSYXRpbyA9IG9wdGlvbnMucmVzaXplUmF0aW8gfHwgMTtcclxuICAgICAgICBvcHRpb25zLmluY2x1ZGVUb29sdGlwID0gb3B0aW9ucy5pbmNsdWRlVG9vbHRpcCB8fCBmYWxzZTtcclxuICAgICAgICBvcHRpb25zLnVzZUN1c3RvbUNvbG9ycyA9IG9wdGlvbnMudXNlQ3VzdG9tQ29sb3JzIHx8IGZhbHNlO1xyXG5cclxuICAgICAgICB2YXIgY3VzdG9tQ29sb3JzID0gWycjZmY3ZjBlJywgJyMwMDk1ZmYnLCAnIzY4YmE2MCddO1xyXG5cclxuICAgICAgICB2YXIgcGllV2lkdGggPSAzMjAgKiBvcHRpb25zLnJlc2l6ZVJhdGlvLCBwaWVIZWlnaHQgPSAzMjAgKiBvcHRpb25zLnJlc2l6ZVJhdGlvLCByYWRpdXMgPSAxNTAgKiBvcHRpb25zLnJlc2l6ZVJhdGlvO1xyXG4gICAgICAgIHZhciBjb2xvciA9IGQzLnNjYWxlLmNhdGVnb3J5MTAoKTtcclxuXHJcbiAgICAgICAgdmFyIHRvdGFsVmlzaXRzID0gZGF0YS5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgY3VyciwgaSwgYXJyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBwcmV2ICsgY3Vyci52aXNpdHM7XHJcbiAgICAgICAgfSwgMCk7XHJcblxyXG4gICAgICAgIHZhciBzdmcgPSBkMy5zZWxlY3RBbGwoc2VsZWN0b3IpXHJcbiAgICAgICAgLmFwcGVuZCgnc3ZnOnN2ZycpXHJcbiAgICAgICAgLmRhdGEoW2RhdGFdKVxyXG4gICAgICAgIC5hdHRyKCd3aWR0aCcsIHBpZVdpZHRoICsgMTUwKVxyXG4gICAgICAgIC5hdHRyKCdoZWlnaHQnLCBwaWVIZWlnaHQpXHJcbiAgICAgICAgLmFwcGVuZCgnc3ZnOmcnKVxyXG4gICAgICAgIC5hdHRyKCd0cmFuc2Zvcm0nLCAndHJhbnNsYXRlKCcgKyBwaWVXaWR0aCAvIDIgKyAnLCcgKyBwaWVIZWlnaHQgLyAyICsgJyknKTtcclxuXHJcbiAgICAgICAgdmFyIGFyYyA9IGQzLnN2Zy5hcmMoKVxyXG4gICAgICAgICAgICAub3V0ZXJSYWRpdXMocmFkaXVzKTtcclxuXHJcbiAgICAgICAgdmFyIHBpZSA9IGQzLmxheW91dC5waWUoKVxyXG4gICAgICAgICAgICAudmFsdWUoZnVuY3Rpb24gKGQpIHsgcmV0dXJuIGQudmlzaXRzOyB9KTtcclxuXHJcbiAgICAgICAgdmFyIGFyY3MgPSBzdmcuc2VsZWN0QWxsKCdnLnNsaWNlJylcclxuICAgICAgICAgICAgLmRhdGEocGllKVxyXG4gICAgICAgICAgICAuZW50ZXIoKVxyXG4gICAgICAgICAgICAuYXBwZW5kKCdzdmc6ZycpXHJcbiAgICAgICAgICAgIC5hdHRyKCdjbGFzcycsICdzbGljZScpO1xyXG5cclxuICAgICAgICBhcmNzLmFwcGVuZCgnc3ZnOnBhdGgnKVxyXG4gICAgICAgICAgICAuYXR0cignZmlsbCcsIGZ1bmN0aW9uIChkLCBpKSB7IHJldHVybiBvcHRpb25zLnVzZUN1c3RvbUNvbG9ycyA/IGN1c3RvbUNvbG9yc1tpXSA6IGNvbG9yKGkpOyB9KVxyXG4gICAgICAgICAgICAuYXR0cignZCcsIGFyYyk7XHJcblxyXG4gICAgICAgIGFyY3MuZmlsdGVyKGZ1bmN0aW9uKGQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE1hdGguYWJzKGQuc3RhcnRBbmdsZSAtIGQuZW5kQW5nbGUpID49IE1hdGguUEkgLyA2O1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuYXBwZW5kKCdzdmc6dGV4dCcpXHJcbiAgICAgICAgICAgIC5hdHRyKCd0cmFuc2Zvcm0nLCBmdW5jdGlvbihkKSB7XHJcbiAgICAgICAgICAgICAgICAvL3dlIGhhdmUgdG8gbWFrZSBzdXJlIHRvIHNldCB0aGVzZSBiZWZvcmUgY2FsbGluZyBhcmMuY2VudHJvaWRcclxuICAgICAgICAgICAgICAgIGQuaW5uZXJSYWRpdXMgPSAwO1xyXG4gICAgICAgICAgICAgICAgZC5vdXRlclJhZGl1cyA9IHJhZGl1cztcclxuICAgICAgICAgICAgICAgIHJldHVybiAndHJhbnNsYXRlKCcgKyBhcmMuY2VudHJvaWQoZCkgKyAnKSc7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5hdHRyKCd0ZXh0LWFuY2hvcicsICdtaWRkbGUnKVxyXG4gICAgICAgICAgICAuYXR0cignZmlsbCcsICd3aGl0ZScpXHJcbiAgICAgICAgICAgIC50ZXh0KGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGQuZGF0YS5zb3VyY2U7IH0pO1xyXG5cclxuICAgICAgICBpZiAob3B0aW9ucy5pbmNsdWRlVG9vbHRpcCkge1xyXG4gICAgICAgICAgICBhcmNzLnRvb2x0aXAoJChzZWxlY3RvciksIHtcclxuICAgICAgICAgICAgICAgIHJlcG9zaXRpb246IGZ1bmN0aW9uKGQsIGkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmh0bWwoKCc8ZGl2PicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNlcmllcy1jb2xvclwiIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjoge2NvbG9yfTtcIj4mbmJzcDs8L2Rpdj4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJzxwPntzb3VyY2V9PC9wPicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnPHA+e3ZhbHVlfTwvcD4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJzwvZGl2PicpLmZvcm1hdFVuaWNvcm4oe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IGQuZGF0YS5zb3VyY2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBjb21taWZ5KGQuZGF0YS52aXNpdHMpICsgJyAoJyArIChkLmRhdGEudmlzaXRzIC8gdG90YWxWaXNpdHMgKiAxMDApLnRvRml4ZWQoMSkgKyAnJSknLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvcjogb3B0aW9ucy51c2VDdXN0b21Db2xvcnMgPyBjdXN0b21Db2xvcnNbaV0gOiBjb2xvcihpKVxyXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdDogZDMuZXZlbnQucGFnZVggKyAxMCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiBkMy5ldmVudC5wYWdlWSAtIDEwLFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKG9wdGlvbnMuaW5jbHVkZUxlZ2VuZCkge1xyXG4gICAgICAgICAgICB2YXIgbGVnZW5kUmVjdFNpemUgPSAxODtcclxuICAgICAgICAgICAgdmFyIGxlZ2VuZFNwYWNpbmcgPSA0O1xyXG5cclxuICAgICAgICAgICAgdmFyIGxlZ2VuZCA9IHN2Zy5zZWxlY3RBbGwoJy5sZWdlbmQnKVxyXG4gICAgICAgICAgICAgICAgLmRhdGEoZGF0YSlcclxuICAgICAgICAgICAgICAgIC5lbnRlcigpXHJcbiAgICAgICAgICAgICAgICAuYXBwZW5kKCdzdmc6ZycpXHJcbiAgICAgICAgICAgICAgICAuYXR0cignY2xhc3MnLCAnbGVnZW5kJylcclxuICAgICAgICAgICAgICAgIC5hdHRyKCd0cmFuc2Zvcm0nLCBmdW5jdGlvbihkLCBpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlY3RIZWlnaHQgPSBsZWdlbmRSZWN0U2l6ZSArIGxlZ2VuZFNwYWNpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9mZnNldCA9IHJlY3RIZWlnaHQgKiBkYXRhLmxlbmd0aCAvIDI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhvcnogPSBwaWVXaWR0aCAvIDIgKyA1O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2ZXJ0ID0gaSAqIG9mZnNldCAtIHBpZUhlaWdodCAvIDIgKyAxMDtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJ3RyYW5zbGF0ZSgnICsgaG9yeiArICcsJyArIHZlcnQgKyAnKSc7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGxlZ2VuZC5hcHBlbmQoJ3N2ZzpyZWN0JylcclxuICAgICAgICAgICAgICAgIC5hdHRyKCd3aWR0aCcsIGxlZ2VuZFJlY3RTaXplKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2hlaWdodCcsIGxlZ2VuZFJlY3RTaXplKVxyXG4gICAgICAgICAgICAgICAgLnN0eWxlKCdmaWxsJywgZnVuY3Rpb24gKGQsIGkpIHsgcmV0dXJuIG9wdGlvbnMudXNlQ3VzdG9tQ29sb3JzID8gY3VzdG9tQ29sb3JzW2ldIDogY29sb3IoaSk7IH0pXHJcbiAgICAgICAgICAgICAgICAuc3R5bGUoJ3N0cm9rZScsIGZ1bmN0aW9uIChkLCBpKSB7IHJldHVybiBvcHRpb25zLnVzZUN1c3RvbUNvbG9ycyA/IGN1c3RvbUNvbG9yc1tpXSA6IGNvbG9yKGkpOyB9KTtcclxuXHJcbiAgICAgICAgICAgIGxlZ2VuZC5hcHBlbmQoJ3N2Zzp0ZXh0JylcclxuICAgICAgICAgICAgICAgIC5hdHRyKCd4JywgbGVnZW5kUmVjdFNpemUgKyBsZWdlbmRTcGFjaW5nKVxyXG4gICAgICAgICAgICAgICAgLmF0dHIoJ3knLCBsZWdlbmRSZWN0U2l6ZSAtIGxlZ2VuZFNwYWNpbmcpXHJcbiAgICAgICAgICAgICAgICAuYXR0cignZm9udC1zaXplJywgMTApXHJcbiAgICAgICAgICAgICAgICAudGV4dChmdW5jdGlvbiAoZCkgeyByZXR1cm4gZC5zb3VyY2UgKyAnOiAnICsgY29tbWlmeShkLnZpc2l0cykgKyAnICgnICsgKGQudmlzaXRzIC8gdG90YWxWaXNpdHMgKiAxMDApLnRvRml4ZWQoMSkgKyAnJSknOyB9KTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHZhciByZW5kZXJUYWJsZSA9IGZ1bmN0aW9uIChzZWxlY3RvciwgZGF0YSkge1xyXG4gICAgICAgIHZhciByb3dzID0gJyc7XHJcbiAgICAgICAgJC5lYWNoKGRhdGEsIGZ1bmN0aW9uKGksIGQpIHtcclxuICAgICAgICAgICAgcm93cyArPSAnPHRyPjx0ZD4nICsgZC5zb3VyY2UgKyAnPC90ZD48dGQ+JyArIGNvbW1pZnkoZC52aXNpdHMpICsgJzwvdGQ+PHRyPic7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgJChzZWxlY3RvcikuYXBwZW5kKHJvd3MpO1xyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4geyBpbml0OiBpbml0LCByZW5kZXJQaWVDaGFydDogcmVuZGVyUGllQ2hhcnQsIHJlbmRlclRhYmxlOiByZW5kZXJUYWJsZSB9O1xyXG59KCk7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9