kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
297 lines (234 loc) • 31.9 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isMSEdge = isMSEdge;
exports.getScaleFromImageSize = getScaleFromImageSize;
exports.calculateExportImageSize = calculateExportImageSize;
exports.convertToPng = convertToPng;
exports.dataURItoBlob = dataURItoBlob;
exports.downloadFile = downloadFile;
exports.exportImage = exportImage;
exports.exportToJsonString = exportToJsonString;
exports.getMapJSON = getMapJSON;
exports.exportJson = exportJson;
exports.exportHtml = exportHtml;
exports.exportData = exportData;
exports.exportMap = exportMap;
exports["default"] = exports.DEFAULT_EXPORT_JSON_SETTINGS = exports.DEFAULT_DATA_NAME = exports.DEFAULT_JSON_NAME = exports.DEFAULT_HTML_NAME = exports.DEFAULT_IMAGE_NAME = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _domToImage = _interopRequireDefault(require("./dom-to-image"));
var _window = require("global/window");
var _defaultSettings = require("../constants/default-settings");
var _exportMapHtml = require("../templates/export-map-html");
var _dataProcessor = require("../processors/data-processor");
var _lodash = _interopRequireDefault(require("lodash.get"));
var _utils = require("./utils");
var _dataContainerUtils = require("./table-utils/data-container-utils");
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
/**
* Default file names
*/
var DEFAULT_IMAGE_NAME = 'kepler.gl.png';
exports.DEFAULT_IMAGE_NAME = DEFAULT_IMAGE_NAME;
var DEFAULT_HTML_NAME = 'kepler.gl.html';
exports.DEFAULT_HTML_NAME = DEFAULT_HTML_NAME;
var DEFAULT_JSON_NAME = 'kepler.gl.json';
exports.DEFAULT_JSON_NAME = DEFAULT_JSON_NAME;
var DEFAULT_DATA_NAME = 'kepler.gl';
/**
* Default json export settings
* @type {{hasData: boolean}}
*/
exports.DEFAULT_DATA_NAME = DEFAULT_DATA_NAME;
var DEFAULT_EXPORT_JSON_SETTINGS = {
hasData: true
};
exports.DEFAULT_EXPORT_JSON_SETTINGS = DEFAULT_EXPORT_JSON_SETTINGS;
var defaultResolution = _defaultSettings.EXPORT_IMG_RESOLUTION_OPTIONS.find(function (op) {
return op.id === _defaultSettings.RESOLUTIONS.ONE_X;
});
var defaultRatio = _defaultSettings.EXPORT_IMG_RATIO_OPTIONS.find(function (op) {
return op.id === _defaultSettings.EXPORT_IMG_RATIOS.FOUR_BY_THREE;
});
function isMSEdge(window) {
return Boolean(window.navigator && window.navigator.msSaveOrOpenBlob);
}
function getScaleFromImageSize() {
var imageW = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var imageH = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var mapW = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var mapH = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
if ([imageW, imageH, mapW, mapH].some(function (d) {
return d <= 0;
})) {
return 1;
}
var base = imageW / imageH > 1 ? imageW : imageH;
var mapBase = imageW / imageH > 1 ? mapW : mapH;
return base / mapBase;
}
function calculateExportImageSize(_ref) {
var mapW = _ref.mapW,
mapH = _ref.mapH,
ratio = _ref.ratio,
resolution = _ref.resolution;
if (mapW <= 0 || mapH <= 0) {
return null;
}
var ratioItem = _defaultSettings.EXPORT_IMG_RATIO_OPTIONS.find(function (op) {
return op.id === ratio;
}) || defaultRatio;
var resolutionItem = _defaultSettings.EXPORT_IMG_RESOLUTION_OPTIONS.find(function (op) {
return op.id === resolution;
}) || defaultResolution;
var _resolutionItem$getSi = resolutionItem.getSize(mapW, mapH),
scaledWidth = _resolutionItem$getSi.width,
scaledHeight = _resolutionItem$getSi.height;
var _ratioItem$getSize = ratioItem.getSize(scaledWidth, scaledHeight),
imageW = _ratioItem$getSize.width,
imageH = _ratioItem$getSize.height;
var _ref2 = ratioItem.id === _defaultSettings.EXPORT_IMG_RATIOS.CUSTOM ? {} : resolutionItem,
scale = _ref2.scale;
return {
scale: scale,
imageW: imageW,
imageH: imageH
};
}
function convertToPng(sourceElem, options) {
return _domToImage["default"].toPng(sourceElem, options);
}
function dataURItoBlob(dataURI) {
var binary = (0, _window.atob)(dataURI.split(',')[1]); // separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // write the bytes of the string to an ArrayBuffer
var ab = new _window.ArrayBuffer(binary.length); // create a view into the buffer
var ia = new _window.Uint8Array(ab);
for (var i = 0; i < binary.length; i++) {
ia[i] = binary.charCodeAt(i);
}
return new _window.Blob([ab], {
type: mimeString
});
}
function downloadFile(fileBlob, fileName) {
if (isMSEdge(window)) {
window.navigator.msSaveOrOpenBlob(fileBlob, fileName);
} else {
var url = _window.URL.createObjectURL(fileBlob);
var link = _window.document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('download', fileName);
_window.document.body.appendChild(link);
link.click();
_window.document.body.removeChild(link);
_window.URL.revokeObjectURL(url);
}
}
function exportImage(state) {
var filename = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_IMAGE_NAME;
var imageDataUri = state.uiState.exportImage.imageDataUri;
if (imageDataUri) {
var file = dataURItoBlob(imageDataUri);
downloadFile(file, filename);
}
}
function exportToJsonString(data) {
try {
return JSON.stringify(data);
} catch (e) {
return e.description;
}
}
function getMapJSON(state) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_EXPORT_JSON_SETTINGS;
var hasData = options.hasData;
var schema = state.visState.schema;
if (!hasData) {
return schema.getConfigToSave(state);
}
var mapToSave = schema.save(state); // add file name if title is not provided
var title = (0, _lodash["default"])(mapToSave, ['info', 'title']);
if (!title || !title.length) {
mapToSave = (0, _utils.set)(['info', 'title'], "keplergl_".concat((0, _utils.generateHashId)(6)), mapToSave);
}
return mapToSave;
}
function exportJson(state) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var map = getMapJSON(state, options);
var fileBlob = new _window.Blob([exportToJsonString(map)], {
type: 'application/json'
});
var fileName = state.appName ? "".concat(state.appName, ".json") : DEFAULT_JSON_NAME;
downloadFile(fileBlob, fileName);
}
function exportHtml(state, options) {
var userMapboxToken = options.userMapboxToken,
exportMapboxAccessToken = options.exportMapboxAccessToken,
mode = options.mode;
var data = _objectSpread(_objectSpread({}, getMapJSON(state)), {}, {
mapboxApiAccessToken: (userMapboxToken || '') !== '' ? userMapboxToken : exportMapboxAccessToken,
mode: mode
});
var fileBlob = new _window.Blob([(0, _exportMapHtml.exportMapToHTML)(data)], {
type: 'text/html'
});
downloadFile(fileBlob, state.appName ? "".concat(state.appName, ".html") : DEFAULT_HTML_NAME);
}
function exportData(state, option) {
var visState = state.visState,
appName = state.appName;
var datasets = visState.datasets;
var selectedDataset = option.selectedDataset,
dataType = option.dataType,
filtered = option.filtered; // get the selected data
var filename = appName ? appName : DEFAULT_DATA_NAME;
var selectedDatasets = datasets[selectedDataset] ? [datasets[selectedDataset]] : Object.values(datasets);
if (!selectedDatasets.length) {
// error: selected dataset not found.
return;
}
selectedDatasets.forEach(function (selectedData) {
var dataContainer = selectedData.dataContainer,
fields = selectedData.fields,
label = selectedData.label,
_selectedData$filtere = selectedData.filteredIdxCPU,
filteredIdxCPU = _selectedData$filtere === void 0 ? [] : _selectedData$filtere;
var toExport = filtered ? (0, _dataContainerUtils.createIndexedDataContainer)(dataContainer, filteredIdxCPU) : dataContainer; // start to export data according to selected data type
switch (dataType) {
case _defaultSettings.EXPORT_DATA_TYPE.CSV:
{
var csv = (0, _dataProcessor.formatCsv)(toExport, fields);
var fileBlob = new _window.Blob([csv], {
type: 'text/csv'
});
downloadFile(fileBlob, "".concat(filename, "_").concat(label, ".csv"));
break;
}
// TODO: support more file types.
default:
break;
}
});
}
function exportMap(state, option) {
var imageDataUri = state.uiState.exportImage.imageDataUri;
var thumbnail = imageDataUri ? dataURItoBlob(imageDataUri) : null;
var mapToSave = getMapJSON(state, option);
return {
map: mapToSave,
thumbnail: thumbnail
};
}
var exporters = {
exportImage: exportImage,
exportJson: exportJson,
exportHtml: exportHtml,
exportData: exportData
};
var _default = exporters;
exports["default"] = _default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9leHBvcnQtdXRpbHMuanMiXSwibmFtZXMiOlsiREVGQVVMVF9JTUFHRV9OQU1FIiwiREVGQVVMVF9IVE1MX05BTUUiLCJERUZBVUxUX0pTT05fTkFNRSIsIkRFRkFVTFRfREFUQV9OQU1FIiwiREVGQVVMVF9FWFBPUlRfSlNPTl9TRVRUSU5HUyIsImhhc0RhdGEiLCJkZWZhdWx0UmVzb2x1dGlvbiIsIkVYUE9SVF9JTUdfUkVTT0xVVElPTl9PUFRJT05TIiwiZmluZCIsIm9wIiwiaWQiLCJSRVNPTFVUSU9OUyIsIk9ORV9YIiwiZGVmYXVsdFJhdGlvIiwiRVhQT1JUX0lNR19SQVRJT19PUFRJT05TIiwiRVhQT1JUX0lNR19SQVRJT1MiLCJGT1VSX0JZX1RIUkVFIiwiaXNNU0VkZ2UiLCJ3aW5kb3ciLCJCb29sZWFuIiwibmF2aWdhdG9yIiwibXNTYXZlT3JPcGVuQmxvYiIsImdldFNjYWxlRnJvbUltYWdlU2l6ZSIsImltYWdlVyIsImltYWdlSCIsIm1hcFciLCJtYXBIIiwic29tZSIsImQiLCJiYXNlIiwibWFwQmFzZSIsImNhbGN1bGF0ZUV4cG9ydEltYWdlU2l6ZSIsInJhdGlvIiwicmVzb2x1dGlvbiIsInJhdGlvSXRlbSIsInJlc29sdXRpb25JdGVtIiwiZ2V0U2l6ZSIsInNjYWxlZFdpZHRoIiwid2lkdGgiLCJzY2FsZWRIZWlnaHQiLCJoZWlnaHQiLCJDVVNUT00iLCJzY2FsZSIsImNvbnZlcnRUb1BuZyIsInNvdXJjZUVsZW0iLCJvcHRpb25zIiwiZG9tdG9pbWFnZSIsInRvUG5nIiwiZGF0YVVSSXRvQmxvYiIsImRhdGFVUkkiLCJiaW5hcnkiLCJzcGxpdCIsIm1pbWVTdHJpbmciLCJhYiIsIkFycmF5QnVmZmVyIiwibGVuZ3RoIiwiaWEiLCJVaW50OEFycmF5IiwiaSIsImNoYXJDb2RlQXQiLCJCbG9iIiwidHlwZSIsImRvd25sb2FkRmlsZSIsImZpbGVCbG9iIiwiZmlsZU5hbWUiLCJ1cmwiLCJVUkwiLCJjcmVhdGVPYmplY3RVUkwiLCJsaW5rIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50Iiwic2V0QXR0cmlidXRlIiwiYm9keSIsImFwcGVuZENoaWxkIiwiY2xpY2siLCJyZW1vdmVDaGlsZCIsInJldm9rZU9iamVjdFVSTCIsImV4cG9ydEltYWdlIiwic3RhdGUiLCJmaWxlbmFtZSIsImltYWdlRGF0YVVyaSIsInVpU3RhdGUiLCJmaWxlIiwiZXhwb3J0VG9Kc29uU3RyaW5nIiwiZGF0YSIsIkpTT04iLCJzdHJpbmdpZnkiLCJlIiwiZGVzY3JpcHRpb24iLCJnZXRNYXBKU09OIiwic2NoZW1hIiwidmlzU3RhdGUiLCJnZXRDb25maWdUb1NhdmUiLCJtYXBUb1NhdmUiLCJzYXZlIiwidGl0bGUiLCJleHBvcnRKc29uIiwibWFwIiwiYXBwTmFtZSIsImV4cG9ydEh0bWwiLCJ1c2VyTWFwYm94VG9rZW4iLCJleHBvcnRNYXBib3hBY2Nlc3NUb2tlbiIsIm1vZGUiLCJtYXBib3hBcGlBY2Nlc3NUb2tlbiIsImV4cG9ydERhdGEiLCJvcHRpb24iLCJkYXRhc2V0cyIsInNlbGVjdGVkRGF0YXNldCIsImRhdGFUeXBlIiwiZmlsdGVyZWQiLCJzZWxlY3RlZERhdGFzZXRzIiwiT2JqZWN0IiwidmFsdWVzIiwiZm9yRWFjaCIsInNlbGVjdGVkRGF0YSIsImRhdGFDb250YWluZXIiLCJmaWVsZHMiLCJsYWJlbCIsImZpbHRlcmVkSWR4Q1BVIiwidG9FeHBvcnQiLCJFWFBPUlRfREFUQV9UWVBFIiwiQ1NWIiwiY3N2IiwiZXhwb3J0TWFwIiwidGh1bWJuYWlsIiwiZXhwb3J0ZXJzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFxQkE7O0FBQ0E7O0FBQ0E7O0FBT0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7Ozs7OztBQUVBO0FBQ0E7QUFDQTtBQUNPLElBQU1BLGtCQUFrQixHQUFHLGVBQTNCOztBQUNBLElBQU1DLGlCQUFpQixHQUFHLGdCQUExQjs7QUFDQSxJQUFNQyxpQkFBaUIsR0FBRyxn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Q0U7QUFWSjtBQVlELEdBbkJEO0FBb0JEOztBQUVNLFNBQVNNLFNBQVQsQ0FBbUI3QyxLQUFuQixFQUEwQjJCLE1BQTFCLEVBQWtDO0FBQUEsTUFDaEN6QixZQURnQyxHQUNoQkYsS0FBSyxDQUFDRyxPQUFOLENBQWNKLFdBREUsQ0FDaENHLFlBRGdDO0FBRXZDLE1BQU00QyxTQUFTLEdBQUc1QyxZQUFZLEdBQUdoQyxhQUFhLENBQUNnQyxZQUFELENBQWhCLEdBQWlDLElBQS9EO0FBQ0EsTUFBTWEsU0FBUyxHQUFHSixVQUFVLENBQUNYLEtBQUQsRUFBUTJCLE1BQVIsQ0FBNUI7QUFFQSxTQUFPO0FBQ0xSLElBQUFBLEdBQUcsRUFBRUosU0FEQTtBQUVMK0IsSUFBQUEsU0FBUyxFQUFUQTtBQUZLLEdBQVA7QUFJRDs7QUFFRCxJQUFNQyxTQUFTLEdBQUc7QUFDaEJoRCxFQUFBQSxXQUFXLEVBQVhBLFdBRGdCO0FBRWhCbUIsRUFBQUEsVUFBVSxFQUFWQSxVQUZnQjtBQUdoQkcsRUFBQUEsVUFBVSxFQUFWQSxVQUhnQjtBQUloQkssRUFBQUEsVUFBVSxFQUFWQTtBQUpnQixDQUFsQjtlQU9lcUIsUyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMSBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbi8vIEB0cy1ub2NoZWNrXG5pbXBvcnQgZG9tdG9pbWFnZSBmcm9tICd1dGlscy9kb20tdG8taW1hZ2UnO1xuaW1wb3J0IHtCbG9iLCBVUkwsIGF0b2IsIFVpbnQ4QXJyYXksIEFycmF5QnVmZmVyLCBkb2N1bWVudH0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5pbXBvcnQge1xuICBFWFBPUlRfSU1HX1JFU09MVVRJT05fT1BUSU9OUyxcbiAgRVhQT1JUX0lNR19SQVRJT19PUFRJT05TLFxuICBSRVNPTFVUSU9OUyxcbiAgRVhQT1JUX0lNR19SQVRJT1MsXG4gIEVYUE9SVF9EQVRBX1RZUEVcbn0gZnJvbSAnY29uc3RhbnRzL2RlZmF1bHQtc2V0dGluZ3MnO1xuaW1wb3J0IHtleHBvcnRNYXBUb0hUTUx9IGZyb20gJ3RlbXBsYXRlcy9leHBvcnQtbWFwLWh0bWwnO1xuaW1wb3J0IHtmb3JtYXRDc3Z9IGZyb20gJ3Byb2Nlc3NvcnMvZGF0YS1wcm9jZXNzb3InO1xuaW1wb3J0IGdldCBmcm9tICdsb2Rhc2guZ2V0JztcbmltcG9ydCB7c2V0LCBnZW5lcmF0ZUhhc2hJZH0gZnJvbSAndXRpbHMvdXRpbHMnO1xuXG5pbXBvcnQge2NyZWF0ZUluZGV4ZWREYXRhQ29udGFpbmVyfSBmcm9tICcuL3RhYmxlLXV0aWxzL2RhdGEtY29udGFpbmVyLXV0aWxzJztcblxuLyoqXG4gKiBEZWZhdWx0IGZpbGUgbmFtZXNcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfSU1BR0VfTkFNRSA9ICdrZXBsZXIuZ2wucG5nJztcbmV4cG9ydCBjb25zdCBERUZBVUxUX0hUTUxfTkFNRSA9ICdrZXBsZXIuZ2wuaHRtbCc7XG5leHBvcnQgY29uc3QgREVGQVVMVF9KU09OX05BTUUgPSAna2VwbGVyLmdsLmpzb24nO1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfREFUQV9OQU1FID0gJ2tlcGxlci5nbCc7XG5cbi8qKlxuICogRGVmYXVsdCBqc29uIGV4cG9ydCBzZXR0aW5nc1xuICogQHR5cGUge3toYXNEYXRhOiBib29sZWFufX1cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRVhQT1JUX0pTT05fU0VUVElOR1MgPSB7XG4gIGhhc0RhdGE6IHRydWVcbn07XG5cbmNvbnN0IGRlZmF1bHRSZXNvbHV0aW9uID0gRVhQT1JUX0lNR19SRVNPTFVUSU9OX09QVElPTlMuZmluZChvcCA9PiBvcC5pZCA9PT0gUkVTT0xVVElPTlMuT05FX1gpO1xuXG5jb25zdCBkZWZhdWx0UmF0aW8gPSBFWFBPUlRfSU1HX1JBVElPX09QVElPTlMuZmluZChvcCA9PiBvcC5pZCA9PT0gRVhQT1JUX0lNR19SQVRJT1MuRk9VUl9CWV9USFJFRSk7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc01TRWRnZSh3aW5kb3cpIHtcbiAgcmV0dXJuIEJvb2xlYW4od2luZG93Lm5hdmlnYXRvciAmJiB3aW5kb3cubmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2NhbGVGcm9tSW1hZ2VTaXplKGltYWdlVyA9IDAsIGltYWdlSCA9IDAsIG1hcFcgPSAwLCBtYXBIID0gMCkge1xuICBpZiAoW2ltYWdlVywgaW1hZ2VILCBtYXBXLCBtYXBIXS5zb21lKGQgPT4gZCA8PSAwKSkge1xuICAgIHJldHVybiAxO1xuICB9XG5cbiAgY29uc3QgYmFzZSA9IGltYWdlVyAvIGltYWdlSCA+IDEgPyBpbWFnZVcgOiBpbWFnZUg7XG4gIGNvbnN0IG1hcEJhc2UgPSBpbWFnZVcgLyBpbWFnZUggPiAxID8gbWFwVyA6IG1hcEg7XG4gIHJldHVybiBiYXNlIC8gbWFwQmFzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUV4cG9ydEltYWdlU2l6ZSh7bWFwVywgbWFwSCwgcmF0aW8sIHJlc29sdXRpb259KSB7XG4gIGlmIChtYXBXIDw9IDAgfHwgbWFwSCA8PSAwKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCByYXRpb0l0ZW0gPSBFWFBPUlRfSU1HX1JBVElPX09QVElPTlMuZmluZChvcCA9PiBvcC5pZCA9PT0gcmF0aW8pIHx8IGRlZmF1bHRSYXRpbztcblxuICBjb25zdCByZXNvbHV0aW9uSXRlbSA9XG4gICAgRVhQT1JUX0lNR19SRVNPTFVUSU9OX09QVElPTlMuZmluZChvcCA9PiBvcC5pZCA9PT0gcmVzb2x1dGlvbikgfHwgZGVmYXVsdFJlc29sdXRpb247XG5cbiAgY29uc3Qge3dpZHRoOiBzY2FsZWRXaWR0aCwgaGVpZ2h0OiBzY2FsZWRIZWlnaHR9ID0gcmVzb2x1dGlvbkl0ZW0uZ2V0U2l6ZShtYXBXLCBtYXBIKTtcblxuICBjb25zdCB7d2lkdGg6IGltYWdlVywgaGVpZ2h0OiBpbWFnZUh9ID0gcmF0aW9JdGVtLmdldFNpemUoc2NhbGVkV2lkdGgsIHNjYWxlZEhlaWdodCk7XG5cbiAgY29uc3Qge3NjYWxlfSA9IHJhdGlvSXRlbS5pZCA9PT0gRVhQT1JUX0lNR19SQVRJT1MuQ1VTVE9NID8ge30gOiByZXNvbHV0aW9uSXRlbTtcblxuICByZXR1cm4ge1xuICAgIHNjYWxlLFxuICAgIGltYWdlVyxcbiAgICBpbWFnZUhcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRUb1BuZyhzb3VyY2VFbGVtLCBvcHRpb25zKSB7XG4gIHJldHVybiBkb210b2ltYWdlLnRvUG5nKHNvdXJjZUVsZW0sIG9wdGlvbnMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGF0YVVSSXRvQmxvYihkYXRhVVJJKSB7XG4gIGNvbnN0IGJpbmFyeSA9IGF0b2IoZGF0YVVSSS5zcGxpdCgnLCcpWzFdKTtcblxuICAvLyBzZXBhcmF0ZSBvdXQgdGhlIG1pbWUgY29tcG9uZW50XG4gIGNvbnN0IG1pbWVTdHJpbmcgPSBkYXRhVVJJXG4gICAgLnNwbGl0KCcsJylbMF1cbiAgICAuc3BsaXQoJzonKVsxXVxuICAgIC5zcGxpdCgnOycpWzBdO1xuXG4gIC8vIHdyaXRlIHRoZSBieXRlcyBvZiB0aGUgc3RyaW5nIHRvIGFuIEFycmF5QnVmZmVyXG4gIGNvbnN0IGFiID0gbmV3IEFycmF5QnVmZmVyKGJpbmFyeS5sZW5ndGgpO1xuXG4gIC8vIGNyZWF0ZSBhIHZpZXcgaW50byB0aGUgYnVmZmVyXG4gIGNvbnN0IGlhID0gbmV3IFVpbnQ4QXJyYXkoYWIpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYmluYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWFbaV0gPSBiaW5hcnkuY2hhckNvZGVBdChpKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgQmxvYihbYWJdLCB7dHlwZTogbWltZVN0cmluZ30pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZG93bmxvYWRGaWxlKGZpbGVCbG9iLCBmaWxlTmFtZSkge1xuICBpZiAoaXNNU0VkZ2Uod2luZG93KSkge1xuICAgIHdpbmRvdy5uYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYihmaWxlQmxvYiwgZmlsZU5hbWUpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZUJsb2IpO1xuXG4gICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBsaW5rLnNldEF0dHJpYnV0ZSgnaHJlZicsIHVybCk7XG4gICAgbGluay5zZXRBdHRyaWJ1dGUoJ2Rvd25sb2FkJywgZmlsZU5hbWUpO1xuXG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChsaW5rKTtcbiAgICBsaW5rLmNsaWNrKCk7XG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChsaW5rKTtcbiAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cG9ydEltYWdlKHN0YXRlLCBmaWxlbmFtZSA9IERFRkFVTFRfSU1BR0VfTkFNRSkge1xuICBjb25zdCB7aW1hZ2VEYXRhVXJpfSA9IHN0YXRlLnVpU3RhdGUuZXhwb3J0SW1hZ2U7XG4gIGlmIChpbWFnZURhdGFVcmkpIHtcbiAgICBjb25zdCBmaWxlID0gZGF0YVVSSXRvQmxvYihpbWFnZURhdGFVcmkpO1xuICAgIGRvd25sb2FkRmlsZShmaWxlLCBmaWxlbmFtZSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cG9ydFRvSnNvblN0cmluZyhkYXRhKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGUuZGVzY3JpcHRpb247XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1hcEpTT04oc3RhdGUsIG9wdGlvbnMgPSBERUZBVUxUX0VYUE9SVF9KU09OX1NFVFRJTkdTKSB7XG4gIGNvbnN0IHtoYXNEYXRhfSA9IG9wdGlvbnM7XG4gIGNvbnN0IHNjaGVtYSA9IHN0YXRlLnZpc1N0YXRlLnNjaGVtYTtcblxuICBpZiAoIWhhc0RhdGEpIHtcbiAgICByZXR1cm4gc2NoZW1hLmdldENvbmZpZ1RvU2F2ZShzdGF0ZSk7XG4gIH1cblxuICBsZXQgbWFwVG9TYXZlID0gc2NoZW1hLnNhdmUoc3RhdGUpO1xuICAvLyBhZGQgZmlsZSBuYW1lIGlmIHRpdGxlIGlzIG5vdCBwcm92aWRlZFxuICBjb25zdCB0aXRsZSA9IGdldChtYXBUb1NhdmUsIFsnaW5mbycsICd0aXRsZSddKTtcbiAgaWYgKCF0aXRsZSB8fCAhdGl0bGUubGVuZ3RoKSB7XG4gICAgbWFwVG9TYXZlID0gc2V0KFsnaW5mbycsICd0aXRsZSddLCBga2VwbGVyZ2xfJHtnZW5lcmF0ZUhhc2hJZCg2KX1gLCBtYXBUb1NhdmUpO1xuICB9XG4gIHJldHVybiBtYXBUb1NhdmU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBvcnRKc29uKHN0YXRlLCBvcHRpb25zID0ge30pIHtcbiAgY29uc3QgbWFwID0gZ2V0TWFwSlNPTihzdGF0ZSwgb3B0aW9ucyk7XG5cbiAgY29uc3QgZmlsZUJsb2IgPSBuZXcgQmxvYihbZXhwb3J0VG9Kc29uU3RyaW5nKG1hcCldLCB7dHlwZTogJ2FwcGxpY2F0aW9uL2pzb24nfSk7XG4gIGNvbnN0IGZpbGVOYW1lID0gc3RhdGUuYXBwTmFtZSA/IGAke3N0YXRlLmFwcE5hbWV9Lmpzb25gIDogREVGQVVMVF9KU09OX05BTUU7XG4gIGRvd25sb2FkRmlsZShmaWxlQmxvYiwgZmlsZU5hbWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXhwb3J0SHRtbChzdGF0ZSwgb3B0aW9ucykge1xuICBjb25zdCB7dXNlck1hcGJveFRva2VuLCBleHBvcnRNYXBib3hBY2Nlc3NUb2tlbiwgbW9kZX0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IGRhdGEgPSB7XG4gICAgLi4uZ2V0TWFwSlNPTihzdGF0ZSksXG4gICAgbWFwYm94QXBpQWNjZXNzVG9rZW46XG4gICAgICAodXNlck1hcGJveFRva2VuIHx8ICcnKSAhPT0gJycgPyB1c2VyTWFwYm94VG9rZW4gOiBleHBvcnRNYXBib3hBY2Nlc3NUb2tlbixcbiAgICBtb2RlXG4gIH07XG5cbiAgY29uc3QgZmlsZUJsb2IgPSBuZXcgQmxvYihbZXhwb3J0TWFwVG9IVE1MKGRhdGEpXSwge3R5cGU6ICd0ZXh0L2h0bWwnfSk7XG4gIGRvd25sb2FkRmlsZShmaWxlQmxvYiwgc3RhdGUuYXBwTmFtZSA/IGAke3N0YXRlLmFwcE5hbWV9Lmh0bWxgIDogREVGQVVMVF9IVE1MX05BTUUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXhwb3J0RGF0YShzdGF0ZSwgb3B0aW9uKSB7XG4gIGNvbnN0IHt2aXNTdGF0ZSwgYXBwTmFtZX0gPSBzdGF0ZTtcbiAgY29uc3Qge2RhdGFzZXRzfSA9IHZpc1N0YXRlO1xuICBjb25zdCB7c2VsZWN0ZWREYXRhc2V0LCBkYXRhVHlwZSwgZmlsdGVyZWR9ID0gb3B0aW9uO1xuICAvLyBnZXQgdGhlIHNlbGVjdGVkIGRhdGFcbiAgY29uc3QgZmlsZW5hbWUgPSBhcHBOYW1lID8gYXBwTmFtZSA6IERFRkFVTFRfREFUQV9OQU1FO1xuICBjb25zdCBzZWxlY3RlZERhdGFzZXRzID0gZGF0YXNldHNbc2VsZWN0ZWREYXRhc2V0XVxuICAgID8gW2RhdGFzZXRzW3NlbGVjdGVkRGF0YXNldF1dXG4gICAgOiBPYmplY3QudmFsdWVzKGRhdGFzZXRzKTtcbiAgaWYgKCFzZWxlY3RlZERhdGFzZXRzLmxlbmd0aCkge1xuICAgIC8vIGVycm9yOiBzZWxlY3RlZCBkYXRhc2V0IG5vdCBmb3VuZC5cbiAgICByZXR1cm47XG4gIH1cblxuICBzZWxlY3RlZERhdGFzZXRzLmZvckVhY2goc2VsZWN0ZWREYXRhID0+IHtcbiAgICBjb25zdCB7ZGF0YUNvbnRhaW5lciwgZmllbGRzLCBsYWJlbCwgZmlsdGVyZWRJZHhDUFUgPSBbXX0gPSBzZWxlY3RlZERhdGE7XG4gICAgY29uc3QgdG9FeHBvcnQgPSBmaWx0ZXJlZFxuICAgICAgPyBjcmVhdGVJbmRleGVkRGF0YUNvbnRhaW5lcihkYXRhQ29udGFpbmVyLCBmaWx0ZXJlZElkeENQVSlcbiAgICAgIDogZGF0YUNvbnRhaW5lcjtcblxuICAgIC8vIHN0YXJ0IHRvIGV4cG9ydCBkYXRhIGFjY29yZGluZyB0byBzZWxlY3RlZCBkYXRhIHR5cGVcbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlIEVYUE9SVF9EQVRBX1RZUEUuQ1NWOiB7XG4gICAgICAgIGNvbnN0IGNzdiA9IGZvcm1hdENzdih0b0V4cG9ydCwgZmllbGRzKTtcblxuICAgICAgICBjb25zdCBmaWxlQmxvYiA9IG5ldyBCbG9iKFtjc3ZdLCB7dHlwZTogJ3RleHQvY3N2J30pO1xuICAgICAgICBkb3dubG9hZEZpbGUoZmlsZUJsb2IsIGAke2ZpbGVuYW1lfV8ke2xhYmVsfS5jc3ZgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvLyBUT0RPOiBzdXBwb3J0IG1vcmUgZmlsZSB0eXBlcy5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBvcnRNYXAoc3RhdGUsIG9wdGlvbikge1xuICBjb25zdCB7aW1hZ2VEYXRhVXJpfSA9IHN0YXRlLnVpU3RhdGUuZXhwb3J0SW1hZ2U7XG4gIGNvbnN0IHRodW1ibmFpbCA9IGltYWdlRGF0YVVyaSA/IGRhdGFVUkl0b0Jsb2IoaW1hZ2VEYXRhVXJpKSA6IG51bGw7XG4gIGNvbnN0IG1hcFRvU2F2ZSA9IGdldE1hcEpTT04oc3RhdGUsIG9wdGlvbik7XG5cbiAgcmV0dXJuIHtcbiAgICBtYXA6IG1hcFRvU2F2ZSxcbiAgICB0aHVtYm5haWxcbiAgfTtcbn1cblxuY29uc3QgZXhwb3J0ZXJzID0ge1xuICBleHBvcnRJbWFnZSxcbiAgZXhwb3J0SnNvbixcbiAgZXhwb3J0SHRtbCxcbiAgZXhwb3J0RGF0YVxufTtcblxuZXhwb3J0IGRlZmF1bHQgZXhwb3J0ZXJzO1xuIl19