@mapbox/tilebelt
Version:
simple tile utilities
227 lines • 21.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.tileToBBOX = tileToBBOX;
exports.tileToGeoJSON = tileToGeoJSON;
exports.pointToTile = pointToTile;
exports.pointToTileFraction = pointToTileFraction;
exports.getChildren = getChildren;
exports.getParent = getParent;
exports.getSiblings = getSiblings;
exports.hasSiblings = hasSiblings;
exports.hasTile = hasTile;
exports.tilesEqual = tilesEqual;
exports.tileToQuadkey = tileToQuadkey;
exports.quadkeyToTile = quadkeyToTile;
exports.bboxToTile = bboxToTile;
const d2r = Math.PI / 180;
const r2d = 180 / Math.PI;
function tile2lon(x, z) {
return (x / Math.pow(2, z)) * 360 - 180;
}
function tile2lat(y, z) {
const n = Math.PI - (2 * Math.PI * y) / Math.pow(2, z);
return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
}
/**
* Get the bbox of a tile
*
* const bbox = tileToBBOX([5, 10, 10])
* //=bbox
*/
function tileToBBOX(tile) {
const e = tile2lon(tile[0] + 1, tile[2]);
const w = tile2lon(tile[0], tile[2]);
const s = tile2lat(tile[1] + 1, tile[2]);
const n = tile2lat(tile[1], tile[2]);
return [w, s, e, n];
}
/**
* Get a geojson representation of a tile
*
* const poly = tileToGeoJSON([5, 10, 10])
* //=poly
*/
function tileToGeoJSON(tile) {
const bbox = tileToBBOX(tile);
return {
type: 'Polygon',
coordinates: [
[
[bbox[0], bbox[3]],
[bbox[0], bbox[1]],
[bbox[2], bbox[1]],
[bbox[2], bbox[3]],
[bbox[0], bbox[3]],
],
],
};
}
/**
* Get the tile for a point at a specified zoom level
*
* const tile = pointToTile(1, 1, 20)
* //=tile
*/
function pointToTile(lon, lat, z) {
const tile = pointToTileFraction(lon, lat, z);
tile[0] = Math.floor(tile[0]);
tile[1] = Math.floor(tile[1]);
return tile;
}
/**
* Get the precise fractional tile location for a point at a zoom level
*
* const tile = pointToTileFraction(30.5, 50.5, 15)
* //=tile
*/
function pointToTileFraction(lon, lat, z) {
const sin = Math.sin(lat * d2r);
const z2 = Math.pow(2, z);
let x = z2 * (lon / 360 + 0.5);
const y = z2 * (0.5 - (0.25 * Math.log((1 + sin) / (1 - sin))) / Math.PI);
// Wrap Tile X
x = x % z2;
if (x < 0)
x = x + z2;
return [x, y, z];
}
/**
* Get the 4 tiles one zoom level higher
*
* const tiles = getChildren([5, 10, 10])
* //=tiles
*/
function getChildren(tile) {
return [
[tile[0] * 2, tile[1] * 2, tile[2] + 1],
[tile[0] * 2 + 1, tile[1] * 2, tile[2] + 1],
[tile[0] * 2 + 1, tile[1] * 2 + 1, tile[2] + 1],
[tile[0] * 2, tile[1] * 2 + 1, tile[2] + 1],
];
}
/**
* Get the tile one zoom level lower
*
* const tile = getParent([5, 10, 10])
* //=tile
*/
function getParent(tile) {
return [tile[0] >> 1, tile[1] >> 1, tile[2] - 1];
}
function getSiblings(tile) {
return getChildren(getParent(tile));
}
/**
* Get the 3 sibling tiles for a tile
*
* const tiles = getSiblings([5, 10, 10])
* //=boolean
*/
function hasSiblings(tile, tiles) {
const siblings = getSiblings(tile);
for (let i = 0; i < siblings.length; i++) {
if (!hasTile(tiles, siblings[i]))
return false;
}
return true;
}
/**
* Check to see if an array of tiles contains a particular tile
*
* const tiles = [
* [0, 0, 5],
* [0, 1, 5],
* [1, 1, 5],
* [1, 0, 5]
* ]
* hasTile(tiles, [0, 0, 5])
* //=boolean
*/
function hasTile(tiles, tile) {
for (let i = 0; i < tiles.length; i++) {
if (tilesEqual(tiles[i], tile))
return true;
}
return false;
}
/**
* Check to see if two tiles are the same
*
* tilesEqual([0, 1, 5], [0, 0, 5])
* //=boolean
*/
function tilesEqual(tile1, tile2) {
return (tile1[0] === tile2[0] && tile1[1] === tile2[1] && tile1[2] === tile2[2]);
}
/**
* Get the quadkey for a tile
*
* const quadkey = tileToQuadkey([0, 1, 5])
* //=quadkey
*/
function tileToQuadkey(tile) {
let index = '';
for (let z = tile[2]; z > 0; z--) {
let b = 0;
const mask = 1 << (z - 1);
if ((tile[0] & mask) !== 0)
b++;
if ((tile[1] & mask) !== 0)
b += 2;
index += b.toString();
}
return index;
}
/**
* Get the tile for a quadkey
*
* const tile = quadkeyToTile('00001033')
* //=tile
*/
function quadkeyToTile(quadkey) {
let x = 0;
let y = 0;
const z = quadkey.length;
for (let i = z; i > 0; i--) {
const mask = 1 << (i - 1);
const q = +quadkey[z - i];
if (q === 1)
x |= mask;
if (q === 2)
y |= mask;
if (q === 3) {
x |= mask;
y |= mask;
}
}
return [x, y, z];
}
function getBboxZoom(bbox) {
const MAX_ZOOM = 28;
for (let z = 0; z < MAX_ZOOM; z++) {
const mask = 1 << (32 - (z + 1));
if ((bbox[0] & mask) !== (bbox[2] & mask) ||
(bbox[1] & mask) !== (bbox[3] & mask)) {
return z;
}
}
return MAX_ZOOM;
}
/**
* Get the smallest tile to cover a bbox
*
* const tile = bboxToTile([ -178, 84, -177, 85 ])
* //=tile
*/
function bboxToTile(bboxCoords) {
const min = pointToTile(bboxCoords[0], bboxCoords[1], 32);
const max = pointToTile(bboxCoords[2], bboxCoords[3], 32);
const bbox = [min[0], min[1], max[0], max[1]];
const z = getBboxZoom(bbox);
if (z === 0)
return [0, 0, 0];
const x = bbox[0] >>> (32 - z);
const y = bbox[1] >>> (32 - z);
return [x, y, z];
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFzQkEsZ0NBTUM7QUFRRCxzQ0FjQztBQVFELGtDQUtDO0FBUUQsa0RBVUM7QUFRRCxrQ0FPQztBQVFELDhCQUVDO0FBRUQsa0NBRUM7QUFRRCxrQ0FNQztBQWNELDBCQUtDO0FBUUQsZ0NBSUM7QUFRRCxzQ0FVQztBQVFELHNDQWdCQztBQXVCRCxnQ0FVQztBQXBPRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQztBQUMxQixNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztBQUkxQixTQUFTLFFBQVEsQ0FBQyxDQUFTLEVBQUUsQ0FBUztJQUNwQyxPQUFPLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztBQUMxQyxDQUFDO0FBRUQsU0FBUyxRQUFRLENBQUMsQ0FBUyxFQUFFLENBQVM7SUFDcEMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3ZELE9BQU8sR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLFVBQVUsQ0FBQyxJQUFVO0lBQ25DLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMs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QU0sQ0FBQyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QixJQUFJLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQy9CLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMvQixPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNuQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBCQm94LCBHZW9tZXRyeSB9IGZyb20gJ2dlb2pzb24nO1xuXG5jb25zdCBkMnIgPSBNYXRoLlBJIC8gMTgwO1xuY29uc3QgcjJkID0gMTgwIC8gTWF0aC5QSTtcblxuZXhwb3J0IHR5cGUgVGlsZSA9IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcblxuZnVuY3Rpb24gdGlsZTJsb24oeDogbnVtYmVyLCB6OiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gKHggLyBNYXRoLnBvdygyLCB6KSkgKiAzNjAgLSAxODA7XG59XG5cbmZ1bmN0aW9uIHRpbGUybGF0KHk6IG51bWJlciwgejogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgbiA9IE1hdGguUEkgLSAoMiAqIE1hdGguUEkgKiB5KSAvIE1hdGgucG93KDIsIHopO1xuICByZXR1cm4gcjJkICogTWF0aC5hdGFuKDAuNSAqIChNYXRoLmV4cChuKSAtIE1hdGguZXhwKC1uKSkpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgYmJveCBvZiBhIHRpbGVcbiAqXG4gKiBjb25zdCBiYm94ID0gdGlsZVRvQkJPWChbNSwgMTAsIDEwXSlcbiAqIC8vPWJib3hcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRpbGVUb0JCT1godGlsZTogVGlsZSk6IEJCb3gge1xuICBjb25zdCBlID0gdGlsZTJsb24odGlsZVswXSArIDEsIHRpbGVbMl0pO1xuICBjb25zdCB3ID0gdGlsZTJsb24odGlsZVswXSwgdGlsZVsyXSk7XG4gIGNvbnN0IHMgPSB0aWxlMmxhdCh0aWxlWzFdICsgMSwgdGlsZVsyXSk7XG4gIGNvbnN0IG4gPSB0aWxlMmxhdCh0aWxlWzFdLCB0aWxlWzJdKTtcbiAgcmV0dXJuIFt3LCBzLCBlLCBuXTtcbn1cblxuLyoqXG4gKiBHZXQgYSBnZW9qc29uIHJlcHJlc2VudGF0aW9uIG9mIGEgdGlsZVxuICpcbiAqIGNvbnN0IHBvbHkgPSB0aWxlVG9HZW9KU09OKFs1LCAxMCwgMTBdKVxuICogLy89cG9seVxuICovXG5leHBvcnQgZnVuY3Rpb24gdGlsZVRvR2VvSlNPTih0aWxlOiBUaWxlKTogR2VvbWV0cnkge1xuICBjb25zdCBiYm94ID0gdGlsZVRvQkJPWCh0aWxlKTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnUG9seWdvbicsXG4gICAgY29vcmRpbmF0ZXM6IFtcbiAgICAgIFtcbiAgICAgICAgW2Jib3hbMF0sIGJib3hbM11dLFxuICAgICAgICBbYmJveFswXSwgYmJveFsxXV0sXG4gICAgICAgIFtiYm94WzJdLCBiYm94WzFdXSxcbiAgICAgICAgW2Jib3hbMl0sIGJib3hbM11dLFxuICAgICAgICBbYmJveFswXSwgYmJveFszXV0sXG4gICAgICBdLFxuICAgIF0sXG4gIH07XG59XG5cbi8qKlxuICogR2V0IHRoZSB0aWxlIGZvciBhIHBvaW50IGF0IGEgc3BlY2lmaWVkIHpvb20gbGV2ZWxcbiAqXG4gKiBjb25zdCB0aWxlID0gcG9pbnRUb1RpbGUoMSwgMSwgMjApXG4gKiAvLz10aWxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb2ludFRvVGlsZShsb246IG51bWJlciwgbGF0OiBudW1iZXIsIHo6IG51bWJlcik6IFRpbGUge1xuICBjb25zdCB0aWxlID0gcG9pbnRUb1RpbGVGcmFjdGlvbihsb24sIGxhdCwgeik7XG4gIHRpbGVbMF0gPSBNYXRoLmZsb29yKHRpbGVbMF0pO1xuICB0aWxlWzFdID0gTWF0aC5mbG9vcih0aWxlWzFdKTtcbiAgcmV0dXJuIHRpbGU7XG59XG5cbi8qKlxuICogR2V0IHRoZSBwcmVjaXNlIGZyYWN0aW9uYWwgdGlsZSBsb2NhdGlvbiBmb3IgYSBwb2ludCBhdCBhIHpvb20gbGV2ZWxcbiAqXG4gKiBjb25zdCB0aWxlID0gcG9pbnRUb1RpbGVGcmFjdGlvbigzMC41LCA1MC41LCAxNSlcbiAqIC8vPXRpbGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvaW50VG9UaWxlRnJhY3Rpb24obG9uOiBudW1iZXIsIGxhdDogbnVtYmVyLCB6OiBudW1iZXIpOiBUaWxlIHtcbiAgY29uc3Qgc2luID0gTWF0aC5zaW4obGF0ICogZDJyKTtcbiAgY29uc3QgejIgPSBNYXRoLnBvdygyLCB6KTtcbiAgbGV0IHggPSB6MiAqIChsb24gLyAzNjAgKyAwLjUpO1xuICBjb25zdCB5ID0gejIgKiAoMC41IC0gKDAuMjUgKiBNYXRoLmxvZygoMSArIHNpbikgLyAoMSAtIHNpbikpKSAvIE1hdGguUEkpO1xuXG4gIC8vIFdyYXAgVGlsZSBYXG4gIHggPSB4ICUgejI7XG4gIGlmICh4IDwgMCkgeCA9IHggKyB6MjtcbiAgcmV0dXJuIFt4LCB5LCB6XTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIDQgdGlsZXMgb25lIHpvb20gbGV2ZWwgaGlnaGVyXG4gKlxuICogY29uc3QgdGlsZXMgPSBnZXRDaGlsZHJlbihbNSwgMTAsIDEwXSlcbiAqIC8vPXRpbGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGlsZHJlbih0aWxlOiBUaWxlKTogVGlsZVtdIHtcbiAgcmV0dXJuIFtcbiAgICBbdGlsZVswXSAqIDIsIHRpbGVbMV0gKiAyLCB0aWxlWzJdICsgMV0sXG4gICAgW3RpbGVbMF0gKiAyICsgMSwgdGlsZVsxXSAqIDIsIHRpbGVbMl0gKyAxXSxcbiAgICBbdGlsZVswXSAqIDIgKyAxLCB0aWxlWzFdICogMiArIDEsIHRpbGVbMl0gKyAxXSxcbiAgICBbdGlsZVswXSAqIDIsIHRpbGVbMV0gKiAyICsgMSwgdGlsZVsyXSArIDFdLFxuICBdO1xufVxuXG4vKipcbiAqIEdldCB0aGUgdGlsZSBvbmUgem9vbSBsZXZlbCBsb3dlclxuICpcbiAqIGNvbnN0IHRpbGUgPSBnZXRQYXJlbnQoWzUsIDEwLCAxMF0pXG4gKiAvLz10aWxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYXJlbnQodGlsZTogVGlsZSk6IFRpbGUge1xuICByZXR1cm4gW3RpbGVbMF0gPj4gMSwgdGlsZVsxXSA+PiAxLCB0aWxlWzJdIC0gMV07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTaWJsaW5ncyh0aWxlOiBUaWxlKTogVGlsZVtdIHtcbiAgcmV0dXJuIGdldENoaWxkcmVuKGdldFBhcmVudCh0aWxlKSk7XG59XG5cbi8qKlxuICogR2V0IHRoZSAzIHNpYmxpbmcgdGlsZXMgZm9yIGEgdGlsZVxuICpcbiAqIGNvbnN0IHRpbGVzID0gZ2V0U2libGluZ3MoWzUsIDEwLCAxMF0pXG4gKiAvLz1ib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNTaWJsaW5ncyh0aWxlOiBUaWxlLCB0aWxlczogVGlsZVtdKTogYm9vbGVhbiB7XG4gIGNvbnN0IHNpYmxpbmdzID0gZ2V0U2libGluZ3ModGlsZSk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2libGluZ3MubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIWhhc1RpbGUodGlsZXMsIHNpYmxpbmdzW2ldKSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIENoZWNrIHRvIHNlZSBpZiBhbiBhcnJheSBvZiB0aWxlcyBjb250YWlucyBhIHBhcnRpY3VsYXIgdGlsZVxuICpcbiAqIGNvbnN0IHRpbGVzID0gW1xuICogICAgIFswLCAwLCA1XSxcbiAqICAgICBbMCwgMSwgNV0sXG4gKiAgICAgWzEsIDEsIDVdLFxuICogICAgIFsxLCAwLCA1XVxuICogXVxuICogaGFzVGlsZSh0aWxlcywgWzAsIDAsIDVdKVxuICogLy89Ym9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzVGlsZSh0aWxlczogVGlsZVtdLCB0aWxlOiBUaWxlKTogYm9vbGVhbiB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdGlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAodGlsZXNFcXVhbCh0aWxlc1tpXSwgdGlsZSkpIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDaGVjayB0byBzZWUgaWYgdHdvIHRpbGVzIGFyZSB0aGUgc2FtZVxuICpcbiAqIHRpbGVzRXF1YWwoWzAsIDEsIDVdLCBbMCwgMCwgNV0pXG4gKiAvLz1ib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0aWxlc0VxdWFsKHRpbGUxOiBUaWxlLCB0aWxlMjogVGlsZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIHRpbGUxWzBdID09PSB0aWxlMlswXSAmJiB0aWxlMVsxXSA9PT0gdGlsZTJbMV0gJiYgdGlsZTFbMl0gPT09IHRpbGUyWzJdXG4gICk7XG59XG5cbi8qKlxuICogR2V0IHRoZSBxdWFka2V5IGZvciBhIHRpbGVcbiAqXG4gKiBjb25zdCBxdWFka2V5ID0gdGlsZVRvUXVhZGtleShbMCwgMSwgNV0pXG4gKiAvLz1xdWFka2V5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0aWxlVG9RdWFka2V5KHRpbGU6IFRpbGUpOiBzdHJpbmcge1xuICBsZXQgaW5kZXggPSAnJztcbiAgZm9yIChsZXQgeiA9IHRpbGVbMl07IHogPiAwOyB6LS0pIHtcbiAgICBsZXQgYiA9IDA7XG4gICAgY29uc3QgbWFzayA9IDEgPDwgKHogLSAxKTtcbiAgICBpZiAoKHRpbGVbMF0gJiBtYXNrKSAhPT0gMCkgYisrO1xuICAgIGlmICgodGlsZVsxXSAmIG1hc2spICE9PSAwKSBiICs9IDI7XG4gICAgaW5kZXggKz0gYi50b1N0cmluZygpO1xuICB9XG4gIHJldHVybiBpbmRleDtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHRpbGUgZm9yIGEgcXVhZGtleVxuICpcbiAqIGNvbnN0IHRpbGUgPSBxdWFka2V5VG9UaWxlKCcwMDAwMTAzMycpXG4gKiAvLz10aWxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBxdWFka2V5VG9UaWxlKHF1YWRrZXk6IHN0cmluZyk6IFRpbGUge1xuICBsZXQgeCA9IDA7XG4gIGxldCB5ID0gMDtcbiAgY29uc3QgeiA9IHF1YWRrZXkubGVuZ3RoO1xuXG4gIGZvciAobGV0IGkgPSB6OyBpID4gMDsgaS0tKSB7XG4gICAgY29uc3QgbWFzayA9IDEgPDwgKGkgLSAxKTtcbiAgICBjb25zdCBxID0gK3F1YWRrZXlbeiAtIGldO1xuICAgIGlmIChxID09PSAxKSB4IHw9IG1hc2s7XG4gICAgaWYgKHEgPT09IDIpIHkgfD0gbWFzaztcbiAgICBpZiAocSA9PT0gMykge1xuICAgICAgeCB8PSBtYXNrO1xuICAgICAgeSB8PSBtYXNrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gW3gsIHksIHpdO1xufVxuXG5mdW5jdGlvbiBnZXRCYm94Wm9vbShiYm94OiBCQm94KTogbnVtYmVyIHtcbiAgY29uc3QgTUFYX1pPT00gPSAyODtcbiAgZm9yIChsZXQgeiA9IDA7IHogPCBNQVhfWk9PTTsgeisrKSB7XG4gICAgY29uc3QgbWFzayA9IDEgPDwgKDMyIC0gKHogKyAxKSk7XG4gICAgaWYgKFxuICAgICAgKGJib3hbMF0gJiBtYXNrKSAhPT0gKGJib3hbMl0gJiBtYXNrKSB8fFxuICAgICAgKGJib3hbMV0gJiBtYXNrKSAhPT0gKGJib3hbM10gJiBtYXNrKVxuICAgICkge1xuICAgICAgcmV0dXJuIHo7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIE1BWF9aT09NO1xufVxuXG4vKipcbiAqIEdldCB0aGUgc21hbGxlc3QgdGlsZSB0byBjb3ZlciBhIGJib3hcbiAqXG4gKiBjb25zdCB0aWxlID0gYmJveFRvVGlsZShbIC0xNzgsIDg0LCAtMTc3LCA4NSBdKVxuICogLy89dGlsZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYmJveFRvVGlsZShiYm94Q29vcmRzOiBCQm94KTogVGlsZSB7XG4gIGNvbnN0IG1pbiA9IHBvaW50VG9UaWxlKGJib3hDb29yZHNbMF0sIGJib3hDb29yZHNbMV0sIDMyKTtcbiAgY29uc3QgbWF4ID0gcG9pbnRUb1RpbGUoYmJveENvb3Jkc1syXSwgYmJveENvb3Jkc1szXSwgMzIpO1xuICBjb25zdCBiYm94OiBCQm94ID0gW21pblswXSwgbWluWzFdLCBtYXhbMF0sIG1heFsxXV07XG5cbiAgY29uc3QgeiA9IGdldEJib3hab29tKGJib3gpO1xuICBpZiAoeiA9PT0gMCkgcmV0dXJuIFswLCAwLCAwXTtcbiAgY29uc3QgeCA9IGJib3hbMF0gPj4+ICgzMiAtIHopO1xuICBjb25zdCB5ID0gYmJveFsxXSA+Pj4gKDMyIC0geik7XG4gIHJldHVybiBbeCwgeSwgel07XG59XG4iXX0=