mapbox-gl-regex-query
Version:
Query source data using regex
1,559 lines • 128 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.RegexQuery = f()}})(function(){var define,module,exports;return (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';
module.exports = Point;
/**
* A standalone point geometry with useful accessor, comparison, and
* modification methods.
*
* @class Point
* @param {Number} x the x-coordinate. this could be longitude or screen
* pixels, or any other sort of unit.
* @param {Number} y the y-coordinate. this could be latitude or screen
* pixels, or any other sort of unit.
* @example
* var point = new Point(-77, 38);
*/
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype = {
/**
* Clone this point, returning a new point that can be modified
* without affecting the old one.
* @return {Point} the clone
*/
clone: function() { return new Point(this.x, this.y); },
/**
* Add this point's x & y coordinates to another point,
* yielding a new point.
* @param {Point} p the other point
* @return {Point} output point
*/
add: function(p) { return this.clone()._add(p); },
/**
* Subtract this point's x & y coordinates to from point,
* yielding a new point.
* @param {Point} p the other point
* @return {Point} output point
*/
sub: function(p) { return this.clone()._sub(p); },
/**
* Multiply this point's x & y coordinates by point,
* yielding a new point.
* @param {Point} p the other point
* @return {Point} output point
*/
multByPoint: function(p) { return this.clone()._multByPoint(p); },
/**
* Divide this point's x & y coordinates by point,
* yielding a new point.
* @param {Point} p the other point
* @return {Point} output point
*/
divByPoint: function(p) { return this.clone()._divByPoint(p); },
/**
* Multiply this point's x & y coordinates by a factor,
* yielding a new point.
* @param {Point} k factor
* @return {Point} output point
*/
mult: function(k) { return this.clone()._mult(k); },
/**
* Divide this point's x & y coordinates by a factor,
* yielding a new point.
* @param {Point} k factor
* @return {Point} output point
*/
div: function(k) { return this.clone()._div(k); },
/**
* Rotate this point around the 0, 0 origin by an angle a,
* given in radians
* @param {Number} a angle to rotate around, in radians
* @return {Point} output point
*/
rotate: function(a) { return this.clone()._rotate(a); },
/**
* Rotate this point around p point by an angle a,
* given in radians
* @param {Number} a angle to rotate around, in radians
* @param {Point} p Point to rotate around
* @return {Point} output point
*/
rotateAround: function(a,p) { return this.clone()._rotateAround(a,p); },
/**
* Multiply this point by a 4x1 transformation matrix
* @param {Array<Number>} m transformation matrix
* @return {Point} output point
*/
matMult: function(m) { return this.clone()._matMult(m); },
/**
* Calculate this point but as a unit vector from 0, 0, meaning
* that the distance from the resulting point to the 0, 0
* coordinate will be equal to 1 and the angle from the resulting
* point to the 0, 0 coordinate will be the same as before.
* @return {Point} unit vector point
*/
unit: function() { return this.clone()._unit(); },
/**
* Compute a perpendicular point, where the new y coordinate
* is the old x coordinate and the new x coordinate is the old y
* coordinate multiplied by -1
* @return {Point} perpendicular point
*/
perp: function() { return this.clone()._perp(); },
/**
* Return a version of this point with the x & y coordinates
* rounded to integers.
* @return {Point} rounded point
*/
round: function() { return this.clone()._round(); },
/**
* Return the magitude of this point: this is the Euclidean
* distance from the 0, 0 coordinate to this point's x and y
* coordinates.
* @return {Number} magnitude
*/
mag: function() {
return Math.sqrt(this.x * this.x + this.y * this.y);
},
/**
* Judge whether this point is equal to another point, returning
* true or false.
* @param {Point} other the other point
* @return {boolean} whether the points are equal
*/
equals: function(other) {
return this.x === other.x &&
this.y === other.y;
},
/**
* Calculate the distance from this point to another point
* @param {Point} p the other point
* @return {Number} distance
*/
dist: function(p) {
return Math.sqrt(this.distSqr(p));
},
/**
* Calculate the distance from this point to another point,
* without the square root step. Useful if you're comparing
* relative distances.
* @param {Point} p the other point
* @return {Number} distance
*/
distSqr: function(p) {
var dx = p.x - this.x,
dy = p.y - this.y;
return dx * dx + dy * dy;
},
/**
* Get the angle from the 0, 0 coordinate to this point, in radians
* coordinates.
* @return {Number} angle
*/
angle: function() {
return Math.atan2(this.y, this.x);
},
/**
* Get the angle from this point to another point, in radians
* @param {Point} b the other point
* @return {Number} angle
*/
angleTo: function(b) {
return Math.atan2(this.y - b.y, this.x - b.x);
},
/**
* Get the angle between this point and another point, in radians
* @param {Point} b the other point
* @return {Number} angle
*/
angleWith: function(b) {
return this.angleWithSep(b.x, b.y);
},
/*
* Find the angle of the two vectors, solving the formula for
* the cross product a x b = |a||b|sin(θ) for θ.
* @param {Number} x the x-coordinate
* @param {Number} y the y-coordinate
* @return {Number} the angle in radians
*/
angleWithSep: function(x, y) {
return Math.atan2(
this.x * y - this.y * x,
this.x * x + this.y * y);
},
_matMult: function(m) {
var x = m[0] * this.x + m[1] * this.y,
y = m[2] * this.x + m[3] * this.y;
this.x = x;
this.y = y;
return this;
},
_add: function(p) {
this.x += p.x;
this.y += p.y;
return this;
},
_sub: function(p) {
this.x -= p.x;
this.y -= p.y;
return this;
},
_mult: function(k) {
this.x *= k;
this.y *= k;
return this;
},
_div: function(k) {
this.x /= k;
this.y /= k;
return this;
},
_multByPoint: function(p) {
this.x *= p.x;
this.y *= p.y;
return this;
},
_divByPoint: function(p) {
this.x /= p.x;
this.y /= p.y;
return this;
},
_unit: function() {
this._div(this.mag());
return this;
},
_perp: function() {
var y = this.y;
this.y = this.x;
this.x = -y;
return this;
},
_rotate: function(angle) {
var cos = Math.cos(angle),
sin = Math.sin(angle),
x = cos * this.x - sin * this.y,
y = sin * this.x + cos * this.y;
this.x = x;
this.y = y;
return this;
},
_rotateAround: function(angle, p) {
var cos = Math.cos(angle),
sin = Math.sin(angle),
x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y),
y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);
this.x = x;
this.y = y;
return this;
},
_round: function() {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
return this;
}
};
/**
* Construct a point from an array if necessary, otherwise if the input
* is already a Point, or an unknown type, return it unchanged
* @param {Array<Number>|Point|*} a any kind of input value
* @return {Point} constructed point, or passed-through value.
* @example
* // this
* var point = Point.convert([0, 1]);
* // is equivalent to
* var point = new Point(0, 1);
*/
Point.convert = function (a) {
if (a instanceof Point) {
return a;
}
if (Array.isArray(a)) {
return new Point(a[0], a[1]);
}
return a;
};
},{}],2:[function(require,module,exports){
module.exports.VectorTile = require('./lib/vectortile.js');
module.exports.VectorTileFeature = require('./lib/vectortilefeature.js');
module.exports.VectorTileLayer = require('./lib/vectortilelayer.js');
},{"./lib/vectortile.js":3,"./lib/vectortilefeature.js":4,"./lib/vectortilelayer.js":5}],3:[function(require,module,exports){
'use strict';
var VectorTileLayer = require('./vectortilelayer');
module.exports = VectorTile;
function VectorTile(pbf, end) {
this.layers = pbf.readFields(readTile, {}, end);
}
function readTile(tag, layers, pbf) {
if (tag === 3) {
var layer = new VectorTileLayer(pbf, pbf.readVarint() + pbf.pos);
if (layer.length) layers[layer.name] = layer;
}
}
},{"./vectortilelayer":5}],4:[function(require,module,exports){
'use strict';
var Point = require('@mapbox/point-geometry');
module.exports = VectorTileFeature;
function VectorTileFeature(pbf, end, extent, keys, values) {
// Public
this.properties = {};
this.extent = extent;
this.type = 0;
// Private
this._pbf = pbf;
this._geometry = -1;
this._keys = keys;
this._values = values;
pbf.readFields(readFeature, this, end);
}
function readFeature(tag, feature, pbf) {
if (tag == 1) feature.id = pbf.readVarint();
else if (tag == 2) readTag(pbf, feature);
else if (tag == 3) feature.type = pbf.readVarint();
else if (tag == 4) feature._geometry = pbf.pos;
}
function readTag(pbf, feature) {
var end = pbf.readVarint() + pbf.pos;
while (pbf.pos < end) {
var key = feature._keys[pbf.readVarint()],
value = feature._values[pbf.readVarint()];
feature.properties[key] = value;
}
}
VectorTileFeature.types = ['Unknown', 'Point', 'LineString', 'Polygon'];
VectorTileFeature.prototype.loadGeometry = function() {
var pbf = this._pbf;
pbf.pos = this._geometry;
var end = pbf.readVarint() + pbf.pos,
cmd = 1,
length = 0,
x = 0,
y = 0,
lines = [],
line;
while (pbf.pos < end) {
if (!length) {
var cmdLen = pbf.readVarint();
cmd = cmdLen & 0x7;
length = cmdLen >> 3;
}
length--;
if (cmd === 1 || cmd === 2) {
x += pbf.readSVarint();
y += pbf.readSVarint();
if (cmd === 1) { // moveTo
if (line) lines.push(line);
line = [];
}
line.push(new Point(x, y));
} else if (cmd === 7) {
// Workaround for https://github.com/mapbox/mapnik-vector-tile/issues/90
if (line) {
line.push(line[0].clone()); // closePolygon
}
} else {
throw new Error('unknown command ' + cmd);
}
}
if (line) lines.push(line);
return lines;
};
VectorTileFeature.prototype.bbox = function() {
var pbf = this._pbf;
pbf.pos = this._geometry;
var end = pbf.readVarint() + pbf.pos,
cmd = 1,
length = 0,
x = 0,
y = 0,
x1 = Infinity,
x2 = -Infinity,
y1 = Infinity,
y2 = -Infinity;
while (pbf.pos < end) {
if (!length) {
var cmdLen = pbf.readVarint();
cmd = cmdLen & 0x7;
length = cmdLen >> 3;
}
length--;
if (cmd === 1 || cmd === 2) {
x += pbf.readSVarint();
y += pbf.readSVarint();
if (x < x1) x1 = x;
if (x > x2) x2 = x;
if (y < y1) y1 = y;
if (y > y2) y2 = y;
} else if (cmd !== 7) {
throw new Error('unknown command ' + cmd);
}
}
return [x1, y1, x2, y2];
};
VectorTileFeature.prototype.toGeoJSON = function(x, y, z) {
var size = this.extent * Math.pow(2, z),
x0 = this.extent * x,
y0 = this.extent * y,
coords = this.loadGeometry(),
type = VectorTileFeature.types[this.type],
i, j;
function project(line) {
for (var j = 0; j < line.length; j++) {
var p = line[j], y2 = 180 - (p.y + y0) * 360 / size;
line[j] = [
(p.x + x0) * 360 / size - 180,
360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90
];
}
}
switch (this.type) {
case 1:
var points = [];
for (i = 0; i < coords.length; i++) {
points[i] = coords[i][0];
}
coords = points;
project(coords);
break;
case 2:
for (i = 0; i < coords.length; i++) {
project(coords[i]);
}
break;
case 3:
coords = classifyRings(coords);
for (i = 0; i < coords.length; i++) {
for (j = 0; j < coords[i].length; j++) {
project(coords[i][j]);
}
}
break;
}
if (coords.length === 1) {
coords = coords[0];
} else {
type = 'Multi' + type;
}
var result = {
type: "Feature",
geometry: {
type: type,
coordinates: coords
},
properties: this.properties
};
if ('id' in this) {
result.id = this.id;
}
return result;
};
// classifies an array of rings into polygons with outer rings and holes
function classifyRings(rings) {
var len = rings.length;
if (len <= 1) return [rings];
var polygons = [],
polygon,
ccw;
for (var i = 0; i < len; i++) {
var area = signedArea(rings[i]);
if (area === 0) continue;
if (ccw === undefined) ccw = area < 0;
if (ccw === area < 0) {
if (polygon) polygons.push(polygon);
polygon = [rings[i]];
} else {
polygon.push(rings[i]);
}
}
if (polygon) polygons.push(polygon);
return polygons;
}
function signedArea(ring) {
var sum = 0;
for (var i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {
p1 = ring[i];
p2 = ring[j];
sum += (p2.x - p1.x) * (p1.y + p2.y);
}
return sum;
}
},{"@mapbox/point-geometry":1}],5:[function(require,module,exports){
'use strict';
var VectorTileFeature = require('./vectortilefeature.js');
module.exports = VectorTileLayer;
function VectorTileLayer(pbf, end) {
// Public
this.version = 1;
this.name = null;
this.extent = 4096;
this.length = 0;
// Private
this._pbf = pbf;
this._keys = [];
this._values = [];
this._features = [];
pbf.readFields(readLayer, this, end);
this.length = this._features.length;
}
function readLayer(tag, layer, pbf) {
if (tag === 15) layer.version = pbf.readVarint();
else if (tag === 1) layer.name = pbf.readString();
else if (tag === 5) layer.extent = pbf.readVarint();
else if (tag === 2) layer._features.push(pbf.pos);
else if (tag === 3) layer._keys.push(pbf.readString());
else if (tag === 4) layer._values.push(readValueMessage(pbf));
}
function readValueMessage(pbf) {
var value = null,
end = pbf.readVarint() + pbf.pos;
while (pbf.pos < end) {
var tag = pbf.readVarint() >> 3;
value = tag === 1 ? pbf.readString() :
tag === 2 ? pbf.readFloat() :
tag === 3 ? pbf.readDouble() :
tag === 4 ? pbf.readVarint64() :
tag === 5 ? pbf.readVarint() :
tag === 6 ? pbf.readSVarint() :
tag === 7 ? pbf.readBoolean() : null;
}
return value;
}
// return feature `i` from this layer as a `VectorTileFeature`
VectorTileLayer.prototype.feature = function(i) {
if (i < 0 || i >= this._features.length) throw new Error('feature index out of bounds');
this._pbf.pos = this._features[i];
var end = this._pbf.readVarint() + this._pbf.pos;
return new VectorTileFeature(this._pbf, end, this.extent, this._keys, this._values);
};
},{"./vectortilefeature.js":4}],6:[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
}
},{}],7:[function(require,module,exports){
'use strict';//
var Feature = function Feature(vectorTileFeature , z , x , y ) {
this.type = 'Feature';
this._vectorTileFeature = vectorTileFeature;
(vectorTileFeature )._z = z;
(vectorTileFeature )._x = x;
(vectorTileFeature )._y = y;
this.properties = vectorTileFeature.properties;
if (vectorTileFeature.id != null) {
this.id = vectorTileFeature.id;
}
};
var prototypeAccessors = { geometry: {} };
prototypeAccessors.geometry.get = function () {
if (this._geometry === undefined) {
this._geometry = this._vectorTileFeature.toGeoJSON(
(this._vectorTileFeature )._x,
(this._vectorTileFeature )._y,
(this._vectorTileFeature )._z).geometry;
}
return this._geometry;
};
prototypeAccessors.geometry.set = function (g ) {
this._geometry = g;
};
Feature.prototype.toJSON = function toJSON () {
var this$1 = this;
var json = {
geometry: this.geometry
};
for (var i in this$1) {
if (i === '_geometry' || i === '_vectorTileFeature') { continue; }
json[i] = (this$1 )[i];
}
return json;
};
Object.defineProperties( Feature.prototype, prototypeAccessors );
module.exports = Feature;
},{}],8:[function(require,module,exports){
'use strict';
module.exports = Pbf;
var ieee754 = require('ieee754');
function Pbf(buf) {
this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf || 0);
this.pos = 0;
this.type = 0;
this.length = this.buf.length;
}
Pbf.Varint = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum
Pbf.Fixed64 = 1; // 64-bit: double, fixed64, sfixed64
Pbf.Bytes = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields
Pbf.Fixed32 = 5; // 32-bit: float, fixed32, sfixed32
var SHIFT_LEFT_32 = (1 << 16) * (1 << 16),
SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;
Pbf.prototype = {
destroy: function() {
this.buf = null;
},
// === READING =================================================================
readFields: function(readField, result, end) {
end = end || this.length;
while (this.pos < end) {
var val = this.readVarint(),
tag = val >> 3,
startPos = this.pos;
this.type = val & 0x7;
readField(tag, result, this);
if (this.pos === startPos) this.skip(val);
}
return result;
},
readMessage: function(readField, result) {
return this.readFields(readField, result, this.readVarint() + this.pos);
},
readFixed32: function() {
var val = readUInt32(this.buf, this.pos);
this.pos += 4;
return val;
},
readSFixed32: function() {
var val = readInt32(this.buf, this.pos);
this.pos += 4;
return val;
},
// 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed)
readFixed64: function() {
var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;
this.pos += 8;
return val;
},
readSFixed64: function() {
var val = readUInt32(this.buf, this.pos) + readInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;
this.pos += 8;
return val;
},
readFloat: function() {
var val = ieee754.read(this.buf, this.pos, true, 23, 4);
this.pos += 4;
return val;
},
readDouble: function() {
var val = ieee754.read(this.buf, this.pos, true, 52, 8);
this.pos += 8;
return val;
},
readVarint: function(isSigned) {
var buf = this.buf,
val, b;
b = buf[this.pos++]; val = b & 0x7f; if (b < 0x80) return val;
b = buf[this.pos++]; val |= (b & 0x7f) << 7; if (b < 0x80) return val;
b = buf[this.pos++]; val |= (b & 0x7f) << 14; if (b < 0x80) return val;
b = buf[this.pos++]; val |= (b & 0x7f) << 21; if (b < 0x80) return val;
b = buf[this.pos]; val |= (b & 0x0f) << 28;
return readVarintRemainder(val, isSigned, this);
},
readVarint64: function() { // for compatibility with v2.0.1
return this.readVarint(true);
},
readSVarint: function() {
var num = this.readVarint();
return num % 2 === 1 ? (num + 1) / -2 : num / 2; // zigzag encoding
},
readBoolean: function() {
return Boolean(this.readVarint());
},
readString: function() {
var end = this.readVarint() + this.pos,
str = readUtf8(this.buf, this.pos, end);
this.pos = end;
return str;
},
readBytes: function() {
var end = this.readVarint() + this.pos,
buffer = this.buf.subarray(this.pos, end);
this.pos = end;
return buffer;
},
// verbose for performance reasons; doesn't affect gzipped size
readPackedVarint: function(arr, isSigned) {
var end = readPackedEnd(this);
arr = arr || [];
while (this.pos < end) arr.push(this.readVarint(isSigned));
return arr;
},
readPackedSVarint: function(arr) {
var end = readPackedEnd(this);
arr = arr || [];
while (this.pos < end) arr.push(this.readSVarint());
return arr;
},
readPackedBoolean: function(arr) {
var end = readPackedEnd(this);
arr = arr || [];
while (this.pos < end) arr.push(this.readBoolean());
return arr;
},
readPackedFloat: function(arr) {
var end = readPackedEnd(this);
arr = arr || [];
while (this.pos < end) arr.push(this.readFloat());
return arr;
},
readPackedDouble: function(arr) {
var end = readPackedEnd(this);
arr = arr || [];
while (this.pos < end) arr.push(this.readDouble());
return arr;
},
readPackedFixed32: function(arr) {
var end = readPackedEnd(this);
arr = arr || [];
while (this.pos < end) arr.push(this.readFixed32());
return arr;
},
readPackedSFixed32: function(arr) {
var end = readPackedEnd(this);
arr = arr || [];
while (this.pos < end) arr.push(this.readSFixed32());
return arr;
},
readPackedFixed64: function(arr) {
var end = readPackedEnd(this);
arr = arr || [];
while (this.pos < end) arr.push(this.readFixed64());
return arr;
},
readPackedSFixed64: function(arr) {
var end = readPackedEnd(this);
arr = arr || [];
while (this.pos < end) arr.push(this.readSFixed64());
return arr;
},
skip: function(val) {
var type = val & 0x7;
if (type === Pbf.Varint) while (this.buf[this.pos++] > 0x7f) {}
else if (type === Pbf.Bytes) this.pos = this.readVarint() + this.pos;
else if (type === Pbf.Fixed32) this.pos += 4;
else if (type === Pbf.Fixed64) this.pos += 8;
else throw new Error('Unimplemented type: ' + type);
},
// === WRITING =================================================================
writeTag: function(tag, type) {
this.writeVarint((tag << 3) | type);
},
realloc: function(min) {
var length = this.length || 16;
while (length < this.pos + min) length *= 2;
if (length !== this.length) {
var buf = new Uint8Array(length);
buf.set(this.buf);
this.buf = buf;
this.length = length;
}
},
finish: function() {
this.length = this.pos;
this.pos = 0;
return this.buf.subarray(0, this.length);
},
writeFixed32: function(val) {
this.realloc(4);
writeInt32(this.buf, val, this.pos);
this.pos += 4;
},
writeSFixed32: function(val) {
this.realloc(4);
writeInt32(this.buf, val, this.pos);
this.pos += 4;
},
writeFixed64: function(val) {
this.realloc(8);
writeInt32(this.buf, val & -1, this.pos);
writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);
this.pos += 8;
},
writeSFixed64: function(val) {
this.realloc(8);
writeInt32(this.buf, val & -1, this.pos);
writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);
this.pos += 8;
},
writeVarint: function(val) {
val = +val || 0;
if (val > 0xfffffff || val < 0) {
writeBigVarint(val, this);
return;
}
this.realloc(4);
this.buf[this.pos++] = val & 0x7f | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;
this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;
this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;
this.buf[this.pos++] = (val >>> 7) & 0x7f;
},
writeSVarint: function(val) {
this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2);
},
writeBoolean: function(val) {
this.writeVarint(Boolean(val));
},
writeString: function(str) {
str = String(str);
this.realloc(str.length * 4);
this.pos++; // reserve 1 byte for short string length
var startPos = this.pos;
// write the string directly to the buffer and see how much was written
this.pos = writeUtf8(this.buf, str, this.pos);
var len = this.pos - startPos;
if (len >= 0x80) makeRoomForExtraLength(startPos, len, this);
// finally, write the message length in the reserved place and restore the position
this.pos = startPos - 1;
this.writeVarint(len);
this.pos += len;
},
writeFloat: function(val) {
this.realloc(4);
ieee754.write(this.buf, val, this.pos, true, 23, 4);
this.pos += 4;
},
writeDouble: function(val) {
this.realloc(8);
ieee754.write(this.buf, val, this.pos, true, 52, 8);
this.pos += 8;
},
writeBytes: function(buffer) {
var len = buffer.length;
this.writeVarint(len);
this.realloc(len);
for (var i = 0; i < len; i++) this.buf[this.pos++] = buffer[i];
},
writeRawMessage: function(fn, obj) {
this.pos++; // reserve 1 byte for short message length
// write the message directly to the buffer and see how much was written
var startPos = this.pos;
fn(obj, this);
var len = this.pos - startPos;
if (len >= 0x80) makeRoomForExtraLength(startPos, len, this);
// finally, write the message length in the reserved place and restore the position
this.pos = startPos - 1;
this.writeVarint(len);
this.pos += len;
},
writeMessage: function(tag, fn, obj) {
this.writeTag(tag, Pbf.Bytes);
this.writeRawMessage(fn, obj);
},
writePackedVarint: function(tag, arr) { this.writeMessage(tag, writePackedVarint, arr); },
writePackedSVarint: function(tag, arr) { this.writeMessage(tag, writePackedSVarint, arr); },
writePackedBoolean: function(tag, arr) { this.writeMessage(tag, writePackedBoolean, arr); },
writePackedFloat: function(tag, arr) { this.writeMessage(tag, writePackedFloat, arr); },
writePackedDouble: function(tag, arr) { this.writeMessage(tag, writePackedDouble, arr); },
writePackedFixed32: function(tag, arr) { this.writeMessage(tag, writePackedFixed32, arr); },
writePackedSFixed32: function(tag, arr) { this.writeMessage(tag, writePackedSFixed32, arr); },
writePackedFixed64: function(tag, arr) { this.writeMessage(tag, writePackedFixed64, arr); },
writePackedSFixed64: function(tag, arr) { this.writeMessage(tag, writePackedSFixed64, arr); },
writeBytesField: function(tag, buffer) {
this.writeTag(tag, Pbf.Bytes);
this.writeBytes(buffer);
},
writeFixed32Field: function(tag, val) {
this.writeTag(tag, Pbf.Fixed32);
this.writeFixed32(val);
},
writeSFixed32Field: function(tag, val) {
this.writeTag(tag, Pbf.Fixed32);
this.writeSFixed32(val);
},
writeFixed64Field: function(tag, val) {
this.writeTag(tag, Pbf.Fixed64);
this.writeFixed64(val);
},
writeSFixed64Field: function(tag, val) {
this.writeTag(tag, Pbf.Fixed64);
this.writeSFixed64(val);
},
writeVarintField: function(tag, val) {
this.writeTag(tag, Pbf.Varint);
this.writeVarint(val);
},
writeSVarintField: function(tag, val) {
this.writeTag(tag, Pbf.Varint);
this.writeSVarint(val);
},
writeStringField: function(tag, str) {
this.writeTag(tag, Pbf.Bytes);
this.writeString(str);
},
writeFloatField: function(tag, val) {
this.writeTag(tag, Pbf.Fixed32);
this.writeFloat(val);
},
writeDoubleField: function(tag, val) {
this.writeTag(tag, Pbf.Fixed64);
this.writeDouble(val);
},
writeBooleanField: function(tag, val) {
this.writeVarintField(tag, Boolean(val));
}
};
function readVarintRemainder(l, s, p) {
var buf = p.buf,
h, b;
b = buf[p.pos++]; h = (b & 0x70) >> 4; if (b < 0x80) return toNum(l, h, s);
b = buf[p.pos++]; h |= (b & 0x7f) << 3; if (b < 0x80) return toNum(l, h, s);
b = buf[p.pos++]; h |= (b & 0x7f) << 10; if (b < 0x80) return toNum(l, h, s);
b = buf[p.pos++]; h |= (b & 0x7f) << 17; if (b < 0x80) return toNum(l, h, s);
b = buf[p.pos++]; h |= (b & 0x7f) << 24; if (b < 0x80) return toNum(l, h, s);
b = buf[p.pos++]; h |= (b & 0x01) << 31; if (b < 0x80) return toNum(l, h, s);
throw new Error('Expected varint not more than 10 bytes');
}
function readPackedEnd(pbf) {
return pbf.type === Pbf.Bytes ?
pbf.readVarint() + pbf.pos : pbf.pos + 1;
}
function toNum(low, high, isSigned) {
if (isSigned) {
return high * 0x100000000 + (low >>> 0);
}
return ((high >>> 0) * 0x100000000) + (low >>> 0);
}
function writeBigVarint(val, pbf) {
var low, high;
if (val >= 0) {
low = (val % 0x100000000) | 0;
high = (val / 0x100000000) | 0;
} else {
low = ~(-val % 0x100000000);
high = ~(-val / 0x100000000);
if (low ^ 0xffffffff) {
low = (low + 1) | 0;
} else {
low = 0;
high = (high + 1) | 0;
}
}
if (val >= 0x10000000000000000 || val < -0x10000000000000000) {
throw new Error('Given varint doesn\'t fit into 10 bytes');
}
pbf.realloc(10);
writeBigVarintLow(low, high, pbf);
writeBigVarintHigh(high, pbf);
}
function writeBigVarintLow(low, high, pbf) {
pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;
pbf.buf[pbf.pos] = low & 0x7f;
}
function writeBigVarintHigh(high, pbf) {
var lsb = (high & 0x07) << 4;
pbf.buf[pbf.pos++] |= lsb | ((high >>>= 3) ? 0x80 : 0); if (!high) return;
pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;
pbf.buf[pbf.pos++] = high & 0x7f;
}
function makeRoomForExtraLength(startPos, len, pbf) {
var extraLen =
len <= 0x3fff ? 1 :
len <= 0x1fffff ? 2 :
len <= 0xfffffff ? 3 : Math.ceil(Math.log(len) / (Math.LN2 * 7));
// if 1 byte isn't enough for encoding message length, shift the data to the right
pbf.realloc(extraLen);
for (var i = pbf.pos - 1; i >= startPos; i--) pbf.buf[i + extraLen] = pbf.buf[i];
}
function writePackedVarint(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeVarint(arr[i]); }
function writePackedSVarint(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSVarint(arr[i]); }
function writePackedFloat(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeFloat(arr[i]); }
function writePackedDouble(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeDouble(arr[i]); }
function writePackedBoolean(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeBoolean(arr[i]); }
function writePackedFixed32(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeFixed32(arr[i]); }
function writePackedSFixed32(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed32(arr[i]); }
function writePackedFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeFixed64(arr[i]); }
function writePackedSFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed64(arr[i]); }
// Buffer code below from https://github.com/feross/buffer, MIT-licensed
function readUInt32(buf, pos) {
return ((buf[pos]) |
(buf[pos + 1] << 8) |
(buf[pos + 2] << 16)) +
(buf[pos + 3] * 0x1000000);
}
function writeInt32(buf, val, pos) {
buf[pos] = val;
buf[pos + 1] = (val >>> 8);
buf[pos + 2] = (val >>> 16);
buf[pos + 3] = (val >>> 24);
}
function readInt32(buf, pos) {
return ((buf[pos]) |
(buf[pos + 1] << 8) |
(buf[pos + 2] << 16)) +
(buf[pos + 3] << 24);
}
function readUtf8(buf, pos, end) {
var str = '';
var i = pos;
while (i < end) {
var b0 = buf[i];
var c = null; // codepoint
var bytesPerSequence =
b0 > 0xEF ? 4 :
b0 > 0xDF ? 3 :
b0 > 0xBF ? 2 : 1;
if (i + bytesPerSequence > end) break;
var b1, b2, b3;
if (bytesPerSequence === 1) {
if (b0 < 0x80) {
c = b0;
}
} else if (bytesPerSequence === 2) {
b1 = buf[i + 1];
if ((b1 & 0xC0) === 0x80) {
c = (b0 & 0x1F) << 0x6 | (b1 & 0x3F);
if (c <= 0x7F) {
c = null;
}
}
} else if (bytesPerSequence === 3) {
b1 = buf[i + 1];
b2 = buf[i + 2];
if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80) {
c = (b0 & 0xF) << 0xC | (b1 & 0x3F) << 0x6 | (b2 & 0x3F);
if (c <= 0x7FF || (c >= 0xD800 && c <= 0xDFFF)) {
c = null;
}
}
} else if (bytesPerSequence === 4) {
b1 = buf[i + 1];
b2 = buf[i + 2];
b3 = buf[i + 3];
if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) {
c = (b0 & 0xF) << 0x12 | (b1 & 0x3F) << 0xC | (b2 & 0x3F) << 0x6 | (b3 & 0x3F);
if (c <= 0xFFFF || c >= 0x110000) {
c = null;
}
}
}
if (c === null) {
c = 0xFFFD;
bytesPerSequence = 1;
} else if (c > 0xFFFF) {
c -= 0x10000;
str += String.fromCharCode(c >>> 10 & 0x3FF | 0xD800);
c = 0xDC00 | c & 0x3FF;
}
str += String.fromCharCode(c);
i += bytesPerSequence;
}
return str;
}
function writeUtf8(buf, str, pos) {
for (var i = 0, c, lead; i < str.length; i++) {
c = str.charCodeAt(i); // code point
if (c > 0xD7FF && c < 0xE000) {
if (lead) {
if (c < 0xDC00) {
buf[pos++] = 0xEF;
buf[pos++] = 0xBF;
buf[pos++] = 0xBD;
lead = c;
continue;
} else {
c = lead - 0xD800 << 10 | c - 0xDC00 | 0x10000;
lead = null;
}
} else {
if (c > 0xDBFF || (i + 1 === str.length)) {
buf[pos++] = 0xEF;
buf[pos++] = 0xBF;
buf[pos++] = 0xBD;
} else {
lead = c;
}
continue;
}
} else if (lead) {
buf[pos++] = 0xEF;
buf[pos++] = 0xBF;
buf[pos++] = 0xBD;
lead = null;
}
if (c < 0x80) {
buf[pos++] = c;
} else {
if (c < 0x800) {
buf[pos++] = c >> 0x6 | 0xC0;
} else {
if (c < 0x10000) {
buf[pos++] = c >> 0xC | 0xE0;
} else {
buf[pos++] = c >> 0x12 | 0xF0;
buf[pos++] = c >> 0xC & 0x3F | 0x80;
}
buf[pos++] = c >> 0x6 & 0x3F | 0x80;
}
buf[pos++] = c & 0x3F | 0x80;
}
}
return pos;
}
},{"ieee754":6}],9:[function(require,module,exports){
//adapted from https://github.com/mapbox/mapbox-gl-js/blob/5886421ea9a5ae26797c950ec698be473fe87d17/src/style-spec/feature_filter/index.js
'use strict';
module.exports = createFilter;
var types = ['Unknown', 'Point', 'LineString', 'Polygon'];
/**
* Given a filter expressed as nested arrays, return a new function
* that evaluates whether a given feature (with a .properties or .tags property)
* passes its test.
*
* @private
* @param {Array} filter mapbox gl filter
* @returns {Function} filter-evaluating function
*/
function createFilter(filter) {
return new Function('f', ("var p = (f && f.properties || {}); return " + (compile(filter))));
}
function compile(filter) {
if (!filter) { return 'true'; }
var op = filter[0];
if (filter.length <= 1) { return op === 'any' ? 'false' : 'true'; }
var str =
op === '==' ? compileComparisonOp(filter[1], filter[2], '===', false) :
op === '!=' ? compileComparisonOp(filter[1], filter[2], '!==', false) :
op === '<' ||
op === '>' ||
op === '<=' ||
op === '>=' ? compileComparisonOp(filter[1], filter[2], op, true) :
op === '~=' ? compileRegexOp(filter[1], filter[2]) :
op === 'any' ? compileLogicalOp(filter.slice(1), '||') :
op === 'all' ? compileLogicalOp(filter.slice(1), '&&') :
op === 'none' ? compileNegation(compileLogicalOp(filter.slice(1), '||')) :
op === 'in' ? compileInOp(filter[1], filter.slice(2)) :
op === '!in' ? compileNegation(compileInOp(filter[1], filter.slice(2))) :
op === 'has' ? compileHasOp(filter[1]) :
op === '!has' ? compileNegation(compileHasOp(filter[1])) :
'true';
return ("(" + str + ")");
}
function compilePropertyReference(property) {
return property === '$type' ? 'f.type' :
property === '$id' ? 'f.id' :
("p[" + (JSON.stringify(property)) + "]");
}
function compileComparisonOp(property, value, op, checkType) {
var left = compilePropertyReference(property);
var right = property === '$type' ? types.indexOf(value) : JSON.stringify(value);
return (checkType ? ("typeof " + left + "=== typeof " + right + "&&") : '') + left + op + right;
}
function compileRegexOp(property, value) {
var left = compilePropertyReference(property);
var right = value;
return ("" + ('function(left, right) {' +
'if(!left) return false; return left.toString().match(right);' +
'}(') + left + ", " + right + ")");
}
function compileLogicalOp(expressions, op) {
return expressions.map(compile).join(op);
}
function compileInOp(property, values) {
if (property === '$type') { values = values.map(function (value) {
return types.indexOf(value);
}); }
var left = JSON.stringify(values.sort(compare));
var right = compilePropertyReference(property);
if (values.length <= 200) { return (left + ".indexOf(" + right + ") !== -1"); }
return ("" + ('function(v, a, i, j) {' +
'while (i <= j) { var m = (i + j) >> 1;' +
' if (a[m] === v) return true; if (a[m] > v) j = m - 1; else i = m + 1;' +
'}' +
'return false; }(') + right + ", " + left + ",0," + (values.length - 1) + ")");
}
function compileHasOp(property) {
return property === '$id' ? '"id" in f' : ((JSON.stringify(property)) + " in p");
}
function compileNegation(expression) {
return ("!(" + expression + ")");
}
// Comparison function to sort numbers and strings
function compare(a, b) {
return a < b ? -1 : a > b ? 1 : 0;
}
},{}],10:[function(require,module,exports){
'use strict';
var vt = require('@mapbox/vector-tile');
var Protobuf = require('pbf');
var GeoJSONFeature = require('mapbox-gl/src/util/vectortile_to_geojson');
var featureFilter = require('./feature_filter');
module.exports = {
querySourceFeatures: function querySourceFeatures(sourceID, params, map) {
var this$1 = this;
var sourceCache = map.style.sourceCaches[sourceID];
//from: https://github.com/mapbox/mapbox-gl-js/blob/5886421ea9a5ae26797c950ec698be473fe87d17/src/source/query_features.js#L25
var tiles = sourceCache.getRenderableIds().map(function (id) {
return sourceCache.getTileByID(id);
});
var result = [];
var dataTiles = {};
for (var i = 0; i < tiles.length; i++) {
var tile = tiles[i];
var dataID = tile.tileID.canonical.key;
if (!dataTiles[dataID]) {
dataTiles[dataID] = true;
this$1.queryTile(result, params, tile);
}
}
return result;
},
queryTile: function queryTile(result, params, tile) {
//from: https://github.com/mapbox/mapbox-gl-js/blob/5886421ea9a5ae26797c950ec698be473fe87d17/src/source/tile.js#L175
if (!tile.rawTileData) { return; }
if (!tile.vtLayers) {
tile.vtLayers = new vt.VectorTile(new Protobuf(tile.rawTileData)).layers;
}
var sourceLayer = params ? params.sourceLayer : '';
var layer = tile.vtLayers._geojsonTileLayer || tile.vtLayers[sourceLayer];
if (!layer) { return; }
var filter = featureFilter(params && params.filter);
var coord = { z: tile.tileID.overscaledZ, x: tile.tileID.canonical.x, y: tile.tileID.canonical.y };
for (var i = 0; i < layer.length; i++) {
var feature = layer.feature(i);
if (filter(feature)) {
var geojsonFeature = new GeoJSONFeature(feature, coord.z, coord.x, coord.y);
geojsonFeature.tile = coord;
result.push(geojsonFeature);
}
}
}
};
},{"./feature_filter":9,"@mapbox/vector-tile":2,"mapbox-gl/src/util/vectortile_to_geojson":7,"pbf":8}]},{},[10])(10)
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvQG1hcGJveC9wb2ludC1nZW9tZXRyeS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AbWFwYm94L3ZlY3Rvci10aWxlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BtYXBib3gvdmVjdG9yLXRpbGUvbGliL3ZlY3RvcnRpbGUuanMiLCJub2RlX21vZHVsZXMvQG1hcGJveC92ZWN0b3ItdGlsZS9saWIvdmVjdG9ydGlsZWZlYXR1cmUuanMiLCJub2RlX21vZHVsZXMvQG1hcGJveC92ZWN0b3ItdGlsZS9saWIvdmVjdG9ydGlsZWxheWVyLmpzIiwibm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCIvVXNlcnMva3Jpcy9kZXYvbWFwaHVicy9tYXBib3gtZ2wtcmVnZXgtcXVlcnkvbm9kZV9tb2R1bGVzL21hcGJveC1nbC9zcmMvdXRpbC92ZWN0b3J0aWxlX3RvX2dlb2pzb24uanMiLCJub2RlX21vZHVsZXMvcGJmL2luZGV4LmpzIiwiL1VzZXJzL2tyaXMvZGV2L21hcGh1YnMvbWFwYm94LWdsLXJlZ2V4LXF1ZXJ5L3NyYy9mZWF0dXJlX2ZpbHRlci5qcyIsIi9Vc2Vycy9rcmlzL2Rldi9tYXBodWJzL21hcGJveC1nbC1yZWdleC1xdWVyeS9zcmMvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4VEE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDek9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFtQkE7O0FBRUEsWUFBWSxDQUFDOztBQUViLE1BQU0sQ0FBQyxPQUFPLEdBQUcsWUFBWSxDQUFDOztBQUU5QixHQUFLLENBQUMsS0FBSyxHQUFH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QUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlFLGNBQWMsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO2dCQUM1QixNQUFNLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO2FBQy9CO1NBQ0o7S0FDSjs7Q0FFSixDQUFDIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBQb2ludDtcblxuLyoqXG4gKiBBIHN0YW5kYWxvbmUgcG9pbnQgZ2VvbWV0cnkgd2l0aCB1c2VmdWwgYWNjZXNzb3IsIGNvbXBhcmlzb24sIGFuZFxuICogbW9kaWZpY2F0aW9uIG1ldGhvZHMuXG4gKlxuICogQGNsYXNzIFBvaW50XG4gKiBAcGFyYW0ge051bWJlcn0geCB0aGUgeC1jb29yZGluYXRlLiB0aGlzIGNvdWxkIGJlIGxvbmdpdHVkZSBvciBzY3JlZW5cbiAqIHBpeGVscywgb3IgYW55IG90aGVyIHNvcnQgb2YgdW5pdC5cbiAqIEBwYXJhbSB7TnVtYmVyfSB5IHRoZSB5LWNvb3JkaW5hdGUuIHRoaXMgY291bGQgYmUgbGF0aXR1ZGUgb3Igc2NyZWVuXG4gKiBwaXhlbHMsIG9yIGFueSBvdGhlciBzb3J0IG9mIHVuaXQuXG4gKiBAZXhhbXBsZVxuICogdmFyIHBvaW50ID0gbmV3IFBvaW50KC03NywgMzgpO1xuICovXG5mdW5jdGlvbiBQb2ludCh4LCB5KSB7XG4gICAgdGhpcy54ID0geDtcbiAgICB0aGlzLnkgPSB5O1xufVxuXG5Qb2ludC5wcm90b3R5cGUgPSB7XG5cbiAgICAvKipcbiAgICAgKiBDbG9uZSB0aGlzIHBvaW50LCByZXR1cm5pbmcgYSBuZXcgcG9pbnQgdGhhdCBjYW4gYmUgbW9kaWZpZWRcbiAgICAgKiB3aXRob3V0IGFmZmVjdGluZyB0aGUgb2xkIG9uZS5cbiAgICAgKiBAcmV0dXJuIHtQb2ludH0gdGhlIGNsb25lXG4gICAgICovXG4gICAgY2xvbmU6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbmV3IFBvaW50KHRoaXMueCwgdGhpcy55KTsgfSxcblxuICAgIC8qKlxuICAgICAqIEFkZCB0aGlzIHBvaW50J3MgeCAmIHkgY29vcmRpbmF0ZXMgdG8gYW5vdGhlciBwb2ludCxcbiAgICAgKiB5aWVsZGluZyBhIG5ldyBwb2ludC5cbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwIHRoZSBvdGhlciBwb2ludFxuICAgICAqIEByZXR1cm4ge1BvaW50fSBvdXRwdXQgcG9pbnRcbiAgICAgKi9cbiAgICBhZGQ6ICAgICBmdW5jdGlvbihwKSB7IHJldHVybiB0aGlzLmNsb25lKCkuX2FkZChwKTsgfSxcblxuICAgIC8qKlxuICAgICAqIFN1YnRyYWN0IHRoaXMgcG9pbnQncyB4ICYgeSBjb29yZGluYXRlcyB0byBmcm9tIHBvaW50LFxuICAgICAqIHlpZWxkaW5nIGEgbmV3IHBvaW50LlxuICAgICAqIEBwYXJhbSB7UG9pbnR9IHAgdGhlIG90aGVyIHBvaW50XG4gICAgICogQHJldHVybiB7UG9pbnR9IG91dHB1dCBwb2ludFxuICAgICAqL1xuICAgIHN1YjogICAgIGZ1bmN0aW9uKHApIHsgcmV0dXJuIHRoaXMuY2xvbmUoKS5fc3ViKHApOyB9LFxuXG4gICAgLyoqXG4gICAgICogTXVsdGlwbHkgdGhpcyBwb2ludCdzIHggJiB5IGNvb3JkaW5hdGVzIGJ5IHBvaW50LFxuICAgICAqIHlpZWxkaW5nIGEgbmV3IHBvaW50LlxuICAgICAqIEBwYXJhbSB7UG9pbnR9IHAgdGhlIG90aGVyIHBvaW50XG4gICAgICogQHJldHVybiB7UG9pbnR9IG91dHB1dCBwb2ludFxuICAgICAqL1xuICAgIG11bHRCeVBvaW50OiAgICBmdW5jdGlvbihwKSB7IHJldHVybiB0aGlzLmNsb25lKCkuX211bHRCeVBvaW50KHApOyB9LFxuXG4gICAgLyoqXG4gICAgICogRGl2aWRlIHRoaXMgcG9pbnQncyB4ICYgeSBjb29yZGluYXRlcyBieSBwb2ludCxcbiAgICAgKiB5aWVsZGluZyBhIG5ldyBwb2ludC5cbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwIHRoZSBvdGhlciBwb2ludFxuICAgICAqIEByZXR1cm4ge1BvaW50fSBvdXRwdXQgcG9pbnRcbiAgICAgKi9cbiAgICBkaXZCeVBvaW50OiAgICAgZnVuY3Rpb24ocCkgeyByZXR1cm4gdGhpcy5jbG9uZSgpLl9kaXZCeVBvaW50KHApOyB9LFxuXG4gICAgLyoqXG4gICAgICogTXVsdGlwbHkgdGhpcyBwb2ludCdzIHggJiB5IGNvb3JkaW5hdGVzIGJ5IGEgZmFjdG9yLFxuICAgICAqIHlpZWxkaW5nIGEgbmV3IHBvaW50LlxuICAgICAqIEBwYXJhbSB7UG9pbnR9IGsgZmFjdG9yXG4gICAgICogQHJldHVybiB7UG9pbnR9IG91dHB1dCBwb2ludFxuICAgICAqL1xuICAgIG11bHQ6ICAgIGZ1bmN0aW9uKGspIHsgcmV0dXJuIHRoaXMuY2xvbmUoKS5fbXVsdChrKTsgfSxcblxuICAgIC8qKlxuICAgICAqIERpdmlkZSB0aGlzIHBvaW50J3MgeCAmIHkgY29vcmRpbmF0ZXMgYnkgYSBmYWN0b3IsXG4gICAgICogeWllbGRpbmcgYSBuZXcgcG9pbnQuXG4gICAgICogQHBhcmFtIHtQb2ludH0gayBmYWN0b3JcbiAgICAgKiBAcmV0dXJuIHtQb2ludH0gb3V0cHV0IHBvaW50XG4gICAgICovXG4gICAgZGl2OiAgICAgZnVuY3Rpb24oaykgeyByZXR1cm4gdGhpcy5jbG9uZSgpLl9kaXYoayk7IH0sXG5cbiAgICAvKipcbiAgICAgKiBSb3RhdGUgdGhpcyBwb2ludCBhcm91bmQgdGhlIDAsIDAgb3JpZ2luIGJ5IGFuIGFuZ2xlIGEsXG4gICAgICogZ2l2ZW4gaW4gcmFkaWFuc1xuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIGFuZ2xlIHRvIHJvdGF0ZSBhcm91bmQsIGluIHJhZGlhbnNcbiAgICAgKiBAcmV0dXJuIHtQb2ludH0gb3V0cHV0IHBvaW50XG4gICAgICovXG4gICAgcm90YXRlOiAgZnVuY3Rpb24oYSkgeyByZXR1cm4gdGhpcy5jbG9uZSgpLl9yb3RhdGUoYSk7IH0sXG5cbiAgICAvKipcbiAgICAgKiBSb3RhdGUgdGhpcyBwb2ludCBhcm91bmQgcCBwb2ludCBieSBhbiBhbmdsZSBhLFxuICAgICAqIGdpdmVuIGluIHJhZGlhbnNcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYSBhbmdsZSB0byByb3RhdGUgYXJvdW5kLCBpbiByYWRpYW5zXG4gICAgICogQHBhcmFtIHtQb2ludH0gcCBQb2ludCB0byByb3RhdGUgYXJvdW5kXG4gICAgICogQHJldHVybiB7UG9pbnR9IG91dHB1dCBwb2ludFxuICAgICAqL1xuICAgIHJvdGF0ZUFyb3VuZDogIGZ1bmN0aW9uKGEscCkgeyByZXR1cm4gdGhpcy5jbG9uZSgpLl9yb3RhdGVBcm91bmQoYSxwKTsgfSxcblxuICAgIC8qKlxuICAgICAqIE11bHRpcGx5IHRoaXMgcG9pbnQgYnkgYSA0eDEgdHJhbnNmb3JtYXRpb24gbWF0cml4XG4gICAgICogQHBhcmFtIHtBcnJheTxOdW1iZXI+fSBtIHRyYW5zZm9ybWF0aW9uIG1hdHJpeFxuICAgICAqIEByZXR1cm4ge1BvaW50fSBvdXRwdXQgcG9pbnRcbiAgICAgKi9cbiAgICBtYXRNdWx0OiBmdW5jdGlvbihtKSB7IHJldHVybiB0aGlzLmNsb25lKCkuX21hdE11bHQobSk7IH0sXG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgdGhpcyBwb2ludCBidXQgYXMgYSB1bml0IHZlY3RvciBmcm9tIDAsIDAsIG1lYW5pbmdcbiAgICAgKiB0aGF0IHRoZSBkaXN0YW5jZSBmcm9tIHRoZSByZXN1bHRpbmcgcG9pbnQgdG8gdGhlIDAsIDBcbiAgICAgKiBjb29yZGluYXRlIHdpbGwgYmUgZXF1YWwgdG8gMSBhbmQgdGhlIGFuZ2xlIGZyb20gdGhlIHJlc3VsdGluZ1xuICAgICAqIHBvaW50IHRvIHRoZSAwLCAwIGNvb3JkaW5hdGUgd2lsbCBiZSB0aGUgc2FtZSBhcyBiZWZvcmUuXG4gICAgICogQHJldHVybiB7UG9pbnR9IHVuaXQgdmVjdG9yIHBvaW50XG4gICAgICovXG4gICAgdW5pdDogICAgZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLmNsb25lKCkuX3VuaXQoKTsgfSxcblxuICAgIC8qKlxuICAgICAqIENvbXB1dGUgYSBwZXJwZW5kaWN1bGFyIHBvaW50LCB3aGVyZSB0aGUgbmV3IHkgY29vcmRpbmF0ZVxuICAgICAqIGlzIHRoZSBvbGQgeCBjb29yZGluYXRlIGFuZCB0aGUgbmV3IHggY29vcmRpbmF0ZSBpcyB0aGUgb2xkIHlcbiAgICAgKiBjb29yZGluYXRlIG11bHRpcGxpZWQgYnkgLTFcbiAgICAgKiBAcmV0dXJuIHtQb2ludH0gcGVycGVuZGljdWxhciBwb2ludFxuICAgICAqL1xuICAgIHBlcnA6ICAgIGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5jbG9uZSgpLl9wZXJwKCk7IH0sXG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gYSB2ZXJzaW9uIG9mIHRoaXMgcG9pbnQgd2l0aCB0aGUgeCAmIHkgY29vcmRpbmF0ZXNcbiAgICAgKiByb3VuZGVkIHRvIGludGVnZXJzLlxuICAgICAqIEByZXR1cm4ge1BvaW50fSByb3VuZGVkIHBvaW50XG4gICAgICovXG4gICAgcm91bmQ6ICAgZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLmNsb25lKCkuX3JvdW5kKCk7IH0sXG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIG1hZ2l0dWRlIG9mIHRoaXMgcG9pbnQ6IHRoaXMgaXMgdGhlIEV1Y2xpZGVhblxuICAgICAqIGRpc3RhbmNlIGZyb20gdGhlIDAsIDAgY29vcmRpbmF0ZSB0byB0aGlzIHBvaW50J3MgeCBhbmQgeVxuICAgICAqIGNvb3JkaW5hdGVzLlxuICAgICAqIEByZXR1cm4ge051bWJlcn0gbWFnbml0dWRlXG4gICAgICovXG4gICAgbWFnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguc3FydCh0aGlzLnggKiB0aGlzLnggKyB0aGlzLnkgKiB0aGlzLnkpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBKdWRnZSB3aGV0aGVyIHRoaXMgcG9pbnQgaXMgZXF1YWwgdG8gYW5vdGhlciBwb2ludCwgcmV0dXJuaW5nXG4gICAgICogdHJ1ZSBvciBmYWxzZS5cbiAgICAgKiBAcGFyYW0ge1BvaW50fSBvdGhlciB0aGUgb3RoZXIgcG9pbnRcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSB3aGV0aGVyIHRoZSBwb2ludHMgYXJlIGVxdWFsXG4gICAgICovXG4gICAgZXF1YWxzOiBmdW5jdGlvbihvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy54ID09PSBvdGhlci54ICYmXG4gICAgICAgICAgICAgICB0aGlzLnkgPT09IG90aGVyLnk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZSB0aGUgZGlzdGFuY2UgZnJvbSB0aGlzIHBvaW50IHRvIGFub3RoZXIgcG9pbnRcbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwIHRoZSBvdGhlciBwb2ludFxuICAgICAqIEByZXR1cm4ge051bWJlcn0gZGlzdGFuY2VcbiAgICAgKi9cbiAgICBkaXN0OiBmdW5jdGlvbihwKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0U3FyKHApKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlIHRoZSBkaXN0YW5jZSBmcm9tIHRoaXMgcG9pbnQgdG8gYW5vdGhlciBwb2ludCxcbiAgICAgKiB3aXRob3V0IHRoZSBzcXVhcmUgcm9vdCBzdGVwLiBVc2VmdWwgaWYgeW91J3JlIGNvbXBhcmluZ1xuICAgICAqIHJlbGF0aXZlIGRpc3RhbmNlcy5cbiAgICAgKiBAcGFyYW0ge1BvaW50fSBwIHRoZSBvdGhlciBwb2ludFxuICAgICAqIEByZXR1cm4ge051bWJlcn0gZGlzdGFuY2VcbiAgICAgKi9cbiAgICBkaXN0U3FyOiBmdW5jdGlvbihwKSB7XG4gICAgICAgIHZhciBkeCA9IHAueCAtIHRoaXMueCxcbiAgICAgICAgICAgIGR5ID0gcC55IC0gdGhpcy55O1xuICAgICAgICByZXR1cm4gZHggKiBkeCArIGR5ICogZHk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYW5nbGUgZnJvbSB0aGUgMCwgMCBjb29yZGluYXRlIHRvIHRoaXMgcG9pbnQsIGluIHJhZGlhbnNcbiAgICAgKiBjb29yZGluYXRlcy5cbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IGFuZ2xlXG4gICAgICovXG4gICAgYW5nbGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gTWF0aC5hdGFuMih0aGlzLnksIHRoaXMueCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYW5nbGUgZnJvbSB0aGlzIHBvaW50IHRvIGFub3RoZXIgcG9pbnQsIGluIHJhZGlhbnNcbiAgICAgKiBAcGFyYW0ge1BvaW50fSBiIHRoZSBvdGhlciBwb2ludFxuICAgICAqIEByZXR1cm4ge051bWJlcn0gYW5nbGVcbiAgICAgKi9cbiAgICBhbmdsZVRvOiBmdW5jdGlvbihiKSB7XG4gICAgICAgIHJldHVybiBNYXRoLmF0YW4yKHRoaXMueSAtIGIueSwgdGhpcy54IC0gYi54KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBhbmdsZSBiZXR3ZWVuIHRoaXMgcG9pbnQgYW5kIGFub3RoZXIgcG9pbnQsIGluIHJhZGlhbnNcbiAgICAgKiBAcGFyYW0ge1BvaW50fSBiIHRoZSBvdGhlciBwb2ludFxuICAgICAqIEByZXR1cm4ge051bWJlcn0gYW5nbGVcbiAgICAgKi9cbiAgICBhbmdsZVdpdGg6IGZ1bmN0aW9uKGIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYW5nbGVXaXRoU2VwKGIueCwgYi55KTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBGaW5kIHRoZSBhbmdsZSBvZiB0aGUgdHdvIHZlY3RvcnMsIHNvbHZpbmcgdGhlIGZvcm11bGEgZm9yXG4gICAgICogdGhlIGNyb3NzIHByb2R1Y3QgYSB4IGIgPSB8YXx8YnxzaW4ozrgpIGZvciDOuC5cbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCB0aGUgeC1jb29yZGluYXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgdGhlIHktY29vcmRpbmF0ZVxuICAgICAqIEByZXR1cm4ge051bWJlcn0gdGhlIGFuZ2xlIGluIHJhZGlhbnNcbiAgICAgKi9cbiAgICBhbmdsZVdpdGhTZXA6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguYXRhbjIoXG4gICAgICAgICAgICB0aGlzLnggKiB5IC0gdGhpcy55ICogeCxcbiAgICAgICAgICAgIHRoaXMueCAqIHggKyB0aGlzLnkgKiB5KTtcbiAgICB9LFxuXG4gICAgX21hdE11bHQ6IGZ1bmN0aW9uKG0pIHtcbiAgICAgICAgdmFyIHggPSBtWzBdICogdGhpcy54ICsgbVsxXSAqIHRoaXMueSxcbiAgICAgICAgICAgIHkgPSBtWzJdICogdGhpcy54ICsgbVszXSAqIHRoaXMueTtcbiAgICAgICAgdGhpcy54ID0geDtcbiAgICAgICAgdGhpcy55ID0geTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIF9hZGQ6IGZ1bmN0aW9uKHApIHtcbiAgICAgICAgdGhpcy54ICs9IHAueDtcbiAgICAgICAgdGhpcy55ICs9IHAueTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIF9zdWI6IGZ1bmN0aW9uKHApIHtcbiAgICAgICAgdGhpcy54IC09IHAueDtcbiAgICAgICAgdGhpcy55IC09IHAueTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIF9tdWx0OiBmdW5jdGlvbihrKSB7XG4gICAgICAgIHRoaXMueCAqPSBrO1xuICAgICAgICB0aGlzLnkgKj0gaztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIF9kaXY6IGZ1bmN0aW9uKGspIHtcbiAgICAgICAgdGhpcy54IC89IGs7XG4gICAgICAgIHRoaXMueSAvPSBrO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgX211bHRCeVBvaW50OiBmdW5jdGlvbihwKSB7XG4gICAgICAgIHRoaXMueCAqPSBwLng7XG4gICAgICAgIHRoaXMueSAqPSBwLnk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBfZGl2QnlQb2ludDogZnVuY3Rpb24ocCkge1xuICAgICAgICB0aGlzLnggLz0gcC54O1xuICAgICAgICB0aGlzLnkgLz0gcC55O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgX3VuaXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLl9kaXYodGhpcy5tYWcoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBfcGVycDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB5ID0gdGhpcy55O1xuICAgICAgICB0aGlzLnkgPSB0aGlzLng7XG4gICAgICAgIHRoaXMueCA9IC15O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgX3JvdGF0ZTogZnVuY3Rpb24oYW5nbGUpIHtcbiAgICAgICAgdmFyIGNvcyA9IE1hdGguY29zKGFuZ2xlKSxcbiAgICAgICAgICAgIHNpbiA9IE1hdGguc2luKGFuZ2xlKSxcbiAgICAgICAgICAgIHggPSBjb3MgKiB0aGlzLnggLSBzaW4gKiB0aGlzLnksXG4gICAgICAgICAgICB5ID0gc2luICogdGhpcy54ICsgY29zICogdGhpcy55O1xuICAgICAgICB0aGlzLnggPSB4O1xuICAgICAgICB0aGlzLnkgPSB5O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgX3JvdGF0ZUFyb3VuZDogZnVuY3Rpb24oYW5nbGUsIHApIHtcbiAgICAgICAgdmFyIGNvcyA9IE1hdGguY29zKGFuZ2xlKSxcbiAgICAgICAgICAgIHNpbiA9IE1hdGguc2luKGFuZ2xlKSxcbiAgICAgICAgICAgIHggPSBwLnggKyBjb3MgKiAodGhpcy54IC0gcC54KSAtIHNpbiAqICh0aGlzLnkgLSBwLnkpLFxuICAgICAgICAgICAgeSA9IHAueSArIHNpbiAqICh0aGlzLnggLSBwLngpICsgY29zICogKHRoaXMueSAtIHAueSk7XG4gICAgICAgIHRoaXMueCA9IHg7XG4gICAgICAgIHRoaXMueSA9IHk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBfcm91bmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnggPSBNYXRoLnJvdW5kKHRoaXMueCk7XG4gICAgICAgIHRoaXMueSA9IE1hdGgucm91bmQodGhpcy55KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3QgYSBwb2ludCBmcm9tIGFuIGFycmF5IGlmIG5lY2Vzc2FyeSwgb3RoZXJ3aXNlIGlmIHRoZSBpbnB1dFxuICogaXMgYWxyZWFkeSBhIFBvaW50LCBvciBhbiB1bmtub3duIHR5cGUsIHJldHVybiBpdCB1bmNoYW5nZWRcbiAqIEBwYXJhbSB7QXJyYXk8TnVtYmVyPnxQb2ludHwqfSBhIGFueSBraW5kIG9mIGlucHV0IHZhbHVlXG4gKiBAcmV0dXJuIHtQb2ludH0gY29uc3RydWN0ZWQgcG9pbnQsIG9yIHBhc3NlZC10aHJvdWdoIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqIC8vIHRoaXNcbiAqIHZhciBwb2ludCA9IFBvaW50LmNvbnZlcnQoWzAsIDFdKTtcbiAqIC8vIGlzIGVxdWl2YWxlbnQgdG9cbiAqIHZhciBwb2ludCA9IG5ldyBQb2ludCgwLCAxKTtcbiAqL1xuUG9pbnQuY29udmVydCA9IGZ1bmN0aW9uIChhKSB7XG4gICAgaWYgKGEgaW5zdGFuY2VvZiBQb2ludCkge1xuICAgICAgICByZXR1cm4gYTtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYSkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQb2ludChhWzBdLCBhWzFdKTtcbiAgICB9XG4gICAgcmV0dXJuIGE7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMuVmVjdG9yVGlsZSA9IHJlcXVpcmUoJy4vbGliL3ZlY3RvcnRpbGUuanMnKTtcbm1vZHVsZS5leHBvcnRzLlZlY3RvclRpbGVGZWF0dXJlID0gcmVxdWlyZSgnLi9saWIvdmVjdG9ydGlsZWZlYXR1cmUuanMnKTtcbm1vZHVsZS5leHBvcnRzLlZlY3RvclRpbGVMYXllciA9IHJlcXVpcmUoJy4vbGliL3ZlY3RvcnRpbGVsYXllci5qcycpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVmVjdG9yVGlsZUxheWVyID0gcmVxdWlyZSgnLi92ZWN0b3J0aWxlbGF5ZXInKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWZWN0b3JUaWxlO1xuXG5mdW5jdGlvbiBWZWN0b3JUaWxlKHBiZiwgZW5kKSB7XG4gICAgdGhpcy5sYXllcnMgPSBwYmYucmVhZEZpZWxkcyhyZWFkVGlsZSwge30sIGVuZCk7XG59XG5cbmZ1bmN0aW9uIHJlYWRUaWxlKHRhZywgbGF5ZXJzLCBwYmYpIHtcbiAgICBpZiAodGFnID09PSAzKSB7XG4gICAgICAgIHZhciBsYXllciA9IG5ldyBWZWN0b3JUaWxlTGF5ZXIocGJmLCBwYmYucmVhZFZhcmludCgpICsgcGJmLnBvcyk7XG4gICAgICAgIGlmIChsYXllci5sZW5ndGgpIGxheWVyc1tsYXllci5uYW1lXSA9IGxheWVyO1xuICAgIH1cbn1cblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgUG9pbnQgPSByZXF1aXJlKCdAbWFwYm94L3BvaW50LWdlb21ldHJ5Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gVmVjdG9yVGlsZUZlYXR1cmU7XG5cbmZ1bmN0aW9uIFZlY3RvclRpbGVGZWF0dXJlKHBiZiwgZW5kLCBleHRlbnQsIGtleXMsIHZhbHVlcykge1xuICAgIC8vIFB1YmxpY1xuICAgIHRoaXMucHJvcGVydGllcyA9IHt9O1xuICAgIHRoaXMuZXh0ZW50ID0gZXh0ZW50O1xuICAgIHRoaXMudHlwZSA9IDA7XG5cbiAgICAvLyBQcml2YXRlXG4gICAgdGhpcy5fcGJmID0gcGJmO1xuICAgIHRoaXMuX2dlb21ldHJ5ID0gLTE7XG4gICAgdGhpcy5fa2V5cyA9IGtleXM7XG4gICAgdGhpcy5fdmFsdWVzID0gdmFsdWVzO1xuXG4gICAgcGJmLnJlYWRGaWVsZHMocmVhZEZlYXR1cmUsIHRoaXMsIGVuZCk7XG59XG5cbmZ1bmN0aW9uIHJlYWRGZWF0dXJlKHRhZywgZmVhdHVyZSwgcGJmKSB7XG4gICAgaWYgKHRhZyA9PSAxKSBmZWF0dXJlLmlkID0gcGJmLnJlYWRWYXJpbnQoKTtcbiAgICBlbHNlIGlmICh0YWcgPT0gMikgcmVhZFRhZyhwYmYsIGZlYXR1cmUpO1xuICAgIGVsc2UgaWYgKHRhZyA9PSAzKSBmZWF0dXJlLnR5cGUgPSBwYmYucmVhZFZhcmludCgpO1xuICAgIGVsc2UgaWYgKHRhZyA9PSA0KSBmZWF0dXJlLl9nZW9tZXRyeSA9IHBiZi5wb3M7XG59XG5cbmZ1bmN0aW9uIHJlYWRUYWcocGJmLCBmZWF0dXJlKSB7XG4gICAgdmFyIGVuZCA9IHBiZi5yZWFkVmFyaW50KCkgKyBwYmYucG9zO1xuXG4gICAgd2hpbGUgKHBiZi5wb3MgPCBlbmQpIHtcbiAgICAgICAgdmFyIGtleSA9IGZlYXR1cmUuX2tleXNbcGJmLnJlYWRWYXJpbnQoKV0sXG4gICAgICAgICAgICB2YWx1ZSA9IGZlYXR1cmUuX3ZhbHVlc1twYmYucmVhZFZhcmludCgpXTtcbiAgICAgICAgZmVhdHVyZS5wcm9wZXJ0aWVzW2tleV0gPSB2YWx1ZTtcbiAgICB9XG59XG5cblZlY3RvclRpbGVGZWF0dXJlLnR5cGVzID0gWydVbmtub3duJywgJ1BvaW50JywgJ0xpbmVTdHJpbmcnLCAnUG9seWdvbiddO1xuXG5WZWN0b3JUaWxlRmVhdHVyZS5wcm90b3R5cGUubG9hZEdlb21ldHJ5ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHBiZiA9IHRoaXMuX3BiZjtcbiAgICBwYmYucG9zID0gdGhpcy5fZ2VvbWV0cnk7XG5cbiAgICB2YXIgZW5kID0gcGJmLnJlYWRWYXJpbnQoKSArIHBiZi5wb3MsXG4gICAgICAgIGNtZCA9IDEsXG4gICAgICAgIGxlbmd0aCA9IDAsXG4gICAgICAgIHggPSAwLFxuICAgICAgICB5ID0gMCxcbiAgICAgICAgbGluZXMgPSBbXSxcbiAgICAgICAgbGluZTtcblxuICAgIHdoaWxlIChwYmYucG9zIDwgZW5kKSB7XG4gICAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgY21kTGVuID0gcGJmLnJlYWRWYXJpbnQoKTtcbiAgICAgICAgICAgIGNtZCA9IGNtZExlbiAmIDB4NztcbiAgICAgICAgICAgIGxlbmd0aCA9IGNtZExlbiA+PiAzO1xuICAgICAgICB9XG5cbiAgICAgICAgbGVuZ3RoLS07XG5cbiAgICAgICAgaWYgKGNtZCA9PT0gMSB8fCBjbWQgPT09IDIpIHtcbiAgICAgICAgICAgIHggKz0gcGJmLnJlYWRTVmFyaW50KCk7XG4gICAgICAgICAgICB5ICs9IHBiZi5yZWFkU1ZhcmludCgpO1xuXG4gICAgICAgICAgICBpZiAoY21kID09PSAxKSB7IC8vIG1vdmVUb1xuICAgICAgICAgICAgICAgIGlmIChsaW5lKSBsaW5lcy5wdXNoKGxpbmUpO1xuICAgICAgICAgICAgICAgIGxpbmUgPSBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGluZS5wdXNoKG5ldyBQb2ludCh4LCB5KSk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjbWQgPT09IDcpIHtcblxuICAgICAgICAgICAgLy8gV29ya2Fyb3VuZCBmb3IgaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBuaWstdmVjdG9yLXRpbGUvaXNzdWVzLzkwXG4gICAgICAgICAgICBpZiAobGluZSkge1xuICAgICAgICAgICAgICAgIGxpbmUucHVzaChsaW5lWzBdLmNsb25lKCkpOyAvLyBjbG9zZVBvbHlnb25cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGNvbW1hbmQgJyArIGNtZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobGluZSkgbGluZXMucHVzaChsaW5lKTtcblxuICAgIHJldHVybiBsaW5lcztcbn07XG5cblZlY3RvclRpbGVGZWF0dXJlLnByb3RvdHlwZS5iYm94ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHBiZiA9IHRoaXMuX3BiZjtcbiAgICBwYmYucG9zID0gdGhpcy5fZ2VvbWV0cnk7XG5cbiAgICB2YXIgZW5kID0gcGJmLnJlYWRWYXJpbnQoKSArIHBiZi5wb3MsXG4gICAgICAgIGNtZCA9IDEsXG4gICAgICAgIGxlbmd0aCA9IDAsXG4gICAgICAgIHggPSAwLFxuICAgICAgICB5ID0gMCxcbiAgICAgICAgeDEgPSBJbmZpbml0eSxcbiAgICAgICAgeDIgPSAtSW5maW5pdHksXG4gICAgICAgIHkxID0gSW5maW5pdHksXG4gICAgICAgIHkyID0gLUluZmluaXR5O1xuXG4gICAgd2hpbGUgKHBiZi5wb3MgPCBlbmQpIHtcbiAgICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgICAgIHZhciBjbWRMZW4gPSBwYmYucmVhZFZhcmludCgpO1xuICAgICAgICAgICAgY21kID0gY21kTGVuICYgMHg3O1xuICAgICAgICAgICAgbGVuZ3RoID0gY21kTGVuID4+IDM7XG4gICAgICAgIH1cblxuICAgICAgICBsZW5ndGgtLTtcblxuICAgICAgICBpZiAoY21kID09PSAxIHx8IGNtZCA9PT0gMikge1xuICAgICAgICAgICAgeCArPSBwYmYucmVhZFNWYXJpbnQoKTtcbiAgICAgICAgICAgIHkgKz0gcGJmLnJlYWRTVmFyaW50KCk7XG4gICAgICAgICAgICBpZiAoeCA8IHgxKSB4MSA9IHg7XG4gICAgICAgICAgICBpZiAoeCA+IHgyKSB4MiA9IHg7XG4gICAgICAgICAgICBpZiAoeSA8IHkxKSB5MSA9IHk7XG4gICAgICAgICAgICBpZiAoeSA+IHkyKSB5MiA9IHk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjbWQgIT09IDcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBjb21tYW5kICcgKyBjbWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFt4MSwgeTEsIHgyLCB5Ml07XG59O1xuXG5WZWN0b3JUaWxlRmVhdHVyZS5wcm90b3R5cGUudG9HZW9KU09OID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICAgIHZhciBzaXplID0gdGhpcy5leHRlbnQgKiBNYXRoLnBvdygyLCB6KSxcbiAgICAgICAgeDAgPSB0aGlzLmV4dGVudCAqIHgsXG4gICAgICAgIHkwID0gdGhpcy5leHRlbnQgKiB5LFxuICAgICAgICBjb29yZHMgPSB0aGlzLmxvYWRHZW9tZXRyeSgpLFxuICAgICAgICB0eXBlID0gVmVjdG9yVGlsZUZlYXR1cmUudHlwZXNbdGhpcy50eXBlXSxcbiAgICAgICAgaSwgajtcblxuICAgIGZ1bmN0aW9uIHByb2plY3QobGluZSkge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxpbmUubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIHZhciBwID0gbGluZVtqXSwgeTIgPSAxODAgLSAocC55ICsgeTApICogMzYwIC8gc2l6ZTtcbiAgICAgICAgICAgIGxpbmVbal0gPSBbXG4gICAgICAgICAgICAgICAgKHAueCArIHgwKSAqIDM2MCAvIHNpemUgLSAxODAsXG4gICAgICAgICAgICAgICAgMzYwIC8gTWF0aC5QSSAqIE1hdGguYXRhbihNYXRoLmV4cCh5MiAqIE1hdGguUEkgLyAxODApKSAtIDkwXG4gICAgICAgICAgICBdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICBjYXNlIDE6XG4gICAgICAgIHZhciBwb2ludHMgPSBbXTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb3Jkcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgcG9pbnRzW2ldID0gY29vcmRzW2ldWzBdO1xuICAgICAgICB9XG4gICAgICAgIGNvb3JkcyA9IHBvaW50cztcbiAgICAgICAgcHJvamVjdChjb29yZHMpO1xuICAgICAgICBicmVhaztcblxuICAgIGNhc2UgMjpcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb3Jkcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgcHJvamVjdChjb29yZHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAzOlxuICAgICAgICBjb29yZHMgPSBjbGFzc2lmeVJpbmdzKGNvb3Jkcyk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb29yZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBjb29yZHNbaV0ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICBwcm9qZWN0KGNvb3Jkc1tpXVtqXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKGNvb3Jkcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgY29vcmRzID0gY29vcmRzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHR5cGUgPSAnTXVsdGknICsgdHlwZTtcbiAgICB9XG5cbiAgICB2YXIgcmVzdWx0ID0ge1xuICAgICAgICB0eXBlOiBcIkZlYXR1cmVcIixcbiAgICAgICAgZ2VvbWV0cnk6IHtcbiAgICAgICAgICAgIHR5cGU6IHR5cGUsXG4gICAgICAgICAgICBjb29yZGluYXRlczogY29vcmRzXG4gICAgICAgIH0sXG4gICAgICAgIHByb3BlcnRpZXM6IHRoaXMucHJvcGVydGllc1xuICAgIH07XG5cbiAgICBpZiAoJ2lkJyBpbiB0aGlzKSB7XG4gICAgICAgIHJlc3VsdC5pZCA9IHRoaXMuaWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8vIGNsYXNzaWZpZXMgYW4gYXJyYXkgb2YgcmluZ3MgaW50byBwb2x5Z29ucyB3aXRoIG91dGVyIHJpbmdzIGFuZCBob2xlc1xuXG5mdW5jdGlvbiBjbGFzc2lmeVJpbmdzKHJpbmdzKSB7XG4gICAgdmFyIGxlbiA9IHJpbmdzLmxlbmd0aDtcblxuICAgIGlmIChsZW4gPD0gMSkgcmV0dXJuIFtyaW5nc107XG5cbiAgICB2YXIgcG9seWdvbnMgPSBbXSxcbiAgICAgICAgcG9seWdvbixcbiAgICAgICAgY2N3O1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgYXJlYSA9IHNpZ25lZEFyZWEocmluZ3NbaV0pO1xuICAgICAgICBpZiAoYXJlYSA9PT0gMCkgY29udGludWU7XG5cbiAgICAgICAgaWYgKGNjdyA9PT0gdW5kZWZpbmVkKSBjY3cgPSBhcmVhIDwgMDtcblxuICAgICAgICBpZiAoY2N3ID09PSBhcmVhIDwgMCkge1xuICAgICAgICAgICAgaWYgKHBvbHlnb24pIHBvbHlnb25zLnB1c2gocG9seWdvbik7XG4gICAgICAgICAgICBwb2x5Z29uID0gW3JpbmdzW2ldXTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9seWdvbi5wdXNoKHJpbmdzW2ldKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAocG9seWdvbikgcG9seWdvbnMucHVzaChwb2x5Z29uKTtcblxuICAgIHJldHVybiBwb2x5Z29ucztcbn1cblxuZnVuY3Rpb24gc2lnbmVkQXJlYShyaW5nKSB7XG4gICAgdmFyIHN1bSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHJpbmcubGVuZ3RoLCBqID0gbGVuIC0gMSwgcDEsIHAyOyBpIDwgbGVuOyBqID0gaSsrKSB7XG4gICAgICAgIHAxID0gcmluZ1tpXTtcbiAgICAgICAgcDIgPSByaW5nW2pdO1xuICAgICAgICBzdW0gKz0gKHAyLnggLSBwMS54KSAqIChwMS55ICsgcDIueSk7XG4gICAgfVxuICAgIHJldHVybiBzdW07XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBWZWN0b3JUaWxlRmVhdHVyZSA9IHJlcXVpcmUoJy4vdmVjdG9ydGlsZWZlYXR1cmUuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBWZWN0b3JUaWxlTGF5ZXI7XG5cbmZ1bmN0aW9uIFZlY3RvclRpbGVMYXllcihwYmYsIGVuZCkge1xuICAgIC8vIFB1YmxpY1xuICAgIHRoaXMudmVyc2lvbiA9IDE7XG4gICAgdGhpcy5uYW1lID0gbnVsbDtcbiAgICB0aGlzLmV4dGVudCA9IDQwOTY7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuXG4gICAgLy8gUHJpdmF0ZVxuICAgIHRoaXMuX3BiZiA9IHBiZjtcbiAgICB0aGlzLl9rZXlzID0gW107XG4gICAgdGhpcy5fdmFsdWVzID0gW107XG4gICAgdGhpcy5fZmVhdHVyZXMgPSBbXTtcblxuICAgIHBiZi5yZWFkRmllbGRzKHJlYWRMYXllciwgdGhpcywgZW5kKTtcblxuICAgIHRoaXMubGVuZ3RoID0gdGhpcy5fZmVhdHVyZXMubGVuZ3RoO1xufVxuXG5mdW5jdGlvbiByZWFkTGF5ZXIodGFnLCBsYXllciwgcGJmKSB7XG4gICAgaWYgKHRhZyA9PT0gMTUpIGxheWVyLnZlcnNpb24gPSBwYmYucmVhZFZhcmludCgpO1xuICAgIGVsc2UgaWYgKHRhZyA9PT0gMSkgbGF5ZXIubmFtZSA9IHBiZi5yZWFkU3RyaW5nKCk7XG4gICAgZWxzZSBpZiAodGFnID09PSA1KSBsYXllci5leHRlbnQgPSBwYmYucmVhZFZhcmludCgpO1xuICAgIGVsc2UgaWYgKHRhZyA9PT0gMikgbGF5ZXIuX2ZlYXR1cmVzLnB1c2gocGJmLnBvcyk7XG4gICAgZWxzZSBpZiAodGFnID09PSAzKSBsYXllci5fa2V5cy5wdXNoKHBiZi5yZWFkU3RyaW5nKCkpO1xuICAgIGVsc2UgaWYgKHRhZyA9PT0gNCkgbGF5ZXIuX3ZhbHVlcy5wdXNoKHJlYWRWYWx1ZU1lc3NhZ2UocGJmKSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRWYWx1ZU1lc3NhZ2UocGJmKSB7XG4gICAgdmFyIHZhbHVlID0gbnVsbCxcbiAgICAgICAgZW5kID0gcGJmLnJlYWRWYXJpbnQoKSArIHBiZi5wb3M7XG5cbiAgICB3aGlsZSAocGJmLnBvcyA8IGVuZCkge1xuICAgICAgICB2YXIgdGFnID0gcGJmLnJlYWRWYXJpbnQoKSA+PiAzO1xuXG4gICAgICAgIHZhbHVlID0gdGFnID09PSAxID8gcGJmLnJlYWRTdHJpbmcoKSA6XG4gICAgICAgICAgICB0YWcgPT09IDIgPyBwYmYucmVhZEZsb2F0KCkgOlxuICAgICAgICAgICAgdGFnID09PSAzID8gcGJmLnJlYWREb3VibGUoKSA6XG4gICAgICAgICAgICB0YWcgPT09IDQgPyBwYmYucmVhZFZhcmludDY0KCkgOlxuICAgICAgICAgICAgdGFnID09PSA1ID8gcGJmLnJlYWRWYXJpbnQoKSA6XG4gICAgICAgICAgICB0YWcgPT09IDYgPyBwYmYucmVhZFNWYXJpbnQoKSA6XG4gICAgICAgICAgICB0YWcgPT09IDcgPyBwYmYucmVhZEJvb2xlYW4oKSA6IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vLyByZXR1cm4gZmVhdHVyZSBgaWAgZnJvbSB0aGlzIGxheWVyIGFzIGEgYFZlY3RvclRpbGVGZWF0dXJlYFxuVmVjdG9yVGlsZUxheWVyLnByb3RvdHlwZS5mZWF0dXJlID0gZnVuY3Rpb24oaSkge1xuICAgIGlmIChpIDwgMCB8fCBpID49IHRoaXMuX2ZlYXR1cmVzLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdmZWF0dXJlIGluZGV4IG91dCBvZiBib3VuZHMnKTtcblxuICAgIHRoaXMuX3BiZi5wb3MgPSB0aGlzLl9mZWF0dXJlc1tpXTtcblxuICAgIHZhciBlbmQgPSB0aGlzLl9wYmYucmVhZFZhcmludCgpICsgdGhpcy5fcGJmLnBvcztcbiAgICByZXR1cm4gbmV3IFZlY3RvclRpbGVGZWF0dXJlKHRoaXMuX3BiZiwgZW5kLCB0aGlzLmV4dGVudCwgdGhpcy5fa2V5cywgdGhpcy5fdmFsdWVzKTtcbn07XG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsIi8vICAgICAgXG5cbmNsYXNzIEZlYXR1cmUge1xuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuXG4gICAgY29uc3RydWN0b3IodmVjdG9yVGlsZUZlYXR1cmUgICAgICAgICAgICAgICAgICAgLCB6ICAgICAgICAsIHggICAgICAgICwgeSAgICAgICAgKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdGZWF0dXJlJztcblxuICAgICAgICB0aGlzLl92ZWN0b3JUaWxlRmVhdHVyZSA9IHZlY3RvclRpbGVGZWF0dXJlO1xuICAgICAgICAodmVjdG9yVGlsZUZlYXR1cmUgICAgICkuX3ogPSB6O1xuICAgICAgICAodmVjdG9yVGlsZUZlYXR1cmUgICAgICkuX3ggPSB4O1xuICAgICAgICAodmVjdG9yVGlsZUZlYXR1cmUgICAgICkuX3kgPSB5O1xuXG4gICAgICAgIHRoaXMucHJvcGVydGllcyA9IHZlY3RvclRpbGVGZWF0dXJlLnByb3BlcnRpZXM7XG5cbiAgICAgICAgaWYgKHZlY3RvclRpbGVGZWF0dXJlLmlkICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuaWQgPSB2ZWN0b3JUaWxlRmVhdHVyZS5pZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBnZW9tZXRyeSgpICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgaWYgKHRoaXMuX2dlb21ldHJ5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2dlb21ldHJ5ID0gdGhpcy5fdmVjdG9yVGlsZUZlYXR1cmUudG9HZW9KU09OKFxuICAgICAgICAgICAgICAgICh0aGlzLl92ZWN0b3JUaWxlRmVhdHVyZSAgICAgKS5feCxcbiAgICAgICAgICAgICAgICAodGhpcy5fdmVjdG9yVGlsZUZlYXR1cmUgICAgICkuX3ksXG4gICAgICAgICAgICAgICAgKHRoaXMuX3ZlY3RvclRpbGVGZWF0dXJlICAgICApLl96KS5nZW9tZXRyeTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fZ2VvbWV0cnk7XG4gICAgfVxuXG4gICAgc2V0IGdlb21ldHJ5KGcgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgdGhpcy5fZ2VvbWV0cnkgPSBnO1xuICAgIH1cblxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3QganNvbiA9IHtcbiAgICAgICAgICAgIGdlb21ldHJ5OiB0aGlzLmdlb21ldHJ5XG4gICAgICAgIH07XG4gICAgICAgIGZvciAoY29uc3QgaSBpbiB0aGlzKSB7XG4gICAgICAgICAgICBpZiAoaSA9PT0gJ19nZW9tZXRyeScgfHwgaSA9PT0gJ192ZWN0b3JUaWxlRmVhdHVyZScpIGNvbnRpbnVlO1xuICAgICAgICAgICAganNvbltpXSA9ICh0aGlzICAgICApW2ldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBqc29uO1xuICAgIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBGZWF0dXJlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBiZjtcblxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0Jyk7XG5cbmZ1bmN0aW9uIFBiZihidWYpIHtcbiAgICB0aGlzLmJ1ZiA9IEFycmF5QnVmZmVyLmlzVmlldyAmJiBBcnJheUJ1ZmZlci5pc1ZpZXcoYnVmKSA/IGJ1ZiA6IG5ldyBVaW50OEFycmF5KGJ1ZiB8fCAwKTtcbiAgICB0aGlzLnBvcyA9IDA7XG4gICAgdGhpcy50eXBlID0gMDtcbiAgICB0aGlzLmxlbmd0aCA9IHRoaXMuYnVmLmxlbmd0aDtcbn1cblxuUGJmLlZhcmludCAgPSAwOyAvLyB2YXJpbnQ6IGludDMyLCBpbnQ2NCwgdWludDMyLCB1aW50NjQsIHNpbnQzMiwgc2ludDY0LCBib29sLCBlbnVtXG5QYmYuRml4ZWQ2NCA9IDE7IC8vIDY0LWJpdDogZG91YmxlLCBmaXhlZDY0LCBzZml4ZWQ2NFxuUGJmLkJ5dGVzICAgPSAyOyAvLyBsZW5ndGgtZGVsaW1pdGVkOiBzdHJpbmcsIGJ5dGVzLCBlbWJlZGRlZCBtZXNzYWdlcywgcGFja2VkIHJlcGVhdGVkIGZpZWxkc1xuUGJmLkZpeGVkMzIgPSA1OyAvLyAzMi1iaXQ6IGZsb2F0LCBmaXhlZDMyLCBzZml4ZWQzMlxuXG52YXIgU0hJRlRfTEVGVF8zMiA9ICgxIDw8IDE2KSAqICgxIDw8IDE2KSxcbiAgICBTSElGVF9SSUdIVF8zMiA9IDEgLyBTSElGVF9MRUZUXzMyO1xuXG5QYmYucHJvdG90eXBlID0ge1xuXG4gICAgZGVzdHJveTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuYnVmID0gbnVsbDtcbiAgICB9LFxuXG4gICAgLy8gPT09IFJFQURJTkcgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIHJlYWRGaWVsZHM6IGZ1bmN0aW9uKHJlYWRGaWVsZCwgcmVzdWx0LCBlbmQpIHtcbiAgICAgICAgZW5kID0gZW5kIHx8IHRoaXMubGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgdmFyIHZhbCA9IHRoaXMucmVhZFZhcmludCgpLFxuICAgICAgICAgICAgICAgIHRhZyA9IHZhbCA+PiAzLFxuICAgICAgICAgICAgICAgIHN0YXJ0UG9zID0gdGhpcy5wb3M7XG5cbiAgICAgICAgICAgIHRoaXMudHlwZSA9IHZhbCAmIDB4NztcbiAgICAgICAgICAgIHJlYWRGaWVsZCh0YWcsIHJlc3VsdCwgdGhpcyk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnBvcyA9PT0gc3RhcnRQb3MpIHRoaXMuc2tpcCh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIHJlYWRNZXNzYWdlOiBmdW5jdGlvbihyZWFkRmllbGQsIHJlc3VsdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkRmllbGRzKHJlYWRGaWVsZCwgcmVzdWx0LCB0aGlzLnJlYWRWYXJpbnQoKSArIHRoaXMucG9zKTtcbiAgICB9LFxuXG4gICAgcmVhZEZpeGVkMzI6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgdmFsID0gcmVhZFVJbnQzMih0aGlzLmJ1ZiwgdGhpcy5wb3MpO1xuICAgICAgICB0aGlzLnBvcyArPSA0O1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH0sXG5cbiAgICByZWFkU0ZpeGVkMzI6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgdmFsID0gcmVhZEludDMyKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgICAgIHRoaXMucG9zICs9IDQ7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgfSxcblxuICAgIC8vIDY0LWJpdCBpbnQgaGFuZGxpbmcgaXMgYmFzZWQgb24gZ2l0aHViLmNvbS9kcHcvbm9kZS1idWZmZXItbW9yZS1pbnRzIChNSVQtbGljZW5zZWQpXG5cbiAgICByZWFkRml4ZWQ2NDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB2YWwgPSByZWFkVUludDMyKHRoaXMuYnVmLCB0aGlzLnBvcykgKyByZWFkVUludDMyKHRoaXMuYnVmLCB0aGlzLnBvcyArIDQpICogU0hJRlRfTEVGVF8zMjtcbiAgICAgICAgdGhpcy5wb3MgKz0gODtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICB9LFxuXG4gICAgcmVhZFNGaXhlZDY0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHZhbCA9IHJlYWRVSW50MzIodGhpcy5idWYsIHRoaXMucG9zKSArIHJlYWRJbnQzMih0aGlzLmJ1ZiwgdGhpcy5wb3MgKyA0KSAqIFNISUZUX0xFRlRfMzI7XG4gICAgICAgIHRoaXMucG9zICs9IDg7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgfSxcblxuICAgIHJlYWRGbG9hdDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB2YWwgPSBpZWVlNzU0LnJlYWQodGhpcy5idWYsIHRoaXMucG9zLCB0cnVlLCAyMywgNCk7XG4gICAgICAgIHRoaXMucG9zICs9IDQ7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgfSxcblxuICAgIHJlYWREb3VibGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgdmFsID0gaWVlZTc1NC5yZWFkKHRoaXMuYnVmLCB0aGlzLnBvcywgdHJ1ZSwgNTIsIDgpO1xuICAgICAgICB0aGlzLnBvcyArPSA4O1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH0sXG5cbiAgICByZWFkVmFyaW50OiBmdW5jdGlvbihpc1NpZ25lZCkge1xuICAgICAgICB2YXIgYnVmID0gdGhpcy5idWYsXG4gICAgICAgICAgICB2YWwsIGI7XG5cbiAgICAgICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTsgdmFsICA9ICBiICYgMHg3ZjsgICAgICAgIGlmIChiIDwgMHg4MCkgcmV0dXJuIHZhbDtcbiAgICAgICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTsgdmFsIHw9IChiICYgMHg3ZikgPDwgNzsgIGlmIChiIDwgMHg4MCkgcmV0dXJuIHZhbDtcbiAgICAgICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTsgdmFsIHw9IChiICYgMHg3ZikgPDwgMTQ7IGlmIChiIDwgMHg4MCkgcmV0dXJuIHZhbDtcbiAgICAgICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTsgdmFsIHw9IChiICYgMHg3ZikgPDwgMjE7IGlmIChiIDwgMHg4MCkgcmV0dXJuIHZhbDtcbiAgICAgICAgYiA9IGJ1Zlt0aGlzLnBvc107ICAgdmFsIHw9IChiICYgMHgwZikgPDwgMjg7XG5cbiAgICAgICAgcmV0dXJuIHJlYWRWYXJpbnRSZW1haW5kZXIodmFsLCBpc1NpZ25lZCwgdGhpcyk7XG4gICAgfSxcblxuICAgIHJlYWRWYXJpbnQ2NDogZnVuY3Rpb24oKSB7IC8vIGZvciBjb21wYXRpYmlsaXR5IHdpdGggdjIuMC4xXG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRWYXJpbnQodHJ1ZSk7XG4gICAgfSxcblxuICAgIHJlYWRTVmFyaW50OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG51bSA9IHRoaXMucmVhZFZhcmludCgpO1xuICAgICAgICByZXR1cm4gbnVtICUgMiA9PT0gMSA/IChudW0gKyAxKSAvIC0yIDogbnVtIC8gMjsgLy8gemlnemFnIGVuY29kaW5nXG4gICAgfSxcblxuICAgIHJlYWRCb29sZWFuOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4odGhpcy5yZWFkVmFyaW50KCkpO1xuICAgIH0sXG5cbiAgICByZWFkU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGVuZCA9IHRoaXMucmVhZFZhcmludCgpICsgdGhpcy5wb3MsXG4gICAgICAgICAgICBzdHIgPSByZWFkVXRmOCh0aGlzLmJ1ZiwgdGhpcy5wb3MsIGVuZCk7XG4gICAgICAgIHRoaXMucG9zID0gZW5kO1xuICAgICAgICByZXR1cm4gc3RyO1xuICAgIH0sXG5cbiAgICByZWFkQnl0ZXM6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZW5kID0gdGhpcy5yZWFkVmFyaW50KCkgKyB0aGlzLnBvcyxcbiAgICAgICAgICAgIGJ1ZmZlciA9IHRoaXMuYnVmLnN1YmFycmF5KHRoaXMucG9zLCBlbmQpO1xuICAgICAgICB0aGlzLnBvcyA9IGVuZDtcbiAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcbiAgICB9LFxuXG4gICAgLy8gdmVyYm9zZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29uczsgZG9lc24ndCBhZmZlY3QgZ3ppcHBlZCBzaXplXG5cbiAgICByZWFkUGFja2VkVmFyaW50OiBmdW5jdGlvbihhcnIsIGlzU2lnbmVkKSB7XG4gICAgICAgIHZhciBlbmQgPSByZWFkUGFja2VkRW5kKHRoaXMpO1xuICAgICAgICBhcnIgPSBhcnIgfHwgW107XG4gICAgICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkgYXJyLnB1c2godGhpcy5yZWFkVmFyaW50KGlzU2lnbmVkKSk7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgfSxcbiAgICByZWFkUGFja2VkU1ZhcmludDogZnVuY3Rpb24oYXJyKSB7XG4gICAgICAgIHZhciBlbmQgPSByZWFkUGFja2VkRW5kKHRoaXMpO1xuICAgICAgICBhcnIgPSBhcnIgfHwgW107XG4gICAgICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkgYXJyLnB1c2godGhpcy5yZWFkU1ZhcmludCgpKTtcbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9LFxuICAgIHJlYWRQYWNrZWRCb29sZWFuOiBmdW5jdGlvbihhcnIpIHtcbiAgICAgICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgICAgIGFyciA9IGFyciB8fCBbXTtcbiAgICAgICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSBhcnIucHVzaCh0aGlzLnJlYWRCb29sZWFuKCkpO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgIH0sXG4gICAgcmVhZFBhY2tlZEZsb2F0OiBmdW5jdGlvbihhcnIpIHtcbiAgICAgICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgICAgIGFyciA9IGFyciB8fCBbXTtcbiAgICAgICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSBhcnIucHVzaCh0aGlzLnJlYWRGbG9hdCgpKTtcbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9LFxuICAgIHJlYWRQYWNrZWREb3VibGU6IGZ1bmN0aW9uKGFycikge1xuICAgICAgICB2YXIgZW5kID0gcmVhZFBhY2tlZEVuZCh0aGlzKTtcbiAgICAgICAgYXJyID0gYXJyIHx8IFtdO1xuICAgICAgICB3aGlsZSAodGhpcy5wb3MgPCBlbmQpIGFyci5wdXNoKHRoaXMucmVhZERvdWJsZSgpKTtcbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9LFxuICAgIHJlYWRQYWNrZWRGaXhlZDMyOiBmdW5jdGlvbihhcnIpIHtcbiAgICAgICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgICAgIGFyciA9IGFyciB8fCBbXTtcbiAgICAgICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSBhcnIucHVzaCh0aGlzLnJlYWRGaXhlZDMyKCkpO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgIH0sXG4gICAgcmVhZFBhY2tlZFNGaXhlZDMyOiBmdW5jdGlvbihhcnIpIHtcbiAgICAgICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgICAgIGFyciA9IGFyciB8fCBbXTtcbiAgICAgICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSBhcnIucHVzaCh0aGlzLnJlYWRTRml4ZWQzMigpKTtcbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9LFxuICAgIHJlYWRQYWNrZWRGaXhlZDY0OiBmdW5jdGlvbihhcnIpIHtcbiAgICAgICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgICAgIGFyciA9IGFyciB8fCBbXTtcbiAgICAgICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSBhcnIucHVzaCh0aGlzLnJlYWRGaXhlZDY0KCkpO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgIH0sXG4gICAgcmVhZFBhY2tlZFNGaXhlZDY0OiBmdW5jdGlvbihhcnIpIHtcbiAgICAgICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgICAgIGFyciA9IGFyciB8fCBbXTtcbiAgICAgICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSBhcnIucHVzaCh0aGlzLnJlYWRTRml4ZWQ2NCgpKTtcbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9LFxuXG4gICAgc2tpcDogZnVuY3Rpb24odmFsKSB7XG4gICAgICAgIHZhciB0eXBlID0gdmFsICYgMHg3O1xuICAgICAgICBpZiAodHlwZSA9PT0gUGJmLlZhcmludCkgd2hpbGUgKHRoaXMuYnVmW3RoaXMucG9zKytdID4gMHg3Zikge31cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gUGJmLkJ5dGVzKSB0aGlzLnBvcyA9IHRoaXMucmVhZFZhcmludCgpICsgdGhpcy5wb3M7XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09IFBiZi5GaXhlZDMyKSB0aGlzLnBvcyArPSA0O1xuICAgICAgICBlbHNlIGlmICh0eXBlID09PSBQYmYuRml4ZWQ2NCkgdGhpcy5wb3MgKz0gODtcbiAgICAgICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ1VuaW1wbGVtZW50ZWQgdHlwZTogJyArIHR5cGUpO1xuICAgIH0sXG5cbiAgICAvLyA9PT0gV1JJVElORyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgd3JpdGVUYWc6IGZ1bmN0aW9uKHRhZywgdHlwZSkge1xuICAgICAgICB0aGlzLndyaXRlVmFyaW50KCh0YWcgPDwgMykgfCB0eXBlKTtcbiAgICB9LFxuXG4gICAgcmVhbGxvYzogZnVuY3Rpb24obWluKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8fCAxNjtcblxuICAgICAgICB3aGlsZSAobGVuZ3RoIDwgdGhpcy5wb3MgKyBtaW4pIGxlbmd0aCAqPSAyO1xuXG4gICAgICAgIGlmIChsZW5ndGggIT09IHRoaXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKTtcbiAgICAgICAgICAgIGJ1Zi5zZXQodGhpcy5idWYpO1xuICAgICAgICAgICAgdGhpcy5idWYgPSBidWY7XG4gICAgICAgICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBmaW5pc2g6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLmxlbmd0aCA9IHRoaXMucG9zO1xuICAgICAgICB0aGlzLnBvcyA9IDA7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1Zi5zdWJhcnJheSgwLCB0aGlzLmxlbmd0aCk7XG4gICAgfSxcblxuICAgIHdyaXRlRml4ZWQzMjogZnVuY3Rpb24odmFsKSB7XG4gICAgICAgIHRoaXMucmVhbGxvYyg0KTtcbiAgICAgICAgd3JpdGVJbnQzMih0aGlzLmJ1ZiwgdmFsLCB0aGlzLnBvcyk7XG4gICAgICAgIHRoaXMucG9zICs9IDQ7XG4gICAgfSxcblxuICAgIHdyaXRlU0ZpeGVkMzI6IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICB0aGlzLnJlYWxsb2MoNCk7XG4gICAgICAgIHdyaXRlSW50MzIodGhpcy5idWYsIHZhbCwgdGhpcy5wb3MpO1xuICAgICAgICB0aGlzLnBvcyArPSA0O1xuICAgIH0sXG5cbiAgICB3cml0ZUZpeGVkNjQ6IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICB0aGlzLnJlYWxsb2MoOCk7XG4gICAgICAgIHdyaXRlSW50MzIodGhpcy5idWYsIHZhbCAmIC0xLCB0aGlzLnBvcyk7XG4gICAgICAgIHdyaXRlSW50MzIodGhpcy5idWYsIE1hdGguZmxvb3IodmFsICogU0hJRlRfUklHSFRfMzIpLCB0aGlzLnBvcyArIDQpO1xuICAgICAgICB0aGlzLnBvcyArPSA4O1xuICAgIH0sXG5cbiAgICB3cml0ZVNGaXhlZDY0OiBmdW5jdGlvbih2YWwpIHtcbiAgICAgICAgdGhpcy5yZWFsbG9jKDgpO1xuICAgICAgICB3cml0ZUludDMyKHRoaXMuYnVmLCB2YWwgJiAtMSwgdGhpcy5wb3MpO1xuICAgICAgICB3cml0ZUludDMyKHRoaXMuYnVmLCBNYXRoLmZsb29yKHZhbCAqIFNISUZUX1JJR0hUXzMyKSwgdGhpcy5wb3MgKyA0KTtcbiAgICAgICAgdGhpcy5wb3MgKz0gODtcbiAgICB9LFxuXG4gICAgd3JpdGVWYXJpbnQ6IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICB2YWwgPSArdmFsIHx8IDA7XG5cbiAgICAgICAgaWYgKHZhbCA+IDB4ZmZmZmZmZiB8fCB2YWwgPCAwKSB7XG4gICAgICAgICAgICB3cml0ZUJpZ1ZhcmludCh2YWwsIHRoaXMpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZWFsbG9jKDQpO1xuXG4gICAgICAgIHRoaXMuYnVmW3RoaXMucG9zKytdID0gICAgICAgICAgIHZhbCAmIDB4N2YgIHwgKHZhbCA+IDB4N2YgPyAweDgwIDogMCk7IGlmICh2YWwgPD0gMHg3ZikgcmV0dXJuO1xuICAgICAgICB0aGlzLmJ1Zlt0aGlzLnBvcysrXSA9ICgodmFsID4+Pj0gNykgJiAweDdmKSB8ICh2YWwgPiAweDdmID8gMHg4MCA6IDApOyBpZiAodmFsIDw9IDB4N2YpIHJldHVybjtcbiAgICAgICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSAoKHZhbCA+Pj49IDcpICYgMHg3ZikgfCAodmFsID4gMHg3ZiA/IDB4ODAgOiAwKTsgaWYgKHZhbCA8PSAweDdmKSByZXR1cm47XG4gICAgICAgIHRoaXMuYnVmW3RoaXMucG9zKytdID0gICAodmFsID4+PiA3KSAmIDB4N2Y7XG4gICAgfSxcblxuICAgIHdyaXRlU1ZhcmludDogZnVuY3Rpb24odmFsKSB7XG4gICAgICAgIHRoaXMud3JpdGVWYXJpbnQodmFsIDwgMCA/IC12YWwgKiAyIC0gMSA6IHZhbCAqIDIpO1xuICAgIH0sXG5cbiAgICB3cml0ZUJvb2xlYW46IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgICB0aGlzLndyaXRlVmFyaW50KEJvb2xlYW4odmFsKSk7XG4gICAgfSxcblxuICAgIHdyaXRlU3RyaW5nOiBmdW5jdGlvbihzdHIpIHtcbiAgICAgICAgc3RyID0gU3RyaW5nKHN0cik7XG4gICAgICAgIHRoaXMucmVhbGxvYyhzdHIubGVuZ3RoICogNCk7XG5cbiAgICAgICAgdGhpcy5wb3MrKzsgLy8gcmVzZXJ2ZSAxIGJ5dGUgZm9yIHNob3J0IHN0cmluZyBsZW5ndGhcblxuICAgICAgICB2YXIgc3RhcnRQb3MgPSB0aGlzLnBvcztcbiAgICAgICAgLy8gd3JpdGUgdGhlIHN0cmluZyBkaXJlY3RseSB0byB0aGUgYnVmZmVyIGFuZCBzZWUgaG93IG11Y2ggd2FzIHdyaXR0ZW5cbiAgICAgICAgdGhpcy5wb3MgPSB3cml0ZVV0ZjgodGhpcy5idWYsIHN0ciwgdGhpcy5wb3MpO1xuICAgICAgICB2YXIgbGVuID0gdGhpcy5wb3MgLSBzdGFydFBvcztcblxuICAgICAgICBpZiAobGVuID49IDB4ODApIG1ha2VSb29tRm9yRXh0cmFMZW5ndGgoc3RhcnRQb3MsIGxlbiwgdGhpcyk7XG5cbiAgICAgICAgLy8gZmluYWxseSwgd3JpdGUgdGhlIG1lc3NhZ2UgbGVuZ3RoIGluIHRoZSByZXNlcnZlZCBwbGFjZSBhbmQgcmVzdG9yZSB0aGUgcG9zaXRpb25cbiAgICAgICAgdGhpcy5wb3MgPSBzdGFydFBvcyAtIDE7XG4gICAgICAgIHRoaXMud3JpdGVWYXJpbnQobGVuKTtcbiAgICAgICAgdGhpcy5wb3MgKz0gbGVuO1xuICAgIH0sXG5cbiAgICB3cml0ZUZsb2F0OiBmdW5jdGlvbih2YWwpIHtcbiAgICAgICAgdGhpcy5yZWFsbG9jKDQpO1xuICAgICAgICBpZWVlNzU0LndyaXRlKHRoaXMuYnVmLCB2YWwsIHRoaXMucG9zLCB0cnVlLCAyMywgNCk7XG4gICAgICAgIHRoaXMucG9zICs9IDQ7XG4gICAgfSxcblxuICAgIHdyaXRlRG91YmxlOiBmdW5jdGlvbih2YWwpIHtcbiAgICAgICAgdGhpcy5yZWFsbG9jKDgpO1xuICAgICAgICBpZWVlNzU0LndyaXRlKHRoaXMuYnVmLCB2YWwsIHRoaXMucG9zLCB0cnVlLCA1MiwgOCk7XG4gICAgICAgIHRoaXMucG9zICs9IDg7XG4gICAgfSxcblxuICAgIHdyaXRlQnl0ZXM6IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgICB2YXIgbGVuID0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgdGhpcy53cml0ZVZhcmludChsZW4pO1xuICAgICAgICB0aGlzLnJlYWxsb2MobGVuKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykgdGhpcy5idWZbdGhpcy5wb3MrK10gPSBidWZmZXJbaV07XG4gICAgfSxcblxuICAgIHdyaXRlUmF3TWVzc2FnZTogZnVuY3Rpb24oZm4sIG9iaikge1xuICAgICAgICB0aGlzLnBvcysrOyAvLyByZXNlcnZlIDEgYnl0ZSBmb3Igc2hvcnQgbWVzc2FnZSBsZW5ndGhcblxuICAgICAgICAvLyB3cml0ZSB0aGUgbWVzc2FnZSBkaXJlY3RseSB0byB0aGUgYnVmZmVyIGFuZCBzZWUgaG93IG11Y2ggd2FzIHdyaXR0ZW5cbiAgICAgICAgdmFyIHN0YXJ0UG9zID0gdGhpcy5wb3M7XG4gICAgICAgIGZuKG9iaiwgdGhpcyk7XG4gICAgICAgIHZhciBsZW4gPSB0aGlzLnBvcyAtIHN0YXJ0UG9zO1xuXG4gICAgICAgIGlmIChsZW4gPj0gMHg4MCkgbWFrZVJvb21Gb3JFeHRyYUxlbmd0aChzdGFydFBvcywgbGVuLCB0aGlzKTtcblxuICAgICAgICAvLyBmaW5hbGx5LCB3cml0ZSB0aGUgbWVzc2FnZSBsZW5ndGggaW4gdGhlIHJlc2VydmVkIHBsYWNlIGFuZCByZXN0b3JlIHRoZSBwb3NpdGlvblxuICAgICAgICB0aGlzLnBvcyA9IHN0YXJ0UG9zIC0gMTtcbiAgICAgICAgdGhpcy53cml0ZVZhcmludChsZW4pO1xuICAgICAgICB0aGlzLnBvcyArPSBsZW47XG4gICAgfSxcblxuICAgIHdyaXRlTWVzc2FnZTogZnVuY3Rpb24odGFnLCBmbiwgb2JqKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgICAgICB0aGlzLndyaXRlUmF3TWVzc2FnZShmbiwgb2JqKTtcbiAgICB9LFxuXG4gICAgd3JpdGVQYWNrZWRWYXJpbnQ6ICAgZnVuY3Rpb24odGFnLCBhcnIpIHsgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCB3cml0ZVBhY2tlZFZhcmludCwgYXJyKTsgICB9LFxuICAgIHdyaXRlUGFja2VkU1ZhcmludDogIGZ1bmN0aW9uKHRhZywgYXJyKSB7IHRoaXMud3JpdGVNZXNzYWdlKHRhZywgd3JpdGVQYWNrZWRTVmFyaW50LCBhcnIpOyAgfSxcbiAgICB3cml0ZVBhY2tlZEJvb2xlYW46ICBmdW5jdGlvbih0YWcsIGFycikgeyB0aGlzLndyaXRlTWVzc2FnZSh0YWcsIHdyaXRlUGFja2VkQm9vbGVhbiwgYXJyKTsgIH0sXG4gICAgd3JpdGVQYWNrZWRGbG9hdDogICAgZnVuY3Rpb24odGFnLCBhcnIpIHsgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCB3cml0ZVBhY2tlZEZsb2F0LCBhcnIpOyAgICB9LFxuICAgIHdyaXRlUGFja2VkRG91YmxlOiAgIGZ1bmN0aW9uKHRhZywgYXJyKSB7IHRoaXMud3JpdGVNZXNzYWdlKHRhZywgd3JpdGVQYWNrZWREb3VibGUsIGFycik7ICAgfSxcbiAgICB3cml0ZVBhY2tlZEZpeGVkMzI6ICBmdW5jdGlvbih0YWcsIGFycikgeyB0aGlzLndyaXRlTWVzc2FnZSh0YWcsIHdyaXRlUGFja2VkRml4ZWQzMiwgYXJyKTsgIH0sXG4gICAgd3JpdGVQYWNrZWRTRml4ZWQzMjogZnVuY3Rpb24odGFnLCBhcnIpIHsgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCB3cml0ZVBhY2tlZFNGaXhlZDMyLCBhcnIpOyB9LFxuICAgIHdyaXRlUGFja2VkRml4ZWQ2NDogIGZ1bmN0aW9uKHRhZywgYXJyKSB7IHRoaXMud3JpdGVNZXNzYWdlKHRhZywgd3JpdGVQYWNrZWRGaXhlZDY0LCBhcnIpOyAgfSxcbiAgICB3cml0ZVBhY2tlZFNGaXhlZDY0OiBmdW5jdGlvbih0YWcsIGFycikgeyB0aGlzLndyaXRlTWVzc2FnZSh0YWcsIHdyaXRlUGFja2VkU0ZpeGVkNjQsIGFycik7IH0sXG5cbiAgICB3cml0ZUJ5dGVzRmllbGQ6IGZ1bmN0aW9uKHRhZywgYnVmZmVyKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgICAgICB0aGlzLndyaXRlQnl0ZXMoYnVmZmVyKTtcbiAgICB9LFxuICAgIHdyaXRlRml4ZWQzMkZpZWxkOiBmdW5jdGlvbih0YWcsIHZhbCkge1xuICAgICAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkMzIpO1xuICAgICAgICB0aGlzLndyaXRlRml4ZWQzMih2YWwpO1xuICAgIH0sXG4gICAgd3JpdGVTRml4ZWQzMkZpZWxkOiBmdW5jdGlvbih0YWcsIHZhbCkge1xuICAgICAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkMzIpO1xuICAgICAgICB0aGlzLndyaXRlU0ZpeGVkMzIodmFsKTtcbiAgICB9LFxuICAgIHdyaXRlRml4ZWQ2NEZpZWxkOiBmdW5jdGlvbih0YWcsIHZhbCkge1xuICAgICAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkNjQpO1xuICAgICAgICB0aGlzLndyaXRlRml4ZWQ2NCh2YWwpO1xuICAgIH0sXG4gICAgd3JpdGVTRml4ZWQ2NEZpZWxkOiBmdW5jdGlvbih0YWcsIHZhbCkge1xuICAgICAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkNjQpO1xuICAgICAgICB0aGlzLndyaXRlU0ZpeGVkNjQodmFsKTtcbiAgICB9LFxuICAgIHdyaXRlVmFyaW50RmllbGQ6IGZ1bmN0aW9uKHRhZywgdmFsKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuVmFyaW50KTtcbiAgICAgICAgdGhpcy53cml0ZVZhcmludCh2YWwpO1xuICAgIH0sXG4gICAgd3JpdGVTVmFyaW50RmllbGQ6IGZ1bmN0aW9uKHRhZywgdmFsKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuVmFyaW50KTtcbiAgICAgICAgdGhpcy53cml0ZVNWYXJpbnQodmFsKTtcbiAgICB9LFxuICAgIHdyaXRlU3RyaW5nRmllbGQ6IGZ1bmN0aW9uKHRhZywgc3RyKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgICAgICB0aGlzLndyaXRlU3RyaW5nKHN0cik7XG4gICAgfSxcbiAgICB3cml0ZUZsb2F0RmllbGQ6IGZ1bmN0aW9uKHRhZywgdmFsKSB7XG4gICAgICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuRml4ZWQzMik7XG4gICAgICAgIHRoaXMud3JpdGVGbG9hdCh2YWwpO1xuICAgIH0sXG4gICAgd3JpdGVEb3VibGVGaWVsZDogZnVuY3Rpb24odGFnLCB2YWwpIHtcbiAgICAgICAgdGhpcy53cml0ZVRhZyh0YWcsIFBiZi5GaXhlZDY0KTtcbiAgICAgICAgdGhpcy53cml0ZURvdWJsZSh2YWwpO1xuICAgIH0sXG4gICAgd3JpdGVCb29sZWFuRmllbGQ6IGZ1bmN0aW9uKHRhZywgdmFsKSB7XG4gICAgICAgIHRoaXMud3JpdGVWYXJpbnRGaWVsZCh0YWcsIEJvb2xlYW4odmFsKSk7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gcmVhZFZhcmludFJlbWFpbmRlcihsLCBzLCBwKSB7XG4gICAgdmFyIGJ1ZiA9IHAuYnVmLFxuICAgICAgICBoLCBiO1xuXG4gICAgYiA9IGJ1ZltwLnBvcysrXTsgaCAgPSAoYiAmIDB4NzApID4+IDQ7ICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgICBiID0gYnVmW3AucG9zKytdOyBoIHw9IChiICYgMHg3ZikgPDwgMzsgIGlmIChiIDwgMHg4MCkgcmV0dXJuIHRvTnVtKGwsIGgsIHMpO1xuICAgIGIgPSBidWZbcC5wb3MrK107IGggfD0gKGIgJiAweDdmKSA8PCAxMDsgaWYgKGIgPCAweDgwKSByZXR1cm4gdG9OdW0obCwgaCwgcyk7XG4gICAgYiA9IGJ1ZltwLnBvcysrXTsgaCB8PSAoYiAmIDB4N2YpIDw8IDE3OyBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgICBiID0gYnVmW3AucG9zKytdOyBoIHw9IChiICYgMHg3ZikgPDwgMjQ7IGlmIChiIDwgMHg4MCkgcmV0dXJuIHRvTnVtKGwsIGgsIHMpO1xuICAgIGIgPSBidWZbcC5wb3MrK107IGggfD0gKGIgJiAweDAxKSA8PCAzMTsgaWYgKGIgPCAweDgwKSByZXR1cm4gdG9OdW0obCwgaCwgcyk7XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHZhcmludCBub3QgbW9yZSB0aGFuIDEwIGJ5dGVzJyk7XG59XG5cbmZ1bmN0aW9uIHJlYWRQYWNrZWRFbmQocGJmKSB7XG4gICAgcmV0dXJuIHBiZi50eXBlID09PSBQYmYuQnl0ZXMgP1xuICAgICAgICBwYmYucmVhZFZhcmludCgpICsgcGJmLnBvcyA6IHBiZi5wb3MgKyAxO1xufVxuXG5mdW5jdGlvbiB0b051bShsb3csIGhpZ2gsIGlzU2lnbmVkKSB7XG4gICAgaWYgKGlzU2lnbmVkKSB7XG4gICAgICAgIHJldHVybiBoaWdoICogMHgxMDAwMDAwMDAgKyAobG93ID4+PiAwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gKChoaWdoID4+PiAwKSAqIDB4MTAwMDAwMDAwKSArIChsb3cgPj4+IDApO1xufVxuXG5mdW5jdGlvbiB3cml0ZUJpZ1ZhcmludCh2YWwsIHBiZikge1xuICAgIHZhciBsb3csIGhpZ2g7XG5cbiAgICBpZiAodmFsID49IDApIHtcbiAgICAgICAgbG93ICA9ICh2YWwgJSAweDEwMDAwMDAwMCkgfCAwO1xuICAgICAgICBoaWdoID0gKHZhbCAvIDB4MTAwMDAwMDAwKSB8IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbG93ICA9IH4oLXZhbCAlIDB4MTAwMDAwMDAwKTtcbiAgICAgICAgaGlnaCA9IH4oLXZhbCAvIDB4MTAwMDAwMDAwKTtcblxuICAgICAgICBpZiAobG93IF4gMHhmZmZmZmZmZikge1xuICAgICAgICAgICAgbG93ID0gKGxvdyArIDEpIHwgMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvdyA9IDA7XG4gICAgICAgICAgICBoaWdoID0gKGhpZ2ggKyAxKSB8IDA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodmFsID49IDB4MTAwMDAwMDAwMDAwMDAwMDAgfHwgdmFsIDwgLTB4MTAwMDAwMDAwMDAwMDAwMDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdHaXZlbiB2YXJpbnQgZG9lc25cXCd0IGZpdCBpbnRvIDEwIGJ5dGVzJyk7XG4gICAgfVxuXG4gICAgcGJmLnJlYWxsb2MoMTApO1xuXG4gICAgd3JpdGVCaWdWYXJpbnRMb3cobG93LCBoaWdoLCBwYmYpO1xuICAgIHdyaXRlQmlnVmFyaW50SGlnaChoaWdoLCBwYmYpO1xufVxuXG5mdW5jdGlvbiB3cml0ZUJpZ1ZhcmludExvdyhsb3csIGhpZ2gsIHBiZikge1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSA9IGxvdyAmIDB4N2YgfCAweDgwOyBsb3cgPj4+PSA3O1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSA9IGxvdyAmIDB4N2YgfCAweDgwOyBsb3cgPj4+PSA3O1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSA9IGxvdyAmIDB4N2YgfCAweDgwOyBsb3cgPj4+PSA3O1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSA9IGxvdyAmIDB4N2YgfCAweDgwOyBsb3cgPj4+PSA3O1xuICAgIHBiZi5idWZbcGJmLnBvc10gICA9IGxvdyAmIDB4N2Y7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmlnVmFyaW50SGlnaChoaWdoLCBwYmYpIHtcbiAgICB2YXIgbHNiID0gKGhpZ2ggJiAweDA3KSA8PCA0O1xuXG4gICAgcGJmLmJ1ZltwYmYucG9zKytdIHw9IGxzYiAgICAgICAgIHwgKChoaWdoID4+Pj0gMykgPyAweDgwIDogMCk7IGlmICghaGlnaCkgcmV0dXJuO1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSAgPSBoaWdoICYgMHg3ZiB8ICgoaGlnaCA+Pj49IDcpID8gMHg4MCA6IDApOyBpZiAoIWhpZ2gpIHJldHVybjtcbiAgICBwYmYuYnVmW3BiZi5wb3MrK10gID0gaGlnaCAmIDB4N2YgfCAoKGhpZ2ggPj4+PSA3KSA/IDB4ODAgOiAwKTsgaWYgKCFoaWdoKSByZXR1cm47XG4gICAgcGJmLmJ1ZltwYmYucG9zKytdICA9IGhpZ2ggJiAweDdmIHwgKChoaWdoID4+Pj0gNykgPyAweDgwIDogMCk7IGlmICghaGlnaCkgcmV0dXJuO1xuICAgIHBiZi5idWZbcGJmLnBvcysrXSAgPSBoaWdoICYgMHg3ZiB8ICgoaGlnaCA+Pj49IDcpID8gMHg4MCA6IDApOyBpZiAoIWhpZ2gpIHJldHVybjtcbiAgICBwYmYuYnVmW3BiZi5wb3MrK10gID0gaGlnaCAmIDB4N2Y7XG59XG5cbmZ1bmN0aW9uIG1ha2VSb29tRm9yRXh0cmFMZW5ndGgoc3RhcnRQb3MsIGxlbiwgcGJmKSB7XG4gICAgdmFyIGV4dHJhTGVuID1cbiAgICAgICAgbGVuIDw9IDB4M2ZmZiA/IDEgOlxuICAgICAgICBsZW4gPD0gMHgxZmZmZmYgPyAyIDpcbiAgICAgICAgbGVuIDw9IDB4ZmZmZmZmZiA/IDMgOiBNYXRoLmNlaWwoTWF0aC5sb2cobGVuKSAvIChNYXRoLkxOMiAqIDcpKTtcblxuICAgIC8vIGlmIDEgYnl0ZSBpc24ndCBlbm91Z2ggZm9yIGVuY29kaW5nIG1lc3NhZ2UgbGVuZ3RoLCBzaGlmdCB0aGUgZGF0YSB0byB0aGUgcmlnaHRcbiAgICBwYmYucmVhbGxvYyhleHRyYUxlbik7XG4gICAgZm9yICh2YXIgaSA9IHBiZi5wb3MgLSAxOyBpID49IHN0YXJ0UG9zOyBpLS0pIHBiZi5idWZbaSArIGV4dHJhTGVuXSA9IHBiZi5idWZbaV07XG59XG5cbmZ1bmN0aW9uIHdyaXRlUGFja2VkVmFyaW50KGFyciwgcGJmKSAgIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHBiZi53cml0ZVZhcmludChhcnJbaV0pOyAgIH1cbmZ1bmN0aW9uIHdyaXRlUGFja2VkU1ZhcmludChhcnIsIHBiZikgIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHBiZi53cml0ZVNWYXJpbnQoYXJyW2ldKTsgIH1cbmZ1bmN0aW9uIHdyaXRlUGFja2VkRmxvYXQoYXJyLCBwYmYpICAgIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHBiZi53cml0ZUZsb2F0KGFycltpXSk7ICAgIH1cbmZ1bmN0aW9uIHdyaXRlUGFja2VkRG91YmxlKGFyciwgcGJmKSAgIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHBiZi53cml0ZURvdWJsZShhcnJbaV0pOyAgIH1cbmZ1bmN0aW9uIHdyaXRlUGFja2VkQm9vbGVhbihhcnIsIHBiZikgIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHBiZi53cml0ZUJvb2xlYW4oYXJyW2ldKTsgIH1cbmZ1bmN0aW9uIHdyaXRlUGFja2VkRml4ZWQzMihhcnIsIHBiZikgIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHBiZi53cml0ZUZpeGVkMzIoYXJyW2ldKTsgIH1cbmZ1bmN0aW9uIHdyaXRlUGFja2VkU0ZpeGVkMzIoYXJyLCBwYmYpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHBiZi53cml0ZVNGaXhlZDMyKGFycltpXSk7IH1cbmZ1bmN0aW9uIHdyaXRlUGFja2VkRml4ZWQ2NChhcnIsIHBiZikgIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHBiZi53cml0ZUZpeGVkNjQoYXJyW2ldKTsgIH1cbmZ1bmN0aW9uIHdyaXRlUGFja2VkU0ZpeGVkNjQoYXJyLCBwYmYpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHBiZi53cml0ZVNGaXhlZDY0KGFycltpXSk7IH1cblxuLy8gQnVmZmVyIGNvZGUgYmVsb3cgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlciwgTUlULWxpY2Vuc2VkXG5cbmZ1bmN0aW9uIHJlYWRVSW50MzIoYnVmLCBwb3MpIHtcbiAgICByZXR1cm4gKChidWZbcG9zXSkgfFxuICAgICAgICAoYnVmW3BvcyArIDFdIDw8IDgpIHxcbiAgICAgICAgKGJ1Zltwb3MgKyAyXSA8PCAxNikpICtcbiAgICAgICAgKGJ1Zltwb3MgKyAzXSAqIDB4MTAwMDAwMCk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlSW50MzIoYnVmLCB2YWwsIHBvcykge1xuICAgIGJ1Zltwb3NdID0gdmFsO1xuICAgIGJ1Zltwb3MgKyAxXSA9ICh2YWwgPj4+IDgpO1xuICAgIGJ1Zltwb3MgKyAyXSA9ICh2YWwgPj4+IDE2KTtcbiAgICBidWZbcG9zICsgM10gPSAodmFsID4+PiAyNCk7XG59XG5cbmZ1bmN0aW9uIHJlYWRJbnQzMihidWYsIHBvcykge1xuICAgIHJldHVybiAoKGJ1Zltwb3NdKSB8XG4gICAgICAgIChidWZbcG9zICsgMV0gPDwgOCkgfFxuICAgICAgICAoYnVmW3BvcyArIDJdIDw8IDE2KSkgK1xuICAgICAgICAoYnVmW3BvcyArIDNdIDw8IDI0KTtcbn1cblxuZnVuY3Rpb24gcmVhZFV0ZjgoYnVmLCBwb3MsIGVuZCkge1xuICAgIHZhciBzdHIgPSAnJztcbiAgICB2YXIgaSA9IHBvcztcblxuICAgIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgICAgIHZhciBiMCA9IGJ1ZltpXTtcbiAgICAgICAgdmFyIGMgPSBudWxsOyAvLyBjb2RlcG9pbnRcbiAgICAgICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPVxuICAgICAgICAgICAgYjAgPiAweEVGID8gNCA6XG4gICAgICAgICAgICBiMCA+IDB4REYgPyAzIDpcbiAgICAgICAgICAgIGIwID4gMHhCRiA/IDIgOiAxO1xuXG4gICAgICAgIGlmIChpICsgYnl0ZXNQZXJTZXF1ZW5jZSA+IGVuZCkgYnJlYWs7XG5cbiAgICAgICAgdmFyIGIxLCBiMiwgYjM7XG5cbiAgICAgICAgaWYgKGJ5dGVzUGVyU2VxdWVuY2UgPT09IDEpIHtcbiAgICAgICAgICAgIGlmIChiMCA8IDB4ODApIHtcbiAgICAgICAgICAgICAgICBjID0gYjA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoYnl0ZXNQZXJTZXF1ZW5jZSA9PT0gMikge1xuICAgICAgICAgICAgYjEgPSBidWZbaSArIDFdO1xuICAgICAgICAgICAgaWYgKChiMSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICAgICAgYyA9IChiMCAmIDB4MUYpIDw8IDB4NiB8IChiMSAmIDB4M0YpO1xuICAgICAgICAgICAgICAgIGlmIChjIDw9IDB4N0YpIHtcbiAgICAgICAgICAgICAgICAgICAgYyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzUGVyU2VxdWVuY2UgPT09IDMpIHtcbiAgICAgICAgICAgIGIxID0gYnVmW2kgKyAxXTtcbiAgICAgICAgICAgIGIyID0gYnVmW2kgKyAyXTtcbiAgICAgICAgICAgIGlmICgoYjEgJiAweEMwKSA9PT0gMHg4MCAmJiAoYjIgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgICAgIGMgPSAoYjAgJiAweEYpIDw8IDB4QyB8IChiMSAmIDB4M0YpIDw8IDB4NiB8IChiMiAmIDB4M0YpO1xuICAgICAgICAgICAgICAgIGlmIChjIDw9IDB4N0ZGIHx8IChjID49IDB4RDgwMCAmJiBjIDw9IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgICAgICAgYyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzUGVyU2VxdWVuY2UgPT09IDQpIHtcbiAgICAgICAgICAgIGIxID0gYnVmW2kgKyAxXTtcbiAgICAgICAgICAgIGIyID0gYnVmW2kgKyAyXTtcbiAgICAgICAgICAgIGIzID0gYnVmW2kgKyAzXTtcbiAgICAgICAgICAgIGlmICgoYjEgJiAweEMwKSA9PT0gMHg4MCAmJiAoYjIgJiAweEMwKSA9PT0gMHg4MCAmJiAoYjMgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgICAgIGMgPSAoYjAgJiAweEYpIDw8IDB4MTIgfCAoYjEgJiAweDNGKSA8PCAweEMgfCAoYjIgJiAweDNGKSA8PCAweDYgfCAoYjMgJiAweDNGKTtcbiAgICAgICAgICAgICAgICBpZiAoYyA8PSAweEZGRkYgfHwgYyA+PSAweDExMDAwMCkge1xuICAgICAgICAgICAgICAgICAgICBjID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgYyA9IDB4RkZGRDtcbiAgICAgICAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoYyA+IDB4RkZGRikge1xuICAgICAgICAgICAgYyAtPSAweDEwMDAwO1xuICAgICAgICAgICAgc3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMCk7XG4gICAgICAgICAgICBjID0gMHhEQzAwIHwgYyAmIDB4M0ZGO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7XG4gICAgICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3RyO1xufVxuXG5mdW5jdGlvbiB3cml0ZVV0ZjgoYnVmLCBzdHIsIHBvcykge1xuICAgIGZvciAodmFyIGkgPSAwLCBjLCBsZWFkOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKTsgLy8gY29kZSBwb2ludFxuXG4gICAgICAgIGlmIChjID4gMHhEN0ZGICYmIGMgPCAweEUwMDApIHtcbiAgICAgICAgICAgIGlmIChsZWFkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGMgPCAweERDMDApIHtcbiAgICAgICAgICAgICAgICAgICAgYnVmW3BvcysrXSA9IDB4RUY7XG4gICAgICAgICAgICAgICAgICAgIGJ1Zltwb3MrK10gPSAweEJGO1xuICAgICAgICAgICAgICAgICAgICBidWZbcG9zKytdID0gMHhCRDtcbiAgICAgICAgICAgICAgICAgICAgbGVhZCA9IGM7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGMgPSBsZWFkIC0gMHhEODAwIDw8IDEwIHwgYyAtIDB4REMwMCB8IDB4MTAwMDA7XG4gICAgICAgICAgICAgICAgICAgIGxlYWQgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGMgPiAweERCRkYgfHwgKGkgKyAxID09PSBzdHIubGVuZ3RoKSkge1xuICAgICAgICAgICAgICAgICAgICBidWZbcG9zKytdID0gMHhFRjtcbiAgICAgICAgICAgICAgICAgICAgYnVmW3BvcysrXSA9IDB4QkY7XG4gICAgICAgICAgICAgICAgICAgIGJ1Zltwb3MrK10gPSAweEJEO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxlYWQgPSBjO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChsZWFkKSB7XG4gICAgICAgICAgICBidWZbcG9zKytdID0gMHhFRjtcbiAgICAgICAgICAgIGJ1Zltwb3MrK10gPSAweEJGO1xuICAgICAgICAgICAgYnVmW3BvcysrXSA9IDB4QkQ7XG4gICAgICAgICAgICBsZWFkID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjIDwgMHg4MCkge1xuICAgICAgICAgICAgYnVmW3BvcysrXSA9IGM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoYyA8IDB4ODAwKSB7XG4gICAgICAgICAgICAgICAgYnVmW3BvcysrXSA9IGMgPj4gMHg2IHwgMHhDMDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGMgPCAweDEwMDAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1Zltwb3MrK10gPSBjID4+IDB4QyB8IDB4RTA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnVmW3BvcysrXSA9IGMgPj4gMHgxMiB8IDB4RjA7XG4gICAgICAgICAgICAgICAgICAgIGJ1Zltwb3MrK10gPSBjID4+IDB4QyAmIDB4M0YgfCAweDgwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBidWZbcG9zKytdID0gYyA+PiAweDYgJiAweDNGIHwgMHg4MDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJ1Zltwb3MrK10gPSBjICYgMHgzRiB8IDB4ODA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBvcztcbn1cbiIsIi8vYWRhcHRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2Jsb2IvNTg4NjQyMWVhOWE1YWUyNjc5N2M5NTBlYzY5OGJlNDczZmU4N2QxNy9zcmMvc3R5bGUtc3BlYy9mZWF0dXJlX2ZpbHRlci9pbmRleC5qc1xuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlRmlsdGVyO1xuXG5jb25zdCB0eXBlcyA9IFsnVW5rbm93bicsICdQb2ludCcsICdMaW5lU3RyaW5nJywgJ1BvbHlnb24nXTtcblxuLyoqXG4gKiBHaXZlbiBhIGZpbHRlciBleHByZXNzZWQgYXMgbmVzdGVkIGFycmF5cywgcmV0dXJuIGEgbmV3IGZ1bmN0aW9uXG4gKiB0aGF0IGV2YWx1YXRlcyB3aGV0aGVyIGEgZ2l2ZW4gZmVhdHVyZSAod2l0aCBhIC5wcm9wZXJ0aWVzIG9yIC50YWdzIHByb3BlcnR5KVxuICogcGFzc2VzIGl0cyB0ZXN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBmaWx0ZXIgbWFwYm94IGdsIGZpbHRlclxuICogQHJldHVybnMge0Z1bmN0aW9ufSBmaWx0ZXItZXZhbHVhdGluZyBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBjcmVhdGVGaWx0ZXIoZmlsdGVyKSB7XG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbignZicsIGB2YXIgcCA9IChmICYmIGYucHJvcGVydGllcyB8fCB7fSk7IHJldHVybiAke2NvbXBpbGUoZmlsdGVyKX1gKTtcbn1cblxuZnVuY3Rpb24gY29tcGlsZShmaWx0ZXIpIHtcbiAgICBpZiAoIWZpbHRlcikgcmV0dXJuICd0cnVlJztcbiAgICBjb25zdCBvcCA9IGZpbHRlclswXTtcbiAgICBpZiAoZmlsdGVyLmxlbmd0aCA8PSAxKSByZXR1cm4gb3AgPT09ICdhbnknID8gJ2ZhbHNlJyA6ICd0cnVlJztcbiAgICBjb25zdCBzdHIgPVxuICAgICAgICBvcCA9PT0gJz09JyA/IGNvbXBpbGVDb21wYXJpc29uT3AoZmlsdGVyWzFdLCBmaWx0ZXJbMl0sICc9PT0nLCBmYWxzZSkgOlxuICAgICAgICBvcCA9PT0gJyE9JyA/IGNvbXBpbGVDb21wYXJpc29uT3AoZmlsdGVyWzFdLCBmaWx0ZXJbMl0sICchPT0nLCBmYWxzZSkgOlxuICAgICAgICBvcCA9PT0gJzwnIHx8XG4gICAgICAgIG9wID09PSAnPicgfHxcbiAgICAgICAgb3AgPT09ICc8PScgfHxcbiAgICAgICAgb3AgPT09ICc+PScgPyBjb21waWxlQ29tcGFyaXNvbk9wKGZpbHRlclsxXSwgZmlsdGVyWzJdLCBvcCwgdHJ1ZSkgOlxuICAgICAgICBvcCA9PT0gJ349JyA/IGNvbXBpbGVSZWdleE9wKGZpbHRlclsxXSwgZmlsdGVyWzJdKSA6XG4gICAgICAgIG9wID09PSAnYW55JyA/IGNvbXBpbGVMb2dpY2FsT3AoZmlsdGVyLnNsaWNlKDEpLCAnfHwnKSA6XG4gICAgICAgIG9wID09PSAnYWxsJyA/IGNvbXBpbGVMb2dpY2FsT3AoZmlsdGVyLnNsaWNlKDEpLCAnJiYnKSA6XG4gICAgICAgIG9wID09PSAnbm9uZScgPyBjb21waWxlTmVnYXRpb24oY29tcGlsZUxvZ2ljYWxPcChmaWx0ZXIuc2xpY2UoMSksICd8fCcpKSA6XG4gICAgICAgIG9wID09PSAnaW4nID8gY29tcGlsZUluT3AoZmlsdGVyWzFdLCBmaWx0ZXIuc2xpY2UoMikpIDpcbiAgICAgICAgb3AgPT09ICchaW4nID8gY29tcGlsZU5lZ2F0aW9uKGNvbXBpbGVJbk9wKGZpbHRlclsxXSwgZmlsdGVyLnNsaWNlKDIpKSkgOlxuICAgICAgICBvcCA9PT0gJ2hhcycgPyBjb21waWxlSGFzT3AoZmlsdGVyWzFdKSA6XG4gICAgICAgIG9wID09PSAnIWhhcycgPyBjb21waWxlTmVnYXRpb24oY29tcGlsZUhhc09wKGZpbHRlclsxXSkpIDpcbiAgICAgICAgJ3RydWUnO1xuICAgIHJldHVybiBgKCR7c3RyfSlgO1xufVxuXG5mdW5jdGlvbiBjb21waWxlUHJvcGVydHlSZWZlcmVuY2UocHJvcGVydHkpIHtcbiAgICByZXR1cm4gcHJvcGVydHkgPT09ICckdHlwZScgPyAnZi50eXBlJyA6XG4gICAgICAgIHByb3BlcnR5ID09PSAnJGlkJyA/ICdmLmlkJyA6XG4gICAgICAgIGBwWyR7SlNPTi5zdHJpbmdpZnkocHJvcGVydHkpfV1gO1xufVxuXG5mdW5jdGlvbiBjb21waWxlQ29tcGFyaXNvbk9wKHByb3BlcnR5LCB2YWx1ZSwgb3AsIGNoZWNrVHlwZSkge1xuICAgIGNvbnN0IGxlZnQgPSBjb21waWxlUHJvcGVydHlSZWZlcmVuY2UocHJvcGVydHkpO1xuICAgIGNvbnN0IHJpZ2h0ID0gcHJvcGVydHkgPT09ICckdHlwZScgPyB0eXBlcy5pbmRleE9mKHZhbHVlKSA6IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICByZXR1cm4gKGNoZWNrVHlwZSA/IGB0eXBlb2YgJHtsZWZ0fT09PSB0eXBlb2YgJHtyaWdodH0mJmAgOiAnJykgKyBsZWZ0ICsgb3AgKyByaWdodDtcbn1cblxuZnVuY3Rpb24gY29tcGlsZVJlZ2V4T3AocHJvcGVydHksIHZhbHVlKSB7XG4gICAgY29uc3QgbGVmdCA9IGNvbXBpbGVQcm9wZXJ0eVJlZmVyZW5jZShwcm9wZXJ0eSk7XG4gICAgY29uc3QgcmlnaHQgPSB2YWx1ZTtcbiAgICByZXR1cm4gYCR7J2Z1bmN0aW9uKGxlZnQsIHJpZ2h0KSB7JyArXG4gICAgJ2lmKCFsZWZ0KSByZXR1cm4gZmFsc2U7IHJldHVybiBsZWZ0LnRvU3RyaW5nKCkubWF0Y2gocmlnaHQpOycgK1xuICAgICd9KCd9JHtsZWZ0fSwgJHtyaWdodH0pYDtcbn1cblxuZnVuY3Rpb24gY29tcGlsZUxvZ2ljYWxPcChleHByZXNzaW9ucywgb3ApIHtcbiAgICByZXR1cm4gZXhwcmVzc2lvbnMubWFwKGNvbXBpbGUpLmpvaW4ob3ApO1xufVxuXG5mdW5jdGlvbiBjb21waWxlSW5PcChwcm9wZXJ0eSwgdmFsdWVzKSB7XG4gICAgaWYgKHByb3BlcnR5ID09PSAnJHR5cGUnKSB2YWx1ZXMgPSB2YWx1ZXMubWFwKCh2YWx1ZSkgPT4ge1xuICAgICAgICByZXR1cm4gdHlwZXMuaW5kZXhPZih2YWx1ZSk7XG4gICAgfSk7XG4gICAgY29uc3QgbGVmdCA9IEpTT04uc3RyaW5naWZ5KHZhbHVlcy5zb3J0KGNvbXBhcmUpKTtcbiAgICBjb25zdCByaWdodCA9IGNvbXBpbGVQcm9wZXJ0eVJlZmVyZW5jZShwcm9wZXJ0eSk7XG5cbiAgICBpZiAodmFsdWVzLmxlbmd0aCA8PSAyMDApIHJldHVybiBgJHtsZWZ0fS5pbmRleE9mKCR7cmlnaHR9KSAhPT0gLTFgO1xuXG4gICAgcmV0dXJuIGAkeydmdW5jdGlvbih2LCBhLCBpLCBqKSB7JyArXG4gICAgICAgICd3aGlsZSAoaSA8PSBqKSB7IHZhciBtID0gKGkgKyBqKSA+PiAxOycgK1xuICAgICAgICAnICAgIGlmIChhW21dID09PSB2KSByZXR1cm4gdHJ1ZTsgaWYgKGFbbV0gPiB2KSBqID0gbSAtIDE7IGVsc2UgaSA9IG0gKyAxOycgK1xuICAgICAgICAnfScgK1xuICAgICdyZXR1cm4gZmFsc2U7IH0oJ30ke3JpZ2h0fSwgJHtsZWZ0fSwwLCR7dmFsdWVzLmxlbmd0aCAtIDF9KWA7XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVIYXNPcChwcm9wZXJ0eSkge1xuICAgIHJldHVybiBwcm9wZXJ0eSA9PT0gJyRpZCcgPyAnXCJpZFwiIGluIGYnIDogYCR7SlNPTi5zdHJpbmdpZnkocHJvcGVydHkpfSBpbiBwYDtcbn1cblxuZnVuY3Rpb24gY29tcGlsZU5lZ2F0aW9uKGV4cHJlc3Npb24pIHtcbiAgICByZXR1cm4gYCEoJHtleHByZXNzaW9ufSlgO1xufVxuXG4vLyBDb21wYXJpc29uIGZ1bmN0aW9uIHRvIHNvcnQgbnVtYmVycyBhbmQgc3RyaW5nc1xuZnVuY3Rpb24gY29tcGFyZShhLCBiKSB7XG4gICAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiAwO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCB2dCA9IHJlcXVpcmUoJ0BtYXBib3gvdmVjdG9yLXRpbGUnKTtcbmNvbnN0IFByb3RvYnVmID0gcmVxdWlyZSgncGJmJyk7XG5jb25zdCBHZW9KU09ORmVhdHVyZSA9IHJlcXVpcmUoJ21hcGJveC1nbC9zcmMvdXRpbC92ZWN0b3J0aWxlX3RvX2dlb2pzb24nKTtcbmNvbnN0IGZlYXR1cmVGaWx0ZXIgPSByZXF1aXJlKCcuL2ZlYXR1cmVfZmlsdGVyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gICAgcXVlcnlTb3VyY2VGZWF0dXJlcyhzb3VyY2VJRCwgcGFyYW1zLCBtYXApIHtcbiAgICAgICAgY29uc3Qgc291cmNlQ2FjaGUgPSBtYXAuc3R5bGUuc291cmNlQ2FjaGVzW3NvdXJjZUlEXTtcblxuICAgICAgICAgLy9mcm9tOiBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9ibG9iLzU4ODY0MjFlYTlhNWFlMjY3OTdjOTUwZWM2OThiZTQ3M2ZlODdkMTcvc3JjL3NvdXJjZS9xdWVyeV9mZWF0dXJlcy5qcyNMMjVcbiAgICAgICAgY29uc3QgdGlsZXMgPSBzb3VyY2VDYWNoZS5nZXRSZW5kZXJhYmxlSWRzKCkubWFwKChpZCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHNvdXJjZUNhY2hlLmdldFRpbGVCeUlEKGlkKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gW107XG5cbiAgICAgICAgY29uc3QgZGF0YVRpbGVzID0ge307XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHRpbGUgPSB0aWxlc1tpXTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGFJRCA9IHRpbGUudGlsZUlELmNhbm9uaWNhbC5rZXk7XG4gICAgICAgICAgICBpZiAoIWRhdGFUaWxlc1tkYXRhSURdKSB7XG4gICAgICAgICAgICAgICAgZGF0YVRpbGVzW2RhdGFJRF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMucXVlcnlUaWxlKHJlc3VsdCwgcGFyYW1zLCB0aWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICB9LFxuXG4gICAgcXVlcnlUaWxlKHJlc3VsdCwgcGFyYW1zLCB0aWxlKSB7XG4gICAgICAgIC8vZnJvbTogaHR0cHM6Ly9naXRodWIuY29tL21hcGJveC9tYXBib3gtZ2wtanMvYmxvYi81ODg2NDIxZWE5YTVhZTI2Nzk3Yzk1MGVjNjk4YmU0NzNmZTg3ZDE3L3NyYy9zb3VyY2UvdGlsZS5qcyNMMTc1XG4gICAgICAgIGlmICghdGlsZS5yYXdUaWxlRGF0YSkgcmV0dXJuO1xuXG4gICAgICAgIGlmICghdGlsZS52dExheWVycykge1xuICAgICAgICAgICAgdGlsZS52dExheWVycyA9IG5ldyB2dC5WZWN0b3JUaWxlKG5ldyBQcm90b2J1Zih0aWxlLnJhd1RpbGVEYXRhKSkubGF5ZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc291cmNlTGF5ZXIgPSBwYXJhbXMgPyBwYXJhbXMuc291cmNlTGF5ZXIgOiAnJztcbiAgICAgICAgY29uc3QgbGF5ZXIgPSB0aWxlLnZ0TGF5ZXJzLl9nZW9qc29uVGlsZUxheWVyIHx8IHRpbGUudnRMYXllcnNbc291cmNlTGF5ZXJdO1xuXG4gICAgICAgIGlmICghbGF5ZXIpIHJldHVybjtcblxuICAgICAgICBjb25zdCBmaWx0ZXIgPSBmZWF0dXJlRmlsdGVyKHBhcmFtcyAmJiBwYXJhbXMuZmlsdGVyKTtcbiAgICAgICAgY29uc3QgY29vcmQgPSB7IHo6IHRpbGUudGlsZUlELm92ZXJzY2FsZWRaLCB4OiB0aWxlLnRpbGVJRC5jYW5vbmljYWwueCwgeTogdGlsZS50aWxlSUQuY2Fub25pY2FsLnkgfTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxheWVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBmZWF0dXJlID0gbGF5ZXIuZmVhdHVyZShpKTtcbiAgICAgICAgICAgIGlmIChmaWx0ZXIoZmVhdHVyZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBnZW9qc29uRmVhdHVyZSA9IG5ldyBHZW9KU09ORmVhdHVyZShmZWF0dXJlLCBjb29yZC56LCBjb29yZC54LCBjb29yZC55KTtcbiAgICAgICAgICAgICAgICBnZW9qc29uRmVhdHVyZS50aWxlID0gY29vcmQ7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goZ2VvanNvbkZlYXR1cmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG59O1xuIl19