UNPKG

@eliorar/angular-cesium

Version:

Angular library for working with Cesium.

138 lines 19.4 kB
import { Injectable, Optional } from '@angular/core'; import { Cartesian2, Cartesian3, Cartographic, Math as cMath, SceneTransforms } from 'cesium'; import * as geodesy from 'geodesy'; import { LatLonEllipsoidal, Utm } from 'geodesy'; import * as i0 from "@angular/core"; import * as i1 from "../cesium/cesium.service"; const LatLonVectors = geodesy['LatLonVectors']; // doesnt exists on typings window['geodesy'] = geodesy; /** * Given different types of coordinates, we provide you a service converting those types to the most common other types. * We are using the geodesy implementation of UTM conversion. see: https://github.com/chrisveness/geodesy. *z * @example * import { Component, OnInit } from '@angular/core'; * import { CoordinateConverter } from 'angular2-cesium'; * * @Component({ * selector:'my-component', * template:'<div>{{showCartographic}}</div>', * providers:[CoordinateConverter] * }) * export class MyComponent implements OnInit { * showCartographic; * * constructor(private coordinateConverter:CoordinateConverter){ * } * * ngOnInit(){ * this.showCartographic = this.coordinateConverter.degreesToCartographic(5, 5, 5); * } * } * */ export class CoordinateConverter { constructor(cesiumService) { this.cesiumService = cesiumService; } static cartesian3ToLatLon(cartesian3, ellipsoid) { const cart = Cartographic.fromCartesian(cartesian3, ellipsoid); return { lon: cMath.toDegrees(cart.longitude), lat: cMath.toDegrees(cart.latitude), height: cart.height }; } screenToCartesian3(screenPos, addMapCanvasBoundsToPos) { if (!this.cesiumService) { throw new Error('ANGULAR2-CESIUM - Cesium service should be provided in order' + ' to do screen position calculations'); } else { const screenPosition = { ...screenPos }; if (addMapCanvasBoundsToPos) { const mapBounds = this.cesiumService.getViewer().canvas.getBoundingClientRect(); screenPosition.x += mapBounds.left; screenPosition.y += mapBounds.top; } const camera = this.cesiumService.getViewer().camera; return camera.pickEllipsoid(screenPosition); } } screenToCartographic(screenPos, ellipsoid) { return this.cartesian3ToCartographic(this.screenToCartesian3(screenPos), ellipsoid); } cartesian3ToCartographic(cartesian, ellipsoid) { return Cartographic.fromCartesian(cartesian, ellipsoid); } degreesToCartographic(longitude, latitude, height) { return Cartographic.fromDegrees(longitude, latitude, height); } radiansToCartographic(longitude, latitude, height) { return Cartographic.fromRadians(longitude, latitude, height); } degreesToUTM(longitude, latitude) { return new LatLonEllipsoidal(latitude, longitude).toUtm(); } UTMToDegrees(zone, hemisphereType, easting, northing) { return this.geodesyToCesiumObject(new Utm(zone, hemisphereType, easting, northing).toLatLonE()); } geodesyToCesiumObject(geodesyRadians) { return { longitude: geodesyRadians.lon, latitude: geodesyRadians.lat, height: geodesyRadians['height'] ? geodesyRadians['height'] : 0 }; } /** * middle point between two points * @param first (latitude,longitude) in radians * @param second (latitude,longitude) in radians */ midPointToCartesian3(first, second) { const toDeg = (rad) => cMath.toDegrees(rad); const firstPoint = new LatLonVectors(toDeg(first.latitude), toDeg(first.longitude)); const secondPoint = new LatLonVectors(toDeg(second.latitude), toDeg(second.longitude)); const middlePoint = firstPoint.midpointTo(secondPoint); return Cartesian3.fromDegrees(middlePoint.lon, middlePoint.lat); } middlePointByScreen(position0, position1) { const scene = this.cesiumService.getScene(); const screenPosition1 = SceneTransforms.wgs84ToWindowCoordinates(scene, position0); const screenPosition2 = SceneTransforms.wgs84ToWindowCoordinates(scene, position1); const middleScreenPoint = new Cartesian2((screenPosition2.x + screenPosition1.x) / 2.0, (screenPosition2.y + screenPosition1.y) / 2.0); return scene.pickPosition(middleScreenPoint); } /** * initial bearing between two points * * * @return bearing in degrees * @param first - {latitude,longitude} in radians * @param second - {latitude,longitude} in radians */ bearingTo(first, second) { const toDeg = (rad) => cMath.toDegrees(rad); const firstPoint = new LatLonVectors(toDeg(first.latitude), toDeg(first.longitude)); const secondPoint = new LatLonVectors(toDeg(second.latitude), toDeg(second.longitude)); const bearing = firstPoint.bearingTo(secondPoint); return bearing; } /** * initial bearing between two points * * @return bearing in degrees */ bearingToCartesian(firstCartesian3, secondCartesian3) { const firstCart = Cartographic.fromCartesian(firstCartesian3); const secondCart = Cartographic.fromCartesian(secondCartesian3); return this.bearingTo(firstCart, secondCart); } } CoordinateConverter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CoordinateConverter, deps: [{ token: i1.CesiumService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); CoordinateConverter.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CoordinateConverter }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CoordinateConverter, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.CesiumService, decorators: [{ type: Optional }] }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29vcmRpbmF0ZS1jb252ZXJ0ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY2VzaXVtL3NyYy9saWIvYW5ndWxhci1jZXNpdW0vc2VydmljZXMvY29vcmRpbmF0ZS1jb252ZXJ0ZXIvY29vcmRpbmF0ZS1jb252ZXJ0ZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsVUFBVSxFQUFFLFFBQVEsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsSUFBSSxJQUFJLEtBQUssRUFBRSxlQUFlLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFFNUYsT0FBTyxLQUFLLE9BQU8sTUFBTSxTQUFTLENBQUM7QUFDbkMsT0FBTyxFQUFxQixpQkFBaUIsRUFBRSxHQUFHLEVBQUMsTUFBTSxTQUFTLENBQUM7OztBQUVuRSxNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQywyQkFBMkI7QUFFM0UsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztBQUU1Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBRUgsTUFBTSxPQUFPLG1CQUFtQjtJQUM5QixZQUFnQyxhQUE2QjtRQUE3QixrQkFBYSxHQUFiLGFBQWEsQ0FBZ0I7SUFDN0QsQ0FBQztJQUVELE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxVQUFzQixFQUFFLFNBQWU7UUFDL0QsTUFBTSxJQUFJLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDL0QsT0FBTztZQUNMLEdBQUcsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDcEMsR0FBRyxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxD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S0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDcEYsTUFBTSxXQUFXLEdBQUcsSUFBSSxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDdkYsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUVsRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGtCQUFrQixDQUFDLGVBQTJCLEVBQUUsZ0JBQTRCO1FBQzFFLE1BQU0sU0FBUyxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDOUQsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBRWhFLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDL0MsQ0FBQzs7Z0hBL0dVLG1CQUFtQjtvSEFBbkIsbUJBQW1COzJGQUFuQixtQkFBbUI7a0JBRC9CLFVBQVU7OzBCQUVJLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdGFibGUsIE9wdGlvbmFsfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Q2FydGVzaWFuMiwgQ2FydGVzaWFuMywgQ2FydG9ncmFwaGljLCBNYXRoIGFzIGNNYXRoLCBTY2VuZVRyYW5zZm9ybXN9IGZyb20gJ2Nlc2l1bSc7XG5pbXBvcnQge0Nlc2l1bVNlcnZpY2V9IGZyb20gJy4uL2Nlc2l1bS9jZXNpdW0uc2VydmljZSc7XG5pbXBvcnQgKiBhcyBnZW9kZXN5IGZyb20gJ2dlb2Rlc3knO1xuaW1wb3J0IHtoZW1pc3BoZXJlLCBMYXRMb24sIExhdExvbkVsbGlwc29pZGFsLCBVdG19IGZyb20gJ2dlb2Rlc3knO1xuXG5jb25zdCBMYXRMb25WZWN0b3JzID0gZ2VvZGVzeVsnTGF0TG9uVmVjdG9ycyddOyAvLyBkb2VzbnQgZXhpc3RzIG9uIHR5cGluZ3Ncblxud2luZG93WydnZW9kZXN5J10gPSBnZW9kZXN5O1xuXG4vKipcbiAqICBHaXZlbiBkaWZmZXJlbnQgdHlwZXMgb2YgY29vcmRpbmF0ZXMsIHdlIHByb3ZpZGUgeW91IGEgc2VydmljZSBjb252ZXJ0aW5nIHRob3NlIHR5cGVzIHRvIHRoZSBtb3N0IGNvbW1vbiBvdGhlciB0eXBlcy5cbiAqICBXZSBhcmUgdXNpbmcgdGhlIGdlb2Rlc3kgaW1wbGVtZW50YXRpb24gb2YgVVRNIGNvbnZlcnNpb24uIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL2NocmlzdmVuZXNzL2dlb2Rlc3kuXG4gKnpcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuICogaW1wb3J0IHsgQ29vcmRpbmF0ZUNvbnZlcnRlciB9IGZyb20gJ2FuZ3VsYXIyLWNlc2l1bSc7XG4gKlxuICogQENvbXBvbmVudCh7XG4gKiBcdFx0c2VsZWN0b3I6J215LWNvbXBvbmVudCcsXG4gKiBcdFx0dGVtcGxhdGU6JzxkaXY+e3tzaG93Q2FydG9ncmFwaGljfX08L2Rpdj4nLFxuICogXHRcdHByb3ZpZGVyczpbQ29vcmRpbmF0ZUNvbnZlcnRlcl1cbiAqIH0pXG4gKiBleHBvcnQgY2xhc3MgTXlDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICogXHRcdHNob3dDYXJ0b2dyYXBoaWM7XG4gKlxuICogXHRcdGNvbnN0cnVjdG9yKHByaXZhdGUgY29vcmRpbmF0ZUNvbnZlcnRlcjpDb29yZGluYXRlQ29udmVydGVyKXtcbiAqIFx0XHR9XG4gKlxuICogXHRcdG5nT25Jbml0KCl7XG4gKiBcdFx0XHR0aGlzLnNob3dDYXJ0b2dyYXBoaWMgPSB0aGlzLmNvb3JkaW5hdGVDb252ZXJ0ZXIuZGVncmVlc1RvQ2FydG9ncmFwaGljKDUsIDUsIDUpO1xuICogIH1cbiAqIH1cbiAqXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBDb29yZGluYXRlQ29udmVydGVyIHtcbiAgY29uc3RydWN0b3IoQE9wdGlvbmFsKCkgcHJpdmF0ZSBjZXNpdW1TZXJ2aWNlPzogQ2VzaXVtU2VydmljZSkge1xuICB9XG5cbiAgc3RhdGljIGNhcnRlc2lhbjNUb0xhdExvbihjYXJ0ZXNpYW4zOiBDYXJ0ZXNpYW4zLCBlbGxpcHNvaWQ/OiBhbnkpOiB7bG9uOiBudW1iZXIsIGxhdDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlcn0ge1xuICAgIGNvbnN0IGNhcnQgPSBDYXJ0b2dyYXBoaWMuZnJvbUNhcnRlc2lhbihjYXJ0ZXNpYW4zLCBlbGxpcHNvaWQpO1xuICAgIHJldHVybiB7XG4gICAgICBsb246IGNNYXRoLnRvRGVncmVlcyhjYXJ0LmxvbmdpdHVkZSksXG4gICAgICBsYXQ6IGNNYXRoLnRvRGVncmVlcyhjYXJ0LmxhdGl0dWRlKSxcbiAgICAgIGhlaWdodDogY2FydC5oZWlnaHRcbiAgICB9O1xuICB9XG5cbiAgc2NyZWVuVG9DYXJ0ZXNpYW4zKHNjcmVlblBvczogeyB4OiBudW1iZXIsIHk6IG51bWJlciB9LCBhZGRNYXBDYW52YXNCb3VuZHNUb1Bvcz86IGJvb2xlYW4pIHtcbiAgICBpZiAoIXRoaXMuY2VzaXVtU2VydmljZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBTkdVTEFSMi1DRVNJVU0gLSBDZXNpdW0gc2VydmljZSBzaG91bGQgYmUgcHJvdmlkZWQgaW4gb3JkZXInICtcbiAgICAgICAgJyB0byBkbyBzY3JlZW4gcG9zaXRpb24gY2FsY3VsYXRpb25zJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHNjcmVlblBvc2l0aW9uID0geyAuLi5zY3JlZW5Qb3MgfTtcbiAgICAgIGlmIChhZGRNYXBDYW52YXNCb3VuZHNUb1Bvcykge1xuICAgICAgICBjb25zdCBtYXBCb3VuZHMgPSB0aGlzLmNlc2l1bVNlcnZpY2UuZ2V0Vmlld2VyKCkuY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBzY3JlZW5Qb3NpdGlvbi54ICs9IG1hcEJvdW5kcy5sZWZ0O1xuICAgICAgICBzY3JlZW5Qb3NpdGlvbi55ICs9IG1hcEJvdW5kcy50b3A7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNhbWVyYSA9IHRoaXMuY2VzaXVtU2VydmljZS5nZXRWaWV3ZXIoKS5jYW1lcmE7XG4gICAgICByZXR1cm4gY2FtZXJhLnBpY2tFbGxpcHNvaWQoc2NyZWVuUG9zaXRpb24pO1xuICAgIH1cbiAgfVxuXG4gIHNjcmVlblRvQ2FydG9ncmFwaGljKHNjcmVlblBvczogeyB4OiBudW1iZXIsIHk6IG51bWJlciB9LCBlbGxpcHNvaWQ/OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5jYXJ0ZXNpYW4zVG9DYXJ0b2dyYXBoaWModGhpcy5zY3JlZW5Ub0NhcnRlc2lhbjMoc2NyZWVuUG9zKSwgZWxsaXBzb2lkKTtcbiAgfVxuXG4gIGNhcnRlc2lhbjNUb0NhcnRvZ3JhcGhpYyhjYXJ0ZXNpYW46IENhcnRlc2lhbjMsIGVsbGlwc29pZD86IGFueSkge1xuICAgIHJldHVybiBDYXJ0b2dyYXBoaWMuZnJvbUNhcnRlc2lhbihjYXJ0ZXNpYW4sIGVsbGlwc29pZCk7XG4gIH1cblxuICBkZWdyZWVzVG9DYXJ0b2dyYXBoaWMobG9uZ2l0dWRlOiBudW1iZXIsIGxhdGl0dWRlOiBudW1iZXIsIGhlaWdodD86IG51bWJlcikge1xuICAgIHJldHVybiBDYXJ0b2dyYXBoaWMuZnJvbURlZ3JlZXMobG9uZ2l0dWRlLCBsYXRpdHVkZSwgaGVpZ2h0KTtcbiAgfVxuXG4gIHJhZGlhbnNUb0NhcnRvZ3JhcGhpYyhsb25naXR1ZGU6IG51bWJlciwgbGF0aXR1ZGU6IG51bWJlciwgaGVpZ2h0PzogbnVtYmVyKSB7XG4gICAgcmV0dXJuIENhcnRvZ3JhcGhpYy5mcm9tUmFkaWFucyhsb25naXR1ZGUsIGxhdGl0dWRlLCBoZWlnaHQpO1xuICB9XG5cbiAgZGVncmVlc1RvVVRNKGxvbmdpdHVkZTogbnVtYmVyLCBsYXRpdHVkZTogbnVtYmVyKSB7XG4gICAgcmV0dXJuIG5ldyBMYXRMb25FbGxpcHNvaWRhbChsYXRpdHVkZSwgbG9uZ2l0dWRlKS50b1V0bSgpO1xuICB9XG5cbiAgVVRNVG9EZWdyZWVzKHpvbmU6IG51bWJlciwgaGVtaXNwaGVyZVR5cGU6IGhlbWlzcGhlcmUsIGVhc3Rpbmc6IG51bWJlciwgbm9ydGhpbmc6IG51bWJlcikge1xuICAgIHJldHVybiB0aGlzLmdlb2Rlc3lUb0Nlc2l1bU9iamVjdChuZXcgVXRtKHpvbmUsIGhlbWlzcGhlcmVUeXBlLCBlYXN0aW5nLCBub3J0aGluZykudG9MYXRMb25FKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZW9kZXN5VG9DZXNpdW1PYmplY3QoZ2VvZGVzeVJhZGlhbnM6IExhdExvbikge1xuICAgIHJldHVybiB7XG4gICAgICBsb25naXR1ZGU6IGdlb2Rlc3lSYWRpYW5zLmxvbixcbiAgICAgIGxhdGl0dWRlOiBnZW9kZXN5UmFkaWFucy5sYXQsXG4gICAgICBoZWlnaHQ6IGdlb2Rlc3lSYWRpYW5zWydoZWlnaHQnXSA/IGdlb2Rlc3lSYWRpYW5zWydoZWlnaHQnXSA6IDBcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIG1pZGRsZSBwb2ludCBiZXR3ZWVuIHR3byBwb2ludHNcbiAgICogQHBhcmFtIGZpcnN0ICAobGF0aXR1ZGUsbG9uZ2l0dWRlKSBpbiByYWRpYW5zXG4gICAqIEBwYXJhbSBzZWNvbmQgKGxhdGl0dWRlLGxvbmdpdHVkZSkgaW4gcmFkaWFuc1xuICAgKi9cbiAgbWlkUG9pbnRUb0NhcnRlc2lhbjMoZmlyc3Q6IHsgbGF0aXR1ZGU6IG51bWJlciwgbG9uZ2l0dWRlOiBudW1iZXIgfSwgc2Vjb25kOiB7IGxhdGl0dWRlOiBudW1iZXIsIGxvbmdpdHVkZTogbnVtYmVyIH0pIHtcbiAgICBjb25zdCB0b0RlZyA9IChyYWQ6IG51bWJlcikgPT4gY01hdGgudG9EZWdyZWVzKHJhZCk7XG4gICAgY29uc3QgZmlyc3RQb2ludCA9IG5ldyBMYXRMb25WZWN0b3JzKHRvRGVnKGZpcnN0LmxhdGl0dWRlKSwgdG9EZWcoZmlyc3QubG9uZ2l0dWRlKSk7XG4gICAgY29uc3Qgc2Vjb25kUG9pbnQgPSBuZXcgTGF0TG9uVmVjdG9ycyh0b0RlZyhzZWNvbmQubGF0aXR1ZGUpLCB0b0RlZyhzZWNvbmQubG9uZ2l0dWRlKSk7XG4gICAgY29uc3QgbWlkZGxlUG9pbnQ6IGFueSA9IGZpcnN0UG9pbnQubWlkcG9pbnRUbyhzZWNvbmRQb2ludCk7XG5cbiAgICByZXR1cm4gQ2FydGVzaWFuMy5mcm9tRGVncmVlcyhtaWRkbGVQb2ludC5sb24sIG1pZGRsZVBvaW50LmxhdCk7XG4gIH1cblxuICBtaWRkbGVQb2ludEJ5U2NyZWVuKHBvc2l0aW9uMDogQ2FydGVzaWFuMywgcG9zaXRpb24xOiBDYXJ0ZXNpYW4zKTogQ2FydGVzaWFuMyB7XG4gICAgY29uc3Qgc2NlbmUgPSB0aGlzLmNlc2l1bVNlcnZpY2UuZ2V0U2NlbmUoKTtcbiAgICBjb25zdCBzY3JlZW5Qb3NpdGlvbjEgPSBTY2VuZVRyYW5zZm9ybXMud2dzODRUb1dpbmRvd0Nvb3JkaW5hdGVzKHNjZW5lLCBwb3NpdGlvbjApO1xuICAgIGNvbnN0IHNjcmVlblBvc2l0aW9uMiA9IFNjZW5lVHJhbnNmb3Jtcy53Z3M4NFRvV2luZG93Q29vcmRpbmF0ZXMoc2NlbmUsIHBvc2l0aW9uMSk7XG4gICAgY29uc3QgbWlkZGxlU2NyZWVuUG9pbnQgPVxuICAgICAgbmV3IENhcnRlc2lhbjIoKHNjcmVlblBvc2l0aW9uMi54ICsgc2NyZWVuUG9zaXRpb24xLngpIC8gMi4wLCAoc2NyZWVuUG9zaXRpb24yLnkgKyBzY3JlZW5Qb3NpdGlvbjEueSkgLyAyLjApO1xuICAgIHJldHVybiBzY2VuZS5waWNrUG9zaXRpb24obWlkZGxlU2NyZWVuUG9pbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIGluaXRpYWwgYmVhcmluZyBiZXR3ZWVuIHR3byBwb2ludHNcbiAgICpcbiAgICogKiBAcmV0dXJuIGJlYXJpbmcgaW4gZGVncmVlc1xuICAgKiBAcGFyYW0gZmlyc3QgLSB7bGF0aXR1ZGUsbG9uZ2l0dWRlfSBpbiByYWRpYW5zXG4gICAqIEBwYXJhbSBzZWNvbmQgLSB7bGF0aXR1ZGUsbG9uZ2l0dWRlfSBpbiByYWRpYW5zXG4gICAqL1xuICBiZWFyaW5nVG8oZmlyc3Q6IHsgbGF0aXR1ZGU6IG51bWJlciwgbG9uZ2l0dWRlOiBudW1iZXIgfSwgc2Vjb25kOiB7IGxhdGl0dWRlOiBudW1iZXIsIGxvbmdpdHVkZTogbnVtYmVyIH0pIHtcbiAgICBjb25zdCB0b0RlZyA9IChyYWQ6IG51bWJlcikgPT4gY01hdGgudG9EZWdyZWVzKHJhZCk7XG4gICAgY29uc3QgZmlyc3RQb2ludCA9IG5ldyBMYXRMb25WZWN0b3JzKHRvRGVnKGZpcnN0LmxhdGl0dWRlKSwgdG9EZWcoZmlyc3QubG9uZ2l0dWRlKSk7XG4gICAgY29uc3Qgc2Vjb25kUG9pbnQgPSBuZXcgTGF0TG9uVmVjdG9ycyh0b0RlZyhzZWNvbmQubGF0aXR1ZGUpLCB0b0RlZyhzZWNvbmQubG9uZ2l0dWRlKSk7XG4gICAgY29uc3QgYmVhcmluZyA9IGZpcnN0UG9pbnQuYmVhcmluZ1RvKHNlY29uZFBvaW50KTtcblxuICAgIHJldHVybiBiZWFyaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIGluaXRpYWwgYmVhcmluZyBiZXR3ZWVuIHR3byBwb2ludHNcbiAgICpcbiAgICogQHJldHVybiBiZWFyaW5nIGluIGRlZ3JlZXNcbiAgICovXG4gIGJlYXJpbmdUb0NhcnRlc2lhbihmaXJzdENhcnRlc2lhbjM6IENhcnRlc2lhbjMsIHNlY29uZENhcnRlc2lhbjM6IENhcnRlc2lhbjMpIHtcbiAgICBjb25zdCBmaXJzdENhcnQgPSBDYXJ0b2dyYXBoaWMuZnJvbUNhcnRlc2lhbihmaXJzdENhcnRlc2lhbjMpO1xuICAgIGNvbnN0IHNlY29uZENhcnQgPSBDYXJ0b2dyYXBoaWMuZnJvbUNhcnRlc2lhbihzZWNvbmRDYXJ0ZXNpYW4zKTtcblxuICAgIHJldHVybiB0aGlzLmJlYXJpbmdUbyhmaXJzdENhcnQsIHNlY29uZENhcnQpO1xuICB9XG59XG4iXX0=