@ingissa/navcore-simulator 1.0.8 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/index.d.mts +87 -0
- package/dist/{simulator/src/react-native/useSimulator.d.ts → index.d.ts} +37 -9
- package/dist/index.js +1393 -0
- package/dist/index.mjs +1383 -0
- package/dist/node.d.mts +527 -0
- package/dist/node.d.ts +527 -0
- package/dist/node.js +957 -0
- package/dist/node.mjs +949 -0
- package/dist/react-native.d.mts +4 -0
- package/dist/react-native.d.ts +4 -0
- package/dist/react-native.js +1393 -0
- package/dist/react-native.mjs +1383 -0
- package/package.json +19 -16
- package/dist/core/src/NavCore.d.ts +0 -142
- package/dist/core/src/NavCore.d.ts.map +0 -1
- package/dist/core/src/NavCore.js +0 -390
- package/dist/core/src/bearing/BearingEngine.d.ts +0 -24
- package/dist/core/src/bearing/BearingEngine.d.ts.map +0 -1
- package/dist/core/src/bearing/BearingEngine.js +0 -50
- package/dist/core/src/constants.d.ts +0 -34
- package/dist/core/src/constants.d.ts.map +0 -1
- package/dist/core/src/constants.js +0 -41
- package/dist/core/src/corridor/DeviationDetector.d.ts +0 -33
- package/dist/core/src/corridor/DeviationDetector.d.ts.map +0 -1
- package/dist/core/src/corridor/DeviationDetector.js +0 -83
- package/dist/core/src/corridor/DynamicCorridor.d.ts +0 -13
- package/dist/core/src/corridor/DynamicCorridor.d.ts.map +0 -1
- package/dist/core/src/corridor/DynamicCorridor.js +0 -26
- package/dist/core/src/dead-reckoning/DeadReckoning.d.ts +0 -35
- package/dist/core/src/dead-reckoning/DeadReckoning.d.ts.map +0 -1
- package/dist/core/src/dead-reckoning/DeadReckoning.js +0 -49
- package/dist/core/src/directions/DirectionsProvider.d.ts +0 -70
- package/dist/core/src/directions/DirectionsProvider.d.ts.map +0 -1
- package/dist/core/src/directions/DirectionsProvider.js +0 -7
- package/dist/core/src/directions/OSRMDirectionsProvider.d.ts +0 -26
- package/dist/core/src/directions/OSRMDirectionsProvider.d.ts.map +0 -1
- package/dist/core/src/directions/OSRMDirectionsProvider.js +0 -90
- package/dist/core/src/directions/OpenRouteServiceProvider.d.ts +0 -30
- package/dist/core/src/directions/OpenRouteServiceProvider.d.ts.map +0 -1
- package/dist/core/src/directions/OpenRouteServiceProvider.js +0 -111
- package/dist/core/src/directions/ValhallaDirectionsProvider.d.ts +0 -33
- package/dist/core/src/directions/ValhallaDirectionsProvider.d.ts.map +0 -1
- package/dist/core/src/directions/ValhallaDirectionsProvider.js +0 -155
- package/dist/core/src/eta/ETAEngine.d.ts +0 -61
- package/dist/core/src/eta/ETAEngine.d.ts.map +0 -1
- package/dist/core/src/eta/ETAEngine.js +0 -74
- package/dist/core/src/features.d.ts +0 -76
- package/dist/core/src/features.d.ts.map +0 -1
- package/dist/core/src/features.js +0 -76
- package/dist/core/src/geo/bearing.d.ts +0 -11
- package/dist/core/src/geo/bearing.d.ts.map +0 -1
- package/dist/core/src/geo/bearing.js +0 -25
- package/dist/core/src/geo/cumulative.d.ts +0 -9
- package/dist/core/src/geo/cumulative.d.ts.map +0 -1
- package/dist/core/src/geo/cumulative.js +0 -20
- package/dist/core/src/geo/haversine.d.ts +0 -13
- package/dist/core/src/geo/haversine.d.ts.map +0 -1
- package/dist/core/src/geo/haversine.js +0 -39
- package/dist/core/src/geo/projection.d.ts +0 -7
- package/dist/core/src/geo/projection.d.ts.map +0 -1
- package/dist/core/src/geo/projection.js +0 -17
- package/dist/core/src/geofencing/GeofencingEngine.d.ts +0 -93
- package/dist/core/src/geofencing/GeofencingEngine.d.ts.map +0 -1
- package/dist/core/src/geofencing/GeofencingEngine.js +0 -154
- package/dist/core/src/index.d.ts +0 -66
- package/dist/core/src/index.d.ts.map +0 -1
- package/dist/core/src/index.js +0 -62
- package/dist/core/src/kalman/KalmanFilter2D.d.ts +0 -46
- package/dist/core/src/kalman/KalmanFilter2D.d.ts.map +0 -1
- package/dist/core/src/kalman/KalmanFilter2D.js +0 -77
- package/dist/core/src/license/LicenseManager.d.ts +0 -40
- package/dist/core/src/license/LicenseManager.d.ts.map +0 -1
- package/dist/core/src/license/LicenseManager.js +0 -119
- package/dist/core/src/license/verifyP256Signature.d.ts +0 -2
- package/dist/core/src/license/verifyP256Signature.d.ts.map +0 -1
- package/dist/core/src/license/verifyP256Signature.js +0 -26
- package/dist/core/src/off-route/NavigationFSM.d.ts +0 -42
- package/dist/core/src/off-route/NavigationFSM.d.ts.map +0 -1
- package/dist/core/src/off-route/NavigationFSM.js +0 -56
- package/dist/core/src/off-route/OffRouteFSM.d.ts +0 -70
- package/dist/core/src/off-route/OffRouteFSM.d.ts.map +0 -1
- package/dist/core/src/off-route/OffRouteFSM.js +0 -151
- package/dist/core/src/predictor/RouteOffsetPredictor.d.ts +0 -24
- package/dist/core/src/predictor/RouteOffsetPredictor.d.ts.map +0 -1
- package/dist/core/src/predictor/RouteOffsetPredictor.js +0 -55
- package/dist/core/src/progress/InstructionEditor.d.ts +0 -77
- package/dist/core/src/progress/InstructionEditor.d.ts.map +0 -1
- package/dist/core/src/progress/InstructionEditor.js +0 -151
- package/dist/core/src/progress/InstructionResolver.d.ts +0 -25
- package/dist/core/src/progress/InstructionResolver.d.ts.map +0 -1
- package/dist/core/src/progress/InstructionResolver.js +0 -78
- package/dist/core/src/progress/ProgressTracker.d.ts +0 -12
- package/dist/core/src/progress/ProgressTracker.d.ts.map +0 -1
- package/dist/core/src/progress/ProgressTracker.js +0 -22
- package/dist/core/src/renderer/MapRendererAdapter.d.ts +0 -72
- package/dist/core/src/renderer/MapRendererAdapter.d.ts.map +0 -1
- package/dist/core/src/renderer/MapRendererAdapter.js +0 -19
- package/dist/core/src/route-builder/CustomRouteBuilder.d.ts +0 -83
- package/dist/core/src/route-builder/CustomRouteBuilder.d.ts.map +0 -1
- package/dist/core/src/route-builder/CustomRouteBuilder.js +0 -160
- package/dist/core/src/route-plan/RoutePlan.d.ts +0 -38
- package/dist/core/src/route-plan/RoutePlan.d.ts.map +0 -1
- package/dist/core/src/route-plan/RoutePlan.js +0 -102
- package/dist/core/src/session/NavigationSession.d.ts +0 -81
- package/dist/core/src/session/NavigationSession.d.ts.map +0 -1
- package/dist/core/src/session/NavigationSession.js +0 -115
- package/dist/core/src/snapper/ParallelRoadResolver.d.ts +0 -86
- package/dist/core/src/snapper/ParallelRoadResolver.d.ts.map +0 -1
- package/dist/core/src/snapper/ParallelRoadResolver.js +0 -83
- package/dist/core/src/snapper/RouteSnapper.d.ts +0 -38
- package/dist/core/src/snapper/RouteSnapper.d.ts.map +0 -1
- package/dist/core/src/snapper/RouteSnapper.js +0 -80
- package/dist/core/src/voice/VoiceTriggerEngine.d.ts +0 -80
- package/dist/core/src/voice/VoiceTriggerEngine.d.ts.map +0 -1
- package/dist/core/src/voice/VoiceTriggerEngine.js +0 -108
- package/dist/simulator/src/core/NoiseEngine.d.ts +0 -46
- package/dist/simulator/src/core/NoiseEngine.d.ts.map +0 -1
- package/dist/simulator/src/core/NoiseEngine.js +0 -106
- package/dist/simulator/src/core/RouteWalker.d.ts +0 -78
- package/dist/simulator/src/core/RouteWalker.d.ts.map +0 -1
- package/dist/simulator/src/core/RouteWalker.js +0 -180
- package/dist/simulator/src/core/SimulatorEngine.d.ts +0 -53
- package/dist/simulator/src/core/SimulatorEngine.d.ts.map +0 -1
- package/dist/simulator/src/core/SimulatorEngine.js +0 -298
- package/dist/simulator/src/core/types.d.ts +0 -157
- package/dist/simulator/src/core/types.d.ts.map +0 -1
- package/dist/simulator/src/core/types.js +0 -7
- package/dist/simulator/src/fleet/FleetSimulator.d.ts +0 -60
- package/dist/simulator/src/fleet/FleetSimulator.d.ts.map +0 -1
- package/dist/simulator/src/fleet/FleetSimulator.js +0 -114
- package/dist/simulator/src/index.d.ts +0 -28
- package/dist/simulator/src/index.d.ts.map +0 -1
- package/dist/simulator/src/index.js +0 -29
- package/dist/simulator/src/node.d.ts +0 -26
- package/dist/simulator/src/node.d.ts.map +0 -1
- package/dist/simulator/src/node.js +0 -25
- package/dist/simulator/src/react-native/SimulatorControls.d.ts +0 -35
- package/dist/simulator/src/react-native/SimulatorControls.d.ts.map +0 -1
- package/dist/simulator/src/react-native/SimulatorControls.js +0 -254
- package/dist/simulator/src/react-native/useSimulator.d.ts.map +0 -1
- package/dist/simulator/src/react-native/useSimulator.js +0 -100
- package/dist/simulator/src/replay/GpxParser.d.ts +0 -40
- package/dist/simulator/src/replay/GpxParser.d.ts.map +0 -1
- package/dist/simulator/src/replay/GpxParser.js +0 -95
- package/dist/simulator/src/replay/SessionRecorder.d.ts +0 -37
- package/dist/simulator/src/replay/SessionRecorder.d.ts.map +0 -1
- package/dist/simulator/src/replay/SessionRecorder.js +0 -120
- package/dist/simulator/src/scenarios/ScenarioInjector.d.ts +0 -55
- package/dist/simulator/src/scenarios/ScenarioInjector.d.ts.map +0 -1
- package/dist/simulator/src/scenarios/ScenarioInjector.js +0 -150
- package/src/__tests__/integration/simulator-pipeline.test.ts +0 -233
- package/src/core/NoiseEngine.ts +0 -137
- package/src/core/RouteWalker.ts +0 -227
- package/src/core/SimulatorEngine.ts +0 -364
- package/src/core/__tests__/NoiseEngine.test.ts +0 -131
- package/src/core/__tests__/RouteWalker.test.ts +0 -139
- package/src/core/__tests__/SimulatorEngine.test.ts +0 -317
- package/src/core/types.ts +0 -191
- package/src/fleet/FleetSimulator.ts +0 -162
- package/src/index.ts +0 -54
- package/src/node.ts +0 -48
- package/src/react-native/SimulatorControls.tsx +0 -473
- package/src/react-native/useSimulator.ts +0 -155
- package/src/replay/GpxParser.ts +0 -122
- package/src/replay/SessionRecorder.ts +0 -138
- package/src/replay/__tests__/GpxParser.test.ts +0 -136
- package/src/scenarios/ScenarioInjector.ts +0 -170
- package/src/scenarios/__tests__/ScenarioInjector.test.ts +0 -171
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Module 10: CustomRouteBuilder
|
|
3
|
-
* Build custom routes with unlimited waypoints, chunking, and GPX/GeoJSON.
|
|
4
|
-
*/
|
|
5
|
-
let _counter = 0;
|
|
6
|
-
function generateId() {
|
|
7
|
-
return `wp_${Date.now()}_${++_counter}`;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* CustomRouteBuilder — builds exam routes from waypoints.
|
|
11
|
-
*
|
|
12
|
-
* Pass a DirectionsProvider to `build()` for routed connections.
|
|
13
|
-
* Without a provider, `build()` returns straight-line geometry.
|
|
14
|
-
*/
|
|
15
|
-
export class CustomRouteBuilder {
|
|
16
|
-
constructor() {
|
|
17
|
-
this.waypoints = [];
|
|
18
|
-
}
|
|
19
|
-
/** Add a waypoint at the end. Returns the generated ID. */
|
|
20
|
-
addWaypoint(coord, options) {
|
|
21
|
-
const id = generateId();
|
|
22
|
-
this.waypoints.push({ id, coord, options });
|
|
23
|
-
return id;
|
|
24
|
-
}
|
|
25
|
-
/** Insert a waypoint after an existing one. Returns the new ID. */
|
|
26
|
-
insertWaypoint(coord, afterId) {
|
|
27
|
-
const idx = this.waypoints.findIndex(w => w.id === afterId);
|
|
28
|
-
if (idx === -1)
|
|
29
|
-
throw new Error(`Waypoint ${afterId} not found`);
|
|
30
|
-
const id = generateId();
|
|
31
|
-
this.waypoints.splice(idx + 1, 0, { id, coord, options: undefined });
|
|
32
|
-
return id;
|
|
33
|
-
}
|
|
34
|
-
/** Remove a waypoint by ID */
|
|
35
|
-
removeWaypoint(id) {
|
|
36
|
-
const idx = this.waypoints.findIndex(w => w.id === id);
|
|
37
|
-
if (idx === -1)
|
|
38
|
-
throw new Error(`Waypoint ${id} not found`);
|
|
39
|
-
this.waypoints.splice(idx, 1);
|
|
40
|
-
}
|
|
41
|
-
/** Move a waypoint to a new coordinate */
|
|
42
|
-
moveWaypoint(id, newCoord) {
|
|
43
|
-
const wp = this.waypoints.find(w => w.id === id);
|
|
44
|
-
if (!wp)
|
|
45
|
-
throw new Error(`Waypoint ${id} not found`);
|
|
46
|
-
wp.coord = newCoord;
|
|
47
|
-
}
|
|
48
|
-
/** Get all current waypoints */
|
|
49
|
-
getWaypoints() {
|
|
50
|
-
return this.waypoints;
|
|
51
|
-
}
|
|
52
|
-
/** Get the number of waypoints */
|
|
53
|
-
get size() {
|
|
54
|
-
return this.waypoints.length;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Chunk waypoints for a provider with max waypoint limits.
|
|
58
|
-
* OVERLAP_1: adjacent chunks share 1 waypoint (last of prev = first of next)
|
|
59
|
-
* OVERLAP_2: adjacent chunks share 2 waypoints
|
|
60
|
-
*/
|
|
61
|
-
chunk(strategy = 'OVERLAP_1', maxPerChunk = 25) {
|
|
62
|
-
const coords = this.waypoints.map(w => w.coord);
|
|
63
|
-
if (coords.length <= maxPerChunk)
|
|
64
|
-
return [coords];
|
|
65
|
-
const overlap = strategy === 'OVERLAP_2' ? 2 : 1;
|
|
66
|
-
const step = maxPerChunk - overlap;
|
|
67
|
-
const chunks = [];
|
|
68
|
-
for (let i = 0; i < coords.length; i += step) {
|
|
69
|
-
const chunk = coords.slice(i, i + maxPerChunk);
|
|
70
|
-
chunks.push(chunk);
|
|
71
|
-
if (i + maxPerChunk >= coords.length)
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
return chunks;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Build straight-line geometry (no provider needed).
|
|
78
|
-
* For routed geometry, pass chunks to a DirectionsProvider externally.
|
|
79
|
-
*/
|
|
80
|
-
buildStraightLine() {
|
|
81
|
-
return {
|
|
82
|
-
geometry: this.waypoints.map(w => w.coord),
|
|
83
|
-
waypoints: [...this.waypoints],
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
/** Import waypoints from a GPX string */
|
|
87
|
-
fromGPX(gpx) {
|
|
88
|
-
this.waypoints = [];
|
|
89
|
-
// Minimal GPX parser — extract <trkpt> and <wpt> elements
|
|
90
|
-
const pointRegex = /<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g;
|
|
91
|
-
let match;
|
|
92
|
-
while ((match = pointRegex.exec(gpx)) !== null) {
|
|
93
|
-
const lat = parseFloat(match[1]);
|
|
94
|
-
const lon = parseFloat(match[2]);
|
|
95
|
-
if (isFinite(lat) && isFinite(lon)) {
|
|
96
|
-
this.addWaypoint([lon, lat]);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
/** Export the current waypoints as a GPX string */
|
|
101
|
-
toGPX() {
|
|
102
|
-
const points = this.waypoints.map(w => ` <wpt lat="${w.coord[1]}" lon="${w.coord[0]}">` +
|
|
103
|
-
(w.options?.name ? `\n <name>${w.options.name}</name>` : '') +
|
|
104
|
-
`\n </wpt>`).join('\n');
|
|
105
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
106
|
-
<gpx version="1.1" creator="NavCore SDK">
|
|
107
|
-
${points}
|
|
108
|
-
</gpx>`;
|
|
109
|
-
}
|
|
110
|
-
/** Import waypoints from GeoJSON */
|
|
111
|
-
fromGeoJSON(geojson) {
|
|
112
|
-
this.waypoints = [];
|
|
113
|
-
if (geojson.type === 'FeatureCollection' && geojson.features) {
|
|
114
|
-
for (const feature of geojson.features) {
|
|
115
|
-
if (feature.geometry.type === 'Point') {
|
|
116
|
-
const coord = feature.geometry.coordinates;
|
|
117
|
-
this.addWaypoint(coord);
|
|
118
|
-
}
|
|
119
|
-
else if (feature.geometry.type === 'LineString') {
|
|
120
|
-
const coords = feature.geometry.coordinates;
|
|
121
|
-
for (const coord of coords) {
|
|
122
|
-
this.addWaypoint(coord);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
/** Export the current route as GeoJSON FeatureCollection */
|
|
129
|
-
toGeoJSON() {
|
|
130
|
-
const pointFeatures = this.waypoints.map((w, i) => ({
|
|
131
|
-
type: 'Feature',
|
|
132
|
-
geometry: {
|
|
133
|
-
type: 'Point',
|
|
134
|
-
coordinates: w.coord,
|
|
135
|
-
},
|
|
136
|
-
properties: {
|
|
137
|
-
id: w.id,
|
|
138
|
-
order: i,
|
|
139
|
-
name: w.options?.name ?? null,
|
|
140
|
-
silent: w.options?.silent ?? false,
|
|
141
|
-
},
|
|
142
|
-
}));
|
|
143
|
-
const lineFeature = {
|
|
144
|
-
type: 'Feature',
|
|
145
|
-
geometry: {
|
|
146
|
-
type: 'LineString',
|
|
147
|
-
coordinates: this.waypoints.map(w => w.coord),
|
|
148
|
-
},
|
|
149
|
-
properties: { type: 'route' },
|
|
150
|
-
};
|
|
151
|
-
return {
|
|
152
|
-
type: 'FeatureCollection',
|
|
153
|
-
features: [...pointFeatures, lineFeature],
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
/** Clear all waypoints */
|
|
157
|
-
clear() {
|
|
158
|
-
this.waypoints = [];
|
|
159
|
-
}
|
|
160
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RoutePlan — the canonical, navigation-ready form of a provider route.
|
|
3
|
-
*
|
|
4
|
-
* Directions providers return vendor-specific steps and geometry. NavCore needs
|
|
5
|
-
* instructions positioned on that geometry. This module owns that conversion so
|
|
6
|
-
* applications do not need provider-specific glue code.
|
|
7
|
-
*/
|
|
8
|
-
import type { DirectionsResult } from '../directions/DirectionsProvider';
|
|
9
|
-
import { type Coordinate } from '../geo/haversine';
|
|
10
|
-
import type { NavInstruction } from '../progress/InstructionResolver';
|
|
11
|
-
export interface RoutePlan {
|
|
12
|
-
/** Validated, immutable route geometry in [lng, lat] order. */
|
|
13
|
-
geometry: ReadonlyArray<Coordinate>;
|
|
14
|
-
/** Immutable, route-aligned maneuver instructions. */
|
|
15
|
-
instructions: ReadonlyArray<NavInstruction>;
|
|
16
|
-
/** Distance measured along the canonical geometry, in metres. */
|
|
17
|
-
distanceM: number;
|
|
18
|
-
/** Duration supplied by the directions provider, in seconds. */
|
|
19
|
-
durationS: number;
|
|
20
|
-
/** Original provider-reported distance, when supplied. */
|
|
21
|
-
providerDistanceM: number;
|
|
22
|
-
/** Optional identifier useful for diagnostics and analytics. */
|
|
23
|
-
provider?: string;
|
|
24
|
-
}
|
|
25
|
-
export interface CreateRoutePlanOptions {
|
|
26
|
-
/** Identifier for the provider that produced the route. */
|
|
27
|
-
provider?: string;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Converts a generic directions response into NavCore's canonical route model.
|
|
31
|
-
*
|
|
32
|
-
* Each maneuver is projected onto the complete route instead of trusting a
|
|
33
|
-
* provider-specific step index. The resulting `cumulativeOffset` is precise to
|
|
34
|
-
* the point within a segment, which keeps progress and voice timing correct on
|
|
35
|
-
* sparse route geometry.
|
|
36
|
-
*/
|
|
37
|
-
export declare function createRoutePlan(result: DirectionsResult, options?: CreateRoutePlanOptions): RoutePlan;
|
|
38
|
-
//# sourceMappingURL=RoutePlan.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RoutePlan.d.ts","sourceRoot":"","sources":["../../../../../core/src/route-plan/RoutePlan.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,WAAW,SAAS;IACxB,+DAA+D;IAC/D,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACpC,sDAAsD;IACtD,YAAY,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;IAC5C,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAQD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,sBAA2B,GACnC,SAAS,CA4BX"}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RoutePlan — the canonical, navigation-ready form of a provider route.
|
|
3
|
-
*
|
|
4
|
-
* Directions providers return vendor-specific steps and geometry. NavCore needs
|
|
5
|
-
* instructions positioned on that geometry. This module owns that conversion so
|
|
6
|
-
* applications do not need provider-specific glue code.
|
|
7
|
-
*/
|
|
8
|
-
import { buildForwardCumulativeDistances } from '../geo/cumulative';
|
|
9
|
-
import { haversineDistance } from '../geo/haversine';
|
|
10
|
-
import { projectPointOnSegment } from '../geo/projection';
|
|
11
|
-
/**
|
|
12
|
-
* Converts a generic directions response into NavCore's canonical route model.
|
|
13
|
-
*
|
|
14
|
-
* Each maneuver is projected onto the complete route instead of trusting a
|
|
15
|
-
* provider-specific step index. The resulting `cumulativeOffset` is precise to
|
|
16
|
-
* the point within a segment, which keeps progress and voice timing correct on
|
|
17
|
-
* sparse route geometry.
|
|
18
|
-
*/
|
|
19
|
-
export function createRoutePlan(result, options = {}) {
|
|
20
|
-
const geometry = copyAndValidateGeometry(result.geometry);
|
|
21
|
-
const cumulative = buildForwardCumulativeDistances(geometry);
|
|
22
|
-
const instructions = result.legs
|
|
23
|
-
.flatMap((leg) => leg.steps ?? [])
|
|
24
|
-
.map((step) => {
|
|
25
|
-
const position = locateOnRoute(step.maneuver.location, geometry, cumulative);
|
|
26
|
-
const text = step.maneuver.instruction ?? step.name;
|
|
27
|
-
return freezeInstruction({
|
|
28
|
-
location: position.coordinate,
|
|
29
|
-
geometryIndex: position.geometryIndex,
|
|
30
|
-
cumulativeOffset: position.cumulativeOffset,
|
|
31
|
-
bearingBefore: step.maneuver.bearingBefore,
|
|
32
|
-
bearingAfter: step.maneuver.bearingAfter,
|
|
33
|
-
...(text ? { text, instruction: text } : {}),
|
|
34
|
-
});
|
|
35
|
-
})
|
|
36
|
-
.sort((a, b) => a.cumulativeOffset - b.cumulativeOffset);
|
|
37
|
-
return Object.freeze({
|
|
38
|
-
geometry: Object.freeze(geometry),
|
|
39
|
-
instructions: Object.freeze(instructions),
|
|
40
|
-
distanceM: cumulative[cumulative.length - 1] ?? 0,
|
|
41
|
-
durationS: requireFiniteNonNegative(result.duration, 'duration'),
|
|
42
|
-
providerDistanceM: requireFiniteNonNegative(result.distance, 'distance'),
|
|
43
|
-
...(options.provider ? { provider: options.provider } : {}),
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
function copyAndValidateGeometry(input) {
|
|
47
|
-
if (input.length < 2) {
|
|
48
|
-
throw new Error('[RoutePlan] A route requires at least two coordinates');
|
|
49
|
-
}
|
|
50
|
-
return input.map((coord, index) => {
|
|
51
|
-
if (!isValidCoordinate(coord)) {
|
|
52
|
-
throw new Error(`[RoutePlan] Invalid coordinate at geometry index ${index}`);
|
|
53
|
-
}
|
|
54
|
-
return Object.freeze([coord[0], coord[1]]);
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
function locateOnRoute(target, geometry, cumulative) {
|
|
58
|
-
if (!isValidCoordinate(target)) {
|
|
59
|
-
throw new Error('[RoutePlan] Invalid maneuver coordinate');
|
|
60
|
-
}
|
|
61
|
-
let best = null;
|
|
62
|
-
let bestDistance = Infinity;
|
|
63
|
-
for (let index = 0; index < geometry.length - 1; index++) {
|
|
64
|
-
const start = geometry[index];
|
|
65
|
-
const end = geometry[index + 1];
|
|
66
|
-
const projected = projectPointOnSegment(target, start, end);
|
|
67
|
-
const distance = haversineDistance(target[1], target[0], projected[1], projected[0]);
|
|
68
|
-
if (distance >= bestDistance)
|
|
69
|
-
continue;
|
|
70
|
-
const segmentLength = haversineDistance(start[1], start[0], end[1], end[0]);
|
|
71
|
-
const fraction = segmentFraction(projected, start, end);
|
|
72
|
-
bestDistance = distance;
|
|
73
|
-
best = {
|
|
74
|
-
geometryIndex: index,
|
|
75
|
-
cumulativeOffset: (cumulative[index] ?? 0) + segmentLength * fraction,
|
|
76
|
-
coordinate: Object.freeze([projected[0], projected[1]]),
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
// Geometry has already been checked for at least two points.
|
|
80
|
-
return best;
|
|
81
|
-
}
|
|
82
|
-
function segmentFraction(point, start, end) {
|
|
83
|
-
const dx = end[0] - start[0];
|
|
84
|
-
const dy = end[1] - start[1];
|
|
85
|
-
const lengthSquared = dx * dx + dy * dy;
|
|
86
|
-
if (lengthSquared === 0)
|
|
87
|
-
return 0;
|
|
88
|
-
return Math.max(0, Math.min(1, ((point[0] - start[0]) * dx + (point[1] - start[1]) * dy) / lengthSquared));
|
|
89
|
-
}
|
|
90
|
-
function freezeInstruction(instruction) {
|
|
91
|
-
return Object.freeze(instruction);
|
|
92
|
-
}
|
|
93
|
-
function isValidCoordinate(coord) {
|
|
94
|
-
return Number.isFinite(coord[0]) && Number.isFinite(coord[1]) &&
|
|
95
|
-
coord[0] >= -180 && coord[0] <= 180 && coord[1] >= -90 && coord[1] <= 90;
|
|
96
|
-
}
|
|
97
|
-
function requireFiniteNonNegative(value, name) {
|
|
98
|
-
if (!Number.isFinite(value) || value < 0) {
|
|
99
|
-
throw new Error(`[RoutePlan] Invalid ${name}`);
|
|
100
|
-
}
|
|
101
|
-
return value;
|
|
102
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NavigationSession — the ergonomic application-facing NavCore API.
|
|
3
|
-
*
|
|
4
|
-
* It owns the route-provider → RoutePlan → NavCore handoff and offers typed
|
|
5
|
-
* subscriptions. `coordinates` are ordered routing waypoints; use `loadRoute`
|
|
6
|
-
* for a route that has already been normalized into a RoutePlan.
|
|
7
|
-
*/
|
|
8
|
-
import type { DirectionsOptions, DirectionsProvider } from '../directions/DirectionsProvider';
|
|
9
|
-
import { NavCore, type NavCoreOptions, type NavCoreState, type NavGpsUpdate } from '../NavCore';
|
|
10
|
-
import type { NavInstruction } from '../progress/InstructionResolver';
|
|
11
|
-
import { type RoutePlan } from '../route-plan/RoutePlan';
|
|
12
|
-
import type { Coordinate } from '../geo/haversine';
|
|
13
|
-
export interface OriginDestinationNavigationRequest {
|
|
14
|
-
origin: Coordinate;
|
|
15
|
-
destination: Coordinate;
|
|
16
|
-
/** Optional stops, traversed in the supplied order. */
|
|
17
|
-
waypoints?: ReadonlyArray<Coordinate>;
|
|
18
|
-
coordinates?: never;
|
|
19
|
-
directions?: DirectionsOptions;
|
|
20
|
-
}
|
|
21
|
-
export interface CoordinatesNavigationRequest {
|
|
22
|
-
/** Ordered routing waypoints. At least two are required. */
|
|
23
|
-
coordinates: ReadonlyArray<Coordinate>;
|
|
24
|
-
origin?: never;
|
|
25
|
-
destination?: never;
|
|
26
|
-
waypoints?: never;
|
|
27
|
-
directions?: DirectionsOptions;
|
|
28
|
-
}
|
|
29
|
-
export type NavigationRequest = OriginDestinationNavigationRequest | CoordinatesNavigationRequest;
|
|
30
|
-
export interface NavigationSessionOptions {
|
|
31
|
-
provider: DirectionsProvider;
|
|
32
|
-
/** Optional provider label retained on created RoutePlans. */
|
|
33
|
-
providerName?: string;
|
|
34
|
-
/** Reuse an existing engine; the caller retains responsibility for it. */
|
|
35
|
-
engine?: NavCore;
|
|
36
|
-
/** Options used only when the session creates its own engine. */
|
|
37
|
-
engineOptions?: NavCoreOptions;
|
|
38
|
-
}
|
|
39
|
-
export interface NavigationSessionEventMap {
|
|
40
|
-
state: NavCoreState;
|
|
41
|
-
routeLoaded: RoutePlan;
|
|
42
|
-
navigationStarted: undefined;
|
|
43
|
-
instruction: NavInstruction;
|
|
44
|
-
deviation: {
|
|
45
|
-
anchorIndex: number;
|
|
46
|
-
ghostCoord: Coordinate;
|
|
47
|
-
};
|
|
48
|
-
rejoined: {
|
|
49
|
-
resumeIndex: number;
|
|
50
|
-
};
|
|
51
|
-
arrival: undefined;
|
|
52
|
-
}
|
|
53
|
-
type EventName = keyof NavigationSessionEventMap;
|
|
54
|
-
type EventHandler<K extends EventName> = (payload: NavigationSessionEventMap[K]) => void;
|
|
55
|
-
export declare class NavigationSession {
|
|
56
|
-
readonly engine: NavCore;
|
|
57
|
-
private readonly provider;
|
|
58
|
-
private readonly providerName?;
|
|
59
|
-
private readonly ownsEngine;
|
|
60
|
-
private readonly listeners;
|
|
61
|
-
private readonly engineListeners;
|
|
62
|
-
private destroyed;
|
|
63
|
-
private currentPlan;
|
|
64
|
-
constructor(options: NavigationSessionOptions);
|
|
65
|
-
/** Fetch, normalize, load, and start a route from either supported input form. */
|
|
66
|
-
navigate(request: NavigationRequest): Promise<RoutePlan>;
|
|
67
|
-
/** Load a route that was previously normalized, optionally starting navigation. */
|
|
68
|
-
loadRoute(plan: RoutePlan, start?: boolean): void;
|
|
69
|
-
update(gps: NavGpsUpdate): NavCoreState;
|
|
70
|
-
tick(nowMs: number): NavCoreState;
|
|
71
|
-
getState(): NavCoreState;
|
|
72
|
-
getRoutePlan(): RoutePlan | null;
|
|
73
|
-
/** Subscribe to a typed event. Returns an unsubscribe function. */
|
|
74
|
-
subscribe<K extends EventName>(event: K, handler: EventHandler<K>): () => void;
|
|
75
|
-
destroy(): void;
|
|
76
|
-
private emit;
|
|
77
|
-
private assertActive;
|
|
78
|
-
}
|
|
79
|
-
export declare function createNavigationSession(options: NavigationSessionOptions): NavigationSession;
|
|
80
|
-
export {};
|
|
81
|
-
//# sourceMappingURL=NavigationSession.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationSession.d.ts","sourceRoot":"","sources":["../../../../../core/src/session/NavigationSession.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NavigationSession — the ergonomic application-facing NavCore API.
|
|
3
|
-
*
|
|
4
|
-
* It owns the route-provider → RoutePlan → NavCore handoff and offers typed
|
|
5
|
-
* subscriptions. `coordinates` are ordered routing waypoints; use `loadRoute`
|
|
6
|
-
* for a route that has already been normalized into a RoutePlan.
|
|
7
|
-
*/
|
|
8
|
-
import { NavCore } from '../NavCore';
|
|
9
|
-
import { createRoutePlan } from '../route-plan/RoutePlan';
|
|
10
|
-
export class NavigationSession {
|
|
11
|
-
constructor(options) {
|
|
12
|
-
this.listeners = new Map();
|
|
13
|
-
this.destroyed = false;
|
|
14
|
-
this.currentPlan = null;
|
|
15
|
-
this.provider = options.provider;
|
|
16
|
-
this.providerName = options.providerName;
|
|
17
|
-
this.ownsEngine = !options.engine;
|
|
18
|
-
this.engine = options.engine ?? new NavCore(options.engineOptions);
|
|
19
|
-
this.engineListeners = [
|
|
20
|
-
{ event: 'update', handler: (state) => this.emit('state', state) },
|
|
21
|
-
{ event: 'instruction', handler: (instruction) => this.emit('instruction', instruction) },
|
|
22
|
-
{ event: 'deviation', handler: (event) => this.emit('deviation', event) },
|
|
23
|
-
{ event: 'rejoined', handler: (event) => this.emit('rejoined', event) },
|
|
24
|
-
{ event: 'arrival', handler: () => this.emit('arrival', undefined) },
|
|
25
|
-
];
|
|
26
|
-
for (const { event, handler } of this.engineListeners) {
|
|
27
|
-
this.engine.on(event, handler);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/** Fetch, normalize, load, and start a route from either supported input form. */
|
|
31
|
-
async navigate(request) {
|
|
32
|
-
this.assertActive();
|
|
33
|
-
const result = await this.provider.getRoute(resolveWaypoints(request), request.directions);
|
|
34
|
-
const plan = createRoutePlan(result, { provider: this.providerName });
|
|
35
|
-
this.loadRoute(plan, true);
|
|
36
|
-
return plan;
|
|
37
|
-
}
|
|
38
|
-
/** Load a route that was previously normalized, optionally starting navigation. */
|
|
39
|
-
loadRoute(plan, start = false) {
|
|
40
|
-
this.assertActive();
|
|
41
|
-
this.currentPlan = plan;
|
|
42
|
-
this.engine.loadRoute(plan);
|
|
43
|
-
this.emit('routeLoaded', plan);
|
|
44
|
-
if (start) {
|
|
45
|
-
this.engine.startNavigation();
|
|
46
|
-
this.emit('navigationStarted', undefined);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
update(gps) {
|
|
50
|
-
this.assertActive();
|
|
51
|
-
return this.engine.update(gps);
|
|
52
|
-
}
|
|
53
|
-
tick(nowMs) {
|
|
54
|
-
this.assertActive();
|
|
55
|
-
return this.engine.tick(nowMs);
|
|
56
|
-
}
|
|
57
|
-
getState() {
|
|
58
|
-
return this.engine.getState();
|
|
59
|
-
}
|
|
60
|
-
getRoutePlan() {
|
|
61
|
-
return this.currentPlan;
|
|
62
|
-
}
|
|
63
|
-
/** Subscribe to a typed event. Returns an unsubscribe function. */
|
|
64
|
-
subscribe(event, handler) {
|
|
65
|
-
this.assertActive();
|
|
66
|
-
const handlers = this.listeners.get(event) ?? new Set();
|
|
67
|
-
const untypedHandler = handler;
|
|
68
|
-
handlers.add(untypedHandler);
|
|
69
|
-
this.listeners.set(event, handlers);
|
|
70
|
-
return () => {
|
|
71
|
-
handlers.delete(untypedHandler);
|
|
72
|
-
if (handlers.size === 0)
|
|
73
|
-
this.listeners.delete(event);
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
destroy() {
|
|
77
|
-
if (this.destroyed)
|
|
78
|
-
return;
|
|
79
|
-
this.destroyed = true;
|
|
80
|
-
for (const { event, handler } of this.engineListeners) {
|
|
81
|
-
this.engine.off(event, handler);
|
|
82
|
-
}
|
|
83
|
-
this.listeners.clear();
|
|
84
|
-
this.currentPlan = null;
|
|
85
|
-
if (this.ownsEngine)
|
|
86
|
-
this.engine.destroy();
|
|
87
|
-
}
|
|
88
|
-
emit(event, payload) {
|
|
89
|
-
for (const handler of this.listeners.get(event) ?? []) {
|
|
90
|
-
handler(payload);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
assertActive() {
|
|
94
|
-
if (this.destroyed)
|
|
95
|
-
throw new Error('[NavigationSession] Session has been destroyed');
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
export function createNavigationSession(options) {
|
|
99
|
-
return new NavigationSession(options);
|
|
100
|
-
}
|
|
101
|
-
function resolveWaypoints(request) {
|
|
102
|
-
const coordinates = request.coordinates !== undefined
|
|
103
|
-
? request.coordinates
|
|
104
|
-
: [request.origin, ...(request.waypoints ?? []), request.destination];
|
|
105
|
-
if (coordinates.length < 2) {
|
|
106
|
-
throw new Error('[NavigationSession] At least two routing coordinates are required');
|
|
107
|
-
}
|
|
108
|
-
return coordinates.map((coordinate, index) => {
|
|
109
|
-
if (!Number.isFinite(coordinate[0]) || !Number.isFinite(coordinate[1]) ||
|
|
110
|
-
coordinate[0] < -180 || coordinate[0] > 180 || coordinate[1] < -90 || coordinate[1] > 90) {
|
|
111
|
-
throw new Error(`[NavigationSession] Invalid routing coordinate at index ${index}`);
|
|
112
|
-
}
|
|
113
|
-
return [coordinate[0], coordinate[1]];
|
|
114
|
-
});
|
|
115
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ParallelRoadResolver
|
|
3
|
-
*
|
|
4
|
-
* First-class feature: resolve GPS ambiguity on parallel roads (e.g. dual carriageways,
|
|
5
|
-
* motorway + service road) and prevent U-turn snap.
|
|
6
|
-
*
|
|
7
|
-
* Extracts and extends the bearing penalty + inertia logic from RouteSnapper
|
|
8
|
-
* into a standalone, composable API that can be used independently.
|
|
9
|
-
*
|
|
10
|
-
* FEATURE: PARALLEL_ROAD_RESOLUTION + U_TURN_PROTECTION
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* const resolver = new ParallelRoadResolver({ bearingPenalty: 80, inertiaPenalty: 40 });
|
|
15
|
-
* const best = resolver.resolve(candidates, vehicleBearing, prevSegmentIndex);
|
|
16
|
-
* ```
|
|
17
|
-
*/
|
|
18
|
-
import type { Coordinate } from '../geo/haversine';
|
|
19
|
-
export interface SnapCandidate {
|
|
20
|
-
/** Route segment index */
|
|
21
|
-
segmentIndex: number;
|
|
22
|
-
/** Projected point on segment */
|
|
23
|
-
projectedCoord: Coordinate;
|
|
24
|
-
/** Raw distance to route in metres */
|
|
25
|
-
distanceMetres: number;
|
|
26
|
-
/** Start of segment */
|
|
27
|
-
segA: Coordinate;
|
|
28
|
-
/** End of segment */
|
|
29
|
-
segB: Coordinate;
|
|
30
|
-
}
|
|
31
|
-
export interface ResolvedCandidate extends SnapCandidate {
|
|
32
|
-
/** Final score (lower is better) */
|
|
33
|
-
score: number;
|
|
34
|
-
/** Bearing delta that triggered U-turn protection (null if not triggered) */
|
|
35
|
-
bearingDeltaDeg: number | null;
|
|
36
|
-
/** Whether inertia penalty was applied */
|
|
37
|
-
inertiaPenaltyApplied: boolean;
|
|
38
|
-
}
|
|
39
|
-
export interface ParallelRoadResolverOptions {
|
|
40
|
-
/**
|
|
41
|
-
* Penalty added to score when vehicle bearing mismatches segment bearing
|
|
42
|
-
* beyond `bearingMismatchThresholdDeg`. Default: 80m equivalent.
|
|
43
|
-
*/
|
|
44
|
-
bearingPenalty?: number;
|
|
45
|
-
/**
|
|
46
|
-
* Bearing mismatch threshold in degrees that activates the penalty.
|
|
47
|
-
* Default: 60°. Higher = more tolerant of U-turns.
|
|
48
|
-
*/
|
|
49
|
-
bearingMismatchThresholdDeg?: number;
|
|
50
|
-
/**
|
|
51
|
-
* Penalty added when the candidate segment is far from the previously
|
|
52
|
-
* snapped segment, preventing oscillation. Default: 40m equivalent.
|
|
53
|
-
*/
|
|
54
|
-
inertiaPenalty?: number;
|
|
55
|
-
/**
|
|
56
|
-
* Minimum segment jump (in index units) to trigger inertia penalty.
|
|
57
|
-
* Default: 3.
|
|
58
|
-
*/
|
|
59
|
-
inertiaSegmentDist?: number;
|
|
60
|
-
}
|
|
61
|
-
export declare class ParallelRoadResolver {
|
|
62
|
-
private readonly options;
|
|
63
|
-
constructor(options?: ParallelRoadResolverOptions);
|
|
64
|
-
/**
|
|
65
|
-
* Score and sort snap candidates — lowest score wins.
|
|
66
|
-
*
|
|
67
|
-
* @param candidates Raw snap candidates (distance-sorted or unsorted)
|
|
68
|
-
* @param vehicleBearing Current vehicle heading in degrees (null disables bearing check)
|
|
69
|
-
* @param prevSegmentIdx Previously snapped segment index (null disables inertia)
|
|
70
|
-
* @returns Candidates sorted by score ascending, with debug metadata attached
|
|
71
|
-
*/
|
|
72
|
-
resolve(candidates: SnapCandidate[], vehicleBearing?: number | null, prevSegmentIdx?: number | null): ResolvedCandidate[];
|
|
73
|
-
/**
|
|
74
|
-
* Resolve and return only the best candidate.
|
|
75
|
-
*/
|
|
76
|
-
resolveBest(candidates: SnapCandidate[], vehicleBearing?: number | null, prevSegmentIdx?: number | null): ResolvedCandidate | null;
|
|
77
|
-
private score;
|
|
78
|
-
/**
|
|
79
|
-
* Quick utility: detect if the vehicle is likely performing a U-turn
|
|
80
|
-
* based on the difference between current bearing and route segment bearing.
|
|
81
|
-
*
|
|
82
|
-
* @returns true if the bearing difference exceeds the configured threshold
|
|
83
|
-
*/
|
|
84
|
-
isLikelyUTurn(vehicleBearing: number, segA: Coordinate, segB: Coordinate): boolean;
|
|
85
|
-
}
|
|
86
|
-
//# sourceMappingURL=ParallelRoadResolver.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ParallelRoadResolver.d.ts","sourceRoot":"","sources":["../../../../../core/src/snapper/ParallelRoadResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,cAAc,EAAE,UAAU,CAAC;IAC3B,sCAAsC;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB;IACvB,IAAI,EAAE,UAAU,CAAC;IACjB,qBAAqB;IACrB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,0CAA0C;IAC1C,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AASD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwC;gBAEpD,OAAO,CAAC,EAAE,2BAA2B;IAIjD;;;;;;;OAOG;IACH,OAAO,CACL,UAAU,EAAE,aAAa,EAAE,EAC3B,cAAc,GAAE,MAAM,GAAG,IAAW,EACpC,cAAc,GAAE,MAAM,GAAG,IAAW,GACnC,iBAAiB,EAAE;IAMtB;;OAEG;IACH,WAAW,CACT,UAAU,EAAE,aAAa,EAAE,EAC3B,cAAc,GAAE,MAAM,GAAG,IAAW,EACpC,cAAc,GAAE,MAAM,GAAG,IAAW,GACnC,iBAAiB,GAAG,IAAI;IAM3B,OAAO,CAAC,KAAK;IA+Bb;;;;;OAKG;IACH,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO;CAKnF"}
|