@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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FleetSimulator — Phase 2 skeleton.
|
|
3
|
-
*
|
|
4
|
-
* Spawns N SimulatorEngine instances with optional per-vehicle profile
|
|
5
|
-
* overrides, runs them in parallel, and produces aggregate reports.
|
|
6
|
-
*
|
|
7
|
-
* @experimental — fully typed but not tested in Phase 1.
|
|
8
|
-
* Activate in a future iteration once SimulatorEngine is validated in CI.
|
|
9
|
-
*/
|
|
10
|
-
import { SimulatorEngine } from '../core/SimulatorEngine';
|
|
11
|
-
import type { SimulatorConfig, SimSession } from '../core/types';
|
|
12
|
-
export interface VehicleProfile extends Partial<SimulatorConfig> {
|
|
13
|
-
/** Human-readable label for this vehicle profile */
|
|
14
|
-
label?: string;
|
|
15
|
-
}
|
|
16
|
-
export interface FleetReport {
|
|
17
|
-
vehicles: Array<{
|
|
18
|
-
id: number;
|
|
19
|
-
label: string;
|
|
20
|
-
session: SimSession;
|
|
21
|
-
profile: VehicleProfile;
|
|
22
|
-
}>;
|
|
23
|
-
comparison: {
|
|
24
|
-
/** Average stats keyed by vehicle label */
|
|
25
|
-
avgScoreByProfile: Record<string, number>;
|
|
26
|
-
/** Per-segment noise deviation across all vehicles (heatmap data) */
|
|
27
|
-
deviationsBySegment: number[];
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
export declare class FleetSimulator {
|
|
31
|
-
private readonly engines;
|
|
32
|
-
private readonly profiles;
|
|
33
|
-
private readonly baseConfig;
|
|
34
|
-
private constructor();
|
|
35
|
-
/**
|
|
36
|
-
* Spawn N SimulatorEngine instances.
|
|
37
|
-
*
|
|
38
|
-
* @param count - number of vehicles
|
|
39
|
-
* @param config - base config (onPositionUpdate is per-vehicle, excluded here)
|
|
40
|
-
*/
|
|
41
|
-
static spawn(count: number, config: Omit<SimulatorConfig, 'onPositionUpdate'> & {
|
|
42
|
-
profiles?: VehicleProfile[];
|
|
43
|
-
}): FleetSimulator;
|
|
44
|
-
/** Start all engines simultaneously */
|
|
45
|
-
start(): void;
|
|
46
|
-
/** Stop all engines */
|
|
47
|
-
stop(): void;
|
|
48
|
-
/**
|
|
49
|
-
* Get the engine at the given index.
|
|
50
|
-
* Use this for per-vehicle control (seek, setSpeed, addScenario, etc.)
|
|
51
|
-
*/
|
|
52
|
-
vehicle(index: number): SimulatorEngine;
|
|
53
|
-
/**
|
|
54
|
-
* Stop all engines, collect sessions, and return an aggregate report.
|
|
55
|
-
*/
|
|
56
|
-
report(): FleetReport;
|
|
57
|
-
/** Destroy all engines and clean up */
|
|
58
|
-
destroy(): void;
|
|
59
|
-
}
|
|
60
|
-
//# sourceMappingURL=FleetSimulator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FleetSimulator.d.ts","sourceRoot":"","sources":["../../../../src/fleet/FleetSimulator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEjE,MAAM,WAAW,cAAe,SAAQ,OAAO,CAAC,eAAe,CAAC;IAC9D,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,UAAU,CAAC;QACpB,OAAO,EAAE,cAAc,CAAC;KACzB,CAAC,CAAC;IACH,UAAU,EAAE;QACV,2CAA2C;QAC3C,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1C,qEAAqE;QACrE,mBAAmB,EAAE,MAAM,EAAE,CAAC;KAC/B,CAAC;CACH;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4C;IAEvE,OAAO;IAUP;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG;QAClD,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;KAC7B,GACA,cAAc;IAsBjB,uCAAuC;IACvC,KAAK,IAAI,IAAI;IAOb,uBAAuB;IACvB,IAAI,IAAI,IAAI;IAMZ;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe;IAMvC;;OAEG;IACH,MAAM,IAAI,WAAW;IA8CrB,uCAAuC;IACvC,OAAO,IAAI,IAAI;CAKhB"}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FleetSimulator — Phase 2 skeleton.
|
|
3
|
-
*
|
|
4
|
-
* Spawns N SimulatorEngine instances with optional per-vehicle profile
|
|
5
|
-
* overrides, runs them in parallel, and produces aggregate reports.
|
|
6
|
-
*
|
|
7
|
-
* @experimental — fully typed but not tested in Phase 1.
|
|
8
|
-
* Activate in a future iteration once SimulatorEngine is validated in CI.
|
|
9
|
-
*/
|
|
10
|
-
import { SimulatorEngine } from '../core/SimulatorEngine';
|
|
11
|
-
export class FleetSimulator {
|
|
12
|
-
constructor(engines, profiles, baseConfig) {
|
|
13
|
-
this.engines = engines;
|
|
14
|
-
this.profiles = profiles;
|
|
15
|
-
this.baseConfig = baseConfig;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Spawn N SimulatorEngine instances.
|
|
19
|
-
*
|
|
20
|
-
* @param count - number of vehicles
|
|
21
|
-
* @param config - base config (onPositionUpdate is per-vehicle, excluded here)
|
|
22
|
-
*/
|
|
23
|
-
static spawn(count, config) {
|
|
24
|
-
const { profiles = [], ...baseConfig } = config;
|
|
25
|
-
const engines = [];
|
|
26
|
-
const resolvedProfiles = [];
|
|
27
|
-
for (let i = 0; i < count; i++) {
|
|
28
|
-
const profile = profiles[i] ?? {};
|
|
29
|
-
resolvedProfiles.push(profile);
|
|
30
|
-
const engine = new SimulatorEngine({
|
|
31
|
-
...baseConfig,
|
|
32
|
-
...profile,
|
|
33
|
-
onPositionUpdate: undefined,
|
|
34
|
-
});
|
|
35
|
-
engines.push(engine);
|
|
36
|
-
}
|
|
37
|
-
return new FleetSimulator(engines, resolvedProfiles, baseConfig);
|
|
38
|
-
}
|
|
39
|
-
/** Start all engines simultaneously */
|
|
40
|
-
start() {
|
|
41
|
-
for (const engine of this.engines) {
|
|
42
|
-
engine.startRecording();
|
|
43
|
-
engine.start();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/** Stop all engines */
|
|
47
|
-
stop() {
|
|
48
|
-
for (const engine of this.engines) {
|
|
49
|
-
engine.stop();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Get the engine at the given index.
|
|
54
|
-
* Use this for per-vehicle control (seek, setSpeed, addScenario, etc.)
|
|
55
|
-
*/
|
|
56
|
-
vehicle(index) {
|
|
57
|
-
const engine = this.engines[index];
|
|
58
|
-
if (!engine)
|
|
59
|
-
throw new Error(`FleetSimulator: no vehicle at index ${index}`);
|
|
60
|
-
return engine;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Stop all engines, collect sessions, and return an aggregate report.
|
|
64
|
-
*/
|
|
65
|
-
report() {
|
|
66
|
-
const vehicleReports = this.engines.map((engine, i) => {
|
|
67
|
-
const session = engine.stopRecording();
|
|
68
|
-
const profile = this.profiles[i] ?? {};
|
|
69
|
-
return {
|
|
70
|
-
id: i,
|
|
71
|
-
label: profile.label ?? `vehicle-${i}`,
|
|
72
|
-
session,
|
|
73
|
-
profile,
|
|
74
|
-
};
|
|
75
|
-
});
|
|
76
|
-
// Compute average speed per profile label
|
|
77
|
-
const avgScoreByProfile = {};
|
|
78
|
-
for (const v of vehicleReports) {
|
|
79
|
-
const key = v.label;
|
|
80
|
-
const existing = avgScoreByProfile[key];
|
|
81
|
-
if (existing === undefined) {
|
|
82
|
-
avgScoreByProfile[key] = v.session.stats.avgSpeedKmh;
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
avgScoreByProfile[key] = (existing + v.session.stats.avgSpeedKmh) / 2;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// Per-segment noise deviation: average accuracy across all vehicles per segment
|
|
89
|
-
const segmentCount = this.baseConfig.routeGeometry.length;
|
|
90
|
-
const deviationsBySegment = new Array(segmentCount).fill(0);
|
|
91
|
-
for (const v of vehicleReports) {
|
|
92
|
-
for (const pos of v.session.positions) {
|
|
93
|
-
const segIdx = pos.metadata?.segmentIndex ?? 0;
|
|
94
|
-
if (segIdx < segmentCount) {
|
|
95
|
-
deviationsBySegment[segIdx] = (deviationsBySegment[segIdx] ?? 0) + pos.accuracy;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
// Average
|
|
100
|
-
for (let i = 0; i < deviationsBySegment.length; i++) {
|
|
101
|
-
deviationsBySegment[i] = (deviationsBySegment[i] ?? 0) / Math.max(1, vehicleReports.length);
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
vehicles: vehicleReports,
|
|
105
|
-
comparison: { avgScoreByProfile, deviationsBySegment },
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
/** Destroy all engines and clean up */
|
|
109
|
-
destroy() {
|
|
110
|
-
for (const engine of this.engines) {
|
|
111
|
-
engine.destroy();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @navcore/simulator — Public API barrel.
|
|
3
|
-
*
|
|
4
|
-
* Import everything from this file. Do NOT import from sub-paths directly.
|
|
5
|
-
*
|
|
6
|
-
* Example:
|
|
7
|
-
* import { SimulatorEngine, NoiseEngine, ScenarioInjector, GpxParser } from '@ingissa/navcore-simulator'
|
|
8
|
-
*
|
|
9
|
-
* React Native consumers also get:
|
|
10
|
-
* import { useSimulator, SimulatorControls } from '@ingissa/navcore-simulator'
|
|
11
|
-
*/
|
|
12
|
-
export type { Coordinate, SimPosition, SimLocationCoords, SimLocationObject, SimulatorConfig, NoiseProfile, Scenario, SimSession, } from './core/types';
|
|
13
|
-
export { SimulatorEngine } from './core/SimulatorEngine';
|
|
14
|
-
export type { EngineState } from './core/SimulatorEngine';
|
|
15
|
-
export { RouteWalker } from './core/RouteWalker';
|
|
16
|
-
export type { WalkerPosition } from './core/RouteWalker';
|
|
17
|
-
export { NoiseEngine } from './core/NoiseEngine';
|
|
18
|
-
export { ScenarioInjector } from './scenarios/ScenarioInjector';
|
|
19
|
-
export { GpxParser } from './replay/GpxParser';
|
|
20
|
-
export type { GpxParseResult } from './replay/GpxParser';
|
|
21
|
-
export { SessionRecorder } from './replay/SessionRecorder';
|
|
22
|
-
export type { ExportFormat } from './replay/SessionRecorder';
|
|
23
|
-
export { FleetSimulator } from './fleet/FleetSimulator';
|
|
24
|
-
export type { VehicleProfile, FleetReport } from './fleet/FleetSimulator';
|
|
25
|
-
export { useSimulator } from './react-native/useSimulator';
|
|
26
|
-
export { SimulatorControls } from './react-native/SimulatorControls';
|
|
27
|
-
export type { ScenarioLogEntry } from './react-native/SimulatorControls';
|
|
28
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,YAAY,EACV,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,UAAU,GACX,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAK1E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @navcore/simulator — Public API barrel.
|
|
3
|
-
*
|
|
4
|
-
* Import everything from this file. Do NOT import from sub-paths directly.
|
|
5
|
-
*
|
|
6
|
-
* Example:
|
|
7
|
-
* import { SimulatorEngine, NoiseEngine, ScenarioInjector, GpxParser } from '@ingissa/navcore-simulator'
|
|
8
|
-
*
|
|
9
|
-
* React Native consumers also get:
|
|
10
|
-
* import { useSimulator, SimulatorControls } from '@ingissa/navcore-simulator'
|
|
11
|
-
*/
|
|
12
|
-
// ── Engine ────────────────────────────────────────────────────────────────────
|
|
13
|
-
export { SimulatorEngine } from './core/SimulatorEngine';
|
|
14
|
-
// ── RouteWalker ───────────────────────────────────────────────────────────────
|
|
15
|
-
export { RouteWalker } from './core/RouteWalker';
|
|
16
|
-
// ── NoiseEngine ───────────────────────────────────────────────────────────────
|
|
17
|
-
export { NoiseEngine } from './core/NoiseEngine';
|
|
18
|
-
// ── Scenarios ─────────────────────────────────────────────────────────────────
|
|
19
|
-
export { ScenarioInjector } from './scenarios/ScenarioInjector';
|
|
20
|
-
// ── Replay ────────────────────────────────────────────────────────────────────
|
|
21
|
-
export { GpxParser } from './replay/GpxParser';
|
|
22
|
-
export { SessionRecorder } from './replay/SessionRecorder';
|
|
23
|
-
// ── Fleet (Phase 2) ───────────────────────────────────────────────────────────
|
|
24
|
-
export { FleetSimulator } from './fleet/FleetSimulator';
|
|
25
|
-
// ── React Native ─────────────────────────────────────────────────────────────
|
|
26
|
-
// Import these from the top-level package — no sub-path imports required:
|
|
27
|
-
// import { useSimulator, SimulatorControls } from '@ingissa/navcore-simulator'
|
|
28
|
-
export { useSimulator } from './react-native/useSimulator';
|
|
29
|
-
export { SimulatorControls } from './react-native/SimulatorControls';
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @navcore/simulator — Node.js / CI barrel
|
|
3
|
-
*
|
|
4
|
-
* This barrel exports ONLY the headless classes that have no React Native
|
|
5
|
-
* dependencies. It is used by vitest (via the @navcore/simulator alias in
|
|
6
|
-
* vitest.config.ts) so that unit tests never pull in react-native and
|
|
7
|
-
* trigger Vite's Flow-syntax parser failure.
|
|
8
|
-
*
|
|
9
|
-
* React Native consumers (useSimulator, SimulatorControls) must import
|
|
10
|
-
* from the main barrel:
|
|
11
|
-
* import { useSimulator } from '@ingissa/navcore-simulator' ← full barrel
|
|
12
|
-
*/
|
|
13
|
-
export type { Coordinate, SimPosition, SimLocationCoords, SimLocationObject, SimulatorConfig, NoiseProfile, Scenario, SimSession, } from './core/types';
|
|
14
|
-
export { SimulatorEngine } from './core/SimulatorEngine';
|
|
15
|
-
export type { EngineState } from './core/SimulatorEngine';
|
|
16
|
-
export { RouteWalker } from './core/RouteWalker';
|
|
17
|
-
export type { WalkerPosition } from './core/RouteWalker';
|
|
18
|
-
export { NoiseEngine } from './core/NoiseEngine';
|
|
19
|
-
export { ScenarioInjector } from './scenarios/ScenarioInjector';
|
|
20
|
-
export { GpxParser } from './replay/GpxParser';
|
|
21
|
-
export type { GpxParseResult } from './replay/GpxParser';
|
|
22
|
-
export { SessionRecorder } from './replay/SessionRecorder';
|
|
23
|
-
export type { ExportFormat } from './replay/SessionRecorder';
|
|
24
|
-
export { FleetSimulator } from './fleet/FleetSimulator';
|
|
25
|
-
export type { VehicleProfile, FleetReport } from './fleet/FleetSimulator';
|
|
26
|
-
//# sourceMappingURL=node.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,YAAY,EACV,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,UAAU,GACX,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @navcore/simulator — Node.js / CI barrel
|
|
3
|
-
*
|
|
4
|
-
* This barrel exports ONLY the headless classes that have no React Native
|
|
5
|
-
* dependencies. It is used by vitest (via the @navcore/simulator alias in
|
|
6
|
-
* vitest.config.ts) so that unit tests never pull in react-native and
|
|
7
|
-
* trigger Vite's Flow-syntax parser failure.
|
|
8
|
-
*
|
|
9
|
-
* React Native consumers (useSimulator, SimulatorControls) must import
|
|
10
|
-
* from the main barrel:
|
|
11
|
-
* import { useSimulator } from '@ingissa/navcore-simulator' ← full barrel
|
|
12
|
-
*/
|
|
13
|
-
// ── Engine ─────────────────────────────────────────────────────────────────────
|
|
14
|
-
export { SimulatorEngine } from './core/SimulatorEngine';
|
|
15
|
-
// ── RouteWalker ────────────────────────────────────────────────────────────────
|
|
16
|
-
export { RouteWalker } from './core/RouteWalker';
|
|
17
|
-
// ── NoiseEngine ────────────────────────────────────────────────────────────────
|
|
18
|
-
export { NoiseEngine } from './core/NoiseEngine';
|
|
19
|
-
// ── Scenarios ──────────────────────────────────────────────────────────────────
|
|
20
|
-
export { ScenarioInjector } from './scenarios/ScenarioInjector';
|
|
21
|
-
// ── Replay ─────────────────────────────────────────────────────────────────────
|
|
22
|
-
export { GpxParser } from './replay/GpxParser';
|
|
23
|
-
export { SessionRecorder } from './replay/SessionRecorder';
|
|
24
|
-
// ── Fleet (Phase 2 skeleton) ───────────────────────────────────────────────────
|
|
25
|
-
export { FleetSimulator } from './fleet/FleetSimulator';
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SimulatorControls — Self-contained React Native control panel for SimulatorEngine.
|
|
3
|
-
*
|
|
4
|
-
* Three style variants:
|
|
5
|
-
* 'minimal' — compact horizontal bar: speed selector + pause/resume
|
|
6
|
-
* 'full' — full card with speed, seek, scenario log, recorder, stats
|
|
7
|
-
* 'floating' — collapsible bottom sheet (Animated, no external libs)
|
|
8
|
-
*
|
|
9
|
-
* Colour tokens match the Klaroways design system used in NavCoreTestScreen.
|
|
10
|
-
*/
|
|
11
|
-
import type { SimulatorControls as Controls, SessionControls } from './useSimulator';
|
|
12
|
-
import type { SimSession } from '../core/types';
|
|
13
|
-
export interface ScenarioLogEntry {
|
|
14
|
-
ts: number;
|
|
15
|
-
name: string;
|
|
16
|
-
type: string;
|
|
17
|
-
}
|
|
18
|
-
export interface SimulatorControlsProps {
|
|
19
|
-
simulator: Controls;
|
|
20
|
-
session?: SessionControls;
|
|
21
|
-
style?: 'minimal' | 'full' | 'floating';
|
|
22
|
-
showScenarioLog?: boolean;
|
|
23
|
-
showSessionRecorder?: boolean;
|
|
24
|
-
scenarioLog?: ScenarioLogEntry[];
|
|
25
|
-
/** Current speed multiplier (controlled externally) */
|
|
26
|
-
currentSpeed?: 1 | 2 | 4 | 8;
|
|
27
|
-
/** Current engine state */
|
|
28
|
-
engineState?: 'idle' | 'running' | 'paused' | 'complete';
|
|
29
|
-
isRecording?: boolean;
|
|
30
|
-
onExportSession?: (session: SimSession) => void;
|
|
31
|
-
/** Additional style for the root container */
|
|
32
|
-
containerStyle?: object;
|
|
33
|
-
}
|
|
34
|
-
export declare function SimulatorControls({ simulator, session, style, showScenarioLog, showSessionRecorder, scenarioLog, currentSpeed, engineState, isRecording, onExportSession, containerStyle, }: SimulatorControlsProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
-
//# sourceMappingURL=SimulatorControls.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SimulatorControls.d.ts","sourceRoot":"","sources":["../../../../src/react-native/SimulatorControls.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAYH,OAAO,KAAK,EAAE,iBAAiB,IAAI,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAuBhD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,QAAQ,CAAC;IACpB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,uDAAuD;IACvD,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA0MD,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,OAAO,EACP,KAAiB,EACjB,eAAuB,EACvB,mBAA2B,EAC3B,WAAgB,EAChB,YAAgB,EAChB,WAAoB,EACpB,WAAmB,EACnB,eAAe,EACf,cAAc,GACf,EAAE,sBAAsB,2CA6GxB"}
|
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* SimulatorControls — Self-contained React Native control panel for SimulatorEngine.
|
|
4
|
-
*
|
|
5
|
-
* Three style variants:
|
|
6
|
-
* 'minimal' — compact horizontal bar: speed selector + pause/resume
|
|
7
|
-
* 'full' — full card with speed, seek, scenario log, recorder, stats
|
|
8
|
-
* 'floating' — collapsible bottom sheet (Animated, no external libs)
|
|
9
|
-
*
|
|
10
|
-
* Colour tokens match the Klaroways design system used in NavCoreTestScreen.
|
|
11
|
-
*/
|
|
12
|
-
import { useState, useRef, useCallback } from 'react';
|
|
13
|
-
import { View, Text, TouchableOpacity, StyleSheet, ScrollView, Animated, Platform, } from 'react-native';
|
|
14
|
-
// ─── Colour Tokens ────────────────────────────────────────────────────────────
|
|
15
|
-
const KW = {
|
|
16
|
-
navyDeep: '#081525',
|
|
17
|
-
navyCard: '#152240',
|
|
18
|
-
navyBorder: '#1E3255',
|
|
19
|
-
emerald: '#00BF76',
|
|
20
|
-
emeraldDark: '#04342C',
|
|
21
|
-
emeraldMid: '#009A5F',
|
|
22
|
-
amber: '#F5A623',
|
|
23
|
-
amberDark: '#412402',
|
|
24
|
-
slate: '#6B7FA3',
|
|
25
|
-
slateLight: '#8FA3C8',
|
|
26
|
-
light: '#EBEFF8',
|
|
27
|
-
fault: '#FF4848',
|
|
28
|
-
faultDark: '#3D0000',
|
|
29
|
-
white: '#FFFFFF',
|
|
30
|
-
mono: Platform.OS === 'ios' ? 'Courier New' : 'monospace',
|
|
31
|
-
};
|
|
32
|
-
// ─── Speed Selector ───────────────────────────────────────────────────────────
|
|
33
|
-
function SpeedSelector({ current, onChange, }) {
|
|
34
|
-
return (_jsxs(View, { style: spd.row, children: [_jsx(Text, { style: spd.label, children: "SIM SPEED" }), [1, 2, 4, 8].map((v) => (_jsx(TouchableOpacity, { style: [spd.btn, current === v && spd.btnActive], onPress: () => onChange(v), activeOpacity: 0.7, children: _jsxs(Text, { style: [spd.btnText, current === v && { color: KW.emeraldDark }], children: [v, "\u00D7"] }) }, v)))] }));
|
|
35
|
-
}
|
|
36
|
-
const spd = StyleSheet.create({
|
|
37
|
-
row: { flexDirection: 'row', alignItems: 'center', gap: 6 },
|
|
38
|
-
label: { fontSize: 9, letterSpacing: 1.2, color: KW.slate, marginRight: 4 },
|
|
39
|
-
btn: {
|
|
40
|
-
paddingHorizontal: 10,
|
|
41
|
-
paddingVertical: 5,
|
|
42
|
-
borderRadius: 6,
|
|
43
|
-
borderWidth: 1,
|
|
44
|
-
borderColor: KW.navyBorder,
|
|
45
|
-
},
|
|
46
|
-
btnActive: { backgroundColor: KW.emerald, borderColor: KW.emerald },
|
|
47
|
-
btnText: { fontSize: 11, fontWeight: '700', color: KW.slate },
|
|
48
|
-
});
|
|
49
|
-
// ─── Pause / Resume ───────────────────────────────────────────────────────────
|
|
50
|
-
function PauseResumeButton({ state, onPause, onResume, }) {
|
|
51
|
-
if (state !== 'running' && state !== 'paused')
|
|
52
|
-
return null;
|
|
53
|
-
return (_jsx(TouchableOpacity, { style: [pr.btn, state === 'paused' && pr.btnResume], onPress: state === 'running' ? onPause : onResume, activeOpacity: 0.75, children: _jsx(Text, { style: pr.text, children: state === 'running' ? '⏸' : '▶' }) }));
|
|
54
|
-
}
|
|
55
|
-
const pr = StyleSheet.create({
|
|
56
|
-
btn: {
|
|
57
|
-
paddingHorizontal: 14,
|
|
58
|
-
paddingVertical: 7,
|
|
59
|
-
borderRadius: 8,
|
|
60
|
-
backgroundColor: KW.navyDeep,
|
|
61
|
-
borderWidth: 1,
|
|
62
|
-
borderColor: KW.navyBorder,
|
|
63
|
-
alignItems: 'center',
|
|
64
|
-
},
|
|
65
|
-
btnResume: { borderColor: KW.emerald },
|
|
66
|
-
text: { fontSize: 16 },
|
|
67
|
-
});
|
|
68
|
-
// ─── Scenario Log ─────────────────────────────────────────────────────────────
|
|
69
|
-
function ScenarioLog({ entries }) {
|
|
70
|
-
return (_jsxs(View, { style: log.container, children: [_jsx(Text, { style: log.title, children: "// scenario log" }), _jsx(ScrollView, { style: log.scroll, showsVerticalScrollIndicator: false, children: entries.length === 0 ? (_jsx(Text, { style: log.empty, children: "No scenarios fired yet\u2026" })) : (entries.map((e, i) => {
|
|
71
|
-
const d = new Date(e.ts);
|
|
72
|
-
const time = `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
|
|
73
|
-
return (_jsxs(Text, { style: log.entry, children: [_jsxs(Text, { style: log.time, children: [time, " "] }), _jsxs(Text, { style: { color: KW.amber }, children: ["[", e.type, "]"] }), ' ', e.name] }, i));
|
|
74
|
-
})) })] }));
|
|
75
|
-
}
|
|
76
|
-
const log = StyleSheet.create({
|
|
77
|
-
container: {
|
|
78
|
-
backgroundColor: KW.navyDeep,
|
|
79
|
-
borderRadius: 8,
|
|
80
|
-
padding: 8,
|
|
81
|
-
borderWidth: 1,
|
|
82
|
-
borderColor: KW.navyBorder,
|
|
83
|
-
maxHeight: 100,
|
|
84
|
-
marginTop: 8,
|
|
85
|
-
},
|
|
86
|
-
title: {
|
|
87
|
-
fontSize: 9,
|
|
88
|
-
letterSpacing: 1,
|
|
89
|
-
color: KW.slate,
|
|
90
|
-
fontFamily: KW.mono,
|
|
91
|
-
marginBottom: 4,
|
|
92
|
-
},
|
|
93
|
-
scroll: { flex: 1 },
|
|
94
|
-
empty: { fontSize: 10, color: KW.slate, fontFamily: KW.mono },
|
|
95
|
-
entry: { fontSize: 10, color: KW.slateLight, fontFamily: KW.mono, marginBottom: 2 },
|
|
96
|
-
time: { color: KW.slate },
|
|
97
|
-
});
|
|
98
|
-
// ─── Session Recorder Controls ────────────────────────────────────────────────
|
|
99
|
-
function SessionRecorderControls({ isRecording, session, onExport, lastSession, }) {
|
|
100
|
-
if (!session)
|
|
101
|
-
return null;
|
|
102
|
-
return (_jsxs(View, { style: rec.row, children: [_jsx(TouchableOpacity, { style: [rec.btn, isRecording && rec.btnActive], onPress: () => {
|
|
103
|
-
if (isRecording) {
|
|
104
|
-
// session stop returns SimSession | null from hook
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
session.start();
|
|
108
|
-
}
|
|
109
|
-
}, activeOpacity: 0.75, children: _jsx(Text, { style: rec.btnText, children: isRecording ? '⏹ STOP REC' : '⏺ RECORD' }) }), lastSession && onExport && (_jsx(TouchableOpacity, { style: rec.exportBtn, onPress: () => onExport(lastSession), activeOpacity: 0.75, children: _jsx(Text, { style: rec.exportText, children: "EXPORT JSON" }) }))] }));
|
|
110
|
-
}
|
|
111
|
-
const rec = StyleSheet.create({
|
|
112
|
-
row: { flexDirection: 'row', gap: 8, marginTop: 8 },
|
|
113
|
-
btn: {
|
|
114
|
-
flex: 1,
|
|
115
|
-
paddingVertical: 8,
|
|
116
|
-
borderRadius: 8,
|
|
117
|
-
backgroundColor: KW.navyDeep,
|
|
118
|
-
borderWidth: 1,
|
|
119
|
-
borderColor: KW.navyBorder,
|
|
120
|
-
alignItems: 'center',
|
|
121
|
-
},
|
|
122
|
-
btnActive: { borderColor: KW.fault, backgroundColor: KW.faultDark },
|
|
123
|
-
btnText: { fontSize: 11, fontWeight: '700', color: KW.slateLight, letterSpacing: 0.8 },
|
|
124
|
-
exportBtn: {
|
|
125
|
-
paddingHorizontal: 12,
|
|
126
|
-
paddingVertical: 8,
|
|
127
|
-
borderRadius: 8,
|
|
128
|
-
backgroundColor: KW.navyDeep,
|
|
129
|
-
borderWidth: 1,
|
|
130
|
-
borderColor: KW.emeraldMid,
|
|
131
|
-
alignItems: 'center',
|
|
132
|
-
},
|
|
133
|
-
exportText: { fontSize: 10, fontWeight: '700', color: KW.emerald, letterSpacing: 0.5 },
|
|
134
|
-
});
|
|
135
|
-
// ─── Main Component ───────────────────────────────────────────────────────────
|
|
136
|
-
export function SimulatorControls({ simulator, session, style = 'minimal', showScenarioLog = false, showSessionRecorder = false, scenarioLog = [], currentSpeed = 1, engineState = 'idle', isRecording = false, onExportSession, containerStyle, }) {
|
|
137
|
-
const [speed, setSpeedState] = useState(currentSpeed);
|
|
138
|
-
const [lastSession, setLastSession] = useState(null);
|
|
139
|
-
// Floating sheet animation
|
|
140
|
-
const sheetAnim = useRef(new Animated.Value(0)).current;
|
|
141
|
-
const [isExpanded, setIsExpanded] = useState(false);
|
|
142
|
-
const handleSpeedChange = useCallback((v) => {
|
|
143
|
-
setSpeedState(v);
|
|
144
|
-
simulator.setSpeed(v);
|
|
145
|
-
}, [simulator]);
|
|
146
|
-
const handleStopRecording = useCallback(() => {
|
|
147
|
-
const s = session?.stop();
|
|
148
|
-
if (s)
|
|
149
|
-
setLastSession(s);
|
|
150
|
-
}, [session]);
|
|
151
|
-
const toggleSheet = useCallback(() => {
|
|
152
|
-
const toValue = isExpanded ? 0 : 1;
|
|
153
|
-
setIsExpanded(!isExpanded);
|
|
154
|
-
Animated.spring(sheetAnim, {
|
|
155
|
-
toValue,
|
|
156
|
-
useNativeDriver: false,
|
|
157
|
-
bounciness: 4,
|
|
158
|
-
}).start();
|
|
159
|
-
}, [isExpanded, sheetAnim]);
|
|
160
|
-
// ── Minimal ────────────────────────────────────────────────────────────────
|
|
161
|
-
if (style === 'minimal') {
|
|
162
|
-
return (_jsxs(View, { style: [s.minimal, containerStyle], children: [_jsx(SpeedSelector, { current: speed, onChange: handleSpeedChange }), _jsx(PauseResumeButton, { state: engineState, onPause: simulator.pause, onResume: simulator.resume })] }));
|
|
163
|
-
}
|
|
164
|
-
// ── Full ───────────────────────────────────────────────────────────────────
|
|
165
|
-
if (style === 'full') {
|
|
166
|
-
return (_jsxs(View, { style: [s.full, containerStyle], children: [_jsxs(View, { style: s.fullHeader, children: [_jsx(Text, { style: s.fullTitle, children: "SIMULATOR" }), _jsx(View, { style: [s.stateBadge, engineState === 'running' && s.stateBadgeActive], children: _jsx(Text, { style: s.stateText, children: engineState.toUpperCase() }) })] }), _jsx(SpeedSelector, { current: speed, onChange: handleSpeedChange }), _jsx(View, { style: s.pauseRow, children: _jsx(PauseResumeButton, { state: engineState, onPause: simulator.pause, onResume: simulator.resume }) }), showScenarioLog && _jsx(ScenarioLog, { entries: scenarioLog }), showSessionRecorder && (_jsx(SessionRecorderControls, { isRecording: isRecording, session: session, onExport: onExportSession, lastSession: lastSession }))] }));
|
|
167
|
-
}
|
|
168
|
-
// ── Floating ───────────────────────────────────────────────────────────────
|
|
169
|
-
const sheetHeight = sheetAnim.interpolate({
|
|
170
|
-
inputRange: [0, 1],
|
|
171
|
-
outputRange: [44, showScenarioLog ? 260 : 160],
|
|
172
|
-
});
|
|
173
|
-
return (_jsxs(Animated.View, { style: [s.floating, { height: sheetHeight }, containerStyle], children: [_jsxs(TouchableOpacity, { style: s.floatHandle, onPress: toggleSheet, activeOpacity: 0.8, children: [_jsx(View, { style: s.handleBar }), _jsxs(Text, { style: s.floatTitle, children: ["SIMULATOR ", isExpanded ? '▼' : '▲'] })] }), isExpanded && (_jsxs(View, { style: s.floatContent, children: [_jsx(SpeedSelector, { current: speed, onChange: handleSpeedChange }), _jsx(View, { style: s.pauseRow, children: _jsx(PauseResumeButton, { state: engineState, onPause: simulator.pause, onResume: simulator.resume }) }), showScenarioLog && _jsx(ScenarioLog, { entries: scenarioLog })] }))] }));
|
|
174
|
-
}
|
|
175
|
-
// ─── Styles ───────────────────────────────────────────────────────────────────
|
|
176
|
-
const s = StyleSheet.create({
|
|
177
|
-
// Minimal
|
|
178
|
-
minimal: {
|
|
179
|
-
flexDirection: 'row',
|
|
180
|
-
alignItems: 'center',
|
|
181
|
-
gap: 12,
|
|
182
|
-
paddingHorizontal: 4,
|
|
183
|
-
paddingVertical: 6,
|
|
184
|
-
},
|
|
185
|
-
// Full
|
|
186
|
-
full: {
|
|
187
|
-
backgroundColor: KW.navyCard,
|
|
188
|
-
borderRadius: 12,
|
|
189
|
-
padding: 14,
|
|
190
|
-
borderWidth: 1,
|
|
191
|
-
borderColor: KW.navyBorder,
|
|
192
|
-
},
|
|
193
|
-
fullHeader: {
|
|
194
|
-
flexDirection: 'row',
|
|
195
|
-
justifyContent: 'space-between',
|
|
196
|
-
alignItems: 'center',
|
|
197
|
-
marginBottom: 10,
|
|
198
|
-
},
|
|
199
|
-
fullTitle: {
|
|
200
|
-
fontSize: 11,
|
|
201
|
-
fontWeight: '800',
|
|
202
|
-
color: KW.slateLight,
|
|
203
|
-
letterSpacing: 1.5,
|
|
204
|
-
},
|
|
205
|
-
stateBadge: {
|
|
206
|
-
paddingHorizontal: 8,
|
|
207
|
-
paddingVertical: 3,
|
|
208
|
-
borderRadius: 4,
|
|
209
|
-
backgroundColor: KW.navyDeep,
|
|
210
|
-
borderWidth: 1,
|
|
211
|
-
borderColor: KW.navyBorder,
|
|
212
|
-
},
|
|
213
|
-
stateBadgeActive: { borderColor: KW.emerald },
|
|
214
|
-
stateText: { fontSize: 9, fontWeight: '700', color: KW.slate, letterSpacing: 1 },
|
|
215
|
-
pauseRow: { marginTop: 8 },
|
|
216
|
-
// Floating
|
|
217
|
-
floating: {
|
|
218
|
-
position: 'absolute',
|
|
219
|
-
bottom: 0,
|
|
220
|
-
left: 0,
|
|
221
|
-
right: 0,
|
|
222
|
-
backgroundColor: KW.navyCard,
|
|
223
|
-
borderTopLeftRadius: 16,
|
|
224
|
-
borderTopRightRadius: 16,
|
|
225
|
-
borderTopWidth: 1,
|
|
226
|
-
borderColor: KW.navyBorder,
|
|
227
|
-
overflow: 'hidden',
|
|
228
|
-
zIndex: 100,
|
|
229
|
-
},
|
|
230
|
-
floatHandle: {
|
|
231
|
-
height: 44,
|
|
232
|
-
alignItems: 'center',
|
|
233
|
-
justifyContent: 'center',
|
|
234
|
-
flexDirection: 'row',
|
|
235
|
-
gap: 10,
|
|
236
|
-
},
|
|
237
|
-
handleBar: {
|
|
238
|
-
width: 36,
|
|
239
|
-
height: 4,
|
|
240
|
-
backgroundColor: KW.navyBorder,
|
|
241
|
-
borderRadius: 2,
|
|
242
|
-
},
|
|
243
|
-
floatTitle: {
|
|
244
|
-
fontSize: 10,
|
|
245
|
-
fontWeight: '700',
|
|
246
|
-
color: KW.slate,
|
|
247
|
-
letterSpacing: 1.2,
|
|
248
|
-
},
|
|
249
|
-
floatContent: {
|
|
250
|
-
paddingHorizontal: 16,
|
|
251
|
-
paddingBottom: 16,
|
|
252
|
-
gap: 8,
|
|
253
|
-
},
|
|
254
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useSimulator.d.ts","sourceRoot":"","sources":["../../../../src/react-native/useSimulator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC3G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,aAAa,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACnC,8CAA8C;IAC9C,MAAM,EAAE,OAAO,CAAC;IAChB,iDAAiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,eAAe,GAAG,kBAAkB,GAAG,iBAAiB,CAAC,CAAC,CAAC;IAClG,+BAA+B;IAC/B,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,mCAAmC;IACnC,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC/C,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,IAAI,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,IAAI,EAAE,MAAM,UAAU,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,2DAA2D;IAC3D,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,2DAA2D;IAC3D,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACtC,wBAAwB;IACxB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,yBAAyB;IACzB,OAAO,EAAE,eAAe,CAAC;IACzB,yCAAyC;IACzC,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAwF7E"}
|