UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

204 lines (165 loc) 22.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.coordHasLength4 = coordHasLength4; exports.containValidTime = containValidTime; exports.isTripGeoJsonField = isTripGeoJsonField; exports.parseTripGeoJsonTimestamp = parseTripGeoJsonTimestamp; exports.getAnimationDomainFromTimestamps = getAnimationDomainFromTimestamps; var _typeAnalyzer = require("type-analyzer"); var _dataUtils = require("../../utils/data-utils"); var _dataContainerUtils = require("../../utils/table-utils/data-container-utils"); var _geojsonUtils = require("../geojson-layer/geojson-utils"); // Copyright (c) 2021 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. /** * Parse geojson from string * @param {array} samples feature object values * @returns {boolean} whether the geometry coordinates has length of 4 */ function coordHasLength4(samples) { var hasLength4 = true; for (var i = 0; i < samples.length; i += 1) { hasLength4 = !samples[i].geometry.coordinates.find(function (c) { return c.length < 4; }); if (!hasLength4) { break; } } return hasLength4; } /** * Check whether geojson linestring's 4th coordinate is 1) not timestamp 2) unix time stamp 3) real date time * @param {array} timestamps array to be tested if its elements are timestamp * @returns {object | boolean} the type of timestamp: unix/datetime/invalid(not timestamp) */ function containValidTime(timestamps) { var formattedTimeStamps = timestamps.map(function (ts) { return { ts: ts }; }); var ignoredDataTypes = Object.keys(_typeAnalyzer.DATA_TYPES).filter(function (type) { return ![_typeAnalyzer.DATA_TYPES.TIME, _typeAnalyzer.DATA_TYPES.DATETIME].includes(type); }); // ignore all types but TIME to improve performance var analyzedType = _typeAnalyzer.Analyzer.computeColMeta(formattedTimeStamps, [], { ignoredDataTypes: ignoredDataTypes })[0]; if (!analyzedType || analyzedType.category !== 'TIME') { return false; } return analyzedType; } /** * Check if geojson features are trip layer animatable by meeting 3 conditions * @param {import('utils/table-utils/data-container-interface').DataContainerInterface} dataContainer geojson feature objects container * @param {object} field array of geojson feature objects * @returns {boolean} whether it is trip layer animatable */ function isTripGeoJsonField(dataContainer, field) { if (dataContainer.numRows() < 1) { return false; } var maxCount = 10000; var sampleRawFeatures = dataContainer.numRows() > maxCount ? (0, _dataContainerUtils.getSampleData)(dataContainer, maxCount) : dataContainer; var features = sampleRawFeatures.mapIndex(field.valueAccessor).map(_geojsonUtils.parseGeoJsonRawFeature).filter(function (f) { return f; }); var featureTypes = (0, _geojsonUtils.getGeojsonFeatureTypes)(features); // condition 1: contain line string if (!featureTypes.line) { return false; } // condition 2:sample line strings contain 4 coordinates if (!coordHasLength4(features)) { return false; } // condition 3:the 4th coordinate of the first feature line strings is valid time var tsHolder = features[0].geometry.coordinates.map(function (coord) { return coord[3]; }); return Boolean(containValidTime(tsHolder)); } /** * Get unix timestamp from animatable geojson for deck.gl trip layer * @param {Array<Object>} dataToFeature array of geojson feature objects, can be null * @returns {{dataToTimeStamp: Array[Number], animationDomain: null | Array<Number>}} {dataToTimeStamp: [], animationDomain: null} */ function parseTripGeoJsonTimestamp(dataToFeature) { // Analyze type based on coordinates of the 1st lineString // select a sample trip to analyze time format var empty = { dataToTimeStamp: [], animationDomain: null }; var sampleTrip = dataToFeature.find(function (f) { return f && f.geometry && f.geometry.coordinates && f.geometry.coordinates.length >= 3; }); // if no valid geometry if (!sampleTrip) { return empty; } var analyzedType = containValidTime(sampleTrip.geometry.coordinates.map(function (coord) { return coord[3]; })); if (!analyzedType) { return empty; } var format = analyzedType.format; var getTimeValue = function getTimeValue(coord) { return coord && (0, _dataUtils.notNullorUndefined)(coord[3]) ? (0, _dataUtils.timeToUnixMilli)(coord[3], format) : null; }; var dataToTimeStamp = dataToFeature.map(function (f) { return f && f.geometry && Array.isArray(f.geometry.coordinates) ? f.geometry.coordinates.map(getTimeValue) : null; }); var animationDomain = getAnimationDomainFromTimestamps(dataToTimeStamp); return { dataToTimeStamp: dataToTimeStamp, animationDomain: animationDomain }; } function findMinFromSorted() { var list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; return list.find(function (d) { return (0, _dataUtils.notNullorUndefined)(d) && Number.isFinite(d); }) || null; } function findMaxFromSorted() { var list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var i = list.length - 1; while (i > 0) { if ((0, _dataUtils.notNullorUndefined)(list[i]) && Number.isFinite(list[i])) { return list[i]; } i--; } return null; } function getAnimationDomainFromTimestamps() { var dataToTimeStamp = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; return dataToTimeStamp.reduce(function (accu, tss) { var tsMin = findMinFromSorted(tss); var tsMax = findMaxFromSorted(tss); if (Number.isFinite(tsMin) && Number.isFinite(tsMax)) { accu[0] = Math.min(accu[0], tsMin); accu[1] = Math.max(accu[1], tsMax); } return accu; }, [Infinity, -Infinity]); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sYXllcnMvdHJpcC1sYXllci90cmlwLXV0aWxzLmpzIl0sIm5hbWVzIjpbImNvb3JkSGFzTGVuZ3RoNCIsInNhbXBsZXMiLCJoYXNMZW5ndGg0IiwiaSIsImxlbmd0aCIsImdlb21ldHJ5IiwiY29vcmRpbmF0ZXMiLCJmaW5kIiwiYyIsImNvbnRhaW5WYWxpZFRpbWUiLCJ0aW1lc3RhbXBzIiwiZm9ybWF0dGVkVGltZVN0YW1wcyIsIm1hcCIsInRzIiwiaWdub3JlZERhdGFUeXBlcyIsIk9iamVjdCIsImtleXMiLCJEQVRBX1RZUEVTIiwiZmlsdGVyIiwidHlwZSIsIlRJTUUiLCJEQVRFVElNRSIsImluY2x1ZGVzIiwiYW5hbHl6ZWRUeXBlIiwiQW5hbHl6ZXIiLCJjb21wdXRlQ29sTWV0YSIsImNhdGVnb3J5IiwiaXNUcmlwR2VvSnNvbkZpZWxkIiwiZGF0YUNvbnRhaW5lciIsImZpZWxkIiwibnVtUm93cyIsIm1heENvdW50Iiwic2FtcGxlUmF3RmVhdHVyZXMiLCJmZWF0dXJlcyIsIm1hcEluZGV4IiwidmFsdWVBY2Nlc3NvciIsInBhcnNlR2VvSnNvblJhd0ZlYXR1cmUiLCJmIiwiZmVhdHVyZVR5cGVzIiwibGluZSIsInRzSG9sZGVyIiwiY29vcmQiLCJCb29sZWFuIiwicGFyc2VUcmlwR2VvSnNvblRpbWVzdGFtcCIsImRhdGFUb0ZlYXR1cmUiLCJlbXB0eSIsImRhdGFUb1RpbWVTdGFtcCIsImFuaW1hdGlvbkRvbWFpbiIsInNhbXBsZVRyaXAiLCJmb3JtYXQiLCJnZXRUaW1lVmFsdWUiLCJBcnJheSIsImlzQXJyYXkiLCJnZXRBbmltYXRpb25Eb21haW5Gcm9tVGltZXN0YW1wcyIsImZpbmRNaW5Gcm9tU29ydGVkIiwibGlzdCIsImQiLCJOdW1iZXIiLCJpc0Zpbml0ZSIsImZpbmRNYXhGcm9tU29ydGVkIiwicmVkdWNlIiwiYWNjdSIsInRzcyIsInRzTWluIiwidHNNYXgiLCJNYXRoIiwibWluIiwibWF4IiwiSW5maW5p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SUFBSSxDQUFDcEQsQ0FBRCxDQUF2QixLQUErQnNELE1BQU0sQ0FBQ0MsUUFBUCxDQUFnQkgsSUFBSSxDQUFDcEQsQ0FBRCxDQUFwQixDQUFuQyxFQUE2RDtBQUMzRCxhQUFPb0QsSUFBSSxDQUFDcEQsQ0FBRCxDQUFYO0FBQ0Q7O0FBQ0RBLElBQUFBLENBQUM7QUFDRjs7QUFDRCxTQUFPLElBQVA7QUFDRDs7QUFFTSxTQUFTa0QsZ0NBQVQsR0FBZ0U7QUFBQSxNQUF0QlAsZUFBc0IsdUVBQUosRUFBSTtBQUNyRSxTQUFPQSxlQUFlLENBQUNjLE1BQWhCLENBQ0wsVUFBQ0MsSUFBRCxFQUFPQyxHQUFQLEVBQWU7QUFDYixRQUFNQyxLQUFLLEdBQUdULGlCQUFpQixDQUFDUSxHQUFELENBQS9CO0FBQ0EsUUFBTUUsS0FBSyxHQUFHTCxpQkFBaUIsQ0FBQ0csR0FBRCxDQUEvQjs7QUFDQSxRQUFJTCxNQUFNLENBQUNDLFFBQVAsQ0FBZ0JLLEtBQWhCLEtBQTBCTixNQUFNLENBQUNDLFFBQVAsQ0FBZ0JNLEtBQWhCLENBQTlCLEVBQXNEO0FBQ3BESCxNQUFBQSxJQUFJLENBQUMsQ0FBRCxDQUFKLEdBQVVJLElBQUksQ0FBQ0MsR0FBTCxDQUFTTCxJQUFJLENBQUMsQ0FBRCxDQUFiLEVBQWtCRSxLQUFsQixDQUFWO0FBQ0FGLE1BQUFBLElBQUksQ0FBQyxDQUFELENBQUosR0FBVUksSUFBSSxDQUFDRSxHQUFMLENBQVNOLElBQUksQ0FBQyxDQUFELENBQWIsRUFBa0JHLEtBQWxCLENBQVY7QUFDRDs7QUFDRCxXQUFPSCxJQUFQO0FBQ0QsR0FUSSxFQVVMLENBQUNPLFFBQUQsRUFBVyxDQUFDQSxRQUFaLENBVkssQ0FBUDtBQVlEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDIxIFViZXIgVGVjaG5vbG9naWVzLCBJbmMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuLy8gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuLy8gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vIFRIRSBTT0ZUV0FSRS5cblxuaW1wb3J0IHtBbmFseXplciwgREFUQV9UWVBFU30gZnJvbSAndHlwZS1hbmFseXplcic7XG5cbmltcG9ydCB7dGltZVRvVW5peE1pbGxpLCBub3ROdWxsb3JVbmRlZmluZWR9IGZyb20gJ3V0aWxzL2RhdGEtdXRpbHMnO1xuaW1wb3J0IHtnZXRTYW1wbGVEYXRhfSBmcm9tICd1dGlscy90YWJsZS11dGlscy9kYXRhLWNvbnRhaW5lci11dGlscyc7XG5cbmltcG9ydCB7cGFyc2VHZW9Kc29uUmF3RmVhdHVyZSwgZ2V0R2VvanNvbkZlYXR1cmVUeXBlc30gZnJvbSAnbGF5ZXJzL2dlb2pzb24tbGF5ZXIvZ2VvanNvbi11dGlscyc7XG5cbi8qKlxuICogUGFyc2UgZ2VvanNvbiBmcm9tIHN0cmluZ1xuICogQHBhcmFtIHthcnJheX0gc2FtcGxlcyBmZWF0dXJlIG9iamVjdCB2YWx1ZXNcbiAqIEByZXR1cm5zIHtib29sZWFufSB3aGV0aGVyIHRoZSBnZW9tZXRyeSBjb29yZGluYXRlcyBoYXMgbGVuZ3RoIG9mIDRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvb3JkSGFzTGVuZ3RoNChzYW1wbGVzKSB7XG4gIGxldCBoYXNMZW5ndGg0ID0gdHJ1ZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzYW1wbGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgaGFzTGVuZ3RoNCA9ICFzYW1wbGVzW2ldLmdlb21ldHJ5LmNvb3JkaW5hdGVzLmZpbmQoYyA9PiBjLmxlbmd0aCA8IDQpO1xuICAgIGlmICghaGFzTGVuZ3RoNCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBoYXNMZW5ndGg0O1xufVxuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgZ2VvanNvbiBsaW5lc3RyaW5nJ3MgNHRoIGNvb3JkaW5hdGUgaXMgMSkgbm90IHRpbWVzdGFtcCAyKSB1bml4IHRpbWUgc3RhbXAgMykgcmVhbCBkYXRlIHRpbWVcbiAqIEBwYXJhbSB7YXJyYXl9IHRpbWVzdGFtcHMgYXJyYXkgdG8gYmUgdGVzdGVkIGlmIGl0cyBlbGVtZW50cyBhcmUgdGltZXN0YW1wXG4gKiBAcmV0dXJucyB7b2JqZWN0IHwgYm9vbGVhbn0gdGhlIHR5cGUgb2YgdGltZXN0YW1wOiB1bml4L2RhdGV0aW1lL2ludmFsaWQobm90IHRpbWVzdGFtcClcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29udGFpblZhbGlkVGltZSh0aW1lc3RhbXBzKSB7XG4gIGNvbnN0IGZvcm1hdHRlZFRpbWVTdGFtcHMgPSB0aW1lc3RhbXBzLm1hcCh0cyA9PiAoe3RzfSkpO1xuICBjb25zdCBpZ25vcmVkRGF0YVR5cGVzID0gT2JqZWN0LmtleXMoREFUQV9UWVBFUykuZmlsdGVyKFxuICAgIHR5cGUgPT4gIVtEQVRBX1RZUEVTLlRJTUUsIERBVEFfVFlQRVMuREFURVRJTUVdLmluY2x1ZGVzKHR5cGUpXG4gICk7XG5cbiAgLy8gaWdub3JlIGFsbCB0eXBlcyBidXQgVElNRSB0byBpbXByb3ZlIHBlcmZvcm1hbmNlXG4gIGNvbnN0IGFuYWx5emVkVHlwZSA9IEFuYWx5emVyLmNvbXB1dGVDb2xNZXRhKGZvcm1hdHRlZFRpbWVTdGFtcHMsIFtdLCB7aWdub3JlZERhdGFUeXBlc30pWzBdO1xuXG4gIGlmICghYW5hbHl6ZWRUeXBlIHx8IGFuYWx5emVkVHlwZS5jYXRlZ29yeSAhPT0gJ1RJTUUnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBhbmFseXplZFR5cGU7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgZ2VvanNvbiBmZWF0dXJlcyBhcmUgdHJpcCBsYXllciBhbmltYXRhYmxlIGJ5IG1lZXRpbmcgMyBjb25kaXRpb25zXG4gKiBAcGFyYW0ge2ltcG9ydCgndXRpbHMvdGFibGUtdXRpbHMvZGF0YS1jb250YWluZXItaW50ZXJmYWNlJykuRGF0YUNvbnRhaW5lckludGVyZmFjZX0gZGF0YUNvbnRhaW5lciBnZW9qc29uIGZlYXR1cmUgb2JqZWN0cyBjb250YWluZXJcbiAqIEBwYXJhbSB7b2JqZWN0fSBmaWVsZCBhcnJheSBvZiBnZW9qc29uIGZlYXR1cmUgb2JqZWN0c1xuICogQHJldHVybnMge2Jvb2xlYW59IHdoZXRoZXIgaXQgaXMgdHJpcCBsYXllciBhbmltYXRhYmxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1RyaXBHZW9Kc29uRmllbGQoZGF0YUNvbnRhaW5lciwgZmllbGQpIHtcbiAgaWYgKGRhdGFDb250YWluZXIubnVtUm93cygpIDwgMSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IG1heENvdW50ID0gMTAwMDA7XG4gIGNvbnN0IHNhbXBsZVJhd0ZlYXR1cmVzID1cbiAgICBkYXRhQ29udGFpbmVyLm51bVJvd3MoKSA+IG1heENvdW50ID8gZ2V0U2FtcGxlRGF0YShkYXRhQ29udGFpbmVyLCBtYXhDb3VudCkgOiBkYXRhQ29udGFpbmVyO1xuXG4gIGNvbnN0IGZlYXR1cmVzID0gc2FtcGxlUmF3RmVhdHVyZXNcbiAgICAubWFwSW5kZXgoZmllbGQudmFsdWVBY2Nlc3NvcilcbiAgICAubWFwKHBhcnNlR2VvSnNvblJhd0ZlYXR1cmUpXG4gICAgLmZpbHRlcihmID0+IGYpO1xuICBjb25zdCBmZWF0dXJlVHlwZXMgPSBnZXRHZW9qc29uRmVhdHVyZVR5cGVzKGZlYXR1cmVzKTtcblxuICAvLyBjb25kaXRpb24gMTogY29udGFpbiBsaW5lIHN0cmluZ1xuICBpZiAoIWZlYXR1cmVUeXBlcy5saW5lKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gY29uZGl0aW9uIDI6c2FtcGxlIGxpbmUgc3RyaW5ncyBjb250YWluIDQgY29vcmRpbmF0ZXNcbiAgaWYgKCFjb29yZEhhc0xlbmd0aDQoZmVhdHVyZXMpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gY29uZGl0aW9uIDM6dGhlIDR0aCBjb29yZGluYXRlIG9mIHRoZSBmaXJzdCBmZWF0dXJlIGxpbmUgc3RyaW5ncyBpcyB2YWxpZCB0aW1lXG4gIGNvbnN0IHRzSG9sZGVyID0gZmVhdHVyZXNbMF0uZ2VvbWV0cnkuY29vcmRpbmF0ZXMubWFwKGNvb3JkID0+IGNvb3JkWzNdKTtcblxuICByZXR1cm4gQm9vbGVhbihjb250YWluVmFsaWRUaW1lKHRzSG9sZGVyKSk7XG59XG5cbi8qKlxuICogR2V0IHVuaXggdGltZXN0YW1wIGZyb20gYW5pbWF0YWJsZSBnZW9qc29uIGZvciBkZWNrLmdsIHRyaXAgbGF5ZXJcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gZGF0YVRvRmVhdHVyZSBhcnJheSBvZiBnZW9qc29uIGZlYXR1cmUgb2JqZWN0cywgY2FuIGJlIG51bGxcbiAqIEByZXR1cm5zIHt7ZGF0YVRvVGltZVN0YW1wOiBBcnJheVtOdW1iZXJdLCBhbmltYXRpb25Eb21haW46IG51bGwgfCBBcnJheTxOdW1iZXI+fX0ge2RhdGFUb1RpbWVTdGFtcDogW10sIGFuaW1hdGlvbkRvbWFpbjogbnVsbH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVHJpcEdlb0pzb25UaW1lc3RhbXAoZGF0YVRvRmVhdHVyZSkge1xuICAvLyBBbmFseXplIHR5cGUgYmFzZWQgb24gY29vcmRpbmF0ZXMgb2YgdGhlIDFzdCBsaW5lU3RyaW5nXG4gIC8vIHNlbGVjdCBhIHNhbXBsZSB0cmlwIHRvIGFuYWx5emUgdGltZSBmb3JtYXRcbiAgY29uc3QgZW1wdHkgPSB7ZGF0YVRvVGltZVN0YW1wOiBbXSwgYW5pbWF0aW9uRG9tYWluOiBudWxsfTtcbiAgY29uc3Qgc2FtcGxlVHJpcCA9IGRhdGFUb0ZlYXR1cmUuZmluZChcbiAgICBmID0+IGYgJiYgZi5nZW9tZXRyeSAmJiBmLmdlb21ldHJ5LmNvb3JkaW5hdGVzICYmIGYuZ2VvbWV0cnkuY29vcmRpbmF0ZXMubGVuZ3RoID49IDNcbiAgKTtcblxuICAvLyBpZiBubyB2YWxpZCBnZW9tZXRyeVxuICBpZiAoIXNhbXBsZVRyaXApIHtcbiAgICByZXR1cm4gZW1wdHk7XG4gIH1cblxuICBjb25zdCBhbmFseXplZFR5cGUgPSBjb250YWluVmFsaWRUaW1lKHNhbXBsZVRyaXAuZ2VvbWV0cnkuY29vcmRpbmF0ZXMubWFwKGNvb3JkID0+IGNvb3JkWzNdKSk7XG5cbiAgaWYgKCFhbmFseXplZFR5cGUpIHtcbiAgICByZXR1cm4gZW1wdHk7XG4gIH1cblxuICBjb25zdCB7Zm9ybWF0fSA9IGFuYWx5emVkVHlwZTtcbiAgY29uc3QgZ2V0VGltZVZhbHVlID0gY29vcmQgPT5cbiAgICBjb29yZCAmJiBub3ROdWxsb3JVbmRlZmluZWQoY29vcmRbM10pID8gdGltZVRvVW5peE1pbGxpKGNvb3JkWzNdLCBmb3JtYXQpIDogbnVsbDtcblxuICBjb25zdCBkYXRhVG9UaW1lU3RhbXAgPSBkYXRhVG9GZWF0dXJlLm1hcChmID0+XG4gICAgZiAmJiBmLmdlb21ldHJ5ICYmIEFycmF5LmlzQXJyYXkoZi5nZW9tZXRyeS5jb29yZGluYXRlcylcbiAgICAgID8gZi5nZW9tZXRyeS5jb29yZGluYXRlcy5tYXAoZ2V0VGltZVZhbHVlKVxuICAgICAgOiBudWxsXG4gICk7XG5cbiAgY29uc3QgYW5pbWF0aW9uRG9tYWluID0gZ2V0QW5pbWF0aW9uRG9tYWluRnJvbVRpbWVzdGFtcHMoZGF0YVRvVGltZVN0YW1wKTtcblxuICByZXR1cm4ge2RhdGFUb1RpbWVTdGFtcCwgYW5pbWF0aW9uRG9tYWlufTtcbn1cblxuZnVuY3Rpb24gZmluZE1pbkZyb21Tb3J0ZWQobGlzdCA9IFtdKSB7XG4gIHJldHVybiBsaXN0LmZpbmQoZCA9PiBub3ROdWxsb3JVbmRlZmluZWQoZCkgJiYgTnVtYmVyLmlzRmluaXRlKGQpKSB8fCBudWxsO1xufVxuXG5mdW5jdGlvbiBmaW5kTWF4RnJvbVNvcnRlZChsaXN0ID0gW10pIHtcbiAgbGV0IGkgPSBsaXN0Lmxlbmd0aCAtIDE7XG4gIHdoaWxlIChpID4gMCkge1xuICAgIGlmIChub3ROdWxsb3JVbmRlZmluZWQobGlzdFtpXSkgJiYgTnVtYmVyLmlzRmluaXRlKGxpc3RbaV0pKSB7XG4gICAgICByZXR1cm4gbGlzdFtpXTtcbiAgICB9XG4gICAgaS0tO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QW5pbWF0aW9uRG9tYWluRnJvbVRpbWVzdGFtcHMoZGF0YVRvVGltZVN0YW1wID0gW10pIHtcbiAgcmV0dXJuIGRhdGFUb1RpbWVTdGFtcC5yZWR1Y2UoXG4gICAgKGFjY3UsIHRzcykgPT4ge1xuICAgICAgY29uc3QgdHNNaW4gPSBmaW5kTWluRnJvbVNvcnRlZCh0c3MpO1xuICAgICAgY29uc3QgdHNNYXggPSBmaW5kTWF4RnJvbVNvcnRlZCh0c3MpO1xuICAgICAgaWYgKE51bWJlci5pc0Zpbml0ZSh0c01pbikgJiYgTnVtYmVyLmlzRmluaXRlKHRzTWF4KSkge1xuICAgICAgICBhY2N1WzBdID0gTWF0aC5taW4oYWNjdVswXSwgdHNNaW4pO1xuICAgICAgICBhY2N1WzFdID0gTWF0aC5tYXgoYWNjdVsxXSwgdHNNYXgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjY3U7XG4gICAgfSxcbiAgICBbSW5maW5pdHksIC1JbmZpbml0eV1cbiAgKTtcbn1cbiJdfQ==