Skip to content

Instantly share code, notes, and snippets.

@tmpvar
Last active May 20, 2016 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmpvar/bf99d3103f4c80d2acc4376d30d62a4d to your computer and use it in GitHub Desktop.
Save tmpvar/bf99d3103f4c80d2acc4376d30d62a4d to your computer and use it in GitHub Desktop.
requirebin sketch
var fc = require('fc')
var center = require('ctx-translate-center')
var grid = require('ctx-render-grid-lines')
var circle = require('ctx-circle')
var ndarray = require('ndarray')
var fillArray = require('ndarray-fill')
var marchingSquares = require('marching-squares')
var surfaceNets = require('surface-nets')
// where size is the bin size from 0..1
function createBinner(radius, width, height) {
var cx = Math.ceil(width/radius)
var cy = Math.ceil(height/radius)
var bins = ndarray(new Int32Array(cx * cy), [cx, cy])
fillArray(bins, function(i, j) { return -1 })
var tests = [[-1, -1], [0, 1], [-1, 1], [0, 1], [1, 1], [1, -1]]
function toCell(point) {
return [
Math.floor(point[0] / radius) * radius,
Math.floor(point[1] / radius) * radius
]
}
function add(point) {
var cell = toCell(point)
findAHome(cell[0], cell[1], point, new Set())
}
add.toCell = toCell
var points = add.points = []
function findAHome(x, y, point, seen) {
seen = new Set(seen)
seen.add(bins.index(x, y))
// cell is empty
if (bins.get(x, y) === -1) {
var index = points.length
points.push(point)
bins.set(x, y, 1)
return true
}
var closest = tests.map(function(t, i) {
var dx = x + t[0] - point[0]
var dy = y + t[1] - point[1]
return [
dx*dx + dy*dy,
i
]
}).sort(function(a, b) {
return a[0] - b[0]
})
for (var i=0; i<tests.length; i++) {
var test = tests[closest[i][1]]
var tx = x + test[0]
var ty = y + test[1]
if (!seen.has(bins.index(tx, ty)) && findAHome(tx, ty, point, seen)) {
return true
}
}
}
function render(ctx) {
var perc = 360/points.length
var loc = 1
for (var x = 0; x < cx; x++) {
for (var y = 0; y < cy; y++) {
if (bins.get(x, y) !== -1) {
ctx.fillStyle = `hsl(${perc * loc}, 100%, 50%)`
ctx.fillRect(x*radius + 1, y*radius + 1, radius - 2, radius - 2)
loc++
}
}
}
}
add.bins = bins
add.render = render
return add
}
var width = 600
var height = 400
var radius = 10
var binner = createBinner(radius, width, height)
// binner([50, 50])
// binner([20, 50])
setInterval(function() {
binner([30, 60])
binner([40, 100])
ctx.dirty()
}, 100)
function point(ctx, vec, r) {
ctx.beginPath()
circle(ctx, vec[0], vec[1], r)
return ctx
}
function fill(ctx, color) {
ctx.fillStyle = color
ctx.fill()
}
var ctx = fc(function() {
ctx.clear()
center(ctx)
ctx.scale(1, -1)
ctx.translate(-400, -200)
ctx.beginPath()
grid(ctx, radius, 0, 0, width, height)
ctx.stroke()
ctx.fillStyle = 'orange'
binner.render(ctx)
var nets = surfaceNets(binner.bins, 0)
ctx.strokeStyle = "white"
nets.cells.forEach(function(cell) {
var start = nets.positions[cell[0]]
var end = nets.positions[cell[1]]
ctx.beginPath()
ctx.moveTo(start[0] * radius, start[1] * radius)
ctx.lineTo(end[0] * radius, end[1] * radius)
ctx.stroke()
})
})
setTimeout(function(){
;require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"fc":[function(require,module,exports){
;(function() {
var performance = window.performance || {}
var performanceNow =
performance.now ||
performance.now ||
performance.mozNow ||
performance.msNow ||
performance.oNow ||
performance.webkitNow ||
function(){ return (new Date()).getTime() }
performanceNow = performanceNow.bind(performance)
// Fullscreen canvas
function fc(fn, autorun, dimensions) {
document.body.style.margin = "0px";
document.body.style.padding = "0px";
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.style.position = 'absolute';
canvas.style.left = '0px';
canvas.style.top = '0px';
var ctx;
dimensions = dimensions || 2;
if (dimensions === 2) {
ctx = canvas.getContext('2d');
} else if (dimensions === 3) {
ctx = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
}
if (!ctx) {
return;
}
var last = performanceNow(), request;
function requestFrame() {
if (request === null) {
request = requestAnimationFrame(tick);
}
}
function tick() {
request = null;
var time = performanceNow();
var delta = time-last;
last = time;
ctx.reset();
dimensions === 2 && ctx.save();
fn && fn.call(ctx, delta);
dimensions === 2 && ctx.restore();
if (autorun) {
requestFrame();
}
}
if (dimensions === 2) {
ctx.reset = function fc_reset() {
canvas.width = 0;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};
ctx.clear = function fc_clear(color) {
var orig = ctx.fillStyle;
ctx.fillStyle = color || "#223";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = orig;
};
} else {
ctx.reset = function fc_reset() {
if (canvas.width !== window.innerWidth) {
canvas.width = window.innerWidth;
}
if (canvas.height !== window.innerHeight) {
canvas.height = window.innerHeight;
}
}
}
setTimeout(tick, 0);
ctx.dirty = function fc_dirty() {
last = performanceNow();
requestFrame();
};
ctx.stop = function fc_stop() {
autorun = false;
request && cancelAnimationFrame(request);
request = null;
};
ctx.start = function fc_start() {
autorun = true;
requestFrame();
};
(window.attachEvent || window.addEventListener)('resize', ctx.dirty);
// resize to fullscreen immediately
ctx.reset();
ctx.canvas = canvas;
return ctx;
};
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = fc;
}
if (typeof window !== 'undefined') {
window.fc = window.fc || fc;
}
})();
},{}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi91c3IvbGliL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvdG1wL2ZjMTE2MDE3LTE4MTg2LTFjNjBseW4vbm9kZV9tb2R1bGVzL2ZjL2ZjLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIjsoZnVuY3Rpb24oKSB7XG4gIHZhciBwZXJmb3JtYW5jZSA9IHdpbmRvdy5wZXJmb3JtYW5jZSB8fCB7fVxuICB2YXIgcGVyZm9ybWFuY2VOb3cgPVxuICAgIHBlcmZvcm1hbmNlLm5vdyAgICAgICAgfHxcbiAgICBwZXJmb3JtYW5jZS5ub3cgICAgICAgIHx8XG4gICAgcGVyZm9ybWFuY2UubW96Tm93ICAgICB8fFxuICAgIHBlcmZvcm1hbmNlLm1zTm93ICAgICAgfHxcbiAgICBwZXJmb3JtYW5jZS5vTm93ICAgICAgIHx8XG4gICAgcGVyZm9ybWFuY2Uud2Via2l0Tm93ICB8fFxuICAgIGZ1bmN0aW9uKCl7IHJldHVybiAobmV3IERhdGUoKSkuZ2V0VGltZSgpIH1cbiAgcGVyZm9ybWFuY2VOb3cgPSBwZXJmb3JtYW5jZU5vdy5iaW5kKHBlcmZvcm1hbmNlKVxuXG4gIC8vIEZ1bGxzY3JlZW4gY2FudmFzXG4gIGZ1bmN0aW9uIGZjKGZuLCBhdXRvcnVuLCBkaW1lbnNpb25zKSB7XG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS5tYXJnaW4gPSBcIjBweFwiO1xuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZyA9IFwiMHB4XCI7XG5cbiAgICB2YXIgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChjYW52YXMpO1xuICAgIGNhbnZhcy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgY2FudmFzLnN0eWxlLmxlZnQgPSAnMHB4JztcbiAgICBjYW52YXMuc3R5bGUudG9wID0gJzBweCc7XG5cbiAgICB2YXIgY3R4O1xuICAgIGRpbWVuc2lvbnMgPSBkaW1lbnNpb25zIHx8IDI7XG5cbiAgICBpZiAoZGltZW5zaW9ucyA9PT0gMikge1xuICAgICAgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgfSBlbHNlIGlmIChkaW1lbnNpb25zID09PSAzKSB7XG4gICAgICBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnd2ViZ2wnKSB8fCBjYW52YXMuZ2V0Q29udGV4dCgnZXhwZXJpbWVudGFsLXdlYmdsJyk7XG4gICAgfVxuXG4gICAgaWYgKCFjdHgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbGFzdCA9IHBlcmZvcm1hbmNlTm93KCksIHJlcXVlc3Q7XG5cbiAgICBmdW5jdGlvbiByZXF1ZXN0RnJhbWUoKSB7XG4gICAgICBpZiAocmVxdWVzdCA9PT0gbnVsbCkge1xuICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRpY2spO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRpY2soKSB7XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICAgIHZhciB0aW1lID0gcGVyZm9ybWFuY2VOb3coKTtcbiAgICAgIHZhciBkZWx0YSA9IHRpbWUtbGFzdDtcbiAgICAgIGxhc3QgPSB0aW1lO1xuXG4gICAgICBjdHgucmVzZXQoKTtcblxuICAgICAgZGltZW5zaW9ucyA9PT0gMiAmJiBjdHguc2F2ZSgpO1xuXG4gICAgICBmbiAmJiBmbi5jYWxsKGN0eCwgZGVsdGEpO1xuXG4gICAgICBkaW1lbnNpb25zID09PSAyICYmIGN0eC5yZXN0b3JlKCk7XG4gICAgICBpZiAoYXV0b3J1bikge1xuICAgICAgICByZXF1ZXN0RnJhbWUoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZGltZW5zaW9ucyA9PT0gMikge1xuICAgICAgY3R4LnJlc2V0ID0gZnVuY3Rpb24gZmNfcmVzZXQoKSB7XG4gICAgICAgIGNhbnZhcy53aWR0aCA9IDA7XG4gICAgICAgIGNhbnZhcy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuICAgICAgfTtcblxuICAgICAgY3R4LmNsZWFyID0gZnVuY3Rpb24gZmNfY2xlYXIoY29sb3IpIHtcbiAgICAgICAgdmFyIG9yaWcgPSBjdHguZmlsbFN0eWxlO1xuICAgICAgICBjdHguZmlsbFN0eWxlID0gY29sb3IgfHwgXCIjMjIzXCI7XG4gICAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuICAgICAgICBjdHguZmlsbFN0eWxlID0gb3JpZztcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGN0eC5yZXNldCA9IGZ1bmN0aW9uIGZjX3Jlc2V0KCkge1xuICAgICAgICBpZiAoY2FudmFzLndpZHRoICE9PSB3aW5kb3cuaW5uZXJXaWR0aCkge1xuICAgICAgICAgIGNhbnZhcy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNhbnZhcy5oZWlnaHQgIT09IHdpbmRvdy5pbm5lckhlaWdodCkge1xuICAgICAgICAgIGNhbnZhcy5oZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KHRpY2ssIDApO1xuXG4gICAgY3R4LmRpcnR5ID0gZnVuY3Rpb24gZmNfZGlydHkoKSB7XG4gICAgICBsYXN0ID0gcGVyZm9ybWFuY2VOb3coKTtcbiAgICAgIHJlcXVlc3RGcmFtZSgpO1xuICAgIH07XG5cbiAgICBjdHguc3RvcCA9IGZ1bmN0aW9uIGZjX3N0b3AoKSB7XG4gICAgICBhdXRvcnVuID0gZmFsc2U7XG4gICAgICByZXF1ZXN0ICYmIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHJlcXVlc3QpO1xuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfTtcblxuICAgIGN0eC5zdGFydCA9IGZ1bmN0aW9uIGZjX3N0YXJ0KCkge1xuICAgICAgYXV0b3J1biA9IHRydWU7XG4gICAgICByZXF1ZXN0RnJhbWUoKTtcbiAgICB9O1xuXG4gICAgKHdpbmRvdy5hdHRhY2hFdmVudCB8fCB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcikoJ3Jlc2l6ZScsIGN0eC5kaXJ0eSk7XG5cbiAgICAvLyByZXNpemUgdG8gZnVsbHNjcmVlbiBpbW1lZGlhdGVseVxuICAgIGN0eC5yZXNldCgpO1xuXG4gICAgY3R4LmNhbnZhcyA9IGNhbnZhcztcbiAgICByZXR1cm4gY3R4O1xuICB9O1xuXG4gIGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBmYztcbiAgfVxuXG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgIHdpbmRvdy5mYyA9IHdpbmRvdy5mYyB8fCBmYztcbiAgfVxufSkoKTtcbiJdfQ==
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"ctx-translate-center":[function(require,module,exports){
module.exports = center;
function center(ctx) {
var w = (ctx.canvas.width/2)|0;
var h = (ctx.canvas.height/2)|0;
ctx.translate(w, h);
}
},{}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImN0eC10cmFuc2xhdGUtY2VudGVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIm1vZHVsZS5leHBvcnRzID0gY2VudGVyO1xuXG5mdW5jdGlvbiBjZW50ZXIoY3R4KSB7XG4gIHZhciB3ID0gKGN0eC5jYW52YXMud2lkdGgvMil8MDtcbiAgdmFyIGggPSAoY3R4LmNhbnZhcy5oZWlnaHQvMil8MDtcblxuICBjdHgudHJhbnNsYXRlKHcsIGgpO1xufVxuIl19
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"ctx-render-grid-lines":[function(require,module,exports){
module.exports = gridlines;
var min = Math.min;
var max = Math.max;
var abs = Math.abs;
function gridlines(ctx, spacing, minx, miny, maxx, maxy) {
var lx = min(minx, maxx);
var ly = min(miny, maxy);
var ux = max(minx, maxx);
var uy = max(miny, maxy);
spacing = abs(spacing|0);
if (!spacing) {
return;
}
for (var x = lx; x <= ux; x += spacing) {
ctx.moveTo(x, ly);
ctx.lineTo(x, uy);
}
for (var y = ly; y <= uy; y += spacing) {
ctx.moveTo(lx, y);
ctx.lineTo(ux, y);
}
}
},{}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImN0eC1yZW5kZXItZ3JpZC1saW5lcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwibW9kdWxlLmV4cG9ydHMgPSBncmlkbGluZXM7XG5cbnZhciBtaW4gPSBNYXRoLm1pbjtcbnZhciBtYXggPSBNYXRoLm1heDtcbnZhciBhYnMgPSBNYXRoLmFicztcblxuZnVuY3Rpb24gZ3JpZGxpbmVzKGN0eCwgc3BhY2luZywgbWlueCwgbWlueSwgbWF4eCwgbWF4eSkge1xuICB2YXIgbHggPSBtaW4obWlueCwgbWF4eCk7XG4gIHZhciBseSA9IG1pbihtaW55LCBtYXh5KTtcbiAgdmFyIHV4ID0gbWF4KG1pbngsIG1heHgpO1xuICB2YXIgdXkgPSBtYXgobWlueSwgbWF4eSk7XG5cbiAgc3BhY2luZyA9IGFicyhzcGFjaW5nfDApO1xuXG4gIGlmICghc3BhY2luZykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAodmFyIHggPSBseDsgeCA8PSB1eDsgeCArPSBzcGFjaW5nKSB7XG4gICAgY3R4Lm1vdmVUbyh4LCBseSk7XG4gICAgY3R4LmxpbmVUbyh4LCB1eSk7XG4gIH1cblxuICBmb3IgKHZhciB5ID0gbHk7IHkgPD0gdXk7IHkgKz0gc3BhY2luZykge1xuICAgIGN0eC5tb3ZlVG8obHgsIHkpO1xuICAgIGN0eC5saW5lVG8odXgsIHkpO1xuICB9XG59XG4iXX0=
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"ctx-circle":[function(require,module,exports){
var TAU = Math.PI*2;
module.exports = circle;
function circle(ctx, x, y, r, reverse) {
ctx.moveTo(x+r, y);
ctx.arc(x, y, r, 0, TAU, !!reverse);
}
},{}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImN0eC1jaXJjbGUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwidmFyIFRBVSA9IE1hdGguUEkqMjtcblxubW9kdWxlLmV4cG9ydHMgPSBjaXJjbGU7XG5cbmZ1bmN0aW9uIGNpcmNsZShjdHgsIHgsIHksIHIsIHJldmVyc2UpIHtcbiAgY3R4Lm1vdmVUbyh4K3IsIHkpO1xuICBjdHguYXJjKHgsIHksIHIsIDAsIFRBVSwgISFyZXZlcnNlKTtcbn1cbiJdfQ==
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict"
function iota(n) {
var result = new Array(n)
for(var i=0; i<n; ++i) {
result[i] = i
}
return result
}
module.exports = iota
},{}],2:[function(require,module,exports){
/**
* Determine if an object is Buffer
*
* Author: Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* License: MIT
*
* `npm install is-buffer`
*/
module.exports = function (obj) {
return !!(obj != null &&
(obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
(obj.constructor &&
typeof obj.constructor.isBuffer === 'function' &&
obj.constructor.isBuffer(obj))
))
}
},{}],"ndarray":[function(require,module,exports){
var iota = require("iota-array")
var isBuffer = require("is-buffer")
var hasTypedArrays = ((typeof Float64Array) !== "undefined")
function compare1st(a, b) {
return a[0] - b[0]
}
function order() {
var stride = this.stride
var terms = new Array(stride.length)
var i
for(i=0; i<terms.length; ++i) {
terms[i] = [Math.abs(stride[i]), i]
}
terms.sort(compare1st)
var result = new Array(terms.length)
for(i=0; i<result.length; ++i) {
result[i] = terms[i][1]
}
return result
}
function compileConstructor(dtype, dimension) {
var className = ["View", dimension, "d", dtype].join("")
if(dimension < 0) {
className = "View_Nil" + dtype
}
var useGetters = (dtype === "generic")
if(dimension === -1) {
//Special case for trivial arrays
var code =
"function "+className+"(a){this.data=a;};\
var proto="+className+".prototype;\
proto.dtype='"+dtype+"';\
proto.index=function(){return -1};\
proto.size=0;\
proto.dimension=-1;\
proto.shape=proto.stride=proto.order=[];\
proto.lo=proto.hi=proto.transpose=proto.step=\
function(){return new "+className+"(this.data);};\
proto.get=proto.set=function(){};\
proto.pick=function(){return null};\
return function construct_"+className+"(a){return new "+className+"(a);}"
var procedure = new Function(code)
return procedure()
} else if(dimension === 0) {
//Special case for 0d arrays
var code =
"function "+className+"(a,d) {\
this.data = a;\
this.offset = d\
};\
var proto="+className+".prototype;\
proto.dtype='"+dtype+"';\
proto.index=function(){return this.offset};\
proto.dimension=0;\
proto.size=1;\
proto.shape=\
proto.stride=\
proto.order=[];\
proto.lo=\
proto.hi=\
proto.transpose=\
proto.step=function "+className+"_copy() {\
return new "+className+"(this.data,this.offset)\
};\
proto.pick=function "+className+"_pick(){\
return TrivialArray(this.data);\
};\
proto.valueOf=proto.get=function "+className+"_get(){\
return "+(useGetters ? "this.data.get(this.offset)" : "this.data[this.offset]")+
"};\
proto.set=function "+className+"_set(v){\
return "+(useGetters ? "this.data.set(this.offset,v)" : "this.data[this.offset]=v")+"\
};\
return function construct_"+className+"(a,b,c,d){return new "+className+"(a,d)}"
var procedure = new Function("TrivialArray", code)
return procedure(CACHED_CONSTRUCTORS[dtype][0])
}
var code = ["'use strict'"]
//Create constructor for view
var indices = iota(dimension)
var args = indices.map(function(i) { return "i"+i })
var index_str = "this.offset+" + indices.map(function(i) {
return "this.stride[" + i + "]*i" + i
}).join("+")
var shapeArg = indices.map(function(i) {
return "b"+i
}).join(",")
var strideArg = indices.map(function(i) {
return "c"+i
}).join(",")
code.push(
"function "+className+"(a," + shapeArg + "," + strideArg + ",d){this.data=a",
"this.shape=[" + shapeArg + "]",
"this.stride=[" + strideArg + "]",
"this.offset=d|0}",
"var proto="+className+".prototype",
"proto.dtype='"+dtype+"'",
"proto.dimension="+dimension)
//view.size:
code.push("Object.defineProperty(proto,'size',{get:function "+className+"_size(){\
return "+indices.map(function(i) { return "this.shape["+i+"]" }).join("*"),
"}})")
//view.order:
if(dimension === 1) {
code.push("proto.order=[0]")
} else {
code.push("Object.defineProperty(proto,'order',{get:")
if(dimension < 4) {
code.push("function "+className+"_order(){")
if(dimension === 2) {
code.push("return (Math.abs(this.stride[0])>Math.abs(this.stride[1]))?[1,0]:[0,1]}})")
} else if(dimension === 3) {
code.push(
"var s0=Math.abs(this.stride[0]),s1=Math.abs(this.stride[1]),s2=Math.abs(this.stride[2]);\
if(s0>s1){\
if(s1>s2){\
return [2,1,0];\
}else if(s0>s2){\
return [1,2,0];\
}else{\
return [1,0,2];\
}\
}else if(s0>s2){\
return [2,0,1];\
}else if(s2>s1){\
return [0,1,2];\
}else{\
return [0,2,1];\
}}})")
}
} else {
code.push("ORDER})")
}
}
//view.set(i0, ..., v):
code.push(
"proto.set=function "+className+"_set("+args.join(",")+",v){")
if(useGetters) {
code.push("return this.data.set("+index_str+",v)}")
} else {
code.push("return this.data["+index_str+"]=v}")
}
//view.get(i0, ...):
code.push("proto.get=function "+className+"_get("+args.join(",")+"){")
if(useGetters) {
code.push("return this.data.get("+index_str+")}")
} else {
code.push("return this.data["+index_str+"]}")
}
//view.index:
code.push(
"proto.index=function "+className+"_index(", args.join(), "){return "+index_str+"}")
//view.hi():
code.push("proto.hi=function "+className+"_hi("+args.join(",")+"){return new "+className+"(this.data,"+
indices.map(function(i) {
return ["(typeof i",i,"!=='number'||i",i,"<0)?this.shape[", i, "]:i", i,"|0"].join("")
}).join(",")+","+
indices.map(function(i) {
return "this.stride["+i + "]"
}).join(",")+",this.offset)}")
//view.lo():
var a_vars = indices.map(function(i) { return "a"+i+"=this.shape["+i+"]" })
var c_vars = indices.map(function(i) { return "c"+i+"=this.stride["+i+"]" })
code.push("proto.lo=function "+className+"_lo("+args.join(",")+"){var b=this.offset,d=0,"+a_vars.join(",")+","+c_vars.join(","))
for(var i=0; i<dimension; ++i) {
code.push(
"if(typeof i"+i+"==='number'&&i"+i+">=0){\
d=i"+i+"|0;\
b+=c"+i+"*d;\
a"+i+"-=d}")
}
code.push("return new "+className+"(this.data,"+
indices.map(function(i) {
return "a"+i
}).join(",")+","+
indices.map(function(i) {
return "c"+i
}).join(",")+",b)}")
//view.step():
code.push("proto.step=function "+className+"_step("+args.join(",")+"){var "+
indices.map(function(i) {
return "a"+i+"=this.shape["+i+"]"
}).join(",")+","+
indices.map(function(i) {
return "b"+i+"=this.stride["+i+"]"
}).join(",")+",c=this.offset,d=0,ceil=Math.ceil")
for(var i=0; i<dimension; ++i) {
code.push(
"if(typeof i"+i+"==='number'){\
d=i"+i+"|0;\
if(d<0){\
c+=b"+i+"*(a"+i+"-1);\
a"+i+"=ceil(-a"+i+"/d)\
}else{\
a"+i+"=ceil(a"+i+"/d)\
}\
b"+i+"*=d\
}")
}
code.push("return new "+className+"(this.data,"+
indices.map(function(i) {
return "a" + i
}).join(",")+","+
indices.map(function(i) {
return "b" + i
}).join(",")+",c)}")
//view.transpose():
var tShape = new Array(dimension)
var tStride = new Array(dimension)
for(var i=0; i<dimension; ++i) {
tShape[i] = "a[i"+i+"]"
tStride[i] = "b[i"+i+"]"
}
code.push("proto.transpose=function "+className+"_transpose("+args+"){"+
args.map(function(n,idx) { return n + "=(" + n + "===undefined?" + idx + ":" + n + "|0)"}).join(";"),
"var a=this.shape,b=this.stride;return new "+className+"(this.data,"+tShape.join(",")+","+tStride.join(",")+",this.offset)}")
//view.pick():
code.push("proto.pick=function "+className+"_pick("+args+"){var a=[],b=[],c=this.offset")
for(var i=0; i<dimension; ++i) {
code.push("if(typeof i"+i+"==='number'&&i"+i+">=0){c=(c+this.stride["+i+"]*i"+i+")|0}else{a.push(this.shape["+i+"]);b.push(this.stride["+i+"])}")
}
code.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}")
//Add return statement
code.push("return function construct_"+className+"(data,shape,stride,offset){return new "+className+"(data,"+
indices.map(function(i) {
return "shape["+i+"]"
}).join(",")+","+
indices.map(function(i) {
return "stride["+i+"]"
}).join(",")+",offset)}")
//Compile procedure
var procedure = new Function("CTOR_LIST", "ORDER", code.join("\n"))
return procedure(CACHED_CONSTRUCTORS[dtype], order)
}
function arrayDType(data) {
if(isBuffer(data)) {
return "buffer"
}
if(hasTypedArrays) {
switch(Object.prototype.toString.call(data)) {
case "[object Float64Array]":
return "float64"
case "[object Float32Array]":
return "float32"
case "[object Int8Array]":
return "int8"
case "[object Int16Array]":
return "int16"
case "[object Int32Array]":
return "int32"
case "[object Uint8Array]":
return "uint8"
case "[object Uint16Array]":
return "uint16"
case "[object Uint32Array]":
return "uint32"
case "[object Uint8ClampedArray]":
return "uint8_clamped"
}
}
if(Array.isArray(data)) {
return "array"
}
return "generic"
}
var CACHED_CONSTRUCTORS = {
"float32":[],
"float64":[],
"int8":[],
"int16":[],
"int32":[],
"uint8":[],
"uint16":[],
"uint32":[],
"array":[],
"uint8_clamped":[],
"buffer":[],
"generic":[]
}
;(function() {
for(var id in CACHED_CONSTRUCTORS) {
CACHED_CONSTRUCTORS[id].push(compileConstructor(id, -1))
}
});
function wrappedNDArrayCtor(data, shape, stride, offset) {
if(data === undefined) {
var ctor = CACHED_CONSTRUCTORS.array[0]
return ctor([])
} else if(typeof data === "number") {
data = [data]
}
if(shape === undefined) {
shape = [ data.length ]
}
var d = shape.length
if(stride === undefined) {
stride = new Array(d)
for(var i=d-1, sz=1; i>=0; --i) {
stride[i] = sz
sz *= shape[i]
}
}
if(offset === undefined) {
offset = 0
for(var i=0; i<d; ++i) {
if(stride[i] < 0) {
offset -= (shape[i]-1)*stride[i]
}
}
}
var dtype = arrayDType(data)
var ctor_list = CACHED_CONSTRUCTORS[dtype]
while(ctor_list.length <= d+1) {
ctor_list.push(compileConstructor(dtype, ctor_list.length-1))
}
var ctor = ctor_list[d+1]
return ctor(data, shape, stride, offset)
}
module.exports = wrappedNDArrayCtor
},{"iota-array":1,"is-buffer":2}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIm5vZGVfbW9kdWxlcy9pb3RhLWFycmF5L2lvdGEuanMiLCJub2RlX21vZHVsZXMvaXMtYnVmZmVyL2luZGV4LmpzIiwibmRhcnJheS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIlwidXNlIHN0cmljdFwiXG5cbmZ1bmN0aW9uIGlvdGEobikge1xuICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KG4pXG4gIGZvcih2YXIgaT0wOyBpPG47ICsraSkge1xuICAgIHJlc3VsdFtpXSA9IGlcbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW90YSIsIi8qKlxuICogRGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBpcyBCdWZmZXJcbiAqXG4gKiBBdXRob3I6ICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIExpY2Vuc2U6ICBNSVRcbiAqXG4gKiBgbnBtIGluc3RhbGwgaXMtYnVmZmVyYFxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gISEob2JqICE9IG51bGwgJiZcbiAgICAob2JqLl9pc0J1ZmZlciB8fCAvLyBGb3IgU2FmYXJpIDUtNyAobWlzc2luZyBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yKVxuICAgICAgKG9iai5jb25zdHJ1Y3RvciAmJlxuICAgICAgdHlwZW9mIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyKG9iaikpXG4gICAgKSlcbn1cbiIsInZhciBpb3RhID0gcmVxdWlyZShcImlvdGEtYXJyYXlcIilcbnZhciBpc0J1ZmZlciA9IHJlcXVpcmUoXCJpcy1idWZmZXJcIilcblxudmFyIGhhc1R5cGVkQXJyYXlzICA9ICgodHlwZW9mIEZsb2F0NjRBcnJheSkgIT09IFwidW5kZWZpbmVkXCIpXG5cbmZ1bmN0aW9uIGNvbXBhcmUxc3QoYSwgYikge1xuICByZXR1cm4gYVswXSAtIGJbMF1cbn1cblxuZnVuY3Rpb24gb3JkZXIoKSB7XG4gIHZhciBzdHJpZGUgPSB0aGlzLnN0cmlkZVxuICB2YXIgdGVybXMgPSBuZXcgQXJyYXkoc3RyaWRlLmxlbmd0aClcbiAgdmFyIGlcbiAgZm9yKGk9MDsgaTx0ZXJtcy5sZW5ndGg7ICsraSkge1xuICAgIHRlcm1zW2ldID0gW01hdGguYWJzKHN0cmlkZVtpXSksIGldXG4gIH1cbiAgdGVybXMuc29ydChjb21wYXJlMXN0KVxuICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KHRlcm1zLmxlbmd0aClcbiAgZm9yKGk9MDsgaTxyZXN1bHQubGVuZ3RoOyArK2kpIHtcbiAgICByZXN1bHRbaV0gPSB0ZXJtc1tpXVsxXVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxuZnVuY3Rpb24gY29tcGlsZUNvbnN0cnVjdG9yKGR0eXBlLCBkaW1lbnNpb24pIHtcbiAgdmFyIGNsYXNzTmFtZSA9IFtcIlZpZXdcIiwgZGltZW5zaW9uLCBcImRcIiwgZHR5cGVdLmpvaW4oXCJcIilcbiAgaWYoZGltZW5zaW9uIDwgMCkge1xuICAgIGNsYXNzTmFtZSA9IFwiVmlld19OaWxcIiArIGR0eXBlXG4gIH1cbiAgdmFyIHVzZUdldHRlcnMgPSAoZHR5cGUgPT09IFwiZ2VuZXJpY1wiKVxuXG4gIGlmKGRpbWVuc2lvbiA9PT0gLTEpIHtcbiAgICAvL1NwZWNpYWwgY2FzZSBmb3IgdHJpdmlhbCBhcnJheXNcbiAgICB2YXIgY29kZSA9XG4gICAgICBcImZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIihhKXt0aGlzLmRhdGE9YTt9O1xcXG52YXIgcHJvdG89XCIrY2xhc3NOYW1lK1wiLnByb3RvdHlwZTtcXFxucHJvdG8uZHR5cGU9J1wiK2R0eXBlK1wiJztcXFxucHJvdG8uaW5kZXg9ZnVuY3Rpb24oKXtyZXR1cm4gLTF9O1xcXG5wcm90by5zaXplPTA7XFxcbnByb3RvLmRpbWVuc2lvbj0tMTtcXFxucHJvdG8uc2hhcGU9cHJvdG8uc3RyaWRlPXByb3RvLm9yZGVyPVtdO1xcXG5wcm90by5sbz1wcm90by5oaT1wcm90by50cmFuc3Bvc2U9cHJvdG8uc3RlcD1cXFxuZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIih0aGlzLmRhdGEpO307XFxcbnByb3RvLmdldD1wcm90by5zZXQ9ZnVuY3Rpb24oKXt9O1xcXG5wcm90by5waWNrPWZ1bmN0aW9uKCl7cmV0dXJuIG51bGx9O1xcXG5yZXR1cm4gZnVuY3Rpb24gY29uc3RydWN0X1wiK2NsYXNzTmFtZStcIihhKXtyZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIihhKTt9XCJcbiAgICB2YXIgcHJvY2VkdXJlID0gbmV3IEZ1bmN0aW9uKGNvZGUpXG4gICAgcmV0dXJuIHByb2NlZHVyZSgpXG4gIH0gZWxzZSBpZihkaW1lbnNpb24gPT09IDApIHtcbiAgICAvL1NwZWNpYWwgY2FzZSBmb3IgMGQgYXJyYXlzXG4gICAgdmFyIGNvZGUgPVxuICAgICAgXCJmdW5jdGlvbiBcIitjbGFzc05hbWUrXCIoYSxkKSB7XFxcbnRoaXMuZGF0YSA9IGE7XFxcbnRoaXMub2Zmc2V0ID0gZFxcXG59O1xcXG52YXIgcHJvdG89XCIrY2xhc3NOYW1lK1wiLnByb3RvdHlwZTtcXFxucHJvdG8uZHR5cGU9J1wiK2R0eXBlK1wiJztcXFxucHJvdG8uaW5kZXg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5vZmZzZXR9O1xcXG5wcm90by5kaW1lbnNpb249MDtcXFxucHJvdG8uc2l6ZT0xO1xcXG5wcm90by5zaGFwZT1cXFxucHJvdG8uc3RyaWRlPVxcXG5wcm90by5vcmRlcj1bXTtcXFxucHJvdG8ubG89XFxcbnByb3RvLmhpPVxcXG5wcm90by50cmFuc3Bvc2U9XFxcbnByb3RvLnN0ZXA9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX2NvcHkoKSB7XFxcbnJldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKHRoaXMuZGF0YSx0aGlzLm9mZnNldClcXFxufTtcXFxucHJvdG8ucGljaz1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfcGljaygpe1xcXG5yZXR1cm4gVHJpdmlhbEFycmF5KHRoaXMuZGF0YSk7XFxcbn07XFxcbnByb3RvLnZhbHVlT2Y9cHJvdG8uZ2V0PWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9nZXQoKXtcXFxucmV0dXJuIFwiKyh1c2VHZXR0ZXJzID8gXCJ0aGlzLmRhdGEuZ2V0KHRoaXMub2Zmc2V0KVwiIDogXCJ0aGlzLmRhdGFbdGhpcy5vZmZzZXRdXCIpK1xuXCJ9O1xcXG5wcm90by5zZXQ9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3NldCh2KXtcXFxucmV0dXJuIFwiKyh1c2VHZXR0ZXJzID8gXCJ0aGlzLmRhdGEuc2V0KHRoaXMub2Zmc2V0LHYpXCIgOiBcInRoaXMuZGF0YVt0aGlzLm9mZnNldF09dlwiKStcIlxcXG59O1xcXG5yZXR1cm4gZnVuY3Rpb24gY29uc3RydWN0X1wiK2NsYXNzTmFtZStcIihhLGIsYyxkKXtyZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIihhLGQpfVwiXG4gICAgdmFyIHByb2NlZHVyZSA9IG5ldyBGdW5jdGlvbihcIlRyaXZpYWxBcnJheVwiLCBjb2RlKVxuICAgIHJldHVybiBwcm9jZWR1cmUoQ0FDSEVEX0NPTlNUUlVDVE9SU1tkdHlwZV1bMF0pXG4gIH1cblxuICB2YXIgY29kZSA9IFtcIid1c2Ugc3RyaWN0J1wiXVxuXG4gIC8vQ3JlYXRlIGNvbnN0cnVjdG9yIGZvciB2aWV3XG4gIHZhciBpbmRpY2VzID0gaW90YShkaW1lbnNpb24pXG4gIHZhciBhcmdzID0gaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkgeyByZXR1cm4gXCJpXCIraSB9KVxuICB2YXIgaW5kZXhfc3RyID0gXCJ0aGlzLm9mZnNldCtcIiArIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgICAgcmV0dXJuIFwidGhpcy5zdHJpZGVbXCIgKyBpICsgXCJdKmlcIiArIGlcbiAgICAgIH0pLmpvaW4oXCIrXCIpXG4gIHZhciBzaGFwZUFyZyA9IGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImJcIitpXG4gICAgfSkuam9pbihcIixcIilcbiAgdmFyIHN0cmlkZUFyZyA9IGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImNcIitpXG4gICAgfSkuam9pbihcIixcIilcbiAgY29kZS5wdXNoKFxuICAgIFwiZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiKGEsXCIgKyBzaGFwZUFyZyArIFwiLFwiICsgc3RyaWRlQXJnICsgXCIsZCl7dGhpcy5kYXRhPWFcIixcbiAgICAgIFwidGhpcy5zaGFwZT1bXCIgKyBzaGFwZUFyZyArIFwiXVwiLFxuICAgICAgXCJ0aGlzLnN0cmlkZT1bXCIgKyBzdHJpZGVBcmcgKyBcIl1cIixcbiAgICAgIFwidGhpcy5vZmZzZXQ9ZHwwfVwiLFxuICAgIFwidmFyIHByb3RvPVwiK2NsYXNzTmFtZStcIi5wcm90b3R5cGVcIixcbiAgICBcInByb3RvLmR0eXBlPSdcIitkdHlwZStcIidcIixcbiAgICBcInByb3RvLmRpbWVuc2lvbj1cIitkaW1lbnNpb24pXG5cbiAgLy92aWV3LnNpemU6XG4gIGNvZGUucHVzaChcIk9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm90bywnc2l6ZScse2dldDpmdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfc2l6ZSgpe1xcXG5yZXR1cm4gXCIraW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkgeyByZXR1cm4gXCJ0aGlzLnNoYXBlW1wiK2krXCJdXCIgfSkuam9pbihcIipcIiksXG5cIn19KVwiKVxuXG4gIC8vdmlldy5vcmRlcjpcbiAgaWYoZGltZW5zaW9uID09PSAxKSB7XG4gICAgY29kZS5wdXNoKFwicHJvdG8ub3JkZXI9WzBdXCIpXG4gIH0gZWxzZSB7XG4gICAgY29kZS5wdXNoKFwiT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3RvLCdvcmRlcicse2dldDpcIilcbiAgICBpZihkaW1lbnNpb24gPCA0KSB7XG4gICAgICBjb2RlLnB1c2goXCJmdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfb3JkZXIoKXtcIilcbiAgICAgIGlmKGRpbWVuc2lvbiA9PT0gMikge1xuICAgICAgICBjb2RlLnB1c2goXCJyZXR1cm4gKE1hdGguYWJzKHRoaXMuc3RyaWRlWzBdKT5NYXRoLmFicyh0aGlzLnN0cmlkZVsxXSkpP1sxLDBdOlswLDFdfX0pXCIpXG4gICAgICB9IGVsc2UgaWYoZGltZW5zaW9uID09PSAzKSB7XG4gICAgICAgIGNvZGUucHVzaChcblwidmFyIHMwPU1hdGguYWJzKHRoaXMuc3RyaWRlWzBdKSxzMT1NYXRoLmFicyh0aGlzLnN0cmlkZVsxXSksczI9TWF0aC5hYnModGhpcy5zdHJpZGVbMl0pO1xcXG5pZihzMD5zMSl7XFxcbmlmKHMxPnMyKXtcXFxucmV0dXJuIFsyLDEsMF07XFxcbn1lbHNlIGlmKHMwPnMyKXtcXFxucmV0dXJuIFsxLDIsMF07XFxcbn1lbHNle1xcXG5yZXR1cm4gWzEsMCwyXTtcXFxufVxcXG59ZWxzZSBpZihzMD5zMil7XFxcbnJldHVybiBbMiwwLDFdO1xcXG59ZWxzZSBpZihzMj5zMSl7XFxcbnJldHVybiBbMCwxLDJdO1xcXG59ZWxzZXtcXFxucmV0dXJuIFswLDIsMV07XFxcbn19fSlcIilcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29kZS5wdXNoKFwiT1JERVJ9KVwiKVxuICAgIH1cbiAgfVxuXG4gIC8vdmlldy5zZXQoaTAsIC4uLiwgdik6XG4gIGNvZGUucHVzaChcblwicHJvdG8uc2V0PWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9zZXQoXCIrYXJncy5qb2luKFwiLFwiKStcIix2KXtcIilcbiAgaWYodXNlR2V0dGVycykge1xuICAgIGNvZGUucHVzaChcInJldHVybiB0aGlzLmRhdGEuc2V0KFwiK2luZGV4X3N0citcIix2KX1cIilcbiAgfSBlbHNlIHtcbiAgICBjb2RlLnB1c2goXCJyZXR1cm4gdGhpcy5kYXRhW1wiK2luZGV4X3N0citcIl09dn1cIilcbiAgfVxuXG4gIC8vdmlldy5nZXQoaTAsIC4uLik6XG4gIGNvZGUucHVzaChcInByb3RvLmdldD1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfZ2V0KFwiK2FyZ3Muam9pbihcIixcIikrXCIpe1wiKVxuICBpZih1c2VHZXR0ZXJzKSB7XG4gICAgY29kZS5wdXNoKFwicmV0dXJuIHRoaXMuZGF0YS5nZXQoXCIraW5kZXhfc3RyK1wiKX1cIilcbiAgfSBlbHNlIHtcbiAgICBjb2RlLnB1c2goXCJyZXR1cm4gdGhpcy5kYXRhW1wiK2luZGV4X3N0citcIl19XCIpXG4gIH1cblxuICAvL3ZpZXcuaW5kZXg6XG4gIGNvZGUucHVzaChcbiAgICBcInByb3RvLmluZGV4PWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9pbmRleChcIiwgYXJncy5qb2luKCksIFwiKXtyZXR1cm4gXCIraW5kZXhfc3RyK1wifVwiKVxuXG4gIC8vdmlldy5oaSgpOlxuICBjb2RlLnB1c2goXCJwcm90by5oaT1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfaGkoXCIrYXJncy5qb2luKFwiLFwiKStcIil7cmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIodGhpcy5kYXRhLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBbXCIodHlwZW9mIGlcIixpLFwiIT09J251bWJlcid8fGlcIixpLFwiPDApP3RoaXMuc2hhcGVbXCIsIGksIFwiXTppXCIsIGksXCJ8MFwiXS5qb2luKFwiXCIpXG4gICAgfSkuam9pbihcIixcIikrXCIsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwidGhpcy5zdHJpZGVbXCIraSArIFwiXVwiXG4gICAgfSkuam9pbihcIixcIikrXCIsdGhpcy5vZmZzZXQpfVwiKVxuXG4gIC8vdmlldy5sbygpOlxuICB2YXIgYV92YXJzID0gaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkgeyByZXR1cm4gXCJhXCIraStcIj10aGlzLnNoYXBlW1wiK2krXCJdXCIgfSlcbiAgdmFyIGNfdmFycyA9IGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIFwiY1wiK2krXCI9dGhpcy5zdHJpZGVbXCIraStcIl1cIiB9KVxuICBjb2RlLnB1c2goXCJwcm90by5sbz1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfbG8oXCIrYXJncy5qb2luKFwiLFwiKStcIil7dmFyIGI9dGhpcy5vZmZzZXQsZD0wLFwiK2FfdmFycy5qb2luKFwiLFwiKStcIixcIitjX3ZhcnMuam9pbihcIixcIikpXG4gIGZvcih2YXIgaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7XG4gICAgY29kZS5wdXNoKFxuXCJpZih0eXBlb2YgaVwiK2krXCI9PT0nbnVtYmVyJyYmaVwiK2krXCI+PTApe1xcXG5kPWlcIitpK1wifDA7XFxcbmIrPWNcIitpK1wiKmQ7XFxcbmFcIitpK1wiLT1kfVwiKVxuICB9XG4gIGNvZGUucHVzaChcInJldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKHRoaXMuZGF0YSxcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJhXCIraVxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImNcIitpXG4gICAgfSkuam9pbihcIixcIikrXCIsYil9XCIpXG5cbiAgLy92aWV3LnN0ZXAoKTpcbiAgY29kZS5wdXNoKFwicHJvdG8uc3RlcD1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfc3RlcChcIithcmdzLmpvaW4oXCIsXCIpK1wiKXt2YXIgXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwiYVwiK2krXCI9dGhpcy5zaGFwZVtcIitpK1wiXVwiXG4gICAgfSkuam9pbihcIixcIikrXCIsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwiYlwiK2krXCI9dGhpcy5zdHJpZGVbXCIraStcIl1cIlxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLGM9dGhpcy5vZmZzZXQsZD0wLGNlaWw9TWF0aC5jZWlsXCIpXG4gIGZvcih2YXIgaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7XG4gICAgY29kZS5wdXNoKFxuXCJpZih0eXBlb2YgaVwiK2krXCI9PT0nbnVtYmVyJyl7XFxcbmQ9aVwiK2krXCJ8MDtcXFxuaWYoZDwwKXtcXFxuYys9YlwiK2krXCIqKGFcIitpK1wiLTEpO1xcXG5hXCIraStcIj1jZWlsKC1hXCIraStcIi9kKVxcXG59ZWxzZXtcXFxuYVwiK2krXCI9Y2VpbChhXCIraStcIi9kKVxcXG59XFxcbmJcIitpK1wiKj1kXFxcbn1cIilcbiAgfVxuICBjb2RlLnB1c2goXCJyZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIih0aGlzLmRhdGEsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwiYVwiICsgaVxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImJcIiArIGlcbiAgICB9KS5qb2luKFwiLFwiKStcIixjKX1cIilcblxuICAvL3ZpZXcudHJhbnNwb3NlKCk6XG4gIHZhciB0U2hhcGUgPSBuZXcgQXJyYXkoZGltZW5zaW9uKVxuICB2YXIgdFN0cmlkZSA9IG5ldyBBcnJheShkaW1lbnNpb24pXG4gIGZvcih2YXIgaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7XG4gICAgdFNoYXBlW2ldID0gXCJhW2lcIitpK1wiXVwiXG4gICAgdFN0cmlkZVtpXSA9IFwiYltpXCIraStcIl1cIlxuICB9XG4gIGNvZGUucHVzaChcInByb3RvLnRyYW5zcG9zZT1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfdHJhbnNwb3NlKFwiK2FyZ3MrXCIpe1wiK1xuICAgIGFyZ3MubWFwKGZ1bmN0aW9uKG4saWR4KSB7IHJldHVybiBuICsgXCI9KFwiICsgbiArIFwiPT09dW5kZWZpbmVkP1wiICsgaWR4ICsgXCI6XCIgKyBuICsgXCJ8MClcIn0pLmpvaW4oXCI7XCIpLFxuICAgIFwidmFyIGE9dGhpcy5zaGFwZSxiPXRoaXMuc3RyaWRlO3JldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKHRoaXMuZGF0YSxcIit0U2hhcGUuam9pbihcIixcIikrXCIsXCIrdFN0cmlkZS5qb2luKFwiLFwiKStcIix0aGlzLm9mZnNldCl9XCIpXG5cbiAgLy92aWV3LnBpY2soKTpcbiAgY29kZS5wdXNoKFwicHJvdG8ucGljaz1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfcGljayhcIithcmdzK1wiKXt2YXIgYT1bXSxiPVtdLGM9dGhpcy5vZmZzZXRcIilcbiAgZm9yKHZhciBpPTA7IGk8ZGltZW5zaW9uOyArK2kpIHtcbiAgICBjb2RlLnB1c2goXCJpZih0eXBlb2YgaVwiK2krXCI9PT0nbnVtYmVyJyYmaVwiK2krXCI+PTApe2M9KGMrdGhpcy5zdHJpZGVbXCIraStcIl0qaVwiK2krXCIpfDB9ZWxzZXthLnB1c2godGhpcy5zaGFwZVtcIitpK1wiXSk7Yi5wdXNoKHRoaXMuc3RyaWRlW1wiK2krXCJdKX1cIilcbiAgfVxuICBjb2RlLnB1c2goXCJ2YXIgY3Rvcj1DVE9SX0xJU1RbYS5sZW5ndGgrMV07cmV0dXJuIGN0b3IodGhpcy5kYXRhLGEsYixjKX1cIilcblxuICAvL0FkZCByZXR1cm4gc3RhdGVtZW50XG4gIGNvZGUucHVzaChcInJldHVybiBmdW5jdGlvbiBjb25zdHJ1Y3RfXCIrY2xhc3NOYW1lK1wiKGRhdGEsc2hhcGUsc3RyaWRlLG9mZnNldCl7cmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIoZGF0YSxcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJzaGFwZVtcIitpK1wiXVwiXG4gICAgfSkuam9pbihcIixcIikrXCIsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwic3RyaWRlW1wiK2krXCJdXCJcbiAgICB9KS5qb2luKFwiLFwiKStcIixvZmZzZXQpfVwiKVxuXG4gIC8vQ29tcGlsZSBwcm9jZWR1cmVcbiAgdmFyIHByb2NlZHVyZSA9IG5ldyBGdW5jdGlvbihcIkNUT1JfTElTVFwiLCBcIk9SREVSXCIsIGNvZGUuam9pbihcIlxcblwiKSlcbiAgcmV0dXJuIHByb2NlZHVyZShDQUNIRURfQ09OU1RSVUNUT1JTW2R0eXBlXSwgb3JkZXIpXG59XG5cbmZ1bmN0aW9uIGFycmF5RFR5cGUoZGF0YSkge1xuICBpZihpc0J1ZmZlcihkYXRhKSkge1xuICAgIHJldHVybiBcImJ1ZmZlclwiXG4gIH1cbiAgaWYoaGFzVHlwZWRBcnJheXMpIHtcbiAgICBzd2l0Y2goT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRhdGEpKSB7XG4gICAgICBjYXNlIFwiW29iamVjdCBGbG9hdDY0QXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcImZsb2F0NjRcIlxuICAgICAgY2FzZSBcIltvYmplY3QgRmxvYXQzMkFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJmbG9hdDMyXCJcbiAgICAgIGNhc2UgXCJbb2JqZWN0IEludDhBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwiaW50OFwiXG4gICAgICBjYXNlIFwiW29iamVjdCBJbnQxNkFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJpbnQxNlwiXG4gICAgICBjYXNlIFwiW29iamVjdCBJbnQzMkFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJpbnQzMlwiXG4gICAgICBjYXNlIFwiW29iamVjdCBVaW50OEFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJ1aW50OFwiXG4gICAgICBjYXNlIFwiW29iamVjdCBVaW50MTZBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwidWludDE2XCJcbiAgICAgIGNhc2UgXCJbb2JqZWN0IFVpbnQzMkFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJ1aW50MzJcIlxuICAgICAgY2FzZSBcIltvYmplY3QgVWludDhDbGFtcGVkQXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcInVpbnQ4X2NsYW1wZWRcIlxuICAgIH1cbiAgfVxuICBpZihBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgcmV0dXJuIFwiYXJyYXlcIlxuICB9XG4gIHJldHVybiBcImdlbmVyaWNcIlxufVxuXG52YXIgQ0FDSEVEX0NPTlNUUlVDVE9SUyA9IHtcbiAgXCJmbG9hdDMyXCI6W10sXG4gIFwiZmxvYXQ2NFwiOltdLFxuICBcImludDhcIjpbXSxcbiAgXCJpbnQxNlwiOltdLFxuICBcImludDMyXCI6W10sXG4gIFwidWludDhcIjpbXSxcbiAgXCJ1aW50MTZcIjpbXSxcbiAgXCJ1aW50MzJcIjpbXSxcbiAgXCJhcnJheVwiOltdLFxuICBcInVpbnQ4X2NsYW1wZWRcIjpbXSxcbiAgXCJidWZmZXJcIjpbXSxcbiAgXCJnZW5lcmljXCI6W11cbn1cblxuOyhmdW5jdGlvbigpIHtcbiAgZm9yKHZhciBpZCBpbiBDQUNIRURfQ09OU1RSVUNUT1JTKSB7XG4gICAgQ0FDSEVEX0NPTlNUUlVDVE9SU1tpZF0ucHVzaChjb21waWxlQ29uc3RydWN0b3IoaWQsIC0xKSlcbiAgfVxufSk7XG5cbmZ1bmN0aW9uIHdyYXBwZWROREFycmF5Q3RvcihkYXRhLCBzaGFwZSwgc3RyaWRlLCBvZmZzZXQpIHtcbiAgaWYoZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIGN0b3IgPSBDQUNIRURfQ09OU1RSVUNUT1JTLmFycmF5WzBdXG4gICAgcmV0dXJuIGN0b3IoW10pXG4gIH0gZWxzZSBpZih0eXBlb2YgZGF0YSA9PT0gXCJudW1iZXJcIikge1xuICAgIGRhdGEgPSBbZGF0YV1cbiAgfVxuICBpZihzaGFwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc2hhcGUgPSBbIGRhdGEubGVuZ3RoIF1cbiAgfVxuICB2YXIgZCA9IHNoYXBlLmxlbmd0aFxuICBpZihzdHJpZGUgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0cmlkZSA9IG5ldyBBcnJheShkKVxuICAgIGZvcih2YXIgaT1kLTEsIHN6PTE7IGk+PTA7IC0taSkge1xuICAgICAgc3RyaWRlW2ldID0gc3pcbiAgICAgIHN6ICo9IHNoYXBlW2ldXG4gICAgfVxuICB9XG4gIGlmKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgb2Zmc2V0ID0gMFxuICAgIGZvcih2YXIgaT0wOyBpPGQ7ICsraSkge1xuICAgICAgaWYoc3RyaWRlW2ldIDwgMCkge1xuICAgICAgICBvZmZzZXQgLT0gKHNoYXBlW2ldLTEpKnN0cmlkZVtpXVxuICAgICAgfVxuICAgIH1cbiAgfVxuICB2YXIgZHR5cGUgPSBhcnJheURUeXBlKGRhdGEpXG4gIHZhciBjdG9yX2xpc3QgPSBDQUNIRURfQ09OU1RSVUNUT1JTW2R0eXBlXVxuICB3aGlsZShjdG9yX2xpc3QubGVuZ3RoIDw9IGQrMSkge1xuICAgIGN0b3JfbGlzdC5wdXNoKGNvbXBpbGVDb25zdHJ1Y3RvcihkdHlwZSwgY3Rvcl9saXN0Lmxlbmd0aC0xKSlcbiAgfVxuICB2YXIgY3RvciA9IGN0b3JfbGlzdFtkKzFdXG4gIHJldHVybiBjdG9yKGRhdGEsIHNoYXBlLCBzdHJpZGUsIG9mZnNldClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB3cmFwcGVkTkRBcnJheUN0b3JcbiJdfQ==
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
module.exports = require("cwise-compiler")
},{"cwise-compiler":2}],2:[function(require,module,exports){
"use strict"
var createThunk = require("./lib/thunk.js")
function Procedure() {
this.argTypes = []
this.shimArgs = []
this.arrayArgs = []
this.arrayBlockIndices = []
this.scalarArgs = []
this.offsetArgs = []
this.offsetArgIndex = []
this.indexArgs = []
this.shapeArgs = []
this.funcName = ""
this.pre = null
this.body = null
this.post = null
this.debug = false
}
function compileCwise(user_args) {
//Create procedure
var proc = new Procedure()
//Parse blocks
proc.pre = user_args.pre
proc.body = user_args.body
proc.post = user_args.post
//Parse arguments
var proc_args = user_args.args.slice(0)
proc.argTypes = proc_args
for(var i=0; i<proc_args.length; ++i) {
var arg_type = proc_args[i]
if(arg_type === "array" || (typeof arg_type === "object" && arg_type.blockIndices)) {
proc.argTypes[i] = "array"
proc.arrayArgs.push(i)
proc.arrayBlockIndices.push(arg_type.blockIndices ? arg_type.blockIndices : 0)
proc.shimArgs.push("array" + i)
if(i < proc.pre.args.length && proc.pre.args[i].count>0) {
throw new Error("cwise: pre() block may not reference array args")
}
if(i < proc.post.args.length && proc.post.args[i].count>0) {
throw new Error("cwise: post() block may not reference array args")
}
} else if(arg_type === "scalar") {
proc.scalarArgs.push(i)
proc.shimArgs.push("scalar" + i)
} else if(arg_type === "index") {
proc.indexArgs.push(i)
if(i < proc.pre.args.length && proc.pre.args[i].count > 0) {
throw new Error("cwise: pre() block may not reference array index")
}
if(i < proc.body.args.length && proc.body.args[i].lvalue) {
throw new Error("cwise: body() block may not write to array index")
}
if(i < proc.post.args.length && proc.post.args[i].count > 0) {
throw new Error("cwise: post() block may not reference array index")
}
} else if(arg_type === "shape") {
proc.shapeArgs.push(i)
if(i < proc.pre.args.length && proc.pre.args[i].lvalue) {
throw new Error("cwise: pre() block may not write to array shape")
}
if(i < proc.body.args.length && proc.body.args[i].lvalue) {
throw new Error("cwise: body() block may not write to array shape")
}
if(i < proc.post.args.length && proc.post.args[i].lvalue) {
throw new Error("cwise: post() block may not write to array shape")
}
} else if(typeof arg_type === "object" && arg_type.offset) {
proc.argTypes[i] = "offset"
proc.offsetArgs.push({ array: arg_type.array, offset:arg_type.offset })
proc.offsetArgIndex.push(i)
} else {
throw new Error("cwise: Unknown argument type " + proc_args[i])
}
}
//Make sure at least one array argument was specified
if(proc.arrayArgs.length <= 0) {
throw new Error("cwise: No array arguments specified")
}
//Make sure arguments are correct
if(proc.pre.args.length > proc_args.length) {
throw new Error("cwise: Too many arguments in pre() block")
}
if(proc.body.args.length > proc_args.length) {
throw new Error("cwise: Too many arguments in body() block")
}
if(proc.post.args.length > proc_args.length) {
throw new Error("cwise: Too many arguments in post() block")
}
//Check debug flag
proc.debug = !!user_args.printCode || !!user_args.debug
//Retrieve name
proc.funcName = user_args.funcName || "cwise"
//Read in block size
proc.blockSize = user_args.blockSize || 64
return createThunk(proc)
}
module.exports = compileCwise
},{"./lib/thunk.js":4}],3:[function(require,module,exports){
"use strict"
var uniq = require("uniq")
// This function generates very simple loops analogous to how you typically traverse arrays (the outermost loop corresponds to the slowest changing index, the innermost loop to the fastest changing index)
// TODO: If two arrays have the same strides (and offsets) there is potential for decreasing the number of "pointers" and related variables. The drawback is that the type signature would become more specific and that there would thus be less potential for caching, but it might still be worth it, especially when dealing with large numbers of arguments.
function innerFill(order, proc, body) {
var dimension = order.length
, nargs = proc.arrayArgs.length
, has_index = proc.indexArgs.length>0
, code = []
, vars = []
, idx=0, pidx=0, i, j
for(i=0; i<dimension; ++i) { // Iteration variables
vars.push(["i",i,"=0"].join(""))
}
//Compute scan deltas
for(j=0; j<nargs; ++j) {
for(i=0; i<dimension; ++i) {
pidx = idx
idx = order[i]
if(i === 0) { // The innermost/fastest dimension's delta is simply its stride
vars.push(["d",j,"s",i,"=t",j,"p",idx].join(""))
} else { // For other dimensions the delta is basically the stride minus something which essentially "rewinds" the previous (more inner) dimension
vars.push(["d",j,"s",i,"=(t",j,"p",idx,"-s",pidx,"*t",j,"p",pidx,")"].join(""))
}
}
}
code.push("var " + vars.join(","))
//Scan loop
for(i=dimension-1; i>=0; --i) { // Start at largest stride and work your way inwards
idx = order[i]
code.push(["for(i",i,"=0;i",i,"<s",idx,";++i",i,"){"].join(""))
}
//Push body of inner loop
code.push(body)
//Advance scan pointers
for(i=0; i<dimension; ++i) {
pidx = idx
idx = order[i]
for(j=0; j<nargs; ++j) {
code.push(["p",j,"+=d",j,"s",i].join(""))
}
if(has_index) {
if(i > 0) {
code.push(["index[",pidx,"]-=s",pidx].join(""))
}
code.push(["++index[",idx,"]"].join(""))
}
code.push("}")
}
return code.join("\n")
}
// Generate "outer" loops that loop over blocks of data, applying "inner" loops to the blocks by manipulating the local variables in such a way that the inner loop only "sees" the current block.
// TODO: If this is used, then the previous declaration (done by generateCwiseOp) of s* is essentially unnecessary.
// I believe the s* are not used elsewhere (in particular, I don't think they're used in the pre/post parts and "shape" is defined independently), so it would be possible to make defining the s* dependent on what loop method is being used.
function outerFill(matched, order, proc, body) {
var dimension = order.length
, nargs = proc.arrayArgs.length
, blockSize = proc.blockSize
, has_index = proc.indexArgs.length > 0
, code = []
for(var i=0; i<nargs; ++i) {
code.push(["var offset",i,"=p",i].join(""))
}
//Generate loops for unmatched dimensions
// The order in which these dimensions are traversed is fairly arbitrary (from small stride to large stride, for the first argument)
// TODO: It would be nice if the order in which these loops are placed would also be somehow "optimal" (at the very least we should check that it really doesn't hurt us if they're not).
for(var i=matched; i<dimension; ++i) {
code.push(["for(var j"+i+"=SS[", order[i], "]|0;j", i, ">0;){"].join("")) // Iterate back to front
code.push(["if(j",i,"<",blockSize,"){"].join("")) // Either decrease j by blockSize (s = blockSize), or set it to zero (after setting s = j).
code.push(["s",order[i],"=j",i].join(""))
code.push(["j",i,"=0"].join(""))
code.push(["}else{s",order[i],"=",blockSize].join(""))
code.push(["j",i,"-=",blockSize,"}"].join(""))
if(has_index) {
code.push(["index[",order[i],"]=j",i].join(""))
}
}
for(var i=0; i<nargs; ++i) {
var indexStr = ["offset"+i]
for(var j=matched; j<dimension; ++j) {
indexStr.push(["j",j,"*t",i,"p",order[j]].join(""))
}
code.push(["p",i,"=(",indexStr.join("+"),")"].join(""))
}
code.push(innerFill(order, proc, body))
for(var i=matched; i<dimension; ++i) {
code.push("}")
}
return code.join("\n")
}
//Count the number of compatible inner orders
// This is the length of the longest common prefix of the arrays in orders.
// Each array in orders lists the dimensions of the correspond ndarray in order of increasing stride.
// This is thus the maximum number of dimensions that can be efficiently traversed by simple nested loops for all arrays.
function countMatches(orders) {
var matched = 0, dimension = orders[0].length
while(matched < dimension) {
for(var j=1; j<orders.length; ++j) {
if(orders[j][matched] !== orders[0][matched]) {
return matched
}
}
++matched
}
return matched
}
//Processes a block according to the given data types
// Replaces variable names by different ones, either "local" ones (that are then ferried in and out of the given array) or ones matching the arguments that the function performing the ultimate loop will accept.
function processBlock(block, proc, dtypes) {
var code = block.body
var pre = []
var post = []
for(var i=0; i<block.args.length; ++i) {
var carg = block.args[i]
if(carg.count <= 0) {
continue
}
var re = new RegExp(carg.name, "g")
var ptrStr = ""
var arrNum = proc.arrayArgs.indexOf(i)
switch(proc.argTypes[i]) {
case "offset":
var offArgIndex = proc.offsetArgIndex.indexOf(i)
var offArg = proc.offsetArgs[offArgIndex]
arrNum = offArg.array
ptrStr = "+q" + offArgIndex // Adds offset to the "pointer" in the array
case "array":
ptrStr = "p" + arrNum + ptrStr
var localStr = "l" + i
var arrStr = "a" + arrNum
if (proc.arrayBlockIndices[arrNum] === 0) { // Argument to body is just a single value from this array
if(carg.count === 1) { // Argument/array used only once(?)
if(dtypes[arrNum] === "generic") {
if(carg.lvalue) {
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // Is this necessary if the argument is ONLY used as an lvalue? (keep in mind that we can have a += something, so we would actually need to check carg.rvalue)
code = code.replace(re, localStr)
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join(""))
} else {
code = code.replace(re, [arrStr, ".get(", ptrStr, ")"].join(""))
}
} else {
code = code.replace(re, [arrStr, "[", ptrStr, "]"].join(""))
}
} else if(dtypes[arrNum] === "generic") {
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // TODO: Could we optimize by checking for carg.rvalue?
code = code.replace(re, localStr)
if(carg.lvalue) {
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join(""))
}
} else {
pre.push(["var ", localStr, "=", arrStr, "[", ptrStr, "]"].join("")) // TODO: Could we optimize by checking for carg.rvalue?
code = code.replace(re, localStr)
if(carg.lvalue) {
post.push([arrStr, "[", ptrStr, "]=", localStr].join(""))
}
}
} else { // Argument to body is a "block"
var reStrArr = [carg.name], ptrStrArr = [ptrStr]
for(var j=0; j<Math.abs(proc.arrayBlockIndices[arrNum]); j++) {
reStrArr.push("\\s*\\[([^\\]]+)\\]")
ptrStrArr.push("$" + (j+1) + "*t" + arrNum + "b" + j) // Matched index times stride
}
re = new RegExp(reStrArr.join(""), "g")
ptrStr = ptrStrArr.join("+")
if(dtypes[arrNum] === "generic") {
/*if(carg.lvalue) {
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // Is this necessary if the argument is ONLY used as an lvalue? (keep in mind that we can have a += something, so we would actually need to check carg.rvalue)
code = code.replace(re, localStr)
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join(""))
} else {
code = code.replace(re, [arrStr, ".get(", ptrStr, ")"].join(""))
}*/
throw new Error("cwise: Generic arrays not supported in combination with blocks!")
} else {
// This does not produce any local variables, even if variables are used multiple times. It would be possible to do so, but it would complicate things quite a bit.
code = code.replace(re, [arrStr, "[", ptrStr, "]"].join(""))
}
}
break
case "scalar":
code = code.replace(re, "Y" + proc.scalarArgs.indexOf(i))
break
case "index":
code = code.replace(re, "index")
break
case "shape":
code = code.replace(re, "shape")
break
}
}
return [pre.join("\n"), code, post.join("\n")].join("\n").trim()
}
function typeSummary(dtypes) {
var summary = new Array(dtypes.length)
var allEqual = true
for(var i=0; i<dtypes.length; ++i) {
var t = dtypes[i]
var digits = t.match(/\d+/)
if(!digits) {
digits = ""
} else {
digits = digits[0]
}
if(t.charAt(0) === 0) {
summary[i] = "u" + t.charAt(1) + digits
} else {
summary[i] = t.charAt(0) + digits
}
if(i > 0) {
allEqual = allEqual && summary[i] === summary[i-1]
}
}
if(allEqual) {
return summary[0]
}
return summary.join("")
}
//Generates a cwise operator
function generateCWiseOp(proc, typesig) {
//Compute dimension
// Arrays get put first in typesig, and there are two entries per array (dtype and order), so this gets the number of dimensions in the first array arg.
var dimension = (typesig[1].length - Math.abs(proc.arrayBlockIndices[0]))|0
var orders = new Array(proc.arrayArgs.length)
var dtypes = new Array(proc.arrayArgs.length)
for(var i=0; i<proc.arrayArgs.length; ++i) {
dtypes[i] = typesig[2*i]
orders[i] = typesig[2*i+1]
}
//Determine where block and loop indices start and end
var blockBegin = [], blockEnd = [] // These indices are exposed as blocks
var loopBegin = [], loopEnd = [] // These indices are iterated over
var loopOrders = [] // orders restricted to the loop indices
for(var i=0; i<proc.arrayArgs.length; ++i) {
if (proc.arrayBlockIndices[i]<0) {
loopBegin.push(0)
loopEnd.push(dimension)
blockBegin.push(dimension)
blockEnd.push(dimension+proc.arrayBlockIndices[i])
} else {
loopBegin.push(proc.arrayBlockIndices[i]) // Non-negative
loopEnd.push(proc.arrayBlockIndices[i]+dimension)
blockBegin.push(0)
blockEnd.push(proc.arrayBlockIndices[i])
}
var newOrder = []
for(var j=0; j<orders[i].length; j++) {
if (loopBegin[i]<=orders[i][j] && orders[i][j]<loopEnd[i]) {
newOrder.push(orders[i][j]-loopBegin[i]) // If this is a loop index, put it in newOrder, subtracting loopBegin, to make sure that all loopOrders are using a common set of indices.
}
}
loopOrders.push(newOrder)
}
//First create arguments for procedure
var arglist = ["SS"] // SS is the overall shape over which we iterate
var code = ["'use strict'"]
var vars = []
for(var j=0; j<dimension; ++j) {
vars.push(["s", j, "=SS[", j, "]"].join("")) // The limits for each dimension.
}
for(var i=0; i<proc.arrayArgs.length; ++i) {
arglist.push("a"+i) // Actual data array
arglist.push("t"+i) // Strides
arglist.push("p"+i) // Offset in the array at which the data starts (also used for iterating over the data)
for(var j=0; j<dimension; ++j) { // Unpack the strides into vars for looping
vars.push(["t",i,"p",j,"=t",i,"[",loopBegin[i]+j,"]"].join(""))
}
for(var j=0; j<Math.abs(proc.arrayBlockIndices[i]); ++j) { // Unpack the strides into vars for block iteration
vars.push(["t",i,"b",j,"=t",i,"[",blockBegin[i]+j,"]"].join(""))
}
}
for(var i=0; i<proc.scalarArgs.length; ++i) {
arglist.push("Y" + i)
}
if(proc.shapeArgs.length > 0) {
vars.push("shape=SS.slice(0)") // Makes the shape over which we iterate available to the user defined functions (so you can use width/height for example)
}
if(proc.indexArgs.length > 0) {
// Prepare an array to keep track of the (logical) indices, initialized to dimension zeroes.
var zeros = new Array(dimension)
for(var i=0; i<dimension; ++i) {
zeros[i] = "0"
}
vars.push(["index=[", zeros.join(","), "]"].join(""))
}
for(var i=0; i<proc.offsetArgs.length; ++i) { // Offset arguments used for stencil operations
var off_arg = proc.offsetArgs[i]
var init_string = []
for(var j=0; j<off_arg.offset.length; ++j) {
if(off_arg.offset[j] === 0) {
continue
} else if(off_arg.offset[j] === 1) {
init_string.push(["t", off_arg.array, "p", j].join(""))
} else {
init_string.push([off_arg.offset[j], "*t", off_arg.array, "p", j].join(""))
}
}
if(init_string.length === 0) {
vars.push("q" + i + "=0")
} else {
vars.push(["q", i, "=", init_string.join("+")].join(""))
}
}
//Prepare this variables
var thisVars = uniq([].concat(proc.pre.thisVars)
.concat(proc.body.thisVars)
.concat(proc.post.thisVars))
vars = vars.concat(thisVars)
code.push("var " + vars.join(","))
for(var i=0; i<proc.arrayArgs.length; ++i) {
code.push("p"+i+"|=0")
}
//Inline prelude
if(proc.pre.body.length > 3) {
code.push(processBlock(proc.pre, proc, dtypes))
}
//Process body
var body = processBlock(proc.body, proc, dtypes)
var matched = countMatches(loopOrders)
if(matched < dimension) {
code.push(outerFill(matched, loopOrders[0], proc, body)) // TODO: Rather than passing loopOrders[0], it might be interesting to look at passing an order that represents the majority of the arguments for example.
} else {
code.push(innerFill(loopOrders[0], proc, body))
}
//Inline epilog
if(proc.post.body.length > 3) {
code.push(processBlock(proc.post, proc, dtypes))
}
if(proc.debug) {
console.log("-----Generated cwise routine for ", typesig, ":\n" + code.join("\n") + "\n----------")
}
var loopName = [(proc.funcName||"unnamed"), "_cwise_loop_", orders[0].join("s"),"m",matched,typeSummary(dtypes)].join("")
var f = new Function(["function ",loopName,"(", arglist.join(","),"){", code.join("\n"),"} return ", loopName].join(""))
return f()
}
module.exports = generateCWiseOp
},{"uniq":5}],4:[function(require,module,exports){
"use strict"
// The function below is called when constructing a cwise function object, and does the following:
// A function object is constructed which accepts as argument a compilation function and returns another function.
// It is this other function that is eventually returned by createThunk, and this function is the one that actually
// checks whether a certain pattern of arguments has already been used before and compiles new loops as needed.
// The compilation passed to the first function object is used for compiling new functions.
// Once this function object is created, it is called with compile as argument, where the first argument of compile
// is bound to "proc" (essentially containing a preprocessed version of the user arguments to cwise).
// So createThunk roughly works like this:
// function createThunk(proc) {
// var thunk = function(compileBound) {
// var CACHED = {}
// return function(arrays and scalars) {
// if (dtype and order of arrays in CACHED) {
// var func = CACHED[dtype and order of arrays]
// } else {
// var func = CACHED[dtype and order of arrays] = compileBound(dtype and order of arrays)
// }
// return func(arrays and scalars)
// }
// }
// return thunk(compile.bind1(proc))
// }
var compile = require("./compile.js")
function createThunk(proc) {
var code = ["'use strict'", "var CACHED={}"]
var vars = []
var thunkName = proc.funcName + "_cwise_thunk"
//Build thunk
code.push(["return function ", thunkName, "(", proc.shimArgs.join(","), "){"].join(""))
var typesig = []
var string_typesig = []
var proc_args = [["array",proc.arrayArgs[0],".shape.slice(", // Slice shape so that we only retain the shape over which we iterate (which gets passed to the cwise operator as SS).
Math.max(0,proc.arrayBlockIndices[0]),proc.arrayBlockIndices[0]<0?(","+proc.arrayBlockIndices[0]+")"):")"].join("")]
var shapeLengthConditions = [], shapeConditions = []
// Process array arguments
for(var i=0; i<proc.arrayArgs.length; ++i) {
var j = proc.arrayArgs[i]
vars.push(["t", j, "=array", j, ".dtype,",
"r", j, "=array", j, ".order"].join(""))
typesig.push("t" + j)
typesig.push("r" + j)
string_typesig.push("t"+j)
string_typesig.push("r"+j+".join()")
proc_args.push("array" + j + ".data")
proc_args.push("array" + j + ".stride")
proc_args.push("array" + j + ".offset|0")
if (i>0) { // Gather conditions to check for shape equality (ignoring block indices)
shapeLengthConditions.push("array" + proc.arrayArgs[0] + ".shape.length===array" + j + ".shape.length+" + (Math.abs(proc.arrayBlockIndices[0])-Math.abs(proc.arrayBlockIndices[i])))
shapeConditions.push("array" + proc.arrayArgs[0] + ".shape[shapeIndex+" + Math.max(0,proc.arrayBlockIndices[0]) + "]===array" + j + ".shape[shapeIndex+" + Math.max(0,proc.arrayBlockIndices[i]) + "]")
}
}
// Check for shape equality
if (proc.arrayArgs.length > 1) {
code.push("if (!(" + shapeLengthConditions.join(" && ") + ")) throw new Error('cwise: Arrays do not all have the same dimensionality!')")
code.push("for(var shapeIndex=array" + proc.arrayArgs[0] + ".shape.length-" + Math.abs(proc.arrayBlockIndices[0]) + "; shapeIndex-->0;) {")
code.push("if (!(" + shapeConditions.join(" && ") + ")) throw new Error('cwise: Arrays do not all have the same shape!')")
code.push("}")
}
// Process scalar arguments
for(var i=0; i<proc.scalarArgs.length; ++i) {
proc_args.push("scalar" + proc.scalarArgs[i])
}
// Check for cached function (and if not present, generate it)
vars.push(["type=[", string_typesig.join(","), "].join()"].join(""))
vars.push("proc=CACHED[type]")
code.push("var " + vars.join(","))
code.push(["if(!proc){",
"CACHED[type]=proc=compile([", typesig.join(","), "])}",
"return proc(", proc_args.join(","), ")}"].join(""))
if(proc.debug) {
console.log("-----Generated thunk:\n" + code.join("\n") + "\n----------")
}
//Compile thunk
var thunk = new Function("compile", code.join("\n"))
return thunk(compile.bind(undefined, proc))
}
module.exports = createThunk
},{"./compile.js":3}],5:[function(require,module,exports){
"use strict"
function unique_pred(list, compare) {
var ptr = 1
, len = list.length
, a=list[0], b=list[0]
for(var i=1; i<len; ++i) {
b = a
a = list[i]
if(compare(a, b)) {
if(i === ptr) {
ptr++
continue
}
list[ptr++] = a
}
}
list.length = ptr
return list
}
function unique_eq(list) {
var ptr = 1
, len = list.length
, a=list[0], b = list[0]
for(var i=1; i<len; ++i, b=a) {
b = a
a = list[i]
if(a !== b) {
if(i === ptr) {
ptr++
continue
}
list[ptr++] = a
}
}
list.length = ptr
return list
}
function unique(list, compare, sorted) {
if(list.length === 0) {
return list
}
if(compare) {
if(!sorted) {
list.sort(compare)
}
return unique_pred(list, compare)
}
if(!sorted) {
list.sort()
}
return unique_eq(list)
}
module.exports = unique
},{}],"ndarray-fill":[function(require,module,exports){
"use strict"
var fill = require('cwise/lib/wrapper')({"args":["index","array","scalar"],"pre":{"body":"{}","args":[],"thisVars":[],"localVars":[]},"body":{"body":"{_inline_1_arg1_=_inline_1_arg2_.apply(void 0,_inline_1_arg0_)}","args":[{"name":"_inline_1_arg0_","lvalue":false,"rvalue":true,"count":1},{"name":"_inline_1_arg1_","lvalue":true,"rvalue":false,"count":1},{"name":"_inline_1_arg2_","lvalue":false,"rvalue":true,"count":1}],"thisVars":[],"localVars":[]},"post":{"body":"{}","args":[],"thisVars":[],"localVars":[]},"debug":false,"funcName":"cwise","blockSize":64})
module.exports = function(array, f) {
fill(array, f)
return array
}
},{"cwise/lib/wrapper":1}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIm5vZGVfbW9kdWxlcy9jd2lzZS9saWIvd3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9jd2lzZS9ub2RlX21vZHVsZXMvY3dpc2UtY29tcGlsZXIvY29tcGlsZXIuanMiLCJub2RlX21vZHVsZXMvY3dpc2Uvbm9kZV9tb2R1bGVzL2N3aXNlLWNvbXBpbGVyL2xpYi9jb21waWxlLmpzIiwibm9kZV9tb2R1bGVzL2N3aXNlL25vZGVfbW9kdWxlcy9jd2lzZS1jb21waWxlci9saWIvdGh1bmsuanMiLCJub2RlX21vZHVsZXMvY3dpc2Uvbm9kZV9tb2R1bGVzL2N3aXNlLWNvbXBpbGVyL25vZGVfbW9kdWxlcy91bmlxL3VuaXEuanMiLCJpbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImN3aXNlLWNvbXBpbGVyXCIpIiwiXCJ1c2Ugc3RyaWN0XCJcclxuXHJcbnZhciBjcmVhdGVUaHVuayA9IHJlcXVpcmUoXCIuL2xpYi90aHVuay5qc1wiKVxyXG5cclxuZnVuY3Rpb24gUHJvY2VkdXJlKCkge1xyXG4gIHRoaXMuYXJnVHlwZXMgPSBbXVxyXG4gIHRoaXMuc2hpbUFyZ3MgPSBbXVxyXG4gIHRoaXMuYXJyYXlBcmdzID0gW11cclxuICB0aGlzLmFycmF5QmxvY2tJbmRpY2VzID0gW11cclxuICB0aGlzLnNjYWxhckFyZ3MgPSBbXVxyXG4gIHRoaXMub2Zmc2V0QXJncyA9IFtdXHJcbiAgdGhpcy5vZmZzZXRBcmdJbmRleCA9IFtdXHJcbiAgdGhpcy5pbmRleEFyZ3MgPSBbXVxyXG4gIHRoaXMuc2hhcGVBcmdzID0gW11cclxuICB0aGlzLmZ1bmNOYW1lID0gXCJcIlxyXG4gIHRoaXMucHJlID0gbnVsbFxyXG4gIHRoaXMuYm9keSA9IG51bGxcclxuICB0aGlzLnBvc3QgPSBudWxsXHJcbiAgdGhpcy5kZWJ1ZyA9IGZhbHNlXHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNvbXBpbGVDd2lzZSh1c2VyX2FyZ3MpIHtcclxuICAvL0NyZWF0ZSBwcm9jZWR1cmVcclxuICB2YXIgcHJvYyA9IG5ldyBQcm9jZWR1cmUoKVxyXG4gIFxyXG4gIC8vUGFyc2UgYmxvY2tzXHJcbiAgcHJvYy5wcmUgICAgPSB1c2VyX2FyZ3MucHJlXHJcbiAgcHJvYy5ib2R5ICAgPSB1c2VyX2FyZ3MuYm9keVxyXG4gIHByb2MucG9zdCAgID0gdXNlcl9hcmdzLnBvc3RcclxuXHJcbiAgLy9QYXJzZSBhcmd1bWVudHNcclxuICB2YXIgcHJvY19hcmdzID0gdXNlcl9hcmdzLmFyZ3Muc2xpY2UoMClcclxuICBwcm9jLmFyZ1R5cGVzID0gcHJvY19hcmdzXHJcbiAgZm9yKHZhciBpPTA7IGk8cHJvY19hcmdzLmxlbmd0aDsgKytpKSB7XHJcbiAgICB2YXIgYXJnX3R5cGUgPSBwcm9jX2FyZ3NbaV1cclxuICAgIGlmKGFyZ190eXBlID09PSBcImFycmF5XCIgfHwgKHR5cGVvZiBhcmdfdHlwZSA9PT0gXCJvYmplY3RcIiAmJiBhcmdfdHlwZS5ibG9ja0luZGljZXMpKSB7XHJcbiAgICAgIHByb2MuYXJnVHlwZXNbaV0gPSBcImFycmF5XCJcclxuICAgICAgcHJvYy5hcnJheUFyZ3MucHVzaChpKVxyXG4gICAgICBwcm9jLmFycmF5QmxvY2tJbmRpY2VzLnB1c2goYXJnX3R5cGUuYmxvY2tJbmRpY2VzID8gYXJnX3R5cGUuYmxvY2tJbmRpY2VzIDogMClcclxuICAgICAgcHJvYy5zaGltQXJncy5wdXNoKFwiYXJyYXlcIiArIGkpXHJcbiAgICAgIGlmKGkgPCBwcm9jLnByZS5hcmdzLmxlbmd0aCAmJiBwcm9jLnByZS5hcmdzW2ldLmNvdW50PjApIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogcHJlKCkgYmxvY2sgbWF5IG5vdCByZWZlcmVuY2UgYXJyYXkgYXJnc1wiKVxyXG4gICAgICB9XHJcbiAgICAgIGlmKGkgPCBwcm9jLnBvc3QuYXJncy5sZW5ndGggJiYgcHJvYy5wb3N0LmFyZ3NbaV0uY291bnQ+MCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImN3aXNlOiBwb3N0KCkgYmxvY2sgbWF5IG5vdCByZWZlcmVuY2UgYXJyYXkgYXJnc1wiKVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYoYXJnX3R5cGUgPT09IFwic2NhbGFyXCIpIHtcclxuICAgICAgcHJvYy5zY2FsYXJBcmdzLnB1c2goaSlcclxuICAgICAgcHJvYy5zaGltQXJncy5wdXNoKFwic2NhbGFyXCIgKyBpKVxyXG4gICAgfSBlbHNlIGlmKGFyZ190eXBlID09PSBcImluZGV4XCIpIHtcclxuICAgICAgcHJvYy5pbmRleEFyZ3MucHVzaChpKVxyXG4gICAgICBpZihpIDwgcHJvYy5wcmUuYXJncy5sZW5ndGggJiYgcHJvYy5wcmUuYXJnc1tpXS5jb3VudCA+IDApIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogcHJlKCkgYmxvY2sgbWF5IG5vdCByZWZlcmVuY2UgYXJyYXkgaW5kZXhcIilcclxuICAgICAgfVxyXG4gICAgICBpZihpIDwgcHJvYy5ib2R5LmFyZ3MubGVuZ3RoICYmIHByb2MuYm9keS5hcmdzW2ldLmx2YWx1ZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImN3aXNlOiBib2R5KCkgYmxvY2sgbWF5IG5vdCB3cml0ZSB0byBhcnJheSBpbmRleFwiKVxyXG4gICAgICB9XHJcbiAgICAgIGlmKGkgPCBwcm9jLnBvc3QuYXJncy5sZW5ndGggJiYgcHJvYy5wb3N0LmFyZ3NbaV0uY291bnQgPiAwKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY3dpc2U6IHBvc3QoKSBibG9jayBtYXkgbm90IHJlZmVyZW5jZSBhcnJheSBpbmRleFwiKVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYoYXJnX3R5cGUgPT09IFwic2hhcGVcIikge1xyXG4gICAgICBwcm9jLnNoYXBlQXJncy5wdXNoKGkpXHJcbiAgICAgIGlmKGkgPCBwcm9jLnByZS5hcmdzLmxlbmd0aCAmJiBwcm9jLnByZS5hcmdzW2ldLmx2YWx1ZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImN3aXNlOiBwcmUoKSBibG9jayBtYXkgbm90IHdyaXRlIHRvIGFycmF5IHNoYXBlXCIpXHJcbiAgICAgIH1cclxuICAgICAgaWYoaSA8IHByb2MuYm9keS5hcmdzLmxlbmd0aCAmJiBwcm9jLmJvZHkuYXJnc1tpXS5sdmFsdWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogYm9keSgpIGJsb2NrIG1heSBub3Qgd3JpdGUgdG8gYXJyYXkgc2hhcGVcIilcclxuICAgICAgfVxyXG4gICAgICBpZihpIDwgcHJvYy5wb3N0LmFyZ3MubGVuZ3RoICYmIHByb2MucG9zdC5hcmdzW2ldLmx2YWx1ZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImN3aXNlOiBwb3N0KCkgYmxvY2sgbWF5IG5vdCB3cml0ZSB0byBhcnJheSBzaGFwZVwiKVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYodHlwZW9mIGFyZ190eXBlID09PSBcIm9iamVjdFwiICYmIGFyZ190eXBlLm9mZnNldCkge1xyXG4gICAgICBwcm9jLmFyZ1R5cGVzW2ldID0gXCJvZmZzZXRcIlxyXG4gICAgICBwcm9jLm9mZnNldEFyZ3MucHVzaCh7IGFycmF5OiBhcmdfdHlwZS5hcnJheSwgb2Zmc2V0OmFyZ190eXBlLm9mZnNldCB9KVxyXG4gICAgICBwcm9jLm9mZnNldEFyZ0luZGV4LnB1c2goaSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImN3aXNlOiBVbmtub3duIGFyZ3VtZW50IHR5cGUgXCIgKyBwcm9jX2FyZ3NbaV0pXHJcbiAgICB9XHJcbiAgfVxyXG4gIFxyXG4gIC8vTWFrZSBzdXJlIGF0IGxlYXN0IG9uZSBhcnJheSBhcmd1bWVudCB3YXMgc3BlY2lmaWVkXHJcbiAgaWYocHJvYy5hcnJheUFyZ3MubGVuZ3RoIDw9IDApIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihcImN3aXNlOiBObyBhcnJheSBhcmd1bWVudHMgc3BlY2lmaWVkXCIpXHJcbiAgfVxyXG4gIFxyXG4gIC8vTWFrZSBzdXJlIGFyZ3VtZW50cyBhcmUgY29ycmVjdFxyXG4gIGlmKHByb2MucHJlLmFyZ3MubGVuZ3RoID4gcHJvY19hcmdzLmxlbmd0aCkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiY3dpc2U6IFRvbyBtYW55IGFyZ3VtZW50cyBpbiBwcmUoKSBibG9ja1wiKVxyXG4gIH1cclxuICBpZihwcm9jLmJvZHkuYXJncy5sZW5ndGggPiBwcm9jX2FyZ3MubGVuZ3RoKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogVG9vIG1hbnkgYXJndW1lbnRzIGluIGJvZHkoKSBibG9ja1wiKVxyXG4gIH1cclxuICBpZihwcm9jLnBvc3QuYXJncy5sZW5ndGggPiBwcm9jX2FyZ3MubGVuZ3RoKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogVG9vIG1hbnkgYXJndW1lbnRzIGluIHBvc3QoKSBibG9ja1wiKVxyXG4gIH1cclxuXHJcbiAgLy9DaGVjayBkZWJ1ZyBmbGFnXHJcbiAgcHJvYy5kZWJ1ZyA9ICEhdXNlcl9hcmdzLnByaW50Q29kZSB8fCAhIXVzZXJfYXJncy5kZWJ1Z1xyXG4gIFxyXG4gIC8vUmV0cmlldmUgbmFtZVxyXG4gIHByb2MuZnVuY05hbWUgPSB1c2VyX2FyZ3MuZnVuY05hbWUgfHwgXCJjd2lzZVwiXHJcbiAgXHJcbiAgLy9SZWFkIGluIGJsb2NrIHNpemVcclxuICBwcm9jLmJsb2NrU2l6ZSA9IHVzZXJfYXJncy5ibG9ja1NpemUgfHwgNjRcclxuXHJcbiAgcmV0dXJuIGNyZWF0ZVRodW5rKHByb2MpXHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY29tcGlsZUN3aXNlXHJcbiIsIlwidXNlIHN0cmljdFwiXHJcblxyXG52YXIgdW5pcSA9IHJlcXVpcmUoXCJ1bmlxXCIpXHJcblxyXG4vLyBUaGlzIGZ1bmN0aW9uIGdlbmVyYXRlcyB2ZXJ5IHNpbXBsZSBsb29wcyBhbmFsb2dvdXMgdG8gaG93IHlvdSB0eXBpY2FsbHkgdHJhdmVyc2UgYXJyYXlzICh0aGUgb3V0ZXJtb3N0IGxvb3AgY29ycmVzcG9uZHMgdG8gdGhlIHNsb3dlc3QgY2hhbmdpbmcgaW5kZXgsIHRoZSBpbm5lcm1vc3QgbG9vcCB0byB0aGUgZmFzdGVzdCBjaGFuZ2luZyBpbmRleClcclxuLy8gVE9ETzogSWYgdHdvIGFycmF5cyBoYXZlIHRoZSBzYW1lIHN0cmlkZXMgKGFuZCBvZmZzZXRzKSB0aGVyZSBpcyBwb3RlbnRpYWwgZm9yIGRlY3JlYXNpbmcgdGhlIG51bWJlciBvZiBcInBvaW50ZXJzXCIgYW5kIHJlbGF0ZWQgdmFyaWFibGVzLiBUaGUgZHJhd2JhY2sgaXMgdGhhdCB0aGUgdHlwZSBzaWduYXR1cmUgd291bGQgYmVjb21lIG1vcmUgc3BlY2lmaWMgYW5kIHRoYXQgdGhlcmUgd291bGQgdGh1cyBiZSBsZXNzIHBvdGVudGlhbCBmb3IgY2FjaGluZywgYnV0IGl0IG1pZ2h0IHN0aWxsIGJlIHdvcnRoIGl0LCBlc3BlY2lhbGx5IHdoZW4gZGVhbGluZyB3aXRoIGxhcmdlIG51bWJlcnMgb2YgYXJndW1lbnRzLlxyXG5mdW5jdGlvbiBpbm5lckZpbGwob3JkZXIsIHByb2MsIGJvZHkpIHtcclxuICB2YXIgZGltZW5zaW9uID0gb3JkZXIubGVuZ3RoXHJcbiAgICAsIG5hcmdzID0gcHJvYy5hcnJheUFyZ3MubGVuZ3RoXHJcbiAgICAsIGhhc19pbmRleCA9IHByb2MuaW5kZXhBcmdzLmxlbmd0aD4wXHJcbiAgICAsIGNvZGUgPSBbXVxyXG4gICAgLCB2YXJzID0gW11cclxuICAgICwgaWR4PTAsIHBpZHg9MCwgaSwgalxyXG4gIGZvcihpPTA7IGk8ZGltZW5zaW9uOyArK2kpIHsgLy8gSXRlcmF0aW9uIHZhcmlhYmxlc1xyXG4gICAgdmFycy5wdXNoKFtcImlcIixpLFwiPTBcIl0uam9pbihcIlwiKSlcclxuICB9XHJcbiAgLy9Db21wdXRlIHNjYW4gZGVsdGFzXHJcbiAgZm9yKGo9MDsgajxuYXJnczsgKytqKSB7XHJcbiAgICBmb3IoaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7XHJcbiAgICAgIHBpZHggPSBpZHhcclxuICAgICAgaWR4ID0gb3JkZXJbaV1cclxuICAgICAgaWYoaSA9PT0gMCkgeyAvLyBUaGUgaW5uZXJtb3N0L2Zhc3Rlc3QgZGltZW5zaW9uJ3MgZGVsdGEgaXMgc2ltcGx5IGl0cyBzdHJpZGVcclxuICAgICAgICB2YXJzLnB1c2goW1wiZFwiLGosXCJzXCIsaSxcIj10XCIsaixcInBcIixpZHhdLmpvaW4oXCJcIikpXHJcbiAgICAgIH0gZWxzZSB7IC8vIEZvciBvdGhlciBkaW1lbnNpb25zIHRoZSBkZWx0YSBpcyBiYXNpY2FsbHkgdGhlIHN0cmlkZSBtaW51cyBzb21ldGhpbmcgd2hpY2ggZXNzZW50aWFsbHkgXCJyZXdpbmRzXCIgdGhlIHByZXZpb3VzIChtb3JlIGlubmVyKSBkaW1lbnNpb25cclxuICAgICAgICB2YXJzLnB1c2goW1wiZFwiLGosXCJzXCIsaSxcIj0odFwiLGosXCJwXCIsaWR4LFwiLXNcIixwaWR4LFwiKnRcIixqLFwicFwiLHBpZHgsXCIpXCJdLmpvaW4oXCJcIikpXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgY29kZS5wdXNoKFwidmFyIFwiICsgdmFycy5qb2luKFwiLFwiKSlcclxuICAvL1NjYW4gbG9vcFxyXG4gIGZvcihpPWRpbWVuc2lvbi0xOyBpPj0wOyAtLWkpIHsgLy8gU3RhcnQgYXQgbGFyZ2VzdCBzdHJpZGUgYW5kIHdvcmsgeW91ciB3YXkgaW53YXJkc1xyXG4gICAgaWR4ID0gb3JkZXJbaV1cclxuICAgIGNvZGUucHVzaChbXCJmb3IoaVwiLGksXCI9MDtpXCIsaSxcIjxzXCIsaWR4LFwiOysraVwiLGksXCIpe1wiXS5qb2luKFwiXCIpKVxyXG4gIH1cclxuICAvL1B1c2ggYm9keSBvZiBpbm5lciBsb29wXHJcbiAgY29kZS5wdXNoKGJvZHkpXHJcbiAgLy9BZHZhbmNlIHNjYW4gcG9pbnRlcnNcclxuICBmb3IoaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7XHJcbiAgICBwaWR4ID0gaWR4XHJcbiAgICBpZHggPSBvcmRlcltpXVxyXG4gICAgZm9yKGo9MDsgajxuYXJnczsgKytqKSB7XHJcbiAgICAgIGNvZGUucHVzaChbXCJwXCIsaixcIis9ZFwiLGosXCJzXCIsaV0uam9pbihcIlwiKSlcclxuICAgIH1cclxuICAgIGlmKGhhc19pbmRleCkge1xyXG4gICAgICBpZihpID4gMCkge1xyXG4gICAgICAgIGNvZGUucHVzaChbXCJpbmRleFtcIixwaWR4LFwiXS09c1wiLHBpZHhdLmpvaW4oXCJcIikpXHJcbiAgICAgIH1cclxuICAgICAgY29kZS5wdXNoKFtcIisraW5kZXhbXCIsaWR4LFwiXVwiXS5qb2luKFwiXCIpKVxyXG4gICAgfVxyXG4gICAgY29kZS5wdXNoKFwifVwiKVxyXG4gIH1cclxuICByZXR1cm4gY29kZS5qb2luKFwiXFxuXCIpXHJcbn1cclxuXHJcbi8vIEdlbmVyYXRlIFwib3V0ZXJcIiBsb29wcyB0aGF0IGxvb3Agb3ZlciBibG9ja3Mgb2YgZGF0YSwgYXBwbHlpbmcgXCJpbm5lclwiIGxvb3BzIHRvIHRoZSBibG9ja3MgYnkgbWFuaXB1bGF0aW5nIHRoZSBsb2NhbCB2YXJpYWJsZXMgaW4gc3VjaCBhIHdheSB0aGF0IHRoZSBpbm5lciBsb29wIG9ubHkgXCJzZWVzXCIgdGhlIGN1cnJlbnQgYmxvY2suXHJcbi8vIFRPRE86IElmIHRoaXMgaXMgdXNlZCwgdGhlbiB0aGUgcHJldmlvdXMgZGVjbGFyYXRpb24gKGRvbmUgYnkgZ2VuZXJhdGVDd2lzZU9wKSBvZiBzKiBpcyBlc3NlbnRpYWxseSB1bm5lY2Vzc2FyeS5cclxuLy8gICAgICAgSSBiZWxpZXZlIHRoZSBzKiBhcmUgbm90IHVzZWQgZWxzZXdoZXJlIChpbiBwYXJ0aWN1bGFyLCBJIGRvbid0IHRoaW5rIHRoZXkncmUgdXNlZCBpbiB0aGUgcHJlL3Bvc3QgcGFydHMgYW5kIFwic2hhcGVcIiBpcyBkZWZpbmVkIGluZGVwZW5kZW50bHkpLCBzbyBpdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBtYWtlIGRlZmluaW5nIHRoZSBzKiBkZXBlbmRlbnQgb24gd2hhdCBsb29wIG1ldGhvZCBpcyBiZWluZyB1c2VkLlxyXG5mdW5jdGlvbiBvdXRlckZpbGwobWF0Y2hlZCwgb3JkZXIsIHByb2MsIGJvZHkpIHtcclxuICB2YXIgZGltZW5zaW9uID0gb3JkZXIubGVuZ3RoXHJcbiAgICAsIG5hcmdzID0gcHJvYy5hcnJheUFyZ3MubGVuZ3RoXHJcbiAgICAsIGJsb2NrU2l6ZSA9IHByb2MuYmxvY2tTaXplXHJcbiAgICAsIGhhc19pbmRleCA9IHByb2MuaW5kZXhBcmdzLmxlbmd0aCA+IDBcclxuICAgICwgY29kZSA9IFtdXHJcbiAgZm9yKHZhciBpPTA7IGk8bmFyZ3M7ICsraSkge1xyXG4gICAgY29kZS5wdXNoKFtcInZhciBvZmZzZXRcIixpLFwiPXBcIixpXS5qb2luKFwiXCIpKVxyXG4gIH1cclxuICAvL0dlbmVyYXRlIGxvb3BzIGZvciB1bm1hdGNoZWQgZGltZW5zaW9uc1xyXG4gIC8vIFRoZSBvcmRlciBpbiB3aGljaCB0aGVzZSBkaW1lbnNpb25zIGFyZSB0cmF2ZXJzZWQgaXMgZmFpcmx5IGFyYml0cmFyeSAoZnJvbSBzbWFsbCBzdHJpZGUgdG8gbGFyZ2Ugc3RyaWRlLCBmb3IgdGhlIGZpcnN0IGFyZ3VtZW50KVxyXG4gIC8vIFRPRE86IEl0IHdvdWxkIGJlIG5pY2UgaWYgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXNlIGxvb3BzIGFyZSBwbGFjZWQgd291bGQgYWxzbyBiZSBzb21laG93IFwib3B0aW1hbFwiIChhdCB0aGUgdmVyeSBsZWFzdCB3ZSBzaG91bGQgY2hlY2sgdGhhdCBpdCByZWFsbHkgZG9lc24ndCBodXJ0IHVzIGlmIHRoZXkncmUgbm90KS5cclxuICBmb3IodmFyIGk9bWF0Y2hlZDsgaTxkaW1lbnNpb247ICsraSkge1xyXG4gICAgY29kZS5wdXNoKFtcImZvcih2YXIgalwiK2krXCI9U1NbXCIsIG9yZGVyW2ldLCBcIl18MDtqXCIsIGksIFwiPjA7KXtcIl0uam9pbihcIlwiKSkgLy8gSXRlcmF0ZSBiYWNrIHRvIGZyb250XHJcbiAgICBjb2RlLnB1c2goW1wiaWYoalwiLGksXCI8XCIsYmxvY2tTaXplLFwiKXtcIl0uam9pbihcIlwiKSkgLy8gRWl0aGVyIGRlY3JlYXNlIGogYnkgYmxvY2tTaXplIChzID0gYmxvY2tTaXplKSwgb3Igc2V0IGl0IHRvIHplcm8gKGFmdGVyIHNldHRpbmcgcyA9IGopLlxyXG4gICAgY29kZS5wdXNoKFtcInNcIixvcmRlcltpXSxcIj1qXCIsaV0uam9pbihcIlwiKSlcclxuICAgIGNvZGUucHVzaChbXCJqXCIsaSxcIj0wXCJdLmpvaW4oXCJcIikpXHJcbiAgICBjb2RlLnB1c2goW1wifWVsc2V7c1wiLG9yZGVyW2ldLFwiPVwiLGJsb2NrU2l6ZV0uam9pbihcIlwiKSlcclxuICAgIGNvZGUucHVzaChbXCJqXCIsaSxcIi09XCIsYmxvY2tTaXplLFwifVwiXS5qb2luKFwiXCIpKVxyXG4gICAgaWYoaGFzX2luZGV4KSB7XHJcbiAgICAgIGNvZGUucHVzaChbXCJpbmRleFtcIixvcmRlcltpXSxcIl09alwiLGldLmpvaW4oXCJcIikpXHJcbiAgICB9XHJcbiAgfVxyXG4gIGZvcih2YXIgaT0wOyBpPG5hcmdzOyArK2kpIHtcclxuICAgIHZhciBpbmRleFN0ciA9IFtcIm9mZnNldFwiK2ldXHJcbiAgICBmb3IodmFyIGo9bWF0Y2hlZDsgajxkaW1lbnNpb247ICsraikge1xyXG4gICAgICBpbmRleFN0ci5wdXNoKFtcImpcIixqLFwiKnRcIixpLFwicFwiLG9yZGVyW2pdXS5qb2luKFwiXCIpKVxyXG4gICAgfVxyXG4gICAgY29kZS5wdXNoKFtcInBcIixpLFwiPShcIixpbmRleFN0ci5qb2luKFwiK1wiKSxcIilcIl0uam9pbihcIlwiKSlcclxuICB9XHJcbiAgY29kZS5wdXNoKGlubmVyRmlsbChvcmRlciwgcHJvYywgYm9keSkpXHJcbiAgZm9yKHZhciBpPW1hdGNoZWQ7IGk8ZGltZW5zaW9uOyArK2kpIHtcclxuICAgIGNvZGUucHVzaChcIn1cIilcclxuICB9XHJcbiAgcmV0dXJuIGNvZGUuam9pbihcIlxcblwiKVxyXG59XHJcblxyXG4vL0NvdW50IHRoZSBudW1iZXIgb2YgY29tcGF0aWJsZSBpbm5lciBvcmRlcnNcclxuLy8gVGhpcyBpcyB0aGUgbGVuZ3RoIG9mIHRoZSBsb25nZXN0IGNvbW1vbiBwcmVmaXggb2YgdGhlIGFycmF5cyBpbiBvcmRlcnMuXHJcbi8vIEVhY2ggYXJyYXkgaW4gb3JkZXJzIGxpc3RzIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBjb3JyZXNwb25kIG5kYXJyYXkgaW4gb3JkZXIgb2YgaW5jcmVhc2luZyBzdHJpZGUuXHJcbi8vIFRoaXMgaXMgdGh1cyB0aGUgbWF4aW11bSBudW1iZXIgb2YgZGltZW5zaW9ucyB0aGF0IGNhbiBiZSBlZmZpY2llbnRseSB0cmF2ZXJzZWQgYnkgc2ltcGxlIG5lc3RlZCBsb29wcyBmb3IgYWxsIGFycmF5cy5cclxuZnVuY3Rpb24gY291bnRNYXRjaGVzKG9yZGVycykge1xyXG4gIHZhciBtYXRjaGVkID0gMCwgZGltZW5zaW9uID0gb3JkZXJzWzBdLmxlbmd0aFxyXG4gIHdoaWxlKG1hdGNoZWQgPCBkaW1lbnNpb24pIHtcclxuICAgIGZvcih2YXIgaj0xOyBqPG9yZGVycy5sZW5ndGg7ICsraikge1xyXG4gICAgICBpZihvcmRlcnNbal1bbWF0Y2hlZF0gIT09IG9yZGVyc1swXVttYXRjaGVkXSkge1xyXG4gICAgICAgIHJldHVybiBtYXRjaGVkXHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgICsrbWF0Y2hlZFxyXG4gIH1cclxuICByZXR1cm4gbWF0Y2hlZFxyXG59XHJcblxyXG4vL1Byb2Nlc3NlcyBhIGJsb2NrIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gZGF0YSB0eXBlc1xyXG4vLyBSZXBsYWNlcyB2YXJpYWJsZSBuYW1lcyBieSBkaWZmZXJlbnQgb25lcywgZWl0aGVyIFwibG9jYWxcIiBvbmVzICh0aGF0IGFyZSB0aGVuIGZlcnJpZWQgaW4gYW5kIG91dCBvZiB0aGUgZ2l2ZW4gYXJyYXkpIG9yIG9uZXMgbWF0Y2hpbmcgdGhlIGFyZ3VtZW50cyB0aGF0IHRoZSBmdW5jdGlvbiBwZXJmb3JtaW5nIHRoZSB1bHRpbWF0ZSBsb29wIHdpbGwgYWNjZXB0LlxyXG5mdW5jdGlvbiBwcm9jZXNzQmxvY2soYmxvY2ssIHByb2MsIGR0eXBlcykge1xyXG4gIHZhciBjb2RlID0gYmxvY2suYm9keVxyXG4gIHZhciBwcmUgPSBbXVxyXG4gIHZhciBwb3N0ID0gW11cclxuICBmb3IodmFyIGk9MDsgaTxibG9jay5hcmdzLmxlbmd0aDsgKytpKSB7XHJcbiAgICB2YXIgY2FyZyA9IGJsb2NrLmFyZ3NbaV1cclxuICAgIGlmKGNhcmcuY291bnQgPD0gMCkge1xyXG4gICAgICBjb250aW51ZVxyXG4gICAgfVxyXG4gICAgdmFyIHJlID0gbmV3IFJlZ0V4cChjYXJnLm5hbWUsIFwiZ1wiKVxyXG4gICAgdmFyIHB0clN0ciA9IFwiXCJcclxuICAgIHZhciBhcnJOdW0gPSBwcm9jLmFycmF5QXJncy5pbmRleE9mKGkpXHJcbiAgICBzd2l0Y2gocHJvYy5hcmdUeXBlc1tpXSkge1xyXG4gICAgICBjYXNlIFwib2Zmc2V0XCI6XHJcbiAgICAgICAgdmFyIG9mZkFyZ0luZGV4ID0gcHJvYy5vZmZzZXRBcmdJbmRleC5pbmRleE9mKGkpXHJcbiAgICAgICAgdmFyIG9mZkFyZyA9IHByb2Mub2Zmc2V0QXJnc1tvZmZBcmdJbmRleF1cclxuICAgICAgICBhcnJOdW0gPSBvZmZBcmcuYXJyYXlcclxuICAgICAgICBwdHJTdHIgPSBcIitxXCIgKyBvZmZBcmdJbmRleCAvLyBBZGRzIG9mZnNldCB0byB0aGUgXCJwb2ludGVyXCIgaW4gdGhlIGFycmF5XHJcbiAgICAgIGNhc2UgXCJhcnJheVwiOlxyXG4gICAgICAgIHB0clN0ciA9IFwicFwiICsgYXJyTnVtICsgcHRyU3RyXHJcbiAgICAgICAgdmFyIGxvY2FsU3RyID0gXCJsXCIgKyBpXHJcbiAgICAgICAgdmFyIGFyclN0ciA9IFwiYVwiICsgYXJyTnVtXHJcbiAgICAgICAgaWYgKHByb2MuYXJyYXlCbG9ja0luZGljZXNbYXJyTnVtXSA9PT0gMCkgeyAvLyBBcmd1bWVudCB0byBib2R5IGlzIGp1c3QgYSBzaW5nbGUgdmFsdWUgZnJvbSB0aGlzIGFycmF5XHJcbiAgICAgICAgICBpZihjYXJnLmNvdW50ID09PSAxKSB7IC8vIEFyZ3VtZW50L2FycmF5IHVzZWQgb25seSBvbmNlKD8pXHJcbiAgICAgICAgICAgIGlmKGR0eXBlc1thcnJOdW1dID09PSBcImdlbmVyaWNcIikge1xyXG4gICAgICAgICAgICAgIGlmKGNhcmcubHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICBwcmUucHVzaChbXCJ2YXIgXCIsIGxvY2FsU3RyLCBcIj1cIiwgYXJyU3RyLCBcIi5nZXQoXCIsIHB0clN0ciwgXCIpXCJdLmpvaW4oXCJcIikpIC8vIElzIHRoaXMgbmVjZXNzYXJ5IGlmIHRoZSBhcmd1bWVudCBpcyBPTkxZIHVzZWQgYXMgYW4gbHZhbHVlPyAoa2VlcCBpbiBtaW5kIHRoYXQgd2UgY2FuIGhhdmUgYSArPSBzb21ldGhpbmcsIHNvIHdlIHdvdWxkIGFjdHVhbGx5IG5lZWQgdG8gY2hlY2sgY2FyZy5ydmFsdWUpXHJcbiAgICAgICAgICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKHJlLCBsb2NhbFN0cilcclxuICAgICAgICAgICAgICAgIHBvc3QucHVzaChbYXJyU3RyLCBcIi5zZXQoXCIsIHB0clN0ciwgXCIsXCIsIGxvY2FsU3RyLFwiKVwiXS5qb2luKFwiXCIpKVxyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKHJlLCBbYXJyU3RyLCBcIi5nZXQoXCIsIHB0clN0ciwgXCIpXCJdLmpvaW4oXCJcIikpXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIGNvZGUgPSBjb2RlLnJlcGxhY2UocmUsIFthcnJTdHIsIFwiW1wiLCBwdHJTdHIsIFwiXVwiXS5qb2luKFwiXCIpKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9IGVsc2UgaWYoZHR5cGVzW2Fyck51bV0gPT09IFwiZ2VuZXJpY1wiKSB7XHJcbiAgICAgICAgICAgIHByZS5wdXNoKFtcInZhciBcIiwgbG9jYWxTdHIsIFwiPVwiLCBhcnJTdHIsIFwiLmdldChcIiwgcHRyU3RyLCBcIilcIl0uam9pbihcIlwiKSkgLy8gVE9ETzogQ291bGQgd2Ugb3B0aW1pemUgYnkgY2hlY2tpbmcgZm9yIGNhcmcucnZhbHVlP1xyXG4gICAgICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKHJlLCBsb2NhbFN0cilcclxuICAgICAgICAgICAgaWYoY2FyZy5sdmFsdWUpIHtcclxuICAgICAgICAgICAgICBwb3N0LnB1c2goW2FyclN0ciwgXCIuc2V0KFwiLCBwdHJTdHIsIFwiLFwiLCBsb2NhbFN0cixcIilcIl0uam9pbihcIlwiKSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcHJlLnB1c2goW1widmFyIFwiLCBsb2NhbFN0ciwgXCI9XCIsIGFyclN0ciwgXCJbXCIsIHB0clN0ciwgXCJdXCJdLmpvaW4oXCJcIikpIC8vIFRPRE86IENvdWxkIHdlIG9wdGltaXplIGJ5IGNoZWNraW5nIGZvciBjYXJnLnJ2YWx1ZT9cclxuICAgICAgICAgICAgY29kZSA9IGNvZGUucmVwbGFjZShyZSwgbG9jYWxTdHIpXHJcbiAgICAgICAgICAgIGlmKGNhcmcubHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgcG9zdC5wdXNoKFthcnJTdHIsIFwiW1wiLCBwdHJTdHIsIFwiXT1cIiwgbG9jYWxTdHJdLmpvaW4oXCJcIikpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgeyAvLyBBcmd1bWVudCB0byBib2R5IGlzIGEgXCJibG9ja1wiXHJcbiAgICAgICAgICB2YXIgcmVTdHJBcnIgPSBbY2FyZy5uYW1lXSwgcHRyU3RyQXJyID0gW3B0clN0cl1cclxuICAgICAgICAgIGZvcih2YXIgaj0wOyBqPE1hdGguYWJzKHByb2MuYXJyYXlCbG9ja0luZGljZXNbYXJyTnVtXSk7IGorKykge1xyXG4gICAgICAgICAgICByZVN0ckFyci5wdXNoKFwiXFxcXHMqXFxcXFsoW15cXFxcXV0rKVxcXFxdXCIpXHJcbiAgICAgICAgICAgIHB0clN0ckFyci5wdXNoKFwiJFwiICsgKGorMSkgKyBcIip0XCIgKyBhcnJOdW0gKyBcImJcIiArIGopIC8vIE1hdGNoZWQgaW5kZXggdGltZXMgc3RyaWRlXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICByZSA9IG5ldyBSZWdFeHAocmVTdHJBcnIuam9pbihcIlwiKSwgXCJnXCIpXHJcbiAgICAgICAgICBwdHJTdHIgPSBwdHJTdHJBcnIuam9pbihcIitcIilcclxuICAgICAgICAgIGlmKGR0eXBlc1thcnJOdW1dID09PSBcImdlbmVyaWNcIikge1xyXG4gICAgICAgICAgICAvKmlmKGNhcmcubHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgcHJlLnB1c2goW1widmFyIFwiLCBsb2NhbFN0ciwgXCI9XCIsIGFyclN0ciwgXCIuZ2V0KFwiLCBwdHJTdHIsIFwiKVwiXS5qb2luKFwiXCIpKSAvLyBJcyB0aGlzIG5lY2Vzc2FyeSBpZiB0aGUgYXJndW1lbnQgaXMgT05MWSB1c2VkIGFzIGFuIGx2YWx1ZT8gKGtlZXAgaW4gbWluZCB0aGF0IHdlIGNhbiBoYXZlIGEgKz0gc29tZXRoaW5nLCBzbyB3ZSB3b3VsZCBhY3R1YWxseSBuZWVkIHRvIGNoZWNrIGNhcmcucnZhbHVlKVxyXG4gICAgICAgICAgICAgIGNvZGUgPSBjb2RlLnJlcGxhY2UocmUsIGxvY2FsU3RyKVxyXG4gICAgICAgICAgICAgIHBvc3QucHVzaChbYXJyU3RyLCBcIi5zZXQoXCIsIHB0clN0ciwgXCIsXCIsIGxvY2FsU3RyLFwiKVwiXS5qb2luKFwiXCIpKVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIGNvZGUgPSBjb2RlLnJlcGxhY2UocmUsIFthcnJTdHIsIFwiLmdldChcIiwgcHRyU3RyLCBcIilcIl0uam9pbihcIlwiKSlcclxuICAgICAgICAgICAgfSovXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImN3aXNlOiBHZW5lcmljIGFycmF5cyBub3Qgc3VwcG9ydGVkIGluIGNvbWJpbmF0aW9uIHdpdGggYmxvY2tzIVwiKVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gVGhpcyBkb2VzIG5vdCBwcm9kdWNlIGFueSBsb2NhbCB2YXJpYWJsZXMsIGV2ZW4gaWYgdmFyaWFibGVzIGFyZSB1c2VkIG11bHRpcGxlIHRpbWVzLiBJdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBkbyBzbywgYnV0IGl0IHdvdWxkIGNvbXBsaWNhdGUgdGhpbmdzIHF1aXRlIGEgYml0LlxyXG4gICAgICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKHJlLCBbYXJyU3RyLCBcIltcIiwgcHRyU3RyLCBcIl1cIl0uam9pbihcIlwiKSlcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIGJyZWFrXHJcbiAgICAgIGNhc2UgXCJzY2FsYXJcIjpcclxuICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKHJlLCBcIllcIiArIHByb2Muc2NhbGFyQXJncy5pbmRleE9mKGkpKVxyXG4gICAgICBicmVha1xyXG4gICAgICBjYXNlIFwiaW5kZXhcIjpcclxuICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKHJlLCBcImluZGV4XCIpXHJcbiAgICAgIGJyZWFrXHJcbiAgICAgIGNhc2UgXCJzaGFwZVwiOlxyXG4gICAgICAgIGNvZGUgPSBjb2RlLnJlcGxhY2UocmUsIFwic2hhcGVcIilcclxuICAgICAgYnJlYWtcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIFtwcmUuam9pbihcIlxcblwiKSwgY29kZSwgcG9zdC5qb2luKFwiXFxuXCIpXS5qb2luKFwiXFxuXCIpLnRyaW0oKVxyXG59XHJcblxyXG5mdW5jdGlvbiB0eXBlU3VtbWFyeShkdHlwZXMpIHtcclxuICB2YXIgc3VtbWFyeSA9IG5ldyBBcnJheShkdHlwZXMubGVuZ3RoKVxyXG4gIHZhciBhbGxFcXVhbCA9IHRydWVcclxuICBmb3IodmFyIGk9MDsgaTxkdHlwZXMubGVuZ3RoOyArK2kpIHtcclxuICAgIHZhciB0ID0gZHR5cGVzW2ldXHJcbiAgICB2YXIgZGlnaXRzID0gdC5tYXRjaCgvXFxkKy8pXHJcbiAgICBpZighZGlnaXRzKSB7XHJcbiAgICAgIGRpZ2l0cyA9IFwiXCJcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGRpZ2l0cyA9IGRpZ2l0c1swXVxyXG4gICAgfVxyXG4gICAgaWYodC5jaGFyQXQoMCkgPT09IDApIHtcclxuICAgICAgc3VtbWFyeVtpXSA9IFwidVwiICsgdC5jaGFyQXQoMSkgKyBkaWdpdHNcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHN1bW1hcnlbaV0gPSB0LmNoYXJBdCgwKSArIGRpZ2l0c1xyXG4gICAgfVxyXG4gICAgaWYoaSA+IDApIHtcclxuICAgICAgYWxsRXF1YWwgPSBhbGxFcXVhbCAmJiBzdW1tYXJ5W2ldID09PSBzdW1tYXJ5W2ktMV1cclxuICAgIH1cclxuICB9XHJcbiAgaWYoYWxsRXF1YWwpIHtcclxuICAgIHJldHVybiBzdW1tYXJ5WzBdXHJcbiAgfVxyXG4gIHJldHVybiBzdW1tYXJ5LmpvaW4oXCJcIilcclxufVxyXG5cclxuLy9HZW5lcmF0ZXMgYSBjd2lzZSBvcGVyYXRvclxyXG5mdW5jdGlvbiBnZW5lcmF0ZUNXaXNlT3AocHJvYywgdHlwZXNpZykge1xyXG5cclxuICAvL0NvbXB1dGUgZGltZW5zaW9uXHJcbiAgLy8gQXJyYXlzIGdldCBwdXQgZmlyc3QgaW4gdHlwZXNpZywgYW5kIHRoZXJlIGFyZSB0d28gZW50cmllcyBwZXIgYXJyYXkgKGR0eXBlIGFuZCBvcmRlciksIHNvIHRoaXMgZ2V0cyB0aGUgbnVtYmVyIG9mIGRpbWVuc2lvbnMgaW4gdGhlIGZpcnN0IGFycmF5IGFyZy5cclxuICB2YXIgZGltZW5zaW9uID0gKHR5cGVzaWdbMV0ubGVuZ3RoIC0gTWF0aC5hYnMocHJvYy5hcnJheUJsb2NrSW5kaWNlc1swXSkpfDBcclxuICB2YXIgb3JkZXJzID0gbmV3IEFycmF5KHByb2MuYXJyYXlBcmdzLmxlbmd0aClcclxuICB2YXIgZHR5cGVzID0gbmV3IEFycmF5KHByb2MuYXJyYXlBcmdzLmxlbmd0aClcclxuICBmb3IodmFyIGk9MDsgaTxwcm9jLmFycmF5QXJncy5sZW5ndGg7ICsraSkge1xyXG4gICAgZHR5cGVzW2ldID0gdHlwZXNpZ1syKmldXHJcbiAgICBvcmRlcnNbaV0gPSB0eXBlc2lnWzIqaSsxXVxyXG4gIH1cclxuICBcclxuICAvL0RldGVybWluZSB3aGVyZSBibG9jayBhbmQgbG9vcCBpbmRpY2VzIHN0YXJ0IGFuZCBlbmRcclxuICB2YXIgYmxvY2tCZWdpbiA9IFtdLCBibG9ja0VuZCA9IFtdIC8vIFRoZXNlIGluZGljZXMgYXJlIGV4cG9zZWQgYXMgYmxvY2tzXHJcbiAgdmFyIGxvb3BCZWdpbiA9IFtdLCBsb29wRW5kID0gW10gLy8gVGhlc2UgaW5kaWNlcyBhcmUgaXRlcmF0ZWQgb3ZlclxyXG4gIHZhciBsb29wT3JkZXJzID0gW10gLy8gb3JkZXJzIHJlc3RyaWN0ZWQgdG8gdGhlIGxvb3AgaW5kaWNlc1xyXG4gIGZvcih2YXIgaT0wOyBpPHByb2MuYXJyYXlBcmdzLmxlbmd0aDsgKytpKSB7XHJcbiAgICBpZiAocHJvYy5hcnJheUJsb2NrSW5kaWNlc1tpXTwwKSB7XHJcbiAgICAgIGxvb3BCZWdpbi5wdXNoKDApXHJcbiAgICAgIGxvb3BFbmQucHVzaChkaW1lbnNpb24pXHJcbiAgICAgIGJsb2NrQmVnaW4ucHVzaChkaW1lbnNpb24pXHJcbiAgICAgIGJsb2NrRW5kLnB1c2goZGltZW5zaW9uK3Byb2MuYXJyYXlCbG9ja0luZGljZXNbaV0pXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsb29wQmVnaW4ucHVzaChwcm9jLmFycmF5QmxvY2tJbmRpY2VzW2ldKSAvLyBOb24tbmVnYXRpdmVcclxuICAgICAgbG9vcEVuZC5wdXNoKHByb2MuYXJyYXlCbG9ja0luZGljZXNbaV0rZGltZW5zaW9uKVxyXG4gICAgICBibG9ja0JlZ2luLnB1c2goMClcclxuICAgICAgYmxvY2tFbmQucHVzaChwcm9jLmFycmF5QmxvY2tJbmRpY2VzW2ldKVxyXG4gICAgfVxyXG4gICAgdmFyIG5ld09yZGVyID0gW11cclxuICAgIGZvcih2YXIgaj0wOyBqPG9yZGVyc1tpXS5sZW5ndGg7IGorKykge1xyXG4gICAgICBpZiAobG9vcEJlZ2luW2ldPD1vcmRlcnNbaV1bal0gJiYgb3JkZXJzW2ldW2pdPGxvb3BFbmRbaV0pIHtcclxuICAgICAgICBuZXdPcmRlci5wdXNoKG9yZGVyc1tpXVtqXS1sb29wQmVnaW5baV0pIC8vIElmIHRoaXMgaXMgYSBsb29wIGluZGV4LCBwdXQgaXQgaW4gbmV3T3JkZXIsIHN1YnRyYWN0aW5nIGxvb3BCZWdpbiwgdG8gbWFrZSBzdXJlIHRoYXQgYWxsIGxvb3BPcmRlcnMgYXJlIHVzaW5nIGEgY29tbW9uIHNldCBvZiBpbmRpY2VzLlxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBsb29wT3JkZXJzLnB1c2gobmV3T3JkZXIpXHJcbiAgfVxyXG5cclxuICAvL0ZpcnN0IGNyZWF0ZSBhcmd1bWVudHMgZm9yIHByb2NlZHVyZVxyXG4gIHZhciBhcmdsaXN0ID0gW1wiU1NcIl0gLy8gU1MgaXMgdGhlIG92ZXJhbGwgc2hhcGUgb3ZlciB3aGljaCB3ZSBpdGVyYXRlXHJcbiAgdmFyIGNvZGUgPSBbXCIndXNlIHN0cmljdCdcIl1cclxuICB2YXIgdmFycyA9IFtdXHJcbiAgXHJcbiAgZm9yKHZhciBqPTA7IGo8ZGltZW5zaW9uOyArK2opIHtcclxuICAgIHZhcnMucHVzaChbXCJzXCIsIGosIFwiPVNTW1wiLCBqLCBcIl1cIl0uam9pbihcIlwiKSkgLy8gVGhlIGxpbWl0cyBmb3IgZWFjaCBkaW1lbnNpb24uXHJcbiAgfVxyXG4gIGZvcih2YXIgaT0wOyBpPHByb2MuYXJyYXlBcmdzLmxlbmd0aDsgKytpKSB7XHJcbiAgICBhcmdsaXN0LnB1c2goXCJhXCIraSkgLy8gQWN0dWFsIGRhdGEgYXJyYXlcclxuICAgIGFyZ2xpc3QucHVzaChcInRcIitpKSAvLyBTdHJpZGVzXHJcbiAgICBhcmdsaXN0LnB1c2goXCJwXCIraSkgLy8gT2Zmc2V0IGluIHRoZSBhcnJheSBhdCB3aGljaCB0aGUgZGF0YSBzdGFydHMgKGFsc28gdXNlZCBmb3IgaXRlcmF0aW5nIG92ZXIgdGhlIGRhdGEpXHJcbiAgICBcclxuICAgIGZvcih2YXIgaj0wOyBqPGRpbWVuc2lvbjsgKytqKSB7IC8vIFVucGFjayB0aGUgc3RyaWRlcyBpbnRvIHZhcnMgZm9yIGxvb3BpbmdcclxuICAgICAgdmFycy5wdXNoKFtcInRcIixpLFwicFwiLGosXCI9dFwiLGksXCJbXCIsbG9vcEJlZ2luW2ldK2osXCJdXCJdLmpvaW4oXCJcIikpXHJcbiAgICB9XHJcbiAgICBcclxuICAgIGZvcih2YXIgaj0wOyBqPE1hdGguYWJzKHByb2MuYXJyYXlCbG9ja0luZGljZXNbaV0pOyArK2opIHsgLy8gVW5wYWNrIHRoZSBzdHJpZGVzIGludG8gdmFycyBmb3IgYmxvY2sgaXRlcmF0aW9uXHJcbiAgICAgIHZhcnMucHVzaChbXCJ0XCIsaSxcImJcIixqLFwiPXRcIixpLFwiW1wiLGJsb2NrQmVnaW5baV0raixcIl1cIl0uam9pbihcIlwiKSlcclxuICAgIH1cclxuICB9XHJcbiAgZm9yKHZhciBpPTA7IGk8cHJvYy5zY2FsYXJBcmdzLmxlbmd0aDsgKytpKSB7XHJcbiAgICBhcmdsaXN0LnB1c2goXCJZXCIgKyBpKVxyXG4gIH1cclxuICBpZihwcm9jLnNoYXBlQXJncy5sZW5ndGggPiAwKSB7XHJcbiAgICB2YXJzLnB1c2goXCJzaGFwZT1TUy5zbGljZSgwKVwiKSAvLyBNYWtlcyB0aGUgc2hhcGUgb3ZlciB3aGljaCB3ZSBpdGVyYXRlIGF2YWlsYWJsZSB0byB0aGUgdXNlciBkZWZpbmVkIGZ1bmN0aW9ucyAoc28geW91IGNhbiB1c2Ugd2lkdGgvaGVpZ2h0IGZvciBleGFtcGxlKVxyXG4gIH1cclxuICBpZihwcm9jLmluZGV4QXJncy5sZW5ndGggPiAwKSB7XHJcbiAgICAvLyBQcmVwYXJlIGFuIGFycmF5IHRvIGtlZXAgdHJhY2sgb2YgdGhlIChsb2dpY2FsKSBpbmRpY2VzLCBpbml0aWFsaXplZCB0byBkaW1lbnNpb24gemVyb2VzLlxyXG4gICAgdmFyIHplcm9zID0gbmV3IEFycmF5KGRpbWVuc2lvbilcclxuICAgIGZvcih2YXIgaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7XHJcbiAgICAgIHplcm9zW2ldID0gXCIwXCJcclxuICAgIH1cclxuICAgIHZhcnMucHVzaChbXCJpbmRleD1bXCIsIHplcm9zLmpvaW4oXCIsXCIpLCBcIl1cIl0uam9pbihcIlwiKSlcclxuICB9XHJcbiAgZm9yKHZhciBpPTA7IGk8cHJvYy5vZmZzZXRBcmdzLmxlbmd0aDsgKytpKSB7IC8vIE9mZnNldCBhcmd1bWVudHMgdXNlZCBmb3Igc3RlbmNpbCBvcGVyYXRpb25zXHJcbiAgICB2YXIgb2ZmX2FyZyA9IHByb2Mub2Zmc2V0QXJnc1tpXVxyXG4gICAgdmFyIGluaXRfc3RyaW5nID0gW11cclxuICAgIGZvcih2YXIgaj0wOyBqPG9mZl9hcmcub2Zmc2V0Lmxlbmd0aDsgKytqKSB7XHJcbiAgICAgIGlmKG9mZl9hcmcub2Zmc2V0W2pdID09PSAwKSB7XHJcbiAgICAgICAgY29udGludWVcclxuICAgICAgfSBlbHNlIGlmKG9mZl9hcmcub2Zmc2V0W2pdID09PSAxKSB7XHJcbiAgICAgICAgaW5pdF9zdHJpbmcucHVzaChbXCJ0XCIsIG9mZl9hcmcuYXJyYXksIFwicFwiLCBqXS5qb2luKFwiXCIpKSAgICAgIFxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGluaXRfc3RyaW5nLnB1c2goW29mZl9hcmcub2Zmc2V0W2pdLCBcIip0XCIsIG9mZl9hcmcuYXJyYXksIFwicFwiLCBqXS5qb2luKFwiXCIpKVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZihpbml0X3N0cmluZy5sZW5ndGggPT09IDApIHtcclxuICAgICAgdmFycy5wdXNoKFwicVwiICsgaSArIFwiPTBcIilcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHZhcnMucHVzaChbXCJxXCIsIGksIFwiPVwiLCBpbml0X3N0cmluZy5qb2luKFwiK1wiKV0uam9pbihcIlwiKSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vUHJlcGFyZSB0aGlzIHZhcmlhYmxlc1xyXG4gIHZhciB0aGlzVmFycyA9IHVuaXEoW10uY29uY2F0KHByb2MucHJlLnRoaXNWYXJzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChwcm9jLmJvZHkudGhpc1ZhcnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KHByb2MucG9zdC50aGlzVmFycykpXHJcbiAgdmFycyA9IHZhcnMuY29uY2F0KHRoaXNWYXJzKVxyXG4gIGNvZGUucHVzaChcInZhciBcIiArIHZhcnMuam9pbihcIixcIikpXHJcbiAgZm9yKHZhciBpPTA7IGk8cHJvYy5hcnJheUFyZ3MubGVuZ3RoOyArK2kpIHtcclxuICAgIGNvZGUucHVzaChcInBcIitpK1wifD0wXCIpXHJcbiAgfVxyXG4gIFxyXG4gIC8vSW5saW5lIHByZWx1ZGVcclxuICBpZihwcm9jLnByZS5ib2R5Lmxlbmd0aCA+IDMpIHtcclxuICAgIGNvZGUucHVzaChwcm9jZXNzQmxvY2socHJvYy5wcmUsIHByb2MsIGR0eXBlcykpXHJcbiAgfVxyXG5cclxuICAvL1Byb2Nlc3MgYm9keVxyXG4gIHZhciBib2R5ID0gcHJvY2Vzc0Jsb2NrKHByb2MuYm9keSwgcHJvYywgZHR5cGVzKVxyXG4gIHZhciBtYXRjaGVkID0gY291bnRNYXRjaGVzKGxvb3BPcmRlcnMpXHJcbiAgaWYobWF0Y2hlZCA8IGRpbWVuc2lvbikge1xyXG4gICAgY29kZS5wdXNoKG91dGVyRmlsbChtYXRjaGVkLCBsb29wT3JkZXJzWzBdLCBwcm9jLCBib2R5KSkgLy8gVE9ETzogUmF0aGVyIHRoYW4gcGFzc2luZyBsb29wT3JkZXJzWzBdLCBpdCBtaWdodCBiZSBpbnRlcmVzdGluZyB0byBsb29rIGF0IHBhc3NpbmcgYW4gb3JkZXIgdGhhdCByZXByZXNlbnRzIHRoZSBtYWpvcml0eSBvZiB0aGUgYXJndW1lbnRzIGZvciBleGFtcGxlLlxyXG4gIH0gZWxzZSB7XHJcbiAgICBjb2RlLnB1c2goaW5uZXJGaWxsKGxvb3BPcmRlcnNbMF0sIHByb2MsIGJvZHkpKVxyXG4gIH1cclxuXHJcbiAgLy9JbmxpbmUgZXBpbG9nXHJcbiAgaWYocHJvYy5wb3N0LmJvZHkubGVuZ3RoID4gMykge1xyXG4gICAgY29kZS5wdXNoKHByb2Nlc3NCbG9jayhwcm9jLnBvc3QsIHByb2MsIGR0eXBlcykpXHJcbiAgfVxyXG4gIFxyXG4gIGlmKHByb2MuZGVidWcpIHtcclxuICAgIGNvbnNvbGUubG9nKFwiLS0tLS1HZW5lcmF0ZWQgY3dpc2Ugcm91dGluZSBmb3IgXCIsIHR5cGVzaWcsIFwiOlxcblwiICsgY29kZS5qb2luKFwiXFxuXCIpICsgXCJcXG4tLS0tLS0tLS0tXCIpXHJcbiAgfVxyXG4gIFxyXG4gIHZhciBsb29wTmFtZSA9IFsocHJvYy5mdW5jTmFtZXx8XCJ1bm5hbWVkXCIpLCBcIl9jd2lzZV9sb29wX1wiLCBvcmRlcnNbMF0uam9pbihcInNcIiksXCJtXCIsbWF0Y2hlZCx0eXBlU3VtbWFyeShkdHlwZXMpXS5qb2luKFwiXCIpXHJcbiAgdmFyIGYgPSBuZXcgRnVuY3Rpb24oW1wiZnVuY3Rpb24gXCIsbG9vcE5hbWUsXCIoXCIsIGFyZ2xpc3Quam9pbihcIixcIiksXCIpe1wiLCBjb2RlLmpvaW4oXCJcXG5cIiksXCJ9IHJldHVybiBcIiwgbG9vcE5hbWVdLmpvaW4oXCJcIikpXHJcbiAgcmV0dXJuIGYoKVxyXG59XHJcbm1vZHVsZS5leHBvcnRzID0gZ2VuZXJhdGVDV2lzZU9wXHJcbiIsIlwidXNlIHN0cmljdFwiXHJcblxyXG4vLyBUaGUgZnVuY3Rpb24gYmVsb3cgaXMgY2FsbGVkIHdoZW4gY29uc3RydWN0aW5nIGEgY3dpc2UgZnVuY3Rpb24gb2JqZWN0LCBhbmQgZG9lcyB0aGUgZm9sbG93aW5nOlxyXG4vLyBBIGZ1bmN0aW9uIG9iamVjdCBpcyBjb25zdHJ1Y3RlZCB3aGljaCBhY2NlcHRzIGFzIGFyZ3VtZW50IGEgY29tcGlsYXRpb24gZnVuY3Rpb24gYW5kIHJldHVybnMgYW5vdGhlciBmdW5jdGlvbi5cclxuLy8gSXQgaXMgdGhpcyBvdGhlciBmdW5jdGlvbiB0aGF0IGlzIGV2ZW50dWFsbHkgcmV0dXJuZWQgYnkgY3JlYXRlVGh1bmssIGFuZCB0aGlzIGZ1bmN0aW9uIGlzIHRoZSBvbmUgdGhhdCBhY3R1YWxseVxyXG4vLyBjaGVja3Mgd2hldGhlciBhIGNlcnRhaW4gcGF0dGVybiBvZiBhcmd1bWVudHMgaGFzIGFscmVhZHkgYmVlbiB1c2VkIGJlZm9yZSBhbmQgY29tcGlsZXMgbmV3IGxvb3BzIGFzIG5lZWRlZC5cclxuLy8gVGhlIGNvbXBpbGF0aW9uIHBhc3NlZCB0byB0aGUgZmlyc3QgZnVuY3Rpb24gb2JqZWN0IGlzIHVzZWQgZm9yIGNvbXBpbGluZyBuZXcgZnVuY3Rpb25zLlxyXG4vLyBPbmNlIHRoaXMgZnVuY3Rpb24gb2JqZWN0IGlzIGNyZWF0ZWQsIGl0IGlzIGNhbGxlZCB3aXRoIGNvbXBpbGUgYXMgYXJndW1lbnQsIHdoZXJlIHRoZSBmaXJzdCBhcmd1bWVudCBvZiBjb21waWxlXHJcbi8vIGlzIGJvdW5kIHRvIFwicHJvY1wiIChlc3NlbnRpYWxseSBjb250YWluaW5nIGEgcHJlcHJvY2Vzc2VkIHZlcnNpb24gb2YgdGhlIHVzZXIgYXJndW1lbnRzIHRvIGN3aXNlKS5cclxuLy8gU28gY3JlYXRlVGh1bmsgcm91Z2hseSB3b3JrcyBsaWtlIHRoaXM6XHJcbi8vIGZ1bmN0aW9uIGNyZWF0ZVRodW5rKHByb2MpIHtcclxuLy8gICB2YXIgdGh1bmsgPSBmdW5jdGlvbihjb21waWxlQm91bmQpIHtcclxuLy8gICAgIHZhciBDQUNIRUQgPSB7fVxyXG4vLyAgICAgcmV0dXJuIGZ1bmN0aW9uKGFycmF5cyBhbmQgc2NhbGFycykge1xyXG4vLyAgICAgICBpZiAoZHR5cGUgYW5kIG9yZGVyIG9mIGFycmF5cyBpbiBDQUNIRUQpIHtcclxuLy8gICAgICAgICB2YXIgZnVuYyA9IENBQ0hFRFtkdHlwZSBhbmQgb3JkZXIgb2YgYXJyYXlzXVxyXG4vLyAgICAgICB9IGVsc2Uge1xyXG4vLyAgICAgICAgIHZhciBmdW5jID0gQ0FDSEVEW2R0eXBlIGFuZCBvcmRlciBvZiBhcnJheXNdID0gY29tcGlsZUJvdW5kKGR0eXBlIGFuZCBvcmRlciBvZiBhcnJheXMpXHJcbi8vICAgICAgIH1cclxuLy8gICAgICAgcmV0dXJuIGZ1bmMoYXJyYXlzIGFuZCBzY2FsYXJzKVxyXG4vLyAgICAgfVxyXG4vLyAgIH1cclxuLy8gICByZXR1cm4gdGh1bmsoY29tcGlsZS5iaW5kMShwcm9jKSlcclxuLy8gfVxyXG5cclxudmFyIGNvbXBpbGUgPSByZXF1aXJlKFwiLi9jb21waWxlLmpzXCIpXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVUaHVuayhwcm9jKSB7XHJcbiAgdmFyIGNvZGUgPSBbXCIndXNlIHN0cmljdCdcIiwgXCJ2YXIgQ0FDSEVEPXt9XCJdXHJcbiAgdmFyIHZhcnMgPSBbXVxyXG4gIHZhciB0aHVua05hbWUgPSBwcm9jLmZ1bmNOYW1lICsgXCJfY3dpc2VfdGh1bmtcIlxyXG4gIFxyXG4gIC8vQnVpbGQgdGh1bmtcclxuICBjb2RlLnB1c2goW1wicmV0dXJuIGZ1bmN0aW9uIFwiLCB0aHVua05hbWUsIFwiKFwiLCBwcm9jLnNoaW1BcmdzLmpvaW4oXCIsXCIpLCBcIil7XCJdLmpvaW4oXCJcIikpXHJcbiAgdmFyIHR5cGVzaWcgPSBbXVxyXG4gIHZhciBzdHJpbmdfdHlwZXNpZyA9IFtdXHJcbiAgdmFyIHByb2NfYXJncyA9IFtbXCJhcnJheVwiLHByb2MuYXJyYXlBcmdzWzBdLFwiLnNoYXBlLnNsaWNlKFwiLCAvLyBTbGljZSBzaGFwZSBzbyB0aGF0IHdlIG9ubHkgcmV0YWluIHRoZSBzaGFwZSBvdmVyIHdoaWNoIHdlIGl0ZXJhdGUgKHdoaWNoIGdldHMgcGFzc2VkIHRvIHRoZSBjd2lzZSBvcGVyYXRvciBhcyBTUykuXHJcbiAgICAgICAgICAgICAgICAgICAgTWF0aC5tYXgoMCxwcm9jLmFycmF5QmxvY2tJbmRpY2VzWzBdKSxwcm9jLmFycmF5QmxvY2tJbmRpY2VzWzBdPDA/KFwiLFwiK3Byb2MuYXJyYXlCbG9ja0luZGljZXNbMF0rXCIpXCIpOlwiKVwiXS5qb2luKFwiXCIpXVxyXG4gIHZhciBzaGFwZUxlbmd0aENvbmRpdGlvbnMgPSBbXSwgc2hhcGVDb25kaXRpb25zID0gW11cclxuICAvLyBQcm9jZXNzIGFycmF5IGFyZ3VtZW50c1xyXG4gIGZvcih2YXIgaT0wOyBpPHByb2MuYXJyYXlBcmdzLmxlbmd0aDsgKytpKSB7XHJcbiAgICB2YXIgaiA9IHByb2MuYXJyYXlBcmdzW2ldXHJcbiAgICB2YXJzLnB1c2goW1widFwiLCBqLCBcIj1hcnJheVwiLCBqLCBcIi5kdHlwZSxcIixcclxuICAgICAgICAgICAgICAgXCJyXCIsIGosIFwiPWFycmF5XCIsIGosIFwiLm9yZGVyXCJdLmpvaW4oXCJcIikpXHJcbiAgICB0eXBlc2lnLnB1c2goXCJ0XCIgKyBqKVxyXG4gICAgdHlwZXNpZy5wdXNoKFwiclwiICsgailcclxuICAgIHN0cmluZ190eXBlc2lnLnB1c2goXCJ0XCIrailcclxuICAgIHN0cmluZ190eXBlc2lnLnB1c2goXCJyXCIraitcIi5qb2luKClcIilcclxuICAgIHByb2NfYXJncy5wdXNoKFwiYXJyYXlcIiArIGogKyBcIi5kYXRhXCIpXHJcbiAgICBwcm9jX2FyZ3MucHVzaChcImFycmF5XCIgKyBqICsgXCIuc3RyaWRlXCIpXHJcbiAgICBwcm9jX2FyZ3MucHVzaChcImFycmF5XCIgKyBqICsgXCIub2Zmc2V0fDBcIilcclxuICAgIGlmIChpPjApIHsgLy8gR2F0aGVyIGNvbmRpdGlvbnMgdG8gY2hlY2sgZm9yIHNoYXBlIGVxdWFsaXR5IChpZ25vcmluZyBibG9jayBpbmRpY2VzKVxyXG4gICAgICBzaGFwZUxlbmd0aENvbmRpdGlvbnMucHVzaChcImFycmF5XCIgKyBwcm9jLmFycmF5QXJnc1swXSArIFwiLnNoYXBlLmxlbmd0aD09PWFycmF5XCIgKyBqICsgXCIuc2hhcGUubGVuZ3RoK1wiICsgKE1hdGguYWJzKHByb2MuYXJyYXlCbG9ja0luZGljZXNbMF0pLU1hdGguYWJzKHByb2MuYXJyYXlCbG9ja0luZGljZXNbaV0pKSlcclxuICAgICAgc2hhcGVDb25kaXRpb25zLnB1c2goXCJhcnJheVwiICsgcHJvYy5hcnJheUFyZ3NbMF0gKyBcIi5zaGFwZVtzaGFwZUluZGV4K1wiICsgTWF0aC5tYXgoMCxwcm9jLmFycmF5QmxvY2tJbmRpY2VzWzBdKSArIFwiXT09PWFycmF5XCIgKyBqICsgXCIuc2hhcGVbc2hhcGVJbmRleCtcIiArIE1hdGgubWF4KDAscHJvYy5hcnJheUJsb2NrSW5kaWNlc1tpXSkgKyBcIl1cIilcclxuICAgIH1cclxuICB9XHJcbiAgLy8gQ2hlY2sgZm9yIHNoYXBlIGVxdWFsaXR5XHJcbiAgaWYgKHByb2MuYXJyYXlBcmdzLmxlbmd0aCA+IDEpIHtcclxuICAgIGNvZGUucHVzaChcImlmICghKFwiICsgc2hhcGVMZW5ndGhDb25kaXRpb25zLmpvaW4oXCIgJiYgXCIpICsgXCIpKSB0aHJvdyBuZXcgRXJyb3IoJ2N3aXNlOiBBcnJheXMgZG8gbm90IGFsbCBoYXZlIHRoZSBzYW1lIGRpbWVuc2lvbmFsaXR5IScpXCIpXHJcbiAgICBjb2RlLnB1c2goXCJmb3IodmFyIHNoYXBlSW5kZXg9YXJyYXlcIiArIHByb2MuYXJyYXlBcmdzWzBdICsgXCIuc2hhcGUubGVuZ3RoLVwiICsgTWF0aC5hYnMocHJvYy5hcnJheUJsb2NrSW5kaWNlc1swXSkgKyBcIjsgc2hhcGVJbmRleC0tPjA7KSB7XCIpXHJcbiAgICBjb2RlLnB1c2goXCJpZiAoIShcIiArIHNoYXBlQ29uZGl0aW9ucy5qb2luKFwiICYmIFwiKSArIFwiKSkgdGhyb3cgbmV3IEVycm9yKCdjd2lzZTogQXJyYXlzIGRvIG5vdCBhbGwgaGF2ZSB0aGUgc2FtZSBzaGFwZSEnKVwiKVxyXG4gICAgY29kZS5wdXNoKFwifVwiKVxyXG4gIH1cclxuICAvLyBQcm9jZXNzIHNjYWxhciBhcmd1bWVudHNcclxuICBmb3IodmFyIGk9MDsgaTxwcm9jLnNjYWxhckFyZ3MubGVuZ3RoOyArK2kpIHtcclxuICAgIHByb2NfYXJncy5wdXNoKFwic2NhbGFyXCIgKyBwcm9jLnNjYWxhckFyZ3NbaV0pXHJcbiAgfVxyXG4gIC8vIENoZWNrIGZvciBjYWNoZWQgZnVuY3Rpb24gKGFuZCBpZiBub3QgcHJlc2VudCwgZ2VuZXJhdGUgaXQpXHJcbiAgdmFycy5wdXNoKFtcInR5cGU9W1wiLCBzdHJpbmdfdHlwZXNpZy5qb2luKFwiLFwiKSwgXCJdLmpvaW4oKVwiXS5qb2luKFwiXCIpKVxyXG4gIHZhcnMucHVzaChcInByb2M9Q0FDSEVEW3R5cGVdXCIpXHJcbiAgY29kZS5wdXNoKFwidmFyIFwiICsgdmFycy5qb2luKFwiLFwiKSlcclxuICBcclxuICBjb2RlLnB1c2goW1wiaWYoIXByb2Mpe1wiLFxyXG4gICAgICAgICAgICAgXCJDQUNIRURbdHlwZV09cHJvYz1jb21waWxlKFtcIiwgdHlwZXNpZy5qb2luKFwiLFwiKSwgXCJdKX1cIixcclxuICAgICAgICAgICAgIFwicmV0dXJuIHByb2MoXCIsIHByb2NfYXJncy5qb2luKFwiLFwiKSwgXCIpfVwiXS5qb2luKFwiXCIpKVxyXG5cclxuICBpZihwcm9jLmRlYnVnKSB7XHJcbiAgICBjb25zb2xlLmxvZyhcIi0tLS0tR2VuZXJhdGVkIHRodW5rOlxcblwiICsgY29kZS5qb2luKFwiXFxuXCIpICsgXCJcXG4tLS0tLS0tLS0tXCIpXHJcbiAgfVxyXG4gIFxyXG4gIC8vQ29tcGlsZSB0aHVua1xyXG4gIHZhciB0aHVuayA9IG5ldyBGdW5jdGlvbihcImNvbXBpbGVcIiwgY29kZS5qb2luKFwiXFxuXCIpKVxyXG4gIHJldHVybiB0aHVuayhjb21waWxlLmJpbmQodW5kZWZpbmVkLCBwcm9jKSlcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVUaHVua1xyXG4iLCJcInVzZSBzdHJpY3RcIlxuXG5mdW5jdGlvbiB1bmlxdWVfcHJlZChsaXN0LCBjb21wYXJlKSB7XG4gIHZhciBwdHIgPSAxXG4gICAgLCBsZW4gPSBsaXN0Lmxlbmd0aFxuICAgICwgYT1saXN0WzBdLCBiPWxpc3RbMF1cbiAgZm9yKHZhciBpPTE7IGk8bGVuOyArK2kpIHtcbiAgICBiID0gYVxuICAgIGEgPSBsaXN0W2ldXG4gICAgaWYoY29tcGFyZShhLCBiKSkge1xuICAgICAgaWYoaSA9PT0gcHRyKSB7XG4gICAgICAgIHB0cisrXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBsaXN0W3B0cisrXSA9IGFcbiAgICB9XG4gIH1cbiAgbGlzdC5sZW5ndGggPSBwdHJcbiAgcmV0dXJuIGxpc3Rcbn1cblxuZnVuY3Rpb24gdW5pcXVlX2VxKGxpc3QpIHtcbiAgdmFyIHB0ciA9IDFcbiAgICAsIGxlbiA9IGxpc3QubGVuZ3RoXG4gICAgLCBhPWxpc3RbMF0sIGIgPSBsaXN0WzBdXG4gIGZvcih2YXIgaT0xOyBpPGxlbjsgKytpLCBiPWEpIHtcbiAgICBiID0gYVxuICAgIGEgPSBsaXN0W2ldXG4gICAgaWYoYSAhPT0gYikge1xuICAgICAgaWYoaSA9PT0gcHRyKSB7XG4gICAgICAgIHB0cisrXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBsaXN0W3B0cisrXSA9IGFcbiAgICB9XG4gIH1cbiAgbGlzdC5sZW5ndGggPSBwdHJcbiAgcmV0dXJuIGxpc3Rcbn1cblxuZnVuY3Rpb24gdW5pcXVlKGxpc3QsIGNvbXBhcmUsIHNvcnRlZCkge1xuICBpZihsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBsaXN0XG4gIH1cbiAgaWYoY29tcGFyZSkge1xuICAgIGlmKCFzb3J0ZWQpIHtcbiAgICAgIGxpc3Quc29ydChjb21wYXJlKVxuICAgIH1cbiAgICByZXR1cm4gdW5pcXVlX3ByZWQobGlzdCwgY29tcGFyZSlcbiAgfVxuICBpZighc29ydGVkKSB7XG4gICAgbGlzdC5zb3J0KClcbiAgfVxuICByZXR1cm4gdW5pcXVlX2VxKGxpc3QpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gdW5pcXVlXG4iLCJcInVzZSBzdHJpY3RcIlxuXG5cblxudmFyIGZpbGwgPSByZXF1aXJlKCdjd2lzZS9saWIvd3JhcHBlcicpKHtcImFyZ3NcIjpbXCJpbmRleFwiLFwiYXJyYXlcIixcInNjYWxhclwiXSxcInByZVwiOntcImJvZHlcIjpcInt9XCIsXCJhcmdzXCI6W10sXCJ0aGlzVmFyc1wiOltdLFwibG9jYWxWYXJzXCI6W119LFwiYm9keVwiOntcImJvZHlcIjpcIntfaW5saW5lXzFfYXJnMV89X2lubGluZV8xX2FyZzJfLmFwcGx5KHZvaWQgMCxfaW5saW5lXzFfYXJnMF8pfVwiLFwiYXJnc1wiOlt7XCJuYW1lXCI6XCJfaW5saW5lXzFfYXJnMF9cIixcImx2YWx1ZVwiOmZhbHNlLFwicnZhbHVlXCI6dHJ1ZSxcImNvdW50XCI6MX0se1wibmFtZVwiOlwiX2lubGluZV8xX2FyZzFfXCIsXCJsdmFsdWVcIjp0cnVlLFwicnZhbHVlXCI6ZmFsc2UsXCJjb3VudFwiOjF9LHtcIm5hbWVcIjpcIl9pbmxpbmVfMV9hcmcyX1wiLFwibHZhbHVlXCI6ZmFsc2UsXCJydmFsdWVcIjp0cnVlLFwiY291bnRcIjoxfV0sXCJ0aGlzVmFyc1wiOltdLFwibG9jYWxWYXJzXCI6W119LFwicG9zdFwiOntcImJvZHlcIjpcInt9XCIsXCJhcmdzXCI6W10sXCJ0aGlzVmFyc1wiOltdLFwibG9jYWxWYXJzXCI6W119LFwiZGVidWdcIjpmYWxzZSxcImZ1bmNOYW1lXCI6XCJjd2lzZVwiLFwiYmxvY2tTaXplXCI6NjR9KVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGFycmF5LCBmKSB7XG4gIGZpbGwoYXJyYXksIGYpXG4gIHJldHVybiBhcnJheVxufVxuIl19
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"marching-squares":[function(require,module,exports){
'use strict';
/**
* @module marching-squares
*/
// [dx, dy, is-down-or-right?0:1]
var UP = [0,-1,1],
DOWN = [0,1,0],
LEFT = [-1,0,1],
RIGHT = [1,0,0];
// There are 16 possible 2-by-2 square configurations.
// We number them by adding the shown value when the cell in the square is in the region.
//
// ----------------
// |x-1,y-1| x,y-1|
// | 1 | 2 |
// |---------------
// | x-1,y | x,y |
// | 4 | 8 |
// ----------------
//
// The transitions are designed to proceed in a clockwise direction around the region.
// Squares 6 and 9 are ambiguous cases where we need to see which direction the previous
// transition was to avoid getting caught looping around a sub-region forever.
var transitions = [
null, // 0
// [direction-if-coming-from-down-or-right, direction-if-coming-from-up-or-left]
[LEFT, LEFT], // 1
[UP, UP], // 2
[LEFT, LEFT], // 3
[DOWN, DOWN], // 4
[DOWN, DOWN], // 5
[UP, DOWN], // 6
[DOWN, DOWN], // 7
[RIGHT, RIGHT], // 8
[RIGHT, LEFT], // 9
[UP, UP], // 10
[LEFT, LEFT], // 11
[RIGHT, RIGHT], // 12
[RIGHT, RIGHT], // 13
[UP, UP] // 14
];
/**
* @alias module:marching-squares.traceImageRegion
* Trace a closed polygon around a region in a two-dimensional grid. The
* isInside function is called to determine if a given point is inside or
* outside the region.
*
* The starting point MUST be on the edge of the region. Specifically this
* means that among these four calls
* 1. isInside(x-1, y-1)
* 2. isInside(x, y-1)
* 3. isInside(x-1, y)
* 4. isInside(x,y)
* At least one must return falsy and at least one must return truthy. If
* this is not the case, an Error is thrown.
*
* An efficient marching-squares algorithm is used to trace the region,
* using minimal memory and calling isInside() only as neccessary.
*
* @param {int} x - starting x coordinate.
* @param {int} y - starting y coordinate.
* @param {function} isInside - function with signature isInside(x,y) returning
* truthy if the given point is inside the region to trace (for
* example, it is an opaque pixel in a bitmap) and falsy if it is outside
* (for example, it is transparent). The function should be able to handle
* any x and y including negative values "outside the bitmap" (for which it
* should return false).
* @returns {array[object]} array of point objects with x & y properties tracing
* a closed polygon around the region. The first point is NOT repeated
* as the last point. The polygon consists entirely of one-unit-long
* horizontal or vertical segments. Use a polygon simplification routine on
* the results to simplify and/or smooth it.
* (Might I suggest https://www.npmjs.com/package/line-simplify-rdp ?)
*/
function traceRegion(x, y, isInside) {
var startX = x, startY = y;
var ret = [{x:x, y:y}];
var dir = DOWN; // arbitrary
var square =
(isInside(x-1, y-1) ? 1 : 0) +
(isInside(x, y-1) ? 2 : 0) +
(isInside(x-1, y) ? 4 : 0) +
(isInside(x, y) ? 8 : 0);
if (square === 0 || square === 15)
throw new Error("Bad Starting point.");
while (true) {
dir = transitions[square][dir[2]];
x += dir[0];
y += dir[1];
if (x === startX && y === startY)
return ret;
ret.push({x:x, y:y});
if (dir === DOWN)
square = ((square & 12) >> 2);
else if (dir === UP)
square = ((square & 3) << 2);
else if (dir === RIGHT)
square = ((square & 10) >> 1);
else if (dir === LEFT)
square = ((square & 5) << 1);
if (dir === DOWN || dir === LEFT)
square += (isInside(x-1, y) ? 4 : 0);
else
square += (isInside(x, y-1) ? 2 : 0);
if (dir === DOWN || dir === RIGHT)
square += (isInside(x, y) ? 8 : 0);
else
square += (isInside(x-1, y-1) ? 1 : 0);
}
}
module.exports = traceRegion;
},{}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImluZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBAbW9kdWxlIG1hcmNoaW5nLXNxdWFyZXNcbiAqL1xuXG4vLyBbZHgsIGR5LCBpcy1kb3duLW9yLXJpZ2h0PzA6MV1cbnZhciBVUCA9IFswLC0xLDFdLFxuICAgIERPV04gPSBbMCwxLDBdLFxuICAgIExFRlQgPSBbLTEsMCwxXSxcbiAgICBSSUdIVCA9IFsxLDAsMF07XG5cbi8vIFRoZXJlIGFyZSAxNiBwb3NzaWJsZSAyLWJ5LTIgc3F1YXJlIGNvbmZpZ3VyYXRpb25zLlxuLy8gV2UgbnVtYmVyIHRoZW0gYnkgYWRkaW5nIHRoZSBzaG93biB2YWx1ZSB3aGVuIHRoZSBjZWxsIGluIHRoZSBzcXVhcmUgaXMgaW4gdGhlIHJlZ2lvbi5cbi8vXG4vLyAtLS0tLS0tLS0tLS0tLS0tXG4vLyB8eC0xLHktMXwgeCx5LTF8XG4vLyB8ICAgMSAgIHwgIDIgICB8XG4vLyB8LS0tLS0tLS0tLS0tLS0tXG4vLyB8IHgtMSx5IHwgeCx5ICB8XG4vLyB8ICAgNCAgIHwgIDggICB8IFxuLy8gLS0tLS0tLS0tLS0tLS0tLVxuLy9cbi8vIFRoZSB0cmFuc2l0aW9ucyBhcmUgZGVzaWduZWQgdG8gcHJvY2VlZCBpbiBhIGNsb2Nrd2lzZSBkaXJlY3Rpb24gYXJvdW5kIHRoZSByZWdpb24uXG4vLyBTcXVhcmVzIDYgYW5kIDkgYXJlIGFtYmlndW91cyBjYXNlcyB3aGVyZSB3ZSBuZWVkIHRvIHNlZSB3aGljaCBkaXJlY3Rpb24gdGhlIHByZXZpb3VzXG4vLyB0cmFuc2l0aW9uIHdhcyB0byBhdm9pZCBnZXR0aW5nIGNhdWdodCBsb29waW5nIGFyb3VuZCBhIHN1Yi1yZWdpb24gZm9yZXZlci5cblxudmFyIHRyYW5zaXRpb25zID0gW1xuICAgbnVsbCwgLy8gMFxuICAgLy8gW2RpcmVjdGlvbi1pZi1jb21pbmctZnJvbS1kb3duLW9yLXJpZ2h0LCBkaXJlY3Rpb24taWYtY29taW5nLWZyb20tdXAtb3ItbGVmdF1cbiAgIFtMRUZULCBMRUZUXSwgLy8gMVxuICAgW1VQLCBVUF0sIC8vIDJcbiAgIFtMRUZULCBMRUZUXSwgLy8gM1xuICAgW0RPV04sIERPV05dLCAgLy8gNFxuICAgW0RPV04sIERPV05dLCAgLy8gNVxuICAgW1VQLCBET1dOXSwgICAgLy8gNlxuICAgW0RPV04sIERPV05dLCAvLyA3XG4gICBbUklHSFQsIFJJR0hUXSwgLy8gOFxuICAgW1JJR0hULCBMRUZUXSwgLy8gOVxuICAgW1VQLCBVUF0sIC8vIDEwXG4gICBbTEVGVCwgTEVGVF0sIC8vIDExXG4gICBbUklHSFQsIFJJR0hUXSwgLy8gMTJcbiAgIFtSSUdIVCwgUklHSFRdLCAvLyAxM1xuICAgW1VQLCBVUF0gLy8gMTRcbl07XG5cbi8qKlxuICogQGFsaWFzIG1vZHVsZTptYXJjaGluZy1zcXVhcmVzLnRyYWNlSW1hZ2VSZWdpb25cbiAqIFRyYWNlIGEgY2xvc2VkIHBvbHlnb24gYXJvdW5kIGEgcmVnaW9uIGluIGEgdHdvLWRpbWVuc2lvbmFsIGdyaWQuIFRoZSBcbiAqIGlzSW5zaWRlIGZ1bmN0aW9uIGlzIGNhbGxlZCB0byBkZXRlcm1pbmUgaWYgYSBnaXZlbiBwb2ludCBpcyBpbnNpZGUgb3IgXG4gKiBvdXRzaWRlIHRoZSByZWdpb24uIFxuICogXG4gKiBUaGUgc3RhcnRpbmcgcG9pbnQgTVVTVCBiZSBvbiB0aGUgZWRnZSBvZiB0aGUgcmVnaW9uLiBTcGVjaWZpY2FsbHkgdGhpc1xuICogbWVhbnMgdGhhdCBhbW9uZyB0aGVzZSBmb3VyIGNhbGxzXG4gKiAxLiBpc0luc2lkZSh4LTEsIHktMSlcbiAqIDIuIGlzSW5zaWRlKHgsIHktMSlcbiAqIDMuIGlzSW5zaWRlKHgtMSwgeSlcbiAqIDQuIGlzSW5zaWRlKHgseSlcbiAqIEF0IGxlYXN0IG9uZSBtdXN0IHJldHVybiBmYWxzeSBhbmQgYXQgbGVhc3Qgb25lIG11c3QgcmV0dXJuIHRydXRoeS4gSWZcbiAqIHRoaXMgaXMgbm90IHRoZSBjYXNlLCBhbiBFcnJvciBpcyB0aHJvd24uXG4gKiBcbiAqIEFuIGVmZmljaWVudCBtYXJjaGluZy1zcXVhcmVzIGFsZ29yaXRobSBpcyB1c2VkIHRvIHRyYWNlIHRoZSByZWdpb24sXG4gKiB1c2luZyBtaW5pbWFsIG1lbW9yeSBhbmQgY2FsbGluZyBpc0luc2lkZSgpIG9ubHkgYXMgbmVjY2Vzc2FyeS5cbiAqIFxuICogQHBhcmFtIHtpbnR9IHggLSBzdGFydGluZyB4IGNvb3JkaW5hdGUuIFxuICogQHBhcmFtIHtpbnR9IHkgLSBzdGFydGluZyB5IGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBpc0luc2lkZSAtIGZ1bmN0aW9uIHdpdGggc2lnbmF0dXJlIGlzSW5zaWRlKHgseSkgcmV0dXJuaW5nICBcbiAqICAgdHJ1dGh5IGlmIHRoZSBnaXZlbiBwb2ludCBpcyBpbnNpZGUgdGhlIHJlZ2lvbiB0byB0cmFjZSAoZm9yIFxuICogICBleGFtcGxlLCBpdCBpcyBhbiBvcGFxdWUgcGl4ZWwgaW4gYSBiaXRtYXApIGFuZCBmYWxzeSBpZiBpdCBpcyBvdXRzaWRlIFxuICogICAoZm9yIGV4YW1wbGUsIGl0IGlzIHRyYW5zcGFyZW50KS4gVGhlIGZ1bmN0aW9uIHNob3VsZCBiZSBhYmxlIHRvIGhhbmRsZSBcbiAqICAgYW55IHggYW5kIHkgaW5jbHVkaW5nIG5lZ2F0aXZlIHZhbHVlcyBcIm91dHNpZGUgdGhlIGJpdG1hcFwiIChmb3Igd2hpY2ggaXRcbiAqICAgc2hvdWxkIHJldHVybiBmYWxzZSkuXG4gKiBAcmV0dXJucyB7YXJyYXlbb2JqZWN0XX0gYXJyYXkgb2YgcG9pbnQgb2JqZWN0cyB3aXRoIHggJiB5IHByb3BlcnRpZXMgdHJhY2luZ1xuICogICBhIGNsb3NlZCBwb2x5Z29uIGFyb3VuZCB0aGUgcmVnaW9uLiBUaGUgZmlyc3QgcG9pbnQgaXMgTk9UIHJlcGVhdGVkIFxuICogICBhcyB0aGUgbGFzdCBwb2ludC4gVGhlIHBvbHlnb24gY29uc2lzdHMgZW50aXJlbHkgb2Ygb25lLXVuaXQtbG9uZyBcbiAqICAgaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbCBzZWdtZW50cy4gVXNlIGEgcG9seWdvbiBzaW1wbGlmaWNhdGlvbiByb3V0aW5lIG9uIFxuICogICB0aGUgcmVzdWx0cyB0byBzaW1wbGlmeSBhbmQvb3Igc21vb3RoIGl0LlxuICogIChNaWdodCBJIHN1Z2dlc3QgaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvbGluZS1zaW1wbGlmeS1yZHAgPylcbiAqL1xuZnVuY3Rpb24gdHJhY2VSZWdpb24oeCwgeSwgaXNJbnNpZGUpIHtcbiAgIHZhciBzdGFydFggPSB4LCBzdGFydFkgPSB5O1xuICAgdmFyIHJldCA9IFt7eDp4LCB5Onl9XTtcbiAgIHZhciBkaXIgPSBET1dOOyAvLyBhcmJpdHJhcnlcblxuIHZhciBzcXVhcmUgPSBcbiAgICAgIChpc0luc2lkZSh4LTEsIHktMSkgPyAxIDogMCkgKyBcbiAgICAgIChpc0luc2lkZSh4LCB5LTEpID8gMiA6IDApICsgXG4gICAgICAoaXNJbnNpZGUoeC0xLCB5KSA/IDQgOiAwKSArIFxuICAgICAgKGlzSW5zaWRlKHgsIHkpID8gOCA6IDApO1xuICAgICAgICAgXG4gICBpZiAoc3F1YXJlID09PSAwIHx8IHNxdWFyZSA9PT0gMTUpIFxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQmFkIFN0YXJ0aW5nIHBvaW50LlwiKTtcblxuICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGRpciA9IHRyYW5zaXRpb25zW3NxdWFyZV1bZGlyWzJdXTtcbiAgICAgIHggKz0gZGlyWzBdO1xuICAgICAgeSArPSBkaXJbMV07XG4gICAgICBcbiAgICAgIGlmICh4ID09PSBzdGFydFggJiYgeSA9PT0gc3RhcnRZKVxuICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgIFxuICAgICAgcmV0LnB1c2goe3g6eCwgeTp5fSk7XG5cbiAgICAgIGlmIChkaXIgPT09IERPV04pIFxuICAgICAgICAgc3F1YXJlID0gKChzcXVhcmUgJiAxMikgPj4gMik7XG4gICAgICBlbHNlIGlmIChkaXIgPT09IFVQKSBcbiAgICAgICAgIHNxdWFyZSA9ICgoc3F1YXJlICYgMykgPDwgMik7IFxuICAgICAgZWxzZSBpZiAoZGlyID09PSBSSUdIVCkgXG4gICAgICAgICBzcXVhcmUgPSAoKHNxdWFyZSAmIDEwKSA+PiAxKTtcbiAgICAgIGVsc2UgaWYgKGRpciA9PT0gTEVGVCkgXG4gICAgICAgICBzcXVhcmUgPSAoKHNxdWFyZSAmIDUpIDw8IDEpO1xuICAgICAgICAgXG4gICAgICBpZiAoZGlyID09PSBET1dOIHx8IGRpciA9PT0gTEVGVClcbiAgICAgICAgIHNxdWFyZSArPSAoaXNJbnNpZGUoeC0xLCB5KSA/IDQgOiAwKTtcbiAgICAgIGVsc2UgICBcbiAgICAgICAgIHNxdWFyZSArPSAoaXNJbnNpZGUoeCwgeS0xKSA/IDIgOiAwKTtcbiAgICAgXG4gICAgICBpZiAoZGlyID09PSBET1dOIHx8IGRpciA9PT0gUklHSFQpXG4gICAgICAgICBzcXVhcmUgKz0gKGlzSW5zaWRlKHgsIHkpID8gOCA6IDApO1xuICAgICAgZWxzZVxuICAgICAgICAgc3F1YXJlICs9ICAoaXNJbnNpZGUoeC0xLCB5LTEpID8gMSA6IDApO1xuICAgIFxuICAgICAgICBcbiAgIH1cbiAgIFxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gdHJhY2VSZWdpb247Il19
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function (global){
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
/* eslint-disable no-proto */
'use strict'
var base64 = require('base64-js')
var ieee754 = require('ieee754')
var isArray = require('isarray')
exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
Buffer.poolSize = 8192 // not used by this implementation
var rootParent = {}
/**
* If `Buffer.TYPED_ARRAY_SUPPORT`:
* === true Use Uint8Array implementation (fastest)
* === false Use Object implementation (most compatible, even IE6)
*
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
* Opera 11.6+, iOS 4.2+.
*
* Due to various browser bugs, sometimes the Object implementation will be used even
* when the browser supports typed arrays.
*
* Note:
*
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
*
* - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
* on objects.
*
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
*
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
* incorrect length in some situations.
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
* get the Object implementation, which is slower but behaves correctly.
*/
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
? global.TYPED_ARRAY_SUPPORT
: typedArraySupport()
function typedArraySupport () {
function Bar () {}
try {
var arr = new Uint8Array(1)
arr.foo = function () { return 42 }
arr.constructor = Bar
return arr.foo() === 42 && // typed array instances can be augmented
arr.constructor === Bar && // constructor can be set
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
} catch (e) {
return false
}
}
function kMaxLength () {
return Buffer.TYPED_ARRAY_SUPPORT
? 0x7fffffff
: 0x3fffffff
}
/**
* Class: Buffer
* =============
*
* The Buffer constructor returns instances of `Uint8Array` that are augmented
* with function properties for all the node `Buffer` API functions. We use
* `Uint8Array` so that square bracket notation works as expected -- it returns
* a single octet.
*
* By augmenting the instances, we can avoid modifying the `Uint8Array`
* prototype.
*/
function Buffer (arg) {
if (!(this instanceof Buffer)) {
// Avoid going through an ArgumentsAdaptorTrampoline in the common case.
if (arguments.length > 1) return new Buffer(arg, arguments[1])
return new Buffer(arg)
}
if (!Buffer.TYPED_ARRAY_SUPPORT) {
this.length = 0
this.parent = undefined
}
// Common case.
if (typeof arg === 'number') {
return fromNumber(this, arg)
}
// Slightly less common case.
if (typeof arg === 'string') {
return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
}
// Unusual.
return fromObject(this, arg)
}
function fromNumber (that, length) {
that = allocate(that, length < 0 ? 0 : checked(length) | 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) {
for (var i = 0; i < length; i++) {
that[i] = 0
}
}
return that
}
function fromString (that, string, encoding) {
if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
// Assumption: byteLength() return value is always < kMaxLength.
var length = byteLength(string, encoding) | 0
that = allocate(that, length)
that.write(string, encoding)
return that
}
function fromObject (that, object) {
if (Buffer.isBuffer(object)) return fromBuffer(that, object)
if (isArray(object)) return fromArray(that, object)
if (object == null) {
throw new TypeError('must start with number, buffer, array or string')
}
if (typeof ArrayBuffer !== 'undefined') {
if (object.buffer instanceof ArrayBuffer) {
return fromTypedArray(that, object)
}
if (object instanceof ArrayBuffer) {
return fromArrayBuffer(that, object)
}
}
if (object.length) return fromArrayLike(that, object)
return fromJsonObject(that, object)
}
function fromBuffer (that, buffer) {
var length = checked(buffer.length) | 0
that = allocate(that, length)
buffer.copy(that, 0, 0, length)
return that
}
function fromArray (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
// Duplicate of fromArray() to keep fromArray() monomorphic.
function fromTypedArray (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
// Truncating the elements is probably not what people expect from typed
// arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
// of the old Buffer constructor.
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
function fromArrayBuffer (that, array) {
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
array.byteLength
that = Buffer._augment(new Uint8Array(array))
} else {
// Fallback: Return an object instance of the Buffer class
that = fromTypedArray(that, new Uint8Array(array))
}
return that
}
function fromArrayLike (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
// Returns a zero-length buffer for inputs that don't conform to the spec.
function fromJsonObject (that, object) {
var array
var length = 0
if (object.type === 'Buffer' && isArray(object.data)) {
array = object.data
length = checked(array.length) | 0
}
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
Buffer.prototype.__proto__ = Uint8Array.prototype
Buffer.__proto__ = Uint8Array
} else {
// pre-set for values that may exist in the future
Buffer.prototype.length = undefined
Buffer.prototype.parent = undefined
}
function allocate (that, length) {
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = Buffer._augment(new Uint8Array(length))
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
that.length = length
that._isBuffer = true
}
var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
if (fromPool) that.parent = rootParent
return that
}
function checked (length) {
// Note: cannot use `length < kMaxLength` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= kMaxLength()) {
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
'size: 0x' + kMaxLength().toString(16) + ' bytes')
}
return length | 0
}
function SlowBuffer (subject, encoding) {
if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
var buf = new Buffer(subject, encoding)
delete buf.parent
return buf
}
Buffer.isBuffer = function isBuffer (b) {
return !!(b != null && b._isBuffer)
}
Buffer.compare = function compare (a, b) {
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
throw new TypeError('Arguments must be Buffers')
}
if (a === b) return 0
var x = a.length
var y = b.length
var i = 0
var len = Math.min(x, y)
while (i < len) {
if (a[i] !== b[i]) break
++i
}
if (i !== len) {
x = a[i]
y = b[i]
}
if (x < y) return -1
if (y < x) return 1
return 0
}
Buffer.isEncoding = function isEncoding (encoding) {
switch (String(encoding).toLowerCase()) {
case 'hex':
case 'utf8':
case 'utf-8':
case 'ascii':
case 'binary':
case 'base64':
case 'raw':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return true
default:
return false
}
}
Buffer.concat = function concat (list, length) {
if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
if (list.length === 0) {
return new Buffer(0)
}
var i
if (length === undefined) {
length = 0
for (i = 0; i < list.length; i++) {
length += list[i].length
}
}
var buf = new Buffer(length)
var pos = 0
for (i = 0; i < list.length; i++) {
var item = list[i]
item.copy(buf, pos)
pos += item.length
}
return buf
}
function byteLength (string, encoding) {
if (typeof string !== 'string') string = '' + string
var len = string.length
if (len === 0) return 0
// Use a for loop to avoid recursion
var loweredCase = false
for (;;) {
switch (encoding) {
case 'ascii':
case 'binary':
// Deprecated
case 'raw':
case 'raws':
return len
case 'utf8':
case 'utf-8':
return utf8ToBytes(string).length
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return len * 2
case 'hex':
return len >>> 1
case 'base64':
return base64ToBytes(string).length
default:
if (loweredCase) return utf8ToBytes(string).length // assume utf8
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.byteLength = byteLength
function slowToString (encoding, start, end) {
var loweredCase = false
start = start | 0
end = end === undefined || end === Infinity ? this.length : end | 0
if (!encoding) encoding = 'utf8'
if (start < 0) start = 0
if (end > this.length) end = this.length
if (end <= start) return ''
while (true) {
switch (encoding) {
case 'hex':
return hexSlice(this, start, end)
case 'utf8':
case 'utf-8':
return utf8Slice(this, start, end)
case 'ascii':
return asciiSlice(this, start, end)
case 'binary':
return binarySlice(this, start, end)
case 'base64':
return base64Slice(this, start, end)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return utf16leSlice(this, start, end)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = (encoding + '').toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toString = function toString () {
var length = this.length | 0
if (length === 0) return ''
if (arguments.length === 0) return utf8Slice(this, 0, length)
return slowToString.apply(this, arguments)
}
Buffer.prototype.equals = function equals (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return true
return Buffer.compare(this, b) === 0
}
Buffer.prototype.inspect = function inspect () {
var str = ''
var max = exports.INSPECT_MAX_BYTES
if (this.length > 0) {
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
if (this.length > max) str += ' ... '
}
return '<Buffer ' + str + '>'
}
Buffer.prototype.compare = function compare (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return 0
return Buffer.compare(this, b)
}
Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
else if (byteOffset < -0x80000000) byteOffset = -0x80000000
byteOffset >>= 0
if (this.length === 0) return -1
if (byteOffset >= this.length) return -1
// Negative offsets start from the end of the buffer
if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
if (typeof val === 'string') {
if (val.length === 0) return -1 // special case: looking for empty string always fails
return String.prototype.indexOf.call(this, val, byteOffset)
}
if (Buffer.isBuffer(val)) {
return arrayIndexOf(this, val, byteOffset)
}
if (typeof val === 'number') {
if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
}
return arrayIndexOf(this, [ val ], byteOffset)
}
function arrayIndexOf (arr, val, byteOffset) {
var foundIndex = -1
for (var i = 0; byteOffset + i < arr.length; i++) {
if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
if (foundIndex === -1) foundIndex = i
if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
} else {
foundIndex = -1
}
}
return -1
}
throw new TypeError('val must be string, number or Buffer')
}
// `get` is deprecated
Buffer.prototype.get = function get (offset) {
console.log('.get() is deprecated. Access using array indexes instead.')
return this.readUInt8(offset)
}
// `set` is deprecated
Buffer.prototype.set = function set (v, offset) {
console.log('.set() is deprecated. Access using array indexes instead.')
return this.writeUInt8(v, offset)
}
function hexWrite (buf, string, offset, length) {
offset = Number(offset) || 0
var remaining = buf.length - offset
if (!length) {
length = remaining
} else {
length = Number(length)
if (length > remaining) {
length = remaining
}
}
// must be an even number of digits
var strLen = string.length
if (strLen % 2 !== 0) throw new Error('Invalid hex string')
if (length > strLen / 2) {
length = strLen / 2
}
for (var i = 0; i < length; i++) {
var parsed = parseInt(string.substr(i * 2, 2), 16)
if (isNaN(parsed)) throw new Error('Invalid hex string')
buf[offset + i] = parsed
}
return i
}
function utf8Write (buf, string, offset, length) {
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}
function asciiWrite (buf, string, offset, length) {
return blitBuffer(asciiToBytes(string), buf, offset, length)
}
function binaryWrite (buf, string, offset, length) {
return asciiWrite(buf, string, offset, length)
}
function base64Write (buf, string, offset, length) {
return blitBuffer(base64ToBytes(string), buf, offset, length)
}
function ucs2Write (buf, string, offset, length) {
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}
Buffer.prototype.write = function write (string, offset, length, encoding) {
// Buffer#write(string)
if (offset === undefined) {
encoding = 'utf8'
length = this.length
offset = 0
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset
length = this.length
offset = 0
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset | 0
if (isFinite(length)) {
length = length | 0
if (encoding === undefined) encoding = 'utf8'
} else {
encoding = length
length = undefined
}
// legacy write(string, encoding, offset, length) - remove in v0.13
} else {
var swap = encoding
encoding = offset
offset = length | 0
length = swap
}
var remaining = this.length - offset
if (length === undefined || length > remaining) length = remaining
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
throw new RangeError('attempt to write outside buffer bounds')
}
if (!encoding) encoding = 'utf8'
var loweredCase = false
for (;;) {
switch (encoding) {
case 'hex':
return hexWrite(this, string, offset, length)
case 'utf8':
case 'utf-8':
return utf8Write(this, string, offset, length)
case 'ascii':
return asciiWrite(this, string, offset, length)
case 'binary':
return binaryWrite(this, string, offset, length)
case 'base64':
// Warning: maxLength not taken into account in base64Write
return base64Write(this, string, offset, length)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return ucs2Write(this, string, offset, length)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toJSON = function toJSON () {
return {
type: 'Buffer',
data: Array.prototype.slice.call(this._arr || this, 0)
}
}
function base64Slice (buf, start, end) {
if (start === 0 && end === buf.length) {
return base64.fromByteArray(buf)
} else {
return base64.fromByteArray(buf.slice(start, end))
}
}
function utf8Slice (buf, start, end) {
end = Math.min(buf.length, end)
var res = []
var i = start
while (i < end) {
var firstByte = buf[i]
var codePoint = null
var bytesPerSequence = (firstByte > 0xEF) ? 4
: (firstByte > 0xDF) ? 3
: (firstByte > 0xBF) ? 2
: 1
if (i + bytesPerSequence <= end) {
var secondByte, thirdByte, fourthByte, tempCodePoint
switch (bytesPerSequence) {
case 1:
if (firstByte < 0x80) {
codePoint = firstByte
}
break
case 2:
secondByte = buf[i + 1]
if ((secondByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
if (tempCodePoint > 0x7F) {
codePoint = tempCodePoint
}
}
break
case 3:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
codePoint = tempCodePoint
}
}
break
case 4:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
fourthByte = buf[i + 3]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
codePoint = tempCodePoint
}
}
}
}
if (codePoint === null) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD
bytesPerSequence = 1
} else if (codePoint > 0xFFFF) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
codePoint = 0xDC00 | codePoint & 0x3FF
}
res.push(codePoint)
i += bytesPerSequence
}
return decodeCodePointsArray(res)
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000
function decodeCodePointsArray (codePoints) {
var len = codePoints.length
if (len <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
}
// Decode in chunks to avoid "call stack size exceeded".
var res = ''
var i = 0
while (i < len) {
res += String.fromCharCode.apply(
String,
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
)
}
return res
}
function asciiSlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; i++) {
ret += String.fromCharCode(buf[i] & 0x7F)
}
return ret
}
function binarySlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; i++) {
ret += String.fromCharCode(buf[i])
}
return ret
}
function hexSlice (buf, start, end) {
var len = buf.length
if (!start || start < 0) start = 0
if (!end || end < 0 || end > len) end = len
var out = ''
for (var i = start; i < end; i++) {
out += toHex(buf[i])
}
return out
}
function utf16leSlice (buf, start, end) {
var bytes = buf.slice(start, end)
var res = ''
for (var i = 0; i < bytes.length; i += 2) {
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
}
return res
}
Buffer.prototype.slice = function slice (start, end) {
var len = this.length
start = ~~start
end = end === undefined ? len : ~~end
if (start < 0) {
start += len
if (start < 0) start = 0
} else if (start > len) {
start = len
}
if (end < 0) {
end += len
if (end < 0) end = 0
} else if (end > len) {
end = len
}
if (end < start) end = start
var newBuf
if (Buffer.TYPED_ARRAY_SUPPORT) {
newBuf = Buffer._augment(this.subarray(start, end))
} else {
var sliceLen = end - start
newBuf = new Buffer(sliceLen, undefined)
for (var i = 0; i < sliceLen; i++) {
newBuf[i] = this[i + start]
}
}
if (newBuf.length) newBuf.parent = this.parent || this
return newBuf
}
/*
* Need to make sure that buffer isn't trying to write out of bounds.
*/
function checkOffset (offset, ext, length) {
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
}
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
return val
}
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
checkOffset(offset, byteLength, this.length)
}
var val = this[offset + --byteLength]
var mul = 1
while (byteLength > 0 && (mul *= 0x100)) {
val += this[offset + --byteLength] * mul
}
return val
}
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
return this[offset]
}
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return this[offset] | (this[offset + 1] << 8)
}
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return (this[offset] << 8) | this[offset + 1]
}
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ((this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16)) +
(this[offset + 3] * 0x1000000)
}
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] * 0x1000000) +
((this[offset + 1] << 16) |
(this[offset + 2] << 8) |
this[offset + 3])
}
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var i = byteLength
var mul = 1
var val = this[offset + --i]
while (i > 0 && (mul *= 0x100)) {
val += this[offset + --i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
if (!(this[offset] & 0x80)) return (this[offset])
return ((0xff - this[offset] + 1) * -1)
}
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset] | (this[offset + 1] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset + 1] | (this[offset] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16) |
(this[offset + 3] << 24)
}
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] << 24) |
(this[offset + 1] << 16) |
(this[offset + 2] << 8) |
(this[offset + 3])
}
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, true, 23, 4)
}
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, false, 23, 4)
}
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, true, 52, 8)
}
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, false, 52, 8)
}
function checkInt (buf, value, offset, ext, max, min) {
if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
if (value > max || value < min) throw new RangeError('value is out of bounds')
if (offset + ext > buf.length) throw new RangeError('index out of range')
}
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
var mul = 1
var i = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
var i = byteLength - 1
var mul = 1
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
this[offset] = (value & 0xff)
return offset + 1
}
function objectWriteUInt16 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
(littleEndian ? i : 1 - i) * 8
}
}
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
function objectWriteUInt32 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffffffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
}
}
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset + 3] = (value >>> 24)
this[offset + 2] = (value >>> 16)
this[offset + 1] = (value >>> 8)
this[offset] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = 0
var mul = 1
var sub = value < 0 ? 1 : 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = byteLength - 1
var mul = 1
var sub = value < 0 ? 1 : 0
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
if (value < 0) value = 0xff + value + 1
this[offset] = (value & 0xff)
return offset + 1
}
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
this[offset + 2] = (value >>> 16)
this[offset + 3] = (value >>> 24)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (value < 0) value = 0xffffffff + value + 1
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
function checkIEEE754 (buf, value, offset, ext, max, min) {
if (value > max || value < min) throw new RangeError('value is out of bounds')
if (offset + ext > buf.length) throw new RangeError('index out of range')
if (offset < 0) throw new RangeError('index out of range')
}
function writeFloat (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
}
ieee754.write(buf, value, offset, littleEndian, 23, 4)
return offset + 4
}
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
return writeFloat(this, value, offset, true, noAssert)
}
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
return writeFloat(this, value, offset, false, noAssert)
}
function writeDouble (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
}
ieee754.write(buf, value, offset, littleEndian, 52, 8)
return offset + 8
}
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
return writeDouble(this, value, offset, true, noAssert)
}
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
return writeDouble(this, value, offset, false, noAssert)
}
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
if (!start) start = 0
if (!end && end !== 0) end = this.length
if (targetStart >= target.length) targetStart = target.length
if (!targetStart) targetStart = 0
if (end > 0 && end < start) end = start
// Copy 0 bytes; we're done
if (end === start) return 0
if (target.length === 0 || this.length === 0) return 0
// Fatal error conditions
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds')
}
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
if (end < 0) throw new RangeError('sourceEnd out of bounds')
// Are we oob?
if (end > this.length) end = this.length
if (target.length - targetStart < end - start) {
end = target.length - targetStart + start
}
var len = end - start
var i
if (this === target && start < targetStart && targetStart < end) {
// descending copy from end
for (i = len - 1; i >= 0; i--) {
target[i + targetStart] = this[i + start]
}
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
// ascending copy from start
for (i = 0; i < len; i++) {
target[i + targetStart] = this[i + start]
}
} else {
target._set(this.subarray(start, start + len), targetStart)
}
return len
}
// fill(value, start=0, end=buffer.length)
Buffer.prototype.fill = function fill (value, start, end) {
if (!value) value = 0
if (!start) start = 0
if (!end) end = this.length
if (end < start) throw new RangeError('end < start')
// Fill 0 bytes; we're done
if (end === start) return
if (this.length === 0) return
if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
var i
if (typeof value === 'number') {
for (i = start; i < end; i++) {
this[i] = value
}
} else {
var bytes = utf8ToBytes(value.toString())
var len = bytes.length
for (i = start; i < end; i++) {
this[i] = bytes[i % len]
}
}
return this
}
/**
* Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
* Added in Node 0.12. Only available in browsers that support ArrayBuffer.
*/
Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
if (typeof Uint8Array !== 'undefined') {
if (Buffer.TYPED_ARRAY_SUPPORT) {
return (new Buffer(this)).buffer
} else {
var buf = new Uint8Array(this.length)
for (var i = 0, len = buf.length; i < len; i += 1) {
buf[i] = this[i]
}
return buf.buffer
}
} else {
throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
}
}
// HELPER FUNCTIONS
// ================
var BP = Buffer.prototype
/**
* Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
*/
Buffer._augment = function _augment (arr) {
arr.constructor = Buffer
arr._isBuffer = true
// save reference to original Uint8Array set method before overwriting
arr._set = arr.set
// deprecated
arr.get = BP.get
arr.set = BP.set
arr.write = BP.write
arr.toString = BP.toString
arr.toLocaleString = BP.toString
arr.toJSON = BP.toJSON
arr.equals = BP.equals
arr.compare = BP.compare
arr.indexOf = BP.indexOf
arr.copy = BP.copy
arr.slice = BP.slice
arr.readUIntLE = BP.readUIntLE
arr.readUIntBE = BP.readUIntBE
arr.readUInt8 = BP.readUInt8
arr.readUInt16LE = BP.readUInt16LE
arr.readUInt16BE = BP.readUInt16BE
arr.readUInt32LE = BP.readUInt32LE
arr.readUInt32BE = BP.readUInt32BE
arr.readIntLE = BP.readIntLE
arr.readIntBE = BP.readIntBE
arr.readInt8 = BP.readInt8
arr.readInt16LE = BP.readInt16LE
arr.readInt16BE = BP.readInt16BE
arr.readInt32LE = BP.readInt32LE
arr.readInt32BE = BP.readInt32BE
arr.readFloatLE = BP.readFloatLE
arr.readFloatBE = BP.readFloatBE
arr.readDoubleLE = BP.readDoubleLE
arr.readDoubleBE = BP.readDoubleBE
arr.writeUInt8 = BP.writeUInt8
arr.writeUIntLE = BP.writeUIntLE
arr.writeUIntBE = BP.writeUIntBE
arr.writeUInt16LE = BP.writeUInt16LE
arr.writeUInt16BE = BP.writeUInt16BE
arr.writeUInt32LE = BP.writeUInt32LE
arr.writeUInt32BE = BP.writeUInt32BE
arr.writeIntLE = BP.writeIntLE
arr.writeIntBE = BP.writeIntBE
arr.writeInt8 = BP.writeInt8
arr.writeInt16LE = BP.writeInt16LE
arr.writeInt16BE = BP.writeInt16BE
arr.writeInt32LE = BP.writeInt32LE
arr.writeInt32BE = BP.writeInt32BE
arr.writeFloatLE = BP.writeFloatLE
arr.writeFloatBE = BP.writeFloatBE
arr.writeDoubleLE = BP.writeDoubleLE
arr.writeDoubleBE = BP.writeDoubleBE
arr.fill = BP.fill
arr.inspect = BP.inspect
arr.toArrayBuffer = BP.toArrayBuffer
return arr
}
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
function base64clean (str) {
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = stringtrim(str).replace(INVALID_BASE64_RE, '')
// Node converts strings with length < 2 to ''
if (str.length < 2) return ''
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
while (str.length % 4 !== 0) {
str = str + '='
}
return str
}
function stringtrim (str) {
if (str.trim) return str.trim()
return str.replace(/^\s+|\s+$/g, '')
}
function toHex (n) {
if (n < 16) return '0' + n.toString(16)
return n.toString(16)
}
function utf8ToBytes (string, units) {
units = units || Infinity
var codePoint
var length = string.length
var leadSurrogate = null
var bytes = []
for (var i = 0; i < length; i++) {
codePoint = string.charCodeAt(i)
// is surrogate component
if (codePoint > 0xD7FF && codePoint < 0xE000) {
// last char was a lead
if (!leadSurrogate) {
// no lead yet
if (codePoint > 0xDBFF) {
// unexpected trail
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
} else if (i + 1 === length) {
// unpaired lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
}
// valid lead
leadSurrogate = codePoint
continue
}
// 2 leads in a row
if (codePoint < 0xDC00) {
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
leadSurrogate = codePoint
continue
}
// valid surrogate pair
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
} else if (leadSurrogate) {
// valid bmp char, but last char was a lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
}
leadSurrogate = null
// encode utf8
if (codePoint < 0x80) {
if ((units -= 1) < 0) break
bytes.push(codePoint)
} else if (codePoint < 0x800) {
if ((units -= 2) < 0) break
bytes.push(
codePoint >> 0x6 | 0xC0,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x10000) {
if ((units -= 3) < 0) break
bytes.push(
codePoint >> 0xC | 0xE0,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x110000) {
if ((units -= 4) < 0) break
bytes.push(
codePoint >> 0x12 | 0xF0,
codePoint >> 0xC & 0x3F | 0x80,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else {
throw new Error('Invalid code point')
}
}
return bytes
}
function asciiToBytes (str) {
var byteArray = []
for (var i = 0; i < str.length; i++) {
// Node's code seems to be doing this and not & 0x7F..
byteArray.push(str.charCodeAt(i) & 0xFF)
}
return byteArray
}
function utf16leToBytes (str, units) {
var c, hi, lo
var byteArray = []
for (var i = 0; i < str.length; i++) {
if ((units -= 2) < 0) break
c = str.charCodeAt(i)
hi = c >> 8
lo = c % 256
byteArray.push(lo)
byteArray.push(hi)
}
return byteArray
}
function base64ToBytes (str) {
return base64.toByteArray(base64clean(str))
}
function blitBuffer (src, dst, offset, length) {
for (var i = 0; i < length; i++) {
if ((i + offset >= dst.length) || (i >= src.length)) break
dst[i + offset] = src[i]
}
return i
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxudmFyIHJvb3RQYXJlbnQgPSB7fVxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIFNhZmFyaSA1LTcgbGFja3Mgc3VwcG9ydCBmb3IgY2hhbmdpbmcgdGhlIGBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yYCBwcm9wZXJ0eVxuICogICAgIG9uIG9iamVjdHMuXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUICE9PSB1bmRlZmluZWRcbiAgPyBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVFxuICA6IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICBmdW5jdGlvbiBCYXIgKCkge31cbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuZm9vID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfVxuICAgIGFyci5jb25zdHJ1Y3RvciA9IEJhclxuICAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyICYmIC8vIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkXG4gICAgICAgIGFyci5jb25zdHJ1Y3RvciA9PT0gQmFyICYmIC8vIGNvbnN0cnVjdG9yIGNhbiBiZSBzZXRcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAmJiAvLyBjaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgICAgICAgYXJyLnN1YmFycmF5KDEsIDEpLmJ5dGVMZW5ndGggPT09IDAgLy8gaWUxMCBoYXMgYnJva2VuIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbmZ1bmN0aW9uIGtNYXhMZW5ndGggKCkge1xuICByZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgICA/IDB4N2ZmZmZmZmZcbiAgICA6IDB4M2ZmZmZmZmZcbn1cblxuLyoqXG4gKiBDbGFzczogQnVmZmVyXG4gKiA9PT09PT09PT09PT09XG4gKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBhcmUgYXVnbWVudGVkXG4gKiB3aXRoIGZ1bmN0aW9uIHByb3BlcnRpZXMgZm9yIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBBUEkgZnVuY3Rpb25zLiBXZSB1c2VcbiAqIGBVaW50OEFycmF5YCBzbyB0aGF0IHNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0IHJldHVybnNcbiAqIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIEJ5IGF1Z21lbnRpbmcgdGhlIGluc3RhbmNlcywgd2UgY2FuIGF2b2lkIG1vZGlmeWluZyB0aGUgYFVpbnQ4QXJyYXlgXG4gKiBwcm90b3R5cGUuXG4gKi9cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgLy8gQXZvaWQgZ29pbmcgdGhyb3VnaCBhbiBBcmd1bWVudHNBZGFwdG9yVHJhbXBvbGluZSBpbiB0aGUgY29tbW9uIGNhc2UuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSByZXR1cm4gbmV3IEJ1ZmZlcihhcmcsIGFyZ3VtZW50c1sxXSlcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihhcmcpXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpcy5sZW5ndGggPSAwXG4gICAgdGhpcy5wYXJlbnQgPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLCBhcmcpXG4gIH1cblxuICAvLyBTbGlnaHRseSBsZXNzIGNvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGlzLCBhcmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogJ3V0ZjgnKVxuICB9XG5cbiAgLy8gVW51c3VhbC5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhpcywgYXJnKVxufVxuXG5mdW5jdGlvbiBmcm9tTnVtYmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChsZW5ndGgpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIC8vIEFzc3VtcHRpb246IGJ5dGVMZW5ndGgoKSByZXR1cm4gdmFsdWUgaXMgYWx3YXlzIDwga01heExlbmd0aC5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG5cbiAgdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpKSByZXR1cm4gZnJvbUJ1ZmZlcih0aGF0LCBvYmplY3QpXG5cbiAgaWYgKGlzQXJyYXkob2JqZWN0KSkgcmV0dXJuIGZyb21BcnJheSh0aGF0LCBvYmplY3QpXG5cbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbXVzdCBzdGFydCB3aXRoIG51bWJlciwgYnVmZmVyLCBhcnJheSBvciBzdHJpbmcnKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAob2JqZWN0LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICByZXR1cm4gZnJvbVR5cGVkQXJyYXkodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgfVxuXG4gIGlmIChvYmplY3QubGVuZ3RoKSByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmplY3QpXG5cbiAgcmV0dXJuIGZyb21Kc29uT2JqZWN0KHRoYXQsIG9iamVjdClcbn1cblxuZnVuY3Rpb24gZnJvbUJ1ZmZlciAodGhhdCwgYnVmZmVyKSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGJ1ZmZlci5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBidWZmZXIuY29weSh0aGF0LCAwLCAwLCBsZW5ndGgpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIER1cGxpY2F0ZSBvZiBmcm9tQXJyYXkoKSB0byBrZWVwIGZyb21BcnJheSgpIG1vbm9tb3JwaGljLlxuZnVuY3Rpb24gZnJvbVR5cGVkQXJyYXkgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIC8vIFRydW5jYXRpbmcgdGhlIGVsZW1lbnRzIGlzIHByb2JhYmx5IG5vdCB3aGF0IHBlb3BsZSBleHBlY3QgZnJvbSB0eXBlZFxuICAvLyBhcnJheXMgd2l0aCBCWVRFU19QRVJfRUxFTUVOVCA+IDEgYnV0IGl0J3MgY29tcGF0aWJsZSB3aXRoIHRoZSBiZWhhdmlvclxuICAvLyBvZiB0aGUgb2xkIEJ1ZmZlciBjb25zdHJ1Y3Rvci5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXkpIHtcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgYXJyYXkuYnl0ZUxlbmd0aFxuICAgIHRoYXQgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbVR5cGVkQXJyYXkodGhhdCwgbmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vLyBEZXNlcmlhbGl6ZSB7IHR5cGU6ICdCdWZmZXInLCBkYXRhOiBbMSwyLDMsLi4uXSB9IGludG8gYSBCdWZmZXIgb2JqZWN0LlxuLy8gUmV0dXJucyBhIHplcm8tbGVuZ3RoIGJ1ZmZlciBmb3IgaW5wdXRzIHRoYXQgZG9uJ3QgY29uZm9ybSB0byB0aGUgc3BlYy5cbmZ1bmN0aW9uIGZyb21Kc29uT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgdmFyIGFycmF5XG4gIHZhciBsZW5ndGggPSAwXG5cbiAgaWYgKG9iamVjdC50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iamVjdC5kYXRhKSkge1xuICAgIGFycmF5ID0gb2JqZWN0LmRhdGFcbiAgICBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIH1cbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbiAgQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcbn0gZWxzZSB7XG4gIC8vIHByZS1zZXQgZm9yIHZhbHVlcyB0aGF0IG1heSBleGlzdCBpbiB0aGUgZnV0dXJlXG4gIEJ1ZmZlci5wcm90b3R5cGUubGVuZ3RoID0gdW5kZWZpbmVkXG4gIEJ1ZmZlci5wcm90b3R5cGUucGFyZW50ID0gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIGFsbG9jYXRlICh0aGF0LCBsZW5ndGgpIHtcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IEJ1ZmZlci5fYXVnbWVudChuZXcgVWludDhBcnJheShsZW5ndGgpKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICAgIHRoYXQuX2lzQnVmZmVyID0gdHJ1ZVxuICB9XG5cbiAgdmFyIGZyb21Qb29sID0gbGVuZ3RoICE9PSAwICYmIGxlbmd0aCA8PSBCdWZmZXIucG9vbFNpemUgPj4+IDFcbiAgaWYgKGZyb21Qb29sKSB0aGF0LnBhcmVudCA9IHJvb3RQYXJlbnRcblxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwga01heExlbmd0aGAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBrTWF4TGVuZ3RoKCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsga01heExlbmd0aCgpLnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKHN1YmplY3QsIGVuY29kaW5nKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTbG93QnVmZmVyKSkgcmV0dXJuIG5ldyBTbG93QnVmZmVyKHN1YmplY3QsIGVuY29kaW5nKVxuXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKHN1YmplY3QsIGVuY29kaW5nKVxuICBkZWxldGUgYnVmLnBhcmVudFxuICByZXR1cm4gYnVmXG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyIChiKSB7XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihhKSB8fCAhQnVmZmVyLmlzQnVmZmVyKGIpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnRzIG11c3QgYmUgQnVmZmVycycpXG4gIH1cblxuICBpZiAoYSA9PT0gYikgcmV0dXJuIDBcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcblxuICB2YXIgaSA9IDBcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIGJyZWFrXG5cbiAgICArK2lcbiAgfVxuXG4gIGlmIChpICE9PSBsZW4pIHtcbiAgICB4ID0gYVtpXVxuICAgIHkgPSBiW2ldXG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3Jhdyc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2xpc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzLicpXG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoMClcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgbGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gbGlzdFtpXVxuICAgIGl0ZW0uY29weShidWYsIHBvcylcbiAgICBwb3MgKz0gaXRlbS5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSBzdHJpbmcgPSAnJyArIHN0cmluZ1xuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgLy8gRGVwcmVjYXRlZFxuICAgICAgY2FzZSAncmF3JzpcbiAgICAgIGNhc2UgJ3Jhd3MnOlxuICAgICAgICByZXR1cm4gbGVuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIHN0YXJ0ID0gc3RhcnQgfCAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA9PT0gSW5maW5pdHkgPyB0aGlzLmxlbmd0aCA6IGVuZCB8IDBcblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAoZW5kIDw9IHN0YXJ0KSByZXR1cm4gJydcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBiaW5hcnlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIDBcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCkge1xuICBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIGJ5dGVPZmZzZXQgPj49IDBcblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAtMVxuICBpZiAoYnl0ZU9mZnNldCA+PSB0aGlzLmxlbmd0aCkgcmV0dXJuIC0xXG5cbiAgLy8gTmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBNYXRoLm1heCh0aGlzLmxlbmd0aCArIGJ5dGVPZmZzZXQsIDApXG5cbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHJldHVybiAtMSAvLyBzcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZyBhbHdheXMgZmFpbHNcbiAgICByZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mLmNhbGwodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZih0aGlzLCBbIHZhbCBdLCBieXRlT2Zmc2V0KVxuICB9XG5cbiAgZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCkge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKHZhciBpID0gMDsgYnl0ZU9mZnNldCArIGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhcnJbYnl0ZU9mZnNldCArIGldID09PSB2YWxbZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXhdKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsLmxlbmd0aCkgcmV0dXJuIGJ5dGVPZmZzZXQgKyBmb3VuZEluZGV4XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG4vLyBgZ2V0YCBpcyBkZXByZWNhdGVkXG5CdWZmZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldCAob2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuZ2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy5yZWFkVUludDgob2Zmc2V0KVxufVxuXG4vLyBgc2V0YCBpcyBkZXByZWNhdGVkXG5CdWZmZXIucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIHNldCAodiwgb2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuc2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy53cml0ZVVJbnQ4KHYsIG9mZnNldClcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChpc05hTihwYXJzZWQpKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiaW5hcnlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdmFyIHN3YXAgPSBlbmNvZGluZ1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgb2Zmc2V0ID0gbGVuZ3RoIHwgMFxuICAgIGxlbmd0aCA9IHN3YXBcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdhdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBiaW5hcnlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gQnVmZmVyLl9hdWdtZW50KHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZCkpXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgaSsrKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICBpZiAobmV3QnVmLmxlbmd0aCkgbmV3QnVmLnBhcmVudCA9IHRoaXMucGFyZW50IHx8IHRoaXNcblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2J1ZmZlciBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndmFsdWUgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgaSsrKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IHZhbHVlIDwgMCA/IDEgOiAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcbiAgdmFyIGlcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBhc2NlbmRpbmcgY29weSBmcm9tIHN0YXJ0XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQuX3NldCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksIHRhcmdldFN0YXJ0KVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBmaWxsKHZhbHVlLCBzdGFydD0wLCBlbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbHVlLCBzdGFydCwgZW5kKSB7XG4gIGlmICghdmFsdWUpIHZhbHVlID0gMFxuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQpIGVuZCA9IHRoaXMubGVuZ3RoXG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignZW5kIDwgc3RhcnQnKVxuXG4gIC8vIEZpbGwgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuXG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3N0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCBvdXQgb2YgYm91bmRzJylcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIHRoaXNbaV0gPSB2YWx1ZVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSB1dGY4VG9CeXRlcyh2YWx1ZS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgYEFycmF5QnVmZmVyYCB3aXRoIHRoZSAqY29waWVkKiBtZW1vcnkgb2YgdGhlIGJ1ZmZlciBpbnN0YW5jZS5cbiAqIEFkZGVkIGluIE5vZGUgMC4xMi4gT25seSBhdmFpbGFibGUgaW4gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IEFycmF5QnVmZmVyLlxuICovXG5CdWZmZXIucHJvdG90eXBlLnRvQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiB0b0FycmF5QnVmZmVyICgpIHtcbiAgaWYgKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgICAgcmV0dXJuIChuZXcgQnVmZmVyKHRoaXMpKS5idWZmZXJcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGJ1ZiA9IG5ldyBVaW50OEFycmF5KHRoaXMubGVuZ3RoKVxuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGJ1Zi5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgICBidWZbaV0gPSB0aGlzW2ldXG4gICAgICB9XG4gICAgICByZXR1cm4gYnVmLmJ1ZmZlclxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCdWZmZXIudG9BcnJheUJ1ZmZlciBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlcicpXG4gIH1cbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgQlAgPSBCdWZmZXIucHJvdG90eXBlXG5cbi8qKlxuICogQXVnbWVudCBhIFVpbnQ4QXJyYXkgKmluc3RhbmNlKiAobm90IHRoZSBVaW50OEFycmF5IGNsYXNzISkgd2l0aCBCdWZmZXIgbWV0aG9kc1xuICovXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiBfYXVnbWVudCAoYXJyKSB7XG4gIGFyci5jb25zdHJ1Y3RvciA9IEJ1ZmZlclxuICBhcnIuX2lzQnVmZmVyID0gdHJ1ZVxuXG4gIC8vIHNhdmUgcmVmZXJlbmNlIHRvIG9yaWdpbmFsIFVpbnQ4QXJyYXkgc2V0IG1ldGhvZCBiZWZvcmUgb3ZlcndyaXRpbmdcbiAgYXJyLl9zZXQgPSBhcnIuc2V0XG5cbiAgLy8gZGVwcmVjYXRlZFxuICBhcnIuZ2V0ID0gQlAuZ2V0XG4gIGFyci5zZXQgPSBCUC5zZXRcblxuICBhcnIud3JpdGUgPSBCUC53cml0ZVxuICBhcnIudG9TdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9Mb2NhbGVTdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9KU09OID0gQlAudG9KU09OXG4gIGFyci5lcXVhbHMgPSBCUC5lcXVhbHNcbiAgYXJyLmNvbXBhcmUgPSBCUC5jb21wYXJlXG4gIGFyci5pbmRleE9mID0gQlAuaW5kZXhPZlxuICBhcnIuY29weSA9IEJQLmNvcHlcbiAgYXJyLnNsaWNlID0gQlAuc2xpY2VcbiAgYXJyLnJlYWRVSW50TEUgPSBCUC5yZWFkVUludExFXG4gIGFyci5yZWFkVUludEJFID0gQlAucmVhZFVJbnRCRVxuICBhcnIucmVhZFVJbnQ4ID0gQlAucmVhZFVJbnQ4XG4gIGFyci5yZWFkVUludDE2TEUgPSBCUC5yZWFkVUludDE2TEVcbiAgYXJyLnJlYWRVSW50MTZCRSA9IEJQLnJlYWRVSW50MTZCRVxuICBhcnIucmVhZFVJbnQzMkxFID0gQlAucmVhZFVJbnQzMkxFXG4gIGFyci5yZWFkVUludDMyQkUgPSBCUC5yZWFkVUludDMyQkVcbiAgYXJyLnJlYWRJbnRMRSA9IEJQLnJlYWRJbnRMRVxuICBhcnIucmVhZEludEJFID0gQlAucmVhZEludEJFXG4gIGFyci5yZWFkSW50OCA9IEJQLnJlYWRJbnQ4XG4gIGFyci5yZWFkSW50MTZMRSA9IEJQLnJlYWRJbnQxNkxFXG4gIGFyci5yZWFkSW50MTZCRSA9IEJQLnJlYWRJbnQxNkJFXG4gIGFyci5yZWFkSW50MzJMRSA9IEJQLnJlYWRJbnQzMkxFXG4gIGFyci5yZWFkSW50MzJCRSA9IEJQLnJlYWRJbnQzMkJFXG4gIGFyci5yZWFkRmxvYXRMRSA9IEJQLnJlYWRGbG9hdExFXG4gIGFyci5yZWFkRmxvYXRCRSA9IEJQLnJlYWRGbG9hdEJFXG4gIGFyci5yZWFkRG91YmxlTEUgPSBCUC5yZWFkRG91YmxlTEVcbiAgYXJyLnJlYWREb3VibGVCRSA9IEJQLnJlYWREb3VibGVCRVxuICBhcnIud3JpdGVVSW50OCA9IEJQLndyaXRlVUludDhcbiAgYXJyLndyaXRlVUludExFID0gQlAud3JpdGVVSW50TEVcbiAgYXJyLndyaXRlVUludEJFID0gQlAud3JpdGVVSW50QkVcbiAgYXJyLndyaXRlVUludDE2TEUgPSBCUC53cml0ZVVJbnQxNkxFXG4gIGFyci53cml0ZVVJbnQxNkJFID0gQlAud3JpdGVVSW50MTZCRVxuICBhcnIud3JpdGVVSW50MzJMRSA9IEJQLndyaXRlVUludDMyTEVcbiAgYXJyLndyaXRlVUludDMyQkUgPSBCUC53cml0ZVVJbnQzMkJFXG4gIGFyci53cml0ZUludExFID0gQlAud3JpdGVJbnRMRVxuICBhcnIud3JpdGVJbnRCRSA9IEJQLndyaXRlSW50QkVcbiAgYXJyLndyaXRlSW50OCA9IEJQLndyaXRlSW50OFxuICBhcnIud3JpdGVJbnQxNkxFID0gQlAud3JpdGVJbnQxNkxFXG4gIGFyci53cml0ZUludDE2QkUgPSBCUC53cml0ZUludDE2QkVcbiAgYXJyLndyaXRlSW50MzJMRSA9IEJQLndyaXRlSW50MzJMRVxuICBhcnIud3JpdGVJbnQzMkJFID0gQlAud3JpdGVJbnQzMkJFXG4gIGFyci53cml0ZUZsb2F0TEUgPSBCUC53cml0ZUZsb2F0TEVcbiAgYXJyLndyaXRlRmxvYXRCRSA9IEJQLndyaXRlRmxvYXRCRVxuICBhcnIud3JpdGVEb3VibGVMRSA9IEJQLndyaXRlRG91YmxlTEVcbiAgYXJyLndyaXRlRG91YmxlQkUgPSBCUC53cml0ZURvdWJsZUJFXG4gIGFyci5maWxsID0gQlAuZmlsbFxuICBhcnIuaW5zcGVjdCA9IEJQLmluc3BlY3RcbiAgYXJyLnRvQXJyYXlCdWZmZXIgPSBCUC50b0FycmF5QnVmZmVyXG5cbiAgcmV0dXJuIGFyclxufVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSlcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cbiJdfQ==
},{"base64-js":2,"ieee754":3,"isarray":4}],2:[function(require,module,exports){
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
;(function (exports) {
'use strict';
var Arr = (typeof Uint8Array !== 'undefined')
? Uint8Array
: Array
var PLUS = '+'.charCodeAt(0)
var SLASH = '/'.charCodeAt(0)
var NUMBER = '0'.charCodeAt(0)
var LOWER = 'a'.charCodeAt(0)
var UPPER = 'A'.charCodeAt(0)
var PLUS_URL_SAFE = '-'.charCodeAt(0)
var SLASH_URL_SAFE = '_'.charCodeAt(0)
function decode (elt) {
var code = elt.charCodeAt(0)
if (code === PLUS ||
code === PLUS_URL_SAFE)
return 62 // '+'
if (code === SLASH ||
code === SLASH_URL_SAFE)
return 63 // '/'
if (code < NUMBER)
return -1 //no match
if (code < NUMBER + 10)
return code - NUMBER + 26 + 26
if (code < UPPER + 26)
return code - UPPER
if (code < LOWER + 26)
return code - LOWER + 26
}
function b64ToByteArray (b64) {
var i, j, l, tmp, placeHolders, arr
if (b64.length % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
// the number of equal signs (place holders)
// if there are two placeholders, than the two characters before it
// represent one byte
// if there is only one, then the three characters before it represent 2 bytes
// this is just a cheap hack to not do indexOf twice
var len = b64.length
placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
// base64 is 4/3 + up to two characters of the original data
arr = new Arr(b64.length * 3 / 4 - placeHolders)
// if there are placeholders, only get up to the last complete 4 chars
l = placeHolders > 0 ? b64.length - 4 : b64.length
var L = 0
function push (v) {
arr[L++] = v
}
for (i = 0, j = 0; i < l; i += 4, j += 3) {
tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
push((tmp & 0xFF0000) >> 16)
push((tmp & 0xFF00) >> 8)
push(tmp & 0xFF)
}
if (placeHolders === 2) {
tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
push(tmp & 0xFF)
} else if (placeHolders === 1) {
tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
push((tmp >> 8) & 0xFF)
push(tmp & 0xFF)
}
return arr
}
function uint8ToBase64 (uint8) {
var i,
extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
output = "",
temp, length
function encode (num) {
return lookup.charAt(num)
}
function tripletToBase64 (num) {
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
}
// go through the array every three bytes, we'll deal with trailing stuff later
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
output += tripletToBase64(temp)
}
// pad the end with zeros, but make sure to not forget the extra bytes
switch (extraBytes) {
case 1:
temp = uint8[uint8.length - 1]
output += encode(temp >> 2)
output += encode((temp << 4) & 0x3F)
output += '=='
break
case 2:
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
output += encode(temp >> 10)
output += encode((temp >> 4) & 0x3F)
output += encode((temp << 2) & 0x3F)
output += '='
break
}
return output
}
exports.toByteArray = b64ToByteArray
exports.fromByteArray = uint8ToBase64
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
},{}],3:[function(require,module,exports){
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
var e, m
var eLen = nBytes * 8 - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var nBits = -7
var i = isLE ? (nBytes - 1) : 0
var d = isLE ? -1 : 1
var s = buffer[offset + i]
i += d
e = s & ((1 << (-nBits)) - 1)
s >>= (-nBits)
nBits += eLen
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
m = e & ((1 << (-nBits)) - 1)
e >>= (-nBits)
nBits += mLen
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
if (e === 0) {
e = 1 - eBias
} else if (e === eMax) {
return m ? NaN : ((s ? -1 : 1) * Infinity)
} else {
m = m + Math.pow(2, mLen)
e = e - eBias
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c
var eLen = nBytes * 8 - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
var i = isLE ? 0 : (nBytes - 1)
var d = isLE ? 1 : -1
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
value = Math.abs(value)
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0
e = eMax
} else {
e = Math.floor(Math.log(value) / Math.LN2)
if (value * (c = Math.pow(2, -e)) < 1) {
e--
c *= 2
}
if (e + eBias >= 1) {
value += rt / c
} else {
value += rt * Math.pow(2, 1 - eBias)
}
if (value * c >= 2) {
e++
c /= 2
}
if (e + eBias >= eMax) {
m = 0
e = eMax
} else if (e + eBias >= 1) {
m = (value * c - 1) * Math.pow(2, mLen)
e = e + eBias
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
e = 0
}
}
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
e = (e << mLen) | m
eLen += mLen
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
buffer[offset + i - d] |= s * 128
}
},{}],4:[function(require,module,exports){
var toString = {}.toString;
module.exports = Array.isArray || function (arr) {
return toString.call(arr) == '[object Array]';
};
},{}],5:[function(require,module,exports){
"use strict"
var pool = require("typedarray-pool")
module.exports = createSurfaceExtractor
//Helper macros
function array(i) {
return "a" + i
}
function data(i) {
return "d" + i
}
function cube(i,bitmask) {
return "c" + i + "_" + bitmask
}
function shape(i) {
return "s" + i
}
function stride(i,j) {
return "t" + i + "_" + j
}
function offset(i) {
return "o" + i
}
function scalar(i) {
return "x" + i
}
function pointer(i) {
return "p" + i
}
function delta(i,bitmask) {
return "d" + i + "_" + bitmask
}
function index(i) {
return "i" + i
}
function step(i,j) {
return "u" + i + "_" + j
}
function pcube(bitmask) {
return "b" + bitmask
}
function qcube(bitmask) {
return "y" + bitmask
}
function pdelta(bitmask) {
return "e" + bitmask
}
function vert(i) {
return "v" + i
}
var VERTEX_IDS = "V"
var PHASES = "P"
var VERTEX_COUNT = "N"
var POOL_SIZE = "Q"
var POINTER = "X"
var TEMPORARY = "T"
function permBitmask(dimension, mask, order) {
var r = 0
for(var i=0; i<dimension; ++i) {
if(mask & (1<<i)) {
r |= (1<<order[i])
}
}
return r
}
//Generates the surface procedure
function compileSurfaceProcedure(vertexFunc, faceFunc, phaseFunc, scalarArgs, order, typesig) {
var arrayArgs = typesig.length
var dimension = order.length
if(dimension < 2) {
throw new Error("ndarray-extract-contour: Dimension must be at least 2")
}
var funcName = "extractContour" + order.join("_")
var code = []
var vars = []
var args = []
//Assemble arguments
for(var i=0; i<arrayArgs; ++i) {
args.push(array(i))
}
for(var i=0; i<scalarArgs; ++i) {
args.push(scalar(i))
}
//Shape
for(var i=0; i<dimension; ++i) {
vars.push(shape(i) + "=" + array(0) + ".shape[" + i + "]|0")
}
//Data, stride, offset pointers
for(var i=0; i<arrayArgs; ++i) {
vars.push(data(i) + "=" + array(i) + ".data",
offset(i) + "=" + array(i) + ".offset|0")
for(var j=0; j<dimension; ++j) {
vars.push(stride(i,j) + "=" + array(i) + ".stride[" + j + "]|0")
}
}
//Pointer, delta and cube variables
for(var i=0; i<arrayArgs; ++i) {
vars.push(pointer(i) + "=" + offset(i))
vars.push(cube(i,0))
for(var j=1; j<(1<<dimension); ++j) {
var ptrStr = []
for(var k=0; k<dimension; ++k) {
if(j & (1<<k)) {
ptrStr.push("-" + stride(i,k))
}
}
vars.push(delta(i,j) + "=(" + ptrStr.join("") + ")|0")
vars.push(cube(i,j) + "=0")
}
}
//Create step variables
for(var i=0; i<arrayArgs; ++i) {
for(var j=0; j<dimension; ++j) {
var stepVal = [ stride(i,order[j]) ]
if(j > 0) {
stepVal.push(stride(i, order[j-1]) + "*" + shape(order[j-1]) )
}
vars.push(step(i,order[j]) + "=(" + stepVal.join("-") + ")|0")
}
}
//Create index variables
for(var i=0; i<dimension; ++i) {
vars.push(index(i) + "=0")
}
//Vertex count
vars.push(VERTEX_COUNT + "=0")
//Compute pool size, initialize pool step
var sizeVariable = ["2"]
for(var i=dimension-2; i>=0; --i) {
sizeVariable.push(shape(order[i]))
}
//Previous phases and vertex_ids
vars.push(POOL_SIZE + "=(" + sizeVariable.join("*") + ")|0",
PHASES + "=mallocUint32(" + POOL_SIZE + ")",
VERTEX_IDS + "=mallocUint32(" + POOL_SIZE + ")",
POINTER + "=0")
//Create cube variables for phases
vars.push(pcube(0) + "=0")
for(var j=1; j<(1<<dimension); ++j) {
var cubeDelta = []
var cubeStep = [ ]
for(var k=0; k<dimension; ++k) {
if(j & (1<<k)) {
if(cubeStep.length === 0) {
cubeDelta.push("1")
} else {
cubeDelta.unshift(cubeStep.join("*"))
}
}
cubeStep.push(shape(order[k]))
}
var signFlag = ""
if(cubeDelta[0].indexOf(shape(order[dimension-2])) < 0) {
signFlag = "-"
}
var jperm = permBitmask(dimension, j, order)
vars.push(pdelta(jperm) + "=(-" + cubeDelta.join("-") + ")|0",
qcube(jperm) + "=(" + signFlag + cubeDelta.join("-") + ")|0",
pcube(jperm) + "=0")
}
vars.push(vert(0) + "=0", TEMPORARY + "=0")
function forLoopBegin(i, start) {
code.push("for(", index(order[i]), "=", start, ";",
index(order[i]), "<", shape(order[i]), ";",
"++", index(order[i]), "){")
}
function forLoopEnd(i) {
for(var j=0; j<arrayArgs; ++j) {
code.push(pointer(j), "+=", step(j,order[i]), ";")
}
code.push("}")
}
function fillEmptySlice(k) {
for(var i=k-1; i>=0; --i) {
forLoopBegin(i, 0)
}
var phaseFuncArgs = []
for(var i=0; i<arrayArgs; ++i) {
if(typesig[i]) {
phaseFuncArgs.push(data(i) + ".get(" + pointer(i) + ")")
} else {
phaseFuncArgs.push(data(i) + "[" + pointer(i) + "]")
}
}
for(var i=0; i<scalarArgs; ++i) {
phaseFuncArgs.push(scalar(i))
}
code.push(PHASES, "[", POINTER, "++]=phase(", phaseFuncArgs.join(), ");")
for(var i=0; i<k; ++i) {
forLoopEnd(i)
}
for(var j=0; j<arrayArgs; ++j) {
code.push(pointer(j), "+=", step(j,order[k]), ";")
}
}
function processGridCell(mask) {
//Read in local data
for(var i=0; i<arrayArgs; ++i) {
if(typesig[i]) {
code.push(cube(i,0), "=", data(i), ".get(", pointer(i), ");")
} else {
code.push(cube(i,0), "=", data(i), "[", pointer(i), "];")
}
}
//Read in phase
var phaseFuncArgs = []
for(var i=0; i<arrayArgs; ++i) {
phaseFuncArgs.push(cube(i,0))
}
for(var i=0; i<scalarArgs; ++i) {
phaseFuncArgs.push(scalar(i))
}
code.push(pcube(0), "=", PHASES, "[", POINTER, "]=phase(", phaseFuncArgs.join(), ");")
//Read in other cube data
for(var j=1; j<(1<<dimension); ++j) {
code.push(pcube(j), "=", PHASES, "[", POINTER, "+", pdelta(j), "];")
}
//Check for boundary crossing
var vertexPredicate = []
for(var j=1; j<(1<<dimension); ++j) {
vertexPredicate.push("(" + pcube(0) + "!==" + pcube(j) + ")")
}
code.push("if(", vertexPredicate.join("||"), "){")
//Read in boundary data
var vertexArgs = []
for(var i=0; i<dimension; ++i) {
vertexArgs.push(index(i))
}
for(var i=0; i<arrayArgs; ++i) {
vertexArgs.push(cube(i,0))
for(var j=1; j<(1<<dimension); ++j) {
if(typesig[i]) {
code.push(cube(i,j), "=", data(i), ".get(", pointer(i), "+", delta(i,j), ");")
} else {
code.push(cube(i,j), "=", data(i), "[", pointer(i), "+", delta(i,j), "];")
}
vertexArgs.push(cube(i,j))
}
}
for(var i=0; i<(1<<dimension); ++i) {
vertexArgs.push(pcube(i))
}
for(var i=0; i<scalarArgs; ++i) {
vertexArgs.push(scalar(i))
}
//Generate vertex
code.push("vertex(", vertexArgs.join(), ");",
vert(0), "=", VERTEX_IDS, "[", POINTER, "]=", VERTEX_COUNT, "++;")
//Check for face crossings
var base = (1<<dimension)-1
var corner = pcube(base)
for(var j=0; j<dimension; ++j) {
if((mask & ~(1<<j))===0) {
//Check face
var subset = base^(1<<j)
var edge = pcube(subset)
var faceArgs = [ ]
for(var k=subset; k>0; k=(k-1)&subset) {
faceArgs.push(VERTEX_IDS + "[" + POINTER + "+" + pdelta(k) + "]")
}
faceArgs.push(vert(0))
for(var k=0; k<arrayArgs; ++k) {
if(j&1) {
faceArgs.push(cube(k,base), cube(k,subset))
} else {
faceArgs.push(cube(k,subset), cube(k,base))
}
}
if(j&1) {
faceArgs.push(corner, edge)
} else {
faceArgs.push(edge, corner)
}
for(var k=0; k<scalarArgs; ++k) {
faceArgs.push(scalar(k))
}
code.push("if(", corner, "!==", edge, "){",
"face(", faceArgs.join(), ")}")
}
}
//Increment pointer, close off if statement
code.push("}",
POINTER, "+=1;")
}
function flip() {
for(var j=1; j<(1<<dimension); ++j) {
code.push(TEMPORARY, "=", pdelta(j), ";",
pdelta(j), "=", qcube(j), ";",
qcube(j), "=", TEMPORARY, ";")
}
}
function createLoop(i, mask) {
if(i < 0) {
processGridCell(mask)
return
}
fillEmptySlice(i)
code.push("if(", shape(order[i]), ">0){",
index(order[i]), "=1;")
createLoop(i-1, mask|(1<<order[i]))
for(var j=0; j<arrayArgs; ++j) {
code.push(pointer(j), "+=", step(j,order[i]), ";")
}
if(i === dimension-1) {
code.push(POINTER, "=0;")
flip()
}
forLoopBegin(i, 2)
createLoop(i-1, mask)
if(i === dimension-1) {
code.push("if(", index(order[dimension-1]), "&1){",
POINTER, "=0;}")
flip()
}
forLoopEnd(i)
code.push("}")
}
createLoop(dimension-1, 0)
//Release scratch memory
code.push("freeUint32(", VERTEX_IDS, ");freeUint32(", PHASES, ");")
//Compile and link procedure
var procedureCode = [
"'use strict';",
"function ", funcName, "(", args.join(), "){",
"var ", vars.join(), ";",
code.join(""),
"}",
"return ", funcName ].join("")
var proc = new Function(
"vertex",
"face",
"phase",
"mallocUint32",
"freeUint32",
procedureCode)
return proc(
vertexFunc,
faceFunc,
phaseFunc,
pool.mallocUint32,
pool.freeUint32)
}
function createSurfaceExtractor(args) {
function error(msg) {
throw new Error("ndarray-extract-contour: " + msg)
}
if(typeof args !== "object") {
error("Must specify arguments")
}
var order = args.order
if(!Array.isArray(order)) {
error("Must specify order")
}
var arrays = args.arrayArguments||1
if(arrays < 1) {
error("Must have at least one array argument")
}
var scalars = args.scalarArguments||0
if(scalars < 0) {
error("Scalar arg count must be > 0")
}
if(typeof args.vertex !== "function") {
error("Must specify vertex creation function")
}
if(typeof args.cell !== "function") {
error("Must specify cell creation function")
}
if(typeof args.phase !== "function") {
error("Must specify phase function")
}
var getters = args.getters || []
var typesig = new Array(arrays)
for(var i=0; i<arrays; ++i) {
if(getters.indexOf(i) >= 0) {
typesig[i] = true
} else {
typesig[i] = false
}
}
return compileSurfaceProcedure(
args.vertex,
args.cell,
args.phase,
scalars,
order,
typesig)
}
},{"typedarray-pool":8}],6:[function(require,module,exports){
/**
* Bit twiddling hacks for JavaScript.
*
* Author: Mikola Lysenko
*
* Ported from Stanford bit twiddling hack library:
* http://graphics.stanford.edu/~seander/bithacks.html
*/
"use strict"; "use restrict";
//Number of bits in an integer
var INT_BITS = 32;
//Constants
exports.INT_BITS = INT_BITS;
exports.INT_MAX = 0x7fffffff;
exports.INT_MIN = -1<<(INT_BITS-1);
//Returns -1, 0, +1 depending on sign of x
exports.sign = function(v) {
return (v > 0) - (v < 0);
}
//Computes absolute value of integer
exports.abs = function(v) {
var mask = v >> (INT_BITS-1);
return (v ^ mask) - mask;
}
//Computes minimum of integers x and y
exports.min = function(x, y) {
return y ^ ((x ^ y) & -(x < y));
}
//Computes maximum of integers x and y
exports.max = function(x, y) {
return x ^ ((x ^ y) & -(x < y));
}
//Checks if a number is a power of two
exports.isPow2 = function(v) {
return !(v & (v-1)) && (!!v);
}
//Computes log base 2 of v
exports.log2 = function(v) {
var r, shift;
r = (v > 0xFFFF) << 4; v >>>= r;
shift = (v > 0xFF ) << 3; v >>>= shift; r |= shift;
shift = (v > 0xF ) << 2; v >>>= shift; r |= shift;
shift = (v > 0x3 ) << 1; v >>>= shift; r |= shift;
return r | (v >> 1);
}
//Computes log base 10 of v
exports.log10 = function(v) {
return (v >= 1000000000) ? 9 : (v >= 100000000) ? 8 : (v >= 10000000) ? 7 :
(v >= 1000000) ? 6 : (v >= 100000) ? 5 : (v >= 10000) ? 4 :
(v >= 1000) ? 3 : (v >= 100) ? 2 : (v >= 10) ? 1 : 0;
}
//Counts number of bits
exports.popCount = function(v) {
v = v - ((v >>> 1) & 0x55555555);
v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);
return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24;
}
//Counts number of trailing zeros
function countTrailingZeros(v) {
var c = 32;
v &= -v;
if (v) c--;
if (v & 0x0000FFFF) c -= 16;
if (v & 0x00FF00FF) c -= 8;
if (v & 0x0F0F0F0F) c -= 4;
if (v & 0x33333333) c -= 2;
if (v & 0x55555555) c -= 1;
return c;
}
exports.countTrailingZeros = countTrailingZeros;
//Rounds to next power of 2
exports.nextPow2 = function(v) {
v += v === 0;
--v;
v |= v >>> 1;
v |= v >>> 2;
v |= v >>> 4;
v |= v >>> 8;
v |= v >>> 16;
return v + 1;
}
//Rounds down to previous power of 2
exports.prevPow2 = function(v) {
v |= v >>> 1;
v |= v >>> 2;
v |= v >>> 4;
v |= v >>> 8;
v |= v >>> 16;
return v - (v>>>1);
}
//Computes parity of word
exports.parity = function(v) {
v ^= v >>> 16;
v ^= v >>> 8;
v ^= v >>> 4;
v &= 0xf;
return (0x6996 >>> v) & 1;
}
var REVERSE_TABLE = new Array(256);
(function(tab) {
for(var i=0; i<256; ++i) {
var v = i, r = i, s = 7;
for (v >>>= 1; v; v >>>= 1) {
r <<= 1;
r |= v & 1;
--s;
}
tab[i] = (r << s) & 0xff;
}
})(REVERSE_TABLE);
//Reverse bits in a 32 bit word
exports.reverse = function(v) {
return (REVERSE_TABLE[ v & 0xff] << 24) |
(REVERSE_TABLE[(v >>> 8) & 0xff] << 16) |
(REVERSE_TABLE[(v >>> 16) & 0xff] << 8) |
REVERSE_TABLE[(v >>> 24) & 0xff];
}
//Interleave bits of 2 coordinates with 16 bits. Useful for fast quadtree codes
exports.interleave2 = function(x, y) {
x &= 0xFFFF;
x = (x | (x << 8)) & 0x00FF00FF;
x = (x | (x << 4)) & 0x0F0F0F0F;
x = (x | (x << 2)) & 0x33333333;
x = (x | (x << 1)) & 0x55555555;
y &= 0xFFFF;
y = (y | (y << 8)) & 0x00FF00FF;
y = (y | (y << 4)) & 0x0F0F0F0F;
y = (y | (y << 2)) & 0x33333333;
y = (y | (y << 1)) & 0x55555555;
return x | (y << 1);
}
//Extracts the nth interleaved component
exports.deinterleave2 = function(v, n) {
v = (v >>> n) & 0x55555555;
v = (v | (v >>> 1)) & 0x33333333;
v = (v | (v >>> 2)) & 0x0F0F0F0F;
v = (v | (v >>> 4)) & 0x00FF00FF;
v = (v | (v >>> 16)) & 0x000FFFF;
return (v << 16) >> 16;
}
//Interleave bits of 3 coordinates, each with 10 bits. Useful for fast octree codes
exports.interleave3 = function(x, y, z) {
x &= 0x3FF;
x = (x | (x<<16)) & 4278190335;
x = (x | (x<<8)) & 251719695;
x = (x | (x<<4)) & 3272356035;
x = (x | (x<<2)) & 1227133513;
y &= 0x3FF;
y = (y | (y<<16)) & 4278190335;
y = (y | (y<<8)) & 251719695;
y = (y | (y<<4)) & 3272356035;
y = (y | (y<<2)) & 1227133513;
x |= (y << 1);
z &= 0x3FF;
z = (z | (z<<16)) & 4278190335;
z = (z | (z<<8)) & 251719695;
z = (z | (z<<4)) & 3272356035;
z = (z | (z<<2)) & 1227133513;
return x | (z << 2);
}
//Extracts nth interleaved component of a 3-tuple
exports.deinterleave3 = function(v, n) {
v = (v >>> n) & 1227133513;
v = (v | (v>>>2)) & 3272356035;
v = (v | (v>>>4)) & 251719695;
v = (v | (v>>>8)) & 4278190335;
v = (v | (v>>>16)) & 0x3FF;
return (v<<22)>>22;
}
//Computes next combination in colexicographic order (this is mistakenly called nextPermutation on the bit twiddling hacks page)
exports.nextCombination = function(v) {
var t = v | (v - 1);
return (t + 1) | (((~t & -~t) - 1) >>> (countTrailingZeros(v) + 1));
}
},{}],7:[function(require,module,exports){
"use strict"
function dupe_array(count, value, i) {
var c = count[i]|0
if(c <= 0) {
return []
}
var result = new Array(c), j
if(i === count.length-1) {
for(j=0; j<c; ++j) {
result[j] = value
}
} else {
for(j=0; j<c; ++j) {
result[j] = dupe_array(count, value, i+1)
}
}
return result
}
function dupe_number(count, value) {
var result, i
result = new Array(count)
for(i=0; i<count; ++i) {
result[i] = value
}
return result
}
function dupe(count, value) {
if(typeof value === "undefined") {
value = 0
}
switch(typeof count) {
case "number":
if(count > 0) {
return dupe_number(count|0, value)
}
break
case "object":
if(typeof (count.length) === "number") {
return dupe_array(count, value, 0)
}
break
}
return []
}
module.exports = dupe
},{}],8:[function(require,module,exports){
(function (global,Buffer){
'use strict'
var bits = require('bit-twiddle')
var dup = require('dup')
//Legacy pool support
if(!global.__TYPEDARRAY_POOL) {
global.__TYPEDARRAY_POOL = {
UINT8 : dup([32, 0])
, UINT16 : dup([32, 0])
, UINT32 : dup([32, 0])
, INT8 : dup([32, 0])
, INT16 : dup([32, 0])
, INT32 : dup([32, 0])
, FLOAT : dup([32, 0])
, DOUBLE : dup([32, 0])
, DATA : dup([32, 0])
, UINT8C : dup([32, 0])
, BUFFER : dup([32, 0])
}
}
var hasUint8C = (typeof Uint8ClampedArray) !== 'undefined'
var POOL = global.__TYPEDARRAY_POOL
//Upgrade pool
if(!POOL.UINT8C) {
POOL.UINT8C = dup([32, 0])
}
if(!POOL.BUFFER) {
POOL.BUFFER = dup([32, 0])
}
//New technique: Only allocate from ArrayBufferView and Buffer
var DATA = POOL.DATA
, BUFFER = POOL.BUFFER
exports.free = function free(array) {
if(Buffer.isBuffer(array)) {
BUFFER[bits.log2(array.length)].push(array)
} else {
if(Object.prototype.toString.call(array) !== '[object ArrayBuffer]') {
array = array.buffer
}
if(!array) {
return
}
var n = array.length || array.byteLength
var log_n = bits.log2(n)|0
DATA[log_n].push(array)
}
}
function freeArrayBuffer(buffer) {
if(!buffer) {
return
}
var n = buffer.length || buffer.byteLength
var log_n = bits.log2(n)
DATA[log_n].push(buffer)
}
function freeTypedArray(array) {
freeArrayBuffer(array.buffer)
}
exports.freeUint8 =
exports.freeUint16 =
exports.freeUint32 =
exports.freeInt8 =
exports.freeInt16 =
exports.freeInt32 =
exports.freeFloat32 =
exports.freeFloat =
exports.freeFloat64 =
exports.freeDouble =
exports.freeUint8Clamped =
exports.freeDataView = freeTypedArray
exports.freeArrayBuffer = freeArrayBuffer
exports.freeBuffer = function freeBuffer(array) {
BUFFER[bits.log2(array.length)].push(array)
}
exports.malloc = function malloc(n, dtype) {
if(dtype === undefined || dtype === 'arraybuffer') {
return mallocArrayBuffer(n)
} else {
switch(dtype) {
case 'uint8':
return mallocUint8(n)
case 'uint16':
return mallocUint16(n)
case 'uint32':
return mallocUint32(n)
case 'int8':
return mallocInt8(n)
case 'int16':
return mallocInt16(n)
case 'int32':
return mallocInt32(n)
case 'float':
case 'float32':
return mallocFloat(n)
case 'double':
case 'float64':
return mallocDouble(n)
case 'uint8_clamped':
return mallocUint8Clamped(n)
case 'buffer':
return mallocBuffer(n)
case 'data':
case 'dataview':
return mallocDataView(n)
default:
return null
}
}
return null
}
function mallocArrayBuffer(n) {
var n = bits.nextPow2(n)
var log_n = bits.log2(n)
var d = DATA[log_n]
if(d.length > 0) {
return d.pop()
}
return new ArrayBuffer(n)
}
exports.mallocArrayBuffer = mallocArrayBuffer
function mallocUint8(n) {
return new Uint8Array(mallocArrayBuffer(n), 0, n)
}
exports.mallocUint8 = mallocUint8
function mallocUint16(n) {
return new Uint16Array(mallocArrayBuffer(2*n), 0, n)
}
exports.mallocUint16 = mallocUint16
function mallocUint32(n) {
return new Uint32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocUint32 = mallocUint32
function mallocInt8(n) {
return new Int8Array(mallocArrayBuffer(n), 0, n)
}
exports.mallocInt8 = mallocInt8
function mallocInt16(n) {
return new Int16Array(mallocArrayBuffer(2*n), 0, n)
}
exports.mallocInt16 = mallocInt16
function mallocInt32(n) {
return new Int32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocInt32 = mallocInt32
function mallocFloat(n) {
return new Float32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocFloat32 = exports.mallocFloat = mallocFloat
function mallocDouble(n) {
return new Float64Array(mallocArrayBuffer(8*n), 0, n)
}
exports.mallocFloat64 = exports.mallocDouble = mallocDouble
function mallocUint8Clamped(n) {
if(hasUint8C) {
return new Uint8ClampedArray(mallocArrayBuffer(n), 0, n)
} else {
return mallocUint8(n)
}
}
exports.mallocUint8Clamped = mallocUint8Clamped
function mallocDataView(n) {
return new DataView(mallocArrayBuffer(n), 0, n)
}
exports.mallocDataView = mallocDataView
function mallocBuffer(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = BUFFER[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Buffer(n)
}
exports.mallocBuffer = mallocBuffer
exports.clearCache = function clearCache() {
for(var i=0; i<32; ++i) {
POOL.UINT8[i].length = 0
POOL.UINT16[i].length = 0
POOL.UINT32[i].length = 0
POOL.INT8[i].length = 0
POOL.INT16[i].length = 0
POOL.INT32[i].length = 0
POOL.FLOAT[i].length = 0
POOL.DOUBLE[i].length = 0
POOL.UINT8C[i].length = 0
DATA[i].length = 0
BUFFER[i].length = 0
}
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer)
//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9uZGFycmF5LWV4dHJhY3QtY29udG91ci9ub2RlX21vZHVsZXMvdHlwZWRhcnJheS1wb29sL3Bvb2wuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCdcblxudmFyIGJpdHMgPSByZXF1aXJlKCdiaXQtdHdpZGRsZScpXG52YXIgZHVwID0gcmVxdWlyZSgnZHVwJylcblxuLy9MZWdhY3kgcG9vbCBzdXBwb3J0XG5pZighZ2xvYmFsLl9fVFlQRURBUlJBWV9QT09MKSB7XG4gIGdsb2JhbC5fX1RZUEVEQVJSQVlfUE9PTCA9IHtcbiAgICAgIFVJTlQ4ICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQxNiAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQzMiAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDggICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDE2ICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDMyICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIEZMT0FUICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIERPVUJMRSAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIERBVEEgICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQ4QyAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIEJVRkZFUiAgOiBkdXAoWzMyLCAwXSlcbiAgfVxufVxuXG52YXIgaGFzVWludDhDID0gKHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSkgIT09ICd1bmRlZmluZWQnXG52YXIgUE9PTCA9IGdsb2JhbC5fX1RZUEVEQVJSQVlfUE9PTFxuXG4vL1VwZ3JhZGUgcG9vbFxuaWYoIVBPT0wuVUlOVDhDKSB7XG4gIFBPT0wuVUlOVDhDID0gZHVwKFszMiwgMF0pXG59XG5pZighUE9PTC5CVUZGRVIpIHtcbiAgUE9PTC5CVUZGRVIgPSBkdXAoWzMyLCAwXSlcbn1cblxuLy9OZXcgdGVjaG5pcXVlOiBPbmx5IGFsbG9jYXRlIGZyb20gQXJyYXlCdWZmZXJWaWV3IGFuZCBCdWZmZXJcbnZhciBEQVRBICAgID0gUE9PTC5EQVRBXG4gICwgQlVGRkVSICA9IFBPT0wuQlVGRkVSXG5cbmV4cG9ydHMuZnJlZSA9IGZ1bmN0aW9uIGZyZWUoYXJyYXkpIHtcbiAgaWYoQnVmZmVyLmlzQnVmZmVyKGFycmF5KSkge1xuICAgIEJVRkZFUltiaXRzLmxvZzIoYXJyYXkubGVuZ3RoKV0ucHVzaChhcnJheSlcbiAgfSBlbHNlIHtcbiAgICBpZihPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyYXkpICE9PSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nKSB7XG4gICAgICBhcnJheSA9IGFycmF5LmJ1ZmZlclxuICAgIH1cbiAgICBpZighYXJyYXkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB2YXIgbiA9IGFycmF5Lmxlbmd0aCB8fCBhcnJheS5ieXRlTGVuZ3RoXG4gICAgdmFyIGxvZ19uID0gYml0cy5sb2cyKG4pfDBcbiAgICBEQVRBW2xvZ19uXS5wdXNoKGFycmF5KVxuICB9XG59XG5cbmZ1bmN0aW9uIGZyZWVBcnJheUJ1ZmZlcihidWZmZXIpIHtcbiAgaWYoIWJ1ZmZlcikge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBuID0gYnVmZmVyLmxlbmd0aCB8fCBidWZmZXIuYnl0ZUxlbmd0aFxuICB2YXIgbG9nX24gPSBiaXRzLmxvZzIobilcbiAgREFUQVtsb2dfbl0ucHVzaChidWZmZXIpXG59XG5cbmZ1bmN0aW9uIGZyZWVUeXBlZEFycmF5KGFycmF5KSB7XG4gIGZyZWVBcnJheUJ1ZmZlcihhcnJheS5idWZmZXIpXG59XG5cbmV4cG9ydHMuZnJlZVVpbnQ4ID1cbmV4cG9ydHMuZnJlZVVpbnQxNiA9XG5leHBvcnRzLmZyZWVVaW50MzIgPVxuZXhwb3J0cy5mcmVlSW50OCA9XG5leHBvcnRzLmZyZWVJbnQxNiA9XG5leHBvcnRzLmZyZWVJbnQzMiA9XG5leHBvcnRzLmZyZWVGbG9hdDMyID0gXG5leHBvcnRzLmZyZWVGbG9hdCA9XG5leHBvcnRzLmZyZWVGbG9hdDY0ID0gXG5leHBvcnRzLmZyZWVEb3VibGUgPSBcbmV4cG9ydHMuZnJlZVVpbnQ4Q2xhbXBlZCA9IFxuZXhwb3J0cy5mcmVlRGF0YVZpZXcgPSBmcmVlVHlwZWRBcnJheVxuXG5leHBvcnRzLmZyZWVBcnJheUJ1ZmZlciA9IGZyZWVBcnJheUJ1ZmZlclxuXG5leHBvcnRzLmZyZWVCdWZmZXIgPSBmdW5jdGlvbiBmcmVlQnVmZmVyKGFycmF5KSB7XG4gIEJVRkZFUltiaXRzLmxvZzIoYXJyYXkubGVuZ3RoKV0ucHVzaChhcnJheSlcbn1cblxuZXhwb3J0cy5tYWxsb2MgPSBmdW5jdGlvbiBtYWxsb2MobiwgZHR5cGUpIHtcbiAgaWYoZHR5cGUgPT09IHVuZGVmaW5lZCB8fCBkdHlwZSA9PT0gJ2FycmF5YnVmZmVyJykge1xuICAgIHJldHVybiBtYWxsb2NBcnJheUJ1ZmZlcihuKVxuICB9IGVsc2Uge1xuICAgIHN3aXRjaChkdHlwZSkge1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgICByZXR1cm4gbWFsbG9jVWludDgobilcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICAgIHJldHVybiBtYWxsb2NVaW50MTYobilcbiAgICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICAgIHJldHVybiBtYWxsb2NVaW50MzIobilcbiAgICAgIGNhc2UgJ2ludDgnOlxuICAgICAgICByZXR1cm4gbWFsbG9jSW50OChuKVxuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgICByZXR1cm4gbWFsbG9jSW50MTYobilcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0ludDMyKG4pXG4gICAgICBjYXNlICdmbG9hdCc6XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0Zsb2F0KG4pXG4gICAgICBjYXNlICdkb3VibGUnOlxuICAgICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICAgIHJldHVybiBtYWxsb2NEb3VibGUobilcbiAgICAgIGNhc2UgJ3VpbnQ4X2NsYW1wZWQnOlxuICAgICAgICByZXR1cm4gbWFsbG9jVWludDhDbGFtcGVkKG4pXG4gICAgICBjYXNlICdidWZmZXInOlxuICAgICAgICByZXR1cm4gbWFsbG9jQnVmZmVyKG4pXG4gICAgICBjYXNlICdkYXRhJzpcbiAgICAgIGNhc2UgJ2RhdGF2aWV3JzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0RhdGFWaWV3KG4pXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsXG59XG5cbmZ1bmN0aW9uIG1hbGxvY0FycmF5QnVmZmVyKG4pIHtcbiAgdmFyIG4gPSBiaXRzLm5leHRQb3cyKG4pXG4gIHZhciBsb2dfbiA9IGJpdHMubG9nMihuKVxuICB2YXIgZCA9IERBVEFbbG9nX25dXG4gIGlmKGQubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBkLnBvcCgpXG4gIH1cbiAgcmV0dXJuIG5ldyBBcnJheUJ1ZmZlcihuKVxufVxuZXhwb3J0cy5tYWxsb2NBcnJheUJ1ZmZlciA9IG1hbGxvY0FycmF5QnVmZmVyXG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQ4KG4pIHtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KG1hbGxvY0FycmF5QnVmZmVyKG4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NVaW50OCA9IG1hbGxvY1VpbnQ4XG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQxNihuKSB7XG4gIHJldHVybiBuZXcgVWludDE2QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoMipuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jVWludDE2ID0gbWFsbG9jVWludDE2XG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQzMihuKSB7XG4gIHJldHVybiBuZXcgVWludDMyQXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoNCpuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jVWludDMyID0gbWFsbG9jVWludDMyXG5cbmZ1bmN0aW9uIG1hbGxvY0ludDgobikge1xuICByZXR1cm4gbmV3IEludDhBcnJheShtYWxsb2NBcnJheUJ1ZmZlcihuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jSW50OCA9IG1hbGxvY0ludDhcblxuZnVuY3Rpb24gbWFsbG9jSW50MTYobikge1xuICByZXR1cm4gbmV3IEludDE2QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoMipuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jSW50MTYgPSBtYWxsb2NJbnQxNlxuXG5mdW5jdGlvbiBtYWxsb2NJbnQzMihuKSB7XG4gIHJldHVybiBuZXcgSW50MzJBcnJheShtYWxsb2NBcnJheUJ1ZmZlcig0Km4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NJbnQzMiA9IG1hbGxvY0ludDMyXG5cbmZ1bmN0aW9uIG1hbGxvY0Zsb2F0KG4pIHtcbiAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoNCpuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jRmxvYXQzMiA9IGV4cG9ydHMubWFsbG9jRmxvYXQgPSBtYWxsb2NGbG9hdFxuXG5mdW5jdGlvbiBtYWxsb2NEb3VibGUobikge1xuICByZXR1cm4gbmV3IEZsb2F0NjRBcnJheShtYWxsb2NBcnJheUJ1ZmZlcig4Km4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NGbG9hdDY0ID0gZXhwb3J0cy5tYWxsb2NEb3VibGUgPSBtYWxsb2NEb3VibGVcblxuZnVuY3Rpb24gbWFsbG9jVWludDhDbGFtcGVkKG4pIHtcbiAgaWYoaGFzVWludDhDKSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OENsYW1wZWRBcnJheShtYWxsb2NBcnJheUJ1ZmZlcihuKSwgMCwgbilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbWFsbG9jVWludDgobilcbiAgfVxufVxuZXhwb3J0cy5tYWxsb2NVaW50OENsYW1wZWQgPSBtYWxsb2NVaW50OENsYW1wZWRcblxuZnVuY3Rpb24gbWFsbG9jRGF0YVZpZXcobikge1xuICByZXR1cm4gbmV3IERhdGFWaWV3KG1hbGxvY0FycmF5QnVmZmVyKG4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NEYXRhVmlldyA9IG1hbGxvY0RhdGFWaWV3XG5cbmZ1bmN0aW9uIG1hbGxvY0J1ZmZlcihuKSB7XG4gIG4gPSBiaXRzLm5leHRQb3cyKG4pXG4gIHZhciBsb2dfbiA9IGJpdHMubG9nMihuKVxuICB2YXIgY2FjaGUgPSBCVUZGRVJbbG9nX25dXG4gIGlmKGNhY2hlLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gY2FjaGUucG9wKClcbiAgfVxuICByZXR1cm4gbmV3IEJ1ZmZlcihuKVxufVxuZXhwb3J0cy5tYWxsb2NCdWZmZXIgPSBtYWxsb2NCdWZmZXJcblxuZXhwb3J0cy5jbGVhckNhY2hlID0gZnVuY3Rpb24gY2xlYXJDYWNoZSgpIHtcbiAgZm9yKHZhciBpPTA7IGk8MzI7ICsraSkge1xuICAgIFBPT0wuVUlOVDhbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuVUlOVDE2W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLlVJTlQzMltpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5JTlQ4W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLklOVDE2W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLklOVDMyW2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLkZMT0FUW2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLkRPVUJMRVtpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5VSU5UOENbaV0ubGVuZ3RoID0gMFxuICAgIERBVEFbaV0ubGVuZ3RoID0gMFxuICAgIEJVRkZFUltpXS5sZW5ndGggPSAwXG4gIH1cbn0iXX0=
},{"bit-twiddle":6,"buffer":1,"dup":7}],9:[function(require,module,exports){
// transliterated from the python snippet here:
// http://en.wikipedia.org/wiki/Lanczos_approximation
var g = 7;
var p = [
0.99999999999980993,
676.5203681218851,
-1259.1392167224028,
771.32342877765313,
-176.61502916214059,
12.507343278686905,
-0.13857109526572012,
9.9843695780195716e-6,
1.5056327351493116e-7
];
var g_ln = 607/128;
var p_ln = [
0.99999999999999709182,
57.156235665862923517,
-59.597960355475491248,
14.136097974741747174,
-0.49191381609762019978,
0.33994649984811888699e-4,
0.46523628927048575665e-4,
-0.98374475304879564677e-4,
0.15808870322491248884e-3,
-0.21026444172410488319e-3,
0.21743961811521264320e-3,
-0.16431810653676389022e-3,
0.84418223983852743293e-4,
-0.26190838401581408670e-4,
0.36899182659531622704e-5
];
// Spouge approximation (suitable for large arguments)
function lngamma(z) {
if(z < 0) return Number('0/0');
var x = p_ln[0];
for(var i = p_ln.length - 1; i > 0; --i) x += p_ln[i] / (z + i);
var t = z + g_ln + 0.5;
return .5*Math.log(2*Math.PI)+(z+.5)*Math.log(t)-t+Math.log(x)-Math.log(z);
}
module.exports = function gamma (z) {
if (z < 0.5) {
return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
}
else if(z > 100) return Math.exp(lngamma(z));
else {
z -= 1;
var x = p[0];
for (var i = 1; i < g + 2; i++) {
x += p[i] / (z + i);
}
var t = z + g + 0.5;
return Math.sqrt(2 * Math.PI)
* Math.pow(t, z + 0.5)
* Math.exp(-t)
* x
;
}
};
module.exports.log = lngamma;
},{}],10:[function(require,module,exports){
arguments[4][6][0].apply(exports,arguments)
},{"dup":6}],11:[function(require,module,exports){
arguments[4][7][0].apply(exports,arguments)
},{"dup":7}],12:[function(require,module,exports){
(function (global,Buffer){
'use strict'
var bits = require('bit-twiddle')
var dup = require('dup')
//Legacy pool support
if(!global.__TYPEDARRAY_POOL) {
global.__TYPEDARRAY_POOL = {
UINT8 : dup([32, 0])
, UINT16 : dup([32, 0])
, UINT32 : dup([32, 0])
, INT8 : dup([32, 0])
, INT16 : dup([32, 0])
, INT32 : dup([32, 0])
, FLOAT : dup([32, 0])
, DOUBLE : dup([32, 0])
, DATA : dup([32, 0])
, UINT8C : dup([32, 0])
, BUFFER : dup([32, 0])
}
}
var hasUint8C = (typeof Uint8ClampedArray) !== 'undefined'
var POOL = global.__TYPEDARRAY_POOL
//Upgrade pool
if(!POOL.UINT8C) {
POOL.UINT8C = dup([32, 0])
}
if(!POOL.BUFFER) {
POOL.BUFFER = dup([32, 0])
}
//New technique: Only allocate from ArrayBufferView and Buffer
var DATA = POOL.DATA
, BUFFER = POOL.BUFFER
exports.free = function free(array) {
if(Buffer.isBuffer(array)) {
BUFFER[bits.log2(array.length)].push(array)
} else {
if(Object.prototype.toString.call(array) !== '[object ArrayBuffer]') {
array = array.buffer
}
if(!array) {
return
}
var n = array.length || array.byteLength
var log_n = bits.log2(n)|0
DATA[log_n].push(array)
}
}
function freeArrayBuffer(buffer) {
if(!buffer) {
return
}
var n = buffer.length || buffer.byteLength
var log_n = bits.log2(n)
DATA[log_n].push(buffer)
}
function freeTypedArray(array) {
freeArrayBuffer(array.buffer)
}
exports.freeUint8 =
exports.freeUint16 =
exports.freeUint32 =
exports.freeInt8 =
exports.freeInt16 =
exports.freeInt32 =
exports.freeFloat32 =
exports.freeFloat =
exports.freeFloat64 =
exports.freeDouble =
exports.freeUint8Clamped =
exports.freeDataView = freeTypedArray
exports.freeArrayBuffer = freeArrayBuffer
exports.freeBuffer = function freeBuffer(array) {
BUFFER[bits.log2(array.length)].push(array)
}
exports.malloc = function malloc(n, dtype) {
if(dtype === undefined || dtype === 'arraybuffer') {
return mallocArrayBuffer(n)
} else {
switch(dtype) {
case 'uint8':
return mallocUint8(n)
case 'uint16':
return mallocUint16(n)
case 'uint32':
return mallocUint32(n)
case 'int8':
return mallocInt8(n)
case 'int16':
return mallocInt16(n)
case 'int32':
return mallocInt32(n)
case 'float':
case 'float32':
return mallocFloat(n)
case 'double':
case 'float64':
return mallocDouble(n)
case 'uint8_clamped':
return mallocUint8Clamped(n)
case 'buffer':
return mallocBuffer(n)
case 'data':
case 'dataview':
return mallocDataView(n)
default:
return null
}
}
return null
}
function mallocArrayBuffer(n) {
var n = bits.nextPow2(n)
var log_n = bits.log2(n)
var d = DATA[log_n]
if(d.length > 0) {
return d.pop()
}
return new ArrayBuffer(n)
}
exports.mallocArrayBuffer = mallocArrayBuffer
function mallocUint8(n) {
return new Uint8Array(mallocArrayBuffer(n), 0, n)
}
exports.mallocUint8 = mallocUint8
function mallocUint16(n) {
return new Uint16Array(mallocArrayBuffer(2*n), 0, n)
}
exports.mallocUint16 = mallocUint16
function mallocUint32(n) {
return new Uint32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocUint32 = mallocUint32
function mallocInt8(n) {
return new Int8Array(mallocArrayBuffer(n), 0, n)
}
exports.mallocInt8 = mallocInt8
function mallocInt16(n) {
return new Int16Array(mallocArrayBuffer(2*n), 0, n)
}
exports.mallocInt16 = mallocInt16
function mallocInt32(n) {
return new Int32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocInt32 = mallocInt32
function mallocFloat(n) {
return new Float32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocFloat32 = exports.mallocFloat = mallocFloat
function mallocDouble(n) {
return new Float64Array(mallocArrayBuffer(8*n), 0, n)
}
exports.mallocFloat64 = exports.mallocDouble = mallocDouble
function mallocUint8Clamped(n) {
if(hasUint8C) {
return new Uint8ClampedArray(mallocArrayBuffer(n), 0, n)
} else {
return mallocUint8(n)
}
}
exports.mallocUint8Clamped = mallocUint8Clamped
function mallocDataView(n) {
return new DataView(mallocArrayBuffer(n), 0, n)
}
exports.mallocDataView = mallocDataView
function mallocBuffer(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = BUFFER[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Buffer(n)
}
exports.mallocBuffer = mallocBuffer
exports.clearCache = function clearCache() {
for(var i=0; i<32; ++i) {
POOL.UINT8[i].length = 0
POOL.UINT16[i].length = 0
POOL.UINT32[i].length = 0
POOL.INT8[i].length = 0
POOL.INT16[i].length = 0
POOL.INT32[i].length = 0
POOL.FLOAT[i].length = 0
POOL.DOUBLE[i].length = 0
POOL.UINT8C[i].length = 0
DATA[i].length = 0
BUFFER[i].length = 0
}
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer)
//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy90cmlhbmd1bGF0ZS1oeXBlcmN1YmUvbm9kZV9tb2R1bGVzL3Blcm11dGF0aW9uLXBhcml0eS9ub2RlX21vZHVsZXMvdHlwZWRhcnJheS1wb29sL3Bvb2wuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCdcblxudmFyIGJpdHMgPSByZXF1aXJlKCdiaXQtdHdpZGRsZScpXG52YXIgZHVwID0gcmVxdWlyZSgnZHVwJylcblxuLy9MZWdhY3kgcG9vbCBzdXBwb3J0XG5pZighZ2xvYmFsLl9fVFlQRURBUlJBWV9QT09MKSB7XG4gIGdsb2JhbC5fX1RZUEVEQVJSQVlfUE9PTCA9IHtcbiAgICAgIFVJTlQ4ICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQxNiAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQzMiAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDggICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDE2ICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDMyICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIEZMT0FUICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIERPVUJMRSAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIERBVEEgICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQ4QyAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIEJVRkZFUiAgOiBkdXAoWzMyLCAwXSlcbiAgfVxufVxuXG52YXIgaGFzVWludDhDID0gKHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSkgIT09ICd1bmRlZmluZWQnXG52YXIgUE9PTCA9IGdsb2JhbC5fX1RZUEVEQVJSQVlfUE9PTFxuXG4vL1VwZ3JhZGUgcG9vbFxuaWYoIVBPT0wuVUlOVDhDKSB7XG4gIFBPT0wuVUlOVDhDID0gZHVwKFszMiwgMF0pXG59XG5pZighUE9PTC5CVUZGRVIpIHtcbiAgUE9PTC5CVUZGRVIgPSBkdXAoWzMyLCAwXSlcbn1cblxuLy9OZXcgdGVjaG5pcXVlOiBPbmx5IGFsbG9jYXRlIGZyb20gQXJyYXlCdWZmZXJWaWV3IGFuZCBCdWZmZXJcbnZhciBEQVRBICAgID0gUE9PTC5EQVRBXG4gICwgQlVGRkVSICA9IFBPT0wuQlVGRkVSXG5cbmV4cG9ydHMuZnJlZSA9IGZ1bmN0aW9uIGZyZWUoYXJyYXkpIHtcbiAgaWYoQnVmZmVyLmlzQnVmZmVyKGFycmF5KSkge1xuICAgIEJVRkZFUltiaXRzLmxvZzIoYXJyYXkubGVuZ3RoKV0ucHVzaChhcnJheSlcbiAgfSBlbHNlIHtcbiAgICBpZihPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyYXkpICE9PSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nKSB7XG4gICAgICBhcnJheSA9IGFycmF5LmJ1ZmZlclxuICAgIH1cbiAgICBpZighYXJyYXkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB2YXIgbiA9IGFycmF5Lmxlbmd0aCB8fCBhcnJheS5ieXRlTGVuZ3RoXG4gICAgdmFyIGxvZ19uID0gYml0cy5sb2cyKG4pfDBcbiAgICBEQVRBW2xvZ19uXS5wdXNoKGFycmF5KVxuICB9XG59XG5cbmZ1bmN0aW9uIGZyZWVBcnJheUJ1ZmZlcihidWZmZXIpIHtcbiAgaWYoIWJ1ZmZlcikge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBuID0gYnVmZmVyLmxlbmd0aCB8fCBidWZmZXIuYnl0ZUxlbmd0aFxuICB2YXIgbG9nX24gPSBiaXRzLmxvZzIobilcbiAgREFUQVtsb2dfbl0ucHVzaChidWZmZXIpXG59XG5cbmZ1bmN0aW9uIGZyZWVUeXBlZEFycmF5KGFycmF5KSB7XG4gIGZyZWVBcnJheUJ1ZmZlcihhcnJheS5idWZmZXIpXG59XG5cbmV4cG9ydHMuZnJlZVVpbnQ4ID1cbmV4cG9ydHMuZnJlZVVpbnQxNiA9XG5leHBvcnRzLmZyZWVVaW50MzIgPVxuZXhwb3J0cy5mcmVlSW50OCA9XG5leHBvcnRzLmZyZWVJbnQxNiA9XG5leHBvcnRzLmZyZWVJbnQzMiA9XG5leHBvcnRzLmZyZWVGbG9hdDMyID0gXG5leHBvcnRzLmZyZWVGbG9hdCA9XG5leHBvcnRzLmZyZWVGbG9hdDY0ID0gXG5leHBvcnRzLmZyZWVEb3VibGUgPSBcbmV4cG9ydHMuZnJlZVVpbnQ4Q2xhbXBlZCA9IFxuZXhwb3J0cy5mcmVlRGF0YVZpZXcgPSBmcmVlVHlwZWRBcnJheVxuXG5leHBvcnRzLmZyZWVBcnJheUJ1ZmZlciA9IGZyZWVBcnJheUJ1ZmZlclxuXG5leHBvcnRzLmZyZWVCdWZmZXIgPSBmdW5jdGlvbiBmcmVlQnVmZmVyKGFycmF5KSB7XG4gIEJVRkZFUltiaXRzLmxvZzIoYXJyYXkubGVuZ3RoKV0ucHVzaChhcnJheSlcbn1cblxuZXhwb3J0cy5tYWxsb2MgPSBmdW5jdGlvbiBtYWxsb2MobiwgZHR5cGUpIHtcbiAgaWYoZHR5cGUgPT09IHVuZGVmaW5lZCB8fCBkdHlwZSA9PT0gJ2FycmF5YnVmZmVyJykge1xuICAgIHJldHVybiBtYWxsb2NBcnJheUJ1ZmZlcihuKVxuICB9IGVsc2Uge1xuICAgIHN3aXRjaChkdHlwZSkge1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgICByZXR1cm4gbWFsbG9jVWludDgobilcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICAgIHJldHVybiBtYWxsb2NVaW50MTYobilcbiAgICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICAgIHJldHVybiBtYWxsb2NVaW50MzIobilcbiAgICAgIGNhc2UgJ2ludDgnOlxuICAgICAgICByZXR1cm4gbWFsbG9jSW50OChuKVxuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgICByZXR1cm4gbWFsbG9jSW50MTYobilcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0ludDMyKG4pXG4gICAgICBjYXNlICdmbG9hdCc6XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0Zsb2F0KG4pXG4gICAgICBjYXNlICdkb3VibGUnOlxuICAgICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICAgIHJldHVybiBtYWxsb2NEb3VibGUobilcbiAgICAgIGNhc2UgJ3VpbnQ4X2NsYW1wZWQnOlxuICAgICAgICByZXR1cm4gbWFsbG9jVWludDhDbGFtcGVkKG4pXG4gICAgICBjYXNlICdidWZmZXInOlxuICAgICAgICByZXR1cm4gbWFsbG9jQnVmZmVyKG4pXG4gICAgICBjYXNlICdkYXRhJzpcbiAgICAgIGNhc2UgJ2RhdGF2aWV3JzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0RhdGFWaWV3KG4pXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsXG59XG5cbmZ1bmN0aW9uIG1hbGxvY0FycmF5QnVmZmVyKG4pIHtcbiAgdmFyIG4gPSBiaXRzLm5leHRQb3cyKG4pXG4gIHZhciBsb2dfbiA9IGJpdHMubG9nMihuKVxuICB2YXIgZCA9IERBVEFbbG9nX25dXG4gIGlmKGQubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBkLnBvcCgpXG4gIH1cbiAgcmV0dXJuIG5ldyBBcnJheUJ1ZmZlcihuKVxufVxuZXhwb3J0cy5tYWxsb2NBcnJheUJ1ZmZlciA9IG1hbGxvY0FycmF5QnVmZmVyXG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQ4KG4pIHtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KG1hbGxvY0FycmF5QnVmZmVyKG4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NVaW50OCA9IG1hbGxvY1VpbnQ4XG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQxNihuKSB7XG4gIHJldHVybiBuZXcgVWludDE2QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoMipuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jVWludDE2ID0gbWFsbG9jVWludDE2XG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQzMihuKSB7XG4gIHJldHVybiBuZXcgVWludDMyQXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoNCpuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jVWludDMyID0gbWFsbG9jVWludDMyXG5cbmZ1bmN0aW9uIG1hbGxvY0ludDgobikge1xuICByZXR1cm4gbmV3IEludDhBcnJheShtYWxsb2NBcnJheUJ1ZmZlcihuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jSW50OCA9IG1hbGxvY0ludDhcblxuZnVuY3Rpb24gbWFsbG9jSW50MTYobikge1xuICByZXR1cm4gbmV3IEludDE2QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoMipuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jSW50MTYgPSBtYWxsb2NJbnQxNlxuXG5mdW5jdGlvbiBtYWxsb2NJbnQzMihuKSB7XG4gIHJldHVybiBuZXcgSW50MzJBcnJheShtYWxsb2NBcnJheUJ1ZmZlcig0Km4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NJbnQzMiA9IG1hbGxvY0ludDMyXG5cbmZ1bmN0aW9uIG1hbGxvY0Zsb2F0KG4pIHtcbiAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoNCpuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jRmxvYXQzMiA9IGV4cG9ydHMubWFsbG9jRmxvYXQgPSBtYWxsb2NGbG9hdFxuXG5mdW5jdGlvbiBtYWxsb2NEb3VibGUobikge1xuICByZXR1cm4gbmV3IEZsb2F0NjRBcnJheShtYWxsb2NBcnJheUJ1ZmZlcig4Km4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NGbG9hdDY0ID0gZXhwb3J0cy5tYWxsb2NEb3VibGUgPSBtYWxsb2NEb3VibGVcblxuZnVuY3Rpb24gbWFsbG9jVWludDhDbGFtcGVkKG4pIHtcbiAgaWYoaGFzVWludDhDKSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OENsYW1wZWRBcnJheShtYWxsb2NBcnJheUJ1ZmZlcihuKSwgMCwgbilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbWFsbG9jVWludDgobilcbiAgfVxufVxuZXhwb3J0cy5tYWxsb2NVaW50OENsYW1wZWQgPSBtYWxsb2NVaW50OENsYW1wZWRcblxuZnVuY3Rpb24gbWFsbG9jRGF0YVZpZXcobikge1xuICByZXR1cm4gbmV3IERhdGFWaWV3KG1hbGxvY0FycmF5QnVmZmVyKG4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NEYXRhVmlldyA9IG1hbGxvY0RhdGFWaWV3XG5cbmZ1bmN0aW9uIG1hbGxvY0J1ZmZlcihuKSB7XG4gIG4gPSBiaXRzLm5leHRQb3cyKG4pXG4gIHZhciBsb2dfbiA9IGJpdHMubG9nMihuKVxuICB2YXIgY2FjaGUgPSBCVUZGRVJbbG9nX25dXG4gIGlmKGNhY2hlLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gY2FjaGUucG9wKClcbiAgfVxuICByZXR1cm4gbmV3IEJ1ZmZlcihuKVxufVxuZXhwb3J0cy5tYWxsb2NCdWZmZXIgPSBtYWxsb2NCdWZmZXJcblxuZXhwb3J0cy5jbGVhckNhY2hlID0gZnVuY3Rpb24gY2xlYXJDYWNoZSgpIHtcbiAgZm9yKHZhciBpPTA7IGk8MzI7ICsraSkge1xuICAgIFBPT0wuVUlOVDhbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuVUlOVDE2W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLlVJTlQzMltpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5JTlQ4W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLklOVDE2W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLklOVDMyW2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLkZMT0FUW2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLkRPVUJMRVtpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5VSU5UOENbaV0ubGVuZ3RoID0gMFxuICAgIERBVEFbaV0ubGVuZ3RoID0gMFxuICAgIEJVRkZFUltpXS5sZW5ndGggPSAwXG4gIH1cbn0iXX0=
},{"bit-twiddle":10,"buffer":1,"dup":11}],13:[function(require,module,exports){
"use strict"
module.exports = permutationSign
var BRUTE_FORCE_CUTOFF = 32
var pool = require("typedarray-pool")
function permutationSign(p) {
var n = p.length
if(n < BRUTE_FORCE_CUTOFF) {
//Use quadratic algorithm for small n
var sgn = 1
for(var i=0; i<n; ++i) {
for(var j=0; j<i; ++j) {
if(p[i] < p[j]) {
sgn = -sgn
} else if(p[i] === p[j]) {
return 0
}
}
}
return sgn
} else {
//Otherwise use linear time algorithm
var visited = pool.mallocUint8(n)
for(var i=0; i<n; ++i) {
visited[i] = 0
}
var sgn = 1
for(var i=0; i<n; ++i) {
if(!visited[i]) {
var count = 1
visited[i] = 1
for(var j=p[i]; j!==i; j=p[j]) {
if(visited[j]) {
pool.freeUint8(visited)
return 0
}
count += 1
visited[j] = 1
}
if(!(count & 1)) {
sgn = -sgn
}
}
}
pool.freeUint8(visited)
return sgn
}
}
},{"typedarray-pool":12}],14:[function(require,module,exports){
"use strict"
var pool = require("typedarray-pool")
var inverse = require("invert-permutation")
function rank(permutation) {
var n = permutation.length
switch(n) {
case 0:
case 1:
return 0
case 2:
return permutation[1]
default:
break
}
var p = pool.mallocUint32(n)
var pinv = pool.mallocUint32(n)
var r = 0, s, t, i
inverse(permutation, pinv)
for(i=0; i<n; ++i) {
p[i] = permutation[i]
}
for(i=n-1; i>0; --i) {
t = pinv[i]
s = p[i]
p[i] = p[t]
p[t] = s
pinv[i] = pinv[s]
pinv[s] = t
r = (r + s) * i
}
pool.freeUint32(pinv)
pool.freeUint32(p)
return r
}
function unrank(n, r, p) {
switch(n) {
case 0:
if(p) { return p }
return []
case 1:
if(p) {
p[0] = 0
return p
} else {
return [0]
}
case 2:
if(p) {
if(r) {
p[0] = 0
p[1] = 1
} else {
p[0] = 1
p[1] = 0
}
return p
} else {
return r ? [0,1] : [1,0]
}
default:
break
}
p = p || new Array(n)
var s, t, i, nf=1
p[0] = 0
for(i=1; i<n; ++i) {
p[i] = i
nf = (nf*i)|0
}
for(i=n-1; i>0; --i) {
s = (r / nf)|0
r = (r - s * nf)|0
nf = (nf / i)|0
t = p[i]|0
p[i] = p[s]|0
p[s] = t|0
}
return p
}
exports.rank = rank
exports.unrank = unrank
},{"invert-permutation":15,"typedarray-pool":18}],15:[function(require,module,exports){
"use strict"
function invertPermutation(pi, result) {
result = result || new Array(pi.length)
for(var i=0; i<pi.length; ++i) {
result[pi[i]] = i
}
return result
}
module.exports = invertPermutation
},{}],16:[function(require,module,exports){
arguments[4][6][0].apply(exports,arguments)
},{"dup":6}],17:[function(require,module,exports){
arguments[4][7][0].apply(exports,arguments)
},{"dup":7}],18:[function(require,module,exports){
(function (global,Buffer){
'use strict'
var bits = require('bit-twiddle')
var dup = require('dup')
//Legacy pool support
if(!global.__TYPEDARRAY_POOL) {
global.__TYPEDARRAY_POOL = {
UINT8 : dup([32, 0])
, UINT16 : dup([32, 0])
, UINT32 : dup([32, 0])
, INT8 : dup([32, 0])
, INT16 : dup([32, 0])
, INT32 : dup([32, 0])
, FLOAT : dup([32, 0])
, DOUBLE : dup([32, 0])
, DATA : dup([32, 0])
, UINT8C : dup([32, 0])
, BUFFER : dup([32, 0])
}
}
var hasUint8C = (typeof Uint8ClampedArray) !== 'undefined'
var POOL = global.__TYPEDARRAY_POOL
//Upgrade pool
if(!POOL.UINT8C) {
POOL.UINT8C = dup([32, 0])
}
if(!POOL.BUFFER) {
POOL.BUFFER = dup([32, 0])
}
//New technique: Only allocate from ArrayBufferView and Buffer
var DATA = POOL.DATA
, BUFFER = POOL.BUFFER
exports.free = function free(array) {
if(Buffer.isBuffer(array)) {
BUFFER[bits.log2(array.length)].push(array)
} else {
if(Object.prototype.toString.call(array) !== '[object ArrayBuffer]') {
array = array.buffer
}
if(!array) {
return
}
var n = array.length || array.byteLength
var log_n = bits.log2(n)|0
DATA[log_n].push(array)
}
}
function freeArrayBuffer(buffer) {
if(!buffer) {
return
}
var n = buffer.length || buffer.byteLength
var log_n = bits.log2(n)
DATA[log_n].push(buffer)
}
function freeTypedArray(array) {
freeArrayBuffer(array.buffer)
}
exports.freeUint8 =
exports.freeUint16 =
exports.freeUint32 =
exports.freeInt8 =
exports.freeInt16 =
exports.freeInt32 =
exports.freeFloat32 =
exports.freeFloat =
exports.freeFloat64 =
exports.freeDouble =
exports.freeUint8Clamped =
exports.freeDataView = freeTypedArray
exports.freeArrayBuffer = freeArrayBuffer
exports.freeBuffer = function freeBuffer(array) {
BUFFER[bits.log2(array.length)].push(array)
}
exports.malloc = function malloc(n, dtype) {
if(dtype === undefined || dtype === 'arraybuffer') {
return mallocArrayBuffer(n)
} else {
switch(dtype) {
case 'uint8':
return mallocUint8(n)
case 'uint16':
return mallocUint16(n)
case 'uint32':
return mallocUint32(n)
case 'int8':
return mallocInt8(n)
case 'int16':
return mallocInt16(n)
case 'int32':
return mallocInt32(n)
case 'float':
case 'float32':
return mallocFloat(n)
case 'double':
case 'float64':
return mallocDouble(n)
case 'uint8_clamped':
return mallocUint8Clamped(n)
case 'buffer':
return mallocBuffer(n)
case 'data':
case 'dataview':
return mallocDataView(n)
default:
return null
}
}
return null
}
function mallocArrayBuffer(n) {
var n = bits.nextPow2(n)
var log_n = bits.log2(n)
var d = DATA[log_n]
if(d.length > 0) {
return d.pop()
}
return new ArrayBuffer(n)
}
exports.mallocArrayBuffer = mallocArrayBuffer
function mallocUint8(n) {
return new Uint8Array(mallocArrayBuffer(n), 0, n)
}
exports.mallocUint8 = mallocUint8
function mallocUint16(n) {
return new Uint16Array(mallocArrayBuffer(2*n), 0, n)
}
exports.mallocUint16 = mallocUint16
function mallocUint32(n) {
return new Uint32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocUint32 = mallocUint32
function mallocInt8(n) {
return new Int8Array(mallocArrayBuffer(n), 0, n)
}
exports.mallocInt8 = mallocInt8
function mallocInt16(n) {
return new Int16Array(mallocArrayBuffer(2*n), 0, n)
}
exports.mallocInt16 = mallocInt16
function mallocInt32(n) {
return new Int32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocInt32 = mallocInt32
function mallocFloat(n) {
return new Float32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocFloat32 = exports.mallocFloat = mallocFloat
function mallocDouble(n) {
return new Float64Array(mallocArrayBuffer(8*n), 0, n)
}
exports.mallocFloat64 = exports.mallocDouble = mallocDouble
function mallocUint8Clamped(n) {
if(hasUint8C) {
return new Uint8ClampedArray(mallocArrayBuffer(n), 0, n)
} else {
return mallocUint8(n)
}
}
exports.mallocUint8Clamped = mallocUint8Clamped
function mallocDataView(n) {
return new DataView(mallocArrayBuffer(n), 0, n)
}
exports.mallocDataView = mallocDataView
function mallocBuffer(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = BUFFER[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Buffer(n)
}
exports.mallocBuffer = mallocBuffer
exports.clearCache = function clearCache() {
for(var i=0; i<32; ++i) {
POOL.UINT8[i].length = 0
POOL.UINT16[i].length = 0
POOL.UINT32[i].length = 0
POOL.INT8[i].length = 0
POOL.INT16[i].length = 0
POOL.INT32[i].length = 0
POOL.FLOAT[i].length = 0
POOL.DOUBLE[i].length = 0
POOL.UINT8C[i].length = 0
DATA[i].length = 0
BUFFER[i].length = 0
}
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer)
//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy90cmlhbmd1bGF0ZS1oeXBlcmN1YmUvbm9kZV9tb2R1bGVzL3Blcm11dGF0aW9uLXJhbmsvbm9kZV9tb2R1bGVzL3R5cGVkYXJyYXktcG9vbC9wb29sLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnXG5cbnZhciBiaXRzID0gcmVxdWlyZSgnYml0LXR3aWRkbGUnKVxudmFyIGR1cCA9IHJlcXVpcmUoJ2R1cCcpXG5cbi8vTGVnYWN5IHBvb2wgc3VwcG9ydFxuaWYoIWdsb2JhbC5fX1RZUEVEQVJSQVlfUE9PTCkge1xuICBnbG9iYWwuX19UWVBFREFSUkFZX1BPT0wgPSB7XG4gICAgICBVSU5UOCAgIDogZHVwKFszMiwgMF0pXG4gICAgLCBVSU5UMTYgIDogZHVwKFszMiwgMF0pXG4gICAgLCBVSU5UMzIgIDogZHVwKFszMiwgMF0pXG4gICAgLCBJTlQ4ICAgIDogZHVwKFszMiwgMF0pXG4gICAgLCBJTlQxNiAgIDogZHVwKFszMiwgMF0pXG4gICAgLCBJTlQzMiAgIDogZHVwKFszMiwgMF0pXG4gICAgLCBGTE9BVCAgIDogZHVwKFszMiwgMF0pXG4gICAgLCBET1VCTEUgIDogZHVwKFszMiwgMF0pXG4gICAgLCBEQVRBICAgIDogZHVwKFszMiwgMF0pXG4gICAgLCBVSU5UOEMgIDogZHVwKFszMiwgMF0pXG4gICAgLCBCVUZGRVIgIDogZHVwKFszMiwgMF0pXG4gIH1cbn1cblxudmFyIGhhc1VpbnQ4QyA9ICh0eXBlb2YgVWludDhDbGFtcGVkQXJyYXkpICE9PSAndW5kZWZpbmVkJ1xudmFyIFBPT0wgPSBnbG9iYWwuX19UWVBFREFSUkFZX1BPT0xcblxuLy9VcGdyYWRlIHBvb2xcbmlmKCFQT09MLlVJTlQ4Qykge1xuICBQT09MLlVJTlQ4QyA9IGR1cChbMzIsIDBdKVxufVxuaWYoIVBPT0wuQlVGRkVSKSB7XG4gIFBPT0wuQlVGRkVSID0gZHVwKFszMiwgMF0pXG59XG5cbi8vTmV3IHRlY2huaXF1ZTogT25seSBhbGxvY2F0ZSBmcm9tIEFycmF5QnVmZmVyVmlldyBhbmQgQnVmZmVyXG52YXIgREFUQSAgICA9IFBPT0wuREFUQVxuICAsIEJVRkZFUiAgPSBQT09MLkJVRkZFUlxuXG5leHBvcnRzLmZyZWUgPSBmdW5jdGlvbiBmcmVlKGFycmF5KSB7XG4gIGlmKEJ1ZmZlci5pc0J1ZmZlcihhcnJheSkpIHtcbiAgICBCVUZGRVJbYml0cy5sb2cyKGFycmF5Lmxlbmd0aCldLnB1c2goYXJyYXkpXG4gIH0gZWxzZSB7XG4gICAgaWYoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFycmF5KSAhPT0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJykge1xuICAgICAgYXJyYXkgPSBhcnJheS5idWZmZXJcbiAgICB9XG4gICAgaWYoIWFycmF5KSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgdmFyIG4gPSBhcnJheS5sZW5ndGggfHwgYXJyYXkuYnl0ZUxlbmd0aFxuICAgIHZhciBsb2dfbiA9IGJpdHMubG9nMihuKXwwXG4gICAgREFUQVtsb2dfbl0ucHVzaChhcnJheSlcbiAgfVxufVxuXG5mdW5jdGlvbiBmcmVlQXJyYXlCdWZmZXIoYnVmZmVyKSB7XG4gIGlmKCFidWZmZXIpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgbiA9IGJ1ZmZlci5sZW5ndGggfHwgYnVmZmVyLmJ5dGVMZW5ndGhcbiAgdmFyIGxvZ19uID0gYml0cy5sb2cyKG4pXG4gIERBVEFbbG9nX25dLnB1c2goYnVmZmVyKVxufVxuXG5mdW5jdGlvbiBmcmVlVHlwZWRBcnJheShhcnJheSkge1xuICBmcmVlQXJyYXlCdWZmZXIoYXJyYXkuYnVmZmVyKVxufVxuXG5leHBvcnRzLmZyZWVVaW50OCA9XG5leHBvcnRzLmZyZWVVaW50MTYgPVxuZXhwb3J0cy5mcmVlVWludDMyID1cbmV4cG9ydHMuZnJlZUludDggPVxuZXhwb3J0cy5mcmVlSW50MTYgPVxuZXhwb3J0cy5mcmVlSW50MzIgPVxuZXhwb3J0cy5mcmVlRmxvYXQzMiA9IFxuZXhwb3J0cy5mcmVlRmxvYXQgPVxuZXhwb3J0cy5mcmVlRmxvYXQ2NCA9IFxuZXhwb3J0cy5mcmVlRG91YmxlID0gXG5leHBvcnRzLmZyZWVVaW50OENsYW1wZWQgPSBcbmV4cG9ydHMuZnJlZURhdGFWaWV3ID0gZnJlZVR5cGVkQXJyYXlcblxuZXhwb3J0cy5mcmVlQXJyYXlCdWZmZXIgPSBmcmVlQXJyYXlCdWZmZXJcblxuZXhwb3J0cy5mcmVlQnVmZmVyID0gZnVuY3Rpb24gZnJlZUJ1ZmZlcihhcnJheSkge1xuICBCVUZGRVJbYml0cy5sb2cyKGFycmF5Lmxlbmd0aCldLnB1c2goYXJyYXkpXG59XG5cbmV4cG9ydHMubWFsbG9jID0gZnVuY3Rpb24gbWFsbG9jKG4sIGR0eXBlKSB7XG4gIGlmKGR0eXBlID09PSB1bmRlZmluZWQgfHwgZHR5cGUgPT09ICdhcnJheWJ1ZmZlcicpIHtcbiAgICByZXR1cm4gbWFsbG9jQXJyYXlCdWZmZXIobilcbiAgfSBlbHNlIHtcbiAgICBzd2l0Y2goZHR5cGUpIHtcbiAgICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY1VpbnQ4KG4pXG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgICByZXR1cm4gbWFsbG9jVWludDE2KG4pXG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gbWFsbG9jVWludDMyKG4pXG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0ludDgobilcbiAgICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0ludDE2KG4pXG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICAgIHJldHVybiBtYWxsb2NJbnQzMihuKVxuICAgICAgY2FzZSAnZmxvYXQnOlxuICAgICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICAgIHJldHVybiBtYWxsb2NGbG9hdChuKVxuICAgICAgY2FzZSAnZG91YmxlJzpcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gbWFsbG9jRG91YmxlKG4pXG4gICAgICBjYXNlICd1aW50OF9jbGFtcGVkJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY1VpbnQ4Q2xhbXBlZChuKVxuICAgICAgY2FzZSAnYnVmZmVyJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0J1ZmZlcihuKVxuICAgICAgY2FzZSAnZGF0YSc6XG4gICAgICBjYXNlICdkYXRhdmlldyc6XG4gICAgICAgIHJldHVybiBtYWxsb2NEYXRhVmlldyhuKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbFxufVxuXG5mdW5jdGlvbiBtYWxsb2NBcnJheUJ1ZmZlcihuKSB7XG4gIHZhciBuID0gYml0cy5uZXh0UG93MihuKVxuICB2YXIgbG9nX24gPSBiaXRzLmxvZzIobilcbiAgdmFyIGQgPSBEQVRBW2xvZ19uXVxuICBpZihkLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gZC5wb3AoKVxuICB9XG4gIHJldHVybiBuZXcgQXJyYXlCdWZmZXIobilcbn1cbmV4cG9ydHMubWFsbG9jQXJyYXlCdWZmZXIgPSBtYWxsb2NBcnJheUJ1ZmZlclxuXG5mdW5jdGlvbiBtYWxsb2NVaW50OChuKSB7XG4gIHJldHVybiBuZXcgVWludDhBcnJheShtYWxsb2NBcnJheUJ1ZmZlcihuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jVWludDggPSBtYWxsb2NVaW50OFxuXG5mdW5jdGlvbiBtYWxsb2NVaW50MTYobikge1xuICByZXR1cm4gbmV3IFVpbnQxNkFycmF5KG1hbGxvY0FycmF5QnVmZmVyKDIqbiksIDAsIG4pXG59XG5leHBvcnRzLm1hbGxvY1VpbnQxNiA9IG1hbGxvY1VpbnQxNlxuXG5mdW5jdGlvbiBtYWxsb2NVaW50MzIobikge1xuICByZXR1cm4gbmV3IFVpbnQzMkFycmF5KG1hbGxvY0FycmF5QnVmZmVyKDQqbiksIDAsIG4pXG59XG5leHBvcnRzLm1hbGxvY1VpbnQzMiA9IG1hbGxvY1VpbnQzMlxuXG5mdW5jdGlvbiBtYWxsb2NJbnQ4KG4pIHtcbiAgcmV0dXJuIG5ldyBJbnQ4QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIobiksIDAsIG4pXG59XG5leHBvcnRzLm1hbGxvY0ludDggPSBtYWxsb2NJbnQ4XG5cbmZ1bmN0aW9uIG1hbGxvY0ludDE2KG4pIHtcbiAgcmV0dXJuIG5ldyBJbnQxNkFycmF5KG1hbGxvY0FycmF5QnVmZmVyKDIqbiksIDAsIG4pXG59XG5leHBvcnRzLm1hbGxvY0ludDE2ID0gbWFsbG9jSW50MTZcblxuZnVuY3Rpb24gbWFsbG9jSW50MzIobikge1xuICByZXR1cm4gbmV3IEludDMyQXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoNCpuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jSW50MzIgPSBtYWxsb2NJbnQzMlxuXG5mdW5jdGlvbiBtYWxsb2NGbG9hdChuKSB7XG4gIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KG1hbGxvY0FycmF5QnVmZmVyKDQqbiksIDAsIG4pXG59XG5leHBvcnRzLm1hbGxvY0Zsb2F0MzIgPSBleHBvcnRzLm1hbGxvY0Zsb2F0ID0gbWFsbG9jRmxvYXRcblxuZnVuY3Rpb24gbWFsbG9jRG91YmxlKG4pIHtcbiAgcmV0dXJuIG5ldyBGbG9hdDY0QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoOCpuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jRmxvYXQ2NCA9IGV4cG9ydHMubWFsbG9jRG91YmxlID0gbWFsbG9jRG91YmxlXG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQ4Q2xhbXBlZChuKSB7XG4gIGlmKGhhc1VpbnQ4Qykge1xuICAgIHJldHVybiBuZXcgVWludDhDbGFtcGVkQXJyYXkobWFsbG9jQXJyYXlCdWZmZXIobiksIDAsIG4pXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG1hbGxvY1VpbnQ4KG4pXG4gIH1cbn1cbmV4cG9ydHMubWFsbG9jVWludDhDbGFtcGVkID0gbWFsbG9jVWludDhDbGFtcGVkXG5cbmZ1bmN0aW9uIG1hbGxvY0RhdGFWaWV3KG4pIHtcbiAgcmV0dXJuIG5ldyBEYXRhVmlldyhtYWxsb2NBcnJheUJ1ZmZlcihuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jRGF0YVZpZXcgPSBtYWxsb2NEYXRhVmlld1xuXG5mdW5jdGlvbiBtYWxsb2NCdWZmZXIobikge1xuICBuID0gYml0cy5uZXh0UG93MihuKVxuICB2YXIgbG9nX24gPSBiaXRzLmxvZzIobilcbiAgdmFyIGNhY2hlID0gQlVGRkVSW2xvZ19uXVxuICBpZihjYWNoZS5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGNhY2hlLnBvcCgpXG4gIH1cbiAgcmV0dXJuIG5ldyBCdWZmZXIobilcbn1cbmV4cG9ydHMubWFsbG9jQnVmZmVyID0gbWFsbG9jQnVmZmVyXG5cbmV4cG9ydHMuY2xlYXJDYWNoZSA9IGZ1bmN0aW9uIGNsZWFyQ2FjaGUoKSB7XG4gIGZvcih2YXIgaT0wOyBpPDMyOyArK2kpIHtcbiAgICBQT09MLlVJTlQ4W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLlVJTlQxNltpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5VSU5UMzJbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuSU5UOFtpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5JTlQxNltpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5JTlQzMltpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5GTE9BVFtpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5ET1VCTEVbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuVUlOVDhDW2ldLmxlbmd0aCA9IDBcbiAgICBEQVRBW2ldLmxlbmd0aCA9IDBcbiAgICBCVUZGRVJbaV0ubGVuZ3RoID0gMFxuICB9XG59Il19
},{"bit-twiddle":16,"buffer":1,"dup":17}],19:[function(require,module,exports){
"use strict"
module.exports = triangulateCube
var perm = require("permutation-rank")
var sgn = require("permutation-parity")
var gamma = require("gamma")
function triangulateCube(dimension) {
if(dimension < 0) {
return [ ]
}
if(dimension === 0) {
return [ [0] ]
}
var dfactorial = Math.round(gamma(dimension+1))|0
var result = []
for(var i=0; i<dfactorial; ++i) {
var p = perm.unrank(dimension, i)
var cell = [ 0 ]
var v = 0
for(var j=0; j<p.length; ++j) {
v += (1<<p[j])
cell.push(v)
}
if(sgn(p) < 1) {
cell[0] = v
cell[dimension] = 0
}
result.push(cell)
}
return result
}
},{"gamma":9,"permutation-parity":13,"permutation-rank":14}],20:[function(require,module,exports){
module.exports = require('cwise-compiler')({
args: ['array', {
offset: [1],
array: 0
}, 'scalar', 'scalar', 'index'],
pre: {
"body": "{}",
"args": [],
"thisVars": [],
"localVars": []
},
post: {
"body": "{}",
"args": [],
"thisVars": [],
"localVars": []
},
body: {
"body": "{\n var _inline_1_da = _inline_1_arg0_ - _inline_1_arg3_\n var _inline_1_db = _inline_1_arg1_ - _inline_1_arg3_\n if((_inline_1_da >= 0) !== (_inline_1_db >= 0)) {\n _inline_1_arg2_.push(_inline_1_arg4_[0] + 0.5 + 0.5 * (_inline_1_da + _inline_1_db) / (_inline_1_da - _inline_1_db))\n }\n }",
"args": [{
"name": "_inline_1_arg0_",
"lvalue": false,
"rvalue": true,
"count": 1
}, {
"name": "_inline_1_arg1_",
"lvalue": false,
"rvalue": true,
"count": 1
}, {
"name": "_inline_1_arg2_",
"lvalue": false,
"rvalue": true,
"count": 1
}, {
"name": "_inline_1_arg3_",
"lvalue": false,
"rvalue": true,
"count": 2
}, {
"name": "_inline_1_arg4_",
"lvalue": false,
"rvalue": true,
"count": 1
}],
"thisVars": [],
"localVars": ["_inline_1_da", "_inline_1_db"]
},
funcName: 'zeroCrossings'
})
},{"cwise-compiler":21}],21:[function(require,module,exports){
"use strict"
var createThunk = require("./lib/thunk.js")
function Procedure() {
this.argTypes = []
this.shimArgs = []
this.arrayArgs = []
this.arrayBlockIndices = []
this.scalarArgs = []
this.offsetArgs = []
this.offsetArgIndex = []
this.indexArgs = []
this.shapeArgs = []
this.funcName = ""
this.pre = null
this.body = null
this.post = null
this.debug = false
}
function compileCwise(user_args) {
//Create procedure
var proc = new Procedure()
//Parse blocks
proc.pre = user_args.pre
proc.body = user_args.body
proc.post = user_args.post
//Parse arguments
var proc_args = user_args.args.slice(0)
proc.argTypes = proc_args
for(var i=0; i<proc_args.length; ++i) {
var arg_type = proc_args[i]
if(arg_type === "array" || (typeof arg_type === "object" && arg_type.blockIndices)) {
proc.argTypes[i] = "array"
proc.arrayArgs.push(i)
proc.arrayBlockIndices.push(arg_type.blockIndices ? arg_type.blockIndices : 0)
proc.shimArgs.push("array" + i)
if(i < proc.pre.args.length && proc.pre.args[i].count>0) {
throw new Error("cwise: pre() block may not reference array args")
}
if(i < proc.post.args.length && proc.post.args[i].count>0) {
throw new Error("cwise: post() block may not reference array args")
}
} else if(arg_type === "scalar") {
proc.scalarArgs.push(i)
proc.shimArgs.push("scalar" + i)
} else if(arg_type === "index") {
proc.indexArgs.push(i)
if(i < proc.pre.args.length && proc.pre.args[i].count > 0) {
throw new Error("cwise: pre() block may not reference array index")
}
if(i < proc.body.args.length && proc.body.args[i].lvalue) {
throw new Error("cwise: body() block may not write to array index")
}
if(i < proc.post.args.length && proc.post.args[i].count > 0) {
throw new Error("cwise: post() block may not reference array index")
}
} else if(arg_type === "shape") {
proc.shapeArgs.push(i)
if(i < proc.pre.args.length && proc.pre.args[i].lvalue) {
throw new Error("cwise: pre() block may not write to array shape")
}
if(i < proc.body.args.length && proc.body.args[i].lvalue) {
throw new Error("cwise: body() block may not write to array shape")
}
if(i < proc.post.args.length && proc.post.args[i].lvalue) {
throw new Error("cwise: post() block may not write to array shape")
}
} else if(typeof arg_type === "object" && arg_type.offset) {
proc.argTypes[i] = "offset"
proc.offsetArgs.push({ array: arg_type.array, offset:arg_type.offset })
proc.offsetArgIndex.push(i)
} else {
throw new Error("cwise: Unknown argument type " + proc_args[i])
}
}
//Make sure at least one array argument was specified
if(proc.arrayArgs.length <= 0) {
throw new Error("cwise: No array arguments specified")
}
//Make sure arguments are correct
if(proc.pre.args.length > proc_args.length) {
throw new Error("cwise: Too many arguments in pre() block")
}
if(proc.body.args.length > proc_args.length) {
throw new Error("cwise: Too many arguments in body() block")
}
if(proc.post.args.length > proc_args.length) {
throw new Error("cwise: Too many arguments in post() block")
}
//Check debug flag
proc.debug = !!user_args.printCode || !!user_args.debug
//Retrieve name
proc.funcName = user_args.funcName || "cwise"
//Read in block size
proc.blockSize = user_args.blockSize || 64
return createThunk(proc)
}
module.exports = compileCwise
},{"./lib/thunk.js":23}],22:[function(require,module,exports){
"use strict"
var uniq = require("uniq")
// This function generates very simple loops analogous to how you typically traverse arrays (the outermost loop corresponds to the slowest changing index, the innermost loop to the fastest changing index)
// TODO: If two arrays have the same strides (and offsets) there is potential for decreasing the number of "pointers" and related variables. The drawback is that the type signature would become more specific and that there would thus be less potential for caching, but it might still be worth it, especially when dealing with large numbers of arguments.
function innerFill(order, proc, body) {
var dimension = order.length
, nargs = proc.arrayArgs.length
, has_index = proc.indexArgs.length>0
, code = []
, vars = []
, idx=0, pidx=0, i, j
for(i=0; i<dimension; ++i) { // Iteration variables
vars.push(["i",i,"=0"].join(""))
}
//Compute scan deltas
for(j=0; j<nargs; ++j) {
for(i=0; i<dimension; ++i) {
pidx = idx
idx = order[i]
if(i === 0) { // The innermost/fastest dimension's delta is simply its stride
vars.push(["d",j,"s",i,"=t",j,"p",idx].join(""))
} else { // For other dimensions the delta is basically the stride minus something which essentially "rewinds" the previous (more inner) dimension
vars.push(["d",j,"s",i,"=(t",j,"p",idx,"-s",pidx,"*t",j,"p",pidx,")"].join(""))
}
}
}
code.push("var " + vars.join(","))
//Scan loop
for(i=dimension-1; i>=0; --i) { // Start at largest stride and work your way inwards
idx = order[i]
code.push(["for(i",i,"=0;i",i,"<s",idx,";++i",i,"){"].join(""))
}
//Push body of inner loop
code.push(body)
//Advance scan pointers
for(i=0; i<dimension; ++i) {
pidx = idx
idx = order[i]
for(j=0; j<nargs; ++j) {
code.push(["p",j,"+=d",j,"s",i].join(""))
}
if(has_index) {
if(i > 0) {
code.push(["index[",pidx,"]-=s",pidx].join(""))
}
code.push(["++index[",idx,"]"].join(""))
}
code.push("}")
}
return code.join("\n")
}
// Generate "outer" loops that loop over blocks of data, applying "inner" loops to the blocks by manipulating the local variables in such a way that the inner loop only "sees" the current block.
// TODO: If this is used, then the previous declaration (done by generateCwiseOp) of s* is essentially unnecessary.
// I believe the s* are not used elsewhere (in particular, I don't think they're used in the pre/post parts and "shape" is defined independently), so it would be possible to make defining the s* dependent on what loop method is being used.
function outerFill(matched, order, proc, body) {
var dimension = order.length
, nargs = proc.arrayArgs.length
, blockSize = proc.blockSize
, has_index = proc.indexArgs.length > 0
, code = []
for(var i=0; i<nargs; ++i) {
code.push(["var offset",i,"=p",i].join(""))
}
//Generate loops for unmatched dimensions
// The order in which these dimensions are traversed is fairly arbitrary (from small stride to large stride, for the first argument)
// TODO: It would be nice if the order in which these loops are placed would also be somehow "optimal" (at the very least we should check that it really doesn't hurt us if they're not).
for(var i=matched; i<dimension; ++i) {
code.push(["for(var j"+i+"=SS[", order[i], "]|0;j", i, ">0;){"].join("")) // Iterate back to front
code.push(["if(j",i,"<",blockSize,"){"].join("")) // Either decrease j by blockSize (s = blockSize), or set it to zero (after setting s = j).
code.push(["s",order[i],"=j",i].join(""))
code.push(["j",i,"=0"].join(""))
code.push(["}else{s",order[i],"=",blockSize].join(""))
code.push(["j",i,"-=",blockSize,"}"].join(""))
if(has_index) {
code.push(["index[",order[i],"]=j",i].join(""))
}
}
for(var i=0; i<nargs; ++i) {
var indexStr = ["offset"+i]
for(var j=matched; j<dimension; ++j) {
indexStr.push(["j",j,"*t",i,"p",order[j]].join(""))
}
code.push(["p",i,"=(",indexStr.join("+"),")"].join(""))
}
code.push(innerFill(order, proc, body))
for(var i=matched; i<dimension; ++i) {
code.push("}")
}
return code.join("\n")
}
//Count the number of compatible inner orders
// This is the length of the longest common prefix of the arrays in orders.
// Each array in orders lists the dimensions of the correspond ndarray in order of increasing stride.
// This is thus the maximum number of dimensions that can be efficiently traversed by simple nested loops for all arrays.
function countMatches(orders) {
var matched = 0, dimension = orders[0].length
while(matched < dimension) {
for(var j=1; j<orders.length; ++j) {
if(orders[j][matched] !== orders[0][matched]) {
return matched
}
}
++matched
}
return matched
}
//Processes a block according to the given data types
// Replaces variable names by different ones, either "local" ones (that are then ferried in and out of the given array) or ones matching the arguments that the function performing the ultimate loop will accept.
function processBlock(block, proc, dtypes) {
var code = block.body
var pre = []
var post = []
for(var i=0; i<block.args.length; ++i) {
var carg = block.args[i]
if(carg.count <= 0) {
continue
}
var re = new RegExp(carg.name, "g")
var ptrStr = ""
var arrNum = proc.arrayArgs.indexOf(i)
switch(proc.argTypes[i]) {
case "offset":
var offArgIndex = proc.offsetArgIndex.indexOf(i)
var offArg = proc.offsetArgs[offArgIndex]
arrNum = offArg.array
ptrStr = "+q" + offArgIndex // Adds offset to the "pointer" in the array
case "array":
ptrStr = "p" + arrNum + ptrStr
var localStr = "l" + i
var arrStr = "a" + arrNum
if (proc.arrayBlockIndices[arrNum] === 0) { // Argument to body is just a single value from this array
if(carg.count === 1) { // Argument/array used only once(?)
if(dtypes[arrNum] === "generic") {
if(carg.lvalue) {
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // Is this necessary if the argument is ONLY used as an lvalue? (keep in mind that we can have a += something, so we would actually need to check carg.rvalue)
code = code.replace(re, localStr)
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join(""))
} else {
code = code.replace(re, [arrStr, ".get(", ptrStr, ")"].join(""))
}
} else {
code = code.replace(re, [arrStr, "[", ptrStr, "]"].join(""))
}
} else if(dtypes[arrNum] === "generic") {
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // TODO: Could we optimize by checking for carg.rvalue?
code = code.replace(re, localStr)
if(carg.lvalue) {
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join(""))
}
} else {
pre.push(["var ", localStr, "=", arrStr, "[", ptrStr, "]"].join("")) // TODO: Could we optimize by checking for carg.rvalue?
code = code.replace(re, localStr)
if(carg.lvalue) {
post.push([arrStr, "[", ptrStr, "]=", localStr].join(""))
}
}
} else { // Argument to body is a "block"
var reStrArr = [carg.name], ptrStrArr = [ptrStr]
for(var j=0; j<Math.abs(proc.arrayBlockIndices[arrNum]); j++) {
reStrArr.push("\\s*\\[([^\\]]+)\\]")
ptrStrArr.push("$" + (j+1) + "*t" + arrNum + "b" + j) // Matched index times stride
}
re = new RegExp(reStrArr.join(""), "g")
ptrStr = ptrStrArr.join("+")
if(dtypes[arrNum] === "generic") {
/*if(carg.lvalue) {
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // Is this necessary if the argument is ONLY used as an lvalue? (keep in mind that we can have a += something, so we would actually need to check carg.rvalue)
code = code.replace(re, localStr)
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join(""))
} else {
code = code.replace(re, [arrStr, ".get(", ptrStr, ")"].join(""))
}*/
throw new Error("cwise: Generic arrays not supported in combination with blocks!")
} else {
// This does not produce any local variables, even if variables are used multiple times. It would be possible to do so, but it would complicate things quite a bit.
code = code.replace(re, [arrStr, "[", ptrStr, "]"].join(""))
}
}
break
case "scalar":
code = code.replace(re, "Y" + proc.scalarArgs.indexOf(i))
break
case "index":
code = code.replace(re, "index")
break
case "shape":
code = code.replace(re, "shape")
break
}
}
return [pre.join("\n"), code, post.join("\n")].join("\n").trim()
}
function typeSummary(dtypes) {
var summary = new Array(dtypes.length)
var allEqual = true
for(var i=0; i<dtypes.length; ++i) {
var t = dtypes[i]
var digits = t.match(/\d+/)
if(!digits) {
digits = ""
} else {
digits = digits[0]
}
if(t.charAt(0) === 0) {
summary[i] = "u" + t.charAt(1) + digits
} else {
summary[i] = t.charAt(0) + digits
}
if(i > 0) {
allEqual = allEqual && summary[i] === summary[i-1]
}
}
if(allEqual) {
return summary[0]
}
return summary.join("")
}
//Generates a cwise operator
function generateCWiseOp(proc, typesig) {
//Compute dimension
// Arrays get put first in typesig, and there are two entries per array (dtype and order), so this gets the number of dimensions in the first array arg.
var dimension = (typesig[1].length - Math.abs(proc.arrayBlockIndices[0]))|0
var orders = new Array(proc.arrayArgs.length)
var dtypes = new Array(proc.arrayArgs.length)
for(var i=0; i<proc.arrayArgs.length; ++i) {
dtypes[i] = typesig[2*i]
orders[i] = typesig[2*i+1]
}
//Determine where block and loop indices start and end
var blockBegin = [], blockEnd = [] // These indices are exposed as blocks
var loopBegin = [], loopEnd = [] // These indices are iterated over
var loopOrders = [] // orders restricted to the loop indices
for(var i=0; i<proc.arrayArgs.length; ++i) {
if (proc.arrayBlockIndices[i]<0) {
loopBegin.push(0)
loopEnd.push(dimension)
blockBegin.push(dimension)
blockEnd.push(dimension+proc.arrayBlockIndices[i])
} else {
loopBegin.push(proc.arrayBlockIndices[i]) // Non-negative
loopEnd.push(proc.arrayBlockIndices[i]+dimension)
blockBegin.push(0)
blockEnd.push(proc.arrayBlockIndices[i])
}
var newOrder = []
for(var j=0; j<orders[i].length; j++) {
if (loopBegin[i]<=orders[i][j] && orders[i][j]<loopEnd[i]) {
newOrder.push(orders[i][j]-loopBegin[i]) // If this is a loop index, put it in newOrder, subtracting loopBegin, to make sure that all loopOrders are using a common set of indices.
}
}
loopOrders.push(newOrder)
}
//First create arguments for procedure
var arglist = ["SS"] // SS is the overall shape over which we iterate
var code = ["'use strict'"]
var vars = []
for(var j=0; j<dimension; ++j) {
vars.push(["s", j, "=SS[", j, "]"].join("")) // The limits for each dimension.
}
for(var i=0; i<proc.arrayArgs.length; ++i) {
arglist.push("a"+i) // Actual data array
arglist.push("t"+i) // Strides
arglist.push("p"+i) // Offset in the array at which the data starts (also used for iterating over the data)
for(var j=0; j<dimension; ++j) { // Unpack the strides into vars for looping
vars.push(["t",i,"p",j,"=t",i,"[",loopBegin[i]+j,"]"].join(""))
}
for(var j=0; j<Math.abs(proc.arrayBlockIndices[i]); ++j) { // Unpack the strides into vars for block iteration
vars.push(["t",i,"b",j,"=t",i,"[",blockBegin[i]+j,"]"].join(""))
}
}
for(var i=0; i<proc.scalarArgs.length; ++i) {
arglist.push("Y" + i)
}
if(proc.shapeArgs.length > 0) {
vars.push("shape=SS.slice(0)") // Makes the shape over which we iterate available to the user defined functions (so you can use width/height for example)
}
if(proc.indexArgs.length > 0) {
// Prepare an array to keep track of the (logical) indices, initialized to dimension zeroes.
var zeros = new Array(dimension)
for(var i=0; i<dimension; ++i) {
zeros[i] = "0"
}
vars.push(["index=[", zeros.join(","), "]"].join(""))
}
for(var i=0; i<proc.offsetArgs.length; ++i) { // Offset arguments used for stencil operations
var off_arg = proc.offsetArgs[i]
var init_string = []
for(var j=0; j<off_arg.offset.length; ++j) {
if(off_arg.offset[j] === 0) {
continue
} else if(off_arg.offset[j] === 1) {
init_string.push(["t", off_arg.array, "p", j].join(""))
} else {
init_string.push([off_arg.offset[j], "*t", off_arg.array, "p", j].join(""))
}
}
if(init_string.length === 0) {
vars.push("q" + i + "=0")
} else {
vars.push(["q", i, "=", init_string.join("+")].join(""))
}
}
//Prepare this variables
var thisVars = uniq([].concat(proc.pre.thisVars)
.concat(proc.body.thisVars)
.concat(proc.post.thisVars))
vars = vars.concat(thisVars)
code.push("var " + vars.join(","))
for(var i=0; i<proc.arrayArgs.length; ++i) {
code.push("p"+i+"|=0")
}
//Inline prelude
if(proc.pre.body.length > 3) {
code.push(processBlock(proc.pre, proc, dtypes))
}
//Process body
var body = processBlock(proc.body, proc, dtypes)
var matched = countMatches(loopOrders)
if(matched < dimension) {
code.push(outerFill(matched, loopOrders[0], proc, body)) // TODO: Rather than passing loopOrders[0], it might be interesting to look at passing an order that represents the majority of the arguments for example.
} else {
code.push(innerFill(loopOrders[0], proc, body))
}
//Inline epilog
if(proc.post.body.length > 3) {
code.push(processBlock(proc.post, proc, dtypes))
}
if(proc.debug) {
console.log("-----Generated cwise routine for ", typesig, ":\n" + code.join("\n") + "\n----------")
}
var loopName = [(proc.funcName||"unnamed"), "_cwise_loop_", orders[0].join("s"),"m",matched,typeSummary(dtypes)].join("")
var f = new Function(["function ",loopName,"(", arglist.join(","),"){", code.join("\n"),"} return ", loopName].join(""))
return f()
}
module.exports = generateCWiseOp
},{"uniq":24}],23:[function(require,module,exports){
"use strict"
// The function below is called when constructing a cwise function object, and does the following:
// A function object is constructed which accepts as argument a compilation function and returns another function.
// It is this other function that is eventually returned by createThunk, and this function is the one that actually
// checks whether a certain pattern of arguments has already been used before and compiles new loops as needed.
// The compilation passed to the first function object is used for compiling new functions.
// Once this function object is created, it is called with compile as argument, where the first argument of compile
// is bound to "proc" (essentially containing a preprocessed version of the user arguments to cwise).
// So createThunk roughly works like this:
// function createThunk(proc) {
// var thunk = function(compileBound) {
// var CACHED = {}
// return function(arrays and scalars) {
// if (dtype and order of arrays in CACHED) {
// var func = CACHED[dtype and order of arrays]
// } else {
// var func = CACHED[dtype and order of arrays] = compileBound(dtype and order of arrays)
// }
// return func(arrays and scalars)
// }
// }
// return thunk(compile.bind1(proc))
// }
var compile = require("./compile.js")
function createThunk(proc) {
var code = ["'use strict'", "var CACHED={}"]
var vars = []
var thunkName = proc.funcName + "_cwise_thunk"
//Build thunk
code.push(["return function ", thunkName, "(", proc.shimArgs.join(","), "){"].join(""))
var typesig = []
var string_typesig = []
var proc_args = [["array",proc.arrayArgs[0],".shape.slice(", // Slice shape so that we only retain the shape over which we iterate (which gets passed to the cwise operator as SS).
Math.max(0,proc.arrayBlockIndices[0]),proc.arrayBlockIndices[0]<0?(","+proc.arrayBlockIndices[0]+")"):")"].join("")]
var shapeLengthConditions = [], shapeConditions = []
// Process array arguments
for(var i=0; i<proc.arrayArgs.length; ++i) {
var j = proc.arrayArgs[i]
vars.push(["t", j, "=array", j, ".dtype,",
"r", j, "=array", j, ".order"].join(""))
typesig.push("t" + j)
typesig.push("r" + j)
string_typesig.push("t"+j)
string_typesig.push("r"+j+".join()")
proc_args.push("array" + j + ".data")
proc_args.push("array" + j + ".stride")
proc_args.push("array" + j + ".offset|0")
if (i>0) { // Gather conditions to check for shape equality (ignoring block indices)
shapeLengthConditions.push("array" + proc.arrayArgs[0] + ".shape.length===array" + j + ".shape.length+" + (Math.abs(proc.arrayBlockIndices[0])-Math.abs(proc.arrayBlockIndices[i])))
shapeConditions.push("array" + proc.arrayArgs[0] + ".shape[shapeIndex+" + Math.max(0,proc.arrayBlockIndices[0]) + "]===array" + j + ".shape[shapeIndex+" + Math.max(0,proc.arrayBlockIndices[i]) + "]")
}
}
// Check for shape equality
if (proc.arrayArgs.length > 1) {
code.push("if (!(" + shapeLengthConditions.join(" && ") + ")) throw new Error('cwise: Arrays do not all have the same dimensionality!')")
code.push("for(var shapeIndex=array" + proc.arrayArgs[0] + ".shape.length-" + Math.abs(proc.arrayBlockIndices[0]) + "; shapeIndex-->0;) {")
code.push("if (!(" + shapeConditions.join(" && ") + ")) throw new Error('cwise: Arrays do not all have the same shape!')")
code.push("}")
}
// Process scalar arguments
for(var i=0; i<proc.scalarArgs.length; ++i) {
proc_args.push("scalar" + proc.scalarArgs[i])
}
// Check for cached function (and if not present, generate it)
vars.push(["type=[", string_typesig.join(","), "].join()"].join(""))
vars.push("proc=CACHED[type]")
code.push("var " + vars.join(","))
code.push(["if(!proc){",
"CACHED[type]=proc=compile([", typesig.join(","), "])}",
"return proc(", proc_args.join(","), ")}"].join(""))
if(proc.debug) {
console.log("-----Generated thunk:\n" + code.join("\n") + "\n----------")
}
//Compile thunk
var thunk = new Function("compile", code.join("\n"))
return thunk(compile.bind(undefined, proc))
}
module.exports = createThunk
},{"./compile.js":22}],24:[function(require,module,exports){
"use strict"
function unique_pred(list, compare) {
var ptr = 1
, len = list.length
, a=list[0], b=list[0]
for(var i=1; i<len; ++i) {
b = a
a = list[i]
if(compare(a, b)) {
if(i === ptr) {
ptr++
continue
}
list[ptr++] = a
}
}
list.length = ptr
return list
}
function unique_eq(list) {
var ptr = 1
, len = list.length
, a=list[0], b = list[0]
for(var i=1; i<len; ++i, b=a) {
b = a
a = list[i]
if(a !== b) {
if(i === ptr) {
ptr++
continue
}
list[ptr++] = a
}
}
list.length = ptr
return list
}
function unique(list, compare, sorted) {
if(list.length === 0) {
return list
}
if(compare) {
if(!sorted) {
list.sort(compare)
}
return unique_pred(list, compare)
}
if(!sorted) {
list.sort()
}
return unique_eq(list)
}
module.exports = unique
},{}],25:[function(require,module,exports){
"use strict"
module.exports = findZeroCrossings
var core = require("./lib/zc-core")
function findZeroCrossings(array, level) {
var cross = []
level = +level || 0.0
core(array.hi(array.shape[0]-1), cross, level)
return cross
}
},{"./lib/zc-core":20}],"surface-nets":[function(require,module,exports){
"use strict"
module.exports = surfaceNets
var generateContourExtractor = require("ndarray-extract-contour")
var triangulateCube = require("triangulate-hypercube")
var zeroCrossings = require("zero-crossings")
function buildSurfaceNets(order, dtype) {
var dimension = order.length
var code = ["'use strict';"]
var funcName = "surfaceNets" + order.join("_") + "d" + dtype
//Contour extraction function
code.push(
"var contour=genContour({",
"order:[", order.join(), "],",
"scalarArguments: 3,",
"phase:function phaseFunc(p,a,b,c) { return (p > c)|0 },")
if(dtype === "generic") {
code.push("getters:[0],")
}
//Generate vertex function
var cubeArgs = []
var extraArgs = []
for(var i=0; i<dimension; ++i) {
cubeArgs.push("d" + i)
extraArgs.push("d" + i)
}
for(var i=0; i<(1<<dimension); ++i) {
cubeArgs.push("v" + i)
extraArgs.push("v" + i)
}
for(var i=0; i<(1<<dimension); ++i) {
cubeArgs.push("p" + i)
extraArgs.push("p" + i)
}
cubeArgs.push("a", "b", "c")
extraArgs.push("a", "c")
code.push("vertex:function vertexFunc(", cubeArgs.join(), "){")
//Mask args together
var maskStr = []
for(var i=0; i<(1<<dimension); ++i) {
maskStr.push("(p" + i + "<<" + i + ")")
}
//Generate variables and giganto switch statement
code.push("var m=(", maskStr.join("+"), ")|0;if(m===0||m===", (1<<(1<<dimension))-1, "){return}")
var extraFuncs = []
var currentFunc = []
if(1<<(1<<dimension) <= 128) {
code.push("switch(m){")
currentFunc = code
} else {
code.push("switch(m>>>7){")
}
for(var i=0; i<1<<(1<<dimension); ++i) {
if(1<<(1<<dimension) > 128) {
if((i%128)===0) {
if(extraFuncs.length > 0) {
currentFunc.push("}}")
}
var efName = "vExtra" + extraFuncs.length
code.push("case ", (i>>>7), ":", efName, "(m&0x7f,", extraArgs.join(), ");break;")
currentFunc = [
"function ", efName, "(m,", extraArgs.join(), "){switch(m){"
]
extraFuncs.push(currentFunc)
}
}
currentFunc.push("case ", (i&0x7f), ":")
var crossings = new Array(dimension)
var denoms = new Array(dimension)
var crossingCount = new Array(dimension)
var bias = new Array(dimension)
var totalCrossings = 0
for(var j=0; j<dimension; ++j) {
crossings[j] = []
denoms[j] = []
crossingCount[j] = 0
bias[j] = 0
}
for(var j=0; j<(1<<dimension); ++j) {
for(var k=0; k<dimension; ++k) {
var u = j ^ (1<<k)
if(u > j) {
continue
}
if(!(i&(1<<u)) !== !(i&(1<<j))) {
var sign = 1
if(i&(1<<u)) {
denoms[k].push("v" + u + "-v" + j)
} else {
denoms[k].push("v" + j + "-v" + u)
sign = -sign
}
if(sign < 0) {
crossings[k].push("-v" + j + "-v" + u)
crossingCount[k] += 2
} else {
crossings[k].push("v" + j + "+v" + u)
crossingCount[k] -= 2
}
totalCrossings += 1
for(var l=0; l<dimension; ++l) {
if(l === k) {
continue
}
if(u&(1<<l)) {
bias[l] += 1
} else {
bias[l] -= 1
}
}
}
}
}
var vertexStr = []
for(var k=0; k<dimension; ++k) {
if(crossings[k].length === 0) {
vertexStr.push("d" + k + "-0.5")
} else {
var cStr = ""
if(crossingCount[k] < 0) {
cStr = crossingCount[k] + "*c"
} else if(crossingCount[k] > 0) {
cStr = "+" + crossingCount[k] + "*c"
}
var weight = 0.5 * (crossings[k].length / totalCrossings)
var shift = 0.5 + 0.5 * (bias[k] / totalCrossings)
vertexStr.push("d" + k + "-" + shift + "-" + weight + "*(" + crossings[k].join("+") + cStr + ")/(" + denoms[k].join("+") + ")")
}
}
currentFunc.push("a.push([", vertexStr.join(), "]);",
"break;")
}
code.push("}},")
if(extraFuncs.length > 0) {
currentFunc.push("}}")
}
//Create face function
var faceArgs = []
for(var i=0; i<(1<<(dimension-1)); ++i) {
faceArgs.push("v" + i)
}
faceArgs.push("c0", "c1", "p0", "p1", "a", "b", "c")
code.push("cell:function cellFunc(", faceArgs.join(), "){")
var facets = triangulateCube(dimension-1)
code.push("if(p0){b.push(",
facets.map(function(f) {
return "[" + f.map(function(v) {
return "v" + v
}) + "]"
}).join(), ")}else{b.push(",
facets.map(function(f) {
var e = f.slice()
e.reverse()
return "[" + e.map(function(v) {
return "v" + v
}) + "]"
}).join(),
")}}});function ", funcName, "(array,level){var verts=[],cells=[];contour(array,verts,cells,level);return {positions:verts,cells:cells};} return ", funcName, ";")
for(var i=0; i<extraFuncs.length; ++i) {
code.push(extraFuncs[i].join(""))
}
//Compile and link
var proc = new Function("genContour", code.join(""))
return proc(generateContourExtractor)
}
//1D case: Need to handle specially
function mesh1D(array, level) {
var zc = zeroCrossings(array, level)
var n = zc.length
var npos = new Array(n)
var ncel = new Array(n)
for(var i=0; i<n; ++i) {
npos[i] = [ zc[i] ]
ncel[i] = [ i ]
}
return {
positions: npos,
cells: ncel
}
}
var CACHE = {}
function surfaceNets(array,level) {
if(array.dimension <= 0) {
return { positions: [], cells: [] }
} else if(array.dimension === 1) {
return mesh1D(array, level)
}
var typesig = array.order.join() + "-" + array.dtype
var proc = CACHE[typesig]
var level = (+level) || 0.0
if(!proc) {
proc = CACHE[typesig] = buildSurfaceNets(array.order, array.dtype)
}
return proc(array,level)
}
},{"ndarray-extract-contour":5,"triangulate-hypercube":19,"zero-crossings":25}]},{},[])
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIi4uLy4uLy4uLy4uL2hvbWUvYWRtaW4vYnJvd3NlcmlmeS1jZG4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYi9iNjQuanMiLCIuLi8uLi8uLi8uLi9ob21lL2FkbWluL2Jyb3dzZXJpZnktY2RuL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCIuLi8uLi8uLi8uLi9ob21lL2FkbWluL2Jyb3dzZXJpZnktY2RuL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvbmRhcnJheS1leHRyYWN0LWNvbnRvdXIvY29udG91ci5qcyIsIm5vZGVfbW9kdWxlcy9uZGFycmF5LWV4dHJhY3QtY29udG91ci9ub2RlX21vZHVsZXMvdHlwZWRhcnJheS1wb29sL25vZGVfbW9kdWxlcy9iaXQtdHdpZGRsZS90d2lkZGxlLmpzIiwibm9kZV9tb2R1bGVzL25kYXJyYXktZXh0cmFjdC1jb250b3VyL25vZGVfbW9kdWxlcy90eXBlZGFycmF5LXBvb2wvbm9kZV9tb2R1bGVzL2R1cC9kdXAuanMiLCJub2RlX21vZHVsZXMvbmRhcnJheS1leHRyYWN0LWNvbnRvdXIvbm9kZV9tb2R1bGVzL3R5cGVkYXJyYXktcG9vbC9wb29sLmpzIiwibm9kZV9tb2R1bGVzL3RyaWFuZ3VsYXRlLWh5cGVyY3ViZS9ub2RlX21vZHVsZXMvZ2FtbWEvaW5kZXguanMiLCJub2RlX21vZHVsZXMvdHJpYW5ndWxhdGUtaHlwZXJjdWJlL25vZGVfbW9kdWxlcy9wZXJtdXRhdGlvbi1wYXJpdHkvbm9kZV9tb2R1bGVzL3R5cGVkYXJyYXktcG9vbC9wb29sLmpzIiwibm9kZV9tb2R1bGVzL3RyaWFuZ3VsYXRlLWh5cGVyY3ViZS9ub2RlX21vZHVsZXMvcGVybXV0YXRpb24tcGFyaXR5L3Blcm11dGF0aW9uLXNpZ24uanMiLCJub2RlX21vZHVsZXMvdHJpYW5ndWxhdGUtaHlwZXJjdWJlL25vZGVfbW9kdWxlcy9wZXJtdXRhdGlvbi1yYW5rL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3RyaWFuZ3VsYXRlLWh5cGVyY3ViZS9ub2RlX21vZHVsZXMvcGVybXV0YXRpb24tcmFuay9ub2RlX21vZHVsZXMvaW52ZXJ0LXBlcm11dGF0aW9uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3RyaWFuZ3VsYXRlLWh5cGVyY3ViZS9ub2RlX21vZHVsZXMvcGVybXV0YXRpb24tcmFuay9ub2RlX21vZHVsZXMvdHlwZWRhcnJheS1wb29sL3Bvb2wuanMiLCJub2RlX21vZHVsZXMvdHJpYW5ndWxhdGUtaHlwZXJjdWJlL3RyaWFuZ3VsYXRlLWN1YmUuanMiLCJub2RlX21vZHVsZXMvemVyby1jcm9zc2luZ3MvbGliL3pjLWNvcmUuanMiLCJub2RlX21vZHVsZXMvemVyby1jcm9zc2luZ3Mvbm9kZV9tb2R1bGVzL2N3aXNlLWNvbXBpbGVyL2NvbXBpbGVyLmpzIiwibm9kZV9tb2R1bGVzL3plcm8tY3Jvc3NpbmdzL25vZGVfbW9kdWxlcy9jd2lzZS1jb21waWxlci9saWIvY29tcGlsZS5qcyIsIm5vZGVfbW9kdWxlcy96ZXJvLWNyb3NzaW5ncy9ub2RlX21vZHVsZXMvY3dpc2UtY29tcGlsZXIvbGliL3RodW5rLmpzIiwibm9kZV9tb2R1bGVzL3plcm8tY3Jvc3NpbmdzL25vZGVfbW9kdWxlcy9jd2lzZS1jb21waWxlci9ub2RlX21vZHVsZXMvdW5pcS91bmlxLmpzIiwibm9kZV9tb2R1bGVzL3plcm8tY3Jvc3NpbmdzL3pjLmpzIiwic3VyZmFjZW5ldHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvZ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOVpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxudmFyIHJvb3RQYXJlbnQgPSB7fVxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIFNhZmFyaSA1LTcgbGFja3Mgc3VwcG9ydCBmb3IgY2hhbmdpbmcgdGhlIGBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yYCBwcm9wZXJ0eVxuICogICAgIG9uIG9iamVjdHMuXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUICE9PSB1bmRlZmluZWRcbiAgPyBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVFxuICA6IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICBmdW5jdGlvbiBCYXIgKCkge31cbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuZm9vID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfVxuICAgIGFyci5jb25zdHJ1Y3RvciA9IEJhclxuICAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyICYmIC8vIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkXG4gICAgICAgIGFyci5jb25zdHJ1Y3RvciA9PT0gQmFyICYmIC8vIGNvbnN0cnVjdG9yIGNhbiBiZSBzZXRcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAmJiAvLyBjaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgICAgICAgYXJyLnN1YmFycmF5KDEsIDEpLmJ5dGVMZW5ndGggPT09IDAgLy8gaWUxMCBoYXMgYnJva2VuIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbmZ1bmN0aW9uIGtNYXhMZW5ndGggKCkge1xuICByZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRcbiAgICA/IDB4N2ZmZmZmZmZcbiAgICA6IDB4M2ZmZmZmZmZcbn1cblxuLyoqXG4gKiBDbGFzczogQnVmZmVyXG4gKiA9PT09PT09PT09PT09XG4gKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBhcmUgYXVnbWVudGVkXG4gKiB3aXRoIGZ1bmN0aW9uIHByb3BlcnRpZXMgZm9yIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBBUEkgZnVuY3Rpb25zLiBXZSB1c2VcbiAqIGBVaW50OEFycmF5YCBzbyB0aGF0IHNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0IHJldHVybnNcbiAqIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIEJ5IGF1Z21lbnRpbmcgdGhlIGluc3RhbmNlcywgd2UgY2FuIGF2b2lkIG1vZGlmeWluZyB0aGUgYFVpbnQ4QXJyYXlgXG4gKiBwcm90b3R5cGUuXG4gKi9cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgLy8gQXZvaWQgZ29pbmcgdGhyb3VnaCBhbiBBcmd1bWVudHNBZGFwdG9yVHJhbXBvbGluZSBpbiB0aGUgY29tbW9uIGNhc2UuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSByZXR1cm4gbmV3IEJ1ZmZlcihhcmcsIGFyZ3VtZW50c1sxXSlcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihhcmcpXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpcy5sZW5ndGggPSAwXG4gICAgdGhpcy5wYXJlbnQgPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLCBhcmcpXG4gIH1cblxuICAvLyBTbGlnaHRseSBsZXNzIGNvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGlzLCBhcmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogJ3V0ZjgnKVxuICB9XG5cbiAgLy8gVW51c3VhbC5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhpcywgYXJnKVxufVxuXG5mdW5jdGlvbiBmcm9tTnVtYmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChsZW5ndGgpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIC8vIEFzc3VtcHRpb246IGJ5dGVMZW5ndGgoKSByZXR1cm4gdmFsdWUgaXMgYWx3YXlzIDwga01heExlbmd0aC5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG5cbiAgdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpKSByZXR1cm4gZnJvbUJ1ZmZlcih0aGF0LCBvYmplY3QpXG5cbiAgaWYgKGlzQXJyYXkob2JqZWN0KSkgcmV0dXJuIGZyb21BcnJheSh0aGF0LCBvYmplY3QpXG5cbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbXVzdCBzdGFydCB3aXRoIG51bWJlciwgYnVmZmVyLCBhcnJheSBvciBzdHJpbmcnKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAob2JqZWN0LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICByZXR1cm4gZnJvbVR5cGVkQXJyYXkodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgfVxuXG4gIGlmIChvYmplY3QubGVuZ3RoKSByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmplY3QpXG5cbiAgcmV0dXJuIGZyb21Kc29uT2JqZWN0KHRoYXQsIG9iamVjdClcbn1cblxuZnVuY3Rpb24gZnJvbUJ1ZmZlciAodGhhdCwgYnVmZmVyKSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGJ1ZmZlci5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBidWZmZXIuY29weSh0aGF0LCAwLCAwLCBsZW5ndGgpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIER1cGxpY2F0ZSBvZiBmcm9tQXJyYXkoKSB0byBrZWVwIGZyb21BcnJheSgpIG1vbm9tb3JwaGljLlxuZnVuY3Rpb24gZnJvbVR5cGVkQXJyYXkgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIC8vIFRydW5jYXRpbmcgdGhlIGVsZW1lbnRzIGlzIHByb2JhYmx5IG5vdCB3aGF0IHBlb3BsZSBleHBlY3QgZnJvbSB0eXBlZFxuICAvLyBhcnJheXMgd2l0aCBCWVRFU19QRVJfRUxFTUVOVCA+IDEgYnV0IGl0J3MgY29tcGF0aWJsZSB3aXRoIHRoZSBiZWhhdmlvclxuICAvLyBvZiB0aGUgb2xkIEJ1ZmZlciBjb25zdHJ1Y3Rvci5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXkpIHtcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgYXJyYXkuYnl0ZUxlbmd0aFxuICAgIHRoYXQgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbVR5cGVkQXJyYXkodGhhdCwgbmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vLyBEZXNlcmlhbGl6ZSB7IHR5cGU6ICdCdWZmZXInLCBkYXRhOiBbMSwyLDMsLi4uXSB9IGludG8gYSBCdWZmZXIgb2JqZWN0LlxuLy8gUmV0dXJucyBhIHplcm8tbGVuZ3RoIGJ1ZmZlciBmb3IgaW5wdXRzIHRoYXQgZG9uJ3QgY29uZm9ybSB0byB0aGUgc3BlYy5cbmZ1bmN0aW9uIGZyb21Kc29uT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgdmFyIGFycmF5XG4gIHZhciBsZW5ndGggPSAwXG5cbiAgaWYgKG9iamVjdC50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iamVjdC5kYXRhKSkge1xuICAgIGFycmF5ID0gb2JqZWN0LmRhdGFcbiAgICBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIH1cbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbiAgQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcbn0gZWxzZSB7XG4gIC8vIHByZS1zZXQgZm9yIHZhbHVlcyB0aGF0IG1heSBleGlzdCBpbiB0aGUgZnV0dXJlXG4gIEJ1ZmZlci5wcm90b3R5cGUubGVuZ3RoID0gdW5kZWZpbmVkXG4gIEJ1ZmZlci5wcm90b3R5cGUucGFyZW50ID0gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIGFsbG9jYXRlICh0aGF0LCBsZW5ndGgpIHtcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgdGhhdCA9IEJ1ZmZlci5fYXVnbWVudChuZXcgVWludDhBcnJheShsZW5ndGgpKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICAgIHRoYXQuX2lzQnVmZmVyID0gdHJ1ZVxuICB9XG5cbiAgdmFyIGZyb21Qb29sID0gbGVuZ3RoICE9PSAwICYmIGxlbmd0aCA8PSBCdWZmZXIucG9vbFNpemUgPj4+IDFcbiAgaWYgKGZyb21Qb29sKSB0aGF0LnBhcmVudCA9IHJvb3RQYXJlbnRcblxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBjaGVja2VkIChsZW5ndGgpIHtcbiAgLy8gTm90ZTogY2Fubm90IHVzZSBgbGVuZ3RoIDwga01heExlbmd0aGAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBrTWF4TGVuZ3RoKCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsga01heExlbmd0aCgpLnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKHN1YmplY3QsIGVuY29kaW5nKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTbG93QnVmZmVyKSkgcmV0dXJuIG5ldyBTbG93QnVmZmVyKHN1YmplY3QsIGVuY29kaW5nKVxuXG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKHN1YmplY3QsIGVuY29kaW5nKVxuICBkZWxldGUgYnVmLnBhcmVudFxuICByZXR1cm4gYnVmXG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyIChiKSB7XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihhKSB8fCAhQnVmZmVyLmlzQnVmZmVyKGIpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnRzIG11c3QgYmUgQnVmZmVycycpXG4gIH1cblxuICBpZiAoYSA9PT0gYikgcmV0dXJuIDBcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcblxuICB2YXIgaSA9IDBcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIGJyZWFrXG5cbiAgICArK2lcbiAgfVxuXG4gIGlmIChpICE9PSBsZW4pIHtcbiAgICB4ID0gYVtpXVxuICAgIHkgPSBiW2ldXG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3Jhdyc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2xpc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzLicpXG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoMClcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgbGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gbGlzdFtpXVxuICAgIGl0ZW0uY29weShidWYsIHBvcylcbiAgICBwb3MgKz0gaXRlbS5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSBzdHJpbmcgPSAnJyArIHN0cmluZ1xuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgLy8gRGVwcmVjYXRlZFxuICAgICAgY2FzZSAncmF3JzpcbiAgICAgIGNhc2UgJ3Jhd3MnOlxuICAgICAgICByZXR1cm4gbGVuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIHN0YXJ0ID0gc3RhcnQgfCAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA9PT0gSW5maW5pdHkgPyB0aGlzLmxlbmd0aCA6IGVuZCB8IDBcblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAoZW5kIDw9IHN0YXJ0KSByZXR1cm4gJydcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBiaW5hcnlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIDBcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCkge1xuICBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIGJ5dGVPZmZzZXQgPj49IDBcblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAtMVxuICBpZiAoYnl0ZU9mZnNldCA+PSB0aGlzLmxlbmd0aCkgcmV0dXJuIC0xXG5cbiAgLy8gTmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBNYXRoLm1heCh0aGlzLmxlbmd0aCArIGJ5dGVPZmZzZXQsIDApXG5cbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHJldHVybiAtMSAvLyBzcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZyBhbHdheXMgZmFpbHNcbiAgICByZXR1cm4gU3RyaW5nLnByb3RvdHlwZS5pbmRleE9mLmNhbGwodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0KVxuICB9XG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZih0aGlzLCBbIHZhbCBdLCBieXRlT2Zmc2V0KVxuICB9XG5cbiAgZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCkge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKHZhciBpID0gMDsgYnl0ZU9mZnNldCArIGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhcnJbYnl0ZU9mZnNldCArIGldID09PSB2YWxbZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXhdKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsLmxlbmd0aCkgcmV0dXJuIGJ5dGVPZmZzZXQgKyBmb3VuZEluZGV4XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG4vLyBgZ2V0YCBpcyBkZXByZWNhdGVkXG5CdWZmZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldCAob2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuZ2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy5yZWFkVUludDgob2Zmc2V0KVxufVxuXG4vLyBgc2V0YCBpcyBkZXByZWNhdGVkXG5CdWZmZXIucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIHNldCAodiwgb2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuc2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy53cml0ZVVJbnQ4KHYsIG9mZnNldClcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KVxuICAgIGlmIChpc05hTihwYXJzZWQpKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiaW5hcnlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdmFyIHN3YXAgPSBlbmNvZGluZ1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgb2Zmc2V0ID0gbGVuZ3RoIHwgMFxuICAgIGxlbmd0aCA9IHN3YXBcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdhdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBiaW5hcnlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gQnVmZmVyLl9hdWdtZW50KHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZCkpXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgaSsrKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICBpZiAobmV3QnVmLmxlbmd0aCkgbmV3QnVmLnBhcmVudCA9IHRoaXMucGFyZW50IHx8IHRoaXNcblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2J1ZmZlciBtdXN0IGJlIGEgQnVmZmVyIGluc3RhbmNlJylcbiAgaWYgKHZhbHVlID4gbWF4IHx8IHZhbHVlIDwgbWluKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndmFsdWUgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCksIDApXG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgaSsrKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50QkUgPSBmdW5jdGlvbiB3cml0ZUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IHZhbHVlIDwgMCA/IDEgOiAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcbiAgdmFyIGlcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBhc2NlbmRpbmcgY29weSBmcm9tIHN0YXJ0XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQuX3NldCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBzdGFydCArIGxlbiksIHRhcmdldFN0YXJ0KVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBmaWxsKHZhbHVlLCBzdGFydD0wLCBlbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbHVlLCBzdGFydCwgZW5kKSB7XG4gIGlmICghdmFsdWUpIHZhbHVlID0gMFxuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQpIGVuZCA9IHRoaXMubGVuZ3RoXG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignZW5kIDwgc3RhcnQnKVxuXG4gIC8vIEZpbGwgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuXG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3N0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCBvdXQgb2YgYm91bmRzJylcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIHRoaXNbaV0gPSB2YWx1ZVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgYnl0ZXMgPSB1dGY4VG9CeXRlcyh2YWx1ZS50b1N0cmluZygpKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gYnl0ZXNbaSAlIGxlbl1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgYEFycmF5QnVmZmVyYCB3aXRoIHRoZSAqY29waWVkKiBtZW1vcnkgb2YgdGhlIGJ1ZmZlciBpbnN0YW5jZS5cbiAqIEFkZGVkIGluIE5vZGUgMC4xMi4gT25seSBhdmFpbGFibGUgaW4gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IEFycmF5QnVmZmVyLlxuICovXG5CdWZmZXIucHJvdG90eXBlLnRvQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiB0b0FycmF5QnVmZmVyICgpIHtcbiAgaWYgKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgICAgcmV0dXJuIChuZXcgQnVmZmVyKHRoaXMpKS5idWZmZXJcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGJ1ZiA9IG5ldyBVaW50OEFycmF5KHRoaXMubGVuZ3RoKVxuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGJ1Zi5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgICBidWZbaV0gPSB0aGlzW2ldXG4gICAgICB9XG4gICAgICByZXR1cm4gYnVmLmJ1ZmZlclxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCdWZmZXIudG9BcnJheUJ1ZmZlciBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlcicpXG4gIH1cbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgQlAgPSBCdWZmZXIucHJvdG90eXBlXG5cbi8qKlxuICogQXVnbWVudCBhIFVpbnQ4QXJyYXkgKmluc3RhbmNlKiAobm90IHRoZSBVaW50OEFycmF5IGNsYXNzISkgd2l0aCBCdWZmZXIgbWV0aG9kc1xuICovXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiBfYXVnbWVudCAoYXJyKSB7XG4gIGFyci5jb25zdHJ1Y3RvciA9IEJ1ZmZlclxuICBhcnIuX2lzQnVmZmVyID0gdHJ1ZVxuXG4gIC8vIHNhdmUgcmVmZXJlbmNlIHRvIG9yaWdpbmFsIFVpbnQ4QXJyYXkgc2V0IG1ldGhvZCBiZWZvcmUgb3ZlcndyaXRpbmdcbiAgYXJyLl9zZXQgPSBhcnIuc2V0XG5cbiAgLy8gZGVwcmVjYXRlZFxuICBhcnIuZ2V0ID0gQlAuZ2V0XG4gIGFyci5zZXQgPSBCUC5zZXRcblxuICBhcnIud3JpdGUgPSBCUC53cml0ZVxuICBhcnIudG9TdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9Mb2NhbGVTdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9KU09OID0gQlAudG9KU09OXG4gIGFyci5lcXVhbHMgPSBCUC5lcXVhbHNcbiAgYXJyLmNvbXBhcmUgPSBCUC5jb21wYXJlXG4gIGFyci5pbmRleE9mID0gQlAuaW5kZXhPZlxuICBhcnIuY29weSA9IEJQLmNvcHlcbiAgYXJyLnNsaWNlID0gQlAuc2xpY2VcbiAgYXJyLnJlYWRVSW50TEUgPSBCUC5yZWFkVUludExFXG4gIGFyci5yZWFkVUludEJFID0gQlAucmVhZFVJbnRCRVxuICBhcnIucmVhZFVJbnQ4ID0gQlAucmVhZFVJbnQ4XG4gIGFyci5yZWFkVUludDE2TEUgPSBCUC5yZWFkVUludDE2TEVcbiAgYXJyLnJlYWRVSW50MTZCRSA9IEJQLnJlYWRVSW50MTZCRVxuICBhcnIucmVhZFVJbnQzMkxFID0gQlAucmVhZFVJbnQzMkxFXG4gIGFyci5yZWFkVUludDMyQkUgPSBCUC5yZWFkVUludDMyQkVcbiAgYXJyLnJlYWRJbnRMRSA9IEJQLnJlYWRJbnRMRVxuICBhcnIucmVhZEludEJFID0gQlAucmVhZEludEJFXG4gIGFyci5yZWFkSW50OCA9IEJQLnJlYWRJbnQ4XG4gIGFyci5yZWFkSW50MTZMRSA9IEJQLnJlYWRJbnQxNkxFXG4gIGFyci5yZWFkSW50MTZCRSA9IEJQLnJlYWRJbnQxNkJFXG4gIGFyci5yZWFkSW50MzJMRSA9IEJQLnJlYWRJbnQzMkxFXG4gIGFyci5yZWFkSW50MzJCRSA9IEJQLnJlYWRJbnQzMkJFXG4gIGFyci5yZWFkRmxvYXRMRSA9IEJQLnJlYWRGbG9hdExFXG4gIGFyci5yZWFkRmxvYXRCRSA9IEJQLnJlYWRGbG9hdEJFXG4gIGFyci5yZWFkRG91YmxlTEUgPSBCUC5yZWFkRG91YmxlTEVcbiAgYXJyLnJlYWREb3VibGVCRSA9IEJQLnJlYWREb3VibGVCRVxuICBhcnIud3JpdGVVSW50OCA9IEJQLndyaXRlVUludDhcbiAgYXJyLndyaXRlVUludExFID0gQlAud3JpdGVVSW50TEVcbiAgYXJyLndyaXRlVUludEJFID0gQlAud3JpdGVVSW50QkVcbiAgYXJyLndyaXRlVUludDE2TEUgPSBCUC53cml0ZVVJbnQxNkxFXG4gIGFyci53cml0ZVVJbnQxNkJFID0gQlAud3JpdGVVSW50MTZCRVxuICBhcnIud3JpdGVVSW50MzJMRSA9IEJQLndyaXRlVUludDMyTEVcbiAgYXJyLndyaXRlVUludDMyQkUgPSBCUC53cml0ZVVJbnQzMkJFXG4gIGFyci53cml0ZUludExFID0gQlAud3JpdGVJbnRMRVxuICBhcnIud3JpdGVJbnRCRSA9IEJQLndyaXRlSW50QkVcbiAgYXJyLndyaXRlSW50OCA9IEJQLndyaXRlSW50OFxuICBhcnIud3JpdGVJbnQxNkxFID0gQlAud3JpdGVJbnQxNkxFXG4gIGFyci53cml0ZUludDE2QkUgPSBCUC53cml0ZUludDE2QkVcbiAgYXJyLndyaXRlSW50MzJMRSA9IEJQLndyaXRlSW50MzJMRVxuICBhcnIud3JpdGVJbnQzMkJFID0gQlAud3JpdGVJbnQzMkJFXG4gIGFyci53cml0ZUZsb2F0TEUgPSBCUC53cml0ZUZsb2F0TEVcbiAgYXJyLndyaXRlRmxvYXRCRSA9IEJQLndyaXRlRmxvYXRCRVxuICBhcnIud3JpdGVEb3VibGVMRSA9IEJQLndyaXRlRG91YmxlTEVcbiAgYXJyLndyaXRlRG91YmxlQkUgPSBCUC53cml0ZURvdWJsZUJFXG4gIGFyci5maWxsID0gQlAuZmlsbFxuICBhcnIuaW5zcGVjdCA9IEJQLmluc3BlY3RcbiAgYXJyLnRvQXJyYXlCdWZmZXIgPSBCUC50b0FycmF5QnVmZmVyXG5cbiAgcmV0dXJuIGFyclxufVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSlcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJaTR1THk0dUx5NHVMeTR1TDJodmJXVXZZV1J0YVc0dlluSnZkM05sY21sbWVTMWpaRzR2Ym05a1pWOXRiMlIxYkdWekwySnliM2R6WlhKcFpua3ZibTlrWlY5dGIyUjFiR1Z6TDJKMVptWmxjaTlwYm1SbGVDNXFjeUpkTENKdVlXMWxjeUk2VzEwc0ltMWhjSEJwYm1keklqb2lPMEZCUVVFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFaUxDSm1hV3hsSWpvaVoyVnVaWEpoZEdWa0xtcHpJaXdpYzI5MWNtTmxVbTl2ZENJNklpSXNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJJaThxSVZ4dUlDb2dWR2hsSUdKMVptWmxjaUJ0YjJSMWJHVWdabkp2YlNCdWIyUmxMbXB6TENCbWIzSWdkR2hsSUdKeWIzZHpaWEl1WEc0Z0tseHVJQ29nUUdGMWRHaHZjaUFnSUVabGNtOXpjeUJCWW05MWEyaGhaR2xxWldnZ1BHWmxjbTl6YzBCbVpYSnZjM011YjNKblBpQThhSFIwY0RvdkwyWmxjbTl6Y3k1dmNtYytYRzRnS2lCQWJHbGpaVzV6WlNBZ1RVbFVYRzRnS2k5Y2JpOHFJR1Z6YkdsdWRDMWthWE5oWW14bElHNXZMWEJ5YjNSdklDb3ZYRzVjYmlkMWMyVWdjM1J5YVdOMEoxeHVYRzUyWVhJZ1ltRnpaVFkwSUQwZ2NtVnhkV2x5WlNnblltRnpaVFkwTFdwekp5bGNiblpoY2lCcFpXVmxOelUwSUQwZ2NtVnhkV2x5WlNnbmFXVmxaVGMxTkNjcFhHNTJZWElnYVhOQmNuSmhlU0E5SUhKbGNYVnBjbVVvSjJsellYSnlZWGtuS1Z4dVhHNWxlSEJ2Y25SekxrSjFabVpsY2lBOUlFSjFabVpsY2x4dVpYaHdiM0owY3k1VGJHOTNRblZtWm1WeUlEMGdVMnh2ZDBKMVptWmxjbHh1Wlhod2IzSjBjeTVKVGxOUVJVTlVYMDFCV0Y5Q1dWUkZVeUE5SURVd1hHNUNkV1ptWlhJdWNHOXZiRk5wZW1VZ1BTQTRNVGt5SUM4dklHNXZkQ0IxYzJWa0lHSjVJSFJvYVhNZ2FXMXdiR1Z0Wlc1MFlYUnBiMjVjYmx4dWRtRnlJSEp2YjNSUVlYSmxiblFnUFNCN2ZWeHVYRzR2S2lwY2JpQXFJRWxtSUdCQ2RXWm1aWEl1VkZsUVJVUmZRVkpTUVZsZlUxVlFVRTlTVkdBNlhHNGdLaUFnSUQwOVBTQjBjblZsSUNBZ0lGVnpaU0JWYVc1ME9FRnljbUY1SUdsdGNHeGxiV1Z1ZEdGMGFXOXVJQ2htWVhOMFpYTjBLVnh1SUNvZ0lDQTlQVDBnWm1Gc2MyVWdJQ0JWYzJVZ1QySnFaV04wSUdsdGNHeGxiV1Z1ZEdGMGFXOXVJQ2h0YjNOMElHTnZiWEJoZEdsaWJHVXNJR1YyWlc0Z1NVVTJLVnh1SUNwY2JpQXFJRUp5YjNkelpYSnpJSFJvWVhRZ2MzVndjRzl5ZENCMGVYQmxaQ0JoY25KaGVYTWdZWEpsSUVsRklERXdLeXdnUm1seVpXWnZlQ0EwS3l3Z1EyaHliMjFsSURjckxDQlRZV1poY21rZ05TNHhLeXhjYmlBcUlFOXdaWEpoSURFeExqWXJMQ0JwVDFNZ05DNHlLeTVjYmlBcVhHNGdLaUJFZFdVZ2RHOGdkbUZ5YVc5MWN5QmljbTkzYzJWeUlHSjFaM01zSUhOdmJXVjBhVzFsY3lCMGFHVWdUMkpxWldOMElHbHRjR3hsYldWdWRHRjBhVzl1SUhkcGJHd2dZbVVnZFhObFpDQmxkbVZ1WEc0Z0tpQjNhR1Z1SUhSb1pTQmljbTkzYzJWeUlITjFjSEJ2Y25SeklIUjVjR1ZrSUdGeWNtRjVjeTVjYmlBcVhHNGdLaUJPYjNSbE9seHVJQ3BjYmlBcUlDQWdMU0JHYVhKbFptOTRJRFF0TWprZ2JHRmphM01nYzNWd2NHOXlkQ0JtYjNJZ1lXUmthVzVuSUc1bGR5QndjbTl3WlhKMGFXVnpJSFJ2SUdCVmFXNTBPRUZ5Y21GNVlDQnBibk4wWVc1alpYTXNYRzRnS2lBZ0lDQWdVMlZsT2lCb2RIUndjem92TDJKMVozcHBiR3hoTG0xdmVtbHNiR0V1YjNKbkwzTm9iM2RmWW5WbkxtTm5hVDlwWkQwMk9UVTBNemd1WEc0Z0tseHVJQ29nSUNBdElGTmhabUZ5YVNBMUxUY2diR0ZqYTNNZ2MzVndjRzl5ZENCbWIzSWdZMmhoYm1kcGJtY2dkR2hsSUdCUFltcGxZM1F1Y0hKdmRHOTBlWEJsTG1OdmJuTjBjblZqZEc5eVlDQndjbTl3WlhKMGVWeHVJQ29nSUNBZ0lHOXVJRzlpYW1WamRITXVYRzRnS2x4dUlDb2dJQ0F0SUVOb2NtOXRaU0E1TFRFd0lHbHpJRzFwYzNOcGJtY2dkR2hsSUdCVWVYQmxaRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXpkV0poY25KaGVXQWdablZ1WTNScGIyNHVYRzRnS2x4dUlDb2dJQ0F0SUVsRk1UQWdhR0Z6SUdFZ1luSnZhMlZ1SUdCVWVYQmxaRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXpkV0poY25KaGVXQWdablZ1WTNScGIyNGdkMmhwWTJnZ2NtVjBkWEp1Y3lCaGNuSmhlWE1nYjJaY2JpQXFJQ0FnSUNCcGJtTnZjbkpsWTNRZ2JHVnVaM1JvSUdsdUlITnZiV1VnYzJsMGRXRjBhVzl1Y3k1Y2JseHVJQ29nVjJVZ1pHVjBaV04wSUhSb1pYTmxJR0oxWjJkNUlHSnliM2R6WlhKeklHRnVaQ0J6WlhRZ1lFSjFabVpsY2k1VVdWQkZSRjlCVWxKQldWOVRWVkJRVDFKVVlDQjBieUJnWm1Gc2MyVmdJSE52SUhSb1pYbGNiaUFxSUdkbGRDQjBhR1VnVDJKcVpXTjBJR2x0Y0d4bGJXVnVkR0YwYVc5dUxDQjNhR2xqYUNCcGN5QnpiRzkzWlhJZ1luVjBJR0psYUdGMlpYTWdZMjl5Y21WamRHeDVMbHh1SUNvdlhHNUNkV1ptWlhJdVZGbFFSVVJmUVZKU1FWbGZVMVZRVUU5U1ZDQTlJR2RzYjJKaGJDNVVXVkJGUkY5QlVsSkJXVjlUVlZCUVQxSlVJQ0U5UFNCMWJtUmxabWx1WldSY2JpQWdQeUJuYkc5aVlXd3VWRmxRUlVSZlFWSlNRVmxmVTFWUVVFOVNWRnh1SUNBNklIUjVjR1ZrUVhKeVlYbFRkWEJ3YjNKMEtDbGNibHh1Wm5WdVkzUnBiMjRnZEhsd1pXUkJjbkpoZVZOMWNIQnZjblFnS0NrZ2UxeHVJQ0JtZFc1amRHbHZiaUJDWVhJZ0tDa2dlMzFjYmlBZ2RISjVJSHRjYmlBZ0lDQjJZWElnWVhKeUlEMGdibVYzSUZWcGJuUTRRWEp5WVhrb01TbGNiaUFnSUNCaGNuSXVabTl2SUQwZ1puVnVZM1JwYjI0Z0tDa2dleUJ5WlhSMWNtNGdORElnZlZ4dUlDQWdJR0Z5Y2k1amIyNXpkSEoxWTNSdmNpQTlJRUpoY2x4dUlDQWdJSEpsZEhWeWJpQmhjbkl1Wm05dktDa2dQVDA5SURReUlDWW1JQzh2SUhSNWNHVmtJR0Z5Y21GNUlHbHVjM1JoYm1ObGN5QmpZVzRnWW1VZ1lYVm5iV1Z1ZEdWa1hHNGdJQ0FnSUNBZ0lHRnljaTVqYjI1emRISjFZM1J2Y2lBOVBUMGdRbUZ5SUNZbUlDOHZJR052Ym5OMGNuVmpkRzl5SUdOaGJpQmlaU0J6WlhSY2JpQWdJQ0FnSUNBZ2RIbHdaVzltSUdGeWNpNXpkV0poY25KaGVTQTlQVDBnSjJaMWJtTjBhVzl1SnlBbUppQXZMeUJqYUhKdmJXVWdPUzB4TUNCc1lXTnJJR0J6ZFdKaGNuSmhlV0JjYmlBZ0lDQWdJQ0FnWVhKeUxuTjFZbUZ5Y21GNUtERXNJREVwTG1KNWRHVk1aVzVuZEdnZ1BUMDlJREFnTHk4Z2FXVXhNQ0JvWVhNZ1luSnZhMlZ1SUdCemRXSmhjbkpoZVdCY2JpQWdmU0JqWVhSamFDQW9aU2tnZTF4dUlDQWdJSEpsZEhWeWJpQm1ZV3h6WlZ4dUlDQjlYRzU5WEc1Y2JtWjFibU4wYVc5dUlHdE5ZWGhNWlc1bmRHZ2dLQ2tnZTF4dUlDQnlaWFIxY200Z1FuVm1abVZ5TGxSWlVFVkVYMEZTVWtGWlgxTlZVRkJQVWxSY2JpQWdJQ0EvSURCNE4yWm1abVptWm1aY2JpQWdJQ0E2SURCNE0yWm1abVptWm1aY2JuMWNibHh1THlvcVhHNGdLaUJEYkdGemN6b2dRblZtWm1WeVhHNGdLaUE5UFQwOVBUMDlQVDA5UFQwOVhHNGdLbHh1SUNvZ1ZHaGxJRUoxWm1abGNpQmpiMjV6ZEhKMVkzUnZjaUJ5WlhSMWNtNXpJR2x1YzNSaGJtTmxjeUJ2WmlCZ1ZXbHVkRGhCY25KaGVXQWdkR2hoZENCaGNtVWdZWFZuYldWdWRHVmtYRzRnS2lCM2FYUm9JR1oxYm1OMGFXOXVJSEJ5YjNCbGNuUnBaWE1nWm05eUlHRnNiQ0IwYUdVZ2JtOWtaU0JnUW5WbVptVnlZQ0JCVUVrZ1puVnVZM1JwYjI1ekxpQlhaU0IxYzJWY2JpQXFJR0JWYVc1ME9FRnljbUY1WUNCemJ5QjBhR0YwSUhOeGRXRnlaU0JpY21GamEyVjBJRzV2ZEdGMGFXOXVJSGR2Y210eklHRnpJR1Y0Y0dWamRHVmtJQzB0SUdsMElISmxkSFZ5Ym5OY2JpQXFJR0VnYzJsdVoyeGxJRzlqZEdWMExseHVJQ3BjYmlBcUlFSjVJR0YxWjIxbGJuUnBibWNnZEdobElHbHVjM1JoYm1ObGN5d2dkMlVnWTJGdUlHRjJiMmxrSUcxdlpHbG1lV2x1WnlCMGFHVWdZRlZwYm5RNFFYSnlZWGxnWEc0Z0tpQndjbTkwYjNSNWNHVXVYRzRnS2k5Y2JtWjFibU4wYVc5dUlFSjFabVpsY2lBb1lYSm5LU0I3WEc0Z0lHbG1JQ2doS0hSb2FYTWdhVzV6ZEdGdVkyVnZaaUJDZFdabVpYSXBLU0I3WEc0Z0lDQWdMeThnUVhadmFXUWdaMjlwYm1jZ2RHaHliM1ZuYUNCaGJpQkJjbWQxYldWdWRITkJaR0Z3ZEc5eVZISmhiWEJ2YkdsdVpTQnBiaUIwYUdVZ1kyOXRiVzl1SUdOaGMyVXVYRzRnSUNBZ2FXWWdLR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ2dQaUF4S1NCeVpYUjFjbTRnYm1WM0lFSjFabVpsY2loaGNtY3NJR0Z5WjNWdFpXNTBjMXN4WFNsY2JpQWdJQ0J5WlhSMWNtNGdibVYzSUVKMVptWmxjaWhoY21jcFhHNGdJSDFjYmx4dUlDQnBaaUFvSVVKMVptWmxjaTVVV1ZCRlJGOUJVbEpCV1Y5VFZWQlFUMUpVS1NCN1hHNGdJQ0FnZEdocGN5NXNaVzVuZEdnZ1BTQXdYRzRnSUNBZ2RHaHBjeTV3WVhKbGJuUWdQU0IxYm1SbFptbHVaV1JjYmlBZ2ZWeHVYRzRnSUM4dklFTnZiVzF2YmlCallYTmxMbHh1SUNCcFppQW9kSGx3Wlc5bUlHRnlaeUE5UFQwZ0oyNTFiV0psY2ljcElIdGNiaUFnSUNCeVpYUjFjbTRnWm5KdmJVNTFiV0psY2loMGFHbHpMQ0JoY21jcFhHNGdJSDFjYmx4dUlDQXZMeUJUYkdsbmFIUnNlU0JzWlhOeklHTnZiVzF2YmlCallYTmxMbHh1SUNCcFppQW9kSGx3Wlc5bUlHRnlaeUE5UFQwZ0ozTjBjbWx1WnljcElIdGNiaUFnSUNCeVpYUjFjbTRnWm5KdmJWTjBjbWx1WnloMGFHbHpMQ0JoY21jc0lHRnlaM1Z0Wlc1MGN5NXNaVzVuZEdnZ1BpQXhJRDhnWVhKbmRXMWxiblJ6V3pGZElEb2dKM1YwWmpnbktWeHVJQ0I5WEc1Y2JpQWdMeThnVlc1MWMzVmhiQzVjYmlBZ2NtVjBkWEp1SUdaeWIyMVBZbXBsWTNRb2RHaHBjeXdnWVhKbktWeHVmVnh1WEc1bWRXNWpkR2x2YmlCbWNtOXRUblZ0WW1WeUlDaDBhR0YwTENCc1pXNW5kR2dwSUh0Y2JpQWdkR2hoZENBOUlHRnNiRzlqWVhSbEtIUm9ZWFFzSUd4bGJtZDBhQ0E4SURBZ1B5QXdJRG9nWTJobFkydGxaQ2hzWlc1bmRHZ3BJSHdnTUNsY2JpQWdhV1lnS0NGQ2RXWm1aWEl1VkZsUVJVUmZRVkpTUVZsZlUxVlFVRTlTVkNrZ2UxeHVJQ0FnSUdadmNpQW9kbUZ5SUdrZ1BTQXdPeUJwSUR3Z2JHVnVaM1JvT3lCcEt5c3BJSHRjYmlBZ0lDQWdJSFJvWVhSYmFWMGdQU0F3WEc0Z0lDQWdmVnh1SUNCOVhHNGdJSEpsZEhWeWJpQjBhR0YwWEc1OVhHNWNibVoxYm1OMGFXOXVJR1p5YjIxVGRISnBibWNnS0hSb1lYUXNJSE4wY21sdVp5d2daVzVqYjJScGJtY3BJSHRjYmlBZ2FXWWdLSFI1Y0dWdlppQmxibU52WkdsdVp5QWhQVDBnSjNOMGNtbHVaeWNnZkh3Z1pXNWpiMlJwYm1jZ1BUMDlJQ2NuS1NCbGJtTnZaR2x1WnlBOUlDZDFkR1k0SjF4dVhHNGdJQzh2SUVGemMzVnRjSFJwYjI0NklHSjVkR1ZNWlc1bmRHZ29LU0J5WlhSMWNtNGdkbUZzZFdVZ2FYTWdZV3gzWVhseklEd2dhMDFoZUV4bGJtZDBhQzVjYmlBZ2RtRnlJR3hsYm1kMGFDQTlJR0o1ZEdWTVpXNW5kR2dvYzNSeWFXNW5MQ0JsYm1OdlpHbHVaeWtnZkNBd1hHNGdJSFJvWVhRZ1BTQmhiR3h2WTJGMFpTaDBhR0YwTENCc1pXNW5kR2dwWEc1Y2JpQWdkR2hoZEM1M2NtbDBaU2h6ZEhKcGJtY3NJR1Z1WTI5a2FXNW5LVnh1SUNCeVpYUjFjbTRnZEdoaGRGeHVmVnh1WEc1bWRXNWpkR2x2YmlCbWNtOXRUMkpxWldOMElDaDBhR0YwTENCdlltcGxZM1FwSUh0Y2JpQWdhV1lnS0VKMVptWmxjaTVwYzBKMVptWmxjaWh2WW1wbFkzUXBLU0J5WlhSMWNtNGdabkp2YlVKMVptWmxjaWgwYUdGMExDQnZZbXBsWTNRcFhHNWNiaUFnYVdZZ0tHbHpRWEp5WVhrb2IySnFaV04wS1NrZ2NtVjBkWEp1SUdaeWIyMUJjbkpoZVNoMGFHRjBMQ0J2WW1wbFkzUXBYRzVjYmlBZ2FXWWdLRzlpYW1WamRDQTlQU0J1ZFd4c0tTQjdYRzRnSUNBZ2RHaHliM2NnYm1WM0lGUjVjR1ZGY25KdmNpZ25iWFZ6ZENCemRHRnlkQ0IzYVhSb0lHNTFiV0psY2l3Z1luVm1abVZ5TENCaGNuSmhlU0J2Y2lCemRISnBibWNuS1Z4dUlDQjlYRzVjYmlBZ2FXWWdLSFI1Y0dWdlppQkJjbkpoZVVKMVptWmxjaUFoUFQwZ0ozVnVaR1ZtYVc1bFpDY3BJSHRjYmlBZ0lDQnBaaUFvYjJKcVpXTjBMbUoxWm1abGNpQnBibk4wWVc1alpXOW1JRUZ5Y21GNVFuVm1abVZ5S1NCN1hHNGdJQ0FnSUNCeVpYUjFjbTRnWm5KdmJWUjVjR1ZrUVhKeVlYa29kR2hoZEN3Z2IySnFaV04wS1Z4dUlDQWdJSDFjYmlBZ0lDQnBaaUFvYjJKcVpXTjBJR2x1YzNSaGJtTmxiMllnUVhKeVlYbENkV1ptWlhJcElIdGNiaUFnSUNBZ0lISmxkSFZ5YmlCbWNtOXRRWEp5WVhsQ2RXWm1aWElvZEdoaGRDd2diMkpxWldOMEtWeHVJQ0FnSUgxY2JpQWdmVnh1WEc0Z0lHbG1JQ2h2WW1wbFkzUXViR1Z1WjNSb0tTQnlaWFIxY200Z1puSnZiVUZ5Y21GNVRHbHJaU2gwYUdGMExDQnZZbXBsWTNRcFhHNWNiaUFnY21WMGRYSnVJR1p5YjIxS2MyOXVUMkpxWldOMEtIUm9ZWFFzSUc5aWFtVmpkQ2xjYm4xY2JseHVablZ1WTNScGIyNGdabkp2YlVKMVptWmxjaUFvZEdoaGRDd2dZblZtWm1WeUtTQjdYRzRnSUhaaGNpQnNaVzVuZEdnZ1BTQmphR1ZqYTJWa0tHSjFabVpsY2k1c1pXNW5kR2dwSUh3Z01GeHVJQ0IwYUdGMElEMGdZV3hzYjJOaGRHVW9kR2hoZEN3Z2JHVnVaM1JvS1Z4dUlDQmlkV1ptWlhJdVkyOXdlU2gwYUdGMExDQXdMQ0F3TENCc1pXNW5kR2dwWEc0Z0lISmxkSFZ5YmlCMGFHRjBYRzU5WEc1Y2JtWjFibU4wYVc5dUlHWnliMjFCY25KaGVTQW9kR2hoZEN3Z1lYSnlZWGtwSUh0Y2JpQWdkbUZ5SUd4bGJtZDBhQ0E5SUdOb1pXTnJaV1FvWVhKeVlYa3ViR1Z1WjNSb0tTQjhJREJjYmlBZ2RHaGhkQ0E5SUdGc2JHOWpZWFJsS0hSb1lYUXNJR3hsYm1kMGFDbGNiaUFnWm05eUlDaDJZWElnYVNBOUlEQTdJR2tnUENCc1pXNW5kR2c3SUdrZ0t6MGdNU2tnZTF4dUlDQWdJSFJvWVhSYmFWMGdQU0JoY25KaGVWdHBYU0FtSURJMU5WeHVJQ0I5WEc0Z0lISmxkSFZ5YmlCMGFHRjBYRzU5WEc1Y2JpOHZJRVIxY0d4cFkyRjBaU0J2WmlCbWNtOXRRWEp5WVhrb0tTQjBieUJyWldWd0lHWnliMjFCY25KaGVTZ3BJRzF2Ym05dGIzSndhR2xqTGx4dVpuVnVZM1JwYjI0Z1puSnZiVlI1Y0dWa1FYSnlZWGtnS0hSb1lYUXNJR0Z5Y21GNUtTQjdYRzRnSUhaaGNpQnNaVzVuZEdnZ1BTQmphR1ZqYTJWa0tHRnljbUY1TG14bGJtZDBhQ2tnZkNBd1hHNGdJSFJvWVhRZ1BTQmhiR3h2WTJGMFpTaDBhR0YwTENCc1pXNW5kR2dwWEc0Z0lDOHZJRlJ5ZFc1allYUnBibWNnZEdobElHVnNaVzFsYm5SeklHbHpJSEJ5YjJKaFlteDVJRzV2ZENCM2FHRjBJSEJsYjNCc1pTQmxlSEJsWTNRZ1puSnZiU0IwZVhCbFpGeHVJQ0F2THlCaGNuSmhlWE1nZDJsMGFDQkNXVlJGVTE5UVJWSmZSVXhGVFVWT1ZDQStJREVnWW5WMElHbDBKM01nWTI5dGNHRjBhV0pzWlNCM2FYUm9JSFJvWlNCaVpXaGhkbWx2Y2x4dUlDQXZMeUJ2WmlCMGFHVWdiMnhrSUVKMVptWmxjaUJqYjI1emRISjFZM1J2Y2k1Y2JpQWdabTl5SUNoMllYSWdhU0E5SURBN0lHa2dQQ0JzWlc1bmRHZzdJR2tnS3owZ01Ta2dlMXh1SUNBZ0lIUm9ZWFJiYVYwZ1BTQmhjbkpoZVZ0cFhTQW1JREkxTlZ4dUlDQjlYRzRnSUhKbGRIVnliaUIwYUdGMFhHNTlYRzVjYm1aMWJtTjBhVzl1SUdaeWIyMUJjbkpoZVVKMVptWmxjaUFvZEdoaGRDd2dZWEp5WVhrcElIdGNiaUFnYVdZZ0tFSjFabVpsY2k1VVdWQkZSRjlCVWxKQldWOVRWVkJRVDFKVUtTQjdYRzRnSUNBZ0x5OGdVbVYwZFhKdUlHRnVJR0YxWjIxbGJuUmxaQ0JnVldsdWREaEJjbkpoZVdBZ2FXNXpkR0Z1WTJVc0lHWnZjaUJpWlhOMElIQmxjbVp2Y20xaGJtTmxYRzRnSUNBZ1lYSnlZWGt1WW5sMFpVeGxibWQwYUZ4dUlDQWdJSFJvWVhRZ1BTQkNkV1ptWlhJdVgyRjFaMjFsYm5Rb2JtVjNJRlZwYm5RNFFYSnlZWGtvWVhKeVlYa3BLVnh1SUNCOUlHVnNjMlVnZTF4dUlDQWdJQzh2SUVaaGJHeGlZV05yT2lCU1pYUjFjbTRnWVc0Z2IySnFaV04wSUdsdWMzUmhibU5sSUc5bUlIUm9aU0JDZFdabVpYSWdZMnhoYzNOY2JpQWdJQ0IwYUdGMElEMGdabkp2YlZSNWNHVmtRWEp5WVhrb2RHaGhkQ3dnYm1WM0lGVnBiblE0UVhKeVlYa29ZWEp5WVhrcEtWeHVJQ0I5WEc0Z0lISmxkSFZ5YmlCMGFHRjBYRzU5WEc1Y2JtWjFibU4wYVc5dUlHWnliMjFCY25KaGVVeHBhMlVnS0hSb1lYUXNJR0Z5Y21GNUtTQjdYRzRnSUhaaGNpQnNaVzVuZEdnZ1BTQmphR1ZqYTJWa0tHRnljbUY1TG14bGJtZDBhQ2tnZkNBd1hHNGdJSFJvWVhRZ1BTQmhiR3h2WTJGMFpTaDBhR0YwTENCc1pXNW5kR2dwWEc0Z0lHWnZjaUFvZG1GeUlHa2dQU0F3T3lCcElEd2diR1Z1WjNSb095QnBJQ3M5SURFcElIdGNiaUFnSUNCMGFHRjBXMmxkSUQwZ1lYSnlZWGxiYVYwZ0ppQXlOVFZjYmlBZ2ZWeHVJQ0J5WlhSMWNtNGdkR2hoZEZ4dWZWeHVYRzR2THlCRVpYTmxjbWxoYkdsNlpTQjdJSFI1Y0dVNklDZENkV1ptWlhJbkxDQmtZWFJoT2lCYk1Td3lMRE1zTGk0dVhTQjlJR2x1ZEc4Z1lTQkNkV1ptWlhJZ2IySnFaV04wTGx4dUx5OGdVbVYwZFhKdWN5QmhJSHBsY204dGJHVnVaM1JvSUdKMVptWmxjaUJtYjNJZ2FXNXdkWFJ6SUhSb1lYUWdaRzl1SjNRZ1kyOXVabTl5YlNCMGJ5QjBhR1VnYzNCbFl5NWNibVoxYm1OMGFXOXVJR1p5YjIxS2MyOXVUMkpxWldOMElDaDBhR0YwTENCdlltcGxZM1FwSUh0Y2JpQWdkbUZ5SUdGeWNtRjVYRzRnSUhaaGNpQnNaVzVuZEdnZ1BTQXdYRzVjYmlBZ2FXWWdLRzlpYW1WamRDNTBlWEJsSUQwOVBTQW5RblZtWm1WeUp5QW1KaUJwYzBGeWNtRjVLRzlpYW1WamRDNWtZWFJoS1NrZ2UxeHVJQ0FnSUdGeWNtRjVJRDBnYjJKcVpXTjBMbVJoZEdGY2JpQWdJQ0JzWlc1bmRHZ2dQU0JqYUdWamEyVmtLR0Z5Y21GNUxteGxibWQwYUNrZ2ZDQXdYRzRnSUgxY2JpQWdkR2hoZENBOUlHRnNiRzlqWVhSbEtIUm9ZWFFzSUd4bGJtZDBhQ2xjYmx4dUlDQm1iM0lnS0haaGNpQnBJRDBnTURzZ2FTQThJR3hsYm1kMGFEc2dhU0FyUFNBeEtTQjdYRzRnSUNBZ2RHaGhkRnRwWFNBOUlHRnljbUY1VzJsZElDWWdNalUxWEc0Z0lIMWNiaUFnY21WMGRYSnVJSFJvWVhSY2JuMWNibHh1YVdZZ0tFSjFabVpsY2k1VVdWQkZSRjlCVWxKQldWOVRWVkJRVDFKVUtTQjdYRzRnSUVKMVptWmxjaTV3Y205MGIzUjVjR1V1WDE5d2NtOTBiMTlmSUQwZ1ZXbHVkRGhCY25KaGVTNXdjbTkwYjNSNWNHVmNiaUFnUW5WbVptVnlMbDlmY0hKdmRHOWZYeUE5SUZWcGJuUTRRWEp5WVhsY2JuMGdaV3h6WlNCN1hHNGdJQzh2SUhCeVpTMXpaWFFnWm05eUlIWmhiSFZsY3lCMGFHRjBJRzFoZVNCbGVHbHpkQ0JwYmlCMGFHVWdablYwZFhKbFhHNGdJRUoxWm1abGNpNXdjbTkwYjNSNWNHVXViR1Z1WjNSb0lEMGdkVzVrWldacGJtVmtYRzRnSUVKMVptWmxjaTV3Y205MGIzUjVjR1V1Y0dGeVpXNTBJRDBnZFc1a1pXWnBibVZrWEc1OVhHNWNibVoxYm1OMGFXOXVJR0ZzYkc5allYUmxJQ2gwYUdGMExDQnNaVzVuZEdncElIdGNiaUFnYVdZZ0tFSjFabVpsY2k1VVdWQkZSRjlCVWxKQldWOVRWVkJRVDFKVUtTQjdYRzRnSUNBZ0x5OGdVbVYwZFhKdUlHRnVJR0YxWjIxbGJuUmxaQ0JnVldsdWREaEJjbkpoZVdBZ2FXNXpkR0Z1WTJVc0lHWnZjaUJpWlhOMElIQmxjbVp2Y20xaGJtTmxYRzRnSUNBZ2RHaGhkQ0E5SUVKMVptWmxjaTVmWVhWbmJXVnVkQ2h1WlhjZ1ZXbHVkRGhCY25KaGVTaHNaVzVuZEdncEtWeHVJQ0FnSUhSb1lYUXVYMTl3Y205MGIxOWZJRDBnUW5WbVptVnlMbkJ5YjNSdmRIbHdaVnh1SUNCOUlHVnNjMlVnZTF4dUlDQWdJQzh2SUVaaGJHeGlZV05yT2lCU1pYUjFjbTRnWVc0Z2IySnFaV04wSUdsdWMzUmhibU5sSUc5bUlIUm9aU0JDZFdabVpYSWdZMnhoYzNOY2JpQWdJQ0IwYUdGMExteGxibWQwYUNBOUlHeGxibWQwYUZ4dUlDQWdJSFJvWVhRdVgybHpRblZtWm1WeUlEMGdkSEoxWlZ4dUlDQjlYRzVjYmlBZ2RtRnlJR1p5YjIxUWIyOXNJRDBnYkdWdVozUm9JQ0U5UFNBd0lDWW1JR3hsYm1kMGFDQThQU0JDZFdabVpYSXVjRzl2YkZOcGVtVWdQajQrSURGY2JpQWdhV1lnS0daeWIyMVFiMjlzS1NCMGFHRjBMbkJoY21WdWRDQTlJSEp2YjNSUVlYSmxiblJjYmx4dUlDQnlaWFIxY200Z2RHaGhkRnh1ZlZ4dVhHNW1kVzVqZEdsdmJpQmphR1ZqYTJWa0lDaHNaVzVuZEdncElIdGNiaUFnTHk4Z1RtOTBaVG9nWTJGdWJtOTBJSFZ6WlNCZ2JHVnVaM1JvSUR3Z2EwMWhlRXhsYm1kMGFHQWdhR1Z5WlNCaVpXTmhkWE5sSUhSb1lYUWdabUZwYkhNZ2QyaGxibHh1SUNBdkx5QnNaVzVuZEdnZ2FYTWdUbUZPSUNoM2FHbGphQ0JwY3lCdmRHaGxjbmRwYzJVZ1kyOWxjbU5sWkNCMGJ5QjZaWEp2TGlsY2JpQWdhV1lnS0d4bGJtZDBhQ0ErUFNCclRXRjRUR1Z1WjNSb0tDa3BJSHRjYmlBZ0lDQjBhSEp2ZHlCdVpYY2dVbUZ1WjJWRmNuSnZjaWduUVhSMFpXMXdkQ0IwYnlCaGJHeHZZMkYwWlNCQ2RXWm1aWElnYkdGeVoyVnlJSFJvWVc0Z2JXRjRhVzExYlNBbklDdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQW5jMmw2WlRvZ01IZ25JQ3NnYTAxaGVFeGxibWQwYUNncExuUnZVM1J5YVc1bktERTJLU0FySUNjZ1lubDBaWE1uS1Z4dUlDQjlYRzRnSUhKbGRIVnliaUJzWlc1bmRHZ2dmQ0F3WEc1OVhHNWNibVoxYm1OMGFXOXVJRk5zYjNkQ2RXWm1aWElnS0hOMVltcGxZM1FzSUdWdVkyOWthVzVuS1NCN1hHNGdJR2xtSUNnaEtIUm9hWE1nYVc1emRHRnVZMlZ2WmlCVGJHOTNRblZtWm1WeUtTa2djbVYwZFhKdUlHNWxkeUJUYkc5M1FuVm1abVZ5S0hOMVltcGxZM1FzSUdWdVkyOWthVzVuS1Z4dVhHNGdJSFpoY2lCaWRXWWdQU0J1WlhjZ1FuVm1abVZ5S0hOMVltcGxZM1FzSUdWdVkyOWthVzVuS1Z4dUlDQmtaV3hsZEdVZ1luVm1MbkJoY21WdWRGeHVJQ0J5WlhSMWNtNGdZblZtWEc1OVhHNWNia0oxWm1abGNpNXBjMEoxWm1abGNpQTlJR1oxYm1OMGFXOXVJR2x6UW5WbVptVnlJQ2hpS1NCN1hHNGdJSEpsZEhWeWJpQWhJU2hpSUNFOUlHNTFiR3dnSmlZZ1lpNWZhWE5DZFdabVpYSXBYRzU5WEc1Y2JrSjFabVpsY2k1amIyMXdZWEpsSUQwZ1puVnVZM1JwYjI0Z1kyOXRjR0Z5WlNBb1lTd2dZaWtnZTF4dUlDQnBaaUFvSVVKMVptWmxjaTVwYzBKMVptWmxjaWhoS1NCOGZDQWhRblZtWm1WeUxtbHpRblZtWm1WeUtHSXBLU0I3WEc0Z0lDQWdkR2h5YjNjZ2JtVjNJRlI1Y0dWRmNuSnZjaWduUVhKbmRXMWxiblJ6SUcxMWMzUWdZbVVnUW5WbVptVnljeWNwWEc0Z0lIMWNibHh1SUNCcFppQW9ZU0E5UFQwZ1lpa2djbVYwZFhKdUlEQmNibHh1SUNCMllYSWdlQ0E5SUdFdWJHVnVaM1JvWEc0Z0lIWmhjaUI1SUQwZ1lpNXNaVzVuZEdoY2JseHVJQ0IyWVhJZ2FTQTlJREJjYmlBZ2RtRnlJR3hsYmlBOUlFMWhkR2d1YldsdUtIZ3NJSGtwWEc0Z0lIZG9hV3hsSUNocElEd2diR1Z1S1NCN1hHNGdJQ0FnYVdZZ0tHRmJhVjBnSVQwOUlHSmJhVjBwSUdKeVpXRnJYRzVjYmlBZ0lDQXJLMmxjYmlBZ2ZWeHVYRzRnSUdsbUlDaHBJQ0U5UFNCc1pXNHBJSHRjYmlBZ0lDQjRJRDBnWVZ0cFhWeHVJQ0FnSUhrZ1BTQmlXMmxkWEc0Z0lIMWNibHh1SUNCcFppQW9lQ0E4SUhrcElISmxkSFZ5YmlBdE1WeHVJQ0JwWmlBb2VTQThJSGdwSUhKbGRIVnliaUF4WEc0Z0lISmxkSFZ5YmlBd1hHNTlYRzVjYmtKMVptWmxjaTVwYzBWdVkyOWthVzVuSUQwZ1puVnVZM1JwYjI0Z2FYTkZibU52WkdsdVp5QW9aVzVqYjJScGJtY3BJSHRjYmlBZ2MzZHBkR05vSUNoVGRISnBibWNvWlc1amIyUnBibWNwTG5SdlRHOTNaWEpEWVhObEtDa3BJSHRjYmlBZ0lDQmpZWE5sSUNkb1pYZ25PbHh1SUNBZ0lHTmhjMlVnSjNWMFpqZ25PbHh1SUNBZ0lHTmhjMlVnSjNWMFppMDRKenBjYmlBZ0lDQmpZWE5sSUNkaGMyTnBhU2M2WEc0Z0lDQWdZMkZ6WlNBblltbHVZWEo1SnpwY2JpQWdJQ0JqWVhObElDZGlZWE5sTmpRbk9seHVJQ0FnSUdOaGMyVWdKM0poZHljNlhHNGdJQ0FnWTJGelpTQW5kV056TWljNlhHNGdJQ0FnWTJGelpTQW5kV056TFRJbk9seHVJQ0FnSUdOaGMyVWdKM1YwWmpFMmJHVW5PbHh1SUNBZ0lHTmhjMlVnSjNWMFppMHhObXhsSnpwY2JpQWdJQ0FnSUhKbGRIVnliaUIwY25WbFhHNGdJQ0FnWkdWbVlYVnNkRHBjYmlBZ0lDQWdJSEpsZEhWeWJpQm1ZV3h6WlZ4dUlDQjlYRzU5WEc1Y2JrSjFabVpsY2k1amIyNWpZWFFnUFNCbWRXNWpkR2x2YmlCamIyNWpZWFFnS0d4cGMzUXNJR3hsYm1kMGFDa2dlMXh1SUNCcFppQW9JV2x6UVhKeVlYa29iR2x6ZENrcElIUm9jbTkzSUc1bGR5QlVlWEJsUlhKeWIzSW9KMnhwYzNRZ1lYSm5kVzFsYm5RZ2JYVnpkQ0JpWlNCaGJpQkJjbkpoZVNCdlppQkNkV1ptWlhKekxpY3BYRzVjYmlBZ2FXWWdLR3hwYzNRdWJHVnVaM1JvSUQwOVBTQXdLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHNWxkeUJDZFdabVpYSW9NQ2xjYmlBZ2ZWeHVYRzRnSUhaaGNpQnBYRzRnSUdsbUlDaHNaVzVuZEdnZ1BUMDlJSFZ1WkdWbWFXNWxaQ2tnZTF4dUlDQWdJR3hsYm1kMGFDQTlJREJjYmlBZ0lDQm1iM0lnS0drZ1BTQXdPeUJwSUR3Z2JHbHpkQzVzWlc1bmRHZzdJR2tyS3lrZ2UxeHVJQ0FnSUNBZ2JHVnVaM1JvSUNzOUlHeHBjM1JiYVYwdWJHVnVaM1JvWEc0Z0lDQWdmVnh1SUNCOVhHNWNiaUFnZG1GeUlHSjFaaUE5SUc1bGR5QkNkV1ptWlhJb2JHVnVaM1JvS1Z4dUlDQjJZWElnY0c5eklEMGdNRnh1SUNCbWIzSWdLR2tnUFNBd095QnBJRHdnYkdsemRDNXNaVzVuZEdnN0lHa3JLeWtnZTF4dUlDQWdJSFpoY2lCcGRHVnRJRDBnYkdsemRGdHBYVnh1SUNBZ0lHbDBaVzB1WTI5d2VTaGlkV1lzSUhCdmN5bGNiaUFnSUNCd2IzTWdLejBnYVhSbGJTNXNaVzVuZEdoY2JpQWdmVnh1SUNCeVpYUjFjbTRnWW5WbVhHNTlYRzVjYm1aMWJtTjBhVzl1SUdKNWRHVk1aVzVuZEdnZ0tITjBjbWx1Wnl3Z1pXNWpiMlJwYm1jcElIdGNiaUFnYVdZZ0tIUjVjR1Z2WmlCemRISnBibWNnSVQwOUlDZHpkSEpwYm1jbktTQnpkSEpwYm1jZ1BTQW5KeUFySUhOMGNtbHVaMXh1WEc0Z0lIWmhjaUJzWlc0Z1BTQnpkSEpwYm1jdWJHVnVaM1JvWEc0Z0lHbG1JQ2hzWlc0Z1BUMDlJREFwSUhKbGRIVnliaUF3WEc1Y2JpQWdMeThnVlhObElHRWdabTl5SUd4dmIzQWdkRzhnWVhadmFXUWdjbVZqZFhKemFXOXVYRzRnSUhaaGNpQnNiM2RsY21Wa1EyRnpaU0E5SUdaaGJITmxYRzRnSUdadmNpQW9PenNwSUh0Y2JpQWdJQ0J6ZDJsMFkyZ2dLR1Z1WTI5a2FXNW5LU0I3WEc0Z0lDQWdJQ0JqWVhObElDZGhjMk5wYVNjNlhHNGdJQ0FnSUNCallYTmxJQ2RpYVc1aGNua25PbHh1SUNBZ0lDQWdMeThnUkdWd2NtVmpZWFJsWkZ4dUlDQWdJQ0FnWTJGelpTQW5jbUYzSnpwY2JpQWdJQ0FnSUdOaGMyVWdKM0poZDNNbk9seHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2JHVnVYRzRnSUNBZ0lDQmpZWE5sSUNkMWRHWTRKenBjYmlBZ0lDQWdJR05oYzJVZ0ozVjBaaTA0SnpwY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhWMFpqaFViMEo1ZEdWektITjBjbWx1WnlrdWJHVnVaM1JvWEc0Z0lDQWdJQ0JqWVhObElDZDFZM015SnpwY2JpQWdJQ0FnSUdOaGMyVWdKM1ZqY3kweUp6cGNiaUFnSUNBZ0lHTmhjMlVnSjNWMFpqRTJiR1VuT2x4dUlDQWdJQ0FnWTJGelpTQW5kWFJtTFRFMmJHVW5PbHh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdiR1Z1SUNvZ01seHVJQ0FnSUNBZ1kyRnpaU0FuYUdWNEp6cGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHeGxiaUErUGo0Z01WeHVJQ0FnSUNBZ1kyRnpaU0FuWW1GelpUWTBKenBjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR0poYzJVMk5GUnZRbmwwWlhNb2MzUnlhVzVuS1M1c1pXNW5kR2hjYmlBZ0lDQWdJR1JsWm1GMWJIUTZYRzRnSUNBZ0lDQWdJR2xtSUNoc2IzZGxjbVZrUTJGelpTa2djbVYwZFhKdUlIVjBaamhVYjBKNWRHVnpLSE4wY21sdVp5a3ViR1Z1WjNSb0lDOHZJR0Z6YzNWdFpTQjFkR1k0WEc0Z0lDQWdJQ0FnSUdWdVkyOWthVzVuSUQwZ0tDY25JQ3NnWlc1amIyUnBibWNwTG5SdlRHOTNaWEpEWVhObEtDbGNiaUFnSUNBZ0lDQWdiRzkzWlhKbFpFTmhjMlVnUFNCMGNuVmxYRzRnSUNBZ2ZWeHVJQ0I5WEc1OVhHNUNkV1ptWlhJdVlubDBaVXhsYm1kMGFDQTlJR0o1ZEdWTVpXNW5kR2hjYmx4dVpuVnVZM1JwYjI0Z2MyeHZkMVJ2VTNSeWFXNW5JQ2hsYm1OdlpHbHVaeXdnYzNSaGNuUXNJR1Z1WkNrZ2UxeHVJQ0IyWVhJZ2JHOTNaWEpsWkVOaGMyVWdQU0JtWVd4elpWeHVYRzRnSUhOMFlYSjBJRDBnYzNSaGNuUWdmQ0F3WEc0Z0lHVnVaQ0E5SUdWdVpDQTlQVDBnZFc1a1pXWnBibVZrSUh4OElHVnVaQ0E5UFQwZ1NXNW1hVzVwZEhrZ1B5QjBhR2x6TG14bGJtZDBhQ0E2SUdWdVpDQjhJREJjYmx4dUlDQnBaaUFvSVdWdVkyOWthVzVuS1NCbGJtTnZaR2x1WnlBOUlDZDFkR1k0SjF4dUlDQnBaaUFvYzNSaGNuUWdQQ0F3S1NCemRHRnlkQ0E5SURCY2JpQWdhV1lnS0dWdVpDQStJSFJvYVhNdWJHVnVaM1JvS1NCbGJtUWdQU0IwYUdsekxteGxibWQwYUZ4dUlDQnBaaUFvWlc1a0lEdzlJSE4wWVhKMEtTQnlaWFIxY200Z0p5ZGNibHh1SUNCM2FHbHNaU0FvZEhKMVpTa2dlMXh1SUNBZ0lITjNhWFJqYUNBb1pXNWpiMlJwYm1jcElIdGNiaUFnSUNBZ0lHTmhjMlVnSjJobGVDYzZYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQm9aWGhUYkdsalpTaDBhR2x6TENCemRHRnlkQ3dnWlc1a0tWeHVYRzRnSUNBZ0lDQmpZWE5sSUNkMWRHWTRKenBjYmlBZ0lDQWdJR05oYzJVZ0ozVjBaaTA0SnpwY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhWMFpqaFRiR2xqWlNoMGFHbHpMQ0J6ZEdGeWRDd2daVzVrS1Z4dVhHNGdJQ0FnSUNCallYTmxJQ2RoYzJOcGFTYzZYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQmhjMk5wYVZOc2FXTmxLSFJvYVhNc0lITjBZWEowTENCbGJtUXBYRzVjYmlBZ0lDQWdJR05oYzJVZ0oySnBibUZ5ZVNjNlhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCaWFXNWhjbmxUYkdsalpTaDBhR2x6TENCemRHRnlkQ3dnWlc1a0tWeHVYRzRnSUNBZ0lDQmpZWE5sSUNkaVlYTmxOalFuT2x4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWW1GelpUWTBVMnhwWTJVb2RHaHBjeXdnYzNSaGNuUXNJR1Z1WkNsY2JseHVJQ0FnSUNBZ1kyRnpaU0FuZFdOek1pYzZYRzRnSUNBZ0lDQmpZWE5sSUNkMVkzTXRNaWM2WEc0Z0lDQWdJQ0JqWVhObElDZDFkR1l4Tm14bEp6cGNiaUFnSUNBZ0lHTmhjMlVnSjNWMFppMHhObXhsSnpwY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhWMFpqRTJiR1ZUYkdsalpTaDBhR2x6TENCemRHRnlkQ3dnWlc1a0tWeHVYRzRnSUNBZ0lDQmtaV1poZFd4ME9seHVJQ0FnSUNBZ0lDQnBaaUFvYkc5M1pYSmxaRU5oYzJVcElIUm9jbTkzSUc1bGR5QlVlWEJsUlhKeWIzSW9KMVZ1YTI1dmQyNGdaVzVqYjJScGJtYzZJQ2NnS3lCbGJtTnZaR2x1WnlsY2JpQWdJQ0FnSUNBZ1pXNWpiMlJwYm1jZ1BTQW9aVzVqYjJScGJtY2dLeUFuSnlrdWRHOU1iM2RsY2tOaGMyVW9LVnh1SUNBZ0lDQWdJQ0JzYjNkbGNtVmtRMkZ6WlNBOUlIUnlkV1ZjYmlBZ0lDQjlYRzRnSUgxY2JuMWNibHh1UW5WbVptVnlMbkJ5YjNSdmRIbHdaUzUwYjFOMGNtbHVaeUE5SUdaMWJtTjBhVzl1SUhSdlUzUnlhVzVuSUNncElIdGNiaUFnZG1GeUlHeGxibWQwYUNBOUlIUm9hWE11YkdWdVozUm9JSHdnTUZ4dUlDQnBaaUFvYkdWdVozUm9JRDA5UFNBd0tTQnlaWFIxY200Z0p5ZGNiaUFnYVdZZ0tHRnlaM1Z0Wlc1MGN5NXNaVzVuZEdnZ1BUMDlJREFwSUhKbGRIVnliaUIxZEdZNFUyeHBZMlVvZEdocGN5d2dNQ3dnYkdWdVozUm9LVnh1SUNCeVpYUjFjbTRnYzJ4dmQxUnZVM1J5YVc1bkxtRndjR3g1S0hSb2FYTXNJR0Z5WjNWdFpXNTBjeWxjYm4xY2JseHVRblZtWm1WeUxuQnliM1J2ZEhsd1pTNWxjWFZoYkhNZ1BTQm1kVzVqZEdsdmJpQmxjWFZoYkhNZ0tHSXBJSHRjYmlBZ2FXWWdLQ0ZDZFdabVpYSXVhWE5DZFdabVpYSW9ZaWtwSUhSb2NtOTNJRzVsZHlCVWVYQmxSWEp5YjNJb0owRnlaM1Z0Wlc1MElHMTFjM1FnWW1VZ1lTQkNkV1ptWlhJbktWeHVJQ0JwWmlBb2RHaHBjeUE5UFQwZ1lpa2djbVYwZFhKdUlIUnlkV1ZjYmlBZ2NtVjBkWEp1SUVKMVptWmxjaTVqYjIxd1lYSmxLSFJvYVhNc0lHSXBJRDA5UFNBd1hHNTlYRzVjYmtKMVptWmxjaTV3Y205MGIzUjVjR1V1YVc1emNHVmpkQ0E5SUdaMWJtTjBhVzl1SUdsdWMzQmxZM1FnS0NrZ2UxeHVJQ0IyWVhJZ2MzUnlJRDBnSnlkY2JpQWdkbUZ5SUcxaGVDQTlJR1Y0Y0c5eWRITXVTVTVUVUVWRFZGOU5RVmhmUWxsVVJWTmNiaUFnYVdZZ0tIUm9hWE11YkdWdVozUm9JRDRnTUNrZ2UxeHVJQ0FnSUhOMGNpQTlJSFJvYVhNdWRHOVRkSEpwYm1jb0oyaGxlQ2NzSURBc0lHMWhlQ2t1YldGMFkyZ29MeTU3TW4wdlp5a3VhbTlwYmlnbklDY3BYRzRnSUNBZ2FXWWdLSFJvYVhNdWJHVnVaM1JvSUQ0Z2JXRjRLU0J6ZEhJZ0t6MGdKeUF1TGk0Z0oxeHVJQ0I5WEc0Z0lISmxkSFZ5YmlBblBFSjFabVpsY2lBbklDc2djM1J5SUNzZ0p6NG5YRzU5WEc1Y2JrSjFabVpsY2k1d2NtOTBiM1I1Y0dVdVkyOXRjR0Z5WlNBOUlHWjFibU4wYVc5dUlHTnZiWEJoY21VZ0tHSXBJSHRjYmlBZ2FXWWdLQ0ZDZFdabVpYSXVhWE5DZFdabVpYSW9ZaWtwSUhSb2NtOTNJRzVsZHlCVWVYQmxSWEp5YjNJb0owRnlaM1Z0Wlc1MElHMTFjM1FnWW1VZ1lTQkNkV1ptWlhJbktWeHVJQ0JwWmlBb2RHaHBjeUE5UFQwZ1lpa2djbVYwZFhKdUlEQmNiaUFnY21WMGRYSnVJRUoxWm1abGNpNWpiMjF3WVhKbEtIUm9hWE1zSUdJcFhHNTlYRzVjYmtKMVptWmxjaTV3Y205MGIzUjVjR1V1YVc1a1pYaFBaaUE5SUdaMWJtTjBhVzl1SUdsdVpHVjRUMllnS0haaGJDd2dZbmwwWlU5bVpuTmxkQ2tnZTF4dUlDQnBaaUFvWW5sMFpVOW1abk5sZENBK0lEQjROMlptWm1abVptWXBJR0o1ZEdWUFptWnpaWFFnUFNBd2VEZG1abVptWm1abVhHNGdJR1ZzYzJVZ2FXWWdLR0o1ZEdWUFptWnpaWFFnUENBdE1IZzRNREF3TURBd01Da2dZbmwwWlU5bVpuTmxkQ0E5SUMwd2VEZ3dNREF3TURBd1hHNGdJR0o1ZEdWUFptWnpaWFFnUGo0OUlEQmNibHh1SUNCcFppQW9kR2hwY3k1c1pXNW5kR2dnUFQwOUlEQXBJSEpsZEhWeWJpQXRNVnh1SUNCcFppQW9ZbmwwWlU5bVpuTmxkQ0ErUFNCMGFHbHpMbXhsYm1kMGFDa2djbVYwZFhKdUlDMHhYRzVjYmlBZ0x5OGdUbVZuWVhScGRtVWdiMlptYzJWMGN5QnpkR0Z5ZENCbWNtOXRJSFJvWlNCbGJtUWdiMllnZEdobElHSjFabVpsY2x4dUlDQnBaaUFvWW5sMFpVOW1abk5sZENBOElEQXBJR0o1ZEdWUFptWnpaWFFnUFNCTllYUm9MbTFoZUNoMGFHbHpMbXhsYm1kMGFDQXJJR0o1ZEdWUFptWnpaWFFzSURBcFhHNWNiaUFnYVdZZ0tIUjVjR1Z2WmlCMllXd2dQVDA5SUNkemRISnBibWNuS1NCN1hHNGdJQ0FnYVdZZ0tIWmhiQzVzWlc1bmRHZ2dQVDA5SURBcElISmxkSFZ5YmlBdE1TQXZMeUJ6Y0dWamFXRnNJR05oYzJVNklHeHZiMnRwYm1jZ1ptOXlJR1Z0Y0hSNUlITjBjbWx1WnlCaGJIZGhlWE1nWm1GcGJITmNiaUFnSUNCeVpYUjFjbTRnVTNSeWFXNW5MbkJ5YjNSdmRIbHdaUzVwYm1SbGVFOW1MbU5oYkd3b2RHaHBjeXdnZG1Gc0xDQmllWFJsVDJabWMyVjBLVnh1SUNCOVhHNGdJR2xtSUNoQ2RXWm1aWEl1YVhOQ2RXWm1aWElvZG1Gc0tTa2dlMXh1SUNBZ0lISmxkSFZ5YmlCaGNuSmhlVWx1WkdWNFQyWW9kR2hwY3l3Z2RtRnNMQ0JpZVhSbFQyWm1jMlYwS1Z4dUlDQjlYRzRnSUdsbUlDaDBlWEJsYjJZZ2RtRnNJRDA5UFNBbmJuVnRZbVZ5SnlrZ2UxeHVJQ0FnSUdsbUlDaENkV1ptWlhJdVZGbFFSVVJmUVZKU1FWbGZVMVZRVUU5U1ZDQW1KaUJWYVc1ME9FRnljbUY1TG5CeWIzUnZkSGx3WlM1cGJtUmxlRTltSUQwOVBTQW5ablZ1WTNScGIyNG5LU0I3WEc0Z0lDQWdJQ0J5WlhSMWNtNGdWV2x1ZERoQmNuSmhlUzV3Y205MGIzUjVjR1V1YVc1a1pYaFBaaTVqWVd4c0tIUm9hWE1zSUhaaGJDd2dZbmwwWlU5bVpuTmxkQ2xjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUdGeWNtRjVTVzVrWlhoUFppaDBhR2x6TENCYklIWmhiQ0JkTENCaWVYUmxUMlptYzJWMEtWeHVJQ0I5WEc1Y2JpQWdablZ1WTNScGIyNGdZWEp5WVhsSmJtUmxlRTltSUNoaGNuSXNJSFpoYkN3Z1lubDBaVTltWm5ObGRDa2dlMXh1SUNBZ0lIWmhjaUJtYjNWdVpFbHVaR1Y0SUQwZ0xURmNiaUFnSUNCbWIzSWdLSFpoY2lCcElEMGdNRHNnWW5sMFpVOW1abk5sZENBcklHa2dQQ0JoY25JdWJHVnVaM1JvT3lCcEt5c3BJSHRjYmlBZ0lDQWdJR2xtSUNoaGNuSmJZbmwwWlU5bVpuTmxkQ0FySUdsZElEMDlQU0IyWVd4YlptOTFibVJKYm1SbGVDQTlQVDBnTFRFZ1B5QXdJRG9nYVNBdElHWnZkVzVrU1c1a1pYaGRLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaG1iM1Z1WkVsdVpHVjRJRDA5UFNBdE1Ta2dabTkxYm1SSmJtUmxlQ0E5SUdsY2JpQWdJQ0FnSUNBZ2FXWWdLR2tnTFNCbWIzVnVaRWx1WkdWNElDc2dNU0E5UFQwZ2RtRnNMbXhsYm1kMGFDa2djbVYwZFhKdUlHSjVkR1ZQWm1aelpYUWdLeUJtYjNWdVpFbHVaR1Y0WEc0Z0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0JtYjNWdVpFbHVaR1Y0SUQwZ0xURmNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnY21WMGRYSnVJQzB4WEc0Z0lIMWNibHh1SUNCMGFISnZkeUJ1WlhjZ1ZIbHdaVVZ5Y205eUtDZDJZV3dnYlhWemRDQmlaU0J6ZEhKcGJtY3NJRzUxYldKbGNpQnZjaUJDZFdabVpYSW5LVnh1ZlZ4dVhHNHZMeUJnWjJWMFlDQnBjeUJrWlhCeVpXTmhkR1ZrWEc1Q2RXWm1aWEl1Y0hKdmRHOTBlWEJsTG1kbGRDQTlJR1oxYm1OMGFXOXVJR2RsZENBb2IyWm1jMlYwS1NCN1hHNGdJR052Ym5OdmJHVXViRzluS0NjdVoyVjBLQ2tnYVhNZ1pHVndjbVZqWVhSbFpDNGdRV05qWlhOeklIVnphVzVuSUdGeWNtRjVJR2x1WkdWNFpYTWdhVzV6ZEdWaFpDNG5LVnh1SUNCeVpYUjFjbTRnZEdocGN5NXlaV0ZrVlVsdWREZ29iMlptYzJWMEtWeHVmVnh1WEc0dkx5QmdjMlYwWUNCcGN5QmtaWEJ5WldOaGRHVmtYRzVDZFdabVpYSXVjSEp2ZEc5MGVYQmxMbk5sZENBOUlHWjFibU4wYVc5dUlITmxkQ0FvZGl3Z2IyWm1jMlYwS1NCN1hHNGdJR052Ym5OdmJHVXViRzluS0NjdWMyVjBLQ2tnYVhNZ1pHVndjbVZqWVhSbFpDNGdRV05qWlhOeklIVnphVzVuSUdGeWNtRjVJR2x1WkdWNFpYTWdhVzV6ZEdWaFpDNG5LVnh1SUNCeVpYUjFjbTRnZEdocGN5NTNjbWwwWlZWSmJuUTRLSFlzSUc5bVpuTmxkQ2xjYm4xY2JseHVablZ1WTNScGIyNGdhR1Y0VjNKcGRHVWdLR0oxWml3Z2MzUnlhVzVuTENCdlptWnpaWFFzSUd4bGJtZDBhQ2tnZTF4dUlDQnZabVp6WlhRZ1BTQk9kVzFpWlhJb2IyWm1jMlYwS1NCOGZDQXdYRzRnSUhaaGNpQnlaVzFoYVc1cGJtY2dQU0JpZFdZdWJHVnVaM1JvSUMwZ2IyWm1jMlYwWEc0Z0lHbG1JQ2doYkdWdVozUm9LU0I3WEc0Z0lDQWdiR1Z1WjNSb0lEMGdjbVZ0WVdsdWFXNW5YRzRnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdiR1Z1WjNSb0lEMGdUblZ0WW1WeUtHeGxibWQwYUNsY2JpQWdJQ0JwWmlBb2JHVnVaM1JvSUQ0Z2NtVnRZV2x1YVc1bktTQjdYRzRnSUNBZ0lDQnNaVzVuZEdnZ1BTQnlaVzFoYVc1cGJtZGNiaUFnSUNCOVhHNGdJSDFjYmx4dUlDQXZMeUJ0ZFhOMElHSmxJR0Z1SUdWMlpXNGdiblZ0WW1WeUlHOW1JR1JwWjJsMGMxeHVJQ0IyWVhJZ2MzUnlUR1Z1SUQwZ2MzUnlhVzVuTG14bGJtZDBhRnh1SUNCcFppQW9jM1J5VEdWdUlDVWdNaUFoUFQwZ01Da2dkR2h5YjNjZ2JtVjNJRVZ5Y205eUtDZEpiblpoYkdsa0lHaGxlQ0J6ZEhKcGJtY25LVnh1WEc0Z0lHbG1JQ2hzWlc1bmRHZ2dQaUJ6ZEhKTVpXNGdMeUF5S1NCN1hHNGdJQ0FnYkdWdVozUm9JRDBnYzNSeVRHVnVJQzhnTWx4dUlDQjlYRzRnSUdadmNpQW9kbUZ5SUdrZ1BTQXdPeUJwSUR3Z2JHVnVaM1JvT3lCcEt5c3BJSHRjYmlBZ0lDQjJZWElnY0dGeWMyVmtJRDBnY0dGeWMyVkpiblFvYzNSeWFXNW5Mbk4xWW5OMGNpaHBJQ29nTWl3Z01pa3NJREUyS1Z4dUlDQWdJR2xtSUNocGMwNWhUaWh3WVhKelpXUXBLU0IwYUhKdmR5QnVaWGNnUlhKeWIzSW9KMGx1ZG1Gc2FXUWdhR1Y0SUhOMGNtbHVaeWNwWEc0Z0lDQWdZblZtVzI5bVpuTmxkQ0FySUdsZElEMGdjR0Z5YzJWa1hHNGdJSDFjYmlBZ2NtVjBkWEp1SUdsY2JuMWNibHh1Wm5WdVkzUnBiMjRnZFhSbU9GZHlhWFJsSUNoaWRXWXNJSE4wY21sdVp5d2diMlptYzJWMExDQnNaVzVuZEdncElIdGNiaUFnY21WMGRYSnVJR0pzYVhSQ2RXWm1aWElvZFhSbU9GUnZRbmwwWlhNb2MzUnlhVzVuTENCaWRXWXViR1Z1WjNSb0lDMGdiMlptYzJWMEtTd2dZblZtTENCdlptWnpaWFFzSUd4bGJtZDBhQ2xjYm4xY2JseHVablZ1WTNScGIyNGdZWE5qYVdsWGNtbDBaU0FvWW5WbUxDQnpkSEpwYm1jc0lHOW1abk5sZEN3Z2JHVnVaM1JvS1NCN1hHNGdJSEpsZEhWeWJpQmliR2wwUW5WbVptVnlLR0Z6WTJscFZHOUNlWFJsY3loemRISnBibWNwTENCaWRXWXNJRzltWm5ObGRDd2diR1Z1WjNSb0tWeHVmVnh1WEc1bWRXNWpkR2x2YmlCaWFXNWhjbmxYY21sMFpTQW9ZblZtTENCemRISnBibWNzSUc5bVpuTmxkQ3dnYkdWdVozUm9LU0I3WEc0Z0lISmxkSFZ5YmlCaGMyTnBhVmR5YVhSbEtHSjFaaXdnYzNSeWFXNW5MQ0J2Wm1aelpYUXNJR3hsYm1kMGFDbGNibjFjYmx4dVpuVnVZM1JwYjI0Z1ltRnpaVFkwVjNKcGRHVWdLR0oxWml3Z2MzUnlhVzVuTENCdlptWnpaWFFzSUd4bGJtZDBhQ2tnZTF4dUlDQnlaWFIxY200Z1lteHBkRUoxWm1abGNpaGlZWE5sTmpSVWIwSjVkR1Z6S0hOMGNtbHVaeWtzSUdKMVppd2diMlptYzJWMExDQnNaVzVuZEdncFhHNTlYRzVjYm1aMWJtTjBhVzl1SUhWamN6SlhjbWwwWlNBb1luVm1MQ0J6ZEhKcGJtY3NJRzltWm5ObGRDd2diR1Z1WjNSb0tTQjdYRzRnSUhKbGRIVnliaUJpYkdsMFFuVm1abVZ5S0hWMFpqRTJiR1ZVYjBKNWRHVnpLSE4wY21sdVp5d2dZblZtTG14bGJtZDBhQ0F0SUc5bVpuTmxkQ2tzSUdKMVppd2diMlptYzJWMExDQnNaVzVuZEdncFhHNTlYRzVjYmtKMVptWmxjaTV3Y205MGIzUjVjR1V1ZDNKcGRHVWdQU0JtZFc1amRHbHZiaUIzY21sMFpTQW9jM1J5YVc1bkxDQnZabVp6WlhRc0lHeGxibWQwYUN3Z1pXNWpiMlJwYm1jcElIdGNiaUFnTHk4Z1FuVm1abVZ5STNkeWFYUmxLSE4wY21sdVp5bGNiaUFnYVdZZ0tHOW1abk5sZENBOVBUMGdkVzVrWldacGJtVmtLU0I3WEc0Z0lDQWdaVzVqYjJScGJtY2dQU0FuZFhSbU9DZGNiaUFnSUNCc1pXNW5kR2dnUFNCMGFHbHpMbXhsYm1kMGFGeHVJQ0FnSUc5bVpuTmxkQ0E5SURCY2JpQWdMeThnUW5WbVptVnlJM2R5YVhSbEtITjBjbWx1Wnl3Z1pXNWpiMlJwYm1jcFhHNGdJSDBnWld4elpTQnBaaUFvYkdWdVozUm9JRDA5UFNCMWJtUmxabWx1WldRZ0ppWWdkSGx3Wlc5bUlHOW1abk5sZENBOVBUMGdKM04wY21sdVp5Y3BJSHRjYmlBZ0lDQmxibU52WkdsdVp5QTlJRzltWm5ObGRGeHVJQ0FnSUd4bGJtZDBhQ0E5SUhSb2FYTXViR1Z1WjNSb1hHNGdJQ0FnYjJabWMyVjBJRDBnTUZ4dUlDQXZMeUJDZFdabVpYSWpkM0pwZEdVb2MzUnlhVzVuTENCdlptWnpaWFJiTENCc1pXNW5kR2hkV3l3Z1pXNWpiMlJwYm1kZEtWeHVJQ0I5SUdWc2MyVWdhV1lnS0dselJtbHVhWFJsS0c5bVpuTmxkQ2twSUh0Y2JpQWdJQ0J2Wm1aelpYUWdQU0J2Wm1aelpYUWdmQ0F3WEc0Z0lDQWdhV1lnS0dselJtbHVhWFJsS0d4bGJtZDBhQ2twSUh0Y2JpQWdJQ0FnSUd4bGJtZDBhQ0E5SUd4bGJtZDBhQ0I4SURCY2JpQWdJQ0FnSUdsbUlDaGxibU52WkdsdVp5QTlQVDBnZFc1a1pXWnBibVZrS1NCbGJtTnZaR2x1WnlBOUlDZDFkR1k0SjF4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQmxibU52WkdsdVp5QTlJR3hsYm1kMGFGeHVJQ0FnSUNBZ2JHVnVaM1JvSUQwZ2RXNWtaV1pwYm1Wa1hHNGdJQ0FnZlZ4dUlDQXZMeUJzWldkaFkza2dkM0pwZEdVb2MzUnlhVzVuTENCbGJtTnZaR2x1Wnl3Z2IyWm1jMlYwTENCc1pXNW5kR2dwSUMwZ2NtVnRiM1psSUdsdUlIWXdMakV6WEc0Z0lIMGdaV3h6WlNCN1hHNGdJQ0FnZG1GeUlITjNZWEFnUFNCbGJtTnZaR2x1WjF4dUlDQWdJR1Z1WTI5a2FXNW5JRDBnYjJabWMyVjBYRzRnSUNBZ2IyWm1jMlYwSUQwZ2JHVnVaM1JvSUh3Z01GeHVJQ0FnSUd4bGJtZDBhQ0E5SUhOM1lYQmNiaUFnZlZ4dVhHNGdJSFpoY2lCeVpXMWhhVzVwYm1jZ1BTQjBhR2x6TG14bGJtZDBhQ0F0SUc5bVpuTmxkRnh1SUNCcFppQW9iR1Z1WjNSb0lEMDlQU0IxYm1SbFptbHVaV1FnZkh3Z2JHVnVaM1JvSUQ0Z2NtVnRZV2x1YVc1bktTQnNaVzVuZEdnZ1BTQnlaVzFoYVc1cGJtZGNibHh1SUNCcFppQW9LSE4wY21sdVp5NXNaVzVuZEdnZ1BpQXdJQ1ltSUNoc1pXNW5kR2dnUENBd0lIeDhJRzltWm5ObGRDQThJREFwS1NCOGZDQnZabVp6WlhRZ1BpQjBhR2x6TG14bGJtZDBhQ2tnZTF4dUlDQWdJSFJvY205M0lHNWxkeUJTWVc1blpVVnljbTl5S0NkaGRIUmxiWEIwSUhSdklIZHlhWFJsSUc5MWRITnBaR1VnWW5WbVptVnlJR0p2ZFc1a2N5Y3BYRzRnSUgxY2JseHVJQ0JwWmlBb0lXVnVZMjlrYVc1bktTQmxibU52WkdsdVp5QTlJQ2QxZEdZNEoxeHVYRzRnSUhaaGNpQnNiM2RsY21Wa1EyRnpaU0E5SUdaaGJITmxYRzRnSUdadmNpQW9PenNwSUh0Y2JpQWdJQ0J6ZDJsMFkyZ2dLR1Z1WTI5a2FXNW5LU0I3WEc0Z0lDQWdJQ0JqWVhObElDZG9aWGduT2x4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnYUdWNFYzSnBkR1VvZEdocGN5d2djM1J5YVc1bkxDQnZabVp6WlhRc0lHeGxibWQwYUNsY2JseHVJQ0FnSUNBZ1kyRnpaU0FuZFhSbU9DYzZYRzRnSUNBZ0lDQmpZWE5sSUNkMWRHWXRPQ2M2WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUIxZEdZNFYzSnBkR1VvZEdocGN5d2djM1J5YVc1bkxDQnZabVp6WlhRc0lHeGxibWQwYUNsY2JseHVJQ0FnSUNBZ1kyRnpaU0FuWVhOamFXa25PbHh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdZWE5qYVdsWGNtbDBaU2gwYUdsekxDQnpkSEpwYm1jc0lHOW1abk5sZEN3Z2JHVnVaM1JvS1Z4dVhHNGdJQ0FnSUNCallYTmxJQ2RpYVc1aGNua25PbHh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdZbWx1WVhKNVYzSnBkR1VvZEdocGN5d2djM1J5YVc1bkxDQnZabVp6WlhRc0lHeGxibWQwYUNsY2JseHVJQ0FnSUNBZ1kyRnpaU0FuWW1GelpUWTBKenBjYmlBZ0lDQWdJQ0FnTHk4Z1YyRnlibWx1WnpvZ2JXRjRUR1Z1WjNSb0lHNXZkQ0IwWVd0bGJpQnBiblJ2SUdGalkyOTFiblFnYVc0Z1ltRnpaVFkwVjNKcGRHVmNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHSmhjMlUyTkZkeWFYUmxLSFJvYVhNc0lITjBjbWx1Wnl3Z2IyWm1jMlYwTENCc1pXNW5kR2dwWEc1Y2JpQWdJQ0FnSUdOaGMyVWdKM1ZqY3pJbk9seHVJQ0FnSUNBZ1kyRnpaU0FuZFdOekxUSW5PbHh1SUNBZ0lDQWdZMkZ6WlNBbmRYUm1NVFpzWlNjNlhHNGdJQ0FnSUNCallYTmxJQ2QxZEdZdE1UWnNaU2M2WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUIxWTNNeVYzSnBkR1VvZEdocGN5d2djM1J5YVc1bkxDQnZabVp6WlhRc0lHeGxibWQwYUNsY2JseHVJQ0FnSUNBZ1pHVm1ZWFZzZERwY2JpQWdJQ0FnSUNBZ2FXWWdLR3h2ZDJWeVpXUkRZWE5sS1NCMGFISnZkeUJ1WlhjZ1ZIbHdaVVZ5Y205eUtDZFZibXR1YjNkdUlHVnVZMjlrYVc1bk9pQW5JQ3NnWlc1amIyUnBibWNwWEc0Z0lDQWdJQ0FnSUdWdVkyOWthVzVuSUQwZ0tDY25JQ3NnWlc1amIyUnBibWNwTG5SdlRHOTNaWEpEWVhObEtDbGNiaUFnSUNBZ0lDQWdiRzkzWlhKbFpFTmhjMlVnUFNCMGNuVmxYRzRnSUNBZ2ZWeHVJQ0I5WEc1OVhHNWNia0oxWm1abGNpNXdjbTkwYjNSNWNHVXVkRzlLVTA5T0lEMGdablZ1WTNScGIyNGdkRzlLVTA5T0lDZ3BJSHRjYmlBZ2NtVjBkWEp1SUh0Y2JpQWdJQ0IwZVhCbE9pQW5RblZtWm1WeUp5eGNiaUFnSUNCa1lYUmhPaUJCY25KaGVTNXdjbTkwYjNSNWNHVXVjMnhwWTJVdVkyRnNiQ2gwYUdsekxsOWhjbklnZkh3Z2RHaHBjeXdnTUNsY2JpQWdmVnh1ZlZ4dVhHNW1kVzVqZEdsdmJpQmlZWE5sTmpSVGJHbGpaU0FvWW5WbUxDQnpkR0Z5ZEN3Z1pXNWtLU0I3WEc0Z0lHbG1JQ2h6ZEdGeWRDQTlQVDBnTUNBbUppQmxibVFnUFQwOUlHSjFaaTVzWlc1bmRHZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z1ltRnpaVFkwTG1aeWIyMUNlWFJsUVhKeVlYa29ZblZtS1Z4dUlDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUhKbGRIVnliaUJpWVhObE5qUXVabkp2YlVKNWRHVkJjbkpoZVNoaWRXWXVjMnhwWTJVb2MzUmhjblFzSUdWdVpDa3BYRzRnSUgxY2JuMWNibHh1Wm5WdVkzUnBiMjRnZFhSbU9GTnNhV05sSUNoaWRXWXNJSE4wWVhKMExDQmxibVFwSUh0Y2JpQWdaVzVrSUQwZ1RXRjBhQzV0YVc0b1luVm1MbXhsYm1kMGFDd2daVzVrS1Z4dUlDQjJZWElnY21WeklEMGdXMTFjYmx4dUlDQjJZWElnYVNBOUlITjBZWEowWEc0Z0lIZG9hV3hsSUNocElEd2daVzVrS1NCN1hHNGdJQ0FnZG1GeUlHWnBjbk4wUW5sMFpTQTlJR0oxWmx0cFhWeHVJQ0FnSUhaaGNpQmpiMlJsVUc5cGJuUWdQU0J1ZFd4c1hHNGdJQ0FnZG1GeUlHSjVkR1Z6VUdWeVUyVnhkV1Z1WTJVZ1BTQW9abWx5YzNSQ2VYUmxJRDRnTUhoRlJpa2dQeUEwWEc0Z0lDQWdJQ0E2SUNobWFYSnpkRUo1ZEdVZ1BpQXdlRVJHS1NBL0lETmNiaUFnSUNBZ0lEb2dLR1pwY25OMFFubDBaU0ErSURCNFFrWXBJRDhnTWx4dUlDQWdJQ0FnT2lBeFhHNWNiaUFnSUNCcFppQW9hU0FySUdKNWRHVnpVR1Z5VTJWeGRXVnVZMlVnUEQwZ1pXNWtLU0I3WEc0Z0lDQWdJQ0IyWVhJZ2MyVmpiMjVrUW5sMFpTd2dkR2hwY21SQ2VYUmxMQ0JtYjNWeWRHaENlWFJsTENCMFpXMXdRMjlrWlZCdmFXNTBYRzVjYmlBZ0lDQWdJSE4zYVhSamFDQW9ZbmwwWlhOUVpYSlRaWEYxWlc1alpTa2dlMXh1SUNBZ0lDQWdJQ0JqWVhObElERTZYRzRnSUNBZ0lDQWdJQ0FnYVdZZ0tHWnBjbk4wUW5sMFpTQThJREI0T0RBcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdOdlpHVlFiMmx1ZENBOUlHWnBjbk4wUW5sMFpWeHVJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnSUNCaWNtVmhhMXh1SUNBZ0lDQWdJQ0JqWVhObElESTZYRzRnSUNBZ0lDQWdJQ0FnYzJWamIyNWtRbmwwWlNBOUlHSjFabHRwSUNzZ01WMWNiaUFnSUNBZ0lDQWdJQ0JwWmlBb0tITmxZMjl1WkVKNWRHVWdKaUF3ZUVNd0tTQTlQVDBnTUhnNE1Da2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2RHVnRjRU52WkdWUWIybHVkQ0E5SUNobWFYSnpkRUo1ZEdVZ0ppQXdlREZHS1NBOFBDQXdlRFlnZkNBb2MyVmpiMjVrUW5sMFpTQW1JREI0TTBZcFhHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2RHVnRjRU52WkdWUWIybHVkQ0ErSURCNE4wWXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdZMjlrWlZCdmFXNTBJRDBnZEdWdGNFTnZaR1ZRYjJsdWRGeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdJQ0JpY21WaGExeHVJQ0FnSUNBZ0lDQmpZWE5sSURNNlhHNGdJQ0FnSUNBZ0lDQWdjMlZqYjI1a1FubDBaU0E5SUdKMVpsdHBJQ3NnTVYxY2JpQWdJQ0FnSUNBZ0lDQjBhR2x5WkVKNWRHVWdQU0JpZFdaYmFTQXJJREpkWEc0Z0lDQWdJQ0FnSUNBZ2FXWWdLQ2h6WldOdmJtUkNlWFJsSUNZZ01IaERNQ2tnUFQwOUlEQjRPREFnSmlZZ0tIUm9hWEprUW5sMFpTQW1JREI0UXpBcElEMDlQU0F3ZURnd0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMFpXMXdRMjlrWlZCdmFXNTBJRDBnS0dacGNuTjBRbmwwWlNBbUlEQjRSaWtnUER3Z01IaERJSHdnS0hObFkyOXVaRUo1ZEdVZ0ppQXdlRE5HS1NBOFBDQXdlRFlnZkNBb2RHaHBjbVJDZVhSbElDWWdNSGd6UmlsY2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMFpXMXdRMjlrWlZCdmFXNTBJRDRnTUhnM1JrWWdKaVlnS0hSbGJYQkRiMlJsVUc5cGJuUWdQQ0F3ZUVRNE1EQWdmSHdnZEdWdGNFTnZaR1ZRYjJsdWRDQStJREI0UkVaR1Jpa3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdZMjlrWlZCdmFXNTBJRDBnZEdWdGNFTnZaR1ZRYjJsdWRGeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdJQ0JpY21WaGExeHVJQ0FnSUNBZ0lDQmpZWE5sSURRNlhHNGdJQ0FnSUNBZ0lDQWdjMlZqYjI1a1FubDBaU0E5SUdKMVpsdHBJQ3NnTVYxY2JpQWdJQ0FnSUNBZ0lDQjBhR2x5WkVKNWRHVWdQU0JpZFdaYmFTQXJJREpkWEc0Z0lDQWdJQ0FnSUNBZ1ptOTFjblJvUW5sMFpTQTlJR0oxWmx0cElDc2dNMTFjYmlBZ0lDQWdJQ0FnSUNCcFppQW9LSE5sWTI5dVpFSjVkR1VnSmlBd2VFTXdLU0E5UFQwZ01IZzRNQ0FtSmlBb2RHaHBjbVJDZVhSbElDWWdNSGhETUNrZ1BUMDlJREI0T0RBZ0ppWWdLR1p2ZFhKMGFFSjVkR1VnSmlBd2VFTXdLU0E5UFQwZ01IZzRNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdkR1Z0Y0VOdlpHVlFiMmx1ZENBOUlDaG1hWEp6ZEVKNWRHVWdKaUF3ZUVZcElEdzhJREI0TVRJZ2ZDQW9jMlZqYjI1a1FubDBaU0FtSURCNE0wWXBJRHc4SURCNFF5QjhJQ2gwYUdseVpFSjVkR1VnSmlBd2VETkdLU0E4UENBd2VEWWdmQ0FvWm05MWNuUm9RbmwwWlNBbUlEQjRNMFlwWEc0Z0lDQWdJQ0FnSUNBZ0lDQnBaaUFvZEdWdGNFTnZaR1ZRYjJsdWRDQStJREI0UmtaR1JpQW1KaUIwWlcxd1EyOWtaVkJ2YVc1MElEd2dNSGd4TVRBd01EQXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdZMjlrWlZCdmFXNTBJRDBnZEdWdGNFTnZaR1ZRYjJsdWRGeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNWNiaUFnSUNCcFppQW9ZMjlrWlZCdmFXNTBJRDA5UFNCdWRXeHNLU0I3WEc0Z0lDQWdJQ0F2THlCM1pTQmthV1FnYm05MElHZGxibVZ5WVhSbElHRWdkbUZzYVdRZ1kyOWtaVkJ2YVc1MElITnZJR2x1YzJWeWRDQmhYRzRnSUNBZ0lDQXZMeUJ5WlhCc1lXTmxiV1Z1ZENCamFHRnlJQ2hWSzBaR1JrUXBJR0Z1WkNCaFpIWmhibU5sSUc5dWJIa2dNU0JpZVhSbFhHNGdJQ0FnSUNCamIyUmxVRzlwYm5RZ1BTQXdlRVpHUmtSY2JpQWdJQ0FnSUdKNWRHVnpVR1Z5VTJWeGRXVnVZMlVnUFNBeFhHNGdJQ0FnZlNCbGJITmxJR2xtSUNoamIyUmxVRzlwYm5RZ1BpQXdlRVpHUmtZcElIdGNiaUFnSUNBZ0lDOHZJR1Z1WTI5a1pTQjBieUIxZEdZeE5pQW9jM1Z5Y205bllYUmxJSEJoYVhJZ1pHRnVZMlVwWEc0Z0lDQWdJQ0JqYjJSbFVHOXBiblFnTFQwZ01IZ3hNREF3TUZ4dUlDQWdJQ0FnY21WekxuQjFjMmdvWTI5a1pWQnZhVzUwSUQ0K1BpQXhNQ0FtSURCNE0wWkdJSHdnTUhoRU9EQXdLVnh1SUNBZ0lDQWdZMjlrWlZCdmFXNTBJRDBnTUhoRVF6QXdJSHdnWTI5a1pWQnZhVzUwSUNZZ01IZ3pSa1pjYmlBZ0lDQjlYRzVjYmlBZ0lDQnlaWE11Y0hWemFDaGpiMlJsVUc5cGJuUXBYRzRnSUNBZ2FTQXJQU0JpZVhSbGMxQmxjbE5sY1hWbGJtTmxYRzRnSUgxY2JseHVJQ0J5WlhSMWNtNGdaR1ZqYjJSbFEyOWtaVkJ2YVc1MGMwRnljbUY1S0hKbGN5bGNibjFjYmx4dUx5OGdRbUZ6WldRZ2IyNGdhSFIwY0RvdkwzTjBZV05yYjNabGNtWnNiM2N1WTI5dEwyRXZNakkzTkRjeU56SXZOamd3TnpReUxDQjBhR1VnWW5KdmQzTmxjaUIzYVhSb1hHNHZMeUIwYUdVZ2JHOTNaWE4wSUd4cGJXbDBJR2x6SUVOb2NtOXRaU3dnZDJsMGFDQXdlREV3TURBd0lHRnlaM011WEc0dkx5QlhaU0JuYnlBeElHMWhaMjVwZEhWa1pTQnNaWE56TENCbWIzSWdjMkZtWlhSNVhHNTJZWElnVFVGWVgwRlNSMVZOUlU1VVUxOU1SVTVIVkVnZ1BTQXdlREV3TURCY2JseHVablZ1WTNScGIyNGdaR1ZqYjJSbFEyOWtaVkJ2YVc1MGMwRnljbUY1SUNoamIyUmxVRzlwYm5SektTQjdYRzRnSUhaaGNpQnNaVzRnUFNCamIyUmxVRzlwYm5SekxteGxibWQwYUZ4dUlDQnBaaUFvYkdWdUlEdzlJRTFCV0Y5QlVrZFZUVVZPVkZOZlRFVk9SMVJJS1NCN1hHNGdJQ0FnY21WMGRYSnVJRk4wY21sdVp5NW1jbTl0UTJoaGNrTnZaR1V1WVhCd2JIa29VM1J5YVc1bkxDQmpiMlJsVUc5cGJuUnpLU0F2THlCaGRtOXBaQ0JsZUhSeVlTQnpiR2xqWlNncFhHNGdJSDFjYmx4dUlDQXZMeUJFWldOdlpHVWdhVzRnWTJoMWJtdHpJSFJ2SUdGMmIybGtJRndpWTJGc2JDQnpkR0ZqYXlCemFYcGxJR1Y0WTJWbFpHVmtYQ0l1WEc0Z0lIWmhjaUJ5WlhNZ1BTQW5KMXh1SUNCMllYSWdhU0E5SURCY2JpQWdkMmhwYkdVZ0tHa2dQQ0JzWlc0cElIdGNiaUFnSUNCeVpYTWdLejBnVTNSeWFXNW5MbVp5YjIxRGFHRnlRMjlrWlM1aGNIQnNlU2hjYmlBZ0lDQWdJRk4wY21sdVp5eGNiaUFnSUNBZ0lHTnZaR1ZRYjJsdWRITXVjMnhwWTJVb2FTd2dhU0FyUFNCTlFWaGZRVkpIVlUxRlRsUlRYMHhGVGtkVVNDbGNiaUFnSUNBcFhHNGdJSDFjYmlBZ2NtVjBkWEp1SUhKbGMxeHVmVnh1WEc1bWRXNWpkR2x2YmlCaGMyTnBhVk5zYVdObElDaGlkV1lzSUhOMFlYSjBMQ0JsYm1RcElIdGNiaUFnZG1GeUlISmxkQ0E5SUNjblhHNGdJR1Z1WkNBOUlFMWhkR2d1YldsdUtHSjFaaTVzWlc1bmRHZ3NJR1Z1WkNsY2JseHVJQ0JtYjNJZ0tIWmhjaUJwSUQwZ2MzUmhjblE3SUdrZ1BDQmxibVE3SUdrckt5a2dlMXh1SUNBZ0lISmxkQ0FyUFNCVGRISnBibWN1Wm5KdmJVTm9ZWEpEYjJSbEtHSjFabHRwWFNBbUlEQjROMFlwWEc0Z0lIMWNiaUFnY21WMGRYSnVJSEpsZEZ4dWZWeHVYRzVtZFc1amRHbHZiaUJpYVc1aGNubFRiR2xqWlNBb1luVm1MQ0J6ZEdGeWRDd2daVzVrS1NCN1hHNGdJSFpoY2lCeVpYUWdQU0FuSjF4dUlDQmxibVFnUFNCTllYUm9MbTFwYmloaWRXWXViR1Z1WjNSb0xDQmxibVFwWEc1Y2JpQWdabTl5SUNoMllYSWdhU0E5SUhOMFlYSjBPeUJwSUR3Z1pXNWtPeUJwS3lzcElIdGNiaUFnSUNCeVpYUWdLejBnVTNSeWFXNW5MbVp5YjIxRGFHRnlRMjlrWlNoaWRXWmJhVjBwWEc0Z0lIMWNiaUFnY21WMGRYSnVJSEpsZEZ4dWZWeHVYRzVtZFc1amRHbHZiaUJvWlhoVGJHbGpaU0FvWW5WbUxDQnpkR0Z5ZEN3Z1pXNWtLU0I3WEc0Z0lIWmhjaUJzWlc0Z1BTQmlkV1l1YkdWdVozUm9YRzVjYmlBZ2FXWWdLQ0Z6ZEdGeWRDQjhmQ0J6ZEdGeWRDQThJREFwSUhOMFlYSjBJRDBnTUZ4dUlDQnBaaUFvSVdWdVpDQjhmQ0JsYm1RZ1BDQXdJSHg4SUdWdVpDQStJR3hsYmlrZ1pXNWtJRDBnYkdWdVhHNWNiaUFnZG1GeUlHOTFkQ0E5SUNjblhHNGdJR1p2Y2lBb2RtRnlJR2tnUFNCemRHRnlkRHNnYVNBOElHVnVaRHNnYVNzcktTQjdYRzRnSUNBZ2IzVjBJQ3M5SUhSdlNHVjRLR0oxWmx0cFhTbGNiaUFnZlZ4dUlDQnlaWFIxY200Z2IzVjBYRzU5WEc1Y2JtWjFibU4wYVc5dUlIVjBaakUyYkdWVGJHbGpaU0FvWW5WbUxDQnpkR0Z5ZEN3Z1pXNWtLU0I3WEc0Z0lIWmhjaUJpZVhSbGN5QTlJR0oxWmk1emJHbGpaU2h6ZEdGeWRDd2daVzVrS1Z4dUlDQjJZWElnY21WeklEMGdKeWRjYmlBZ1ptOXlJQ2gyWVhJZ2FTQTlJREE3SUdrZ1BDQmllWFJsY3k1c1pXNW5kR2c3SUdrZ0t6MGdNaWtnZTF4dUlDQWdJSEpsY3lBclBTQlRkSEpwYm1jdVpuSnZiVU5vWVhKRGIyUmxLR0o1ZEdWelcybGRJQ3NnWW5sMFpYTmJhU0FySURGZElDb2dNalUyS1Z4dUlDQjlYRzRnSUhKbGRIVnliaUJ5WlhOY2JuMWNibHh1UW5WbVptVnlMbkJ5YjNSdmRIbHdaUzV6YkdsalpTQTlJR1oxYm1OMGFXOXVJSE5zYVdObElDaHpkR0Z5ZEN3Z1pXNWtLU0I3WEc0Z0lIWmhjaUJzWlc0Z1BTQjBhR2x6TG14bGJtZDBhRnh1SUNCemRHRnlkQ0E5SUg1K2MzUmhjblJjYmlBZ1pXNWtJRDBnWlc1a0lEMDlQU0IxYm1SbFptbHVaV1FnUHlCc1pXNGdPaUIrZm1WdVpGeHVYRzRnSUdsbUlDaHpkR0Z5ZENBOElEQXBJSHRjYmlBZ0lDQnpkR0Z5ZENBclBTQnNaVzVjYmlBZ0lDQnBaaUFvYzNSaGNuUWdQQ0F3S1NCemRHRnlkQ0E5SURCY2JpQWdmU0JsYkhObElHbG1JQ2h6ZEdGeWRDQStJR3hsYmlrZ2UxeHVJQ0FnSUhOMFlYSjBJRDBnYkdWdVhHNGdJSDFjYmx4dUlDQnBaaUFvWlc1a0lEd2dNQ2tnZTF4dUlDQWdJR1Z1WkNBclBTQnNaVzVjYmlBZ0lDQnBaaUFvWlc1a0lEd2dNQ2tnWlc1a0lEMGdNRnh1SUNCOUlHVnNjMlVnYVdZZ0tHVnVaQ0ErSUd4bGJpa2dlMXh1SUNBZ0lHVnVaQ0E5SUd4bGJseHVJQ0I5WEc1Y2JpQWdhV1lnS0dWdVpDQThJSE4wWVhKMEtTQmxibVFnUFNCemRHRnlkRnh1WEc0Z0lIWmhjaUJ1WlhkQ2RXWmNiaUFnYVdZZ0tFSjFabVpsY2k1VVdWQkZSRjlCVWxKQldWOVRWVkJRVDFKVUtTQjdYRzRnSUNBZ2JtVjNRblZtSUQwZ1FuVm1abVZ5TGw5aGRXZHRaVzUwS0hSb2FYTXVjM1ZpWVhKeVlYa29jM1JoY25Rc0lHVnVaQ2twWEc0Z0lIMGdaV3h6WlNCN1hHNGdJQ0FnZG1GeUlITnNhV05sVEdWdUlEMGdaVzVrSUMwZ2MzUmhjblJjYmlBZ0lDQnVaWGRDZFdZZ1BTQnVaWGNnUW5WbVptVnlLSE5zYVdObFRHVnVMQ0IxYm1SbFptbHVaV1FwWEc0Z0lDQWdabTl5SUNoMllYSWdhU0E5SURBN0lHa2dQQ0J6YkdsalpVeGxianNnYVNzcktTQjdYRzRnSUNBZ0lDQnVaWGRDZFdaYmFWMGdQU0IwYUdselcya2dLeUJ6ZEdGeWRGMWNiaUFnSUNCOVhHNGdJSDFjYmx4dUlDQnBaaUFvYm1WM1FuVm1MbXhsYm1kMGFDa2dibVYzUW5WbUxuQmhjbVZ1ZENBOUlIUm9hWE11Y0dGeVpXNTBJSHg4SUhSb2FYTmNibHh1SUNCeVpYUjFjbTRnYm1WM1FuVm1YRzU5WEc1Y2JpOHFYRzRnS2lCT1pXVmtJSFJ2SUcxaGEyVWdjM1Z5WlNCMGFHRjBJR0oxWm1abGNpQnBjMjRuZENCMGNubHBibWNnZEc4Z2QzSnBkR1VnYjNWMElHOW1JR0p2ZFc1a2N5NWNiaUFxTDF4dVpuVnVZM1JwYjI0Z1kyaGxZMnRQWm1aelpYUWdLRzltWm5ObGRDd2daWGgwTENCc1pXNW5kR2dwSUh0Y2JpQWdhV1lnS0NodlptWnpaWFFnSlNBeEtTQWhQVDBnTUNCOGZDQnZabVp6WlhRZ1BDQXdLU0IwYUhKdmR5QnVaWGNnVW1GdVoyVkZjbkp2Y2lnbmIyWm1jMlYwSUdseklHNXZkQ0IxYVc1MEp5bGNiaUFnYVdZZ0tHOW1abk5sZENBcklHVjRkQ0ErSUd4bGJtZDBhQ2tnZEdoeWIzY2dibVYzSUZKaGJtZGxSWEp5YjNJb0oxUnllV2x1WnlCMGJ5QmhZMk5sYzNNZ1ltVjViMjVrSUdKMVptWmxjaUJzWlc1bmRHZ25LVnh1ZlZ4dVhHNUNkV1ptWlhJdWNISnZkRzkwZVhCbExuSmxZV1JWU1c1MFRFVWdQU0JtZFc1amRHbHZiaUJ5WldGa1ZVbHVkRXhGSUNodlptWnpaWFFzSUdKNWRHVk1aVzVuZEdnc0lHNXZRWE56WlhKMEtTQjdYRzRnSUc5bVpuTmxkQ0E5SUc5bVpuTmxkQ0I4SURCY2JpQWdZbmwwWlV4bGJtZDBhQ0E5SUdKNWRHVk1aVzVuZEdnZ2ZDQXdYRzRnSUdsbUlDZ2hibTlCYzNObGNuUXBJR05vWldOclQyWm1jMlYwS0c5bVpuTmxkQ3dnWW5sMFpVeGxibWQwYUN3Z2RHaHBjeTVzWlc1bmRHZ3BYRzVjYmlBZ2RtRnlJSFpoYkNBOUlIUm9hWE5iYjJabWMyVjBYVnh1SUNCMllYSWdiWFZzSUQwZ01WeHVJQ0IyWVhJZ2FTQTlJREJjYmlBZ2QyaHBiR1VnS0NzcmFTQThJR0o1ZEdWTVpXNW5kR2dnSmlZZ0tHMTFiQ0FxUFNBd2VERXdNQ2twSUh0Y2JpQWdJQ0IyWVd3Z0t6MGdkR2hwYzF0dlptWnpaWFFnS3lCcFhTQXFJRzExYkZ4dUlDQjlYRzVjYmlBZ2NtVjBkWEp1SUhaaGJGeHVmVnh1WEc1Q2RXWm1aWEl1Y0hKdmRHOTBlWEJsTG5KbFlXUlZTVzUwUWtVZ1BTQm1kVzVqZEdsdmJpQnlaV0ZrVlVsdWRFSkZJQ2h2Wm1aelpYUXNJR0o1ZEdWTVpXNW5kR2dzSUc1dlFYTnpaWEowS1NCN1hHNGdJRzltWm5ObGRDQTlJRzltWm5ObGRDQjhJREJjYmlBZ1lubDBaVXhsYm1kMGFDQTlJR0o1ZEdWTVpXNW5kR2dnZkNBd1hHNGdJR2xtSUNnaGJtOUJjM05sY25RcElIdGNiaUFnSUNCamFHVmphMDltWm5ObGRDaHZabVp6WlhRc0lHSjVkR1ZNWlc1bmRHZ3NJSFJvYVhNdWJHVnVaM1JvS1Z4dUlDQjlYRzVjYmlBZ2RtRnlJSFpoYkNBOUlIUm9hWE5iYjJabWMyVjBJQ3NnTFMxaWVYUmxUR1Z1WjNSb1hWeHVJQ0IyWVhJZ2JYVnNJRDBnTVZ4dUlDQjNhR2xzWlNBb1lubDBaVXhsYm1kMGFDQStJREFnSmlZZ0tHMTFiQ0FxUFNBd2VERXdNQ2twSUh0Y2JpQWdJQ0IyWVd3Z0t6MGdkR2hwYzF0dlptWnpaWFFnS3lBdExXSjVkR1ZNWlc1bmRHaGRJQ29nYlhWc1hHNGdJSDFjYmx4dUlDQnlaWFIxY200Z2RtRnNYRzU5WEc1Y2JrSjFabVpsY2k1d2NtOTBiM1I1Y0dVdWNtVmhaRlZKYm5RNElEMGdablZ1WTNScGIyNGdjbVZoWkZWSmJuUTRJQ2h2Wm1aelpYUXNJRzV2UVhOelpYSjBLU0I3WEc0Z0lHbG1JQ2doYm05QmMzTmxjblFwSUdOb1pXTnJUMlptYzJWMEtHOW1abk5sZEN3Z01Td2dkR2hwY3k1c1pXNW5kR2dwWEc0Z0lISmxkSFZ5YmlCMGFHbHpXMjltWm5ObGRGMWNibjFjYmx4dVFuVm1abVZ5TG5CeWIzUnZkSGx3WlM1eVpXRmtWVWx1ZERFMlRFVWdQU0JtZFc1amRHbHZiaUJ5WldGa1ZVbHVkREUyVEVVZ0tHOW1abk5sZEN3Z2JtOUJjM05sY25RcElIdGNiaUFnYVdZZ0tDRnViMEZ6YzJWeWRDa2dZMmhsWTJ0UFptWnpaWFFvYjJabWMyVjBMQ0F5TENCMGFHbHpMbXhsYm1kMGFDbGNiaUFnY21WMGRYSnVJSFJvYVhOYmIyWm1jMlYwWFNCOElDaDBhR2x6VzI5bVpuTmxkQ0FySURGZElEdzhJRGdwWEc1OVhHNWNia0oxWm1abGNpNXdjbTkwYjNSNWNHVXVjbVZoWkZWSmJuUXhOa0pGSUQwZ1puVnVZM1JwYjI0Z2NtVmhaRlZKYm5ReE5rSkZJQ2h2Wm1aelpYUXNJRzV2UVhOelpYSjBLU0I3WEc0Z0lHbG1JQ2doYm05QmMzTmxjblFwSUdOb1pXTnJUMlptYzJWMEtHOW1abk5sZEN3Z01pd2dkR2hwY3k1c1pXNW5kR2dwWEc0Z0lISmxkSFZ5YmlBb2RHaHBjMXR2Wm1aelpYUmRJRHc4SURncElId2dkR2hwYzF0dlptWnpaWFFnS3lBeFhWeHVmVnh1WEc1Q2RXWm1aWEl1Y0hKdmRHOTBlWEJsTG5KbFlXUlZTVzUwTXpKTVJTQTlJR1oxYm1OMGFXOXVJSEpsWVdSVlNXNTBNekpNUlNBb2IyWm1jMlYwTENCdWIwRnpjMlZ5ZENrZ2UxeHVJQ0JwWmlBb0lXNXZRWE56WlhKMEtTQmphR1ZqYTA5bVpuTmxkQ2h2Wm1aelpYUXNJRFFzSUhSb2FYTXViR1Z1WjNSb0tWeHVYRzRnSUhKbGRIVnliaUFvS0hSb2FYTmJiMlptYzJWMFhTa2dmRnh1SUNBZ0lDQWdLSFJvYVhOYmIyWm1jMlYwSUNzZ01WMGdQRHdnT0NrZ2ZGeHVJQ0FnSUNBZ0tIUm9hWE5iYjJabWMyVjBJQ3NnTWwwZ1BEd2dNVFlwS1NBclhHNGdJQ0FnSUNBb2RHaHBjMXR2Wm1aelpYUWdLeUF6WFNBcUlEQjRNVEF3TURBd01DbGNibjFjYmx4dVFuVm1abVZ5TG5CeWIzUnZkSGx3WlM1eVpXRmtWVWx1ZERNeVFrVWdQU0JtZFc1amRHbHZiaUJ5WldGa1ZVbHVkRE15UWtVZ0tHOW1abk5sZEN3Z2JtOUJjM05sY25RcElIdGNiaUFnYVdZZ0tDRnViMEZ6YzJWeWRDa2dZMmhsWTJ0UFptWnpaWFFvYjJabWMyVjBMQ0EwTENCMGFHbHpMbXhsYm1kMGFDbGNibHh1SUNCeVpYUjFjbTRnS0hSb2FYTmJiMlptYzJWMFhTQXFJREI0TVRBd01EQXdNQ2tnSzF4dUlDQWdJQ2dvZEdocGMxdHZabVp6WlhRZ0t5QXhYU0E4UENBeE5pa2dmRnh1SUNBZ0lDaDBhR2x6VzI5bVpuTmxkQ0FySURKZElEdzhJRGdwSUh4Y2JpQWdJQ0IwYUdselcyOW1abk5sZENBcklETmRLVnh1ZlZ4dVhHNUNkV1ptWlhJdWNISnZkRzkwZVhCbExuSmxZV1JKYm5STVJTQTlJR1oxYm1OMGFXOXVJSEpsWVdSSmJuUk1SU0FvYjJabWMyVjBMQ0JpZVhSbFRHVnVaM1JvTENCdWIwRnpjMlZ5ZENrZ2UxeHVJQ0J2Wm1aelpYUWdQU0J2Wm1aelpYUWdmQ0F3WEc0Z0lHSjVkR1ZNWlc1bmRHZ2dQU0JpZVhSbFRHVnVaM1JvSUh3Z01GeHVJQ0JwWmlBb0lXNXZRWE56WlhKMEtTQmphR1ZqYTA5bVpuTmxkQ2h2Wm1aelpYUXNJR0o1ZEdWTVpXNW5kR2dzSUhSb2FYTXViR1Z1WjNSb0tWeHVYRzRnSUhaaGNpQjJZV3dnUFNCMGFHbHpXMjltWm5ObGRGMWNiaUFnZG1GeUlHMTFiQ0E5SURGY2JpQWdkbUZ5SUdrZ1BTQXdYRzRnSUhkb2FXeGxJQ2dySzJrZ1BDQmllWFJsVEdWdVozUm9JQ1ltSUNodGRXd2dLajBnTUhneE1EQXBLU0I3WEc0Z0lDQWdkbUZzSUNzOUlIUm9hWE5iYjJabWMyVjBJQ3NnYVYwZ0tpQnRkV3hjYmlBZ2ZWeHVJQ0J0ZFd3Z0tqMGdNSGc0TUZ4dVhHNGdJR2xtSUNoMllXd2dQajBnYlhWc0tTQjJZV3dnTFQwZ1RXRjBhQzV3YjNjb01pd2dPQ0FxSUdKNWRHVk1aVzVuZEdncFhHNWNiaUFnY21WMGRYSnVJSFpoYkZ4dWZWeHVYRzVDZFdabVpYSXVjSEp2ZEc5MGVYQmxMbkpsWVdSSmJuUkNSU0E5SUdaMWJtTjBhVzl1SUhKbFlXUkpiblJDUlNBb2IyWm1jMlYwTENCaWVYUmxUR1Z1WjNSb0xDQnViMEZ6YzJWeWRDa2dlMXh1SUNCdlptWnpaWFFnUFNCdlptWnpaWFFnZkNBd1hHNGdJR0o1ZEdWTVpXNW5kR2dnUFNCaWVYUmxUR1Z1WjNSb0lId2dNRnh1SUNCcFppQW9JVzV2UVhOelpYSjBLU0JqYUdWamEwOW1abk5sZENodlptWnpaWFFzSUdKNWRHVk1aVzVuZEdnc0lIUm9hWE11YkdWdVozUm9LVnh1WEc0Z0lIWmhjaUJwSUQwZ1lubDBaVXhsYm1kMGFGeHVJQ0IyWVhJZ2JYVnNJRDBnTVZ4dUlDQjJZWElnZG1Gc0lEMGdkR2hwYzF0dlptWnpaWFFnS3lBdExXbGRYRzRnSUhkb2FXeGxJQ2hwSUQ0Z01DQW1KaUFvYlhWc0lDbzlJREI0TVRBd0tTa2dlMXh1SUNBZ0lIWmhiQ0FyUFNCMGFHbHpXMjltWm5ObGRDQXJJQzB0YVYwZ0tpQnRkV3hjYmlBZ2ZWeHVJQ0J0ZFd3Z0tqMGdNSGc0TUZ4dVhHNGdJR2xtSUNoMllXd2dQajBnYlhWc0tTQjJZV3dnTFQwZ1RXRjBhQzV3YjNjb01pd2dPQ0FxSUdKNWRHVk1aVzVuZEdncFhHNWNiaUFnY21WMGRYSnVJSFpoYkZ4dWZWeHVYRzVDZFdabVpYSXVjSEp2ZEc5MGVYQmxMbkpsWVdSSmJuUTRJRDBnWm5WdVkzUnBiMjRnY21WaFpFbHVkRGdnS0c5bVpuTmxkQ3dnYm05QmMzTmxjblFwSUh0Y2JpQWdhV1lnS0NGdWIwRnpjMlZ5ZENrZ1kyaGxZMnRQWm1aelpYUW9iMlptYzJWMExDQXhMQ0IwYUdsekxteGxibWQwYUNsY2JpQWdhV1lnS0NFb2RHaHBjMXR2Wm1aelpYUmRJQ1lnTUhnNE1Da3BJSEpsZEhWeWJpQW9kR2hwYzF0dlptWnpaWFJkS1Z4dUlDQnlaWFIxY200Z0tDZ3dlR1ptSUMwZ2RHaHBjMXR2Wm1aelpYUmRJQ3NnTVNrZ0tpQXRNU2xjYm4xY2JseHVRblZtWm1WeUxuQnliM1J2ZEhsd1pTNXlaV0ZrU1c1ME1UWk1SU0E5SUdaMWJtTjBhVzl1SUhKbFlXUkpiblF4Tmt4RklDaHZabVp6WlhRc0lHNXZRWE56WlhKMEtTQjdYRzRnSUdsbUlDZ2hibTlCYzNObGNuUXBJR05vWldOclQyWm1jMlYwS0c5bVpuTmxkQ3dnTWl3Z2RHaHBjeTVzWlc1bmRHZ3BYRzRnSUhaaGNpQjJZV3dnUFNCMGFHbHpXMjltWm5ObGRGMGdmQ0FvZEdocGMxdHZabVp6WlhRZ0t5QXhYU0E4UENBNEtWeHVJQ0J5WlhSMWNtNGdLSFpoYkNBbUlEQjRPREF3TUNrZ1B5QjJZV3dnZkNBd2VFWkdSa1l3TURBd0lEb2dkbUZzWEc1OVhHNWNia0oxWm1abGNpNXdjbTkwYjNSNWNHVXVjbVZoWkVsdWRERTJRa1VnUFNCbWRXNWpkR2x2YmlCeVpXRmtTVzUwTVRaQ1JTQW9iMlptYzJWMExDQnViMEZ6YzJWeWRDa2dlMXh1SUNCcFppQW9JVzV2UVhOelpYSjBLU0JqYUdWamEwOW1abk5sZENodlptWnpaWFFzSURJc0lIUm9hWE11YkdWdVozUm9LVnh1SUNCMllYSWdkbUZzSUQwZ2RHaHBjMXR2Wm1aelpYUWdLeUF4WFNCOElDaDBhR2x6VzI5bVpuTmxkRjBnUER3Z09DbGNiaUFnY21WMGRYSnVJQ2gyWVd3Z0ppQXdlRGd3TURBcElEOGdkbUZzSUh3Z01IaEdSa1pHTURBd01DQTZJSFpoYkZ4dWZWeHVYRzVDZFdabVpYSXVjSEp2ZEc5MGVYQmxMbkpsWVdSSmJuUXpNa3hGSUQwZ1puVnVZM1JwYjI0Z2NtVmhaRWx1ZERNeVRFVWdLRzltWm5ObGRDd2dibTlCYzNObGNuUXBJSHRjYmlBZ2FXWWdLQ0Z1YjBGemMyVnlkQ2tnWTJobFkydFBabVp6WlhRb2IyWm1jMlYwTENBMExDQjBhR2x6TG14bGJtZDBhQ2xjYmx4dUlDQnlaWFIxY200Z0tIUm9hWE5iYjJabWMyVjBYU2tnZkZ4dUlDQWdJQ2gwYUdselcyOW1abk5sZENBcklERmRJRHc4SURncElIeGNiaUFnSUNBb2RHaHBjMXR2Wm1aelpYUWdLeUF5WFNBOFBDQXhOaWtnZkZ4dUlDQWdJQ2gwYUdselcyOW1abk5sZENBcklETmRJRHc4SURJMEtWeHVmVnh1WEc1Q2RXWm1aWEl1Y0hKdmRHOTBlWEJsTG5KbFlXUkpiblF6TWtKRklEMGdablZ1WTNScGIyNGdjbVZoWkVsdWRETXlRa1VnS0c5bVpuTmxkQ3dnYm05QmMzTmxjblFwSUh0Y2JpQWdhV1lnS0NGdWIwRnpjMlZ5ZENrZ1kyaGxZMnRQWm1aelpYUW9iMlptYzJWMExDQTBMQ0IwYUdsekxteGxibWQwYUNsY2JseHVJQ0J5WlhSMWNtNGdLSFJvYVhOYmIyWm1jMlYwWFNBOFBDQXlOQ2tnZkZ4dUlDQWdJQ2gwYUdselcyOW1abk5sZENBcklERmRJRHc4SURFMktTQjhYRzRnSUNBZ0tIUm9hWE5iYjJabWMyVjBJQ3NnTWwwZ1BEd2dPQ2tnZkZ4dUlDQWdJQ2gwYUdselcyOW1abk5sZENBcklETmRLVnh1ZlZ4dVhHNUNkV1ptWlhJdWNISnZkRzkwZVhCbExuSmxZV1JHYkc5aGRFeEZJRDBnWm5WdVkzUnBiMjRnY21WaFpFWnNiMkYwVEVVZ0tHOW1abk5sZEN3Z2JtOUJjM05sY25RcElIdGNiaUFnYVdZZ0tDRnViMEZ6YzJWeWRDa2dZMmhsWTJ0UFptWnpaWFFvYjJabWMyVjBMQ0EwTENCMGFHbHpMbXhsYm1kMGFDbGNiaUFnY21WMGRYSnVJR2xsWldVM05UUXVjbVZoWkNoMGFHbHpMQ0J2Wm1aelpYUXNJSFJ5ZFdVc0lESXpMQ0EwS1Z4dWZWeHVYRzVDZFdabVpYSXVjSEp2ZEc5MGVYQmxMbkpsWVdSR2JHOWhkRUpGSUQwZ1puVnVZM1JwYjI0Z2NtVmhaRVpzYjJGMFFrVWdLRzltWm5ObGRDd2dibTlCYzNObGNuUXBJSHRjYmlBZ2FXWWdLQ0Z1YjBGemMyVnlkQ2tnWTJobFkydFBabVp6WlhRb2IyWm1jMlYwTENBMExDQjBhR2x6TG14bGJtZDBhQ2xjYmlBZ2NtVjBkWEp1SUdsbFpXVTNOVFF1Y21WaFpDaDBhR2x6TENCdlptWnpaWFFzSUdaaGJITmxMQ0F5TXl3Z05DbGNibjFjYmx4dVFuVm1abVZ5TG5CeWIzUnZkSGx3WlM1eVpXRmtSRzkxWW14bFRFVWdQU0JtZFc1amRHbHZiaUJ5WldGa1JHOTFZbXhsVEVVZ0tHOW1abk5sZEN3Z2JtOUJjM05sY25RcElIdGNiaUFnYVdZZ0tDRnViMEZ6YzJWeWRDa2dZMmhsWTJ0UFptWnpaWFFvYjJabWMyVjBMQ0E0TENCMGFHbHpMbXhsYm1kMGFDbGNiaUFnY21WMGRYSnVJR2xsWldVM05UUXVjbVZoWkNoMGFHbHpMQ0J2Wm1aelpYUXNJSFJ5ZFdVc0lEVXlMQ0E0S1Z4dWZWeHVYRzVDZFdabVpYSXVjSEp2ZEc5MGVYQmxMbkpsWVdSRWIzVmliR1ZDUlNBOUlHWjFibU4wYVc5dUlISmxZV1JFYjNWaWJHVkNSU0FvYjJabWMyVjBMQ0J1YjBGemMyVnlkQ2tnZTF4dUlDQnBaaUFvSVc1dlFYTnpaWEowS1NCamFHVmphMDltWm5ObGRDaHZabVp6WlhRc0lEZ3NJSFJvYVhNdWJHVnVaM1JvS1Z4dUlDQnlaWFIxY200Z2FXVmxaVGMxTkM1eVpXRmtLSFJvYVhNc0lHOW1abk5sZEN3Z1ptRnNjMlVzSURVeUxDQTRLVnh1ZlZ4dVhHNW1kVzVqZEdsdmJpQmphR1ZqYTBsdWRDQW9ZblZtTENCMllXeDFaU3dnYjJabWMyVjBMQ0JsZUhRc0lHMWhlQ3dnYldsdUtTQjdYRzRnSUdsbUlDZ2hRblZtWm1WeUxtbHpRblZtWm1WeUtHSjFaaWtwSUhSb2NtOTNJRzVsZHlCVWVYQmxSWEp5YjNJb0oySjFabVpsY2lCdGRYTjBJR0psSUdFZ1FuVm1abVZ5SUdsdWMzUmhibU5sSnlsY2JpQWdhV1lnS0haaGJIVmxJRDRnYldGNElIeDhJSFpoYkhWbElEd2diV2x1S1NCMGFISnZkeUJ1WlhjZ1VtRnVaMlZGY25KdmNpZ25kbUZzZFdVZ2FYTWdiM1YwSUc5bUlHSnZkVzVrY3ljcFhHNGdJR2xtSUNodlptWnpaWFFnS3lCbGVIUWdQaUJpZFdZdWJHVnVaM1JvS1NCMGFISnZkeUJ1WlhjZ1VtRnVaMlZGY25KdmNpZ25hVzVrWlhnZ2IzVjBJRzltSUhKaGJtZGxKeWxjYm4xY2JseHVRblZtWm1WeUxuQnliM1J2ZEhsd1pTNTNjbWwwWlZWSmJuUk1SU0E5SUdaMWJtTjBhVzl1SUhkeWFYUmxWVWx1ZEV4RklDaDJZV3gxWlN3Z2IyWm1jMlYwTENCaWVYUmxUR1Z1WjNSb0xDQnViMEZ6YzJWeWRDa2dlMXh1SUNCMllXeDFaU0E5SUN0MllXeDFaVnh1SUNCdlptWnpaWFFnUFNCdlptWnpaWFFnZkNBd1hHNGdJR0o1ZEdWTVpXNW5kR2dnUFNCaWVYUmxUR1Z1WjNSb0lId2dNRnh1SUNCcFppQW9JVzV2UVhOelpYSjBLU0JqYUdWamEwbHVkQ2gwYUdsekxDQjJZV3gxWlN3Z2IyWm1jMlYwTENCaWVYUmxUR1Z1WjNSb0xDQk5ZWFJvTG5CdmR5Z3lMQ0E0SUNvZ1lubDBaVXhsYm1kMGFDa3NJREFwWEc1Y2JpQWdkbUZ5SUcxMWJDQTlJREZjYmlBZ2RtRnlJR2tnUFNBd1hHNGdJSFJvYVhOYmIyWm1jMlYwWFNBOUlIWmhiSFZsSUNZZ01IaEdSbHh1SUNCM2FHbHNaU0FvS3l0cElEd2dZbmwwWlV4bGJtZDBhQ0FtSmlBb2JYVnNJQ285SURCNE1UQXdLU2tnZTF4dUlDQWdJSFJvYVhOYmIyWm1jMlYwSUNzZ2FWMGdQU0FvZG1Gc2RXVWdMeUJ0ZFd3cElDWWdNSGhHUmx4dUlDQjlYRzVjYmlBZ2NtVjBkWEp1SUc5bVpuTmxkQ0FySUdKNWRHVk1aVzVuZEdoY2JuMWNibHh1UW5WbVptVnlMbkJ5YjNSdmRIbHdaUzUzY21sMFpWVkpiblJDUlNBOUlHWjFibU4wYVc5dUlIZHlhWFJsVlVsdWRFSkZJQ2gyWVd4MVpTd2diMlptYzJWMExDQmllWFJsVEdWdVozUm9MQ0J1YjBGemMyVnlkQ2tnZTF4dUlDQjJZV3gxWlNBOUlDdDJZV3gxWlZ4dUlDQnZabVp6WlhRZ1BTQnZabVp6WlhRZ2ZDQXdYRzRnSUdKNWRHVk1aVzVuZEdnZ1BTQmllWFJsVEdWdVozUm9JSHdnTUZ4dUlDQnBaaUFvSVc1dlFYTnpaWEowS1NCamFHVmphMGx1ZENoMGFHbHpMQ0IyWVd4MVpTd2diMlptYzJWMExDQmllWFJsVEdWdVozUm9MQ0JOWVhSb0xuQnZkeWd5TENBNElDb2dZbmwwWlV4bGJtZDBhQ2tzSURBcFhHNWNiaUFnZG1GeUlHa2dQU0JpZVhSbFRHVnVaM1JvSUMwZ01WeHVJQ0IyWVhJZ2JYVnNJRDBnTVZ4dUlDQjBhR2x6VzI5bVpuTmxkQ0FySUdsZElEMGdkbUZzZFdVZ0ppQXdlRVpHWEc0Z0lIZG9hV3hsSUNndExXa2dQajBnTUNBbUppQW9iWFZzSUNvOUlEQjRNVEF3S1NrZ2UxeHVJQ0FnSUhSb2FYTmJiMlptYzJWMElDc2dhVjBnUFNBb2RtRnNkV1VnTHlCdGRXd3BJQ1lnTUhoR1JseHVJQ0I5WEc1Y2JpQWdjbVYwZFhKdUlHOW1abk5sZENBcklHSjVkR1ZNWlc1bmRHaGNibjFjYmx4dVFuVm1abVZ5TG5CeWIzUnZkSGx3WlM1M2NtbDBaVlZKYm5RNElEMGdablZ1WTNScGIyNGdkM0pwZEdWVlNXNTBPQ0FvZG1Gc2RXVXNJRzltWm5ObGRDd2dibTlCYzNObGNuUXBJSHRjYmlBZ2RtRnNkV1VnUFNBcmRtRnNkV1ZjYmlBZ2IyWm1jMlYwSUQwZ2IyWm1jMlYwSUh3Z01GeHVJQ0JwWmlBb0lXNXZRWE56WlhKMEtTQmphR1ZqYTBsdWRDaDBhR2x6TENCMllXeDFaU3dnYjJabWMyVjBMQ0F4TENBd2VHWm1MQ0F3S1Z4dUlDQnBaaUFvSVVKMVptWmxjaTVVV1ZCRlJGOUJVbEpCV1Y5VFZWQlFUMUpVS1NCMllXeDFaU0E5SUUxaGRHZ3VabXh2YjNJb2RtRnNkV1VwWEc0Z0lIUm9hWE5iYjJabWMyVjBYU0E5SUNoMllXeDFaU0FtSURCNFptWXBYRzRnSUhKbGRIVnliaUJ2Wm1aelpYUWdLeUF4WEc1OVhHNWNibVoxYm1OMGFXOXVJRzlpYW1WamRGZHlhWFJsVlVsdWRERTJJQ2hpZFdZc0lIWmhiSFZsTENCdlptWnpaWFFzSUd4cGRIUnNaVVZ1WkdsaGJpa2dlMXh1SUNCcFppQW9kbUZzZFdVZ1BDQXdLU0IyWVd4MVpTQTlJREI0Wm1abVppQXJJSFpoYkhWbElDc2dNVnh1SUNCbWIzSWdLSFpoY2lCcElEMGdNQ3dnYWlBOUlFMWhkR2d1YldsdUtHSjFaaTVzWlc1bmRHZ2dMU0J2Wm1aelpYUXNJRElwT3lCcElEd2dhanNnYVNzcktTQjdYRzRnSUNBZ1luVm1XMjltWm5ObGRDQXJJR2xkSUQwZ0tIWmhiSFZsSUNZZ0tEQjRabVlnUER3Z0tEZ2dLaUFvYkdsMGRHeGxSVzVrYVdGdUlEOGdhU0E2SURFZ0xTQnBLU2twS1NBK1BqNWNiaUFnSUNBZ0lDaHNhWFIwYkdWRmJtUnBZVzRnUHlCcElEb2dNU0F0SUdrcElDb2dPRnh1SUNCOVhHNTlYRzVjYmtKMVptWmxjaTV3Y205MGIzUjVjR1V1ZDNKcGRHVlZTVzUwTVRaTVJTQTlJR1oxYm1OMGFXOXVJSGR5YVhSbFZVbHVkREUyVEVVZ0tIWmhiSFZsTENCdlptWnpaWFFzSUc1dlFYTnpaWEowS1NCN1hHNGdJSFpoYkhWbElEMGdLM1poYkhWbFhHNGdJRzltWm5ObGRDQTlJRzltWm5ObGRDQjhJREJjYmlBZ2FXWWdLQ0Z1YjBGemMyVnlkQ2tnWTJobFkydEpiblFvZEdocGN5d2dkbUZzZFdVc0lHOW1abk5sZEN3Z01pd2dNSGhtWm1abUxDQXdLVnh1SUNCcFppQW9RblZtWm1WeUxsUlpVRVZFWDBGU1VrRlpYMU5WVUZCUFVsUXBJSHRjYmlBZ0lDQjBhR2x6VzI5bVpuTmxkRjBnUFNBb2RtRnNkV1VnSmlBd2VHWm1LVnh1SUNBZ0lIUm9hWE5iYjJabWMyVjBJQ3NnTVYwZ1BTQW9kbUZzZFdVZ1BqNCtJRGdwWEc0Z0lIMGdaV3h6WlNCN1hHNGdJQ0FnYjJKcVpXTjBWM0pwZEdWVlNXNTBNVFlvZEdocGN5d2dkbUZzZFdVc0lHOW1abk5sZEN3Z2RISjFaU2xjYmlBZ2ZWeHVJQ0J5WlhSMWNtNGdiMlptYzJWMElDc2dNbHh1ZlZ4dVhHNUNkV1ptWlhJdWNISnZkRzkwZVhCbExuZHlhWFJsVlVsdWRERTJRa1VnUFNCbWRXNWpkR2x2YmlCM2NtbDBaVlZKYm5ReE5rSkZJQ2gyWVd4MVpTd2diMlptYzJWMExDQnViMEZ6YzJWeWRDa2dlMXh1SUNCMllXeDFaU0E5SUN0MllXeDFaVnh1SUNCdlptWnpaWFFnUFNCdlptWnpaWFFnZkNBd1hHNGdJR2xtSUNnaGJtOUJjM05sY25RcElHTm9aV05yU1c1MEtIUm9hWE1zSUhaaGJIVmxMQ0J2Wm1aelpYUXNJRElzSURCNFptWm1aaXdnTUNsY2JpQWdhV1lnS0VKMVptWmxjaTVVV1ZCRlJGOUJVbEpCV1Y5VFZWQlFUMUpVS1NCN1hHNGdJQ0FnZEdocGMxdHZabVp6WlhSZElEMGdLSFpoYkhWbElENCtQaUE0S1Z4dUlDQWdJSFJvYVhOYmIyWm1jMlYwSUNzZ01WMGdQU0FvZG1Gc2RXVWdKaUF3ZUdabUtWeHVJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lHOWlhbVZqZEZkeWFYUmxWVWx1ZERFMktIUm9hWE1zSUhaaGJIVmxMQ0J2Wm1aelpYUXNJR1poYkhObEtWeHVJQ0I5WEc0Z0lISmxkSFZ5YmlCdlptWnpaWFFnS3lBeVhHNTlYRzVjYm1aMWJtTjBhVzl1SUc5aWFtVmpkRmR5YVhSbFZVbHVkRE15SUNoaWRXWXNJSFpoYkhWbExDQnZabVp6WlhRc0lHeHBkSFJzWlVWdVpHbGhiaWtnZTF4dUlDQnBaaUFvZG1Gc2RXVWdQQ0F3S1NCMllXeDFaU0E5SURCNFptWm1abVptWm1ZZ0t5QjJZV3gxWlNBcklERmNiaUFnWm05eUlDaDJZWElnYVNBOUlEQXNJR29nUFNCTllYUm9MbTFwYmloaWRXWXViR1Z1WjNSb0lDMGdiMlptYzJWMExDQTBLVHNnYVNBOElHbzdJR2tyS3lrZ2UxeHVJQ0FnSUdKMVpsdHZabVp6WlhRZ0t5QnBYU0E5SUNoMllXeDFaU0ErUGo0Z0tHeHBkSFJzWlVWdVpHbGhiaUEvSUdrZ09pQXpJQzBnYVNrZ0tpQTRLU0FtSURCNFptWmNiaUFnZlZ4dWZWeHVYRzVDZFdabVpYSXVjSEp2ZEc5MGVYQmxMbmR5YVhSbFZVbHVkRE15VEVVZ1BTQm1kVzVqZEdsdmJpQjNjbWwwWlZWSmJuUXpNa3hGSUNoMllXeDFaU3dnYjJabWMyVjBMQ0J1YjBGemMyVnlkQ2tnZTF4dUlDQjJZV3gxWlNBOUlDdDJZV3gxWlZ4dUlDQnZabVp6WlhRZ1BTQnZabVp6WlhRZ2ZDQXdYRzRnSUdsbUlDZ2hibTlCYzNObGNuUXBJR05vWldOclNXNTBLSFJvYVhNc0lIWmhiSFZsTENCdlptWnpaWFFzSURRc0lEQjRabVptWm1abVptWXNJREFwWEc0Z0lHbG1JQ2hDZFdabVpYSXVWRmxRUlVSZlFWSlNRVmxmVTFWUVVFOVNWQ2tnZTF4dUlDQWdJSFJvYVhOYmIyWm1jMlYwSUNzZ00xMGdQU0FvZG1Gc2RXVWdQajQrSURJMEtWeHVJQ0FnSUhSb2FYTmJiMlptYzJWMElDc2dNbDBnUFNBb2RtRnNkV1VnUGo0K0lERTJLVnh1SUNBZ0lIUm9hWE5iYjJabWMyVjBJQ3NnTVYwZ1BTQW9kbUZzZFdVZ1BqNCtJRGdwWEc0Z0lDQWdkR2hwYzF0dlptWnpaWFJkSUQwZ0tIWmhiSFZsSUNZZ01IaG1aaWxjYmlBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0J2WW1wbFkzUlhjbWwwWlZWSmJuUXpNaWgwYUdsekxDQjJZV3gxWlN3Z2IyWm1jMlYwTENCMGNuVmxLVnh1SUNCOVhHNGdJSEpsZEhWeWJpQnZabVp6WlhRZ0t5QTBYRzU5WEc1Y2JrSjFabVpsY2k1d2NtOTBiM1I1Y0dVdWQzSnBkR1ZWU1c1ME16SkNSU0E5SUdaMWJtTjBhVzl1SUhkeWFYUmxWVWx1ZERNeVFrVWdLSFpoYkhWbExDQnZabVp6WlhRc0lHNXZRWE56WlhKMEtTQjdYRzRnSUhaaGJIVmxJRDBnSzNaaGJIVmxYRzRnSUc5bVpuTmxkQ0E5SUc5bVpuTmxkQ0I4SURCY2JpQWdhV1lnS0NGdWIwRnpjMlZ5ZENrZ1kyaGxZMnRKYm5Rb2RHaHBjeXdnZG1Gc2RXVXNJRzltWm5ObGRDd2dOQ3dnTUhobVptWm1abVptWml3Z01DbGNiaUFnYVdZZ0tFSjFabVpsY2k1VVdWQkZSRjlCVWxKQldWOVRWVkJRVDFKVUtTQjdYRzRnSUNBZ2RHaHBjMXR2Wm1aelpYUmRJRDBnS0haaGJIVmxJRDQrUGlBeU5DbGNiaUFnSUNCMGFHbHpXMjltWm5ObGRDQXJJREZkSUQwZ0tIWmhiSFZsSUQ0K1BpQXhOaWxjYmlBZ0lDQjBhR2x6VzI5bVpuTmxkQ0FySURKZElEMGdLSFpoYkhWbElENCtQaUE0S1Z4dUlDQWdJSFJvYVhOYmIyWm1jMlYwSUNzZ00xMGdQU0FvZG1Gc2RXVWdKaUF3ZUdabUtWeHVJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lHOWlhbVZqZEZkeWFYUmxWVWx1ZERNeUtIUm9hWE1zSUhaaGJIVmxMQ0J2Wm1aelpYUXNJR1poYkhObEtWeHVJQ0I5WEc0Z0lISmxkSFZ5YmlCdlptWnpaWFFnS3lBMFhHNTlYRzVjYmtKMVptWmxjaTV3Y205MGIzUjVjR1V1ZDNKcGRHVkpiblJNUlNBOUlHWjFibU4wYVc5dUlIZHlhWFJsU1c1MFRFVWdLSFpoYkhWbExDQnZabVp6WlhRc0lHSjVkR1ZNWlc1bmRHZ3NJRzV2UVhOelpYSjBLU0I3WEc0Z0lIWmhiSFZsSUQwZ0szWmhiSFZsWEc0Z0lHOW1abk5sZENBOUlHOW1abk5sZENCOElEQmNiaUFnYVdZZ0tDRnViMEZ6YzJWeWRDa2dlMXh1SUNBZ0lIWmhjaUJzYVcxcGRDQTlJRTFoZEdndWNHOTNLRElzSURnZ0tpQmllWFJsVEdWdVozUm9JQzBnTVNsY2JseHVJQ0FnSUdOb1pXTnJTVzUwS0hSb2FYTXNJSFpoYkhWbExDQnZabVp6WlhRc0lHSjVkR1ZNWlc1bmRHZ3NJR3hwYldsMElDMGdNU3dnTFd4cGJXbDBLVnh1SUNCOVhHNWNiaUFnZG1GeUlHa2dQU0F3WEc0Z0lIWmhjaUJ0ZFd3Z1BTQXhYRzRnSUhaaGNpQnpkV0lnUFNCMllXeDFaU0E4SURBZ1B5QXhJRG9nTUZ4dUlDQjBhR2x6VzI5bVpuTmxkRjBnUFNCMllXeDFaU0FtSURCNFJrWmNiaUFnZDJocGJHVWdLQ3NyYVNBOElHSjVkR1ZNWlc1bmRHZ2dKaVlnS0cxMWJDQXFQU0F3ZURFd01Da3BJSHRjYmlBZ0lDQjBhR2x6VzI5bVpuTmxkQ0FySUdsZElEMGdLQ2gyWVd4MVpTQXZJRzExYkNrZ1BqNGdNQ2tnTFNCemRXSWdKaUF3ZUVaR1hHNGdJSDFjYmx4dUlDQnlaWFIxY200Z2IyWm1jMlYwSUNzZ1lubDBaVXhsYm1kMGFGeHVmVnh1WEc1Q2RXWm1aWEl1Y0hKdmRHOTBlWEJsTG5keWFYUmxTVzUwUWtVZ1BTQm1kVzVqZEdsdmJpQjNjbWwwWlVsdWRFSkZJQ2gyWVd4MVpTd2diMlptYzJWMExDQmllWFJsVEdWdVozUm9MQ0J1YjBGemMyVnlkQ2tnZTF4dUlDQjJZV3gxWlNBOUlDdDJZV3gxWlZ4dUlDQnZabVp6WlhRZ1BTQnZabVp6WlhRZ2ZDQXdYRzRnSUdsbUlDZ2hibTlCYzNObGNuUXBJSHRjYmlBZ0lDQjJZWElnYkdsdGFYUWdQU0JOWVhSb0xuQnZkeWd5TENBNElDb2dZbmwwWlV4bGJtZDBhQ0F0SURFcFhHNWNiaUFnSUNCamFHVmphMGx1ZENoMGFHbHpMQ0IyWVd4MVpTd2diMlptYzJWMExDQmllWFJsVEdWdVozUm9MQ0JzYVcxcGRDQXRJREVzSUMxc2FXMXBkQ2xjYmlBZ2ZWeHVYRzRnSUhaaGNpQnBJRDBnWW5sMFpVeGxibWQwYUNBdElERmNiaUFnZG1GeUlHMTFiQ0E5SURGY2JpQWdkbUZ5SUhOMVlpQTlJSFpoYkhWbElEd2dNQ0EvSURFZ09pQXdYRzRnSUhSb2FYTmJiMlptYzJWMElDc2dhVjBnUFNCMllXeDFaU0FtSURCNFJrWmNiaUFnZDJocGJHVWdLQzB0YVNBK1BTQXdJQ1ltSUNodGRXd2dLajBnTUhneE1EQXBLU0I3WEc0Z0lDQWdkR2hwYzF0dlptWnpaWFFnS3lCcFhTQTlJQ2dvZG1Gc2RXVWdMeUJ0ZFd3cElENCtJREFwSUMwZ2MzVmlJQ1lnTUhoR1JseHVJQ0I5WEc1Y2JpQWdjbVYwZFhKdUlHOW1abk5sZENBcklHSjVkR1ZNWlc1bmRHaGNibjFjYmx4dVFuVm1abVZ5TG5CeWIzUnZkSGx3WlM1M2NtbDBaVWx1ZERnZ1BTQm1kVzVqZEdsdmJpQjNjbWwwWlVsdWREZ2dLSFpoYkhWbExDQnZabVp6WlhRc0lHNXZRWE56WlhKMEtTQjdYRzRnSUhaaGJIVmxJRDBnSzNaaGJIVmxYRzRnSUc5bVpuTmxkQ0E5SUc5bVpuTmxkQ0I4SURCY2JpQWdhV1lnS0NGdWIwRnpjMlZ5ZENrZ1kyaGxZMnRKYm5Rb2RHaHBjeXdnZG1Gc2RXVXNJRzltWm5ObGRDd2dNU3dnTUhnM1ppd2dMVEI0T0RBcFhHNGdJR2xtSUNnaFFuVm1abVZ5TGxSWlVFVkVYMEZTVWtGWlgxTlZVRkJQVWxRcElIWmhiSFZsSUQwZ1RXRjBhQzVtYkc5dmNpaDJZV3gxWlNsY2JpQWdhV1lnS0haaGJIVmxJRHdnTUNrZ2RtRnNkV1VnUFNBd2VHWm1JQ3NnZG1Gc2RXVWdLeUF4WEc0Z0lIUm9hWE5iYjJabWMyVjBYU0E5SUNoMllXeDFaU0FtSURCNFptWXBYRzRnSUhKbGRIVnliaUJ2Wm1aelpYUWdLeUF4WEc1OVhHNWNia0oxWm1abGNpNXdjbTkwYjNSNWNHVXVkM0pwZEdWSmJuUXhOa3hGSUQwZ1puVnVZM1JwYjI0Z2QzSnBkR1ZKYm5ReE5reEZJQ2gyWVd4MVpTd2diMlptYzJWMExDQnViMEZ6YzJWeWRDa2dlMXh1SUNCMllXeDFaU0E5SUN0MllXeDFaVnh1SUNCdlptWnpaWFFnUFNCdlptWnpaWFFnZkNBd1hHNGdJR2xtSUNnaGJtOUJjM05sY25RcElHTm9aV05yU1c1MEtIUm9hWE1zSUhaaGJIVmxMQ0J2Wm1aelpYUXNJRElzSURCNE4yWm1aaXdnTFRCNE9EQXdNQ2xjYmlBZ2FXWWdLRUoxWm1abGNpNVVXVkJGUkY5QlVsSkJXVjlUVlZCUVQxSlVLU0I3WEc0Z0lDQWdkR2hwYzF0dlptWnpaWFJkSUQwZ0tIWmhiSFZsSUNZZ01IaG1aaWxjYmlBZ0lDQjBhR2x6VzI5bVpuTmxkQ0FySURGZElEMGdLSFpoYkhWbElENCtQaUE0S1Z4dUlDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUc5aWFtVmpkRmR5YVhSbFZVbHVkREUyS0hSb2FYTXNJSFpoYkhWbExDQnZabVp6WlhRc0lIUnlkV1VwWEc0Z0lIMWNiaUFnY21WMGRYSnVJRzltWm5ObGRDQXJJREpjYm4xY2JseHVRblZtWm1WeUxuQnliM1J2ZEhsd1pTNTNjbWwwWlVsdWRERTJRa1VnUFNCbWRXNWpkR2x2YmlCM2NtbDBaVWx1ZERFMlFrVWdLSFpoYkhWbExDQnZabVp6WlhRc0lHNXZRWE56WlhKMEtTQjdYRzRnSUhaaGJIVmxJRDBnSzNaaGJIVmxYRzRnSUc5bVpuTmxkQ0E5SUc5bVpuTmxkQ0I4SURCY2JpQWdhV1lnS0NGdWIwRnpjMlZ5ZENrZ1kyaGxZMnRKYm5Rb2RHaHBjeXdnZG1Gc2RXVXNJRzltWm5ObGRDd2dNaXdnTUhnM1ptWm1MQ0F0TUhnNE1EQXdLVnh1SUNCcFppQW9RblZtWm1WeUxsUlpVRVZFWDBGU1VrRlpYMU5WVUZCUFVsUXBJSHRjYmlBZ0lDQjBhR2x6VzI5bVpuTmxkRjBnUFNBb2RtRnNkV1VnUGo0K0lEZ3BYRzRnSUNBZ2RHaHBjMXR2Wm1aelpYUWdLeUF4WFNBOUlDaDJZV3gxWlNBbUlEQjRabVlwWEc0Z0lIMGdaV3h6WlNCN1hHNGdJQ0FnYjJKcVpXTjBWM0pwZEdWVlNXNTBNVFlvZEdocGN5d2dkbUZzZFdVc0lHOW1abk5sZEN3Z1ptRnNjMlVwWEc0Z0lIMWNiaUFnY21WMGRYSnVJRzltWm5ObGRDQXJJREpjYm4xY2JseHVRblZtWm1WeUxuQnliM1J2ZEhsd1pTNTNjbWwwWlVsdWRETXlURVVnUFNCbWRXNWpkR2x2YmlCM2NtbDBaVWx1ZERNeVRFVWdLSFpoYkhWbExDQnZabVp6WlhRc0lHNXZRWE56WlhKMEtTQjdYRzRnSUhaaGJIVmxJRDBnSzNaaGJIVmxYRzRnSUc5bVpuTmxkQ0E5SUc5bVpuTmxkQ0I4SURCY2JpQWdhV1lnS0NGdWIwRnpjMlZ5ZENrZ1kyaGxZMnRKYm5Rb2RHaHBjeXdnZG1Gc2RXVXNJRzltWm5ObGRDd2dOQ3dnTUhnM1ptWm1abVptWml3Z0xUQjRPREF3TURBd01EQXBYRzRnSUdsbUlDaENkV1ptWlhJdVZGbFFSVVJmUVZKU1FWbGZVMVZRVUU5U1ZDa2dlMXh1SUNBZ0lIUm9hWE5iYjJabWMyVjBYU0E5SUNoMllXeDFaU0FtSURCNFptWXBYRzRnSUNBZ2RHaHBjMXR2Wm1aelpYUWdLeUF4WFNBOUlDaDJZV3gxWlNBK1BqNGdPQ2xjYmlBZ0lDQjBhR2x6VzI5bVpuTmxkQ0FySURKZElEMGdLSFpoYkhWbElENCtQaUF4TmlsY2JpQWdJQ0IwYUdselcyOW1abk5sZENBcklETmRJRDBnS0haaGJIVmxJRDQrUGlBeU5DbGNiaUFnZlNCbGJITmxJSHRjYmlBZ0lDQnZZbXBsWTNSWGNtbDBaVlZKYm5Rek1paDBhR2x6TENCMllXeDFaU3dnYjJabWMyVjBMQ0IwY25WbEtWeHVJQ0I5WEc0Z0lISmxkSFZ5YmlCdlptWnpaWFFnS3lBMFhHNTlYRzVjYmtKMVptWmxjaTV3Y205MGIzUjVjR1V1ZDNKcGRHVkpiblF6TWtKRklEMGdablZ1WTNScGIyNGdkM0pwZEdWSmJuUXpNa0pGSUNoMllXeDFaU3dnYjJabWMyVjBMQ0J1YjBGemMyVnlkQ2tnZTF4dUlDQjJZV3gxWlNBOUlDdDJZV3gxWlZ4dUlDQnZabVp6WlhRZ1BTQnZabVp6WlhRZ2ZDQXdYRzRnSUdsbUlDZ2hibTlCYzNObGNuUXBJR05vWldOclNXNTBLSFJvYVhNc0lIWmhiSFZsTENCdlptWnpaWFFzSURRc0lEQjROMlptWm1abVptWXNJQzB3ZURnd01EQXdNREF3S1Z4dUlDQnBaaUFvZG1Gc2RXVWdQQ0F3S1NCMllXeDFaU0E5SURCNFptWm1abVptWm1ZZ0t5QjJZV3gxWlNBcklERmNiaUFnYVdZZ0tFSjFabVpsY2k1VVdWQkZSRjlCVWxKQldWOVRWVkJRVDFKVUtTQjdYRzRnSUNBZ2RHaHBjMXR2Wm1aelpYUmRJRDBnS0haaGJIVmxJRDQrUGlBeU5DbGNiaUFnSUNCMGFHbHpXMjltWm5ObGRDQXJJREZkSUQwZ0tIWmhiSFZsSUQ0K1BpQXhOaWxjYmlBZ0lDQjBhR2x6VzI5bVpuTmxkQ0FySURKZElEMGdLSFpoYkhWbElENCtQaUE0S1Z4dUlDQWdJSFJvYVhOYmIyWm1jMlYwSUNzZ00xMGdQU0FvZG1Gc2RXVWdKaUF3ZUdabUtWeHVJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lHOWlhbVZqZEZkeWFYUmxWVWx1ZERNeUtIUm9hWE1zSUhaaGJIVmxMQ0J2Wm1aelpYUXNJR1poYkhObEtWeHVJQ0I5WEc0Z0lISmxkSFZ5YmlCdlptWnpaWFFnS3lBMFhHNTlYRzVjYm1aMWJtTjBhVzl1SUdOb1pXTnJTVVZGUlRjMU5DQW9ZblZtTENCMllXeDFaU3dnYjJabWMyVjBMQ0JsZUhRc0lHMWhlQ3dnYldsdUtTQjdYRzRnSUdsbUlDaDJZV3gxWlNBK0lHMWhlQ0I4ZkNCMllXeDFaU0E4SUcxcGJpa2dkR2h5YjNjZ2JtVjNJRkpoYm1kbFJYSnliM0lvSjNaaGJIVmxJR2x6SUc5MWRDQnZaaUJpYjNWdVpITW5LVnh1SUNCcFppQW9iMlptYzJWMElDc2daWGgwSUQ0Z1luVm1MbXhsYm1kMGFDa2dkR2h5YjNjZ2JtVjNJRkpoYm1kbFJYSnliM0lvSjJsdVpHVjRJRzkxZENCdlppQnlZVzVuWlNjcFhHNGdJR2xtSUNodlptWnpaWFFnUENBd0tTQjBhSEp2ZHlCdVpYY2dVbUZ1WjJWRmNuSnZjaWduYVc1a1pYZ2diM1YwSUc5bUlISmhibWRsSnlsY2JuMWNibHh1Wm5WdVkzUnBiMjRnZDNKcGRHVkdiRzloZENBb1luVm1MQ0IyWVd4MVpTd2diMlptYzJWMExDQnNhWFIwYkdWRmJtUnBZVzRzSUc1dlFYTnpaWEowS1NCN1hHNGdJR2xtSUNnaGJtOUJjM05sY25RcElIdGNiaUFnSUNCamFHVmphMGxGUlVVM05UUW9ZblZtTENCMllXeDFaU3dnYjJabWMyVjBMQ0EwTENBekxqUXdNamd5TXpRMk5qTTROVEk0T0RabEt6TTRMQ0F0TXk0ME1ESTRNak0wTmpZek9EVXlPRGcyWlNzek9DbGNiaUFnZlZ4dUlDQnBaV1ZsTnpVMExuZHlhWFJsS0dKMVppd2dkbUZzZFdVc0lHOW1abk5sZEN3Z2JHbDBkR3hsUlc1a2FXRnVMQ0F5TXl3Z05DbGNiaUFnY21WMGRYSnVJRzltWm5ObGRDQXJJRFJjYm4xY2JseHVRblZtWm1WeUxuQnliM1J2ZEhsd1pTNTNjbWwwWlVac2IyRjBURVVnUFNCbWRXNWpkR2x2YmlCM2NtbDBaVVpzYjJGMFRFVWdLSFpoYkhWbExDQnZabVp6WlhRc0lHNXZRWE56WlhKMEtTQjdYRzRnSUhKbGRIVnliaUIzY21sMFpVWnNiMkYwS0hSb2FYTXNJSFpoYkhWbExDQnZabVp6WlhRc0lIUnlkV1VzSUc1dlFYTnpaWEowS1Z4dWZWeHVYRzVDZFdabVpYSXVjSEp2ZEc5MGVYQmxMbmR5YVhSbFJteHZZWFJDUlNBOUlHWjFibU4wYVc5dUlIZHlhWFJsUm14dllYUkNSU0FvZG1Gc2RXVXNJRzltWm5ObGRDd2dibTlCYzNObGNuUXBJSHRjYmlBZ2NtVjBkWEp1SUhkeWFYUmxSbXh2WVhRb2RHaHBjeXdnZG1Gc2RXVXNJRzltWm5ObGRDd2dabUZzYzJVc0lHNXZRWE56WlhKMEtWeHVmVnh1WEc1bWRXNWpkR2x2YmlCM2NtbDBaVVJ2ZFdKc1pTQW9ZblZtTENCMllXeDFaU3dnYjJabWMyVjBMQ0JzYVhSMGJHVkZibVJwWVc0c0lHNXZRWE56WlhKMEtTQjdYRzRnSUdsbUlDZ2hibTlCYzNObGNuUXBJSHRjYmlBZ0lDQmphR1ZqYTBsRlJVVTNOVFFvWW5WbUxDQjJZV3gxWlN3Z2IyWm1jMlYwTENBNExDQXhMamM1TnpZNU16RXpORGcyTWpNeE5UZEZLek13T0N3Z0xURXVOemszTmprek1UTTBPRFl5TXpFMU4wVXJNekE0S1Z4dUlDQjlYRzRnSUdsbFpXVTNOVFF1ZDNKcGRHVW9ZblZtTENCMllXeDFaU3dnYjJabWMyVjBMQ0JzYVhSMGJHVkZibVJwWVc0c0lEVXlMQ0E0S1Z4dUlDQnlaWFIxY200Z2IyWm1jMlYwSUNzZ09GeHVmVnh1WEc1Q2RXWm1aWEl1Y0hKdmRHOTBlWEJsTG5keWFYUmxSRzkxWW14bFRFVWdQU0JtZFc1amRHbHZiaUIzY21sMFpVUnZkV0pzWlV4RklDaDJZV3gxWlN3Z2IyWm1jMlYwTENCdWIwRnpjMlZ5ZENrZ2UxeHVJQ0J5WlhSMWNtNGdkM0pwZEdWRWIzVmliR1VvZEdocGN5d2dkbUZzZFdVc0lHOW1abk5sZEN3Z2RISjFaU3dnYm05QmMzTmxjblFwWEc1OVhHNWNia0oxWm1abGNpNXdjbTkwYjNSNWNHVXVkM0pwZEdWRWIzVmliR1ZDUlNBOUlHWjFibU4wYVc5dUlIZHlhWFJsUkc5MVlteGxRa1VnS0haaGJIVmxMQ0J2Wm1aelpYUXNJRzV2UVhOelpYSjBLU0I3WEc0Z0lISmxkSFZ5YmlCM2NtbDBaVVJ2ZFdKc1pTaDBhR2x6TENCMllXeDFaU3dnYjJabWMyVjBMQ0JtWVd4elpTd2dibTlCYzNObGNuUXBYRzU5WEc1Y2JpOHZJR052Y0hrb2RHRnlaMlYwUW5WbVptVnlMQ0IwWVhKblpYUlRkR0Z5ZEQwd0xDQnpiM1Z5WTJWVGRHRnlkRDB3TENCemIzVnlZMlZGYm1ROVluVm1abVZ5TG14bGJtZDBhQ2xjYmtKMVptWmxjaTV3Y205MGIzUjVjR1V1WTI5d2VTQTlJR1oxYm1OMGFXOXVJR052Y0hrZ0tIUmhjbWRsZEN3Z2RHRnlaMlYwVTNSaGNuUXNJSE4wWVhKMExDQmxibVFwSUh0Y2JpQWdhV1lnS0NGemRHRnlkQ2tnYzNSaGNuUWdQU0F3WEc0Z0lHbG1JQ2doWlc1a0lDWW1JR1Z1WkNBaFBUMGdNQ2tnWlc1a0lEMGdkR2hwY3k1c1pXNW5kR2hjYmlBZ2FXWWdLSFJoY21kbGRGTjBZWEowSUQ0OUlIUmhjbWRsZEM1c1pXNW5kR2dwSUhSaGNtZGxkRk4wWVhKMElEMGdkR0Z5WjJWMExteGxibWQwYUZ4dUlDQnBaaUFvSVhSaGNtZGxkRk4wWVhKMEtTQjBZWEpuWlhSVGRHRnlkQ0E5SURCY2JpQWdhV1lnS0dWdVpDQStJREFnSmlZZ1pXNWtJRHdnYzNSaGNuUXBJR1Z1WkNBOUlITjBZWEowWEc1Y2JpQWdMeThnUTI5d2VTQXdJR0o1ZEdWek95QjNaU2R5WlNCa2IyNWxYRzRnSUdsbUlDaGxibVFnUFQwOUlITjBZWEowS1NCeVpYUjFjbTRnTUZ4dUlDQnBaaUFvZEdGeVoyVjBMbXhsYm1kMGFDQTlQVDBnTUNCOGZDQjBhR2x6TG14bGJtZDBhQ0E5UFQwZ01Da2djbVYwZFhKdUlEQmNibHh1SUNBdkx5QkdZWFJoYkNCbGNuSnZjaUJqYjI1a2FYUnBiMjV6WEc0Z0lHbG1JQ2gwWVhKblpYUlRkR0Z5ZENBOElEQXBJSHRjYmlBZ0lDQjBhSEp2ZHlCdVpYY2dVbUZ1WjJWRmNuSnZjaWduZEdGeVoyVjBVM1JoY25RZ2IzVjBJRzltSUdKdmRXNWtjeWNwWEc0Z0lIMWNiaUFnYVdZZ0tITjBZWEowSUR3Z01DQjhmQ0J6ZEdGeWRDQStQU0IwYUdsekxteGxibWQwYUNrZ2RHaHliM2NnYm1WM0lGSmhibWRsUlhKeWIzSW9KM052ZFhKalpWTjBZWEowSUc5MWRDQnZaaUJpYjNWdVpITW5LVnh1SUNCcFppQW9aVzVrSUR3Z01Da2dkR2h5YjNjZ2JtVjNJRkpoYm1kbFJYSnliM0lvSjNOdmRYSmpaVVZ1WkNCdmRYUWdiMllnWW05MWJtUnpKeWxjYmx4dUlDQXZMeUJCY21VZ2QyVWdiMjlpUDF4dUlDQnBaaUFvWlc1a0lENGdkR2hwY3k1c1pXNW5kR2dwSUdWdVpDQTlJSFJvYVhNdWJHVnVaM1JvWEc0Z0lHbG1JQ2gwWVhKblpYUXViR1Z1WjNSb0lDMGdkR0Z5WjJWMFUzUmhjblFnUENCbGJtUWdMU0J6ZEdGeWRDa2dlMXh1SUNBZ0lHVnVaQ0E5SUhSaGNtZGxkQzVzWlc1bmRHZ2dMU0IwWVhKblpYUlRkR0Z5ZENBcklITjBZWEowWEc0Z0lIMWNibHh1SUNCMllYSWdiR1Z1SUQwZ1pXNWtJQzBnYzNSaGNuUmNiaUFnZG1GeUlHbGNibHh1SUNCcFppQW9kR2hwY3lBOVBUMGdkR0Z5WjJWMElDWW1JSE4wWVhKMElEd2dkR0Z5WjJWMFUzUmhjblFnSmlZZ2RHRnlaMlYwVTNSaGNuUWdQQ0JsYm1RcElIdGNiaUFnSUNBdkx5QmtaWE5qWlc1a2FXNW5JR052Y0hrZ1puSnZiU0JsYm1SY2JpQWdJQ0JtYjNJZ0tHa2dQU0JzWlc0Z0xTQXhPeUJwSUQ0OUlEQTdJR2t0TFNrZ2UxeHVJQ0FnSUNBZ2RHRnlaMlYwVzJrZ0t5QjBZWEpuWlhSVGRHRnlkRjBnUFNCMGFHbHpXMmtnS3lCemRHRnlkRjFjYmlBZ0lDQjlYRzRnSUgwZ1pXeHpaU0JwWmlBb2JHVnVJRHdnTVRBd01DQjhmQ0FoUW5WbVptVnlMbFJaVUVWRVgwRlNVa0ZaWDFOVlVGQlBVbFFwSUh0Y2JpQWdJQ0F2THlCaGMyTmxibVJwYm1jZ1kyOXdlU0JtY205dElITjBZWEowWEc0Z0lDQWdabTl5SUNocElEMGdNRHNnYVNBOElHeGxianNnYVNzcktTQjdYRzRnSUNBZ0lDQjBZWEpuWlhSYmFTQXJJSFJoY21kbGRGTjBZWEowWFNBOUlIUm9hWE5iYVNBcklITjBZWEowWFZ4dUlDQWdJSDFjYmlBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0IwWVhKblpYUXVYM05sZENoMGFHbHpMbk4xWW1GeWNtRjVLSE4wWVhKMExDQnpkR0Z5ZENBcklHeGxiaWtzSUhSaGNtZGxkRk4wWVhKMEtWeHVJQ0I5WEc1Y2JpQWdjbVYwZFhKdUlHeGxibHh1ZlZ4dVhHNHZMeUJtYVd4c0tIWmhiSFZsTENCemRHRnlkRDB3TENCbGJtUTlZblZtWm1WeUxteGxibWQwYUNsY2JrSjFabVpsY2k1d2NtOTBiM1I1Y0dVdVptbHNiQ0E5SUdaMWJtTjBhVzl1SUdacGJHd2dLSFpoYkhWbExDQnpkR0Z5ZEN3Z1pXNWtLU0I3WEc0Z0lHbG1JQ2doZG1Gc2RXVXBJSFpoYkhWbElEMGdNRnh1SUNCcFppQW9JWE4wWVhKMEtTQnpkR0Z5ZENBOUlEQmNiaUFnYVdZZ0tDRmxibVFwSUdWdVpDQTlJSFJvYVhNdWJHVnVaM1JvWEc1Y2JpQWdhV1lnS0dWdVpDQThJSE4wWVhKMEtTQjBhSEp2ZHlCdVpYY2dVbUZ1WjJWRmNuSnZjaWduWlc1a0lEd2djM1JoY25RbktWeHVYRzRnSUM4dklFWnBiR3dnTUNCaWVYUmxjenNnZDJVbmNtVWdaRzl1WlZ4dUlDQnBaaUFvWlc1a0lEMDlQU0J6ZEdGeWRDa2djbVYwZFhKdVhHNGdJR2xtSUNoMGFHbHpMbXhsYm1kMGFDQTlQVDBnTUNrZ2NtVjBkWEp1WEc1Y2JpQWdhV1lnS0hOMFlYSjBJRHdnTUNCOGZDQnpkR0Z5ZENBK1BTQjBhR2x6TG14bGJtZDBhQ2tnZEdoeWIzY2dibVYzSUZKaGJtZGxSWEp5YjNJb0ozTjBZWEowSUc5MWRDQnZaaUJpYjNWdVpITW5LVnh1SUNCcFppQW9aVzVrSUR3Z01DQjhmQ0JsYm1RZ1BpQjBhR2x6TG14bGJtZDBhQ2tnZEdoeWIzY2dibVYzSUZKaGJtZGxSWEp5YjNJb0oyVnVaQ0J2ZFhRZ2IyWWdZbTkxYm1Sekp5bGNibHh1SUNCMllYSWdhVnh1SUNCcFppQW9kSGx3Wlc5bUlIWmhiSFZsSUQwOVBTQW5iblZ0WW1WeUp5a2dlMXh1SUNBZ0lHWnZjaUFvYVNBOUlITjBZWEowT3lCcElEd2daVzVrT3lCcEt5c3BJSHRjYmlBZ0lDQWdJSFJvYVhOYmFWMGdQU0IyWVd4MVpWeHVJQ0FnSUgxY2JpQWdmU0JsYkhObElIdGNiaUFnSUNCMllYSWdZbmwwWlhNZ1BTQjFkR1k0Vkc5Q2VYUmxjeWgyWVd4MVpTNTBiMU4wY21sdVp5Z3BLVnh1SUNBZ0lIWmhjaUJzWlc0Z1BTQmllWFJsY3k1c1pXNW5kR2hjYmlBZ0lDQm1iM0lnS0drZ1BTQnpkR0Z5ZERzZ2FTQThJR1Z1WkRzZ2FTc3JLU0I3WEc0Z0lDQWdJQ0IwYUdselcybGRJRDBnWW5sMFpYTmJhU0FsSUd4bGJsMWNiaUFnSUNCOVhHNGdJSDFjYmx4dUlDQnlaWFIxY200Z2RHaHBjMXh1ZlZ4dVhHNHZLaXBjYmlBcUlFTnlaV0YwWlhNZ1lTQnVaWGNnWUVGeWNtRjVRblZtWm1WeVlDQjNhWFJvSUhSb1pTQXFZMjl3YVdWa0tpQnRaVzF2Y25rZ2IyWWdkR2hsSUdKMVptWmxjaUJwYm5OMFlXNWpaUzVjYmlBcUlFRmtaR1ZrSUdsdUlFNXZaR1VnTUM0eE1pNGdUMjVzZVNCaGRtRnBiR0ZpYkdVZ2FXNGdZbkp2ZDNObGNuTWdkR2hoZENCemRYQndiM0owSUVGeWNtRjVRblZtWm1WeUxseHVJQ292WEc1Q2RXWm1aWEl1Y0hKdmRHOTBlWEJsTG5SdlFYSnlZWGxDZFdabVpYSWdQU0JtZFc1amRHbHZiaUIwYjBGeWNtRjVRblZtWm1WeUlDZ3BJSHRjYmlBZ2FXWWdLSFI1Y0dWdlppQlZhVzUwT0VGeWNtRjVJQ0U5UFNBbmRXNWtaV1pwYm1Wa0p5a2dlMXh1SUNBZ0lHbG1JQ2hDZFdabVpYSXVWRmxRUlVSZlFWSlNRVmxmVTFWUVVFOVNWQ2tnZTF4dUlDQWdJQ0FnY21WMGRYSnVJQ2h1WlhjZ1FuVm1abVZ5S0hSb2FYTXBLUzVpZFdabVpYSmNiaUFnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnZG1GeUlHSjFaaUE5SUc1bGR5QlZhVzUwT0VGeWNtRjVLSFJvYVhNdWJHVnVaM1JvS1Z4dUlDQWdJQ0FnWm05eUlDaDJZWElnYVNBOUlEQXNJR3hsYmlBOUlHSjFaaTVzWlc1bmRHZzdJR2tnUENCc1pXNDdJR2tnS3owZ01Ta2dlMXh1SUNBZ0lDQWdJQ0JpZFdaYmFWMGdQU0IwYUdselcybGRYRzRnSUNBZ0lDQjlYRzRnSUNBZ0lDQnlaWFIxY200Z1luVm1MbUoxWm1abGNseHVJQ0FnSUgxY2JpQWdmU0JsYkhObElIdGNiaUFnSUNCMGFISnZkeUJ1WlhjZ1ZIbHdaVVZ5Y205eUtDZENkV1ptWlhJdWRHOUJjbkpoZVVKMVptWmxjaUJ1YjNRZ2MzVndjRzl5ZEdWa0lHbHVJSFJvYVhNZ1luSnZkM05sY2ljcFhHNGdJSDFjYm4xY2JseHVMeThnU0VWTVVFVlNJRVpWVGtOVVNVOU9VMXh1THk4Z1BUMDlQVDA5UFQwOVBUMDlQVDA5UFZ4dVhHNTJZWElnUWxBZ1BTQkNkV1ptWlhJdWNISnZkRzkwZVhCbFhHNWNiaThxS2x4dUlDb2dRWFZuYldWdWRDQmhJRlZwYm5RNFFYSnlZWGtnS21sdWMzUmhibU5sS2lBb2JtOTBJSFJvWlNCVmFXNTBPRUZ5Y21GNUlHTnNZWE56SVNrZ2QybDBhQ0JDZFdabVpYSWdiV1YwYUc5a2MxeHVJQ292WEc1Q2RXWm1aWEl1WDJGMVoyMWxiblFnUFNCbWRXNWpkR2x2YmlCZllYVm5iV1Z1ZENBb1lYSnlLU0I3WEc0Z0lHRnljaTVqYjI1emRISjFZM1J2Y2lBOUlFSjFabVpsY2x4dUlDQmhjbkl1WDJselFuVm1abVZ5SUQwZ2RISjFaVnh1WEc0Z0lDOHZJSE5oZG1VZ2NtVm1aWEpsYm1ObElIUnZJRzl5YVdkcGJtRnNJRlZwYm5RNFFYSnlZWGtnYzJWMElHMWxkR2h2WkNCaVpXWnZjbVVnYjNabGNuZHlhWFJwYm1kY2JpQWdZWEp5TGw5elpYUWdQU0JoY25JdWMyVjBYRzVjYmlBZ0x5OGdaR1Z3Y21WallYUmxaRnh1SUNCaGNuSXVaMlYwSUQwZ1FsQXVaMlYwWEc0Z0lHRnljaTV6WlhRZ1BTQkNVQzV6WlhSY2JseHVJQ0JoY25JdWQzSnBkR1VnUFNCQ1VDNTNjbWwwWlZ4dUlDQmhjbkl1ZEc5VGRISnBibWNnUFNCQ1VDNTBiMU4wY21sdVoxeHVJQ0JoY25JdWRHOU1iMk5oYkdWVGRISnBibWNnUFNCQ1VDNTBiMU4wY21sdVoxeHVJQ0JoY25JdWRHOUtVMDlPSUQwZ1FsQXVkRzlLVTA5T1hHNGdJR0Z5Y2k1bGNYVmhiSE1nUFNCQ1VDNWxjWFZoYkhOY2JpQWdZWEp5TG1OdmJYQmhjbVVnUFNCQ1VDNWpiMjF3WVhKbFhHNGdJR0Z5Y2k1cGJtUmxlRTltSUQwZ1FsQXVhVzVrWlhoUFpseHVJQ0JoY25JdVkyOXdlU0E5SUVKUUxtTnZjSGxjYmlBZ1lYSnlMbk5zYVdObElEMGdRbEF1YzJ4cFkyVmNiaUFnWVhKeUxuSmxZV1JWU1c1MFRFVWdQU0JDVUM1eVpXRmtWVWx1ZEV4RlhHNGdJR0Z5Y2k1eVpXRmtWVWx1ZEVKRklEMGdRbEF1Y21WaFpGVkpiblJDUlZ4dUlDQmhjbkl1Y21WaFpGVkpiblE0SUQwZ1FsQXVjbVZoWkZWSmJuUTRYRzRnSUdGeWNpNXlaV0ZrVlVsdWRERTJURVVnUFNCQ1VDNXlaV0ZrVlVsdWRERTJURVZjYmlBZ1lYSnlMbkpsWVdSVlNXNTBNVFpDUlNBOUlFSlFMbkpsWVdSVlNXNTBNVFpDUlZ4dUlDQmhjbkl1Y21WaFpGVkpiblF6TWt4RklEMGdRbEF1Y21WaFpGVkpiblF6TWt4RlhHNGdJR0Z5Y2k1eVpXRmtWVWx1ZERNeVFrVWdQU0JDVUM1eVpXRmtWVWx1ZERNeVFrVmNiaUFnWVhKeUxuSmxZV1JKYm5STVJTQTlJRUpRTG5KbFlXUkpiblJNUlZ4dUlDQmhjbkl1Y21WaFpFbHVkRUpGSUQwZ1FsQXVjbVZoWkVsdWRFSkZYRzRnSUdGeWNpNXlaV0ZrU1c1ME9DQTlJRUpRTG5KbFlXUkpiblE0WEc0Z0lHRnljaTV5WldGa1NXNTBNVFpNUlNBOUlFSlFMbkpsWVdSSmJuUXhOa3hGWEc0Z0lHRnljaTV5WldGa1NXNTBNVFpDUlNBOUlFSlFMbkpsWVdSSmJuUXhOa0pGWEc0Z0lHRnljaTV5WldGa1NXNTBNekpNUlNBOUlFSlFMbkpsWVdSSmJuUXpNa3hGWEc0Z0lHRnljaTV5WldGa1NXNTBNekpDUlNBOUlFSlFMbkpsWVdSSmJuUXpNa0pGWEc0Z0lHRnljaTV5WldGa1JteHZZWFJNUlNBOUlFSlFMbkpsWVdSR2JHOWhkRXhGWEc0Z0lHRnljaTV5WldGa1JteHZZWFJDUlNBOUlFSlFMbkpsWVdSR2JHOWhkRUpGWEc0Z0lHRnljaTV5WldGa1JHOTFZbXhsVEVVZ1BTQkNVQzV5WldGa1JHOTFZbXhsVEVWY2JpQWdZWEp5TG5KbFlXUkViM1ZpYkdWQ1JTQTlJRUpRTG5KbFlXUkViM1ZpYkdWQ1JWeHVJQ0JoY25JdWQzSnBkR1ZWU1c1ME9DQTlJRUpRTG5keWFYUmxWVWx1ZERoY2JpQWdZWEp5TG5keWFYUmxWVWx1ZEV4RklEMGdRbEF1ZDNKcGRHVlZTVzUwVEVWY2JpQWdZWEp5TG5keWFYUmxWVWx1ZEVKRklEMGdRbEF1ZDNKcGRHVlZTVzUwUWtWY2JpQWdZWEp5TG5keWFYUmxWVWx1ZERFMlRFVWdQU0JDVUM1M2NtbDBaVlZKYm5ReE5reEZYRzRnSUdGeWNpNTNjbWwwWlZWSmJuUXhOa0pGSUQwZ1FsQXVkM0pwZEdWVlNXNTBNVFpDUlZ4dUlDQmhjbkl1ZDNKcGRHVlZTVzUwTXpKTVJTQTlJRUpRTG5keWFYUmxWVWx1ZERNeVRFVmNiaUFnWVhKeUxuZHlhWFJsVlVsdWRETXlRa1VnUFNCQ1VDNTNjbWwwWlZWSmJuUXpNa0pGWEc0Z0lHRnljaTUzY21sMFpVbHVkRXhGSUQwZ1FsQXVkM0pwZEdWSmJuUk1SVnh1SUNCaGNuSXVkM0pwZEdWSmJuUkNSU0E5SUVKUUxuZHlhWFJsU1c1MFFrVmNiaUFnWVhKeUxuZHlhWFJsU1c1ME9DQTlJRUpRTG5keWFYUmxTVzUwT0Z4dUlDQmhjbkl1ZDNKcGRHVkpiblF4Tmt4RklEMGdRbEF1ZDNKcGRHVkpiblF4Tmt4RlhHNGdJR0Z5Y2k1M2NtbDBaVWx1ZERFMlFrVWdQU0JDVUM1M2NtbDBaVWx1ZERFMlFrVmNiaUFnWVhKeUxuZHlhWFJsU1c1ME16Sk1SU0E5SUVKUUxuZHlhWFJsU1c1ME16Sk1SVnh1SUNCaGNuSXVkM0pwZEdWSmJuUXpNa0pGSUQwZ1FsQXVkM0pwZEdWSmJuUXpNa0pGWEc0Z0lHRnljaTUzY21sMFpVWnNiMkYwVEVVZ1BTQkNVQzUzY21sMFpVWnNiMkYwVEVWY2JpQWdZWEp5TG5keWFYUmxSbXh2WVhSQ1JTQTlJRUpRTG5keWFYUmxSbXh2WVhSQ1JWeHVJQ0JoY25JdWQzSnBkR1ZFYjNWaWJHVk1SU0E5SUVKUUxuZHlhWFJsUkc5MVlteGxURVZjYmlBZ1lYSnlMbmR5YVhSbFJHOTFZbXhsUWtVZ1BTQkNVQzUzY21sMFpVUnZkV0pzWlVKRlhHNGdJR0Z5Y2k1bWFXeHNJRDBnUWxBdVptbHNiRnh1SUNCaGNuSXVhVzV6Y0dWamRDQTlJRUpRTG1sdWMzQmxZM1JjYmlBZ1lYSnlMblJ2UVhKeVlYbENkV1ptWlhJZ1BTQkNVQzUwYjBGeWNtRjVRblZtWm1WeVhHNWNiaUFnY21WMGRYSnVJR0Z5Y2x4dWZWeHVYRzUyWVhJZ1NVNVdRVXhKUkY5Q1FWTkZOalJmVWtVZ1BTQXZXMTRyWEZ3dk1DMDVRUzFhWVMxNkxWOWRMMmRjYmx4dVpuVnVZM1JwYjI0Z1ltRnpaVFkwWTJ4bFlXNGdLSE4wY2lrZ2UxeHVJQ0F2THlCT2IyUmxJSE4wY21sd2N5QnZkWFFnYVc1MllXeHBaQ0JqYUdGeVlXTjBaWEp6SUd4cGEyVWdYRnh1SUdGdVpDQmNYSFFnWm5KdmJTQjBhR1VnYzNSeWFXNW5MQ0JpWVhObE5qUXRhbk1nWkc5bGN5QnViM1JjYmlBZ2MzUnlJRDBnYzNSeWFXNW5kSEpwYlNoemRISXBMbkpsY0d4aFkyVW9TVTVXUVV4SlJGOUNRVk5GTmpSZlVrVXNJQ2NuS1Z4dUlDQXZMeUJPYjJSbElHTnZiblpsY25SeklITjBjbWx1WjNNZ2QybDBhQ0JzWlc1bmRHZ2dQQ0F5SUhSdklDY25YRzRnSUdsbUlDaHpkSEl1YkdWdVozUm9JRHdnTWlrZ2NtVjBkWEp1SUNjblhHNGdJQzh2SUU1dlpHVWdZV3hzYjNkeklHWnZjaUJ1YjI0dGNHRmtaR1ZrSUdKaGMyVTJOQ0J6ZEhKcGJtZHpJQ2h0YVhOemFXNW5JSFJ5WVdsc2FXNW5JRDA5UFNrc0lHSmhjMlUyTkMxcWN5QmtiMlZ6SUc1dmRGeHVJQ0IzYUdsc1pTQW9jM1J5TG14bGJtZDBhQ0FsSURRZ0lUMDlJREFwSUh0Y2JpQWdJQ0J6ZEhJZ1BTQnpkSElnS3lBblBTZGNiaUFnZlZ4dUlDQnlaWFIxY200Z2MzUnlYRzU5WEc1Y2JtWjFibU4wYVc5dUlITjBjbWx1WjNSeWFXMGdLSE4wY2lrZ2UxeHVJQ0JwWmlBb2MzUnlMblJ5YVcwcElISmxkSFZ5YmlCemRISXVkSEpwYlNncFhHNGdJSEpsZEhWeWJpQnpkSEl1Y21Wd2JHRmpaU2d2WGx4Y2N5dDhYRnh6S3lRdlp5d2dKeWNwWEc1OVhHNWNibVoxYm1OMGFXOXVJSFJ2U0dWNElDaHVLU0I3WEc0Z0lHbG1JQ2h1SUR3Z01UWXBJSEpsZEhWeWJpQW5NQ2NnS3lCdUxuUnZVM1J5YVc1bktERTJLVnh1SUNCeVpYUjFjbTRnYmk1MGIxTjBjbWx1WnlneE5pbGNibjFjYmx4dVpuVnVZM1JwYjI0Z2RYUm1PRlJ2UW5sMFpYTWdLSE4wY21sdVp5d2dkVzVwZEhNcElIdGNiaUFnZFc1cGRITWdQU0IxYm1sMGN5QjhmQ0JKYm1acGJtbDBlVnh1SUNCMllYSWdZMjlrWlZCdmFXNTBYRzRnSUhaaGNpQnNaVzVuZEdnZ1BTQnpkSEpwYm1jdWJHVnVaM1JvWEc0Z0lIWmhjaUJzWldGa1UzVnljbTluWVhSbElEMGdiblZzYkZ4dUlDQjJZWElnWW5sMFpYTWdQU0JiWFZ4dVhHNGdJR1p2Y2lBb2RtRnlJR2tnUFNBd095QnBJRHdnYkdWdVozUm9PeUJwS3lzcElIdGNiaUFnSUNCamIyUmxVRzlwYm5RZ1BTQnpkSEpwYm1jdVkyaGhja052WkdWQmRDaHBLVnh1WEc0Z0lDQWdMeThnYVhNZ2MzVnljbTluWVhSbElHTnZiWEJ2Ym1WdWRGeHVJQ0FnSUdsbUlDaGpiMlJsVUc5cGJuUWdQaUF3ZUVRM1JrWWdKaVlnWTI5a1pWQnZhVzUwSUR3Z01IaEZNREF3S1NCN1hHNGdJQ0FnSUNBdkx5QnNZWE4wSUdOb1lYSWdkMkZ6SUdFZ2JHVmhaRnh1SUNBZ0lDQWdhV1lnS0NGc1pXRmtVM1Z5Y205bllYUmxLU0I3WEc0Z0lDQWdJQ0FnSUM4dklHNXZJR3hsWVdRZ2VXVjBYRzRnSUNBZ0lDQWdJR2xtSUNoamIyUmxVRzlwYm5RZ1BpQXdlRVJDUmtZcElIdGNiaUFnSUNBZ0lDQWdJQ0F2THlCMWJtVjRjR1ZqZEdWa0lIUnlZV2xzWEc0Z0lDQWdJQ0FnSUNBZ2FXWWdLQ2gxYm1sMGN5QXRQU0F6S1NBK0lDMHhLU0JpZVhSbGN5NXdkWE5vS0RCNFJVWXNJREI0UWtZc0lEQjRRa1FwWEc0Z0lDQWdJQ0FnSUNBZ1kyOXVkR2x1ZFdWY2JpQWdJQ0FnSUNBZ2ZTQmxiSE5sSUdsbUlDaHBJQ3NnTVNBOVBUMGdiR1Z1WjNSb0tTQjdYRzRnSUNBZ0lDQWdJQ0FnTHk4Z2RXNXdZV2x5WldRZ2JHVmhaRnh1SUNBZ0lDQWdJQ0FnSUdsbUlDZ29kVzVwZEhNZ0xUMGdNeWtnUGlBdE1Ta2dZbmwwWlhNdWNIVnphQ2d3ZUVWR0xDQXdlRUpHTENBd2VFSkVLVnh1SUNBZ0lDQWdJQ0FnSUdOdmJuUnBiblZsWEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQXZMeUIyWVd4cFpDQnNaV0ZrWEc0Z0lDQWdJQ0FnSUd4bFlXUlRkWEp5YjJkaGRHVWdQU0JqYjJSbFVHOXBiblJjYmx4dUlDQWdJQ0FnSUNCamIyNTBhVzUxWlZ4dUlDQWdJQ0FnZlZ4dVhHNGdJQ0FnSUNBdkx5QXlJR3hsWVdSeklHbHVJR0VnY205M1hHNGdJQ0FnSUNCcFppQW9ZMjlrWlZCdmFXNTBJRHdnTUhoRVF6QXdLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDZ29kVzVwZEhNZ0xUMGdNeWtnUGlBdE1Ta2dZbmwwWlhNdWNIVnphQ2d3ZUVWR0xDQXdlRUpHTENBd2VFSkVLVnh1SUNBZ0lDQWdJQ0JzWldGa1UzVnljbTluWVhSbElEMGdZMjlrWlZCdmFXNTBYRzRnSUNBZ0lDQWdJR052Ym5ScGJuVmxYRzRnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQzh2SUhaaGJHbGtJSE4xY25KdloyRjBaU0J3WVdseVhHNGdJQ0FnSUNCamIyUmxVRzlwYm5RZ1BTQW9iR1ZoWkZOMWNuSnZaMkYwWlNBdElEQjRSRGd3TUNBOFBDQXhNQ0I4SUdOdlpHVlFiMmx1ZENBdElEQjRSRU13TUNrZ0t5QXdlREV3TURBd1hHNGdJQ0FnZlNCbGJITmxJR2xtSUNoc1pXRmtVM1Z5Y205bllYUmxLU0I3WEc0Z0lDQWdJQ0F2THlCMllXeHBaQ0JpYlhBZ1kyaGhjaXdnWW5WMElHeGhjM1FnWTJoaGNpQjNZWE1nWVNCc1pXRmtYRzRnSUNBZ0lDQnBaaUFvS0hWdWFYUnpJQzA5SURNcElENGdMVEVwSUdKNWRHVnpMbkIxYzJnb01IaEZSaXdnTUhoQ1Jpd2dNSGhDUkNsY2JpQWdJQ0I5WEc1Y2JpQWdJQ0JzWldGa1UzVnljbTluWVhSbElEMGdiblZzYkZ4dVhHNGdJQ0FnTHk4Z1pXNWpiMlJsSUhWMFpqaGNiaUFnSUNCcFppQW9ZMjlrWlZCdmFXNTBJRHdnTUhnNE1Da2dlMXh1SUNBZ0lDQWdhV1lnS0NoMWJtbDBjeUF0UFNBeEtTQThJREFwSUdKeVpXRnJYRzRnSUNBZ0lDQmllWFJsY3k1d2RYTm9LR052WkdWUWIybHVkQ2xjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLR052WkdWUWIybHVkQ0E4SURCNE9EQXdLU0I3WEc0Z0lDQWdJQ0JwWmlBb0tIVnVhWFJ6SUMwOUlESXBJRHdnTUNrZ1luSmxZV3RjYmlBZ0lDQWdJR0o1ZEdWekxuQjFjMmdvWEc0Z0lDQWdJQ0FnSUdOdlpHVlFiMmx1ZENBK1BpQXdlRFlnZkNBd2VFTXdMRnh1SUNBZ0lDQWdJQ0JqYjJSbFVHOXBiblFnSmlBd2VETkdJSHdnTUhnNE1GeHVJQ0FnSUNBZ0tWeHVJQ0FnSUgwZ1pXeHpaU0JwWmlBb1kyOWtaVkJ2YVc1MElEd2dNSGd4TURBd01Da2dlMXh1SUNBZ0lDQWdhV1lnS0NoMWJtbDBjeUF0UFNBektTQThJREFwSUdKeVpXRnJYRzRnSUNBZ0lDQmllWFJsY3k1d2RYTm9LRnh1SUNBZ0lDQWdJQ0JqYjJSbFVHOXBiblFnUGo0Z01IaERJSHdnTUhoRk1DeGNiaUFnSUNBZ0lDQWdZMjlrWlZCdmFXNTBJRDQrSURCNE5pQW1JREI0TTBZZ2ZDQXdlRGd3TEZ4dUlDQWdJQ0FnSUNCamIyUmxVRzlwYm5RZ0ppQXdlRE5HSUh3Z01IZzRNRnh1SUNBZ0lDQWdLVnh1SUNBZ0lIMGdaV3h6WlNCcFppQW9ZMjlrWlZCdmFXNTBJRHdnTUhneE1UQXdNREFwSUh0Y2JpQWdJQ0FnSUdsbUlDZ29kVzVwZEhNZ0xUMGdOQ2tnUENBd0tTQmljbVZoYTF4dUlDQWdJQ0FnWW5sMFpYTXVjSFZ6YUNoY2JpQWdJQ0FnSUNBZ1kyOWtaVkJ2YVc1MElENCtJREI0TVRJZ2ZDQXdlRVl3TEZ4dUlDQWdJQ0FnSUNCamIyUmxVRzlwYm5RZ1BqNGdNSGhESUNZZ01IZ3pSaUI4SURCNE9EQXNYRzRnSUNBZ0lDQWdJR052WkdWUWIybHVkQ0ErUGlBd2VEWWdKaUF3ZUROR0lId2dNSGc0TUN4Y2JpQWdJQ0FnSUNBZ1kyOWtaVkJ2YVc1MElDWWdNSGd6UmlCOElEQjRPREJjYmlBZ0lDQWdJQ2xjYmlBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0NkSmJuWmhiR2xrSUdOdlpHVWdjRzlwYm5RbktWeHVJQ0FnSUgxY2JpQWdmVnh1WEc0Z0lISmxkSFZ5YmlCaWVYUmxjMXh1ZlZ4dVhHNW1kVzVqZEdsdmJpQmhjMk5wYVZSdlFubDBaWE1nS0hOMGNpa2dlMXh1SUNCMllYSWdZbmwwWlVGeWNtRjVJRDBnVzExY2JpQWdabTl5SUNoMllYSWdhU0E5SURBN0lHa2dQQ0J6ZEhJdWJHVnVaM1JvT3lCcEt5c3BJSHRjYmlBZ0lDQXZMeUJPYjJSbEozTWdZMjlrWlNCelpXVnRjeUIwYnlCaVpTQmtiMmx1WnlCMGFHbHpJR0Z1WkNCdWIzUWdKaUF3ZURkR0xpNWNiaUFnSUNCaWVYUmxRWEp5WVhrdWNIVnphQ2h6ZEhJdVkyaGhja052WkdWQmRDaHBLU0FtSURCNFJrWXBYRzRnSUgxY2JpQWdjbVYwZFhKdUlHSjVkR1ZCY25KaGVWeHVmVnh1WEc1bWRXNWpkR2x2YmlCMWRHWXhObXhsVkc5Q2VYUmxjeUFvYzNSeUxDQjFibWwwY3lrZ2UxeHVJQ0IyWVhJZ1l5d2dhR2tzSUd4dlhHNGdJSFpoY2lCaWVYUmxRWEp5WVhrZ1BTQmJYVnh1SUNCbWIzSWdLSFpoY2lCcElEMGdNRHNnYVNBOElITjBjaTVzWlc1bmRHZzdJR2tyS3lrZ2UxeHVJQ0FnSUdsbUlDZ29kVzVwZEhNZ0xUMGdNaWtnUENBd0tTQmljbVZoYTF4dVhHNGdJQ0FnWXlBOUlITjBjaTVqYUdGeVEyOWtaVUYwS0drcFhHNGdJQ0FnYUdrZ1BTQmpJRDQrSURoY2JpQWdJQ0JzYnlBOUlHTWdKU0F5TlRaY2JpQWdJQ0JpZVhSbFFYSnlZWGt1Y0hWemFDaHNieWxjYmlBZ0lDQmllWFJsUVhKeVlYa3VjSFZ6YUNob2FTbGNiaUFnZlZ4dVhHNGdJSEpsZEhWeWJpQmllWFJsUVhKeVlYbGNibjFjYmx4dVpuVnVZM1JwYjI0Z1ltRnpaVFkwVkc5Q2VYUmxjeUFvYzNSeUtTQjdYRzRnSUhKbGRIVnliaUJpWVhObE5qUXVkRzlDZVhSbFFYSnlZWGtvWW1GelpUWTBZMnhsWVc0b2MzUnlLU2xjYm4xY2JseHVablZ1WTNScGIyNGdZbXhwZEVKMVptWmxjaUFvYzNKakxDQmtjM1FzSUc5bVpuTmxkQ3dnYkdWdVozUm9LU0I3WEc0Z0lHWnZjaUFvZG1GeUlHa2dQU0F3T3lCcElEd2diR1Z1WjNSb095QnBLeXNwSUh0Y2JpQWdJQ0JwWmlBb0tHa2dLeUJ2Wm1aelpYUWdQajBnWkhOMExteGxibWQwYUNrZ2ZId2dLR2tnUGowZ2MzSmpMbXhsYm1kMGFDa3BJR0p5WldGclhHNGdJQ0FnWkhOMFcya2dLeUJ2Wm1aelpYUmRJRDBnYzNKalcybGRYRzRnSUgxY2JpQWdjbVYwZFhKdUlHbGNibjFjYmlKZGZRPT0iLCJ2YXIgbG9va3VwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuICB2YXIgQXJyID0gKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJylcbiAgICA/IFVpbnQ4QXJyYXlcbiAgICA6IEFycmF5XG5cblx0dmFyIFBMVVMgICA9ICcrJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSCAgPSAnLycuY2hhckNvZGVBdCgwKVxuXHR2YXIgTlVNQkVSID0gJzAnLmNoYXJDb2RlQXQoMClcblx0dmFyIExPV0VSICA9ICdhJy5jaGFyQ29kZUF0KDApXG5cdHZhciBVUFBFUiAgPSAnQScuY2hhckNvZGVBdCgwKVxuXHR2YXIgUExVU19VUkxfU0FGRSA9ICctJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSF9VUkxfU0FGRSA9ICdfJy5jaGFyQ29kZUF0KDApXG5cblx0ZnVuY3Rpb24gZGVjb2RlIChlbHQpIHtcblx0XHR2YXIgY29kZSA9IGVsdC5jaGFyQ29kZUF0KDApXG5cdFx0aWYgKGNvZGUgPT09IFBMVVMgfHxcblx0XHQgICAgY29kZSA9PT0gUExVU19VUkxfU0FGRSlcblx0XHRcdHJldHVybiA2MiAvLyAnKydcblx0XHRpZiAoY29kZSA9PT0gU0xBU0ggfHxcblx0XHQgICAgY29kZSA9PT0gU0xBU0hfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjMgLy8gJy8nXG5cdFx0aWYgKGNvZGUgPCBOVU1CRVIpXG5cdFx0XHRyZXR1cm4gLTEgLy9ubyBtYXRjaFxuXHRcdGlmIChjb2RlIDwgTlVNQkVSICsgMTApXG5cdFx0XHRyZXR1cm4gY29kZSAtIE5VTUJFUiArIDI2ICsgMjZcblx0XHRpZiAoY29kZSA8IFVQUEVSICsgMjYpXG5cdFx0XHRyZXR1cm4gY29kZSAtIFVQUEVSXG5cdFx0aWYgKGNvZGUgPCBMT1dFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBMT1dFUiArIDI2XG5cdH1cblxuXHRmdW5jdGlvbiBiNjRUb0J5dGVBcnJheSAoYjY0KSB7XG5cdFx0dmFyIGksIGosIGwsIHRtcCwgcGxhY2VIb2xkZXJzLCBhcnJcblxuXHRcdGlmIChiNjQubGVuZ3RoICUgNCA+IDApIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG5cdFx0fVxuXG5cdFx0Ly8gdGhlIG51bWJlciBvZiBlcXVhbCBzaWducyAocGxhY2UgaG9sZGVycylcblx0XHQvLyBpZiB0aGVyZSBhcmUgdHdvIHBsYWNlaG9sZGVycywgdGhhbiB0aGUgdHdvIGNoYXJhY3RlcnMgYmVmb3JlIGl0XG5cdFx0Ly8gcmVwcmVzZW50IG9uZSBieXRlXG5cdFx0Ly8gaWYgdGhlcmUgaXMgb25seSBvbmUsIHRoZW4gdGhlIHRocmVlIGNoYXJhY3RlcnMgYmVmb3JlIGl0IHJlcHJlc2VudCAyIGJ5dGVzXG5cdFx0Ly8gdGhpcyBpcyBqdXN0IGEgY2hlYXAgaGFjayB0byBub3QgZG8gaW5kZXhPZiB0d2ljZVxuXHRcdHZhciBsZW4gPSBiNjQubGVuZ3RoXG5cdFx0cGxhY2VIb2xkZXJzID0gJz0nID09PSBiNjQuY2hhckF0KGxlbiAtIDIpID8gMiA6ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAxKSA/IDEgOiAwXG5cblx0XHQvLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcblx0XHRhcnIgPSBuZXcgQXJyKGI2NC5sZW5ndGggKiAzIC8gNCAtIHBsYWNlSG9sZGVycylcblxuXHRcdC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcblx0XHRsID0gcGxhY2VIb2xkZXJzID4gMCA/IGI2NC5sZW5ndGggLSA0IDogYjY0Lmxlbmd0aFxuXG5cdFx0dmFyIEwgPSAwXG5cblx0XHRmdW5jdGlvbiBwdXNoICh2KSB7XG5cdFx0XHRhcnJbTCsrXSA9IHZcblx0XHR9XG5cblx0XHRmb3IgKGkgPSAwLCBqID0gMDsgaSA8IGw7IGkgKz0gNCwgaiArPSAzKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDE4KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDEyKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpIDw8IDYpIHwgZGVjb2RlKGI2NC5jaGFyQXQoaSArIDMpKVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwMDApID4+IDE2KVxuXHRcdFx0cHVzaCgodG1wICYgMHhGRjAwKSA+PiA4KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA+PiA0KVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH0gZWxzZSBpZiAocGxhY2VIb2xkZXJzID09PSAxKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDEwKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpIDw8IDQpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAyKSkgPj4gMilcblx0XHRcdHB1c2goKHRtcCA+PiA4KSAmIDB4RkYpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFyclxuXHR9XG5cblx0ZnVuY3Rpb24gdWludDhUb0Jhc2U2NCAodWludDgpIHtcblx0XHR2YXIgaSxcblx0XHRcdGV4dHJhQnl0ZXMgPSB1aW50OC5sZW5ndGggJSAzLCAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuXHRcdFx0b3V0cHV0ID0gXCJcIixcblx0XHRcdHRlbXAsIGxlbmd0aFxuXG5cdFx0ZnVuY3Rpb24gZW5jb2RlIChudW0pIHtcblx0XHRcdHJldHVybiBsb29rdXAuY2hhckF0KG51bSlcblx0XHR9XG5cblx0XHRmdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuXHRcdFx0cmV0dXJuIGVuY29kZShudW0gPj4gMTggJiAweDNGKSArIGVuY29kZShudW0gPj4gMTIgJiAweDNGKSArIGVuY29kZShudW0gPj4gNiAmIDB4M0YpICsgZW5jb2RlKG51bSAmIDB4M0YpXG5cdFx0fVxuXG5cdFx0Ly8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuXHRcdGZvciAoaSA9IDAsIGxlbmd0aCA9IHVpbnQ4Lmxlbmd0aCAtIGV4dHJhQnl0ZXM7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuXHRcdFx0dGVtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSlcblx0XHRcdG91dHB1dCArPSB0cmlwbGV0VG9CYXNlNjQodGVtcClcblx0XHR9XG5cblx0XHQvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG5cdFx0c3dpdGNoIChleHRyYUJ5dGVzKSB7XG5cdFx0XHRjYXNlIDE6XG5cdFx0XHRcdHRlbXAgPSB1aW50OFt1aW50OC5sZW5ndGggLSAxXVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMilcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSAnPT0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0XHRjYXNlIDI6XG5cdFx0XHRcdHRlbXAgPSAodWludDhbdWludDgubGVuZ3RoIC0gMl0gPDwgOCkgKyAodWludDhbdWludDgubGVuZ3RoIC0gMV0pXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAxMClcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA+PiA0KSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgMikgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz0nXG5cdFx0XHRcdGJyZWFrXG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dFxuXHR9XG5cblx0ZXhwb3J0cy50b0J5dGVBcnJheSA9IGI2NFRvQnl0ZUFycmF5XG5cdGV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IHVpbnQ4VG9CYXNlNjRcbn0odHlwZW9mIGV4cG9ydHMgPT09ICd1bmRlZmluZWQnID8gKHRoaXMuYmFzZTY0anMgPSB7fSkgOiBleHBvcnRzKSlcbiIsImV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwidmFyIHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKGFycikgPT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgcG9vbCA9IHJlcXVpcmUoXCJ0eXBlZGFycmF5LXBvb2xcIilcblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVTdXJmYWNlRXh0cmFjdG9yXG5cbi8vSGVscGVyIG1hY3Jvc1xuZnVuY3Rpb24gYXJyYXkoaSkge1xuICByZXR1cm4gXCJhXCIgKyBpXG59XG5mdW5jdGlvbiBkYXRhKGkpIHtcbiAgcmV0dXJuIFwiZFwiICsgaVxufVxuZnVuY3Rpb24gY3ViZShpLGJpdG1hc2spIHtcbiAgcmV0dXJuIFwiY1wiICsgaSArIFwiX1wiICsgYml0bWFza1xufVxuZnVuY3Rpb24gc2hhcGUoaSkge1xuICByZXR1cm4gXCJzXCIgKyBpXG59XG5mdW5jdGlvbiBzdHJpZGUoaSxqKSB7XG4gIHJldHVybiBcInRcIiArIGkgKyBcIl9cIiArIGpcbn1cbmZ1bmN0aW9uIG9mZnNldChpKSB7XG4gIHJldHVybiBcIm9cIiArIGlcbn1cbmZ1bmN0aW9uIHNjYWxhcihpKSB7XG4gIHJldHVybiBcInhcIiArIGlcbn1cbmZ1bmN0aW9uIHBvaW50ZXIoaSkge1xuICByZXR1cm4gXCJwXCIgKyBpXG59XG5mdW5jdGlvbiBkZWx0YShpLGJpdG1hc2spIHtcbiAgcmV0dXJuIFwiZFwiICsgaSArIFwiX1wiICsgYml0bWFza1xufVxuZnVuY3Rpb24gaW5kZXgoaSkge1xuICByZXR1cm4gXCJpXCIgKyBpXG59XG5mdW5jdGlvbiBzdGVwKGksaikge1xuICByZXR1cm4gXCJ1XCIgKyBpICsgXCJfXCIgKyBqXG59XG5mdW5jdGlvbiBwY3ViZShiaXRtYXNrKSB7XG4gIHJldHVybiBcImJcIiArIGJpdG1hc2tcbn1cbmZ1bmN0aW9uIHFjdWJlKGJpdG1hc2spIHtcbiAgcmV0dXJuIFwieVwiICsgYml0bWFza1xufVxuZnVuY3Rpb24gcGRlbHRhKGJpdG1hc2spIHtcbiAgcmV0dXJuIFwiZVwiICsgYml0bWFza1xufVxuZnVuY3Rpb24gdmVydChpKSB7XG4gIHJldHVybiBcInZcIiArIGlcbn1cbnZhciBWRVJURVhfSURTID0gXCJWXCJcbnZhciBQSEFTRVMgPSBcIlBcIlxudmFyIFZFUlRFWF9DT1VOVCA9IFwiTlwiXG52YXIgUE9PTF9TSVpFID0gXCJRXCJcbnZhciBQT0lOVEVSID0gXCJYXCJcbnZhciBURU1QT1JBUlkgPSBcIlRcIlxuXG5mdW5jdGlvbiBwZXJtQml0bWFzayhkaW1lbnNpb24sIG1hc2ssIG9yZGVyKSB7XG4gIHZhciByID0gMFxuICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xuICAgIGlmKG1hc2sgJiAoMTw8aSkpIHtcbiAgICAgIHIgfD0gKDE8PG9yZGVyW2ldKVxuICAgIH1cbiAgfVxuICByZXR1cm4gclxufVxuXG4vL0dlbmVyYXRlcyB0aGUgc3VyZmFjZSBwcm9jZWR1cmVcbmZ1bmN0aW9uIGNvbXBpbGVTdXJmYWNlUHJvY2VkdXJlKHZlcnRleEZ1bmMsIGZhY2VGdW5jLCBwaGFzZUZ1bmMsIHNjYWxhckFyZ3MsIG9yZGVyLCB0eXBlc2lnKSB7XG4gIHZhciBhcnJheUFyZ3MgPSB0eXBlc2lnLmxlbmd0aFxuICB2YXIgZGltZW5zaW9uID0gb3JkZXIubGVuZ3RoXG5cbiAgaWYoZGltZW5zaW9uIDwgMikge1xuICAgIHRocm93IG5ldyBFcnJvcihcIm5kYXJyYXktZXh0cmFjdC1jb250b3VyOiBEaW1lbnNpb24gbXVzdCBiZSBhdCBsZWFzdCAyXCIpXG4gIH1cblxuICB2YXIgZnVuY05hbWUgPSBcImV4dHJhY3RDb250b3VyXCIgKyBvcmRlci5qb2luKFwiX1wiKVxuICB2YXIgY29kZSA9IFtdXG4gIHZhciB2YXJzID0gW11cbiAgdmFyIGFyZ3MgPSBbXVxuXG4gIC8vQXNzZW1ibGUgYXJndW1lbnRzXG4gIGZvcih2YXIgaT0wOyBpPGFycmF5QXJnczsgKytpKSB7XG4gICAgYXJncy5wdXNoKGFycmF5KGkpKSAgXG4gIH1cbiAgZm9yKHZhciBpPTA7IGk8c2NhbGFyQXJnczsgKytpKSB7XG4gICAgYXJncy5wdXNoKHNjYWxhcihpKSlcbiAgfVxuXG4gIC8vU2hhcGVcbiAgZm9yKHZhciBpPTA7IGk8ZGltZW5zaW9uOyArK2kpIHtcbiAgICB2YXJzLnB1c2goc2hhcGUoaSkgKyBcIj1cIiArIGFycmF5KDApICsgXCIuc2hhcGVbXCIgKyBpICsgXCJdfDBcIilcbiAgfVxuICAvL0RhdGEsIHN0cmlkZSwgb2Zmc2V0IHBvaW50ZXJzXG4gIGZvcih2YXIgaT0wOyBpPGFycmF5QXJnczsgKytpKSB7XG4gICAgdmFycy5wdXNoKGRhdGEoaSkgKyBcIj1cIiArIGFycmF5KGkpICsgXCIuZGF0YVwiLFxuICAgICAgICAgICAgICBvZmZzZXQoaSkgKyBcIj1cIiArIGFycmF5KGkpICsgXCIub2Zmc2V0fDBcIilcbiAgICBmb3IodmFyIGo9MDsgajxkaW1lbnNpb247ICsraikge1xuICAgICAgdmFycy5wdXNoKHN0cmlkZShpLGopICsgXCI9XCIgKyBhcnJheShpKSArIFwiLnN0cmlkZVtcIiArIGogKyBcIl18MFwiKVxuICAgIH1cbiAgfVxuICAvL1BvaW50ZXIsIGRlbHRhIGFuZCBjdWJlIHZhcmlhYmxlc1xuICBmb3IodmFyIGk9MDsgaTxhcnJheUFyZ3M7ICsraSkge1xuICAgIHZhcnMucHVzaChwb2ludGVyKGkpICsgXCI9XCIgKyBvZmZzZXQoaSkpXG4gICAgdmFycy5wdXNoKGN1YmUoaSwwKSlcbiAgICBmb3IodmFyIGo9MTsgajwoMTw8ZGltZW5zaW9uKTsgKytqKSB7XG4gICAgICB2YXIgcHRyU3RyID0gW11cbiAgICAgIGZvcih2YXIgaz0wOyBrPGRpbWVuc2lvbjsgKytrKSB7XG4gICAgICAgIGlmKGogJiAoMTw8aykpIHtcbiAgICAgICAgICBwdHJTdHIucHVzaChcIi1cIiArIHN0cmlkZShpLGspKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB2YXJzLnB1c2goZGVsdGEoaSxqKSArIFwiPShcIiArIHB0clN0ci5qb2luKFwiXCIpICsgXCIpfDBcIilcbiAgICAgIHZhcnMucHVzaChjdWJlKGksaikgKyBcIj0wXCIpXG4gICAgfVxuICB9XG4gIC8vQ3JlYXRlIHN0ZXAgdmFyaWFibGVzXG4gIGZvcih2YXIgaT0wOyBpPGFycmF5QXJnczsgKytpKSB7XG4gICAgZm9yKHZhciBqPTA7IGo8ZGltZW5zaW9uOyArK2opIHtcbiAgICAgIHZhciBzdGVwVmFsID0gWyBzdHJpZGUoaSxvcmRlcltqXSkgXVxuICAgICAgaWYoaiA+IDApIHtcbiAgICAgICAgc3RlcFZhbC5wdXNoKHN0cmlkZShpLCBvcmRlcltqLTFdKSArIFwiKlwiICsgc2hhcGUob3JkZXJbai0xXSkgKVxuICAgICAgfVxuICAgICAgdmFycy5wdXNoKHN0ZXAoaSxvcmRlcltqXSkgKyBcIj0oXCIgKyBzdGVwVmFsLmpvaW4oXCItXCIpICsgXCIpfDBcIilcbiAgICB9XG4gIH1cbiAgLy9DcmVhdGUgaW5kZXggdmFyaWFibGVzXG4gIGZvcih2YXIgaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7XG4gICAgdmFycy5wdXNoKGluZGV4KGkpICsgXCI9MFwiKVxuICB9XG4gIC8vVmVydGV4IGNvdW50XG4gIHZhcnMucHVzaChWRVJURVhfQ09VTlQgKyBcIj0wXCIpXG4gIC8vQ29tcHV0ZSBwb29sIHNpemUsIGluaXRpYWxpemUgcG9vbCBzdGVwXG4gIHZhciBzaXplVmFyaWFibGUgPSBbXCIyXCJdXG4gIGZvcih2YXIgaT1kaW1lbnNpb24tMjsgaT49MDsgLS1pKSB7XG4gICAgc2l6ZVZhcmlhYmxlLnB1c2goc2hhcGUob3JkZXJbaV0pKVxuICB9XG4gIC8vUHJldmlvdXMgcGhhc2VzIGFuZCB2ZXJ0ZXhfaWRzXG4gIHZhcnMucHVzaChQT09MX1NJWkUgKyBcIj0oXCIgKyBzaXplVmFyaWFibGUuam9pbihcIipcIikgKyBcIil8MFwiLFxuICAgICAgICAgICAgUEhBU0VTICsgXCI9bWFsbG9jVWludDMyKFwiICsgUE9PTF9TSVpFICsgXCIpXCIsXG4gICAgICAgICAgICBWRVJURVhfSURTICsgXCI9bWFsbG9jVWludDMyKFwiICsgUE9PTF9TSVpFICsgXCIpXCIsXG4gICAgICAgICAgICBQT0lOVEVSICsgXCI9MFwiKVxuICAvL0NyZWF0ZSBjdWJlIHZhcmlhYmxlcyBmb3IgcGhhc2VzXG4gIHZhcnMucHVzaChwY3ViZSgwKSArIFwiPTBcIilcbiAgZm9yKHZhciBqPTE7IGo8KDE8PGRpbWVuc2lvbik7ICsraikge1xuICAgIHZhciBjdWJlRGVsdGEgPSBbXVxuICAgIHZhciBjdWJlU3RlcCA9IFsgXVxuICAgIGZvcih2YXIgaz0wOyBrPGRpbWVuc2lvbjsgKytrKSB7XG4gICAgICBpZihqICYgKDE8PGspKSB7XG4gICAgICAgIGlmKGN1YmVTdGVwLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGN1YmVEZWx0YS5wdXNoKFwiMVwiKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGN1YmVEZWx0YS51bnNoaWZ0KGN1YmVTdGVwLmpvaW4oXCIqXCIpKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjdWJlU3RlcC5wdXNoKHNoYXBlKG9yZGVyW2tdKSlcbiAgICB9XG4gICAgdmFyIHNpZ25GbGFnID0gXCJcIlxuICAgIGlmKGN1YmVEZWx0YVswXS5pbmRleE9mKHNoYXBlKG9yZGVyW2RpbWVuc2lvbi0yXSkpIDwgMCkge1xuICAgICAgc2lnbkZsYWcgPSBcIi1cIlxuICAgIH1cbiAgICB2YXIganBlcm0gPSBwZXJtQml0bWFzayhkaW1lbnNpb24sIGosIG9yZGVyKVxuICAgIHZhcnMucHVzaChwZGVsdGEoanBlcm0pICsgXCI9KC1cIiArIGN1YmVEZWx0YS5qb2luKFwiLVwiKSArIFwiKXwwXCIsXG4gICAgICAgICAgICAgIHFjdWJlKGpwZXJtKSArIFwiPShcIiArIHNpZ25GbGFnICsgY3ViZURlbHRhLmpvaW4oXCItXCIpICsgXCIpfDBcIixcbiAgICAgICAgICAgICAgcGN1YmUoanBlcm0pICsgXCI9MFwiKVxuICB9XG4gIHZhcnMucHVzaCh2ZXJ0KDApICsgXCI9MFwiLCBURU1QT1JBUlkgKyBcIj0wXCIpXG5cbiAgZnVuY3Rpb24gZm9yTG9vcEJlZ2luKGksIHN0YXJ0KSB7XG4gICAgY29kZS5wdXNoKFwiZm9yKFwiLCBpbmRleChvcmRlcltpXSksIFwiPVwiLCBzdGFydCwgXCI7XCIsXG4gICAgICBpbmRleChvcmRlcltpXSksIFwiPFwiLCBzaGFwZShvcmRlcltpXSksIFwiO1wiLFxuICAgICAgXCIrK1wiLCBpbmRleChvcmRlcltpXSksIFwiKXtcIilcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvckxvb3BFbmQoaSkge1xuICAgIGZvcih2YXIgaj0wOyBqPGFycmF5QXJnczsgKytqKSB7XG4gICAgICBjb2RlLnB1c2gocG9pbnRlcihqKSwgXCIrPVwiLCBzdGVwKGosb3JkZXJbaV0pLCBcIjtcIilcbiAgICB9XG4gICAgY29kZS5wdXNoKFwifVwiKVxuICB9XG5cbiAgZnVuY3Rpb24gZmlsbEVtcHR5U2xpY2Uoaykge1xuICAgIGZvcih2YXIgaT1rLTE7IGk+PTA7IC0taSkge1xuICAgICAgZm9yTG9vcEJlZ2luKGksIDApIFxuICAgIH1cbiAgICB2YXIgcGhhc2VGdW5jQXJncyA9IFtdXG4gICAgZm9yKHZhciBpPTA7IGk8YXJyYXlBcmdzOyArK2kpIHtcbiAgICAgIGlmKHR5cGVzaWdbaV0pIHtcbiAgICAgICAgcGhhc2VGdW5jQXJncy5wdXNoKGRhdGEoaSkgKyBcIi5nZXQoXCIgKyBwb2ludGVyKGkpICsgXCIpXCIpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwaGFzZUZ1bmNBcmdzLnB1c2goZGF0YShpKSArIFwiW1wiICsgcG9pbnRlcihpKSArIFwiXVwiKVxuICAgICAgfVxuICAgIH1cbiAgICBmb3IodmFyIGk9MDsgaTxzY2FsYXJBcmdzOyArK2kpIHtcbiAgICAgIHBoYXNlRnVuY0FyZ3MucHVzaChzY2FsYXIoaSkpXG4gICAgfVxuICAgIGNvZGUucHVzaChQSEFTRVMsIFwiW1wiLCBQT0lOVEVSLCBcIisrXT1waGFzZShcIiwgcGhhc2VGdW5jQXJncy5qb2luKCksIFwiKTtcIilcbiAgICBmb3IodmFyIGk9MDsgaTxrOyArK2kpIHtcbiAgICAgIGZvckxvb3BFbmQoaSlcbiAgICB9XG4gICAgZm9yKHZhciBqPTA7IGo8YXJyYXlBcmdzOyArK2opIHtcbiAgICAgIGNvZGUucHVzaChwb2ludGVyKGopLCBcIis9XCIsIHN0ZXAoaixvcmRlcltrXSksIFwiO1wiKVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHByb2Nlc3NHcmlkQ2VsbChtYXNrKSB7XG4gICAgLy9SZWFkIGluIGxvY2FsIGRhdGFcbiAgICBmb3IodmFyIGk9MDsgaTxhcnJheUFyZ3M7ICsraSkge1xuICAgICAgaWYodHlwZXNpZ1tpXSkge1xuICAgICAgICBjb2RlLnB1c2goY3ViZShpLDApLCBcIj1cIiwgZGF0YShpKSwgXCIuZ2V0KFwiLCBwb2ludGVyKGkpLCBcIik7XCIpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb2RlLnB1c2goY3ViZShpLDApLCBcIj1cIiwgZGF0YShpKSwgXCJbXCIsIHBvaW50ZXIoaSksIFwiXTtcIilcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvL1JlYWQgaW4gcGhhc2VcbiAgICB2YXIgcGhhc2VGdW5jQXJncyA9IFtdXG4gICAgZm9yKHZhciBpPTA7IGk8YXJyYXlBcmdzOyArK2kpIHtcbiAgICAgIHBoYXNlRnVuY0FyZ3MucHVzaChjdWJlKGksMCkpXG4gICAgfVxuICAgIGZvcih2YXIgaT0wOyBpPHNjYWxhckFyZ3M7ICsraSkge1xuICAgICAgcGhhc2VGdW5jQXJncy5wdXNoKHNjYWxhcihpKSlcbiAgICB9XG4gICAgXG4gICAgY29kZS5wdXNoKHBjdWJlKDApLCBcIj1cIiwgUEhBU0VTLCBcIltcIiwgUE9JTlRFUiwgXCJdPXBoYXNlKFwiLCBwaGFzZUZ1bmNBcmdzLmpvaW4oKSwgXCIpO1wiKVxuICAgIFxuICAgIC8vUmVhZCBpbiBvdGhlciBjdWJlIGRhdGFcbiAgICBmb3IodmFyIGo9MTsgajwoMTw8ZGltZW5zaW9uKTsgKytqKSB7XG4gICAgICBjb2RlLnB1c2gocGN1YmUoaiksIFwiPVwiLCBQSEFTRVMsIFwiW1wiLCBQT0lOVEVSLCBcIitcIiwgcGRlbHRhKGopLCBcIl07XCIpXG4gICAgfVxuXG4gICAgLy9DaGVjayBmb3IgYm91bmRhcnkgY3Jvc3NpbmdcbiAgICB2YXIgdmVydGV4UHJlZGljYXRlID0gW11cbiAgICBmb3IodmFyIGo9MTsgajwoMTw8ZGltZW5zaW9uKTsgKytqKSB7XG4gICAgICB2ZXJ0ZXhQcmVkaWNhdGUucHVzaChcIihcIiArIHBjdWJlKDApICsgXCIhPT1cIiArIHBjdWJlKGopICsgXCIpXCIpXG4gICAgfVxuICAgIGNvZGUucHVzaChcImlmKFwiLCB2ZXJ0ZXhQcmVkaWNhdGUuam9pbihcInx8XCIpLCBcIil7XCIpXG5cbiAgICAvL1JlYWQgaW4gYm91bmRhcnkgZGF0YVxuICAgIHZhciB2ZXJ0ZXhBcmdzID0gW11cbiAgICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xuICAgICAgdmVydGV4QXJncy5wdXNoKGluZGV4KGkpKVxuICAgIH1cbiAgICBmb3IodmFyIGk9MDsgaTxhcnJheUFyZ3M7ICsraSkge1xuICAgICAgdmVydGV4QXJncy5wdXNoKGN1YmUoaSwwKSlcbiAgICAgIGZvcih2YXIgaj0xOyBqPCgxPDxkaW1lbnNpb24pOyArK2opIHtcbiAgICAgICAgaWYodHlwZXNpZ1tpXSkge1xuICAgICAgICAgIGNvZGUucHVzaChjdWJlKGksaiksIFwiPVwiLCBkYXRhKGkpLCBcIi5nZXQoXCIsIHBvaW50ZXIoaSksIFwiK1wiLCBkZWx0YShpLGopLCBcIik7XCIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29kZS5wdXNoKGN1YmUoaSxqKSwgXCI9XCIsIGRhdGEoaSksIFwiW1wiLCBwb2ludGVyKGkpLCBcIitcIiwgZGVsdGEoaSxqKSwgXCJdO1wiKVxuICAgICAgICB9XG4gICAgICAgIHZlcnRleEFyZ3MucHVzaChjdWJlKGksaikpXG4gICAgICB9XG4gICAgfVxuICAgIGZvcih2YXIgaT0wOyBpPCgxPDxkaW1lbnNpb24pOyArK2kpIHtcbiAgICAgIHZlcnRleEFyZ3MucHVzaChwY3ViZShpKSlcbiAgICB9XG4gICAgZm9yKHZhciBpPTA7IGk8c2NhbGFyQXJnczsgKytpKSB7XG4gICAgICB2ZXJ0ZXhBcmdzLnB1c2goc2NhbGFyKGkpKVxuICAgIH1cblxuICAgIC8vR2VuZXJhdGUgdmVydGV4XG4gICAgY29kZS5wdXNoKFwidmVydGV4KFwiLCB2ZXJ0ZXhBcmdzLmpvaW4oKSwgXCIpO1wiLFxuICAgICAgdmVydCgwKSwgXCI9XCIsIFZFUlRFWF9JRFMsIFwiW1wiLCBQT0lOVEVSLCBcIl09XCIsIFZFUlRFWF9DT1VOVCwgXCIrKztcIilcblxuICAgIC8vQ2hlY2sgZm9yIGZhY2UgY3Jvc3NpbmdzXG4gICAgdmFyIGJhc2UgPSAoMTw8ZGltZW5zaW9uKS0xXG4gICAgdmFyIGNvcm5lciA9IHBjdWJlKGJhc2UpXG4gICAgZm9yKHZhciBqPTA7IGo8ZGltZW5zaW9uOyArK2opIHtcbiAgICAgIGlmKChtYXNrICYgfigxPDxqKSk9PT0wKSB7XG4gICAgICAgIC8vQ2hlY2sgZmFjZVxuICAgICAgICB2YXIgc3Vic2V0ID0gYmFzZV4oMTw8ailcbiAgICAgICAgdmFyIGVkZ2UgPSBwY3ViZShzdWJzZXQpXG4gICAgICAgIHZhciBmYWNlQXJncyA9IFsgXVxuICAgICAgICBmb3IodmFyIGs9c3Vic2V0OyBrPjA7IGs9KGstMSkmc3Vic2V0KSB7XG4gICAgICAgICAgZmFjZUFyZ3MucHVzaChWRVJURVhfSURTICsgXCJbXCIgKyBQT0lOVEVSICsgXCIrXCIgKyBwZGVsdGEoaykgKyBcIl1cIilcbiAgICAgICAgfVxuICAgICAgICBmYWNlQXJncy5wdXNoKHZlcnQoMCkpXG4gICAgICAgIGZvcih2YXIgaz0wOyBrPGFycmF5QXJnczsgKytrKSB7XG4gICAgICAgICAgaWYoaiYxKSB7XG4gICAgICAgICAgICBmYWNlQXJncy5wdXNoKGN1YmUoayxiYXNlKSwgY3ViZShrLHN1YnNldCkpXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZhY2VBcmdzLnB1c2goY3ViZShrLHN1YnNldCksIGN1YmUoayxiYXNlKSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYoaiYxKSB7XG4gICAgICAgICAgZmFjZUFyZ3MucHVzaChjb3JuZXIsIGVkZ2UpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZmFjZUFyZ3MucHVzaChlZGdlLCBjb3JuZXIpXG4gICAgICAgIH1cbiAgICAgICAgZm9yKHZhciBrPTA7IGs8c2NhbGFyQXJnczsgKytrKSB7XG4gICAgICAgICAgZmFjZUFyZ3MucHVzaChzY2FsYXIoaykpXG4gICAgICAgIH1cbiAgICAgICAgY29kZS5wdXNoKFwiaWYoXCIsIGNvcm5lciwgXCIhPT1cIiwgZWRnZSwgXCIpe1wiLFxuICAgICAgICAgIFwiZmFjZShcIiwgZmFjZUFyZ3Muam9pbigpLCBcIil9XCIpXG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIC8vSW5jcmVtZW50IHBvaW50ZXIsIGNsb3NlIG9mZiBpZiBzdGF0ZW1lbnRcbiAgICBjb2RlLnB1c2goXCJ9XCIsXG4gICAgICBQT0lOVEVSLCBcIis9MTtcIilcbiAgfVxuXG4gIGZ1bmN0aW9uIGZsaXAoKSB7XG4gICAgZm9yKHZhciBqPTE7IGo8KDE8PGRpbWVuc2lvbik7ICsraikge1xuICAgICAgY29kZS5wdXNoKFRFTVBPUkFSWSwgXCI9XCIsIHBkZWx0YShqKSwgXCI7XCIsXG4gICAgICAgICAgICAgICAgcGRlbHRhKGopLCBcIj1cIiwgcWN1YmUoaiksIFwiO1wiLFxuICAgICAgICAgICAgICAgIHFjdWJlKGopLCBcIj1cIiwgVEVNUE9SQVJZLCBcIjtcIilcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVMb29wKGksIG1hc2spIHtcbiAgICBpZihpIDwgMCkge1xuICAgICAgcHJvY2Vzc0dyaWRDZWxsKG1hc2spXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgZmlsbEVtcHR5U2xpY2UoaSlcbiAgICBjb2RlLnB1c2goXCJpZihcIiwgc2hhcGUob3JkZXJbaV0pLCBcIj4wKXtcIixcbiAgICAgIGluZGV4KG9yZGVyW2ldKSwgXCI9MTtcIilcbiAgICBjcmVhdGVMb29wKGktMSwgbWFza3woMTw8b3JkZXJbaV0pKVxuXG4gICAgZm9yKHZhciBqPTA7IGo8YXJyYXlBcmdzOyArK2opIHtcbiAgICAgIGNvZGUucHVzaChwb2ludGVyKGopLCBcIis9XCIsIHN0ZXAoaixvcmRlcltpXSksIFwiO1wiKVxuICAgIH1cbiAgICBpZihpID09PSBkaW1lbnNpb24tMSkge1xuICAgICAgY29kZS5wdXNoKFBPSU5URVIsIFwiPTA7XCIpXG4gICAgICBmbGlwKClcbiAgICB9XG4gICAgZm9yTG9vcEJlZ2luKGksIDIpXG4gICAgY3JlYXRlTG9vcChpLTEsIG1hc2spXG4gICAgaWYoaSA9PT0gZGltZW5zaW9uLTEpIHtcbiAgICAgIGNvZGUucHVzaChcImlmKFwiLCBpbmRleChvcmRlcltkaW1lbnNpb24tMV0pLCBcIiYxKXtcIixcbiAgICAgICAgUE9JTlRFUiwgXCI9MDt9XCIpXG4gICAgICBmbGlwKClcbiAgICB9XG4gICAgZm9yTG9vcEVuZChpKVxuICAgIGNvZGUucHVzaChcIn1cIilcbiAgfVxuXG4gIGNyZWF0ZUxvb3AoZGltZW5zaW9uLTEsIDApXG5cbiAgLy9SZWxlYXNlIHNjcmF0Y2ggbWVtb3J5XG4gIGNvZGUucHVzaChcImZyZWVVaW50MzIoXCIsIFZFUlRFWF9JRFMsIFwiKTtmcmVlVWludDMyKFwiLCBQSEFTRVMsIFwiKTtcIilcblxuICAvL0NvbXBpbGUgYW5kIGxpbmsgcHJvY2VkdXJlXG4gIHZhciBwcm9jZWR1cmVDb2RlID0gW1xuICAgIFwiJ3VzZSBzdHJpY3QnO1wiLFxuICAgIFwiZnVuY3Rpb24gXCIsIGZ1bmNOYW1lLCBcIihcIiwgYXJncy5qb2luKCksIFwiKXtcIixcbiAgICAgIFwidmFyIFwiLCB2YXJzLmpvaW4oKSwgXCI7XCIsXG4gICAgICBjb2RlLmpvaW4oXCJcIiksXG4gICAgXCJ9XCIsXG4gICAgXCJyZXR1cm4gXCIsIGZ1bmNOYW1lIF0uam9pbihcIlwiKVxuXG4gIHZhciBwcm9jID0gbmV3IEZ1bmN0aW9uKFxuICAgIFwidmVydGV4XCIsIFxuICAgIFwiZmFjZVwiLCBcbiAgICBcInBoYXNlXCIsIFxuICAgIFwibWFsbG9jVWludDMyXCIsIFxuICAgIFwiZnJlZVVpbnQzMlwiLFxuICAgIHByb2NlZHVyZUNvZGUpXG4gIHJldHVybiBwcm9jKFxuICAgIHZlcnRleEZ1bmMsIFxuICAgIGZhY2VGdW5jLCBcbiAgICBwaGFzZUZ1bmMsIFxuICAgIHBvb2wubWFsbG9jVWludDMyLCBcbiAgICBwb29sLmZyZWVVaW50MzIpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVN1cmZhY2VFeHRyYWN0b3IoYXJncykge1xuICBmdW5jdGlvbiBlcnJvcihtc2cpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJuZGFycmF5LWV4dHJhY3QtY29udG91cjogXCIgKyBtc2cpXG4gIH1cbiAgaWYodHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIpIHtcbiAgICBlcnJvcihcIk11c3Qgc3BlY2lmeSBhcmd1bWVudHNcIilcbiAgfVxuICB2YXIgb3JkZXIgPSBhcmdzLm9yZGVyXG4gIGlmKCFBcnJheS5pc0FycmF5KG9yZGVyKSkge1xuICAgIGVycm9yKFwiTXVzdCBzcGVjaWZ5IG9yZGVyXCIpXG4gIH1cbiAgdmFyIGFycmF5cyA9IGFyZ3MuYXJyYXlBcmd1bWVudHN8fDFcbiAgaWYoYXJyYXlzIDwgMSkge1xuICAgIGVycm9yKFwiTXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBhcnJheSBhcmd1bWVudFwiKVxuICB9XG4gIHZhciBzY2FsYXJzID0gYXJncy5zY2FsYXJBcmd1bWVudHN8fDBcbiAgaWYoc2NhbGFycyA8IDApIHtcbiAgICBlcnJvcihcIlNjYWxhciBhcmcgY291bnQgbXVzdCBiZSA+IDBcIilcbiAgfVxuICBpZih0eXBlb2YgYXJncy52ZXJ0ZXggIT09IFwiZnVuY3Rpb25cIikge1xuICAgIGVycm9yKFwiTXVzdCBzcGVjaWZ5IHZlcnRleCBjcmVhdGlvbiBmdW5jdGlvblwiKVxuICB9XG4gIGlmKHR5cGVvZiBhcmdzLmNlbGwgIT09IFwiZnVuY3Rpb25cIikge1xuICAgIGVycm9yKFwiTXVzdCBzcGVjaWZ5IGNlbGwgY3JlYXRpb24gZnVuY3Rpb25cIilcbiAgfVxuICBpZih0eXBlb2YgYXJncy5waGFzZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgZXJyb3IoXCJNdXN0IHNwZWNpZnkgcGhhc2UgZnVuY3Rpb25cIilcbiAgfVxuICB2YXIgZ2V0dGVycyA9IGFyZ3MuZ2V0dGVycyB8fCBbXVxuICB2YXIgdHlwZXNpZyA9IG5ldyBBcnJheShhcnJheXMpXG4gIGZvcih2YXIgaT0wOyBpPGFycmF5czsgKytpKSB7XG4gICAgaWYoZ2V0dGVycy5pbmRleE9mKGkpID49IDApIHtcbiAgICAgIHR5cGVzaWdbaV0gPSB0cnVlXG4gICAgfSBlbHNlIHtcbiAgICAgIHR5cGVzaWdbaV0gPSBmYWxzZVxuICAgIH1cbiAgfVxuICByZXR1cm4gY29tcGlsZVN1cmZhY2VQcm9jZWR1cmUoXG4gICAgYXJncy52ZXJ0ZXgsXG4gICAgYXJncy5jZWxsLFxuICAgIGFyZ3MucGhhc2UsXG4gICAgc2NhbGFycyxcbiAgICBvcmRlcixcbiAgICB0eXBlc2lnKVxufSIsIi8qKlxuICogQml0IHR3aWRkbGluZyBoYWNrcyBmb3IgSmF2YVNjcmlwdC5cbiAqXG4gKiBBdXRob3I6IE1pa29sYSBMeXNlbmtvXG4gKlxuICogUG9ydGVkIGZyb20gU3RhbmZvcmQgYml0IHR3aWRkbGluZyBoYWNrIGxpYnJhcnk6XG4gKiAgICBodHRwOi8vZ3JhcGhpY3Muc3RhbmZvcmQuZWR1L35zZWFuZGVyL2JpdGhhY2tzLmh0bWxcbiAqL1xuXG5cInVzZSBzdHJpY3RcIjsgXCJ1c2UgcmVzdHJpY3RcIjtcblxuLy9OdW1iZXIgb2YgYml0cyBpbiBhbiBpbnRlZ2VyXG52YXIgSU5UX0JJVFMgPSAzMjtcblxuLy9Db25zdGFudHNcbmV4cG9ydHMuSU5UX0JJVFMgID0gSU5UX0JJVFM7XG5leHBvcnRzLklOVF9NQVggICA9ICAweDdmZmZmZmZmO1xuZXhwb3J0cy5JTlRfTUlOICAgPSAtMTw8KElOVF9CSVRTLTEpO1xuXG4vL1JldHVybnMgLTEsIDAsICsxIGRlcGVuZGluZyBvbiBzaWduIG9mIHhcbmV4cG9ydHMuc2lnbiA9IGZ1bmN0aW9uKHYpIHtcbiAgcmV0dXJuICh2ID4gMCkgLSAodiA8IDApO1xufVxuXG4vL0NvbXB1dGVzIGFic29sdXRlIHZhbHVlIG9mIGludGVnZXJcbmV4cG9ydHMuYWJzID0gZnVuY3Rpb24odikge1xuICB2YXIgbWFzayA9IHYgPj4gKElOVF9CSVRTLTEpO1xuICByZXR1cm4gKHYgXiBtYXNrKSAtIG1hc2s7XG59XG5cbi8vQ29tcHV0ZXMgbWluaW11bSBvZiBpbnRlZ2VycyB4IGFuZCB5XG5leHBvcnRzLm1pbiA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgcmV0dXJuIHkgXiAoKHggXiB5KSAmIC0oeCA8IHkpKTtcbn1cblxuLy9Db21wdXRlcyBtYXhpbXVtIG9mIGludGVnZXJzIHggYW5kIHlcbmV4cG9ydHMubWF4ID0gZnVuY3Rpb24oeCwgeSkge1xuICByZXR1cm4geCBeICgoeCBeIHkpICYgLSh4IDwgeSkpO1xufVxuXG4vL0NoZWNrcyBpZiBhIG51bWJlciBpcyBhIHBvd2VyIG9mIHR3b1xuZXhwb3J0cy5pc1BvdzIgPSBmdW5jdGlvbih2KSB7XG4gIHJldHVybiAhKHYgJiAodi0xKSkgJiYgKCEhdik7XG59XG5cbi8vQ29tcHV0ZXMgbG9nIGJhc2UgMiBvZiB2XG5leHBvcnRzLmxvZzIgPSBmdW5jdGlvbih2KSB7XG4gIHZhciByLCBzaGlmdDtcbiAgciA9ICAgICAodiA+IDB4RkZGRikgPDwgNDsgdiA+Pj49IHI7XG4gIHNoaWZ0ID0gKHYgPiAweEZGICApIDw8IDM7IHYgPj4+PSBzaGlmdDsgciB8PSBzaGlmdDtcbiAgc2hpZnQgPSAodiA+IDB4RiAgICkgPDwgMjsgdiA+Pj49IHNoaWZ0OyByIHw9IHNoaWZ0O1xuICBzaGlmdCA9ICh2ID4gMHgzICAgKSA8PCAxOyB2ID4+Pj0gc2hpZnQ7IHIgfD0gc2hpZnQ7XG4gIHJldHVybiByIHwgKHYgPj4gMSk7XG59XG5cbi8vQ29tcHV0ZXMgbG9nIGJhc2UgMTAgb2YgdlxuZXhwb3J0cy5sb2cxMCA9IGZ1bmN0aW9uKHYpIHtcbiAgcmV0dXJuICAodiA+PSAxMDAwMDAwMDAwKSA/IDkgOiAodiA+PSAxMDAwMDAwMDApID8gOCA6ICh2ID49IDEwMDAwMDAwKSA/IDcgOlxuICAgICAgICAgICh2ID49IDEwMDAwMDApID8gNiA6ICh2ID49IDEwMDAwMCkgPyA1IDogKHYgPj0gMTAwMDApID8gNCA6XG4gICAgICAgICAgKHYgPj0gMTAwMCkgPyAzIDogKHYgPj0gMTAwKSA/IDIgOiAodiA+PSAxMCkgPyAxIDogMDtcbn1cblxuLy9Db3VudHMgbnVtYmVyIG9mIGJpdHNcbmV4cG9ydHMucG9wQ291bnQgPSBmdW5jdGlvbih2KSB7XG4gIHYgPSB2IC0gKCh2ID4+PiAxKSAmIDB4NTU1NTU1NTUpO1xuICB2ID0gKHYgJiAweDMzMzMzMzMzKSArICgodiA+Pj4gMikgJiAweDMzMzMzMzMzKTtcbiAgcmV0dXJuICgodiArICh2ID4+PiA0KSAmIDB4RjBGMEYwRikgKiAweDEwMTAxMDEpID4+PiAyNDtcbn1cblxuLy9Db3VudHMgbnVtYmVyIG9mIHRyYWlsaW5nIHplcm9zXG5mdW5jdGlvbiBjb3VudFRyYWlsaW5nWmVyb3Modikge1xuICB2YXIgYyA9IDMyO1xuICB2ICY9IC12O1xuICBpZiAodikgYy0tO1xuICBpZiAodiAmIDB4MDAwMEZGRkYpIGMgLT0gMTY7XG4gIGlmICh2ICYgMHgwMEZGMDBGRikgYyAtPSA4O1xuICBpZiAodiAmIDB4MEYwRjBGMEYpIGMgLT0gNDtcbiAgaWYgKHYgJiAweDMzMzMzMzMzKSBjIC09IDI7XG4gIGlmICh2ICYgMHg1NTU1NTU1NSkgYyAtPSAxO1xuICByZXR1cm4gYztcbn1cbmV4cG9ydHMuY291bnRUcmFpbGluZ1plcm9zID0gY291bnRUcmFpbGluZ1plcm9zO1xuXG4vL1JvdW5kcyB0byBuZXh0IHBvd2VyIG9mIDJcbmV4cG9ydHMubmV4dFBvdzIgPSBmdW5jdGlvbih2KSB7XG4gIHYgKz0gdiA9PT0gMDtcbiAgLS12O1xuICB2IHw9IHYgPj4+IDE7XG4gIHYgfD0gdiA+Pj4gMjtcbiAgdiB8PSB2ID4+PiA0O1xuICB2IHw9IHYgPj4+IDg7XG4gIHYgfD0gdiA+Pj4gMTY7XG4gIHJldHVybiB2ICsgMTtcbn1cblxuLy9Sb3VuZHMgZG93biB0byBwcmV2aW91cyBwb3dlciBvZiAyXG5leHBvcnRzLnByZXZQb3cyID0gZnVuY3Rpb24odikge1xuICB2IHw9IHYgPj4+IDE7XG4gIHYgfD0gdiA+Pj4gMjtcbiAgdiB8PSB2ID4+PiA0O1xuICB2IHw9IHYgPj4+IDg7XG4gIHYgfD0gdiA+Pj4gMTY7XG4gIHJldHVybiB2IC0gKHY+Pj4xKTtcbn1cblxuLy9Db21wdXRlcyBwYXJpdHkgb2Ygd29yZFxuZXhwb3J0cy5wYXJpdHkgPSBmdW5jdGlvbih2KSB7XG4gIHYgXj0gdiA+Pj4gMTY7XG4gIHYgXj0gdiA+Pj4gODtcbiAgdiBePSB2ID4+PiA0O1xuICB2ICY9IDB4ZjtcbiAgcmV0dXJuICgweDY5OTYgPj4+IHYpICYgMTtcbn1cblxudmFyIFJFVkVSU0VfVEFCTEUgPSBuZXcgQXJyYXkoMjU2KTtcblxuKGZ1bmN0aW9uKHRhYikge1xuICBmb3IodmFyIGk9MDsgaTwyNTY7ICsraSkge1xuICAgIHZhciB2ID0gaSwgciA9IGksIHMgPSA3O1xuICAgIGZvciAodiA+Pj49IDE7IHY7IHYgPj4+PSAxKSB7XG4gICAgICByIDw8PSAxO1xuICAgICAgciB8PSB2ICYgMTtcbiAgICAgIC0tcztcbiAgICB9XG4gICAgdGFiW2ldID0gKHIgPDwgcykgJiAweGZmO1xuICB9XG59KShSRVZFUlNFX1RBQkxFKTtcblxuLy9SZXZlcnNlIGJpdHMgaW4gYSAzMiBiaXQgd29yZFxuZXhwb3J0cy5yZXZlcnNlID0gZnVuY3Rpb24odikge1xuICByZXR1cm4gIChSRVZFUlNFX1RBQkxFWyB2ICAgICAgICAgJiAweGZmXSA8PCAyNCkgfFxuICAgICAgICAgIChSRVZFUlNFX1RBQkxFWyh2ID4+PiA4KSAgJiAweGZmXSA8PCAxNikgfFxuICAgICAgICAgIChSRVZFUlNFX1RBQkxFWyh2ID4+PiAxNikgJiAweGZmXSA8PCA4KSAgfFxuICAgICAgICAgICBSRVZFUlNFX1RBQkxFWyh2ID4+PiAyNCkgJiAweGZmXTtcbn1cblxuLy9JbnRlcmxlYXZlIGJpdHMgb2YgMiBjb29yZGluYXRlcyB3aXRoIDE2IGJpdHMuICBVc2VmdWwgZm9yIGZhc3QgcXVhZHRyZWUgY29kZXNcbmV4cG9ydHMuaW50ZXJsZWF2ZTIgPSBmdW5jdGlvbih4LCB5KSB7XG4gIHggJj0gMHhGRkZGO1xuICB4ID0gKHggfCAoeCA8PCA4KSkgJiAweDAwRkYwMEZGO1xuICB4ID0gKHggfCAoeCA8PCA0KSkgJiAweDBGMEYwRjBGO1xuICB4ID0gKHggfCAoeCA8PCAyKSkgJiAweDMzMzMzMzMzO1xuICB4ID0gKHggfCAoeCA8PCAxKSkgJiAweDU1NTU1NTU1O1xuXG4gIHkgJj0gMHhGRkZGO1xuICB5ID0gKHkgfCAoeSA8PCA4KSkgJiAweDAwRkYwMEZGO1xuICB5ID0gKHkgfCAoeSA8PCA0KSkgJiAweDBGMEYwRjBGO1xuICB5ID0gKHkgfCAoeSA8PCAyKSkgJiAweDMzMzMzMzMzO1xuICB5ID0gKHkgfCAoeSA8PCAxKSkgJiAweDU1NTU1NTU1O1xuXG4gIHJldHVybiB4IHwgKHkgPDwgMSk7XG59XG5cbi8vRXh0cmFjdHMgdGhlIG50aCBpbnRlcmxlYXZlZCBjb21wb25lbnRcbmV4cG9ydHMuZGVpbnRlcmxlYXZlMiA9IGZ1bmN0aW9uKHYsIG4pIHtcbiAgdiA9ICh2ID4+PiBuKSAmIDB4NTU1NTU1NTU7XG4gIHYgPSAodiB8ICh2ID4+PiAxKSkgICYgMHgzMzMzMzMzMztcbiAgdiA9ICh2IHwgKHYgPj4+IDIpKSAgJiAweDBGMEYwRjBGO1xuICB2ID0gKHYgfCAodiA+Pj4gNCkpICAmIDB4MDBGRjAwRkY7XG4gIHYgPSAodiB8ICh2ID4+PiAxNikpICYgMHgwMDBGRkZGO1xuICByZXR1cm4gKHYgPDwgMTYpID4+IDE2O1xufVxuXG5cbi8vSW50ZXJsZWF2ZSBiaXRzIG9mIDMgY29vcmRpbmF0ZXMsIGVhY2ggd2l0aCAxMCBiaXRzLiAgVXNlZnVsIGZvciBmYXN0IG9jdHJlZSBjb2Rlc1xuZXhwb3J0cy5pbnRlcmxlYXZlMyA9IGZ1bmN0aW9uKHgsIHksIHopIHtcbiAgeCAmPSAweDNGRjtcbiAgeCAgPSAoeCB8ICh4PDwxNikpICYgNDI3ODE5MDMzNTtcbiAgeCAgPSAoeCB8ICh4PDw4KSkgICYgMjUxNzE5Njk1O1xuICB4ICA9ICh4IHwgKHg8PDQpKSAgJiAzMjcyMzU2MDM1O1xuICB4ICA9ICh4IHwgKHg8PDIpKSAgJiAxMjI3MTMzNTEzO1xuXG4gIHkgJj0gMHgzRkY7XG4gIHkgID0gKHkgfCAoeTw8MTYpKSAmIDQyNzgxOTAzMzU7XG4gIHkgID0gKHkgfCAoeTw8OCkpICAmIDI1MTcxOTY5NTtcbiAgeSAgPSAoeSB8ICh5PDw0KSkgICYgMzI3MjM1NjAzNTtcbiAgeSAgPSAoeSB8ICh5PDwyKSkgICYgMTIyNzEzMzUxMztcbiAgeCB8PSAoeSA8PCAxKTtcbiAgXG4gIHogJj0gMHgzRkY7XG4gIHogID0gKHogfCAoejw8MTYpKSAmIDQyNzgxOTAzMzU7XG4gIHogID0gKHogfCAoejw8OCkpICAmIDI1MTcxOTY5NTtcbiAgeiAgPSAoeiB8ICh6PDw0KSkgICYgMzI3MjM1NjAzNTtcbiAgeiAgPSAoeiB8ICh6PDwyKSkgICYgMTIyNzEzMzUxMztcbiAgXG4gIHJldHVybiB4IHwgKHogPDwgMik7XG59XG5cbi8vRXh0cmFjdHMgbnRoIGludGVybGVhdmVkIGNvbXBvbmVudCBvZiBhIDMtdHVwbGVcbmV4cG9ydHMuZGVpbnRlcmxlYXZlMyA9IGZ1bmN0aW9uKHYsIG4pIHtcbiAgdiA9ICh2ID4+PiBuKSAgICAgICAmIDEyMjcxMzM1MTM7XG4gIHYgPSAodiB8ICh2Pj4+MikpICAgJiAzMjcyMzU2MDM1O1xuICB2ID0gKHYgfCAodj4+PjQpKSAgICYgMjUxNzE5Njk1O1xuICB2ID0gKHYgfCAodj4+PjgpKSAgICYgNDI3ODE5MDMzNTtcbiAgdiA9ICh2IHwgKHY+Pj4xNikpICAmIDB4M0ZGO1xuICByZXR1cm4gKHY8PDIyKT4+MjI7XG59XG5cbi8vQ29tcHV0ZXMgbmV4dCBjb21iaW5hdGlvbiBpbiBjb2xleGljb2dyYXBoaWMgb3JkZXIgKHRoaXMgaXMgbWlzdGFrZW5seSBjYWxsZWQgbmV4dFBlcm11dGF0aW9uIG9uIHRoZSBiaXQgdHdpZGRsaW5nIGhhY2tzIHBhZ2UpXG5leHBvcnRzLm5leHRDb21iaW5hdGlvbiA9IGZ1bmN0aW9uKHYpIHtcbiAgdmFyIHQgPSB2IHwgKHYgLSAxKTtcbiAgcmV0dXJuICh0ICsgMSkgfCAoKCh+dCAmIC1+dCkgLSAxKSA+Pj4gKGNvdW50VHJhaWxpbmdaZXJvcyh2KSArIDEpKTtcbn1cblxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuZnVuY3Rpb24gZHVwZV9hcnJheShjb3VudCwgdmFsdWUsIGkpIHtcbiAgdmFyIGMgPSBjb3VudFtpXXwwXG4gIGlmKGMgPD0gMCkge1xuICAgIHJldHVybiBbXVxuICB9XG4gIHZhciByZXN1bHQgPSBuZXcgQXJyYXkoYyksIGpcbiAgaWYoaSA9PT0gY291bnQubGVuZ3RoLTEpIHtcbiAgICBmb3Ioaj0wOyBqPGM7ICsraikge1xuICAgICAgcmVzdWx0W2pdID0gdmFsdWVcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yKGo9MDsgajxjOyArK2opIHtcbiAgICAgIHJlc3VsdFtqXSA9IGR1cGVfYXJyYXkoY291bnQsIHZhbHVlLCBpKzEpXG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxuZnVuY3Rpb24gZHVwZV9udW1iZXIoY291bnQsIHZhbHVlKSB7XG4gIHZhciByZXN1bHQsIGlcbiAgcmVzdWx0ID0gbmV3IEFycmF5KGNvdW50KVxuICBmb3IoaT0wOyBpPGNvdW50OyArK2kpIHtcbiAgICByZXN1bHRbaV0gPSB2YWx1ZVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxuZnVuY3Rpb24gZHVwZShjb3VudCwgdmFsdWUpIHtcbiAgaWYodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgdmFsdWUgPSAwXG4gIH1cbiAgc3dpdGNoKHR5cGVvZiBjb3VudCkge1xuICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIGlmKGNvdW50ID4gMCkge1xuICAgICAgICByZXR1cm4gZHVwZV9udW1iZXIoY291bnR8MCwgdmFsdWUpXG4gICAgICB9XG4gICAgYnJlYWtcbiAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICBpZih0eXBlb2YgKGNvdW50Lmxlbmd0aCkgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgcmV0dXJuIGR1cGVfYXJyYXkoY291bnQsIHZhbHVlLCAwKVxuICAgICAgfVxuICAgIGJyZWFrXG4gIH1cbiAgcmV0dXJuIFtdXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZHVwZSIsIihmdW5jdGlvbiAoZ2xvYmFsLEJ1ZmZlcil7XG4ndXNlIHN0cmljdCdcblxudmFyIGJpdHMgPSByZXF1aXJlKCdiaXQtdHdpZGRsZScpXG52YXIgZHVwID0gcmVxdWlyZSgnZHVwJylcblxuLy9MZWdhY3kgcG9vbCBzdXBwb3J0XG5pZighZ2xvYmFsLl9fVFlQRURBUlJBWV9QT09MKSB7XG4gIGdsb2JhbC5fX1RZUEVEQVJSQVlfUE9PTCA9IHtcbiAgICAgIFVJTlQ4ICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQxNiAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQzMiAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDggICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDE2ICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDMyICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIEZMT0FUICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIERPVUJMRSAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIERBVEEgICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQ4QyAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIEJVRkZFUiAgOiBkdXAoWzMyLCAwXSlcbiAgfVxufVxuXG52YXIgaGFzVWludDhDID0gKHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSkgIT09ICd1bmRlZmluZWQnXG52YXIgUE9PTCA9IGdsb2JhbC5fX1RZUEVEQVJSQVlfUE9PTFxuXG4vL1VwZ3JhZGUgcG9vbFxuaWYoIVBPT0wuVUlOVDhDKSB7XG4gIFBPT0wuVUlOVDhDID0gZHVwKFszMiwgMF0pXG59XG5pZighUE9PTC5CVUZGRVIpIHtcbiAgUE9PTC5CVUZGRVIgPSBkdXAoWzMyLCAwXSlcbn1cblxuLy9OZXcgdGVjaG5pcXVlOiBPbmx5IGFsbG9jYXRlIGZyb20gQXJyYXlCdWZmZXJWaWV3IGFuZCBCdWZmZXJcbnZhciBEQVRBICAgID0gUE9PTC5EQVRBXG4gICwgQlVGRkVSICA9IFBPT0wuQlVGRkVSXG5cbmV4cG9ydHMuZnJlZSA9IGZ1bmN0aW9uIGZyZWUoYXJyYXkpIHtcbiAgaWYoQnVmZmVyLmlzQnVmZmVyKGFycmF5KSkge1xuICAgIEJVRkZFUltiaXRzLmxvZzIoYXJyYXkubGVuZ3RoKV0ucHVzaChhcnJheSlcbiAgfSBlbHNlIHtcbiAgICBpZihPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyYXkpICE9PSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nKSB7XG4gICAgICBhcnJheSA9IGFycmF5LmJ1ZmZlclxuICAgIH1cbiAgICBpZighYXJyYXkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB2YXIgbiA9IGFycmF5Lmxlbmd0aCB8fCBhcnJheS5ieXRlTGVuZ3RoXG4gICAgdmFyIGxvZ19uID0gYml0cy5sb2cyKG4pfDBcbiAgICBEQVRBW2xvZ19uXS5wdXNoKGFycmF5KVxuICB9XG59XG5cbmZ1bmN0aW9uIGZyZWVBcnJheUJ1ZmZlcihidWZmZXIpIHtcbiAgaWYoIWJ1ZmZlcikge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBuID0gYnVmZmVyLmxlbmd0aCB8fCBidWZmZXIuYnl0ZUxlbmd0aFxuICB2YXIgbG9nX24gPSBiaXRzLmxvZzIobilcbiAgREFUQVtsb2dfbl0ucHVzaChidWZmZXIpXG59XG5cbmZ1bmN0aW9uIGZyZWVUeXBlZEFycmF5KGFycmF5KSB7XG4gIGZyZWVBcnJheUJ1ZmZlcihhcnJheS5idWZmZXIpXG59XG5cbmV4cG9ydHMuZnJlZVVpbnQ4ID1cbmV4cG9ydHMuZnJlZVVpbnQxNiA9XG5leHBvcnRzLmZyZWVVaW50MzIgPVxuZXhwb3J0cy5mcmVlSW50OCA9XG5leHBvcnRzLmZyZWVJbnQxNiA9XG5leHBvcnRzLmZyZWVJbnQzMiA9XG5leHBvcnRzLmZyZWVGbG9hdDMyID0gXG5leHBvcnRzLmZyZWVGbG9hdCA9XG5leHBvcnRzLmZyZWVGbG9hdDY0ID0gXG5leHBvcnRzLmZyZWVEb3VibGUgPSBcbmV4cG9ydHMuZnJlZVVpbnQ4Q2xhbXBlZCA9IFxuZXhwb3J0cy5mcmVlRGF0YVZpZXcgPSBmcmVlVHlwZWRBcnJheVxuXG5leHBvcnRzLmZyZWVBcnJheUJ1ZmZlciA9IGZyZWVBcnJheUJ1ZmZlclxuXG5leHBvcnRzLmZyZWVCdWZmZXIgPSBmdW5jdGlvbiBmcmVlQnVmZmVyKGFycmF5KSB7XG4gIEJVRkZFUltiaXRzLmxvZzIoYXJyYXkubGVuZ3RoKV0ucHVzaChhcnJheSlcbn1cblxuZXhwb3J0cy5tYWxsb2MgPSBmdW5jdGlvbiBtYWxsb2MobiwgZHR5cGUpIHtcbiAgaWYoZHR5cGUgPT09IHVuZGVmaW5lZCB8fCBkdHlwZSA9PT0gJ2FycmF5YnVmZmVyJykge1xuICAgIHJldHVybiBtYWxsb2NBcnJheUJ1ZmZlcihuKVxuICB9IGVsc2Uge1xuICAgIHN3aXRjaChkdHlwZSkge1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgICByZXR1cm4gbWFsbG9jVWludDgobilcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICAgIHJldHVybiBtYWxsb2NVaW50MTYobilcbiAgICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICAgIHJldHVybiBtYWxsb2NVaW50MzIobilcbiAgICAgIGNhc2UgJ2ludDgnOlxuICAgICAgICByZXR1cm4gbWFsbG9jSW50OChuKVxuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgICByZXR1cm4gbWFsbG9jSW50MTYobilcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0ludDMyKG4pXG4gICAgICBjYXNlICdmbG9hdCc6XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0Zsb2F0KG4pXG4gICAgICBjYXNlICdkb3VibGUnOlxuICAgICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICAgIHJldHVybiBtYWxsb2NEb3VibGUobilcbiAgICAgIGNhc2UgJ3VpbnQ4X2NsYW1wZWQnOlxuICAgICAgICByZXR1cm4gbWFsbG9jVWludDhDbGFtcGVkKG4pXG4gICAgICBjYXNlICdidWZmZXInOlxuICAgICAgICByZXR1cm4gbWFsbG9jQnVmZmVyKG4pXG4gICAgICBjYXNlICdkYXRhJzpcbiAgICAgIGNhc2UgJ2RhdGF2aWV3JzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0RhdGFWaWV3KG4pXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsXG59XG5cbmZ1bmN0aW9uIG1hbGxvY0FycmF5QnVmZmVyKG4pIHtcbiAgdmFyIG4gPSBiaXRzLm5leHRQb3cyKG4pXG4gIHZhciBsb2dfbiA9IGJpdHMubG9nMihuKVxuICB2YXIgZCA9IERBVEFbbG9nX25dXG4gIGlmKGQubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBkLnBvcCgpXG4gIH1cbiAgcmV0dXJuIG5ldyBBcnJheUJ1ZmZlcihuKVxufVxuZXhwb3J0cy5tYWxsb2NBcnJheUJ1ZmZlciA9IG1hbGxvY0FycmF5QnVmZmVyXG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQ4KG4pIHtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KG1hbGxvY0FycmF5QnVmZmVyKG4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NVaW50OCA9IG1hbGxvY1VpbnQ4XG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQxNihuKSB7XG4gIHJldHVybiBuZXcgVWludDE2QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoMipuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jVWludDE2ID0gbWFsbG9jVWludDE2XG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQzMihuKSB7XG4gIHJldHVybiBuZXcgVWludDMyQXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoNCpuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jVWludDMyID0gbWFsbG9jVWludDMyXG5cbmZ1bmN0aW9uIG1hbGxvY0ludDgobikge1xuICByZXR1cm4gbmV3IEludDhBcnJheShtYWxsb2NBcnJheUJ1ZmZlcihuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jSW50OCA9IG1hbGxvY0ludDhcblxuZnVuY3Rpb24gbWFsbG9jSW50MTYobikge1xuICByZXR1cm4gbmV3IEludDE2QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoMipuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jSW50MTYgPSBtYWxsb2NJbnQxNlxuXG5mdW5jdGlvbiBtYWxsb2NJbnQzMihuKSB7XG4gIHJldHVybiBuZXcgSW50MzJBcnJheShtYWxsb2NBcnJheUJ1ZmZlcig0Km4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NJbnQzMiA9IG1hbGxvY0ludDMyXG5cbmZ1bmN0aW9uIG1hbGxvY0Zsb2F0KG4pIHtcbiAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoNCpuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jRmxvYXQzMiA9IGV4cG9ydHMubWFsbG9jRmxvYXQgPSBtYWxsb2NGbG9hdFxuXG5mdW5jdGlvbiBtYWxsb2NEb3VibGUobikge1xuICByZXR1cm4gbmV3IEZsb2F0NjRBcnJheShtYWxsb2NBcnJheUJ1ZmZlcig4Km4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NGbG9hdDY0ID0gZXhwb3J0cy5tYWxsb2NEb3VibGUgPSBtYWxsb2NEb3VibGVcblxuZnVuY3Rpb24gbWFsbG9jVWludDhDbGFtcGVkKG4pIHtcbiAgaWYoaGFzVWludDhDKSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OENsYW1wZWRBcnJheShtYWxsb2NBcnJheUJ1ZmZlcihuKSwgMCwgbilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbWFsbG9jVWludDgobilcbiAgfVxufVxuZXhwb3J0cy5tYWxsb2NVaW50OENsYW1wZWQgPSBtYWxsb2NVaW50OENsYW1wZWRcblxuZnVuY3Rpb24gbWFsbG9jRGF0YVZpZXcobikge1xuICByZXR1cm4gbmV3IERhdGFWaWV3KG1hbGxvY0FycmF5QnVmZmVyKG4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NEYXRhVmlldyA9IG1hbGxvY0RhdGFWaWV3XG5cbmZ1bmN0aW9uIG1hbGxvY0J1ZmZlcihuKSB7XG4gIG4gPSBiaXRzLm5leHRQb3cyKG4pXG4gIHZhciBsb2dfbiA9IGJpdHMubG9nMihuKVxuICB2YXIgY2FjaGUgPSBCVUZGRVJbbG9nX25dXG4gIGlmKGNhY2hlLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gY2FjaGUucG9wKClcbiAgfVxuICByZXR1cm4gbmV3IEJ1ZmZlcihuKVxufVxuZXhwb3J0cy5tYWxsb2NCdWZmZXIgPSBtYWxsb2NCdWZmZXJcblxuZXhwb3J0cy5jbGVhckNhY2hlID0gZnVuY3Rpb24gY2xlYXJDYWNoZSgpIHtcbiAgZm9yKHZhciBpPTA7IGk8MzI7ICsraSkge1xuICAgIFBPT0wuVUlOVDhbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuVUlOVDE2W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLlVJTlQzMltpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5JTlQ4W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLklOVDE2W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLklOVDMyW2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLkZMT0FUW2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLkRPVUJMRVtpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5VSU5UOENbaV0ubGVuZ3RoID0gMFxuICAgIERBVEFbaV0ubGVuZ3RoID0gMFxuICAgIEJVRkZFUltpXS5sZW5ndGggPSAwXG4gIH1cbn1cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXVaR0Z5Y21GNUxXVjRkSEpoWTNRdFkyOXVkRzkxY2k5dWIyUmxYMjF2WkhWc1pYTXZkSGx3WldSaGNuSmhlUzF3YjI5c0wzQnZiMnd1YW5NaVhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWp0QlFVRkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SW5kWE5sSUhOMGNtbGpkQ2RjYmx4dWRtRnlJR0pwZEhNZ1BTQnlaWEYxYVhKbEtDZGlhWFF0ZEhkcFpHUnNaU2NwWEc1MllYSWdaSFZ3SUQwZ2NtVnhkV2x5WlNnblpIVndKeWxjYmx4dUx5OU1aV2RoWTNrZ2NHOXZiQ0J6ZFhCd2IzSjBYRzVwWmlnaFoyeHZZbUZzTGw5ZlZGbFFSVVJCVWxKQldWOVFUMDlNS1NCN1hHNGdJR2RzYjJKaGJDNWZYMVJaVUVWRVFWSlNRVmxmVUU5UFRDQTlJSHRjYmlBZ0lDQWdJRlZKVGxRNElDQWdPaUJrZFhBb1d6TXlMQ0F3WFNsY2JpQWdJQ0FzSUZWSlRsUXhOaUFnT2lCa2RYQW9Xek15TENBd1hTbGNiaUFnSUNBc0lGVkpUbFF6TWlBZ09pQmtkWEFvV3pNeUxDQXdYU2xjYmlBZ0lDQXNJRWxPVkRnZ0lDQWdPaUJrZFhBb1d6TXlMQ0F3WFNsY2JpQWdJQ0FzSUVsT1ZERTJJQ0FnT2lCa2RYQW9Xek15TENBd1hTbGNiaUFnSUNBc0lFbE9WRE15SUNBZ09pQmtkWEFvV3pNeUxDQXdYU2xjYmlBZ0lDQXNJRVpNVDBGVUlDQWdPaUJrZFhBb1d6TXlMQ0F3WFNsY2JpQWdJQ0FzSUVSUFZVSk1SU0FnT2lCa2RYQW9Xek15TENBd1hTbGNiaUFnSUNBc0lFUkJWRUVnSUNBZ09pQmtkWEFvV3pNeUxDQXdYU2xjYmlBZ0lDQXNJRlZKVGxRNFF5QWdPaUJrZFhBb1d6TXlMQ0F3WFNsY2JpQWdJQ0FzSUVKVlJrWkZVaUFnT2lCa2RYQW9Xek15TENBd1hTbGNiaUFnZlZ4dWZWeHVYRzUyWVhJZ2FHRnpWV2x1ZERoRElEMGdLSFI1Y0dWdlppQlZhVzUwT0VOc1lXMXdaV1JCY25KaGVTa2dJVDA5SUNkMWJtUmxabWx1WldRblhHNTJZWElnVUU5UFRDQTlJR2RzYjJKaGJDNWZYMVJaVUVWRVFWSlNRVmxmVUU5UFRGeHVYRzR2TDFWd1ozSmhaR1VnY0c5dmJGeHVhV1lvSVZCUFQwd3VWVWxPVkRoREtTQjdYRzRnSUZCUFQwd3VWVWxPVkRoRElEMGdaSFZ3S0Zzek1pd2dNRjBwWEc1OVhHNXBaaWdoVUU5UFRDNUNWVVpHUlZJcElIdGNiaUFnVUU5UFRDNUNWVVpHUlZJZ1BTQmtkWEFvV3pNeUxDQXdYU2xjYm4xY2JseHVMeTlPWlhjZ2RHVmphRzVwY1hWbE9pQlBibXg1SUdGc2JHOWpZWFJsSUdaeWIyMGdRWEp5WVhsQ2RXWm1aWEpXYVdWM0lHRnVaQ0JDZFdabVpYSmNiblpoY2lCRVFWUkJJQ0FnSUQwZ1VFOVBUQzVFUVZSQlhHNGdJQ3dnUWxWR1JrVlNJQ0E5SUZCUFQwd3VRbFZHUmtWU1hHNWNibVY0Y0c5eWRITXVabkpsWlNBOUlHWjFibU4wYVc5dUlHWnlaV1VvWVhKeVlYa3BJSHRjYmlBZ2FXWW9RblZtWm1WeUxtbHpRblZtWm1WeUtHRnljbUY1S1NrZ2UxeHVJQ0FnSUVKVlJrWkZVbHRpYVhSekxteHZaeklvWVhKeVlYa3ViR1Z1WjNSb0tWMHVjSFZ6YUNoaGNuSmhlU2xjYmlBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0JwWmloUFltcGxZM1F1Y0hKdmRHOTBlWEJsTG5SdlUzUnlhVzVuTG1OaGJHd29ZWEp5WVhrcElDRTlQU0FuVzI5aWFtVmpkQ0JCY25KaGVVSjFabVpsY2wwbktTQjdYRzRnSUNBZ0lDQmhjbkpoZVNBOUlHRnljbUY1TG1KMVptWmxjbHh1SUNBZ0lIMWNiaUFnSUNCcFppZ2hZWEp5WVhrcElIdGNiaUFnSUNBZ0lISmxkSFZ5Ymx4dUlDQWdJSDFjYmlBZ0lDQjJZWElnYmlBOUlHRnljbUY1TG14bGJtZDBhQ0I4ZkNCaGNuSmhlUzVpZVhSbFRHVnVaM1JvWEc0Z0lDQWdkbUZ5SUd4dloxOXVJRDBnWW1sMGN5NXNiMmN5S0c0cGZEQmNiaUFnSUNCRVFWUkJXMnh2WjE5dVhTNXdkWE5vS0dGeWNtRjVLVnh1SUNCOVhHNTlYRzVjYm1aMWJtTjBhVzl1SUdaeVpXVkJjbkpoZVVKMVptWmxjaWhpZFdabVpYSXBJSHRjYmlBZ2FXWW9JV0oxWm1abGNpa2dlMXh1SUNBZ0lISmxkSFZ5Ymx4dUlDQjlYRzRnSUhaaGNpQnVJRDBnWW5WbVptVnlMbXhsYm1kMGFDQjhmQ0JpZFdabVpYSXVZbmwwWlV4bGJtZDBhRnh1SUNCMllYSWdiRzluWDI0Z1BTQmlhWFJ6TG14dlp6SW9iaWxjYmlBZ1JFRlVRVnRzYjJkZmJsMHVjSFZ6YUNoaWRXWm1aWElwWEc1OVhHNWNibVoxYm1OMGFXOXVJR1p5WldWVWVYQmxaRUZ5Y21GNUtHRnljbUY1S1NCN1hHNGdJR1p5WldWQmNuSmhlVUoxWm1abGNpaGhjbkpoZVM1aWRXWm1aWElwWEc1OVhHNWNibVY0Y0c5eWRITXVabkpsWlZWcGJuUTRJRDFjYm1WNGNHOXlkSE11Wm5KbFpWVnBiblF4TmlBOVhHNWxlSEJ2Y25SekxtWnlaV1ZWYVc1ME16SWdQVnh1Wlhod2IzSjBjeTVtY21WbFNXNTBPQ0E5WEc1bGVIQnZjblJ6TG1aeVpXVkpiblF4TmlBOVhHNWxlSEJ2Y25SekxtWnlaV1ZKYm5Rek1pQTlYRzVsZUhCdmNuUnpMbVp5WldWR2JHOWhkRE15SUQwZ1hHNWxlSEJ2Y25SekxtWnlaV1ZHYkc5aGRDQTlYRzVsZUhCdmNuUnpMbVp5WldWR2JHOWhkRFkwSUQwZ1hHNWxlSEJ2Y25SekxtWnlaV1ZFYjNWaWJHVWdQU0JjYm1WNGNHOXlkSE11Wm5KbFpWVnBiblE0UTJ4aGJYQmxaQ0E5SUZ4dVpYaHdiM0owY3k1bWNtVmxSR0YwWVZacFpYY2dQU0JtY21WbFZIbHdaV1JCY25KaGVWeHVYRzVsZUhCdmNuUnpMbVp5WldWQmNuSmhlVUoxWm1abGNpQTlJR1p5WldWQmNuSmhlVUoxWm1abGNseHVYRzVsZUhCdmNuUnpMbVp5WldWQ2RXWm1aWElnUFNCbWRXNWpkR2x2YmlCbWNtVmxRblZtWm1WeUtHRnljbUY1S1NCN1hHNGdJRUpWUmtaRlVsdGlhWFJ6TG14dlp6SW9ZWEp5WVhrdWJHVnVaM1JvS1YwdWNIVnphQ2hoY25KaGVTbGNibjFjYmx4dVpYaHdiM0owY3k1dFlXeHNiMk1nUFNCbWRXNWpkR2x2YmlCdFlXeHNiMk1vYml3Z1pIUjVjR1VwSUh0Y2JpQWdhV1lvWkhSNWNHVWdQVDA5SUhWdVpHVm1hVzVsWkNCOGZDQmtkSGx3WlNBOVBUMGdKMkZ5Y21GNVluVm1abVZ5SnlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJ0WVd4c2IyTkJjbkpoZVVKMVptWmxjaWh1S1Z4dUlDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUhOM2FYUmphQ2hrZEhsd1pTa2dlMXh1SUNBZ0lDQWdZMkZ6WlNBbmRXbHVkRGduT2x4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnYldGc2JHOWpWV2x1ZERnb2JpbGNiaUFnSUNBZ0lHTmhjMlVnSjNWcGJuUXhOaWM2WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJ0WVd4c2IyTlZhVzUwTVRZb2JpbGNiaUFnSUNBZ0lHTmhjMlVnSjNWcGJuUXpNaWM2WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJ0WVd4c2IyTlZhVzUwTXpJb2JpbGNiaUFnSUNBZ0lHTmhjMlVnSjJsdWREZ25PbHh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdiV0ZzYkc5alNXNTBPQ2h1S1Z4dUlDQWdJQ0FnWTJGelpTQW5hVzUwTVRZbk9seHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2JXRnNiRzlqU1c1ME1UWW9iaWxjYmlBZ0lDQWdJR05oYzJVZ0oybHVkRE15SnpwY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUcxaGJHeHZZMGx1ZERNeUtHNHBYRzRnSUNBZ0lDQmpZWE5sSUNkbWJHOWhkQ2M2WEc0Z0lDQWdJQ0JqWVhObElDZG1iRzloZERNeUp6cGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHMWhiR3h2WTBac2IyRjBLRzRwWEc0Z0lDQWdJQ0JqWVhObElDZGtiM1ZpYkdVbk9seHVJQ0FnSUNBZ1kyRnpaU0FuWm14dllYUTJOQ2M2WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJ0WVd4c2IyTkViM1ZpYkdVb2JpbGNiaUFnSUNBZ0lHTmhjMlVnSjNWcGJuUTRYMk5zWVcxd1pXUW5PbHh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdiV0ZzYkc5alZXbHVkRGhEYkdGdGNHVmtLRzRwWEc0Z0lDQWdJQ0JqWVhObElDZGlkV1ptWlhJbk9seHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2JXRnNiRzlqUW5WbVptVnlLRzRwWEc0Z0lDQWdJQ0JqWVhObElDZGtZWFJoSnpwY2JpQWdJQ0FnSUdOaGMyVWdKMlJoZEdGMmFXVjNKenBjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRzFoYkd4dlkwUmhkR0ZXYVdWM0tHNHBYRzVjYmlBZ0lDQWdJR1JsWm1GMWJIUTZYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQnVkV3hzWEc0Z0lDQWdmVnh1SUNCOVhHNGdJSEpsZEhWeWJpQnVkV3hzWEc1OVhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkwRnljbUY1UW5WbVptVnlLRzRwSUh0Y2JpQWdkbUZ5SUc0Z1BTQmlhWFJ6TG01bGVIUlFiM2N5S0c0cFhHNGdJSFpoY2lCc2IyZGZiaUE5SUdKcGRITXViRzluTWlodUtWeHVJQ0IyWVhJZ1pDQTlJRVJCVkVGYmJHOW5YMjVkWEc0Z0lHbG1LR1F1YkdWdVozUm9JRDRnTUNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJrTG5CdmNDZ3BYRzRnSUgxY2JpQWdjbVYwZFhKdUlHNWxkeUJCY25KaGVVSjFabVpsY2lodUtWeHVmVnh1Wlhod2IzSjBjeTV0WVd4c2IyTkJjbkpoZVVKMVptWmxjaUE5SUcxaGJHeHZZMEZ5Y21GNVFuVm1abVZ5WEc1Y2JtWjFibU4wYVc5dUlHMWhiR3h2WTFWcGJuUTRLRzRwSUh0Y2JpQWdjbVYwZFhKdUlHNWxkeUJWYVc1ME9FRnljbUY1S0cxaGJHeHZZMEZ5Y21GNVFuVm1abVZ5S0c0cExDQXdMQ0J1S1Z4dWZWeHVaWGh3YjNKMGN5NXRZV3hzYjJOVmFXNTBPQ0E5SUcxaGJHeHZZMVZwYm5RNFhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkxVnBiblF4TmlodUtTQjdYRzRnSUhKbGRIVnliaUJ1WlhjZ1ZXbHVkREUyUVhKeVlYa29iV0ZzYkc5alFYSnlZWGxDZFdabVpYSW9NaXB1S1N3Z01Dd2diaWxjYm4xY2JtVjRjRzl5ZEhNdWJXRnNiRzlqVldsdWRERTJJRDBnYldGc2JHOWpWV2x1ZERFMlhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkxVnBiblF6TWlodUtTQjdYRzRnSUhKbGRIVnliaUJ1WlhjZ1ZXbHVkRE15UVhKeVlYa29iV0ZzYkc5alFYSnlZWGxDZFdabVpYSW9OQ3B1S1N3Z01Dd2diaWxjYm4xY2JtVjRjRzl5ZEhNdWJXRnNiRzlqVldsdWRETXlJRDBnYldGc2JHOWpWV2x1ZERNeVhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkwbHVkRGdvYmlrZ2UxeHVJQ0J5WlhSMWNtNGdibVYzSUVsdWREaEJjbkpoZVNodFlXeHNiMk5CY25KaGVVSjFabVpsY2lodUtTd2dNQ3dnYmlsY2JuMWNibVY0Y0c5eWRITXViV0ZzYkc5alNXNTBPQ0E5SUcxaGJHeHZZMGx1ZERoY2JseHVablZ1WTNScGIyNGdiV0ZzYkc5alNXNTBNVFlvYmlrZ2UxeHVJQ0J5WlhSMWNtNGdibVYzSUVsdWRERTJRWEp5WVhrb2JXRnNiRzlqUVhKeVlYbENkV1ptWlhJb01pcHVLU3dnTUN3Z2JpbGNibjFjYm1WNGNHOXlkSE11YldGc2JHOWpTVzUwTVRZZ1BTQnRZV3hzYjJOSmJuUXhObHh1WEc1bWRXNWpkR2x2YmlCdFlXeHNiMk5KYm5Rek1paHVLU0I3WEc0Z0lISmxkSFZ5YmlCdVpYY2dTVzUwTXpKQmNuSmhlU2h0WVd4c2IyTkJjbkpoZVVKMVptWmxjaWcwS200cExDQXdMQ0J1S1Z4dWZWeHVaWGh3YjNKMGN5NXRZV3hzYjJOSmJuUXpNaUE5SUcxaGJHeHZZMGx1ZERNeVhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkwWnNiMkYwS0c0cElIdGNiaUFnY21WMGRYSnVJRzVsZHlCR2JHOWhkRE15UVhKeVlYa29iV0ZzYkc5alFYSnlZWGxDZFdabVpYSW9OQ3B1S1N3Z01Dd2diaWxjYm4xY2JtVjRjRzl5ZEhNdWJXRnNiRzlqUm14dllYUXpNaUE5SUdWNGNHOXlkSE11YldGc2JHOWpSbXh2WVhRZ1BTQnRZV3hzYjJOR2JHOWhkRnh1WEc1bWRXNWpkR2x2YmlCdFlXeHNiMk5FYjNWaWJHVW9iaWtnZTF4dUlDQnlaWFIxY200Z2JtVjNJRVpzYjJGME5qUkJjbkpoZVNodFlXeHNiMk5CY25KaGVVSjFabVpsY2lnNEttNHBMQ0F3TENCdUtWeHVmVnh1Wlhod2IzSjBjeTV0WVd4c2IyTkdiRzloZERZMElEMGdaWGh3YjNKMGN5NXRZV3hzYjJORWIzVmliR1VnUFNCdFlXeHNiMk5FYjNWaWJHVmNibHh1Wm5WdVkzUnBiMjRnYldGc2JHOWpWV2x1ZERoRGJHRnRjR1ZrS0c0cElIdGNiaUFnYVdZb2FHRnpWV2x1ZERoREtTQjdYRzRnSUNBZ2NtVjBkWEp1SUc1bGR5QlZhVzUwT0VOc1lXMXdaV1JCY25KaGVTaHRZV3hzYjJOQmNuSmhlVUoxWm1abGNpaHVLU3dnTUN3Z2JpbGNiaUFnZlNCbGJITmxJSHRjYmlBZ0lDQnlaWFIxY200Z2JXRnNiRzlqVldsdWREZ29iaWxjYmlBZ2ZWeHVmVnh1Wlhod2IzSjBjeTV0WVd4c2IyTlZhVzUwT0VOc1lXMXdaV1FnUFNCdFlXeHNiMk5WYVc1ME9FTnNZVzF3WldSY2JseHVablZ1WTNScGIyNGdiV0ZzYkc5alJHRjBZVlpwWlhjb2Jpa2dlMXh1SUNCeVpYUjFjbTRnYm1WM0lFUmhkR0ZXYVdWM0tHMWhiR3h2WTBGeWNtRjVRblZtWm1WeUtHNHBMQ0F3TENCdUtWeHVmVnh1Wlhod2IzSjBjeTV0WVd4c2IyTkVZWFJoVm1sbGR5QTlJRzFoYkd4dlkwUmhkR0ZXYVdWM1hHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkwSjFabVpsY2lodUtTQjdYRzRnSUc0Z1BTQmlhWFJ6TG01bGVIUlFiM2N5S0c0cFhHNGdJSFpoY2lCc2IyZGZiaUE5SUdKcGRITXViRzluTWlodUtWeHVJQ0IyWVhJZ1kyRmphR1VnUFNCQ1ZVWkdSVkpiYkc5blgyNWRYRzRnSUdsbUtHTmhZMmhsTG14bGJtZDBhQ0ErSURBcElIdGNiaUFnSUNCeVpYUjFjbTRnWTJGamFHVXVjRzl3S0NsY2JpQWdmVnh1SUNCeVpYUjFjbTRnYm1WM0lFSjFabVpsY2lodUtWeHVmVnh1Wlhod2IzSjBjeTV0WVd4c2IyTkNkV1ptWlhJZ1BTQnRZV3hzYjJOQ2RXWm1aWEpjYmx4dVpYaHdiM0owY3k1amJHVmhja05oWTJobElEMGdablZ1WTNScGIyNGdZMnhsWVhKRFlXTm9aU2dwSUh0Y2JpQWdabTl5S0haaGNpQnBQVEE3SUdrOE16STdJQ3NyYVNrZ2UxeHVJQ0FnSUZCUFQwd3VWVWxPVkRoYmFWMHViR1Z1WjNSb0lEMGdNRnh1SUNBZ0lGQlBUMHd1VlVsT1ZERTJXMmxkTG14bGJtZDBhQ0E5SURCY2JpQWdJQ0JRVDA5TUxsVkpUbFF6TWx0cFhTNXNaVzVuZEdnZ1BTQXdYRzRnSUNBZ1VFOVBUQzVKVGxRNFcybGRMbXhsYm1kMGFDQTlJREJjYmlBZ0lDQlFUMDlNTGtsT1ZERTJXMmxkTG14bGJtZDBhQ0E5SURCY2JpQWdJQ0JRVDA5TUxrbE9WRE15VzJsZExteGxibWQwYUNBOUlEQmNiaUFnSUNCUVQwOU1Ma1pNVDBGVVcybGRMbXhsYm1kMGFDQTlJREJjYmlBZ0lDQlFUMDlNTGtSUFZVSk1SVnRwWFM1c1pXNW5kR2dnUFNBd1hHNGdJQ0FnVUU5UFRDNVZTVTVVT0VOYmFWMHViR1Z1WjNSb0lEMGdNRnh1SUNBZ0lFUkJWRUZiYVYwdWJHVnVaM1JvSUQwZ01GeHVJQ0FnSUVKVlJrWkZVbHRwWFM1c1pXNW5kR2dnUFNBd1hHNGdJSDFjYm4waVhYMD0iLCIvLyB0cmFuc2xpdGVyYXRlZCBmcm9tIHRoZSBweXRob24gc25pcHBldCBoZXJlOlxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYW5jem9zX2FwcHJveGltYXRpb25cblxudmFyIGcgPSA3O1xudmFyIHAgPSBbXG4gICAgMC45OTk5OTk5OTk5OTk4MDk5MyxcbiAgICA2NzYuNTIwMzY4MTIxODg1MSxcbiAgICAtMTI1OS4xMzkyMTY3MjI0MDI4LFxuICAgIDc3MS4zMjM0Mjg3Nzc2NTMxMyxcbiAgICAtMTc2LjYxNTAyOTE2MjE0MDU5LFxuICAgIDEyLjUwNzM0MzI3ODY4NjkwNSxcbiAgICAtMC4xMzg1NzEwOTUyNjU3MjAxMixcbiAgICA5Ljk4NDM2OTU3ODAxOTU3MTZlLTYsXG4gICAgMS41MDU2MzI3MzUxNDkzMTE2ZS03XG5dO1xuXG52YXIgZ19sbiA9IDYwNy8xMjg7XG52YXIgcF9sbiA9IFtcbiAgICAwLjk5OTk5OTk5OTk5OTk5NzA5MTgyLFxuICAgIDU3LjE1NjIzNTY2NTg2MjkyMzUxNyxcbiAgICAtNTkuNTk3OTYwMzU1NDc1NDkxMjQ4LFxuICAgIDE0LjEzNjA5Nzk3NDc0MTc0NzE3NCxcbiAgICAtMC40OTE5MTM4MTYwOTc2MjAxOTk3OCxcbiAgICAwLjMzOTk0NjQ5OTg0ODExODg4Njk5ZS00LFxuICAgIDAuNDY1MjM2Mjg5MjcwNDg1NzU2NjVlLTQsXG4gICAgLTAuOTgzNzQ0NzUzMDQ4Nzk1NjQ2NzdlLTQsXG4gICAgMC4xNTgwODg3MDMyMjQ5MTI0ODg4NGUtMyxcbiAgICAtMC4yMTAyNjQ0NDE3MjQxMDQ4ODMxOWUtMyxcbiAgICAwLjIxNzQzOTYxODExNTIxMjY0MzIwZS0zLFxuICAgIC0wLjE2NDMxODEwNjUzNjc2Mzg5MDIyZS0zLFxuICAgIDAuODQ0MTgyMjM5ODM4NTI3NDMyOTNlLTQsXG4gICAgLTAuMjYxOTA4Mzg0MDE1ODE0MDg2NzBlLTQsXG4gICAgMC4zNjg5OTE4MjY1OTUzMTYyMjcwNGUtNVxuXTtcblxuLy8gU3BvdWdlIGFwcHJveGltYXRpb24gKHN1aXRhYmxlIGZvciBsYXJnZSBhcmd1bWVudHMpXG5mdW5jdGlvbiBsbmdhbW1hKHopIHtcblxuICAgIGlmKHogPCAwKSByZXR1cm4gTnVtYmVyKCcwLzAnKTtcbiAgICB2YXIgeCA9IHBfbG5bMF07XG4gICAgZm9yKHZhciBpID0gcF9sbi5sZW5ndGggLSAxOyBpID4gMDsgLS1pKSB4ICs9IHBfbG5baV0gLyAoeiArIGkpO1xuICAgIHZhciB0ID0geiArIGdfbG4gKyAwLjU7XG4gICAgcmV0dXJuIC41Kk1hdGgubG9nKDIqTWF0aC5QSSkrKHorLjUpKk1hdGgubG9nKHQpLXQrTWF0aC5sb2coeCktTWF0aC5sb2coeik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2FtbWEgKHopIHtcbiAgICBpZiAoeiA8IDAuNSkge1xuICAgICAgICByZXR1cm4gTWF0aC5QSSAvIChNYXRoLnNpbihNYXRoLlBJICogeikgKiBnYW1tYSgxIC0geikpO1xuICAgIH1cbiAgICBlbHNlIGlmKHogPiAxMDApIHJldHVybiBNYXRoLmV4cChsbmdhbW1hKHopKTtcbiAgICBlbHNlIHtcbiAgICAgICAgeiAtPSAxO1xuICAgICAgICB2YXIgeCA9IHBbMF07XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgZyArIDI7IGkrKykge1xuICAgICAgICAgICAgeCArPSBwW2ldIC8gKHogKyBpKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdCA9IHogKyBnICsgMC41O1xuXG4gICAgICAgIHJldHVybiBNYXRoLnNxcnQoMiAqIE1hdGguUEkpXG4gICAgICAgICAgICAqIE1hdGgucG93KHQsIHogKyAwLjUpXG4gICAgICAgICAgICAqIE1hdGguZXhwKC10KVxuICAgICAgICAgICAgKiB4XG4gICAgICAgIDtcbiAgICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5sb2cgPSBsbmdhbW1hO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwsQnVmZmVyKXtcbid1c2Ugc3RyaWN0J1xuXG52YXIgYml0cyA9IHJlcXVpcmUoJ2JpdC10d2lkZGxlJylcbnZhciBkdXAgPSByZXF1aXJlKCdkdXAnKVxuXG4vL0xlZ2FjeSBwb29sIHN1cHBvcnRcbmlmKCFnbG9iYWwuX19UWVBFREFSUkFZX1BPT0wpIHtcbiAgZ2xvYmFsLl9fVFlQRURBUlJBWV9QT09MID0ge1xuICAgICAgVUlOVDggICA6IGR1cChbMzIsIDBdKVxuICAgICwgVUlOVDE2ICA6IGR1cChbMzIsIDBdKVxuICAgICwgVUlOVDMyICA6IGR1cChbMzIsIDBdKVxuICAgICwgSU5UOCAgICA6IGR1cChbMzIsIDBdKVxuICAgICwgSU5UMTYgICA6IGR1cChbMzIsIDBdKVxuICAgICwgSU5UMzIgICA6IGR1cChbMzIsIDBdKVxuICAgICwgRkxPQVQgICA6IGR1cChbMzIsIDBdKVxuICAgICwgRE9VQkxFICA6IGR1cChbMzIsIDBdKVxuICAgICwgREFUQSAgICA6IGR1cChbMzIsIDBdKVxuICAgICwgVUlOVDhDICA6IGR1cChbMzIsIDBdKVxuICAgICwgQlVGRkVSICA6IGR1cChbMzIsIDBdKVxuICB9XG59XG5cbnZhciBoYXNVaW50OEMgPSAodHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5KSAhPT0gJ3VuZGVmaW5lZCdcbnZhciBQT09MID0gZ2xvYmFsLl9fVFlQRURBUlJBWV9QT09MXG5cbi8vVXBncmFkZSBwb29sXG5pZighUE9PTC5VSU5UOEMpIHtcbiAgUE9PTC5VSU5UOEMgPSBkdXAoWzMyLCAwXSlcbn1cbmlmKCFQT09MLkJVRkZFUikge1xuICBQT09MLkJVRkZFUiA9IGR1cChbMzIsIDBdKVxufVxuXG4vL05ldyB0ZWNobmlxdWU6IE9ubHkgYWxsb2NhdGUgZnJvbSBBcnJheUJ1ZmZlclZpZXcgYW5kIEJ1ZmZlclxudmFyIERBVEEgICAgPSBQT09MLkRBVEFcbiAgLCBCVUZGRVIgID0gUE9PTC5CVUZGRVJcblxuZXhwb3J0cy5mcmVlID0gZnVuY3Rpb24gZnJlZShhcnJheSkge1xuICBpZihCdWZmZXIuaXNCdWZmZXIoYXJyYXkpKSB7XG4gICAgQlVGRkVSW2JpdHMubG9nMihhcnJheS5sZW5ndGgpXS5wdXNoKGFycmF5KVxuICB9IGVsc2Uge1xuICAgIGlmKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcnJheSkgIT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpIHtcbiAgICAgIGFycmF5ID0gYXJyYXkuYnVmZmVyXG4gICAgfVxuICAgIGlmKCFhcnJheSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHZhciBuID0gYXJyYXkubGVuZ3RoIHx8IGFycmF5LmJ5dGVMZW5ndGhcbiAgICB2YXIgbG9nX24gPSBiaXRzLmxvZzIobil8MFxuICAgIERBVEFbbG9nX25dLnB1c2goYXJyYXkpXG4gIH1cbn1cblxuZnVuY3Rpb24gZnJlZUFycmF5QnVmZmVyKGJ1ZmZlcikge1xuICBpZighYnVmZmVyKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIG4gPSBidWZmZXIubGVuZ3RoIHx8IGJ1ZmZlci5ieXRlTGVuZ3RoXG4gIHZhciBsb2dfbiA9IGJpdHMubG9nMihuKVxuICBEQVRBW2xvZ19uXS5wdXNoKGJ1ZmZlcilcbn1cblxuZnVuY3Rpb24gZnJlZVR5cGVkQXJyYXkoYXJyYXkpIHtcbiAgZnJlZUFycmF5QnVmZmVyKGFycmF5LmJ1ZmZlcilcbn1cblxuZXhwb3J0cy5mcmVlVWludDggPVxuZXhwb3J0cy5mcmVlVWludDE2ID1cbmV4cG9ydHMuZnJlZVVpbnQzMiA9XG5leHBvcnRzLmZyZWVJbnQ4ID1cbmV4cG9ydHMuZnJlZUludDE2ID1cbmV4cG9ydHMuZnJlZUludDMyID1cbmV4cG9ydHMuZnJlZUZsb2F0MzIgPSBcbmV4cG9ydHMuZnJlZUZsb2F0ID1cbmV4cG9ydHMuZnJlZUZsb2F0NjQgPSBcbmV4cG9ydHMuZnJlZURvdWJsZSA9IFxuZXhwb3J0cy5mcmVlVWludDhDbGFtcGVkID0gXG5leHBvcnRzLmZyZWVEYXRhVmlldyA9IGZyZWVUeXBlZEFycmF5XG5cbmV4cG9ydHMuZnJlZUFycmF5QnVmZmVyID0gZnJlZUFycmF5QnVmZmVyXG5cbmV4cG9ydHMuZnJlZUJ1ZmZlciA9IGZ1bmN0aW9uIGZyZWVCdWZmZXIoYXJyYXkpIHtcbiAgQlVGRkVSW2JpdHMubG9nMihhcnJheS5sZW5ndGgpXS5wdXNoKGFycmF5KVxufVxuXG5leHBvcnRzLm1hbGxvYyA9IGZ1bmN0aW9uIG1hbGxvYyhuLCBkdHlwZSkge1xuICBpZihkdHlwZSA9PT0gdW5kZWZpbmVkIHx8IGR0eXBlID09PSAnYXJyYXlidWZmZXInKSB7XG4gICAgcmV0dXJuIG1hbGxvY0FycmF5QnVmZmVyKG4pXG4gIH0gZWxzZSB7XG4gICAgc3dpdGNoKGR0eXBlKSB7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICAgIHJldHVybiBtYWxsb2NVaW50OChuKVxuICAgICAgY2FzZSAndWludDE2JzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY1VpbnQxNihuKVxuICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY1VpbnQzMihuKVxuICAgICAgY2FzZSAnaW50OCc6XG4gICAgICAgIHJldHVybiBtYWxsb2NJbnQ4KG4pXG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICAgIHJldHVybiBtYWxsb2NJbnQxNihuKVxuICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgICByZXR1cm4gbWFsbG9jSW50MzIobilcbiAgICAgIGNhc2UgJ2Zsb2F0JzpcbiAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgICByZXR1cm4gbWFsbG9jRmxvYXQobilcbiAgICAgIGNhc2UgJ2RvdWJsZSc6XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0RvdWJsZShuKVxuICAgICAgY2FzZSAndWludDhfY2xhbXBlZCc6XG4gICAgICAgIHJldHVybiBtYWxsb2NVaW50OENsYW1wZWQobilcbiAgICAgIGNhc2UgJ2J1ZmZlcic6XG4gICAgICAgIHJldHVybiBtYWxsb2NCdWZmZXIobilcbiAgICAgIGNhc2UgJ2RhdGEnOlxuICAgICAgY2FzZSAnZGF0YXZpZXcnOlxuICAgICAgICByZXR1cm4gbWFsbG9jRGF0YVZpZXcobilcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGxcbn1cblxuZnVuY3Rpb24gbWFsbG9jQXJyYXlCdWZmZXIobikge1xuICB2YXIgbiA9IGJpdHMubmV4dFBvdzIobilcbiAgdmFyIGxvZ19uID0gYml0cy5sb2cyKG4pXG4gIHZhciBkID0gREFUQVtsb2dfbl1cbiAgaWYoZC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGQucG9wKClcbiAgfVxuICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKG4pXG59XG5leHBvcnRzLm1hbGxvY0FycmF5QnVmZmVyID0gbWFsbG9jQXJyYXlCdWZmZXJcblxuZnVuY3Rpb24gbWFsbG9jVWludDgobikge1xuICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIobiksIDAsIG4pXG59XG5leHBvcnRzLm1hbGxvY1VpbnQ4ID0gbWFsbG9jVWludDhcblxuZnVuY3Rpb24gbWFsbG9jVWludDE2KG4pIHtcbiAgcmV0dXJuIG5ldyBVaW50MTZBcnJheShtYWxsb2NBcnJheUJ1ZmZlcigyKm4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NVaW50MTYgPSBtYWxsb2NVaW50MTZcblxuZnVuY3Rpb24gbWFsbG9jVWludDMyKG4pIHtcbiAgcmV0dXJuIG5ldyBVaW50MzJBcnJheShtYWxsb2NBcnJheUJ1ZmZlcig0Km4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NVaW50MzIgPSBtYWxsb2NVaW50MzJcblxuZnVuY3Rpb24gbWFsbG9jSW50OChuKSB7XG4gIHJldHVybiBuZXcgSW50OEFycmF5KG1hbGxvY0FycmF5QnVmZmVyKG4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NJbnQ4ID0gbWFsbG9jSW50OFxuXG5mdW5jdGlvbiBtYWxsb2NJbnQxNihuKSB7XG4gIHJldHVybiBuZXcgSW50MTZBcnJheShtYWxsb2NBcnJheUJ1ZmZlcigyKm4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NJbnQxNiA9IG1hbGxvY0ludDE2XG5cbmZ1bmN0aW9uIG1hbGxvY0ludDMyKG4pIHtcbiAgcmV0dXJuIG5ldyBJbnQzMkFycmF5KG1hbGxvY0FycmF5QnVmZmVyKDQqbiksIDAsIG4pXG59XG5leHBvcnRzLm1hbGxvY0ludDMyID0gbWFsbG9jSW50MzJcblxuZnVuY3Rpb24gbWFsbG9jRmxvYXQobikge1xuICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShtYWxsb2NBcnJheUJ1ZmZlcig0Km4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NGbG9hdDMyID0gZXhwb3J0cy5tYWxsb2NGbG9hdCA9IG1hbGxvY0Zsb2F0XG5cbmZ1bmN0aW9uIG1hbGxvY0RvdWJsZShuKSB7XG4gIHJldHVybiBuZXcgRmxvYXQ2NEFycmF5KG1hbGxvY0FycmF5QnVmZmVyKDgqbiksIDAsIG4pXG59XG5leHBvcnRzLm1hbGxvY0Zsb2F0NjQgPSBleHBvcnRzLm1hbGxvY0RvdWJsZSA9IG1hbGxvY0RvdWJsZVxuXG5mdW5jdGlvbiBtYWxsb2NVaW50OENsYW1wZWQobikge1xuICBpZihoYXNVaW50OEMpIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4Q2xhbXBlZEFycmF5KG1hbGxvY0FycmF5QnVmZmVyKG4pLCAwLCBuKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBtYWxsb2NVaW50OChuKVxuICB9XG59XG5leHBvcnRzLm1hbGxvY1VpbnQ4Q2xhbXBlZCA9IG1hbGxvY1VpbnQ4Q2xhbXBlZFxuXG5mdW5jdGlvbiBtYWxsb2NEYXRhVmlldyhuKSB7XG4gIHJldHVybiBuZXcgRGF0YVZpZXcobWFsbG9jQXJyYXlCdWZmZXIobiksIDAsIG4pXG59XG5leHBvcnRzLm1hbGxvY0RhdGFWaWV3ID0gbWFsbG9jRGF0YVZpZXdcblxuZnVuY3Rpb24gbWFsbG9jQnVmZmVyKG4pIHtcbiAgbiA9IGJpdHMubmV4dFBvdzIobilcbiAgdmFyIGxvZ19uID0gYml0cy5sb2cyKG4pXG4gIHZhciBjYWNoZSA9IEJVRkZFUltsb2dfbl1cbiAgaWYoY2FjaGUubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBjYWNoZS5wb3AoKVxuICB9XG4gIHJldHVybiBuZXcgQnVmZmVyKG4pXG59XG5leHBvcnRzLm1hbGxvY0J1ZmZlciA9IG1hbGxvY0J1ZmZlclxuXG5leHBvcnRzLmNsZWFyQ2FjaGUgPSBmdW5jdGlvbiBjbGVhckNhY2hlKCkge1xuICBmb3IodmFyIGk9MDsgaTwzMjsgKytpKSB7XG4gICAgUE9PTC5VSU5UOFtpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5VSU5UMTZbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuVUlOVDMyW2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLklOVDhbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuSU5UMTZbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuSU5UMzJbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuRkxPQVRbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuRE9VQkxFW2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLlVJTlQ4Q1tpXS5sZW5ndGggPSAwXG4gICAgREFUQVtpXS5sZW5ndGggPSAwXG4gICAgQlVGRkVSW2ldLmxlbmd0aCA9IDBcbiAgfVxufVxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5MGNtbGhibWQxYkdGMFpTMW9lWEJsY21OMVltVXZibTlrWlY5dGIyUjFiR1Z6TDNCbGNtMTFkR0YwYVc5dUxYQmhjbWwwZVM5dWIyUmxYMjF2WkhWc1pYTXZkSGx3WldSaGNuSmhlUzF3YjI5c0wzQnZiMnd1YW5NaVhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWp0QlFVRkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SW5kWE5sSUhOMGNtbGpkQ2RjYmx4dWRtRnlJR0pwZEhNZ1BTQnlaWEYxYVhKbEtDZGlhWFF0ZEhkcFpHUnNaU2NwWEc1MllYSWdaSFZ3SUQwZ2NtVnhkV2x5WlNnblpIVndKeWxjYmx4dUx5OU1aV2RoWTNrZ2NHOXZiQ0J6ZFhCd2IzSjBYRzVwWmlnaFoyeHZZbUZzTGw5ZlZGbFFSVVJCVWxKQldWOVFUMDlNS1NCN1hHNGdJR2RzYjJKaGJDNWZYMVJaVUVWRVFWSlNRVmxmVUU5UFRDQTlJSHRjYmlBZ0lDQWdJRlZKVGxRNElDQWdPaUJrZFhBb1d6TXlMQ0F3WFNsY2JpQWdJQ0FzSUZWSlRsUXhOaUFnT2lCa2RYQW9Xek15TENBd1hTbGNiaUFnSUNBc0lGVkpUbFF6TWlBZ09pQmtkWEFvV3pNeUxDQXdYU2xjYmlBZ0lDQXNJRWxPVkRnZ0lDQWdPaUJrZFhBb1d6TXlMQ0F3WFNsY2JpQWdJQ0FzSUVsT1ZERTJJQ0FnT2lCa2RYQW9Xek15TENBd1hTbGNiaUFnSUNBc0lFbE9WRE15SUNBZ09pQmtkWEFvV3pNeUxDQXdYU2xjYmlBZ0lDQXNJRVpNVDBGVUlDQWdPaUJrZFhBb1d6TXlMQ0F3WFNsY2JpQWdJQ0FzSUVSUFZVSk1SU0FnT2lCa2RYQW9Xek15TENBd1hTbGNiaUFnSUNBc0lFUkJWRUVnSUNBZ09pQmtkWEFvV3pNeUxDQXdYU2xjYmlBZ0lDQXNJRlZKVGxRNFF5QWdPaUJrZFhBb1d6TXlMQ0F3WFNsY2JpQWdJQ0FzSUVKVlJrWkZVaUFnT2lCa2RYQW9Xek15TENBd1hTbGNiaUFnZlZ4dWZWeHVYRzUyWVhJZ2FHRnpWV2x1ZERoRElEMGdLSFI1Y0dWdlppQlZhVzUwT0VOc1lXMXdaV1JCY25KaGVTa2dJVDA5SUNkMWJtUmxabWx1WldRblhHNTJZWElnVUU5UFRDQTlJR2RzYjJKaGJDNWZYMVJaVUVWRVFWSlNRVmxmVUU5UFRGeHVYRzR2TDFWd1ozSmhaR1VnY0c5dmJGeHVhV1lvSVZCUFQwd3VWVWxPVkRoREtTQjdYRzRnSUZCUFQwd3VWVWxPVkRoRElEMGdaSFZ3S0Zzek1pd2dNRjBwWEc1OVhHNXBaaWdoVUU5UFRDNUNWVVpHUlZJcElIdGNiaUFnVUU5UFRDNUNWVVpHUlZJZ1BTQmtkWEFvV3pNeUxDQXdYU2xjYm4xY2JseHVMeTlPWlhjZ2RHVmphRzVwY1hWbE9pQlBibXg1SUdGc2JHOWpZWFJsSUdaeWIyMGdRWEp5WVhsQ2RXWm1aWEpXYVdWM0lHRnVaQ0JDZFdabVpYSmNiblpoY2lCRVFWUkJJQ0FnSUQwZ1VFOVBUQzVFUVZSQlhHNGdJQ3dnUWxWR1JrVlNJQ0E5SUZCUFQwd3VRbFZHUmtWU1hHNWNibVY0Y0c5eWRITXVabkpsWlNBOUlHWjFibU4wYVc5dUlHWnlaV1VvWVhKeVlYa3BJSHRjYmlBZ2FXWW9RblZtWm1WeUxtbHpRblZtWm1WeUtHRnljbUY1S1NrZ2UxeHVJQ0FnSUVKVlJrWkZVbHRpYVhSekxteHZaeklvWVhKeVlYa3ViR1Z1WjNSb0tWMHVjSFZ6YUNoaGNuSmhlU2xjYmlBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0JwWmloUFltcGxZM1F1Y0hKdmRHOTBlWEJsTG5SdlUzUnlhVzVuTG1OaGJHd29ZWEp5WVhrcElDRTlQU0FuVzI5aWFtVmpkQ0JCY25KaGVVSjFabVpsY2wwbktTQjdYRzRnSUNBZ0lDQmhjbkpoZVNBOUlHRnljbUY1TG1KMVptWmxjbHh1SUNBZ0lIMWNiaUFnSUNCcFppZ2hZWEp5WVhrcElIdGNiaUFnSUNBZ0lISmxkSFZ5Ymx4dUlDQWdJSDFjYmlBZ0lDQjJZWElnYmlBOUlHRnljbUY1TG14bGJtZDBhQ0I4ZkNCaGNuSmhlUzVpZVhSbFRHVnVaM1JvWEc0Z0lDQWdkbUZ5SUd4dloxOXVJRDBnWW1sMGN5NXNiMmN5S0c0cGZEQmNiaUFnSUNCRVFWUkJXMnh2WjE5dVhTNXdkWE5vS0dGeWNtRjVLVnh1SUNCOVhHNTlYRzVjYm1aMWJtTjBhVzl1SUdaeVpXVkJjbkpoZVVKMVptWmxjaWhpZFdabVpYSXBJSHRjYmlBZ2FXWW9JV0oxWm1abGNpa2dlMXh1SUNBZ0lISmxkSFZ5Ymx4dUlDQjlYRzRnSUhaaGNpQnVJRDBnWW5WbVptVnlMbXhsYm1kMGFDQjhmQ0JpZFdabVpYSXVZbmwwWlV4bGJtZDBhRnh1SUNCMllYSWdiRzluWDI0Z1BTQmlhWFJ6TG14dlp6SW9iaWxjYmlBZ1JFRlVRVnRzYjJkZmJsMHVjSFZ6YUNoaWRXWm1aWElwWEc1OVhHNWNibVoxYm1OMGFXOXVJR1p5WldWVWVYQmxaRUZ5Y21GNUtHRnljbUY1S1NCN1hHNGdJR1p5WldWQmNuSmhlVUoxWm1abGNpaGhjbkpoZVM1aWRXWm1aWElwWEc1OVhHNWNibVY0Y0c5eWRITXVabkpsWlZWcGJuUTRJRDFjYm1WNGNHOXlkSE11Wm5KbFpWVnBiblF4TmlBOVhHNWxlSEJ2Y25SekxtWnlaV1ZWYVc1ME16SWdQVnh1Wlhod2IzSjBjeTVtY21WbFNXNTBPQ0E5WEc1bGVIQnZjblJ6TG1aeVpXVkpiblF4TmlBOVhHNWxlSEJ2Y25SekxtWnlaV1ZKYm5Rek1pQTlYRzVsZUhCdmNuUnpMbVp5WldWR2JHOWhkRE15SUQwZ1hHNWxlSEJ2Y25SekxtWnlaV1ZHYkc5aGRDQTlYRzVsZUhCdmNuUnpMbVp5WldWR2JHOWhkRFkwSUQwZ1hHNWxlSEJ2Y25SekxtWnlaV1ZFYjNWaWJHVWdQU0JjYm1WNGNHOXlkSE11Wm5KbFpWVnBiblE0UTJ4aGJYQmxaQ0E5SUZ4dVpYaHdiM0owY3k1bWNtVmxSR0YwWVZacFpYY2dQU0JtY21WbFZIbHdaV1JCY25KaGVWeHVYRzVsZUhCdmNuUnpMbVp5WldWQmNuSmhlVUoxWm1abGNpQTlJR1p5WldWQmNuSmhlVUoxWm1abGNseHVYRzVsZUhCdmNuUnpMbVp5WldWQ2RXWm1aWElnUFNCbWRXNWpkR2x2YmlCbWNtVmxRblZtWm1WeUtHRnljbUY1S1NCN1hHNGdJRUpWUmtaRlVsdGlhWFJ6TG14dlp6SW9ZWEp5WVhrdWJHVnVaM1JvS1YwdWNIVnphQ2hoY25KaGVTbGNibjFjYmx4dVpYaHdiM0owY3k1dFlXeHNiMk1nUFNCbWRXNWpkR2x2YmlCdFlXeHNiMk1vYml3Z1pIUjVjR1VwSUh0Y2JpQWdhV1lvWkhSNWNHVWdQVDA5SUhWdVpHVm1hVzVsWkNCOGZDQmtkSGx3WlNBOVBUMGdKMkZ5Y21GNVluVm1abVZ5SnlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJ0WVd4c2IyTkJjbkpoZVVKMVptWmxjaWh1S1Z4dUlDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUhOM2FYUmphQ2hrZEhsd1pTa2dlMXh1SUNBZ0lDQWdZMkZ6WlNBbmRXbHVkRGduT2x4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnYldGc2JHOWpWV2x1ZERnb2JpbGNiaUFnSUNBZ0lHTmhjMlVnSjNWcGJuUXhOaWM2WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJ0WVd4c2IyTlZhVzUwTVRZb2JpbGNiaUFnSUNBZ0lHTmhjMlVnSjNWcGJuUXpNaWM2WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJ0WVd4c2IyTlZhVzUwTXpJb2JpbGNiaUFnSUNBZ0lHTmhjMlVnSjJsdWREZ25PbHh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdiV0ZzYkc5alNXNTBPQ2h1S1Z4dUlDQWdJQ0FnWTJGelpTQW5hVzUwTVRZbk9seHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2JXRnNiRzlqU1c1ME1UWW9iaWxjYmlBZ0lDQWdJR05oYzJVZ0oybHVkRE15SnpwY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUcxaGJHeHZZMGx1ZERNeUtHNHBYRzRnSUNBZ0lDQmpZWE5sSUNkbWJHOWhkQ2M2WEc0Z0lDQWdJQ0JqWVhObElDZG1iRzloZERNeUp6cGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHMWhiR3h2WTBac2IyRjBLRzRwWEc0Z0lDQWdJQ0JqWVhObElDZGtiM1ZpYkdVbk9seHVJQ0FnSUNBZ1kyRnpaU0FuWm14dllYUTJOQ2M2WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJ0WVd4c2IyTkViM1ZpYkdVb2JpbGNiaUFnSUNBZ0lHTmhjMlVnSjNWcGJuUTRYMk5zWVcxd1pXUW5PbHh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdiV0ZzYkc5alZXbHVkRGhEYkdGdGNHVmtLRzRwWEc0Z0lDQWdJQ0JqWVhObElDZGlkV1ptWlhJbk9seHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2JXRnNiRzlqUW5WbVptVnlLRzRwWEc0Z0lDQWdJQ0JqWVhObElDZGtZWFJoSnpwY2JpQWdJQ0FnSUdOaGMyVWdKMlJoZEdGMmFXVjNKenBjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRzFoYkd4dlkwUmhkR0ZXYVdWM0tHNHBYRzVjYmlBZ0lDQWdJR1JsWm1GMWJIUTZYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQnVkV3hzWEc0Z0lDQWdmVnh1SUNCOVhHNGdJSEpsZEhWeWJpQnVkV3hzWEc1OVhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkwRnljbUY1UW5WbVptVnlLRzRwSUh0Y2JpQWdkbUZ5SUc0Z1BTQmlhWFJ6TG01bGVIUlFiM2N5S0c0cFhHNGdJSFpoY2lCc2IyZGZiaUE5SUdKcGRITXViRzluTWlodUtWeHVJQ0IyWVhJZ1pDQTlJRVJCVkVGYmJHOW5YMjVkWEc0Z0lHbG1LR1F1YkdWdVozUm9JRDRnTUNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJrTG5CdmNDZ3BYRzRnSUgxY2JpQWdjbVYwZFhKdUlHNWxkeUJCY25KaGVVSjFabVpsY2lodUtWeHVmVnh1Wlhod2IzSjBjeTV0WVd4c2IyTkJjbkpoZVVKMVptWmxjaUE5SUcxaGJHeHZZMEZ5Y21GNVFuVm1abVZ5WEc1Y2JtWjFibU4wYVc5dUlHMWhiR3h2WTFWcGJuUTRLRzRwSUh0Y2JpQWdjbVYwZFhKdUlHNWxkeUJWYVc1ME9FRnljbUY1S0cxaGJHeHZZMEZ5Y21GNVFuVm1abVZ5S0c0cExDQXdMQ0J1S1Z4dWZWeHVaWGh3YjNKMGN5NXRZV3hzYjJOVmFXNTBPQ0E5SUcxaGJHeHZZMVZwYm5RNFhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkxVnBiblF4TmlodUtTQjdYRzRnSUhKbGRIVnliaUJ1WlhjZ1ZXbHVkREUyUVhKeVlYa29iV0ZzYkc5alFYSnlZWGxDZFdabVpYSW9NaXB1S1N3Z01Dd2diaWxjYm4xY2JtVjRjRzl5ZEhNdWJXRnNiRzlqVldsdWRERTJJRDBnYldGc2JHOWpWV2x1ZERFMlhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkxVnBiblF6TWlodUtTQjdYRzRnSUhKbGRIVnliaUJ1WlhjZ1ZXbHVkRE15UVhKeVlYa29iV0ZzYkc5alFYSnlZWGxDZFdabVpYSW9OQ3B1S1N3Z01Dd2diaWxjYm4xY2JtVjRjRzl5ZEhNdWJXRnNiRzlqVldsdWRETXlJRDBnYldGc2JHOWpWV2x1ZERNeVhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkwbHVkRGdvYmlrZ2UxeHVJQ0J5WlhSMWNtNGdibVYzSUVsdWREaEJjbkpoZVNodFlXeHNiMk5CY25KaGVVSjFabVpsY2lodUtTd2dNQ3dnYmlsY2JuMWNibVY0Y0c5eWRITXViV0ZzYkc5alNXNTBPQ0E5SUcxaGJHeHZZMGx1ZERoY2JseHVablZ1WTNScGIyNGdiV0ZzYkc5alNXNTBNVFlvYmlrZ2UxeHVJQ0J5WlhSMWNtNGdibVYzSUVsdWRERTJRWEp5WVhrb2JXRnNiRzlqUVhKeVlYbENkV1ptWlhJb01pcHVLU3dnTUN3Z2JpbGNibjFjYm1WNGNHOXlkSE11YldGc2JHOWpTVzUwTVRZZ1BTQnRZV3hzYjJOSmJuUXhObHh1WEc1bWRXNWpkR2x2YmlCdFlXeHNiMk5KYm5Rek1paHVLU0I3WEc0Z0lISmxkSFZ5YmlCdVpYY2dTVzUwTXpKQmNuSmhlU2h0WVd4c2IyTkJjbkpoZVVKMVptWmxjaWcwS200cExDQXdMQ0J1S1Z4dWZWeHVaWGh3YjNKMGN5NXRZV3hzYjJOSmJuUXpNaUE5SUcxaGJHeHZZMGx1ZERNeVhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkwWnNiMkYwS0c0cElIdGNiaUFnY21WMGRYSnVJRzVsZHlCR2JHOWhkRE15UVhKeVlYa29iV0ZzYkc5alFYSnlZWGxDZFdabVpYSW9OQ3B1S1N3Z01Dd2diaWxjYm4xY2JtVjRjRzl5ZEhNdWJXRnNiRzlqUm14dllYUXpNaUE5SUdWNGNHOXlkSE11YldGc2JHOWpSbXh2WVhRZ1BTQnRZV3hzYjJOR2JHOWhkRnh1WEc1bWRXNWpkR2x2YmlCdFlXeHNiMk5FYjNWaWJHVW9iaWtnZTF4dUlDQnlaWFIxY200Z2JtVjNJRVpzYjJGME5qUkJjbkpoZVNodFlXeHNiMk5CY25KaGVVSjFabVpsY2lnNEttNHBMQ0F3TENCdUtWeHVmVnh1Wlhod2IzSjBjeTV0WVd4c2IyTkdiRzloZERZMElEMGdaWGh3YjNKMGN5NXRZV3hzYjJORWIzVmliR1VnUFNCdFlXeHNiMk5FYjNWaWJHVmNibHh1Wm5WdVkzUnBiMjRnYldGc2JHOWpWV2x1ZERoRGJHRnRjR1ZrS0c0cElIdGNiaUFnYVdZb2FHRnpWV2x1ZERoREtTQjdYRzRnSUNBZ2NtVjBkWEp1SUc1bGR5QlZhVzUwT0VOc1lXMXdaV1JCY25KaGVTaHRZV3hzYjJOQmNuSmhlVUoxWm1abGNpaHVLU3dnTUN3Z2JpbGNiaUFnZlNCbGJITmxJSHRjYmlBZ0lDQnlaWFIxY200Z2JXRnNiRzlqVldsdWREZ29iaWxjYmlBZ2ZWeHVmVnh1Wlhod2IzSjBjeTV0WVd4c2IyTlZhVzUwT0VOc1lXMXdaV1FnUFNCdFlXeHNiMk5WYVc1ME9FTnNZVzF3WldSY2JseHVablZ1WTNScGIyNGdiV0ZzYkc5alJHRjBZVlpwWlhjb2Jpa2dlMXh1SUNCeVpYUjFjbTRnYm1WM0lFUmhkR0ZXYVdWM0tHMWhiR3h2WTBGeWNtRjVRblZtWm1WeUtHNHBMQ0F3TENCdUtWeHVmVnh1Wlhod2IzSjBjeTV0WVd4c2IyTkVZWFJoVm1sbGR5QTlJRzFoYkd4dlkwUmhkR0ZXYVdWM1hHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkwSjFabVpsY2lodUtTQjdYRzRnSUc0Z1BTQmlhWFJ6TG01bGVIUlFiM2N5S0c0cFhHNGdJSFpoY2lCc2IyZGZiaUE5SUdKcGRITXViRzluTWlodUtWeHVJQ0IyWVhJZ1kyRmphR1VnUFNCQ1ZVWkdSVkpiYkc5blgyNWRYRzRnSUdsbUtHTmhZMmhsTG14bGJtZDBhQ0ErSURBcElIdGNiaUFnSUNCeVpYUjFjbTRnWTJGamFHVXVjRzl3S0NsY2JpQWdmVnh1SUNCeVpYUjFjbTRnYm1WM0lFSjFabVpsY2lodUtWeHVmVnh1Wlhod2IzSjBjeTV0WVd4c2IyTkNkV1ptWlhJZ1BTQnRZV3hzYjJOQ2RXWm1aWEpjYmx4dVpYaHdiM0owY3k1amJHVmhja05oWTJobElEMGdablZ1WTNScGIyNGdZMnhsWVhKRFlXTm9aU2dwSUh0Y2JpQWdabTl5S0haaGNpQnBQVEE3SUdrOE16STdJQ3NyYVNrZ2UxeHVJQ0FnSUZCUFQwd3VWVWxPVkRoYmFWMHViR1Z1WjNSb0lEMGdNRnh1SUNBZ0lGQlBUMHd1VlVsT1ZERTJXMmxkTG14bGJtZDBhQ0E5SURCY2JpQWdJQ0JRVDA5TUxsVkpUbFF6TWx0cFhTNXNaVzVuZEdnZ1BTQXdYRzRnSUNBZ1VFOVBUQzVKVGxRNFcybGRMbXhsYm1kMGFDQTlJREJjYmlBZ0lDQlFUMDlNTGtsT1ZERTJXMmxkTG14bGJtZDBhQ0E5SURCY2JpQWdJQ0JRVDA5TUxrbE9WRE15VzJsZExteGxibWQwYUNBOUlEQmNiaUFnSUNCUVQwOU1Ma1pNVDBGVVcybGRMbXhsYm1kMGFDQTlJREJjYmlBZ0lDQlFUMDlNTGtSUFZVSk1SVnRwWFM1c1pXNW5kR2dnUFNBd1hHNGdJQ0FnVUU5UFRDNVZTVTVVT0VOYmFWMHViR1Z1WjNSb0lEMGdNRnh1SUNBZ0lFUkJWRUZiYVYwdWJHVnVaM1JvSUQwZ01GeHVJQ0FnSUVKVlJrWkZVbHRwWFM1c1pXNW5kR2dnUFNBd1hHNGdJSDFjYm4waVhYMD0iLCJcInVzZSBzdHJpY3RcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IHBlcm11dGF0aW9uU2lnblxuXG52YXIgQlJVVEVfRk9SQ0VfQ1VUT0ZGID0gMzJcblxudmFyIHBvb2wgPSByZXF1aXJlKFwidHlwZWRhcnJheS1wb29sXCIpXG5cbmZ1bmN0aW9uIHBlcm11dGF0aW9uU2lnbihwKSB7XG4gIHZhciBuID0gcC5sZW5ndGhcbiAgaWYobiA8IEJSVVRFX0ZPUkNFX0NVVE9GRikge1xuICAgIC8vVXNlIHF1YWRyYXRpYyBhbGdvcml0aG0gZm9yIHNtYWxsIG5cbiAgICB2YXIgc2duID0gMVxuICAgIGZvcih2YXIgaT0wOyBpPG47ICsraSkge1xuICAgICAgZm9yKHZhciBqPTA7IGo8aTsgKytqKSB7XG4gICAgICAgIGlmKHBbaV0gPCBwW2pdKSB7XG4gICAgICAgICAgc2duID0gLXNnblxuICAgICAgICB9IGVsc2UgaWYocFtpXSA9PT0gcFtqXSkge1xuICAgICAgICAgIHJldHVybiAwXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNnblxuICB9IGVsc2Uge1xuICAgIC8vT3RoZXJ3aXNlIHVzZSBsaW5lYXIgdGltZSBhbGdvcml0aG1cbiAgICB2YXIgdmlzaXRlZCA9IHBvb2wubWFsbG9jVWludDgobilcbiAgICBmb3IodmFyIGk9MDsgaTxuOyArK2kpIHtcbiAgICAgIHZpc2l0ZWRbaV0gPSAwXG4gICAgfVxuICAgIHZhciBzZ24gPSAxXG4gICAgZm9yKHZhciBpPTA7IGk8bjsgKytpKSB7XG4gICAgICBpZighdmlzaXRlZFtpXSkge1xuICAgICAgICB2YXIgY291bnQgPSAxXG4gICAgICAgIHZpc2l0ZWRbaV0gPSAxXG4gICAgICAgIGZvcih2YXIgaj1wW2ldOyBqIT09aTsgaj1wW2pdKSB7XG4gICAgICAgICAgaWYodmlzaXRlZFtqXSkge1xuICAgICAgICAgICAgcG9vbC5mcmVlVWludDgodmlzaXRlZClcbiAgICAgICAgICAgIHJldHVybiAwXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvdW50ICs9IDFcbiAgICAgICAgICB2aXNpdGVkW2pdID0gMVxuICAgICAgICB9XG4gICAgICAgIGlmKCEoY291bnQgJiAxKSkge1xuICAgICAgICAgIHNnbiA9IC1zZ25cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBwb29sLmZyZWVVaW50OCh2aXNpdGVkKVxuICAgIHJldHVybiBzZ25cbiAgfVxufSIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBwb29sID0gcmVxdWlyZShcInR5cGVkYXJyYXktcG9vbFwiKVxudmFyIGludmVyc2UgPSByZXF1aXJlKFwiaW52ZXJ0LXBlcm11dGF0aW9uXCIpXG5cbmZ1bmN0aW9uIHJhbmsocGVybXV0YXRpb24pIHtcbiAgdmFyIG4gPSBwZXJtdXRhdGlvbi5sZW5ndGhcbiAgc3dpdGNoKG4pIHtcbiAgICBjYXNlIDA6XG4gICAgY2FzZSAxOlxuICAgICAgcmV0dXJuIDBcbiAgICBjYXNlIDI6XG4gICAgICByZXR1cm4gcGVybXV0YXRpb25bMV1cbiAgICBkZWZhdWx0OlxuICAgICAgYnJlYWtcbiAgfVxuICB2YXIgcCA9IHBvb2wubWFsbG9jVWludDMyKG4pXG4gIHZhciBwaW52ID0gcG9vbC5tYWxsb2NVaW50MzIobilcbiAgdmFyIHIgPSAwLCBzLCB0LCBpXG4gIGludmVyc2UocGVybXV0YXRpb24sIHBpbnYpXG4gIGZvcihpPTA7IGk8bjsgKytpKSB7XG4gICAgcFtpXSA9IHBlcm11dGF0aW9uW2ldXG4gIH1cbiAgZm9yKGk9bi0xOyBpPjA7IC0taSkge1xuICAgIHQgPSBwaW52W2ldXG4gICAgcyA9IHBbaV1cbiAgICBwW2ldID0gcFt0XVxuICAgIHBbdF0gPSBzXG4gICAgcGludltpXSA9IHBpbnZbc11cbiAgICBwaW52W3NdID0gdFxuICAgIHIgPSAociArIHMpICogaVxuICB9XG4gIHBvb2wuZnJlZVVpbnQzMihwaW52KVxuICBwb29sLmZyZWVVaW50MzIocClcbiAgcmV0dXJuIHJcbn1cblxuZnVuY3Rpb24gdW5yYW5rKG4sIHIsIHApIHtcbiAgc3dpdGNoKG4pIHtcbiAgICBjYXNlIDA6XG4gICAgICBpZihwKSB7IHJldHVybiBwIH1cbiAgICAgIHJldHVybiBbXVxuICAgIGNhc2UgMTpcbiAgICAgIGlmKHApIHtcbiAgICAgICAgcFswXSA9IDBcbiAgICAgICAgcmV0dXJuIHBcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbMF1cbiAgICAgIH1cbiAgICBjYXNlIDI6XG4gICAgICBpZihwKSB7XG4gICAgICAgIGlmKHIpIHtcbiAgICAgICAgICBwWzBdID0gMFxuICAgICAgICAgIHBbMV0gPSAxXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcFswXSA9IDFcbiAgICAgICAgICBwWzFdID0gMFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gciA/IFswLDFdIDogWzEsMF1cbiAgICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgYnJlYWtcbiAgfVxuICBwID0gcCB8fCBuZXcgQXJyYXkobilcbiAgdmFyIHMsIHQsIGksIG5mPTFcbiAgcFswXSA9IDBcbiAgZm9yKGk9MTsgaTxuOyArK2kpIHtcbiAgICBwW2ldID0gaVxuICAgIG5mID0gKG5mKmkpfDBcbiAgfVxuICBmb3IoaT1uLTE7IGk+MDsgLS1pKSB7XG4gICAgcyA9IChyIC8gbmYpfDBcbiAgICByID0gKHIgLSBzICogbmYpfDBcbiAgICBuZiA9IChuZiAvIGkpfDBcbiAgICB0ID0gcFtpXXwwXG4gICAgcFtpXSA9IHBbc118MFxuICAgIHBbc10gPSB0fDBcbiAgfVxuICByZXR1cm4gcFxufVxuXG5leHBvcnRzLnJhbmsgPSByYW5rXG5leHBvcnRzLnVucmFuayA9IHVucmFua1xuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuZnVuY3Rpb24gaW52ZXJ0UGVybXV0YXRpb24ocGksIHJlc3VsdCkge1xuICByZXN1bHQgPSByZXN1bHQgfHwgbmV3IEFycmF5KHBpLmxlbmd0aClcbiAgZm9yKHZhciBpPTA7IGk8cGkubGVuZ3RoOyArK2kpIHtcbiAgICByZXN1bHRbcGlbaV1dID0gaVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbnZlcnRQZXJtdXRhdGlvbiIsIihmdW5jdGlvbiAoZ2xvYmFsLEJ1ZmZlcil7XG4ndXNlIHN0cmljdCdcblxudmFyIGJpdHMgPSByZXF1aXJlKCdiaXQtdHdpZGRsZScpXG52YXIgZHVwID0gcmVxdWlyZSgnZHVwJylcblxuLy9MZWdhY3kgcG9vbCBzdXBwb3J0XG5pZighZ2xvYmFsLl9fVFlQRURBUlJBWV9QT09MKSB7XG4gIGdsb2JhbC5fX1RZUEVEQVJSQVlfUE9PTCA9IHtcbiAgICAgIFVJTlQ4ICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQxNiAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQzMiAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDggICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDE2ICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIElOVDMyICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIEZMT0FUICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIERPVUJMRSAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIERBVEEgICAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIFVJTlQ4QyAgOiBkdXAoWzMyLCAwXSlcbiAgICAsIEJVRkZFUiAgOiBkdXAoWzMyLCAwXSlcbiAgfVxufVxuXG52YXIgaGFzVWludDhDID0gKHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSkgIT09ICd1bmRlZmluZWQnXG52YXIgUE9PTCA9IGdsb2JhbC5fX1RZUEVEQVJSQVlfUE9PTFxuXG4vL1VwZ3JhZGUgcG9vbFxuaWYoIVBPT0wuVUlOVDhDKSB7XG4gIFBPT0wuVUlOVDhDID0gZHVwKFszMiwgMF0pXG59XG5pZighUE9PTC5CVUZGRVIpIHtcbiAgUE9PTC5CVUZGRVIgPSBkdXAoWzMyLCAwXSlcbn1cblxuLy9OZXcgdGVjaG5pcXVlOiBPbmx5IGFsbG9jYXRlIGZyb20gQXJyYXlCdWZmZXJWaWV3IGFuZCBCdWZmZXJcbnZhciBEQVRBICAgID0gUE9PTC5EQVRBXG4gICwgQlVGRkVSICA9IFBPT0wuQlVGRkVSXG5cbmV4cG9ydHMuZnJlZSA9IGZ1bmN0aW9uIGZyZWUoYXJyYXkpIHtcbiAgaWYoQnVmZmVyLmlzQnVmZmVyKGFycmF5KSkge1xuICAgIEJVRkZFUltiaXRzLmxvZzIoYXJyYXkubGVuZ3RoKV0ucHVzaChhcnJheSlcbiAgfSBlbHNlIHtcbiAgICBpZihPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyYXkpICE9PSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nKSB7XG4gICAgICBhcnJheSA9IGFycmF5LmJ1ZmZlclxuICAgIH1cbiAgICBpZighYXJyYXkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB2YXIgbiA9IGFycmF5Lmxlbmd0aCB8fCBhcnJheS5ieXRlTGVuZ3RoXG4gICAgdmFyIGxvZ19uID0gYml0cy5sb2cyKG4pfDBcbiAgICBEQVRBW2xvZ19uXS5wdXNoKGFycmF5KVxuICB9XG59XG5cbmZ1bmN0aW9uIGZyZWVBcnJheUJ1ZmZlcihidWZmZXIpIHtcbiAgaWYoIWJ1ZmZlcikge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBuID0gYnVmZmVyLmxlbmd0aCB8fCBidWZmZXIuYnl0ZUxlbmd0aFxuICB2YXIgbG9nX24gPSBiaXRzLmxvZzIobilcbiAgREFUQVtsb2dfbl0ucHVzaChidWZmZXIpXG59XG5cbmZ1bmN0aW9uIGZyZWVUeXBlZEFycmF5KGFycmF5KSB7XG4gIGZyZWVBcnJheUJ1ZmZlcihhcnJheS5idWZmZXIpXG59XG5cbmV4cG9ydHMuZnJlZVVpbnQ4ID1cbmV4cG9ydHMuZnJlZVVpbnQxNiA9XG5leHBvcnRzLmZyZWVVaW50MzIgPVxuZXhwb3J0cy5mcmVlSW50OCA9XG5leHBvcnRzLmZyZWVJbnQxNiA9XG5leHBvcnRzLmZyZWVJbnQzMiA9XG5leHBvcnRzLmZyZWVGbG9hdDMyID0gXG5leHBvcnRzLmZyZWVGbG9hdCA9XG5leHBvcnRzLmZyZWVGbG9hdDY0ID0gXG5leHBvcnRzLmZyZWVEb3VibGUgPSBcbmV4cG9ydHMuZnJlZVVpbnQ4Q2xhbXBlZCA9IFxuZXhwb3J0cy5mcmVlRGF0YVZpZXcgPSBmcmVlVHlwZWRBcnJheVxuXG5leHBvcnRzLmZyZWVBcnJheUJ1ZmZlciA9IGZyZWVBcnJheUJ1ZmZlclxuXG5leHBvcnRzLmZyZWVCdWZmZXIgPSBmdW5jdGlvbiBmcmVlQnVmZmVyKGFycmF5KSB7XG4gIEJVRkZFUltiaXRzLmxvZzIoYXJyYXkubGVuZ3RoKV0ucHVzaChhcnJheSlcbn1cblxuZXhwb3J0cy5tYWxsb2MgPSBmdW5jdGlvbiBtYWxsb2MobiwgZHR5cGUpIHtcbiAgaWYoZHR5cGUgPT09IHVuZGVmaW5lZCB8fCBkdHlwZSA9PT0gJ2FycmF5YnVmZmVyJykge1xuICAgIHJldHVybiBtYWxsb2NBcnJheUJ1ZmZlcihuKVxuICB9IGVsc2Uge1xuICAgIHN3aXRjaChkdHlwZSkge1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgICByZXR1cm4gbWFsbG9jVWludDgobilcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICAgIHJldHVybiBtYWxsb2NVaW50MTYobilcbiAgICAgIGNhc2UgJ3VpbnQzMic6XG4gICAgICAgIHJldHVybiBtYWxsb2NVaW50MzIobilcbiAgICAgIGNhc2UgJ2ludDgnOlxuICAgICAgICByZXR1cm4gbWFsbG9jSW50OChuKVxuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgICByZXR1cm4gbWFsbG9jSW50MTYobilcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0ludDMyKG4pXG4gICAgICBjYXNlICdmbG9hdCc6XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0Zsb2F0KG4pXG4gICAgICBjYXNlICdkb3VibGUnOlxuICAgICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICAgIHJldHVybiBtYWxsb2NEb3VibGUobilcbiAgICAgIGNhc2UgJ3VpbnQ4X2NsYW1wZWQnOlxuICAgICAgICByZXR1cm4gbWFsbG9jVWludDhDbGFtcGVkKG4pXG4gICAgICBjYXNlICdidWZmZXInOlxuICAgICAgICByZXR1cm4gbWFsbG9jQnVmZmVyKG4pXG4gICAgICBjYXNlICdkYXRhJzpcbiAgICAgIGNhc2UgJ2RhdGF2aWV3JzpcbiAgICAgICAgcmV0dXJuIG1hbGxvY0RhdGFWaWV3KG4pXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsXG59XG5cbmZ1bmN0aW9uIG1hbGxvY0FycmF5QnVmZmVyKG4pIHtcbiAgdmFyIG4gPSBiaXRzLm5leHRQb3cyKG4pXG4gIHZhciBsb2dfbiA9IGJpdHMubG9nMihuKVxuICB2YXIgZCA9IERBVEFbbG9nX25dXG4gIGlmKGQubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBkLnBvcCgpXG4gIH1cbiAgcmV0dXJuIG5ldyBBcnJheUJ1ZmZlcihuKVxufVxuZXhwb3J0cy5tYWxsb2NBcnJheUJ1ZmZlciA9IG1hbGxvY0FycmF5QnVmZmVyXG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQ4KG4pIHtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KG1hbGxvY0FycmF5QnVmZmVyKG4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NVaW50OCA9IG1hbGxvY1VpbnQ4XG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQxNihuKSB7XG4gIHJldHVybiBuZXcgVWludDE2QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoMipuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jVWludDE2ID0gbWFsbG9jVWludDE2XG5cbmZ1bmN0aW9uIG1hbGxvY1VpbnQzMihuKSB7XG4gIHJldHVybiBuZXcgVWludDMyQXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoNCpuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jVWludDMyID0gbWFsbG9jVWludDMyXG5cbmZ1bmN0aW9uIG1hbGxvY0ludDgobikge1xuICByZXR1cm4gbmV3IEludDhBcnJheShtYWxsb2NBcnJheUJ1ZmZlcihuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jSW50OCA9IG1hbGxvY0ludDhcblxuZnVuY3Rpb24gbWFsbG9jSW50MTYobikge1xuICByZXR1cm4gbmV3IEludDE2QXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoMipuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jSW50MTYgPSBtYWxsb2NJbnQxNlxuXG5mdW5jdGlvbiBtYWxsb2NJbnQzMihuKSB7XG4gIHJldHVybiBuZXcgSW50MzJBcnJheShtYWxsb2NBcnJheUJ1ZmZlcig0Km4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NJbnQzMiA9IG1hbGxvY0ludDMyXG5cbmZ1bmN0aW9uIG1hbGxvY0Zsb2F0KG4pIHtcbiAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkobWFsbG9jQXJyYXlCdWZmZXIoNCpuKSwgMCwgbilcbn1cbmV4cG9ydHMubWFsbG9jRmxvYXQzMiA9IGV4cG9ydHMubWFsbG9jRmxvYXQgPSBtYWxsb2NGbG9hdFxuXG5mdW5jdGlvbiBtYWxsb2NEb3VibGUobikge1xuICByZXR1cm4gbmV3IEZsb2F0NjRBcnJheShtYWxsb2NBcnJheUJ1ZmZlcig4Km4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NGbG9hdDY0ID0gZXhwb3J0cy5tYWxsb2NEb3VibGUgPSBtYWxsb2NEb3VibGVcblxuZnVuY3Rpb24gbWFsbG9jVWludDhDbGFtcGVkKG4pIHtcbiAgaWYoaGFzVWludDhDKSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OENsYW1wZWRBcnJheShtYWxsb2NBcnJheUJ1ZmZlcihuKSwgMCwgbilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbWFsbG9jVWludDgobilcbiAgfVxufVxuZXhwb3J0cy5tYWxsb2NVaW50OENsYW1wZWQgPSBtYWxsb2NVaW50OENsYW1wZWRcblxuZnVuY3Rpb24gbWFsbG9jRGF0YVZpZXcobikge1xuICByZXR1cm4gbmV3IERhdGFWaWV3KG1hbGxvY0FycmF5QnVmZmVyKG4pLCAwLCBuKVxufVxuZXhwb3J0cy5tYWxsb2NEYXRhVmlldyA9IG1hbGxvY0RhdGFWaWV3XG5cbmZ1bmN0aW9uIG1hbGxvY0J1ZmZlcihuKSB7XG4gIG4gPSBiaXRzLm5leHRQb3cyKG4pXG4gIHZhciBsb2dfbiA9IGJpdHMubG9nMihuKVxuICB2YXIgY2FjaGUgPSBCVUZGRVJbbG9nX25dXG4gIGlmKGNhY2hlLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gY2FjaGUucG9wKClcbiAgfVxuICByZXR1cm4gbmV3IEJ1ZmZlcihuKVxufVxuZXhwb3J0cy5tYWxsb2NCdWZmZXIgPSBtYWxsb2NCdWZmZXJcblxuZXhwb3J0cy5jbGVhckNhY2hlID0gZnVuY3Rpb24gY2xlYXJDYWNoZSgpIHtcbiAgZm9yKHZhciBpPTA7IGk8MzI7ICsraSkge1xuICAgIFBPT0wuVUlOVDhbaV0ubGVuZ3RoID0gMFxuICAgIFBPT0wuVUlOVDE2W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLlVJTlQzMltpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5JTlQ4W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLklOVDE2W2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLklOVDMyW2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLkZMT0FUW2ldLmxlbmd0aCA9IDBcbiAgICBQT09MLkRPVUJMRVtpXS5sZW5ndGggPSAwXG4gICAgUE9PTC5VSU5UOENbaV0ubGVuZ3RoID0gMFxuICAgIERBVEFbaV0ubGVuZ3RoID0gMFxuICAgIEJVRkZFUltpXS5sZW5ndGggPSAwXG4gIH1cbn1cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OTBjbWxoYm1kMWJHRjBaUzFvZVhCbGNtTjFZbVV2Ym05a1pWOXRiMlIxYkdWekwzQmxjbTExZEdGMGFXOXVMWEpoYm1zdmJtOWtaVjl0YjJSMWJHVnpMM1I1Y0dWa1lYSnlZWGt0Y0c5dmJDOXdiMjlzTG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVNJc0ltWnBiR1VpT2lKblpXNWxjbUYwWldRdWFuTWlMQ0p6YjNWeVkyVlNiMjkwSWpvaUlpd2ljMjkxY21ObGMwTnZiblJsYm5RaU9sc2lKM1Z6WlNCemRISnBZM1FuWEc1Y2JuWmhjaUJpYVhSeklEMGdjbVZ4ZFdseVpTZ25ZbWwwTFhSM2FXUmtiR1VuS1Z4dWRtRnlJR1IxY0NBOUlISmxjWFZwY21Vb0oyUjFjQ2NwWEc1Y2JpOHZUR1ZuWVdONUlIQnZiMndnYzNWd2NHOXlkRnh1YVdZb0lXZHNiMkpoYkM1ZlgxUlpVRVZFUVZKU1FWbGZVRTlQVENrZ2UxeHVJQ0JuYkc5aVlXd3VYMTlVV1ZCRlJFRlNVa0ZaWDFCUFQwd2dQU0I3WEc0Z0lDQWdJQ0JWU1U1VU9DQWdJRG9nWkhWd0tGc3pNaXdnTUYwcFhHNGdJQ0FnTENCVlNVNVVNVFlnSURvZ1pIVndLRnN6TWl3Z01GMHBYRzRnSUNBZ0xDQlZTVTVVTXpJZ0lEb2daSFZ3S0Zzek1pd2dNRjBwWEc0Z0lDQWdMQ0JKVGxRNElDQWdJRG9nWkhWd0tGc3pNaXdnTUYwcFhHNGdJQ0FnTENCSlRsUXhOaUFnSURvZ1pIVndLRnN6TWl3Z01GMHBYRzRnSUNBZ0xDQkpUbFF6TWlBZ0lEb2daSFZ3S0Zzek1pd2dNRjBwWEc0Z0lDQWdMQ0JHVEU5QlZDQWdJRG9nWkhWd0tGc3pNaXdnTUYwcFhHNGdJQ0FnTENCRVQxVkNURVVnSURvZ1pIVndLRnN6TWl3Z01GMHBYRzRnSUNBZ0xDQkVRVlJCSUNBZ0lEb2daSFZ3S0Zzek1pd2dNRjBwWEc0Z0lDQWdMQ0JWU1U1VU9FTWdJRG9nWkhWd0tGc3pNaXdnTUYwcFhHNGdJQ0FnTENCQ1ZVWkdSVklnSURvZ1pIVndLRnN6TWl3Z01GMHBYRzRnSUgxY2JuMWNibHh1ZG1GeUlHaGhjMVZwYm5RNFF5QTlJQ2gwZVhCbGIyWWdWV2x1ZERoRGJHRnRjR1ZrUVhKeVlYa3BJQ0U5UFNBbmRXNWtaV1pwYm1Wa0oxeHVkbUZ5SUZCUFQwd2dQU0JuYkc5aVlXd3VYMTlVV1ZCRlJFRlNVa0ZaWDFCUFQweGNibHh1THk5VmNHZHlZV1JsSUhCdmIyeGNibWxtS0NGUVQwOU1MbFZKVGxRNFF5a2dlMXh1SUNCUVQwOU1MbFZKVGxRNFF5QTlJR1IxY0NoYk16SXNJREJkS1Z4dWZWeHVhV1lvSVZCUFQwd3VRbFZHUmtWU0tTQjdYRzRnSUZCUFQwd3VRbFZHUmtWU0lEMGdaSFZ3S0Zzek1pd2dNRjBwWEc1OVhHNWNiaTh2VG1WM0lIUmxZMmh1YVhGMVpUb2dUMjVzZVNCaGJHeHZZMkYwWlNCbWNtOXRJRUZ5Y21GNVFuVm1abVZ5Vm1sbGR5QmhibVFnUW5WbVptVnlYRzUyWVhJZ1JFRlVRU0FnSUNBOUlGQlBUMHd1UkVGVVFWeHVJQ0FzSUVKVlJrWkZVaUFnUFNCUVQwOU1Ma0pWUmtaRlVseHVYRzVsZUhCdmNuUnpMbVp5WldVZ1BTQm1kVzVqZEdsdmJpQm1jbVZsS0dGeWNtRjVLU0I3WEc0Z0lHbG1LRUoxWm1abGNpNXBjMEoxWm1abGNpaGhjbkpoZVNrcElIdGNiaUFnSUNCQ1ZVWkdSVkpiWW1sMGN5NXNiMmN5S0dGeWNtRjVMbXhsYm1kMGFDbGRMbkIxYzJnb1lYSnlZWGtwWEc0Z0lIMGdaV3h6WlNCN1hHNGdJQ0FnYVdZb1QySnFaV04wTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1Wnk1allXeHNLR0Z5Y21GNUtTQWhQVDBnSjF0dlltcGxZM1FnUVhKeVlYbENkV1ptWlhKZEp5a2dlMXh1SUNBZ0lDQWdZWEp5WVhrZ1BTQmhjbkpoZVM1aWRXWm1aWEpjYmlBZ0lDQjlYRzRnSUNBZ2FXWW9JV0Z5Y21GNUtTQjdYRzRnSUNBZ0lDQnlaWFIxY201Y2JpQWdJQ0I5WEc0Z0lDQWdkbUZ5SUc0Z1BTQmhjbkpoZVM1c1pXNW5kR2dnZkh3Z1lYSnlZWGt1WW5sMFpVeGxibWQwYUZ4dUlDQWdJSFpoY2lCc2IyZGZiaUE5SUdKcGRITXViRzluTWlodUtYd3dYRzRnSUNBZ1JFRlVRVnRzYjJkZmJsMHVjSFZ6YUNoaGNuSmhlU2xjYmlBZ2ZWeHVmVnh1WEc1bWRXNWpkR2x2YmlCbWNtVmxRWEp5WVhsQ2RXWm1aWElvWW5WbVptVnlLU0I3WEc0Z0lHbG1LQ0ZpZFdabVpYSXBJSHRjYmlBZ0lDQnlaWFIxY201Y2JpQWdmVnh1SUNCMllYSWdiaUE5SUdKMVptWmxjaTVzWlc1bmRHZ2dmSHdnWW5WbVptVnlMbUo1ZEdWTVpXNW5kR2hjYmlBZ2RtRnlJR3h2WjE5dUlEMGdZbWwwY3k1c2IyY3lLRzRwWEc0Z0lFUkJWRUZiYkc5blgyNWRMbkIxYzJnb1luVm1abVZ5S1Z4dWZWeHVYRzVtZFc1amRHbHZiaUJtY21WbFZIbHdaV1JCY25KaGVTaGhjbkpoZVNrZ2UxeHVJQ0JtY21WbFFYSnlZWGxDZFdabVpYSW9ZWEp5WVhrdVluVm1abVZ5S1Z4dWZWeHVYRzVsZUhCdmNuUnpMbVp5WldWVmFXNTBPQ0E5WEc1bGVIQnZjblJ6TG1aeVpXVlZhVzUwTVRZZ1BWeHVaWGh3YjNKMGN5NW1jbVZsVldsdWRETXlJRDFjYm1WNGNHOXlkSE11Wm5KbFpVbHVkRGdnUFZ4dVpYaHdiM0owY3k1bWNtVmxTVzUwTVRZZ1BWeHVaWGh3YjNKMGN5NW1jbVZsU1c1ME16SWdQVnh1Wlhod2IzSjBjeTVtY21WbFJteHZZWFF6TWlBOUlGeHVaWGh3YjNKMGN5NW1jbVZsUm14dllYUWdQVnh1Wlhod2IzSjBjeTVtY21WbFJteHZZWFEyTkNBOUlGeHVaWGh3YjNKMGN5NW1jbVZsUkc5MVlteGxJRDBnWEc1bGVIQnZjblJ6TG1aeVpXVlZhVzUwT0VOc1lXMXdaV1FnUFNCY2JtVjRjRzl5ZEhNdVpuSmxaVVJoZEdGV2FXVjNJRDBnWm5KbFpWUjVjR1ZrUVhKeVlYbGNibHh1Wlhod2IzSjBjeTVtY21WbFFYSnlZWGxDZFdabVpYSWdQU0JtY21WbFFYSnlZWGxDZFdabVpYSmNibHh1Wlhod2IzSjBjeTVtY21WbFFuVm1abVZ5SUQwZ1puVnVZM1JwYjI0Z1puSmxaVUoxWm1abGNpaGhjbkpoZVNrZ2UxeHVJQ0JDVlVaR1JWSmJZbWwwY3k1c2IyY3lLR0Z5Y21GNUxteGxibWQwYUNsZExuQjFjMmdvWVhKeVlYa3BYRzU5WEc1Y2JtVjRjRzl5ZEhNdWJXRnNiRzlqSUQwZ1puVnVZM1JwYjI0Z2JXRnNiRzlqS0c0c0lHUjBlWEJsS1NCN1hHNGdJR2xtS0dSMGVYQmxJRDA5UFNCMWJtUmxabWx1WldRZ2ZId2daSFI1Y0dVZ1BUMDlJQ2RoY25KaGVXSjFabVpsY2ljcElIdGNiaUFnSUNCeVpYUjFjbTRnYldGc2JHOWpRWEp5WVhsQ2RXWm1aWElvYmlsY2JpQWdmU0JsYkhObElIdGNiaUFnSUNCemQybDBZMmdvWkhSNWNHVXBJSHRjYmlBZ0lDQWdJR05oYzJVZ0ozVnBiblE0SnpwY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUcxaGJHeHZZMVZwYm5RNEtHNHBYRzRnSUNBZ0lDQmpZWE5sSUNkMWFXNTBNVFluT2x4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnYldGc2JHOWpWV2x1ZERFMktHNHBYRzRnSUNBZ0lDQmpZWE5sSUNkMWFXNTBNekluT2x4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnYldGc2JHOWpWV2x1ZERNeUtHNHBYRzRnSUNBZ0lDQmpZWE5sSUNkcGJuUTRKenBjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRzFoYkd4dlkwbHVkRGdvYmlsY2JpQWdJQ0FnSUdOaGMyVWdKMmx1ZERFMkp6cGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHMWhiR3h2WTBsdWRERTJLRzRwWEc0Z0lDQWdJQ0JqWVhObElDZHBiblF6TWljNlhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCdFlXeHNiMk5KYm5Rek1paHVLVnh1SUNBZ0lDQWdZMkZ6WlNBblpteHZZWFFuT2x4dUlDQWdJQ0FnWTJGelpTQW5abXh2WVhRek1pYzZYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQnRZV3hzYjJOR2JHOWhkQ2h1S1Z4dUlDQWdJQ0FnWTJGelpTQW5aRzkxWW14bEp6cGNiaUFnSUNBZ0lHTmhjMlVnSjJac2IyRjBOalFuT2x4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnYldGc2JHOWpSRzkxWW14bEtHNHBYRzRnSUNBZ0lDQmpZWE5sSUNkMWFXNTBPRjlqYkdGdGNHVmtKenBjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRzFoYkd4dlkxVnBiblE0UTJ4aGJYQmxaQ2h1S1Z4dUlDQWdJQ0FnWTJGelpTQW5ZblZtWm1WeUp6cGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHMWhiR3h2WTBKMVptWmxjaWh1S1Z4dUlDQWdJQ0FnWTJGelpTQW5aR0YwWVNjNlhHNGdJQ0FnSUNCallYTmxJQ2RrWVhSaGRtbGxkeWM2WEc0Z0lDQWdJQ0FnSUhKbGRIVnliaUJ0WVd4c2IyTkVZWFJoVm1sbGR5aHVLVnh1WEc0Z0lDQWdJQ0JrWldaaGRXeDBPbHh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdiblZzYkZ4dUlDQWdJSDFjYmlBZ2ZWeHVJQ0J5WlhSMWNtNGdiblZzYkZ4dWZWeHVYRzVtZFc1amRHbHZiaUJ0WVd4c2IyTkJjbkpoZVVKMVptWmxjaWh1S1NCN1hHNGdJSFpoY2lCdUlEMGdZbWwwY3k1dVpYaDBVRzkzTWlodUtWeHVJQ0IyWVhJZ2JHOW5YMjRnUFNCaWFYUnpMbXh2WnpJb2JpbGNiaUFnZG1GeUlHUWdQU0JFUVZSQlcyeHZaMTl1WFZ4dUlDQnBaaWhrTG14bGJtZDBhQ0ErSURBcElIdGNiaUFnSUNCeVpYUjFjbTRnWkM1d2IzQW9LVnh1SUNCOVhHNGdJSEpsZEhWeWJpQnVaWGNnUVhKeVlYbENkV1ptWlhJb2JpbGNibjFjYm1WNGNHOXlkSE11YldGc2JHOWpRWEp5WVhsQ2RXWm1aWElnUFNCdFlXeHNiMk5CY25KaGVVSjFabVpsY2x4dVhHNW1kVzVqZEdsdmJpQnRZV3hzYjJOVmFXNTBPQ2h1S1NCN1hHNGdJSEpsZEhWeWJpQnVaWGNnVldsdWREaEJjbkpoZVNodFlXeHNiMk5CY25KaGVVSjFabVpsY2lodUtTd2dNQ3dnYmlsY2JuMWNibVY0Y0c5eWRITXViV0ZzYkc5alZXbHVkRGdnUFNCdFlXeHNiMk5WYVc1ME9GeHVYRzVtZFc1amRHbHZiaUJ0WVd4c2IyTlZhVzUwTVRZb2Jpa2dlMXh1SUNCeVpYUjFjbTRnYm1WM0lGVnBiblF4TmtGeWNtRjVLRzFoYkd4dlkwRnljbUY1UW5WbVptVnlLRElxYmlrc0lEQXNJRzRwWEc1OVhHNWxlSEJ2Y25SekxtMWhiR3h2WTFWcGJuUXhOaUE5SUcxaGJHeHZZMVZwYm5ReE5seHVYRzVtZFc1amRHbHZiaUJ0WVd4c2IyTlZhVzUwTXpJb2Jpa2dlMXh1SUNCeVpYUjFjbTRnYm1WM0lGVnBiblF6TWtGeWNtRjVLRzFoYkd4dlkwRnljbUY1UW5WbVptVnlLRFFxYmlrc0lEQXNJRzRwWEc1OVhHNWxlSEJ2Y25SekxtMWhiR3h2WTFWcGJuUXpNaUE5SUcxaGJHeHZZMVZwYm5Rek1seHVYRzVtZFc1amRHbHZiaUJ0WVd4c2IyTkpiblE0S0c0cElIdGNiaUFnY21WMGRYSnVJRzVsZHlCSmJuUTRRWEp5WVhrb2JXRnNiRzlqUVhKeVlYbENkV1ptWlhJb2Jpa3NJREFzSUc0cFhHNTlYRzVsZUhCdmNuUnpMbTFoYkd4dlkwbHVkRGdnUFNCdFlXeHNiMk5KYm5RNFhHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkwbHVkREUyS0c0cElIdGNiaUFnY21WMGRYSnVJRzVsZHlCSmJuUXhOa0Z5Y21GNUtHMWhiR3h2WTBGeWNtRjVRblZtWm1WeUtESXFiaWtzSURBc0lHNHBYRzU5WEc1bGVIQnZjblJ6TG0xaGJHeHZZMGx1ZERFMklEMGdiV0ZzYkc5alNXNTBNVFpjYmx4dVpuVnVZM1JwYjI0Z2JXRnNiRzlqU1c1ME16SW9iaWtnZTF4dUlDQnlaWFIxY200Z2JtVjNJRWx1ZERNeVFYSnlZWGtvYldGc2JHOWpRWEp5WVhsQ2RXWm1aWElvTkNwdUtTd2dNQ3dnYmlsY2JuMWNibVY0Y0c5eWRITXViV0ZzYkc5alNXNTBNeklnUFNCdFlXeHNiMk5KYm5Rek1seHVYRzVtZFc1amRHbHZiaUJ0WVd4c2IyTkdiRzloZENodUtTQjdYRzRnSUhKbGRIVnliaUJ1WlhjZ1JteHZZWFF6TWtGeWNtRjVLRzFoYkd4dlkwRnljbUY1UW5WbVptVnlLRFFxYmlrc0lEQXNJRzRwWEc1OVhHNWxlSEJ2Y25SekxtMWhiR3h2WTBac2IyRjBNeklnUFNCbGVIQnZjblJ6TG0xaGJHeHZZMFpzYjJGMElEMGdiV0ZzYkc5alJteHZZWFJjYmx4dVpuVnVZM1JwYjI0Z2JXRnNiRzlqUkc5MVlteGxLRzRwSUh0Y2JpQWdjbVYwZFhKdUlHNWxkeUJHYkc5aGREWTBRWEp5WVhrb2JXRnNiRzlqUVhKeVlYbENkV1ptWlhJb09DcHVLU3dnTUN3Z2JpbGNibjFjYm1WNGNHOXlkSE11YldGc2JHOWpSbXh2WVhRMk5DQTlJR1Y0Y0c5eWRITXViV0ZzYkc5alJHOTFZbXhsSUQwZ2JXRnNiRzlqUkc5MVlteGxYRzVjYm1aMWJtTjBhVzl1SUcxaGJHeHZZMVZwYm5RNFEyeGhiWEJsWkNodUtTQjdYRzRnSUdsbUtHaGhjMVZwYm5RNFF5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCdVpYY2dWV2x1ZERoRGJHRnRjR1ZrUVhKeVlYa29iV0ZzYkc5alFYSnlZWGxDZFdabVpYSW9iaWtzSURBc0lHNHBYRzRnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdjbVYwZFhKdUlHMWhiR3h2WTFWcGJuUTRLRzRwWEc0Z0lIMWNibjFjYm1WNGNHOXlkSE11YldGc2JHOWpWV2x1ZERoRGJHRnRjR1ZrSUQwZ2JXRnNiRzlqVldsdWREaERiR0Z0Y0dWa1hHNWNibVoxYm1OMGFXOXVJRzFoYkd4dlkwUmhkR0ZXYVdWM0tHNHBJSHRjYmlBZ2NtVjBkWEp1SUc1bGR5QkVZWFJoVm1sbGR5aHRZV3hzYjJOQmNuSmhlVUoxWm1abGNpaHVLU3dnTUN3Z2JpbGNibjFjYm1WNGNHOXlkSE11YldGc2JHOWpSR0YwWVZacFpYY2dQU0J0WVd4c2IyTkVZWFJoVm1sbGQxeHVYRzVtZFc1amRHbHZiaUJ0WVd4c2IyTkNkV1ptWlhJb2Jpa2dlMXh1SUNCdUlEMGdZbWwwY3k1dVpYaDBVRzkzTWlodUtWeHVJQ0IyWVhJZ2JHOW5YMjRnUFNCaWFYUnpMbXh2WnpJb2JpbGNiaUFnZG1GeUlHTmhZMmhsSUQwZ1FsVkdSa1ZTVzJ4dloxOXVYVnh1SUNCcFppaGpZV05vWlM1c1pXNW5kR2dnUGlBd0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUdOaFkyaGxMbkJ2Y0NncFhHNGdJSDFjYmlBZ2NtVjBkWEp1SUc1bGR5QkNkV1ptWlhJb2JpbGNibjFjYm1WNGNHOXlkSE11YldGc2JHOWpRblZtWm1WeUlEMGdiV0ZzYkc5alFuVm1abVZ5WEc1Y2JtVjRjRzl5ZEhNdVkyeGxZWEpEWVdOb1pTQTlJR1oxYm1OMGFXOXVJR05zWldGeVEyRmphR1VvS1NCN1hHNGdJR1p2Y2loMllYSWdhVDB3T3lCcFBETXlPeUFySzJrcElIdGNiaUFnSUNCUVQwOU1MbFZKVGxRNFcybGRMbXhsYm1kMGFDQTlJREJjYmlBZ0lDQlFUMDlNTGxWSlRsUXhObHRwWFM1c1pXNW5kR2dnUFNBd1hHNGdJQ0FnVUU5UFRDNVZTVTVVTXpKYmFWMHViR1Z1WjNSb0lEMGdNRnh1SUNBZ0lGQlBUMHd1U1U1VU9GdHBYUzVzWlc1bmRHZ2dQU0F3WEc0Z0lDQWdVRTlQVEM1SlRsUXhObHRwWFM1c1pXNW5kR2dnUFNBd1hHNGdJQ0FnVUU5UFRDNUpUbFF6TWx0cFhTNXNaVzVuZEdnZ1BTQXdYRzRnSUNBZ1VFOVBUQzVHVEU5QlZGdHBYUzVzWlc1bmRHZ2dQU0F3WEc0Z0lDQWdVRTlQVEM1RVQxVkNURVZiYVYwdWJHVnVaM1JvSUQwZ01GeHVJQ0FnSUZCUFQwd3VWVWxPVkRoRFcybGRMbXhsYm1kMGFDQTlJREJjYmlBZ0lDQkVRVlJCVzJsZExteGxibWQwYUNBOUlEQmNiaUFnSUNCQ1ZVWkdSVkpiYVYwdWJHVnVaM1JvSUQwZ01GeHVJQ0I5WEc1OUlsMTkiLCJcInVzZSBzdHJpY3RcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IHRyaWFuZ3VsYXRlQ3ViZVxuXG52YXIgcGVybSA9IHJlcXVpcmUoXCJwZXJtdXRhdGlvbi1yYW5rXCIpXG52YXIgc2duID0gcmVxdWlyZShcInBlcm11dGF0aW9uLXBhcml0eVwiKVxudmFyIGdhbW1hID0gcmVxdWlyZShcImdhbW1hXCIpXG5cbmZ1bmN0aW9uIHRyaWFuZ3VsYXRlQ3ViZShkaW1lbnNpb24pIHtcbiAgaWYoZGltZW5zaW9uIDwgMCkge1xuICAgIHJldHVybiBbIF1cbiAgfVxuICBpZihkaW1lbnNpb24gPT09IDApIHtcbiAgICByZXR1cm4gWyBbMF0gXVxuICB9XG4gIHZhciBkZmFjdG9yaWFsID0gTWF0aC5yb3VuZChnYW1tYShkaW1lbnNpb24rMSkpfDBcbiAgdmFyIHJlc3VsdCA9IFtdXG4gIGZvcih2YXIgaT0wOyBpPGRmYWN0b3JpYWw7ICsraSkge1xuICAgIHZhciBwID0gcGVybS51bnJhbmsoZGltZW5zaW9uLCBpKVxuICAgIHZhciBjZWxsID0gWyAwIF1cbiAgICB2YXIgdiA9IDBcbiAgICBmb3IodmFyIGo9MDsgajxwLmxlbmd0aDsgKytqKSB7XG4gICAgICB2ICs9ICgxPDxwW2pdKVxuICAgICAgY2VsbC5wdXNoKHYpXG4gICAgfVxuICAgIGlmKHNnbihwKSA8IDEpIHtcbiAgICAgIGNlbGxbMF0gPSB2XG4gICAgICBjZWxsW2RpbWVuc2lvbl0gPSAwXG4gICAgfVxuICAgIHJlc3VsdC5wdXNoKGNlbGwpXG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufSIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnY3dpc2UtY29tcGlsZXInKSh7XG4gICAgYXJnczogWydhcnJheScsIHtcbiAgICAgICAgb2Zmc2V0OiBbMV0sXG4gICAgICAgIGFycmF5OiAwXG4gICAgfSwgJ3NjYWxhcicsICdzY2FsYXInLCAnaW5kZXgnXSxcbiAgICBwcmU6IHtcbiAgICAgICAgXCJib2R5XCI6IFwie31cIixcbiAgICAgICAgXCJhcmdzXCI6IFtdLFxuICAgICAgICBcInRoaXNWYXJzXCI6IFtdLFxuICAgICAgICBcImxvY2FsVmFyc1wiOiBbXVxuICAgIH0sXG4gICAgcG9zdDoge1xuICAgICAgICBcImJvZHlcIjogXCJ7fVwiLFxuICAgICAgICBcImFyZ3NcIjogW10sXG4gICAgICAgIFwidGhpc1ZhcnNcIjogW10sXG4gICAgICAgIFwibG9jYWxWYXJzXCI6IFtdXG4gICAgfSxcbiAgICBib2R5OiB7XG4gICAgICAgIFwiYm9keVwiOiBcIntcXG4gICAgICAgIHZhciBfaW5saW5lXzFfZGEgPSBfaW5saW5lXzFfYXJnMF8gLSBfaW5saW5lXzFfYXJnM19cXG4gICAgICAgIHZhciBfaW5saW5lXzFfZGIgPSBfaW5saW5lXzFfYXJnMV8gLSBfaW5saW5lXzFfYXJnM19cXG4gICAgICAgIGlmKChfaW5saW5lXzFfZGEgPj0gMCkgIT09IChfaW5saW5lXzFfZGIgPj0gMCkpIHtcXG4gICAgICAgICAgX2lubGluZV8xX2FyZzJfLnB1c2goX2lubGluZV8xX2FyZzRfWzBdICsgMC41ICsgMC41ICogKF9pbmxpbmVfMV9kYSArIF9pbmxpbmVfMV9kYikgLyAoX2lubGluZV8xX2RhIC0gX2lubGluZV8xX2RiKSlcXG4gICAgICAgIH1cXG4gICAgICB9XCIsXG4gICAgICAgIFwiYXJnc1wiOiBbe1xuICAgICAgICAgICAgXCJuYW1lXCI6IFwiX2lubGluZV8xX2FyZzBfXCIsXG4gICAgICAgICAgICBcImx2YWx1ZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwicnZhbHVlXCI6IHRydWUsXG4gICAgICAgICAgICBcImNvdW50XCI6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgICAgXCJuYW1lXCI6IFwiX2lubGluZV8xX2FyZzFfXCIsXG4gICAgICAgICAgICBcImx2YWx1ZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwicnZhbHVlXCI6IHRydWUsXG4gICAgICAgICAgICBcImNvdW50XCI6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgICAgXCJuYW1lXCI6IFwiX2lubGluZV8xX2FyZzJfXCIsXG4gICAgICAgICAgICBcImx2YWx1ZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwicnZhbHVlXCI6IHRydWUsXG4gICAgICAgICAgICBcImNvdW50XCI6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgICAgXCJuYW1lXCI6IFwiX2lubGluZV8xX2FyZzNfXCIsXG4gICAgICAgICAgICBcImx2YWx1ZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwicnZhbHVlXCI6IHRydWUsXG4gICAgICAgICAgICBcImNvdW50XCI6IDJcbiAgICAgICAgfSwge1xuICAgICAgICAgICAgXCJuYW1lXCI6IFwiX2lubGluZV8xX2FyZzRfXCIsXG4gICAgICAgICAgICBcImx2YWx1ZVwiOiBmYWxzZSxcbiAgICAgICAgICAgIFwicnZhbHVlXCI6IHRydWUsXG4gICAgICAgICAgICBcImNvdW50XCI6IDFcbiAgICAgICAgfV0sXG4gICAgICAgIFwidGhpc1ZhcnNcIjogW10sXG4gICAgICAgIFwibG9jYWxWYXJzXCI6IFtcIl9pbmxpbmVfMV9kYVwiLCBcIl9pbmxpbmVfMV9kYlwiXVxuICAgIH0sXG4gICAgZnVuY05hbWU6ICd6ZXJvQ3Jvc3NpbmdzJ1xufSlcbiIsIlwidXNlIHN0cmljdFwiXHJcblxyXG52YXIgY3JlYXRlVGh1bmsgPSByZXF1aXJlKFwiLi9saWIvdGh1bmsuanNcIilcclxuXHJcbmZ1bmN0aW9uIFByb2NlZHVyZSgpIHtcclxuICB0aGlzLmFyZ1R5cGVzID0gW11cclxuICB0aGlzLnNoaW1BcmdzID0gW11cclxuICB0aGlzLmFycmF5QXJncyA9IFtdXHJcbiAgdGhpcy5hcnJheUJsb2NrSW5kaWNlcyA9IFtdXHJcbiAgdGhpcy5zY2FsYXJBcmdzID0gW11cclxuICB0aGlzLm9mZnNldEFyZ3MgPSBbXVxyXG4gIHRoaXMub2Zmc2V0QXJnSW5kZXggPSBbXVxyXG4gIHRoaXMuaW5kZXhBcmdzID0gW11cclxuICB0aGlzLnNoYXBlQXJncyA9IFtdXHJcbiAgdGhpcy5mdW5jTmFtZSA9IFwiXCJcclxuICB0aGlzLnByZSA9IG51bGxcclxuICB0aGlzLmJvZHkgPSBudWxsXHJcbiAgdGhpcy5wb3N0ID0gbnVsbFxyXG4gIHRoaXMuZGVidWcgPSBmYWxzZVxyXG59XHJcblxyXG5mdW5jdGlvbiBjb21waWxlQ3dpc2UodXNlcl9hcmdzKSB7XHJcbiAgLy9DcmVhdGUgcHJvY2VkdXJlXHJcbiAgdmFyIHByb2MgPSBuZXcgUHJvY2VkdXJlKClcclxuICBcclxuICAvL1BhcnNlIGJsb2Nrc1xyXG4gIHByb2MucHJlICAgID0gdXNlcl9hcmdzLnByZVxyXG4gIHByb2MuYm9keSAgID0gdXNlcl9hcmdzLmJvZHlcclxuICBwcm9jLnBvc3QgICA9IHVzZXJfYXJncy5wb3N0XHJcblxyXG4gIC8vUGFyc2UgYXJndW1lbnRzXHJcbiAgdmFyIHByb2NfYXJncyA9IHVzZXJfYXJncy5hcmdzLnNsaWNlKDApXHJcbiAgcHJvYy5hcmdUeXBlcyA9IHByb2NfYXJnc1xyXG4gIGZvcih2YXIgaT0wOyBpPHByb2NfYXJncy5sZW5ndGg7ICsraSkge1xyXG4gICAgdmFyIGFyZ190eXBlID0gcHJvY19hcmdzW2ldXHJcbiAgICBpZihhcmdfdHlwZSA9PT0gXCJhcnJheVwiIHx8ICh0eXBlb2YgYXJnX3R5cGUgPT09IFwib2JqZWN0XCIgJiYgYXJnX3R5cGUuYmxvY2tJbmRpY2VzKSkge1xyXG4gICAgICBwcm9jLmFyZ1R5cGVzW2ldID0gXCJhcnJheVwiXHJcbiAgICAgIHByb2MuYXJyYXlBcmdzLnB1c2goaSlcclxuICAgICAgcHJvYy5hcnJheUJsb2NrSW5kaWNlcy5wdXNoKGFyZ190eXBlLmJsb2NrSW5kaWNlcyA/IGFyZ190eXBlLmJsb2NrSW5kaWNlcyA6IDApXHJcbiAgICAgIHByb2Muc2hpbUFyZ3MucHVzaChcImFycmF5XCIgKyBpKVxyXG4gICAgICBpZihpIDwgcHJvYy5wcmUuYXJncy5sZW5ndGggJiYgcHJvYy5wcmUuYXJnc1tpXS5jb3VudD4wKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY3dpc2U6IHByZSgpIGJsb2NrIG1heSBub3QgcmVmZXJlbmNlIGFycmF5IGFyZ3NcIilcclxuICAgICAgfVxyXG4gICAgICBpZihpIDwgcHJvYy5wb3N0LmFyZ3MubGVuZ3RoICYmIHByb2MucG9zdC5hcmdzW2ldLmNvdW50PjApIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogcG9zdCgpIGJsb2NrIG1heSBub3QgcmVmZXJlbmNlIGFycmF5IGFyZ3NcIilcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmKGFyZ190eXBlID09PSBcInNjYWxhclwiKSB7XHJcbiAgICAgIHByb2Muc2NhbGFyQXJncy5wdXNoKGkpXHJcbiAgICAgIHByb2Muc2hpbUFyZ3MucHVzaChcInNjYWxhclwiICsgaSlcclxuICAgIH0gZWxzZSBpZihhcmdfdHlwZSA9PT0gXCJpbmRleFwiKSB7XHJcbiAgICAgIHByb2MuaW5kZXhBcmdzLnB1c2goaSlcclxuICAgICAgaWYoaSA8IHByb2MucHJlLmFyZ3MubGVuZ3RoICYmIHByb2MucHJlLmFyZ3NbaV0uY291bnQgPiAwKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY3dpc2U6IHByZSgpIGJsb2NrIG1heSBub3QgcmVmZXJlbmNlIGFycmF5IGluZGV4XCIpXHJcbiAgICAgIH1cclxuICAgICAgaWYoaSA8IHByb2MuYm9keS5hcmdzLmxlbmd0aCAmJiBwcm9jLmJvZHkuYXJnc1tpXS5sdmFsdWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogYm9keSgpIGJsb2NrIG1heSBub3Qgd3JpdGUgdG8gYXJyYXkgaW5kZXhcIilcclxuICAgICAgfVxyXG4gICAgICBpZihpIDwgcHJvYy5wb3N0LmFyZ3MubGVuZ3RoICYmIHByb2MucG9zdC5hcmdzW2ldLmNvdW50ID4gMCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImN3aXNlOiBwb3N0KCkgYmxvY2sgbWF5IG5vdCByZWZlcmVuY2UgYXJyYXkgaW5kZXhcIilcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmKGFyZ190eXBlID09PSBcInNoYXBlXCIpIHtcclxuICAgICAgcHJvYy5zaGFwZUFyZ3MucHVzaChpKVxyXG4gICAgICBpZihpIDwgcHJvYy5wcmUuYXJncy5sZW5ndGggJiYgcHJvYy5wcmUuYXJnc1tpXS5sdmFsdWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogcHJlKCkgYmxvY2sgbWF5IG5vdCB3cml0ZSB0byBhcnJheSBzaGFwZVwiKVxyXG4gICAgICB9XHJcbiAgICAgIGlmKGkgPCBwcm9jLmJvZHkuYXJncy5sZW5ndGggJiYgcHJvYy5ib2R5LmFyZ3NbaV0ubHZhbHVlKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY3dpc2U6IGJvZHkoKSBibG9jayBtYXkgbm90IHdyaXRlIHRvIGFycmF5IHNoYXBlXCIpXHJcbiAgICAgIH1cclxuICAgICAgaWYoaSA8IHByb2MucG9zdC5hcmdzLmxlbmd0aCAmJiBwcm9jLnBvc3QuYXJnc1tpXS5sdmFsdWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogcG9zdCgpIGJsb2NrIG1heSBub3Qgd3JpdGUgdG8gYXJyYXkgc2hhcGVcIilcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmKHR5cGVvZiBhcmdfdHlwZSA9PT0gXCJvYmplY3RcIiAmJiBhcmdfdHlwZS5vZmZzZXQpIHtcclxuICAgICAgcHJvYy5hcmdUeXBlc1tpXSA9IFwib2Zmc2V0XCJcclxuICAgICAgcHJvYy5vZmZzZXRBcmdzLnB1c2goeyBhcnJheTogYXJnX3R5cGUuYXJyYXksIG9mZnNldDphcmdfdHlwZS5vZmZzZXQgfSlcclxuICAgICAgcHJvYy5vZmZzZXRBcmdJbmRleC5wdXNoKGkpXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogVW5rbm93biBhcmd1bWVudCB0eXBlIFwiICsgcHJvY19hcmdzW2ldKVxyXG4gICAgfVxyXG4gIH1cclxuICBcclxuICAvL01ha2Ugc3VyZSBhdCBsZWFzdCBvbmUgYXJyYXkgYXJndW1lbnQgd2FzIHNwZWNpZmllZFxyXG4gIGlmKHByb2MuYXJyYXlBcmdzLmxlbmd0aCA8PSAwKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogTm8gYXJyYXkgYXJndW1lbnRzIHNwZWNpZmllZFwiKVxyXG4gIH1cclxuICBcclxuICAvL01ha2Ugc3VyZSBhcmd1bWVudHMgYXJlIGNvcnJlY3RcclxuICBpZihwcm9jLnByZS5hcmdzLmxlbmd0aCA+IHByb2NfYXJncy5sZW5ndGgpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihcImN3aXNlOiBUb28gbWFueSBhcmd1bWVudHMgaW4gcHJlKCkgYmxvY2tcIilcclxuICB9XHJcbiAgaWYocHJvYy5ib2R5LmFyZ3MubGVuZ3RoID4gcHJvY19hcmdzLmxlbmd0aCkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiY3dpc2U6IFRvbyBtYW55IGFyZ3VtZW50cyBpbiBib2R5KCkgYmxvY2tcIilcclxuICB9XHJcbiAgaWYocHJvYy5wb3N0LmFyZ3MubGVuZ3RoID4gcHJvY19hcmdzLmxlbmd0aCkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiY3dpc2U6IFRvbyBtYW55IGFyZ3VtZW50cyBpbiBwb3N0KCkgYmxvY2tcIilcclxuICB9XHJcblxyXG4gIC8vQ2hlY2sgZGVidWcgZmxhZ1xyXG4gIHByb2MuZGVidWcgPSAhIXVzZXJfYXJncy5wcmludENvZGUgfHwgISF1c2VyX2FyZ3MuZGVidWdcclxuICBcclxuICAvL1JldHJpZXZlIG5hbWVcclxuICBwcm9jLmZ1bmNOYW1lID0gdXNlcl9hcmdzLmZ1bmNOYW1lIHx8IFwiY3dpc2VcIlxyXG4gIFxyXG4gIC8vUmVhZCBpbiBibG9jayBzaXplXHJcbiAgcHJvYy5ibG9ja1NpemUgPSB1c2VyX2FyZ3MuYmxvY2tTaXplIHx8IDY0XHJcblxyXG4gIHJldHVybiBjcmVhdGVUaHVuayhwcm9jKVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBpbGVDd2lzZVxyXG4iLCJcInVzZSBzdHJpY3RcIlxyXG5cclxudmFyIHVuaXEgPSByZXF1aXJlKFwidW5pcVwiKVxyXG5cclxuLy8gVGhpcyBmdW5jdGlvbiBnZW5lcmF0ZXMgdmVyeSBzaW1wbGUgbG9vcHMgYW5hbG9nb3VzIHRvIGhvdyB5b3UgdHlwaWNhbGx5IHRyYXZlcnNlIGFycmF5cyAodGhlIG91dGVybW9zdCBsb29wIGNvcnJlc3BvbmRzIHRvIHRoZSBzbG93ZXN0IGNoYW5naW5nIGluZGV4LCB0aGUgaW5uZXJtb3N0IGxvb3AgdG8gdGhlIGZhc3Rlc3QgY2hhbmdpbmcgaW5kZXgpXHJcbi8vIFRPRE86IElmIHR3byBhcnJheXMgaGF2ZSB0aGUgc2FtZSBzdHJpZGVzIChhbmQgb2Zmc2V0cykgdGhlcmUgaXMgcG90ZW50aWFsIGZvciBkZWNyZWFzaW5nIHRoZSBudW1iZXIgb2YgXCJwb2ludGVyc1wiIGFuZCByZWxhdGVkIHZhcmlhYmxlcy4gVGhlIGRyYXdiYWNrIGlzIHRoYXQgdGhlIHR5cGUgc2lnbmF0dXJlIHdvdWxkIGJlY29tZSBtb3JlIHNwZWNpZmljIGFuZCB0aGF0IHRoZXJlIHdvdWxkIHRodXMgYmUgbGVzcyBwb3RlbnRpYWwgZm9yIGNhY2hpbmcsIGJ1dCBpdCBtaWdodCBzdGlsbCBiZSB3b3J0aCBpdCwgZXNwZWNpYWxseSB3aGVuIGRlYWxpbmcgd2l0aCBsYXJnZSBudW1iZXJzIG9mIGFyZ3VtZW50cy5cclxuZnVuY3Rpb24gaW5uZXJGaWxsKG9yZGVyLCBwcm9jLCBib2R5KSB7XHJcbiAgdmFyIGRpbWVuc2lvbiA9IG9yZGVyLmxlbmd0aFxyXG4gICAgLCBuYXJncyA9IHByb2MuYXJyYXlBcmdzLmxlbmd0aFxyXG4gICAgLCBoYXNfaW5kZXggPSBwcm9jLmluZGV4QXJncy5sZW5ndGg+MFxyXG4gICAgLCBjb2RlID0gW11cclxuICAgICwgdmFycyA9IFtdXHJcbiAgICAsIGlkeD0wLCBwaWR4PTAsIGksIGpcclxuICBmb3IoaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7IC8vIEl0ZXJhdGlvbiB2YXJpYWJsZXNcclxuICAgIHZhcnMucHVzaChbXCJpXCIsaSxcIj0wXCJdLmpvaW4oXCJcIikpXHJcbiAgfVxyXG4gIC8vQ29tcHV0ZSBzY2FuIGRlbHRhc1xyXG4gIGZvcihqPTA7IGo8bmFyZ3M7ICsraikge1xyXG4gICAgZm9yKGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xyXG4gICAgICBwaWR4ID0gaWR4XHJcbiAgICAgIGlkeCA9IG9yZGVyW2ldXHJcbiAgICAgIGlmKGkgPT09IDApIHsgLy8gVGhlIGlubmVybW9zdC9mYXN0ZXN0IGRpbWVuc2lvbidzIGRlbHRhIGlzIHNpbXBseSBpdHMgc3RyaWRlXHJcbiAgICAgICAgdmFycy5wdXNoKFtcImRcIixqLFwic1wiLGksXCI9dFwiLGosXCJwXCIsaWR4XS5qb2luKFwiXCIpKVxyXG4gICAgICB9IGVsc2UgeyAvLyBGb3Igb3RoZXIgZGltZW5zaW9ucyB0aGUgZGVsdGEgaXMgYmFzaWNhbGx5IHRoZSBzdHJpZGUgbWludXMgc29tZXRoaW5nIHdoaWNoIGVzc2VudGlhbGx5IFwicmV3aW5kc1wiIHRoZSBwcmV2aW91cyAobW9yZSBpbm5lcikgZGltZW5zaW9uXHJcbiAgICAgICAgdmFycy5wdXNoKFtcImRcIixqLFwic1wiLGksXCI9KHRcIixqLFwicFwiLGlkeCxcIi1zXCIscGlkeCxcIip0XCIsaixcInBcIixwaWR4LFwiKVwiXS5qb2luKFwiXCIpKVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIGNvZGUucHVzaChcInZhciBcIiArIHZhcnMuam9pbihcIixcIikpXHJcbiAgLy9TY2FuIGxvb3BcclxuICBmb3IoaT1kaW1lbnNpb24tMTsgaT49MDsgLS1pKSB7IC8vIFN0YXJ0IGF0IGxhcmdlc3Qgc3RyaWRlIGFuZCB3b3JrIHlvdXIgd2F5IGlud2FyZHNcclxuICAgIGlkeCA9IG9yZGVyW2ldXHJcbiAgICBjb2RlLnB1c2goW1wiZm9yKGlcIixpLFwiPTA7aVwiLGksXCI8c1wiLGlkeCxcIjsrK2lcIixpLFwiKXtcIl0uam9pbihcIlwiKSlcclxuICB9XHJcbiAgLy9QdXNoIGJvZHkgb2YgaW5uZXIgbG9vcFxyXG4gIGNvZGUucHVzaChib2R5KVxyXG4gIC8vQWR2YW5jZSBzY2FuIHBvaW50ZXJzXHJcbiAgZm9yKGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xyXG4gICAgcGlkeCA9IGlkeFxyXG4gICAgaWR4ID0gb3JkZXJbaV1cclxuICAgIGZvcihqPTA7IGo8bmFyZ3M7ICsraikge1xyXG4gICAgICBjb2RlLnB1c2goW1wicFwiLGosXCIrPWRcIixqLFwic1wiLGldLmpvaW4oXCJcIikpXHJcbiAgICB9XHJcbiAgICBpZihoYXNfaW5kZXgpIHtcclxuICAgICAgaWYoaSA+IDApIHtcclxuICAgICAgICBjb2RlLnB1c2goW1wiaW5kZXhbXCIscGlkeCxcIl0tPXNcIixwaWR4XS5qb2luKFwiXCIpKVxyXG4gICAgICB9XHJcbiAgICAgIGNvZGUucHVzaChbXCIrK2luZGV4W1wiLGlkeCxcIl1cIl0uam9pbihcIlwiKSlcclxuICAgIH1cclxuICAgIGNvZGUucHVzaChcIn1cIilcclxuICB9XHJcbiAgcmV0dXJuIGNvZGUuam9pbihcIlxcblwiKVxyXG59XHJcblxyXG4vLyBHZW5lcmF0ZSBcIm91dGVyXCIgbG9vcHMgdGhhdCBsb29wIG92ZXIgYmxvY2tzIG9mIGRhdGEsIGFwcGx5aW5nIFwiaW5uZXJcIiBsb29wcyB0byB0aGUgYmxvY2tzIGJ5IG1hbmlwdWxhdGluZyB0aGUgbG9jYWwgdmFyaWFibGVzIGluIHN1Y2ggYSB3YXkgdGhhdCB0aGUgaW5uZXIgbG9vcCBvbmx5IFwic2Vlc1wiIHRoZSBjdXJyZW50IGJsb2NrLlxyXG4vLyBUT0RPOiBJZiB0aGlzIGlzIHVzZWQsIHRoZW4gdGhlIHByZXZpb3VzIGRlY2xhcmF0aW9uIChkb25lIGJ5IGdlbmVyYXRlQ3dpc2VPcCkgb2YgcyogaXMgZXNzZW50aWFsbHkgdW5uZWNlc3NhcnkuXHJcbi8vICAgICAgIEkgYmVsaWV2ZSB0aGUgcyogYXJlIG5vdCB1c2VkIGVsc2V3aGVyZSAoaW4gcGFydGljdWxhciwgSSBkb24ndCB0aGluayB0aGV5J3JlIHVzZWQgaW4gdGhlIHByZS9wb3N0IHBhcnRzIGFuZCBcInNoYXBlXCIgaXMgZGVmaW5lZCBpbmRlcGVuZGVudGx5KSwgc28gaXQgd291bGQgYmUgcG9zc2libGUgdG8gbWFrZSBkZWZpbmluZyB0aGUgcyogZGVwZW5kZW50IG9uIHdoYXQgbG9vcCBtZXRob2QgaXMgYmVpbmcgdXNlZC5cclxuZnVuY3Rpb24gb3V0ZXJGaWxsKG1hdGNoZWQsIG9yZGVyLCBwcm9jLCBib2R5KSB7XHJcbiAgdmFyIGRpbWVuc2lvbiA9IG9yZGVyLmxlbmd0aFxyXG4gICAgLCBuYXJncyA9IHByb2MuYXJyYXlBcmdzLmxlbmd0aFxyXG4gICAgLCBibG9ja1NpemUgPSBwcm9jLmJsb2NrU2l6ZVxyXG4gICAgLCBoYXNfaW5kZXggPSBwcm9jLmluZGV4QXJncy5sZW5ndGggPiAwXHJcbiAgICAsIGNvZGUgPSBbXVxyXG4gIGZvcih2YXIgaT0wOyBpPG5hcmdzOyArK2kpIHtcclxuICAgIGNvZGUucHVzaChbXCJ2YXIgb2Zmc2V0XCIsaSxcIj1wXCIsaV0uam9pbihcIlwiKSlcclxuICB9XHJcbiAgLy9HZW5lcmF0ZSBsb29wcyBmb3IgdW5tYXRjaGVkIGRpbWVuc2lvbnNcclxuICAvLyBUaGUgb3JkZXIgaW4gd2hpY2ggdGhlc2UgZGltZW5zaW9ucyBhcmUgdHJhdmVyc2VkIGlzIGZhaXJseSBhcmJpdHJhcnkgKGZyb20gc21hbGwgc3RyaWRlIHRvIGxhcmdlIHN0cmlkZSwgZm9yIHRoZSBmaXJzdCBhcmd1bWVudClcclxuICAvLyBUT0RPOiBJdCB3b3VsZCBiZSBuaWNlIGlmIHRoZSBvcmRlciBpbiB3aGljaCB0aGVzZSBsb29wcyBhcmUgcGxhY2VkIHdvdWxkIGFsc28gYmUgc29tZWhvdyBcIm9wdGltYWxcIiAoYXQgdGhlIHZlcnkgbGVhc3Qgd2Ugc2hvdWxkIGNoZWNrIHRoYXQgaXQgcmVhbGx5IGRvZXNuJ3QgaHVydCB1cyBpZiB0aGV5J3JlIG5vdCkuXHJcbiAgZm9yKHZhciBpPW1hdGNoZWQ7IGk8ZGltZW5zaW9uOyArK2kpIHtcclxuICAgIGNvZGUucHVzaChbXCJmb3IodmFyIGpcIitpK1wiPVNTW1wiLCBvcmRlcltpXSwgXCJdfDA7alwiLCBpLCBcIj4wOyl7XCJdLmpvaW4oXCJcIikpIC8vIEl0ZXJhdGUgYmFjayB0byBmcm9udFxyXG4gICAgY29kZS5wdXNoKFtcImlmKGpcIixpLFwiPFwiLGJsb2NrU2l6ZSxcIil7XCJdLmpvaW4oXCJcIikpIC8vIEVpdGhlciBkZWNyZWFzZSBqIGJ5IGJsb2NrU2l6ZSAocyA9IGJsb2NrU2l6ZSksIG9yIHNldCBpdCB0byB6ZXJvIChhZnRlciBzZXR0aW5nIHMgPSBqKS5cclxuICAgIGNvZGUucHVzaChbXCJzXCIsb3JkZXJbaV0sXCI9alwiLGldLmpvaW4oXCJcIikpXHJcbiAgICBjb2RlLnB1c2goW1wialwiLGksXCI9MFwiXS5qb2luKFwiXCIpKVxyXG4gICAgY29kZS5wdXNoKFtcIn1lbHNle3NcIixvcmRlcltpXSxcIj1cIixibG9ja1NpemVdLmpvaW4oXCJcIikpXHJcbiAgICBjb2RlLnB1c2goW1wialwiLGksXCItPVwiLGJsb2NrU2l6ZSxcIn1cIl0uam9pbihcIlwiKSlcclxuICAgIGlmKGhhc19pbmRleCkge1xyXG4gICAgICBjb2RlLnB1c2goW1wiaW5kZXhbXCIsb3JkZXJbaV0sXCJdPWpcIixpXS5qb2luKFwiXCIpKVxyXG4gICAgfVxyXG4gIH1cclxuICBmb3IodmFyIGk9MDsgaTxuYXJnczsgKytpKSB7XHJcbiAgICB2YXIgaW5kZXhTdHIgPSBbXCJvZmZzZXRcIitpXVxyXG4gICAgZm9yKHZhciBqPW1hdGNoZWQ7IGo8ZGltZW5zaW9uOyArK2opIHtcclxuICAgICAgaW5kZXhTdHIucHVzaChbXCJqXCIsaixcIip0XCIsaSxcInBcIixvcmRlcltqXV0uam9pbihcIlwiKSlcclxuICAgIH1cclxuICAgIGNvZGUucHVzaChbXCJwXCIsaSxcIj0oXCIsaW5kZXhTdHIuam9pbihcIitcIiksXCIpXCJdLmpvaW4oXCJcIikpXHJcbiAgfVxyXG4gIGNvZGUucHVzaChpbm5lckZpbGwob3JkZXIsIHByb2MsIGJvZHkpKVxyXG4gIGZvcih2YXIgaT1tYXRjaGVkOyBpPGRpbWVuc2lvbjsgKytpKSB7XHJcbiAgICBjb2RlLnB1c2goXCJ9XCIpXHJcbiAgfVxyXG4gIHJldHVybiBjb2RlLmpvaW4oXCJcXG5cIilcclxufVxyXG5cclxuLy9Db3VudCB0aGUgbnVtYmVyIG9mIGNvbXBhdGlibGUgaW5uZXIgb3JkZXJzXHJcbi8vIFRoaXMgaXMgdGhlIGxlbmd0aCBvZiB0aGUgbG9uZ2VzdCBjb21tb24gcHJlZml4IG9mIHRoZSBhcnJheXMgaW4gb3JkZXJzLlxyXG4vLyBFYWNoIGFycmF5IGluIG9yZGVycyBsaXN0cyB0aGUgZGltZW5zaW9ucyBvZiB0aGUgY29ycmVzcG9uZCBuZGFycmF5IGluIG9yZGVyIG9mIGluY3JlYXNpbmcgc3RyaWRlLlxyXG4vLyBUaGlzIGlzIHRodXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIGRpbWVuc2lvbnMgdGhhdCBjYW4gYmUgZWZmaWNpZW50bHkgdHJhdmVyc2VkIGJ5IHNpbXBsZSBuZXN0ZWQgbG9vcHMgZm9yIGFsbCBhcnJheXMuXHJcbmZ1bmN0aW9uIGNvdW50TWF0Y2hlcyhvcmRlcnMpIHtcclxuICB2YXIgbWF0Y2hlZCA9IDAsIGRpbWVuc2lvbiA9IG9yZGVyc1swXS5sZW5ndGhcclxuICB3aGlsZShtYXRjaGVkIDwgZGltZW5zaW9uKSB7XHJcbiAgICBmb3IodmFyIGo9MTsgajxvcmRlcnMubGVuZ3RoOyArK2opIHtcclxuICAgICAgaWYob3JkZXJzW2pdW21hdGNoZWRdICE9PSBvcmRlcnNbMF1bbWF0Y2hlZF0pIHtcclxuICAgICAgICByZXR1cm4gbWF0Y2hlZFxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICArK21hdGNoZWRcclxuICB9XHJcbiAgcmV0dXJuIG1hdGNoZWRcclxufVxyXG5cclxuLy9Qcm9jZXNzZXMgYSBibG9jayBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIGRhdGEgdHlwZXNcclxuLy8gUmVwbGFjZXMgdmFyaWFibGUgbmFtZXMgYnkgZGlmZmVyZW50IG9uZXMsIGVpdGhlciBcImxvY2FsXCIgb25lcyAodGhhdCBhcmUgdGhlbiBmZXJyaWVkIGluIGFuZCBvdXQgb2YgdGhlIGdpdmVuIGFycmF5KSBvciBvbmVzIG1hdGNoaW5nIHRoZSBhcmd1bWVudHMgdGhhdCB0aGUgZnVuY3Rpb24gcGVyZm9ybWluZyB0aGUgdWx0aW1hdGUgbG9vcCB3aWxsIGFjY2VwdC5cclxuZnVuY3Rpb24gcHJvY2Vzc0Jsb2NrKGJsb2NrLCBwcm9jLCBkdHlwZXMpIHtcclxuICB2YXIgY29kZSA9IGJsb2NrLmJvZHlcclxuICB2YXIgcHJlID0gW11cclxuICB2YXIgcG9zdCA9IFtdXHJcbiAgZm9yKHZhciBpPTA7IGk8YmxvY2suYXJncy5sZW5ndGg7ICsraSkge1xyXG4gICAgdmFyIGNhcmcgPSBibG9jay5hcmdzW2ldXHJcbiAgICBpZihjYXJnLmNvdW50IDw9IDApIHtcclxuICAgICAgY29udGludWVcclxuICAgIH1cclxuICAgIHZhciByZSA9IG5ldyBSZWdFeHAoY2FyZy5uYW1lLCBcImdcIilcclxuICAgIHZhciBwdHJTdHIgPSBcIlwiXHJcbiAgICB2YXIgYXJyTnVtID0gcHJvYy5hcnJheUFyZ3MuaW5kZXhPZihpKVxyXG4gICAgc3dpdGNoKHByb2MuYXJnVHlwZXNbaV0pIHtcclxuICAgICAgY2FzZSBcIm9mZnNldFwiOlxyXG4gICAgICAgIHZhciBvZmZBcmdJbmRleCA9IHByb2Mub2Zmc2V0QXJnSW5kZXguaW5kZXhPZihpKVxyXG4gICAgICAgIHZhciBvZmZBcmcgPSBwcm9jLm9mZnNldEFyZ3Nbb2ZmQXJnSW5kZXhdXHJcbiAgICAgICAgYXJyTnVtID0gb2ZmQXJnLmFycmF5XHJcbiAgICAgICAgcHRyU3RyID0gXCIrcVwiICsgb2ZmQXJnSW5kZXggLy8gQWRkcyBvZmZzZXQgdG8gdGhlIFwicG9pbnRlclwiIGluIHRoZSBhcnJheVxyXG4gICAgICBjYXNlIFwiYXJyYXlcIjpcclxuICAgICAgICBwdHJTdHIgPSBcInBcIiArIGFyck51bSArIHB0clN0clxyXG4gICAgICAgIHZhciBsb2NhbFN0ciA9IFwibFwiICsgaVxyXG4gICAgICAgIHZhciBhcnJTdHIgPSBcImFcIiArIGFyck51bVxyXG4gICAgICAgIGlmIChwcm9jLmFycmF5QmxvY2tJbmRpY2VzW2Fyck51bV0gPT09IDApIHsgLy8gQXJndW1lbnQgdG8gYm9keSBpcyBqdXN0IGEgc2luZ2xlIHZhbHVlIGZyb20gdGhpcyBhcnJheVxyXG4gICAgICAgICAgaWYoY2FyZy5jb3VudCA9PT0gMSkgeyAvLyBBcmd1bWVudC9hcnJheSB1c2VkIG9ubHkgb25jZSg/KVxyXG4gICAgICAgICAgICBpZihkdHlwZXNbYXJyTnVtXSA9PT0gXCJnZW5lcmljXCIpIHtcclxuICAgICAgICAgICAgICBpZihjYXJnLmx2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgcHJlLnB1c2goW1widmFyIFwiLCBsb2NhbFN0ciwgXCI9XCIsIGFyclN0ciwgXCIuZ2V0KFwiLCBwdHJTdHIsIFwiKVwiXS5qb2luKFwiXCIpKSAvLyBJcyB0aGlzIG5lY2Vzc2FyeSBpZiB0aGUgYXJndW1lbnQgaXMgT05MWSB1c2VkIGFzIGFuIGx2YWx1ZT8gKGtlZXAgaW4gbWluZCB0aGF0IHdlIGNhbiBoYXZlIGEgKz0gc29tZXRoaW5nLCBzbyB3ZSB3b3VsZCBhY3R1YWxseSBuZWVkIHRvIGNoZWNrIGNhcmcucnZhbHVlKVxyXG4gICAgICAgICAgICAgICAgY29kZSA9IGNvZGUucmVwbGFjZShyZSwgbG9jYWxTdHIpXHJcbiAgICAgICAgICAgICAgICBwb3N0LnB1c2goW2FyclN0ciwgXCIuc2V0KFwiLCBwdHJTdHIsIFwiLFwiLCBsb2NhbFN0cixcIilcIl0uam9pbihcIlwiKSlcclxuICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29kZSA9IGNvZGUucmVwbGFjZShyZSwgW2FyclN0ciwgXCIuZ2V0KFwiLCBwdHJTdHIsIFwiKVwiXS5qb2luKFwiXCIpKVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKHJlLCBbYXJyU3RyLCBcIltcIiwgcHRyU3RyLCBcIl1cIl0uam9pbihcIlwiKSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIGlmKGR0eXBlc1thcnJOdW1dID09PSBcImdlbmVyaWNcIikge1xyXG4gICAgICAgICAgICBwcmUucHVzaChbXCJ2YXIgXCIsIGxvY2FsU3RyLCBcIj1cIiwgYXJyU3RyLCBcIi5nZXQoXCIsIHB0clN0ciwgXCIpXCJdLmpvaW4oXCJcIikpIC8vIFRPRE86IENvdWxkIHdlIG9wdGltaXplIGJ5IGNoZWNraW5nIGZvciBjYXJnLnJ2YWx1ZT9cclxuICAgICAgICAgICAgY29kZSA9IGNvZGUucmVwbGFjZShyZSwgbG9jYWxTdHIpXHJcbiAgICAgICAgICAgIGlmKGNhcmcubHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgcG9zdC5wdXNoKFthcnJTdHIsIFwiLnNldChcIiwgcHRyU3RyLCBcIixcIiwgbG9jYWxTdHIsXCIpXCJdLmpvaW4oXCJcIikpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHByZS5wdXNoKFtcInZhciBcIiwgbG9jYWxTdHIsIFwiPVwiLCBhcnJTdHIsIFwiW1wiLCBwdHJTdHIsIFwiXVwiXS5qb2luKFwiXCIpKSAvLyBUT0RPOiBDb3VsZCB3ZSBvcHRpbWl6ZSBieSBjaGVja2luZyBmb3IgY2FyZy5ydmFsdWU/XHJcbiAgICAgICAgICAgIGNvZGUgPSBjb2RlLnJlcGxhY2UocmUsIGxvY2FsU3RyKVxyXG4gICAgICAgICAgICBpZihjYXJnLmx2YWx1ZSkge1xyXG4gICAgICAgICAgICAgIHBvc3QucHVzaChbYXJyU3RyLCBcIltcIiwgcHRyU3RyLCBcIl09XCIsIGxvY2FsU3RyXS5qb2luKFwiXCIpKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHsgLy8gQXJndW1lbnQgdG8gYm9keSBpcyBhIFwiYmxvY2tcIlxyXG4gICAgICAgICAgdmFyIHJlU3RyQXJyID0gW2NhcmcubmFtZV0sIHB0clN0ckFyciA9IFtwdHJTdHJdXHJcbiAgICAgICAgICBmb3IodmFyIGo9MDsgajxNYXRoLmFicyhwcm9jLmFycmF5QmxvY2tJbmRpY2VzW2Fyck51bV0pOyBqKyspIHtcclxuICAgICAgICAgICAgcmVTdHJBcnIucHVzaChcIlxcXFxzKlxcXFxbKFteXFxcXF1dKylcXFxcXVwiKVxyXG4gICAgICAgICAgICBwdHJTdHJBcnIucHVzaChcIiRcIiArIChqKzEpICsgXCIqdFwiICsgYXJyTnVtICsgXCJiXCIgKyBqKSAvLyBNYXRjaGVkIGluZGV4IHRpbWVzIHN0cmlkZVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmUgPSBuZXcgUmVnRXhwKHJlU3RyQXJyLmpvaW4oXCJcIiksIFwiZ1wiKVxyXG4gICAgICAgICAgcHRyU3RyID0gcHRyU3RyQXJyLmpvaW4oXCIrXCIpXHJcbiAgICAgICAgICBpZihkdHlwZXNbYXJyTnVtXSA9PT0gXCJnZW5lcmljXCIpIHtcclxuICAgICAgICAgICAgLyppZihjYXJnLmx2YWx1ZSkge1xyXG4gICAgICAgICAgICAgIHByZS5wdXNoKFtcInZhciBcIiwgbG9jYWxTdHIsIFwiPVwiLCBhcnJTdHIsIFwiLmdldChcIiwgcHRyU3RyLCBcIilcIl0uam9pbihcIlwiKSkgLy8gSXMgdGhpcyBuZWNlc3NhcnkgaWYgdGhlIGFyZ3VtZW50IGlzIE9OTFkgdXNlZCBhcyBhbiBsdmFsdWU/IChrZWVwIGluIG1pbmQgdGhhdCB3ZSBjYW4gaGF2ZSBhICs9IHNvbWV0aGluZywgc28gd2Ugd291bGQgYWN0dWFsbHkgbmVlZCB0byBjaGVjayBjYXJnLnJ2YWx1ZSlcclxuICAgICAgICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKHJlLCBsb2NhbFN0cilcclxuICAgICAgICAgICAgICBwb3N0LnB1c2goW2FyclN0ciwgXCIuc2V0KFwiLCBwdHJTdHIsIFwiLFwiLCBsb2NhbFN0cixcIilcIl0uam9pbihcIlwiKSlcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKHJlLCBbYXJyU3RyLCBcIi5nZXQoXCIsIHB0clN0ciwgXCIpXCJdLmpvaW4oXCJcIikpXHJcbiAgICAgICAgICAgIH0qL1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjd2lzZTogR2VuZXJpYyBhcnJheXMgbm90IHN1cHBvcnRlZCBpbiBjb21iaW5hdGlvbiB3aXRoIGJsb2NrcyFcIilcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFRoaXMgZG9lcyBub3QgcHJvZHVjZSBhbnkgbG9jYWwgdmFyaWFibGVzLCBldmVuIGlmIHZhcmlhYmxlcyBhcmUgdXNlZCBtdWx0aXBsZSB0aW1lcy4gSXQgd291bGQgYmUgcG9zc2libGUgdG8gZG8gc28sIGJ1dCBpdCB3b3VsZCBjb21wbGljYXRlIHRoaW5ncyBxdWl0ZSBhIGJpdC5cclxuICAgICAgICAgICAgY29kZSA9IGNvZGUucmVwbGFjZShyZSwgW2FyclN0ciwgXCJbXCIsIHB0clN0ciwgXCJdXCJdLmpvaW4oXCJcIikpXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICBicmVha1xyXG4gICAgICBjYXNlIFwic2NhbGFyXCI6XHJcbiAgICAgICAgY29kZSA9IGNvZGUucmVwbGFjZShyZSwgXCJZXCIgKyBwcm9jLnNjYWxhckFyZ3MuaW5kZXhPZihpKSlcclxuICAgICAgYnJlYWtcclxuICAgICAgY2FzZSBcImluZGV4XCI6XHJcbiAgICAgICAgY29kZSA9IGNvZGUucmVwbGFjZShyZSwgXCJpbmRleFwiKVxyXG4gICAgICBicmVha1xyXG4gICAgICBjYXNlIFwic2hhcGVcIjpcclxuICAgICAgICBjb2RlID0gY29kZS5yZXBsYWNlKHJlLCBcInNoYXBlXCIpXHJcbiAgICAgIGJyZWFrXHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBbcHJlLmpvaW4oXCJcXG5cIiksIGNvZGUsIHBvc3Quam9pbihcIlxcblwiKV0uam9pbihcIlxcblwiKS50cmltKClcclxufVxyXG5cclxuZnVuY3Rpb24gdHlwZVN1bW1hcnkoZHR5cGVzKSB7XHJcbiAgdmFyIHN1bW1hcnkgPSBuZXcgQXJyYXkoZHR5cGVzLmxlbmd0aClcclxuICB2YXIgYWxsRXF1YWwgPSB0cnVlXHJcbiAgZm9yKHZhciBpPTA7IGk8ZHR5cGVzLmxlbmd0aDsgKytpKSB7XHJcbiAgICB2YXIgdCA9IGR0eXBlc1tpXVxyXG4gICAgdmFyIGRpZ2l0cyA9IHQubWF0Y2goL1xcZCsvKVxyXG4gICAgaWYoIWRpZ2l0cykge1xyXG4gICAgICBkaWdpdHMgPSBcIlwiXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBkaWdpdHMgPSBkaWdpdHNbMF1cclxuICAgIH1cclxuICAgIGlmKHQuY2hhckF0KDApID09PSAwKSB7XHJcbiAgICAgIHN1bW1hcnlbaV0gPSBcInVcIiArIHQuY2hhckF0KDEpICsgZGlnaXRzXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzdW1tYXJ5W2ldID0gdC5jaGFyQXQoMCkgKyBkaWdpdHNcclxuICAgIH1cclxuICAgIGlmKGkgPiAwKSB7XHJcbiAgICAgIGFsbEVxdWFsID0gYWxsRXF1YWwgJiYgc3VtbWFyeVtpXSA9PT0gc3VtbWFyeVtpLTFdXHJcbiAgICB9XHJcbiAgfVxyXG4gIGlmKGFsbEVxdWFsKSB7XHJcbiAgICByZXR1cm4gc3VtbWFyeVswXVxyXG4gIH1cclxuICByZXR1cm4gc3VtbWFyeS5qb2luKFwiXCIpXHJcbn1cclxuXHJcbi8vR2VuZXJhdGVzIGEgY3dpc2Ugb3BlcmF0b3JcclxuZnVuY3Rpb24gZ2VuZXJhdGVDV2lzZU9wKHByb2MsIHR5cGVzaWcpIHtcclxuXHJcbiAgLy9Db21wdXRlIGRpbWVuc2lvblxyXG4gIC8vIEFycmF5cyBnZXQgcHV0IGZpcnN0IGluIHR5cGVzaWcsIGFuZCB0aGVyZSBhcmUgdHdvIGVudHJpZXMgcGVyIGFycmF5IChkdHlwZSBhbmQgb3JkZXIpLCBzbyB0aGlzIGdldHMgdGhlIG51bWJlciBvZiBkaW1lbnNpb25zIGluIHRoZSBmaXJzdCBhcnJheSBhcmcuXHJcbiAgdmFyIGRpbWVuc2lvbiA9ICh0eXBlc2lnWzFdLmxlbmd0aCAtIE1hdGguYWJzKHByb2MuYXJyYXlCbG9ja0luZGljZXNbMF0pKXwwXHJcbiAgdmFyIG9yZGVycyA9IG5ldyBBcnJheShwcm9jLmFycmF5QXJncy5sZW5ndGgpXHJcbiAgdmFyIGR0eXBlcyA9IG5ldyBBcnJheShwcm9jLmFycmF5QXJncy5sZW5ndGgpXHJcbiAgZm9yKHZhciBpPTA7IGk8cHJvYy5hcnJheUFyZ3MubGVuZ3RoOyArK2kpIHtcclxuICAgIGR0eXBlc1tpXSA9IHR5cGVzaWdbMippXVxyXG4gICAgb3JkZXJzW2ldID0gdHlwZXNpZ1syKmkrMV1cclxuICB9XHJcbiAgXHJcbiAgLy9EZXRlcm1pbmUgd2hlcmUgYmxvY2sgYW5kIGxvb3AgaW5kaWNlcyBzdGFydCBhbmQgZW5kXHJcbiAgdmFyIGJsb2NrQmVnaW4gPSBbXSwgYmxvY2tFbmQgPSBbXSAvLyBUaGVzZSBpbmRpY2VzIGFyZSBleHBvc2VkIGFzIGJsb2Nrc1xyXG4gIHZhciBsb29wQmVnaW4gPSBbXSwgbG9vcEVuZCA9IFtdIC8vIFRoZXNlIGluZGljZXMgYXJlIGl0ZXJhdGVkIG92ZXJcclxuICB2YXIgbG9vcE9yZGVycyA9IFtdIC8vIG9yZGVycyByZXN0cmljdGVkIHRvIHRoZSBsb29wIGluZGljZXNcclxuICBmb3IodmFyIGk9MDsgaTxwcm9jLmFycmF5QXJncy5sZW5ndGg7ICsraSkge1xyXG4gICAgaWYgKHByb2MuYXJyYXlCbG9ja0luZGljZXNbaV08MCkge1xyXG4gICAgICBsb29wQmVnaW4ucHVzaCgwKVxyXG4gICAgICBsb29wRW5kLnB1c2goZGltZW5zaW9uKVxyXG4gICAgICBibG9ja0JlZ2luLnB1c2goZGltZW5zaW9uKVxyXG4gICAgICBibG9ja0VuZC5wdXNoKGRpbWVuc2lvbitwcm9jLmFycmF5QmxvY2tJbmRpY2VzW2ldKVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbG9vcEJlZ2luLnB1c2gocHJvYy5hcnJheUJsb2NrSW5kaWNlc1tpXSkgLy8gTm9uLW5lZ2F0aXZlXHJcbiAgICAgIGxvb3BFbmQucHVzaChwcm9jLmFycmF5QmxvY2tJbmRpY2VzW2ldK2RpbWVuc2lvbilcclxuICAgICAgYmxvY2tCZWdpbi5wdXNoKDApXHJcbiAgICAgIGJsb2NrRW5kLnB1c2gocHJvYy5hcnJheUJsb2NrSW5kaWNlc1tpXSlcclxuICAgIH1cclxuICAgIHZhciBuZXdPcmRlciA9IFtdXHJcbiAgICBmb3IodmFyIGo9MDsgajxvcmRlcnNbaV0ubGVuZ3RoOyBqKyspIHtcclxuICAgICAgaWYgKGxvb3BCZWdpbltpXTw9b3JkZXJzW2ldW2pdICYmIG9yZGVyc1tpXVtqXTxsb29wRW5kW2ldKSB7XHJcbiAgICAgICAgbmV3T3JkZXIucHVzaChvcmRlcnNbaV1bal0tbG9vcEJlZ2luW2ldKSAvLyBJZiB0aGlzIGlzIGEgbG9vcCBpbmRleCwgcHV0IGl0IGluIG5ld09yZGVyLCBzdWJ0cmFjdGluZyBsb29wQmVnaW4sIHRvIG1ha2Ugc3VyZSB0aGF0IGFsbCBsb29wT3JkZXJzIGFyZSB1c2luZyBhIGNvbW1vbiBzZXQgb2YgaW5kaWNlcy5cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgbG9vcE9yZGVycy5wdXNoKG5ld09yZGVyKVxyXG4gIH1cclxuXHJcbiAgLy9GaXJzdCBjcmVhdGUgYXJndW1lbnRzIGZvciBwcm9jZWR1cmVcclxuICB2YXIgYXJnbGlzdCA9IFtcIlNTXCJdIC8vIFNTIGlzIHRoZSBvdmVyYWxsIHNoYXBlIG92ZXIgd2hpY2ggd2UgaXRlcmF0ZVxyXG4gIHZhciBjb2RlID0gW1wiJ3VzZSBzdHJpY3QnXCJdXHJcbiAgdmFyIHZhcnMgPSBbXVxyXG4gIFxyXG4gIGZvcih2YXIgaj0wOyBqPGRpbWVuc2lvbjsgKytqKSB7XHJcbiAgICB2YXJzLnB1c2goW1wic1wiLCBqLCBcIj1TU1tcIiwgaiwgXCJdXCJdLmpvaW4oXCJcIikpIC8vIFRoZSBsaW1pdHMgZm9yIGVhY2ggZGltZW5zaW9uLlxyXG4gIH1cclxuICBmb3IodmFyIGk9MDsgaTxwcm9jLmFycmF5QXJncy5sZW5ndGg7ICsraSkge1xyXG4gICAgYXJnbGlzdC5wdXNoKFwiYVwiK2kpIC8vIEFjdHVhbCBkYXRhIGFycmF5XHJcbiAgICBhcmdsaXN0LnB1c2goXCJ0XCIraSkgLy8gU3RyaWRlc1xyXG4gICAgYXJnbGlzdC5wdXNoKFwicFwiK2kpIC8vIE9mZnNldCBpbiB0aGUgYXJyYXkgYXQgd2hpY2ggdGhlIGRhdGEgc3RhcnRzIChhbHNvIHVzZWQgZm9yIGl0ZXJhdGluZyBvdmVyIHRoZSBkYXRhKVxyXG4gICAgXHJcbiAgICBmb3IodmFyIGo9MDsgajxkaW1lbnNpb247ICsraikgeyAvLyBVbnBhY2sgdGhlIHN0cmlkZXMgaW50byB2YXJzIGZvciBsb29waW5nXHJcbiAgICAgIHZhcnMucHVzaChbXCJ0XCIsaSxcInBcIixqLFwiPXRcIixpLFwiW1wiLGxvb3BCZWdpbltpXStqLFwiXVwiXS5qb2luKFwiXCIpKVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICBmb3IodmFyIGo9MDsgajxNYXRoLmFicyhwcm9jLmFycmF5QmxvY2tJbmRpY2VzW2ldKTsgKytqKSB7IC8vIFVucGFjayB0aGUgc3RyaWRlcyBpbnRvIHZhcnMgZm9yIGJsb2NrIGl0ZXJhdGlvblxyXG4gICAgICB2YXJzLnB1c2goW1widFwiLGksXCJiXCIsaixcIj10XCIsaSxcIltcIixibG9ja0JlZ2luW2ldK2osXCJdXCJdLmpvaW4oXCJcIikpXHJcbiAgICB9XHJcbiAgfVxyXG4gIGZvcih2YXIgaT0wOyBpPHByb2Muc2NhbGFyQXJncy5sZW5ndGg7ICsraSkge1xyXG4gICAgYXJnbGlzdC5wdXNoKFwiWVwiICsgaSlcclxuICB9XHJcbiAgaWYocHJvYy5zaGFwZUFyZ3MubGVuZ3RoID4gMCkge1xyXG4gICAgdmFycy5wdXNoKFwic2hhcGU9U1Muc2xpY2UoMClcIikgLy8gTWFrZXMgdGhlIHNoYXBlIG92ZXIgd2hpY2ggd2UgaXRlcmF0ZSBhdmFpbGFibGUgdG8gdGhlIHVzZXIgZGVmaW5lZCBmdW5jdGlvbnMgKHNvIHlvdSBjYW4gdXNlIHdpZHRoL2hlaWdodCBmb3IgZXhhbXBsZSlcclxuICB9XHJcbiAgaWYocHJvYy5pbmRleEFyZ3MubGVuZ3RoID4gMCkge1xyXG4gICAgLy8gUHJlcGFyZSBhbiBhcnJheSB0byBrZWVwIHRyYWNrIG9mIHRoZSAobG9naWNhbCkgaW5kaWNlcywgaW5pdGlhbGl6ZWQgdG8gZGltZW5zaW9uIHplcm9lcy5cclxuICAgIHZhciB6ZXJvcyA9IG5ldyBBcnJheShkaW1lbnNpb24pXHJcbiAgICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xyXG4gICAgICB6ZXJvc1tpXSA9IFwiMFwiXHJcbiAgICB9XHJcbiAgICB2YXJzLnB1c2goW1wiaW5kZXg9W1wiLCB6ZXJvcy5qb2luKFwiLFwiKSwgXCJdXCJdLmpvaW4oXCJcIikpXHJcbiAgfVxyXG4gIGZvcih2YXIgaT0wOyBpPHByb2Mub2Zmc2V0QXJncy5sZW5ndGg7ICsraSkgeyAvLyBPZmZzZXQgYXJndW1lbnRzIHVzZWQgZm9yIHN0ZW5jaWwgb3BlcmF0aW9uc1xyXG4gICAgdmFyIG9mZl9hcmcgPSBwcm9jLm9mZnNldEFyZ3NbaV1cclxuICAgIHZhciBpbml0X3N0cmluZyA9IFtdXHJcbiAgICBmb3IodmFyIGo9MDsgajxvZmZfYXJnLm9mZnNldC5sZW5ndGg7ICsraikge1xyXG4gICAgICBpZihvZmZfYXJnLm9mZnNldFtqXSA9PT0gMCkge1xyXG4gICAgICAgIGNvbnRpbnVlXHJcbiAgICAgIH0gZWxzZSBpZihvZmZfYXJnLm9mZnNldFtqXSA9PT0gMSkge1xyXG4gICAgICAgIGluaXRfc3RyaW5nLnB1c2goW1widFwiLCBvZmZfYXJnLmFycmF5LCBcInBcIiwgal0uam9pbihcIlwiKSkgICAgICBcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpbml0X3N0cmluZy5wdXNoKFtvZmZfYXJnLm9mZnNldFtqXSwgXCIqdFwiLCBvZmZfYXJnLmFycmF5LCBcInBcIiwgal0uam9pbihcIlwiKSlcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYoaW5pdF9zdHJpbmcubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHZhcnMucHVzaChcInFcIiArIGkgKyBcIj0wXCIpXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB2YXJzLnB1c2goW1wicVwiLCBpLCBcIj1cIiwgaW5pdF9zdHJpbmcuam9pbihcIitcIildLmpvaW4oXCJcIikpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvL1ByZXBhcmUgdGhpcyB2YXJpYWJsZXNcclxuICB2YXIgdGhpc1ZhcnMgPSB1bmlxKFtdLmNvbmNhdChwcm9jLnByZS50aGlzVmFycylcclxuICAgICAgICAgICAgICAgICAgICAgIC5jb25jYXQocHJvYy5ib2R5LnRoaXNWYXJzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgLmNvbmNhdChwcm9jLnBvc3QudGhpc1ZhcnMpKVxyXG4gIHZhcnMgPSB2YXJzLmNvbmNhdCh0aGlzVmFycylcclxuICBjb2RlLnB1c2goXCJ2YXIgXCIgKyB2YXJzLmpvaW4oXCIsXCIpKVxyXG4gIGZvcih2YXIgaT0wOyBpPHByb2MuYXJyYXlBcmdzLmxlbmd0aDsgKytpKSB7XHJcbiAgICBjb2RlLnB1c2goXCJwXCIraStcInw9MFwiKVxyXG4gIH1cclxuICBcclxuICAvL0lubGluZSBwcmVsdWRlXHJcbiAgaWYocHJvYy5wcmUuYm9keS5sZW5ndGggPiAzKSB7XHJcbiAgICBjb2RlLnB1c2gocHJvY2Vzc0Jsb2NrKHByb2MucHJlLCBwcm9jLCBkdHlwZXMpKVxyXG4gIH1cclxuXHJcbiAgLy9Qcm9jZXNzIGJvZHlcclxuICB2YXIgYm9keSA9IHByb2Nlc3NCbG9jayhwcm9jLmJvZHksIHByb2MsIGR0eXBlcylcclxuICB2YXIgbWF0Y2hlZCA9IGNvdW50TWF0Y2hlcyhsb29wT3JkZXJzKVxyXG4gIGlmKG1hdGNoZWQgPCBkaW1lbnNpb24pIHtcclxuICAgIGNvZGUucHVzaChvdXRlckZpbGwobWF0Y2hlZCwgbG9vcE9yZGVyc1swXSwgcHJvYywgYm9keSkpIC8vIFRPRE86IFJhdGhlciB0aGFuIHBhc3NpbmcgbG9vcE9yZGVyc1swXSwgaXQgbWlnaHQgYmUgaW50ZXJlc3RpbmcgdG8gbG9vayBhdCBwYXNzaW5nIGFuIG9yZGVyIHRoYXQgcmVwcmVzZW50cyB0aGUgbWFqb3JpdHkgb2YgdGhlIGFyZ3VtZW50cyBmb3IgZXhhbXBsZS5cclxuICB9IGVsc2Uge1xyXG4gICAgY29kZS5wdXNoKGlubmVyRmlsbChsb29wT3JkZXJzWzBdLCBwcm9jLCBib2R5KSlcclxuICB9XHJcblxyXG4gIC8vSW5saW5lIGVwaWxvZ1xyXG4gIGlmKHByb2MucG9zdC5ib2R5Lmxlbmd0aCA+IDMpIHtcclxuICAgIGNvZGUucHVzaChwcm9jZXNzQmxvY2socHJvYy5wb3N0LCBwcm9jLCBkdHlwZXMpKVxyXG4gIH1cclxuICBcclxuICBpZihwcm9jLmRlYnVnKSB7XHJcbiAgICBjb25zb2xlLmxvZyhcIi0tLS0tR2VuZXJhdGVkIGN3aXNlIHJvdXRpbmUgZm9yIFwiLCB0eXBlc2lnLCBcIjpcXG5cIiArIGNvZGUuam9pbihcIlxcblwiKSArIFwiXFxuLS0tLS0tLS0tLVwiKVxyXG4gIH1cclxuICBcclxuICB2YXIgbG9vcE5hbWUgPSBbKHByb2MuZnVuY05hbWV8fFwidW5uYW1lZFwiKSwgXCJfY3dpc2VfbG9vcF9cIiwgb3JkZXJzWzBdLmpvaW4oXCJzXCIpLFwibVwiLG1hdGNoZWQsdHlwZVN1bW1hcnkoZHR5cGVzKV0uam9pbihcIlwiKVxyXG4gIHZhciBmID0gbmV3IEZ1bmN0aW9uKFtcImZ1bmN0aW9uIFwiLGxvb3BOYW1lLFwiKFwiLCBhcmdsaXN0LmpvaW4oXCIsXCIpLFwiKXtcIiwgY29kZS5qb2luKFwiXFxuXCIpLFwifSByZXR1cm4gXCIsIGxvb3BOYW1lXS5qb2luKFwiXCIpKVxyXG4gIHJldHVybiBmKClcclxufVxyXG5tb2R1bGUuZXhwb3J0cyA9IGdlbmVyYXRlQ1dpc2VPcFxyXG4iLCJcInVzZSBzdHJpY3RcIlxyXG5cclxuLy8gVGhlIGZ1bmN0aW9uIGJlbG93IGlzIGNhbGxlZCB3aGVuIGNvbnN0cnVjdGluZyBhIGN3aXNlIGZ1bmN0aW9uIG9iamVjdCwgYW5kIGRvZXMgdGhlIGZvbGxvd2luZzpcclxuLy8gQSBmdW5jdGlvbiBvYmplY3QgaXMgY29uc3RydWN0ZWQgd2hpY2ggYWNjZXB0cyBhcyBhcmd1bWVudCBhIGNvbXBpbGF0aW9uIGZ1bmN0aW9uIGFuZCByZXR1cm5zIGFub3RoZXIgZnVuY3Rpb24uXHJcbi8vIEl0IGlzIHRoaXMgb3RoZXIgZnVuY3Rpb24gdGhhdCBpcyBldmVudHVhbGx5IHJldHVybmVkIGJ5IGNyZWF0ZVRodW5rLCBhbmQgdGhpcyBmdW5jdGlvbiBpcyB0aGUgb25lIHRoYXQgYWN0dWFsbHlcclxuLy8gY2hlY2tzIHdoZXRoZXIgYSBjZXJ0YWluIHBhdHRlcm4gb2YgYXJndW1lbnRzIGhhcyBhbHJlYWR5IGJlZW4gdXNlZCBiZWZvcmUgYW5kIGNvbXBpbGVzIG5ldyBsb29wcyBhcyBuZWVkZWQuXHJcbi8vIFRoZSBjb21waWxhdGlvbiBwYXNzZWQgdG8gdGhlIGZpcnN0IGZ1bmN0aW9uIG9iamVjdCBpcyB1c2VkIGZvciBjb21waWxpbmcgbmV3IGZ1bmN0aW9ucy5cclxuLy8gT25jZSB0aGlzIGZ1bmN0aW9uIG9iamVjdCBpcyBjcmVhdGVkLCBpdCBpcyBjYWxsZWQgd2l0aCBjb21waWxlIGFzIGFyZ3VtZW50LCB3aGVyZSB0aGUgZmlyc3QgYXJndW1lbnQgb2YgY29tcGlsZVxyXG4vLyBpcyBib3VuZCB0byBcInByb2NcIiAoZXNzZW50aWFsbHkgY29udGFpbmluZyBhIHByZXByb2Nlc3NlZCB2ZXJzaW9uIG9mIHRoZSB1c2VyIGFyZ3VtZW50cyB0byBjd2lzZSkuXHJcbi8vIFNvIGNyZWF0ZVRodW5rIHJvdWdobHkgd29ya3MgbGlrZSB0aGlzOlxyXG4vLyBmdW5jdGlvbiBjcmVhdGVUaHVuayhwcm9jKSB7XHJcbi8vICAgdmFyIHRodW5rID0gZnVuY3Rpb24oY29tcGlsZUJvdW5kKSB7XHJcbi8vICAgICB2YXIgQ0FDSEVEID0ge31cclxuLy8gICAgIHJldHVybiBmdW5jdGlvbihhcnJheXMgYW5kIHNjYWxhcnMpIHtcclxuLy8gICAgICAgaWYgKGR0eXBlIGFuZCBvcmRlciBvZiBhcnJheXMgaW4gQ0FDSEVEKSB7XHJcbi8vICAgICAgICAgdmFyIGZ1bmMgPSBDQUNIRURbZHR5cGUgYW5kIG9yZGVyIG9mIGFycmF5c11cclxuLy8gICAgICAgfSBlbHNlIHtcclxuLy8gICAgICAgICB2YXIgZnVuYyA9IENBQ0hFRFtkdHlwZSBhbmQgb3JkZXIgb2YgYXJyYXlzXSA9IGNvbXBpbGVCb3VuZChkdHlwZSBhbmQgb3JkZXIgb2YgYXJyYXlzKVxyXG4vLyAgICAgICB9XHJcbi8vICAgICAgIHJldHVybiBmdW5jKGFycmF5cyBhbmQgc2NhbGFycylcclxuLy8gICAgIH1cclxuLy8gICB9XHJcbi8vICAgcmV0dXJuIHRodW5rKGNvbXBpbGUuYmluZDEocHJvYykpXHJcbi8vIH1cclxuXHJcbnZhciBjb21waWxlID0gcmVxdWlyZShcIi4vY29tcGlsZS5qc1wiKVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlVGh1bmsocHJvYykge1xyXG4gIHZhciBjb2RlID0gW1wiJ3VzZSBzdHJpY3QnXCIsIFwidmFyIENBQ0hFRD17fVwiXVxyXG4gIHZhciB2YXJzID0gW11cclxuICB2YXIgdGh1bmtOYW1lID0gcHJvYy5mdW5jTmFtZSArIFwiX2N3aXNlX3RodW5rXCJcclxuICBcclxuICAvL0J1aWxkIHRodW5rXHJcbiAgY29kZS5wdXNoKFtcInJldHVybiBmdW5jdGlvbiBcIiwgdGh1bmtOYW1lLCBcIihcIiwgcHJvYy5zaGltQXJncy5qb2luKFwiLFwiKSwgXCIpe1wiXS5qb2luKFwiXCIpKVxyXG4gIHZhciB0eXBlc2lnID0gW11cclxuICB2YXIgc3RyaW5nX3R5cGVzaWcgPSBbXVxyXG4gIHZhciBwcm9jX2FyZ3MgPSBbW1wiYXJyYXlcIixwcm9jLmFycmF5QXJnc1swXSxcIi5zaGFwZS5zbGljZShcIiwgLy8gU2xpY2Ugc2hhcGUgc28gdGhhdCB3ZSBvbmx5IHJldGFpbiB0aGUgc2hhcGUgb3ZlciB3aGljaCB3ZSBpdGVyYXRlICh3aGljaCBnZXRzIHBhc3NlZCB0byB0aGUgY3dpc2Ugb3BlcmF0b3IgYXMgU1MpLlxyXG4gICAgICAgICAgICAgICAgICAgIE1hdGgubWF4KDAscHJvYy5hcnJheUJsb2NrSW5kaWNlc1swXSkscHJvYy5hcnJheUJsb2NrSW5kaWNlc1swXTwwPyhcIixcIitwcm9jLmFycmF5QmxvY2tJbmRpY2VzWzBdK1wiKVwiKTpcIilcIl0uam9pbihcIlwiKV1cclxuICB2YXIgc2hhcGVMZW5ndGhDb25kaXRpb25zID0gW10sIHNoYXBlQ29uZGl0aW9ucyA9IFtdXHJcbiAgLy8gUHJvY2VzcyBhcnJheSBhcmd1bWVudHNcclxuICBmb3IodmFyIGk9MDsgaTxwcm9jLmFycmF5QXJncy5sZW5ndGg7ICsraSkge1xyXG4gICAgdmFyIGogPSBwcm9jLmFycmF5QXJnc1tpXVxyXG4gICAgdmFycy5wdXNoKFtcInRcIiwgaiwgXCI9YXJyYXlcIiwgaiwgXCIuZHR5cGUsXCIsXHJcbiAgICAgICAgICAgICAgIFwiclwiLCBqLCBcIj1hcnJheVwiLCBqLCBcIi5vcmRlclwiXS5qb2luKFwiXCIpKVxyXG4gICAgdHlwZXNpZy5wdXNoKFwidFwiICsgailcclxuICAgIHR5cGVzaWcucHVzaChcInJcIiArIGopXHJcbiAgICBzdHJpbmdfdHlwZXNpZy5wdXNoKFwidFwiK2opXHJcbiAgICBzdHJpbmdfdHlwZXNpZy5wdXNoKFwiclwiK2orXCIuam9pbigpXCIpXHJcbiAgICBwcm9jX2FyZ3MucHVzaChcImFycmF5XCIgKyBqICsgXCIuZGF0YVwiKVxyXG4gICAgcHJvY19hcmdzLnB1c2goXCJhcnJheVwiICsgaiArIFwiLnN0cmlkZVwiKVxyXG4gICAgcHJvY19hcmdzLnB1c2goXCJhcnJheVwiICsgaiArIFwiLm9mZnNldHwwXCIpXHJcbiAgICBpZiAoaT4wKSB7IC8vIEdhdGhlciBjb25kaXRpb25zIHRvIGNoZWNrIGZvciBzaGFwZSBlcXVhbGl0eSAoaWdub3JpbmcgYmxvY2sgaW5kaWNlcylcclxuICAgICAgc2hhcGVMZW5ndGhDb25kaXRpb25zLnB1c2goXCJhcnJheVwiICsgcHJvYy5hcnJheUFyZ3NbMF0gKyBcIi5zaGFwZS5sZW5ndGg9PT1hcnJheVwiICsgaiArIFwiLnNoYXBlLmxlbmd0aCtcIiArIChNYXRoLmFicyhwcm9jLmFycmF5QmxvY2tJbmRpY2VzWzBdKS1NYXRoLmFicyhwcm9jLmFycmF5QmxvY2tJbmRpY2VzW2ldKSkpXHJcbiAgICAgIHNoYXBlQ29uZGl0aW9ucy5wdXNoKFwiYXJyYXlcIiArIHByb2MuYXJyYXlBcmdzWzBdICsgXCIuc2hhcGVbc2hhcGVJbmRleCtcIiArIE1hdGgubWF4KDAscHJvYy5hcnJheUJsb2NrSW5kaWNlc1swXSkgKyBcIl09PT1hcnJheVwiICsgaiArIFwiLnNoYXBlW3NoYXBlSW5kZXgrXCIgKyBNYXRoLm1heCgwLHByb2MuYXJyYXlCbG9ja0luZGljZXNbaV0pICsgXCJdXCIpXHJcbiAgICB9XHJcbiAgfVxyXG4gIC8vIENoZWNrIGZvciBzaGFwZSBlcXVhbGl0eVxyXG4gIGlmIChwcm9jLmFycmF5QXJncy5sZW5ndGggPiAxKSB7XHJcbiAgICBjb2RlLnB1c2goXCJpZiAoIShcIiArIHNoYXBlTGVuZ3RoQ29uZGl0aW9ucy5qb2luKFwiICYmIFwiKSArIFwiKSkgdGhyb3cgbmV3IEVycm9yKCdjd2lzZTogQXJyYXlzIGRvIG5vdCBhbGwgaGF2ZSB0aGUgc2FtZSBkaW1lbnNpb25hbGl0eSEnKVwiKVxyXG4gICAgY29kZS5wdXNoKFwiZm9yKHZhciBzaGFwZUluZGV4PWFycmF5XCIgKyBwcm9jLmFycmF5QXJnc1swXSArIFwiLnNoYXBlLmxlbmd0aC1cIiArIE1hdGguYWJzKHByb2MuYXJyYXlCbG9ja0luZGljZXNbMF0pICsgXCI7IHNoYXBlSW5kZXgtLT4wOykge1wiKVxyXG4gICAgY29kZS5wdXNoKFwiaWYgKCEoXCIgKyBzaGFwZUNvbmRpdGlvbnMuam9pbihcIiAmJiBcIikgKyBcIikpIHRocm93IG5ldyBFcnJvcignY3dpc2U6IEFycmF5cyBkbyBub3QgYWxsIGhhdmUgdGhlIHNhbWUgc2hhcGUhJylcIilcclxuICAgIGNvZGUucHVzaChcIn1cIilcclxuICB9XHJcbiAgLy8gUHJvY2VzcyBzY2FsYXIgYXJndW1lbnRzXHJcbiAgZm9yKHZhciBpPTA7IGk8cHJvYy5zY2FsYXJBcmdzLmxlbmd0aDsgKytpKSB7XHJcbiAgICBwcm9jX2FyZ3MucHVzaChcInNjYWxhclwiICsgcHJvYy5zY2FsYXJBcmdzW2ldKVxyXG4gIH1cclxuICAvLyBDaGVjayBmb3IgY2FjaGVkIGZ1bmN0aW9uIChhbmQgaWYgbm90IHByZXNlbnQsIGdlbmVyYXRlIGl0KVxyXG4gIHZhcnMucHVzaChbXCJ0eXBlPVtcIiwgc3RyaW5nX3R5cGVzaWcuam9pbihcIixcIiksIFwiXS5qb2luKClcIl0uam9pbihcIlwiKSlcclxuICB2YXJzLnB1c2goXCJwcm9jPUNBQ0hFRFt0eXBlXVwiKVxyXG4gIGNvZGUucHVzaChcInZhciBcIiArIHZhcnMuam9pbihcIixcIikpXHJcbiAgXHJcbiAgY29kZS5wdXNoKFtcImlmKCFwcm9jKXtcIixcclxuICAgICAgICAgICAgIFwiQ0FDSEVEW3R5cGVdPXByb2M9Y29tcGlsZShbXCIsIHR5cGVzaWcuam9pbihcIixcIiksIFwiXSl9XCIsXHJcbiAgICAgICAgICAgICBcInJldHVybiBwcm9jKFwiLCBwcm9jX2FyZ3Muam9pbihcIixcIiksIFwiKX1cIl0uam9pbihcIlwiKSlcclxuXHJcbiAgaWYocHJvYy5kZWJ1Zykge1xyXG4gICAgY29uc29sZS5sb2coXCItLS0tLUdlbmVyYXRlZCB0aHVuazpcXG5cIiArIGNvZGUuam9pbihcIlxcblwiKSArIFwiXFxuLS0tLS0tLS0tLVwiKVxyXG4gIH1cclxuICBcclxuICAvL0NvbXBpbGUgdGh1bmtcclxuICB2YXIgdGh1bmsgPSBuZXcgRnVuY3Rpb24oXCJjb21waWxlXCIsIGNvZGUuam9pbihcIlxcblwiKSlcclxuICByZXR1cm4gdGh1bmsoY29tcGlsZS5iaW5kKHVuZGVmaW5lZCwgcHJvYykpXHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlVGh1bmtcclxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuZnVuY3Rpb24gdW5pcXVlX3ByZWQobGlzdCwgY29tcGFyZSkge1xuICB2YXIgcHRyID0gMVxuICAgICwgbGVuID0gbGlzdC5sZW5ndGhcbiAgICAsIGE9bGlzdFswXSwgYj1saXN0WzBdXG4gIGZvcih2YXIgaT0xOyBpPGxlbjsgKytpKSB7XG4gICAgYiA9IGFcbiAgICBhID0gbGlzdFtpXVxuICAgIGlmKGNvbXBhcmUoYSwgYikpIHtcbiAgICAgIGlmKGkgPT09IHB0cikge1xuICAgICAgICBwdHIrK1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgbGlzdFtwdHIrK10gPSBhXG4gICAgfVxuICB9XG4gIGxpc3QubGVuZ3RoID0gcHRyXG4gIHJldHVybiBsaXN0XG59XG5cbmZ1bmN0aW9uIHVuaXF1ZV9lcShsaXN0KSB7XG4gIHZhciBwdHIgPSAxXG4gICAgLCBsZW4gPSBsaXN0Lmxlbmd0aFxuICAgICwgYT1saXN0WzBdLCBiID0gbGlzdFswXVxuICBmb3IodmFyIGk9MTsgaTxsZW47ICsraSwgYj1hKSB7XG4gICAgYiA9IGFcbiAgICBhID0gbGlzdFtpXVxuICAgIGlmKGEgIT09IGIpIHtcbiAgICAgIGlmKGkgPT09IHB0cikge1xuICAgICAgICBwdHIrK1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgbGlzdFtwdHIrK10gPSBhXG4gICAgfVxuICB9XG4gIGxpc3QubGVuZ3RoID0gcHRyXG4gIHJldHVybiBsaXN0XG59XG5cbmZ1bmN0aW9uIHVuaXF1ZShsaXN0LCBjb21wYXJlLCBzb3J0ZWQpIHtcbiAgaWYobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbGlzdFxuICB9XG4gIGlmKGNvbXBhcmUpIHtcbiAgICBpZighc29ydGVkKSB7XG4gICAgICBsaXN0LnNvcnQoY29tcGFyZSlcbiAgICB9XG4gICAgcmV0dXJuIHVuaXF1ZV9wcmVkKGxpc3QsIGNvbXBhcmUpXG4gIH1cbiAgaWYoIXNvcnRlZCkge1xuICAgIGxpc3Quc29ydCgpXG4gIH1cbiAgcmV0dXJuIHVuaXF1ZV9lcShsaXN0KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHVuaXF1ZVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxubW9kdWxlLmV4cG9ydHMgPSBmaW5kWmVyb0Nyb3NzaW5nc1xuXG52YXIgY29yZSA9IHJlcXVpcmUoXCIuL2xpYi96Yy1jb3JlXCIpXG5cbmZ1bmN0aW9uIGZpbmRaZXJvQ3Jvc3NpbmdzKGFycmF5LCBsZXZlbCkge1xuICB2YXIgY3Jvc3MgPSBbXVxuICBsZXZlbCA9ICtsZXZlbCB8fCAwLjBcbiAgY29yZShhcnJheS5oaShhcnJheS5zaGFwZVswXS0xKSwgY3Jvc3MsIGxldmVsKVxuICByZXR1cm4gY3Jvc3Ncbn0iLCJcInVzZSBzdHJpY3RcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IHN1cmZhY2VOZXRzXG5cbnZhciBnZW5lcmF0ZUNvbnRvdXJFeHRyYWN0b3IgPSByZXF1aXJlKFwibmRhcnJheS1leHRyYWN0LWNvbnRvdXJcIilcbnZhciB0cmlhbmd1bGF0ZUN1YmUgPSByZXF1aXJlKFwidHJpYW5ndWxhdGUtaHlwZXJjdWJlXCIpXG52YXIgemVyb0Nyb3NzaW5ncyA9IHJlcXVpcmUoXCJ6ZXJvLWNyb3NzaW5nc1wiKVxuXG5mdW5jdGlvbiBidWlsZFN1cmZhY2VOZXRzKG9yZGVyLCBkdHlwZSkge1xuICB2YXIgZGltZW5zaW9uID0gb3JkZXIubGVuZ3RoXG4gIHZhciBjb2RlID0gW1wiJ3VzZSBzdHJpY3QnO1wiXVxuICB2YXIgZnVuY05hbWUgPSBcInN1cmZhY2VOZXRzXCIgKyBvcmRlci5qb2luKFwiX1wiKSArIFwiZFwiICsgZHR5cGVcblxuICAvL0NvbnRvdXIgZXh0cmFjdGlvbiBmdW5jdGlvblxuICBjb2RlLnB1c2goXG4gICAgXCJ2YXIgY29udG91cj1nZW5Db250b3VyKHtcIixcbiAgICAgIFwib3JkZXI6W1wiLCBvcmRlci5qb2luKCksIFwiXSxcIixcbiAgICAgIFwic2NhbGFyQXJndW1lbnRzOiAzLFwiLFxuICAgICAgXCJwaGFzZTpmdW5jdGlvbiBwaGFzZUZ1bmMocCxhLGIsYykgeyByZXR1cm4gKHAgPiBjKXwwIH0sXCIpXG4gIGlmKGR0eXBlID09PSBcImdlbmVyaWNcIikge1xuICAgIGNvZGUucHVzaChcImdldHRlcnM6WzBdLFwiKVxuICB9XG5cbiAgLy9HZW5lcmF0ZSB2ZXJ0ZXggZnVuY3Rpb25cbiAgdmFyIGN1YmVBcmdzID0gW11cbiAgdmFyIGV4dHJhQXJncyA9IFtdXG4gIGZvcih2YXIgaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7XG4gICAgY3ViZUFyZ3MucHVzaChcImRcIiArIGkpXG4gICAgZXh0cmFBcmdzLnB1c2goXCJkXCIgKyBpKVxuICB9XG4gIGZvcih2YXIgaT0wOyBpPCgxPDxkaW1lbnNpb24pOyArK2kpIHtcbiAgICBjdWJlQXJncy5wdXNoKFwidlwiICsgaSlcbiAgICBleHRyYUFyZ3MucHVzaChcInZcIiArIGkpXG4gIH1cbiAgZm9yKHZhciBpPTA7IGk8KDE8PGRpbWVuc2lvbik7ICsraSkge1xuICAgIGN1YmVBcmdzLnB1c2goXCJwXCIgKyBpKVxuICAgIGV4dHJhQXJncy5wdXNoKFwicFwiICsgaSlcbiAgfVxuICBjdWJlQXJncy5wdXNoKFwiYVwiLCBcImJcIiwgXCJjXCIpXG4gIGV4dHJhQXJncy5wdXNoKFwiYVwiLCBcImNcIilcbiAgY29kZS5wdXNoKFwidmVydGV4OmZ1bmN0aW9uIHZlcnRleEZ1bmMoXCIsIGN1YmVBcmdzLmpvaW4oKSwgXCIpe1wiKVxuICAvL01hc2sgYXJncyB0b2dldGhlclxuICB2YXIgbWFza1N0ciA9IFtdXG4gIGZvcih2YXIgaT0wOyBpPCgxPDxkaW1lbnNpb24pOyArK2kpIHtcbiAgICBtYXNrU3RyLnB1c2goXCIocFwiICsgaSArIFwiPDxcIiArIGkgKyBcIilcIilcbiAgfVxuICAvL0dlbmVyYXRlIHZhcmlhYmxlcyBhbmQgZ2lnYW50byBzd2l0Y2ggc3RhdGVtZW50XG4gIGNvZGUucHVzaChcInZhciBtPShcIiwgbWFza1N0ci5qb2luKFwiK1wiKSwgXCIpfDA7aWYobT09PTB8fG09PT1cIiwgKDE8PCgxPDxkaW1lbnNpb24pKS0xLCBcIil7cmV0dXJufVwiKVxuICB2YXIgZXh0cmFGdW5jcyA9IFtdXG4gIHZhciBjdXJyZW50RnVuYyA9IFtdXG4gIGlmKDE8PCgxPDxkaW1lbnNpb24pIDw9IDEyOCkge1xuICAgIGNvZGUucHVzaChcInN3aXRjaChtKXtcIilcbiAgICBjdXJyZW50RnVuYyA9IGNvZGVcbiAgfSBlbHNlIHtcbiAgICBjb2RlLnB1c2goXCJzd2l0Y2gobT4+Pjcpe1wiKVxuICB9XG4gIGZvcih2YXIgaT0wOyBpPDE8PCgxPDxkaW1lbnNpb24pOyArK2kpIHtcbiAgICBpZigxPDwoMTw8ZGltZW5zaW9uKSA+IDEyOCkge1xuICAgICAgaWYoKGklMTI4KT09PTApIHtcbiAgICAgICAgaWYoZXh0cmFGdW5jcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY3VycmVudEZ1bmMucHVzaChcIn19XCIpXG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVmTmFtZSA9IFwidkV4dHJhXCIgKyBleHRyYUZ1bmNzLmxlbmd0aFxuICAgICAgICBjb2RlLnB1c2goXCJjYXNlIFwiLCAoaT4+PjcpLCBcIjpcIiwgZWZOYW1lLCBcIihtJjB4N2YsXCIsIGV4dHJhQXJncy5qb2luKCksIFwiKTticmVhaztcIilcbiAgICAgICAgY3VycmVudEZ1bmMgPSBbXG4gICAgICAgICAgXCJmdW5jdGlvbiBcIiwgZWZOYW1lLCBcIihtLFwiLCBleHRyYUFyZ3Muam9pbigpLCBcIil7c3dpdGNoKG0pe1wiXG4gICAgICAgIF1cbiAgICAgICAgZXh0cmFGdW5jcy5wdXNoKGN1cnJlbnRGdW5jKVxuICAgICAgfSAgXG4gICAgfVxuICAgIGN1cnJlbnRGdW5jLnB1c2goXCJjYXNlIFwiLCAoaSYweDdmKSwgXCI6XCIpXG4gICAgdmFyIGNyb3NzaW5ncyA9IG5ldyBBcnJheShkaW1lbnNpb24pXG4gICAgdmFyIGRlbm9tcyA9IG5ldyBBcnJheShkaW1lbnNpb24pXG4gICAgdmFyIGNyb3NzaW5nQ291bnQgPSBuZXcgQXJyYXkoZGltZW5zaW9uKVxuICAgIHZhciBiaWFzID0gbmV3IEFycmF5KGRpbWVuc2lvbilcbiAgICB2YXIgdG90YWxDcm9zc2luZ3MgPSAwXG4gICAgZm9yKHZhciBqPTA7IGo8ZGltZW5zaW9uOyArK2opIHtcbiAgICAgIGNyb3NzaW5nc1tqXSA9IFtdXG4gICAgICBkZW5vbXNbal0gPSBbXVxuICAgICAgY3Jvc3NpbmdDb3VudFtqXSA9IDBcbiAgICAgIGJpYXNbal0gPSAwXG4gICAgfVxuICAgIGZvcih2YXIgaj0wOyBqPCgxPDxkaW1lbnNpb24pOyArK2opIHtcbiAgICAgIGZvcih2YXIgaz0wOyBrPGRpbWVuc2lvbjsgKytrKSB7XG4gICAgICAgIHZhciB1ID0gaiBeICgxPDxrKVxuICAgICAgICBpZih1ID4gaikge1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgICAgaWYoIShpJigxPDx1KSkgIT09ICEoaSYoMTw8aikpKSB7XG4gICAgICAgICAgdmFyIHNpZ24gPSAxXG4gICAgICAgICAgaWYoaSYoMTw8dSkpIHtcbiAgICAgICAgICAgIGRlbm9tc1trXS5wdXNoKFwidlwiICsgdSArIFwiLXZcIiArIGopXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlbm9tc1trXS5wdXNoKFwidlwiICsgaiArIFwiLXZcIiArIHUpXG4gICAgICAgICAgICBzaWduID0gLXNpZ25cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYoc2lnbiA8IDApIHtcbiAgICAgICAgICAgIGNyb3NzaW5nc1trXS5wdXNoKFwiLXZcIiArIGogKyBcIi12XCIgKyB1KVxuICAgICAgICAgICAgY3Jvc3NpbmdDb3VudFtrXSArPSAyXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNyb3NzaW5nc1trXS5wdXNoKFwidlwiICsgaiArIFwiK3ZcIiArIHUpXG4gICAgICAgICAgICBjcm9zc2luZ0NvdW50W2tdIC09IDIgICAgICAgICAgICBcbiAgICAgICAgICB9XG4gICAgICAgICAgdG90YWxDcm9zc2luZ3MgKz0gMVxuICAgICAgICAgIGZvcih2YXIgbD0wOyBsPGRpbWVuc2lvbjsgKytsKSB7XG4gICAgICAgICAgICBpZihsID09PSBrKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZih1JigxPDxsKSkge1xuICAgICAgICAgICAgICBiaWFzW2xdICs9IDFcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGJpYXNbbF0gLT0gMVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB2YXIgdmVydGV4U3RyID0gW11cbiAgICBmb3IodmFyIGs9MDsgazxkaW1lbnNpb247ICsraykge1xuICAgICAgaWYoY3Jvc3NpbmdzW2tdLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2ZXJ0ZXhTdHIucHVzaChcImRcIiArIGsgKyBcIi0wLjVcIilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBjU3RyID0gXCJcIlxuICAgICAgICBpZihjcm9zc2luZ0NvdW50W2tdIDwgMCkge1xuICAgICAgICAgIGNTdHIgPSBjcm9zc2luZ0NvdW50W2tdICsgXCIqY1wiXG4gICAgICAgIH0gZWxzZSBpZihjcm9zc2luZ0NvdW50W2tdID4gMCkge1xuICAgICAgICAgIGNTdHIgPSBcIitcIiArIGNyb3NzaW5nQ291bnRba10gKyBcIipjXCJcbiAgICAgICAgfVxuICAgICAgICB2YXIgd2VpZ2h0ID0gMC41ICogKGNyb3NzaW5nc1trXS5sZW5ndGggLyB0b3RhbENyb3NzaW5ncylcbiAgICAgICAgdmFyIHNoaWZ0ID0gMC41ICsgMC41ICogKGJpYXNba10gLyB0b3RhbENyb3NzaW5ncylcbiAgICAgICAgdmVydGV4U3RyLnB1c2goXCJkXCIgKyBrICsgXCItXCIgKyBzaGlmdCArIFwiLVwiICsgd2VpZ2h0ICsgXCIqKFwiICsgY3Jvc3NpbmdzW2tdLmpvaW4oXCIrXCIpICsgY1N0ciArIFwiKS8oXCIgKyBkZW5vbXNba10uam9pbihcIitcIikgKyBcIilcIilcbiAgICAgICAgXG4gICAgICB9XG4gICAgfVxuICAgIGN1cnJlbnRGdW5jLnB1c2goXCJhLnB1c2goW1wiLCB2ZXJ0ZXhTdHIuam9pbigpLCBcIl0pO1wiLFxuICAgICAgXCJicmVhaztcIilcbiAgfVxuICBjb2RlLnB1c2goXCJ9fSxcIilcbiAgaWYoZXh0cmFGdW5jcy5sZW5ndGggPiAwKSB7XG4gICAgY3VycmVudEZ1bmMucHVzaChcIn19XCIpXG4gIH1cblxuICAvL0NyZWF0ZSBmYWNlIGZ1bmN0aW9uXG4gIHZhciBmYWNlQXJncyA9IFtdXG4gIGZvcih2YXIgaT0wOyBpPCgxPDwoZGltZW5zaW9uLTEpKTsgKytpKSB7XG4gICAgZmFjZUFyZ3MucHVzaChcInZcIiArIGkpXG4gIH1cbiAgZmFjZUFyZ3MucHVzaChcImMwXCIsIFwiYzFcIiwgXCJwMFwiLCBcInAxXCIsIFwiYVwiLCBcImJcIiwgXCJjXCIpXG4gIGNvZGUucHVzaChcImNlbGw6ZnVuY3Rpb24gY2VsbEZ1bmMoXCIsIGZhY2VBcmdzLmpvaW4oKSwgXCIpe1wiKVxuXG4gIHZhciBmYWNldHMgPSB0cmlhbmd1bGF0ZUN1YmUoZGltZW5zaW9uLTEpXG4gIGNvZGUucHVzaChcImlmKHAwKXtiLnB1c2goXCIsXG4gICAgZmFjZXRzLm1hcChmdW5jdGlvbihmKSB7XG4gICAgICByZXR1cm4gXCJbXCIgKyBmLm1hcChmdW5jdGlvbih2KSB7XG4gICAgICAgIHJldHVybiBcInZcIiArIHZcbiAgICAgIH0pICsgXCJdXCJcbiAgICB9KS5qb2luKCksIFwiKX1lbHNle2IucHVzaChcIixcbiAgICBmYWNldHMubWFwKGZ1bmN0aW9uKGYpIHtcbiAgICAgIHZhciBlID0gZi5zbGljZSgpXG4gICAgICBlLnJldmVyc2UoKVxuICAgICAgcmV0dXJuIFwiW1wiICsgZS5tYXAoZnVuY3Rpb24odikge1xuICAgICAgICByZXR1cm4gXCJ2XCIgKyB2XG4gICAgICB9KSArIFwiXVwiXG4gICAgfSkuam9pbigpLFxuICAgIFwiKX19fSk7ZnVuY3Rpb24gXCIsIGZ1bmNOYW1lLCBcIihhcnJheSxsZXZlbCl7dmFyIHZlcnRzPVtdLGNlbGxzPVtdO2NvbnRvdXIoYXJyYXksdmVydHMsY2VsbHMsbGV2ZWwpO3JldHVybiB7cG9zaXRpb25zOnZlcnRzLGNlbGxzOmNlbGxzfTt9IHJldHVybiBcIiwgZnVuY05hbWUsIFwiO1wiKVxuXG4gIGZvcih2YXIgaT0wOyBpPGV4dHJhRnVuY3MubGVuZ3RoOyArK2kpIHtcbiAgICBjb2RlLnB1c2goZXh0cmFGdW5jc1tpXS5qb2luKFwiXCIpKVxuICB9XG5cbiAgLy9Db21waWxlIGFuZCBsaW5rXG4gIHZhciBwcm9jID0gbmV3IEZ1bmN0aW9uKFwiZ2VuQ29udG91clwiLCBjb2RlLmpvaW4oXCJcIikpXG4gIHJldHVybiBwcm9jKGdlbmVyYXRlQ29udG91ckV4dHJhY3Rvcilcbn1cblxuLy8xRCBjYXNlOiBOZWVkIHRvIGhhbmRsZSBzcGVjaWFsbHlcbmZ1bmN0aW9uIG1lc2gxRChhcnJheSwgbGV2ZWwpIHtcbiAgdmFyIHpjID0gemVyb0Nyb3NzaW5ncyhhcnJheSwgbGV2ZWwpXG4gIHZhciBuID0gemMubGVuZ3RoXG4gIHZhciBucG9zID0gbmV3IEFycmF5KG4pXG4gIHZhciBuY2VsID0gbmV3IEFycmF5KG4pXG4gIGZvcih2YXIgaT0wOyBpPG47ICsraSkge1xuICAgIG5wb3NbaV0gPSBbIHpjW2ldIF1cbiAgICBuY2VsW2ldID0gWyBpIF1cbiAgfVxuICByZXR1cm4ge1xuICAgIHBvc2l0aW9uczogbnBvcyxcbiAgICBjZWxsczogbmNlbFxuICB9XG59XG5cbnZhciBDQUNIRSA9IHt9XG5cbmZ1bmN0aW9uIHN1cmZhY2VOZXRzKGFycmF5LGxldmVsKSB7XG4gIGlmKGFycmF5LmRpbWVuc2lvbiA8PSAwKSB7XG4gICAgcmV0dXJuIHsgcG9zaXRpb25zOiBbXSwgY2VsbHM6IFtdIH1cbiAgfSBlbHNlIGlmKGFycmF5LmRpbWVuc2lvbiA9PT0gMSkge1xuICAgIHJldHVybiBtZXNoMUQoYXJyYXksIGxldmVsKVxuICB9XG4gIHZhciB0eXBlc2lnID0gYXJyYXkub3JkZXIuam9pbigpICsgXCItXCIgKyBhcnJheS5kdHlwZVxuICB2YXIgcHJvYyA9IENBQ0hFW3R5cGVzaWddXG4gIHZhciBsZXZlbCA9ICgrbGV2ZWwpIHx8IDAuMFxuICBpZighcHJvYykge1xuICAgIHByb2MgPSBDQUNIRVt0eXBlc2lnXSA9IGJ1aWxkU3VyZmFjZU5ldHMoYXJyYXkub3JkZXIsIGFycmF5LmR0eXBlKVxuICB9XG4gIHJldHVybiBwcm9jKGFycmF5LGxldmVsKVxufSJdfQ==
var fc = require('fc')
var center = require('ctx-translate-center')
var grid = require('ctx-render-grid-lines')
var circle = require('ctx-circle')
var ndarray = require('ndarray')
var fillArray = require('ndarray-fill')
var marchingSquares = require('marching-squares')
var surfaceNets = require('surface-nets')
// where size is the bin size from 0..1
function createBinner(radius, width, height) {
var cx = Math.ceil(width/radius)
var cy = Math.ceil(height/radius)
var bins = ndarray(new Int32Array(cx * cy), [cx, cy])
fillArray(bins, function(i, j) { return -1 })
var tests = [[-1, -1], [0, 1], [-1, 1], [0, 1], [1, 1], [1, -1]]
function toCell(point) {
return [
Math.floor(point[0] / radius) * radius,
Math.floor(point[1] / radius) * radius
]
}
function add(point) {
var cell = toCell(point)
findAHome(cell[0], cell[1], point, new Set())
}
add.toCell = toCell
var points = add.points = []
function findAHome(x, y, point, seen) {
seen = new Set(seen)
seen.add(bins.index(x, y))
// cell is empty
if (bins.get(x, y) === -1) {
var index = points.length
points.push(point)
bins.set(x, y, 1)
return true
}
var closest = tests.map(function(t, i) {
var dx = x + t[0] - point[0]
var dy = y + t[1] - point[1]
return [
dx*dx + dy*dy,
i
]
}).sort(function(a, b) {
return a[0] - b[0]
})
for (var i=0; i<tests.length; i++) {
var test = tests[closest[i][1]]
var tx = x + test[0]
var ty = y + test[1]
if (!seen.has(bins.index(tx, ty)) && findAHome(tx, ty, point, seen)) {
return true
}
}
}
function render(ctx) {
var perc = 360/points.length
var loc = 1
for (var x = 0; x < cx; x++) {
for (var y = 0; y < cy; y++) {
if (bins.get(x, y) !== -1) {
ctx.fillStyle = `hsl(${perc * loc}, 100%, 50%)`
ctx.fillRect(x*radius + 1, y*radius + 1, radius - 2, radius - 2)
loc++
}
}
}
}
add.bins = bins
add.render = render
return add
}
var width = 600
var height = 400
var radius = 10
var binner = createBinner(radius, width, height)
// binner([50, 50])
// binner([20, 50])
setInterval(function() {
binner([30, 60])
binner([40, 100])
ctx.dirty()
}, 100)
function point(ctx, vec, r) {
ctx.beginPath()
circle(ctx, vec[0], vec[1], r)
return ctx
}
function fill(ctx, color) {
ctx.fillStyle = color
ctx.fill()
}
var ctx = fc(function() {
ctx.clear()
center(ctx)
ctx.scale(1, -1)
ctx.translate(-400, -200)
ctx.beginPath()
grid(ctx, radius, 0, 0, width, height)
ctx.stroke()
ctx.fillStyle = 'orange'
binner.render(ctx)
var nets = surfaceNets(binner.bins, 0)
ctx.strokeStyle = "white"
nets.cells.forEach(function(cell) {
var start = nets.positions[cell[0]]
var end = nets.positions[cell[1]]
ctx.beginPath()
ctx.moveTo(start[0] * radius, start[1] * radius)
ctx.lineTo(end[0] * radius, end[1] * radius)
ctx.stroke()
})
})
;}, 0)
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"fc": "1.4.3",
"ctx-translate-center": "1.0.0",
"ctx-render-grid-lines": "1.0.0",
"ctx-circle": "1.0.0",
"ndarray": "1.0.18",
"ndarray-fill": "1.0.1",
"marching-squares": "0.2.0",
"surface-nets": "1.0.2"
}
}
<!-- contents of this file will be placed inside the <body> -->
<!-- contents of this file will be placed inside the <head> -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment