vehicle-path2 1.0.5 → 1.0.6

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/dist/react.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useVehicleEvents-B1_CZyWq.cjs");exports.VehicleEventContext=e.VehicleEventContext;exports.VehicleEventProvider=e.VehicleEventProvider;exports.useAnimation=e.useAnimation;exports.useCreateVehicleEventEmitter=e.useCreateVehicleEventEmitter;exports.useInitialMovement=e.useInitialMovement;exports.useMovement=e.useMovementQueue;exports.useMovementQueue=e.useMovementQueue;exports.useMovementSequence=e.useMovementSequence;exports.useScene=e.useScene;exports.useSceneDefinition=e.useSceneDefinition;exports.useVehicleEvent=e.useVehicleEvent;exports.useVehicleEventEmitter=e.useVehicleEventEmitter;exports.useVehicleMovement=e.useAnimation;exports.useVehicleSimulation=e.useVehicleSimulation;exports.useVehicles=e.useVehicles;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useVehicleEvents-DngnyUej.cjs");exports.VehicleEventContext=e.VehicleEventContext;exports.VehicleEventProvider=e.VehicleEventProvider;exports.useAnimation=e.useAnimation;exports.useCreateVehicleEventEmitter=e.useCreateVehicleEventEmitter;exports.useInitialMovement=e.useInitialMovement;exports.useMovement=e.useMovementQueue;exports.useMovementQueue=e.useMovementQueue;exports.useMovementSequence=e.useMovementSequence;exports.useScene=e.useScene;exports.useSceneDefinition=e.useSceneDefinition;exports.useVehicleEvent=e.useVehicleEvent;exports.useVehicleEventEmitter=e.useVehicleEventEmitter;exports.useVehicleMovement=e.useAnimation;exports.useVehicleSimulation=e.useVehicleSimulation;exports.useVehicles=e.useVehicles;
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { V as t, a as i, u as a, b as n, c as u, d as c, d as o, e as v, f as l, g as m, h, i as V, u as r, j as E, k as M } from "./useVehicleEvents-Cv-YgfXB.js";
1
+ import { V as t, a as i, u as a, b as n, c as u, d as c, d as o, e as v, f as l, g as m, h, i as V, u as r, j as E, k as M } from "./useVehicleEvents-5-uvxZme.js";
2
2
  export {
3
3
  t as VehicleEventContext,
4
4
  i as VehicleEventProvider,
@@ -73,7 +73,7 @@ function ne() {
73
73
  return t(a), { success: !1, error: a };
74
74
  }
75
75
  return o((a) => [...a, J(n)]), t(null), { success: !0 };
76
- }, [r]), q = P((n, h) => {
76
+ }, [r]), T = P((n, h) => {
77
77
  if (r.findIndex((m) => m.id === n) === -1) {
78
78
  const m = `Line with ID '${n}' not found`;
79
79
  return t(m), { success: !1, error: m };
@@ -89,7 +89,7 @@ function ne() {
89
89
  return t(a), { success: !1, error: a };
90
90
  }
91
91
  return o((a) => a.filter((m) => m.id !== n)), s((a) => a.filter((m) => m.fromLineId !== n && m.toLineId !== n)), t(null), { success: !0 };
92
- }, [r]), L = P((n) => {
92
+ }, [r]), S = P((n) => {
93
93
  const h = r.some((l) => l.id === n.from), a = r.some((l) => l.id === n.to);
94
94
  if (!h) {
95
95
  const l = `Line '${n.from}' not found`;
@@ -176,9 +176,9 @@ function ne() {
176
176
  curves: x,
177
177
  setScene: I,
178
178
  addLine: O,
179
- updateLine: q,
179
+ updateLine: T,
180
180
  removeLine: y,
181
- addConnection: L,
181
+ addConnection: S,
182
182
  updateConnection: v,
183
183
  removeConnection: p,
184
184
  clear: i,
@@ -201,7 +201,7 @@ function oe({ lines: r, wheelbase: o }) {
201
201
  o
202
202
  );
203
203
  return a.length > 0 ? (t(a.join("; ")), { success: !1, errors: a }) : (f.current = [...f.current, ...h], s(f.current), t(null), { success: !0 });
204
- }, [r, o]), q = P((v, p) => {
204
+ }, [r, o]), T = P((v, p) => {
205
205
  const i = f.current.findIndex(($) => $.id === v);
206
206
  if (i === -1) {
207
207
  const $ = `Vehicle with ID '${v}' not found`;
@@ -238,25 +238,25 @@ function oe({ lines: r, wheelbase: o }) {
238
238
  return t(i), { success: !1, error: i };
239
239
  }
240
240
  return f.current = f.current.filter((i) => i.id !== v), s(f.current), t(null), { success: !0 };
241
- }, []), L = P(() => {
241
+ }, []), S = P(() => {
242
242
  f.current = [], s([]), t(null);
243
243
  }, []);
244
244
  return {
245
245
  vehicles: x,
246
246
  addVehicles: O,
247
- updateVehicle: q,
247
+ updateVehicle: T,
248
248
  removeVehicle: y,
249
- clear: L,
249
+ clear: S,
250
250
  error: d,
251
251
  _loadVehicles: I
252
252
  };
253
253
  }
254
254
  function ce({ vehicles: r, lines: o }) {
255
- const [x, s] = _(/* @__PURE__ */ new Map()), [d, t] = _(null), f = A(/* @__PURE__ */ new Map()), I = P(() => f.current, []), O = P((L) => {
256
- f.current = L, s(L), t(null);
257
- }, []), q = P((L, v) => {
258
- if (!r.some((l) => l.id === L)) {
259
- const l = `Vehicle '${L}' not found`;
255
+ const [x, s] = _(/* @__PURE__ */ new Map()), [d, t] = _(null), f = A(/* @__PURE__ */ new Map()), I = P(() => f.current, []), O = P((S) => {
256
+ f.current = S, s(S), t(null);
257
+ }, []), T = P((S, v) => {
258
+ if (!r.some((l) => l.id === S)) {
259
+ const l = `Vehicle '${S}' not found`;
260
260
  return t(l), { success: !1, error: l };
261
261
  }
262
262
  const i = o.find((l) => l.id === v.targetLineId);
@@ -285,16 +285,16 @@ function ce({ vehicles: r, lines: o }) {
285
285
  return t(l), { success: !1, error: l };
286
286
  }
287
287
  }
288
- const m = Y({ vehicleId: L, ...v }), V = new Map(f.current), Q = V.get(L) || [];
289
- return V.set(L, [...Q, m]), f.current = V, s(V), t(null), { success: !0 };
290
- }, [r, o]), y = P((L) => {
291
- if (L !== void 0) {
292
- if (!r.some((i) => i.id === L)) {
293
- const i = `Vehicle '${L}' not found`;
288
+ const m = Y({ vehicleId: S, ...v }), V = new Map(f.current), Q = V.get(S) || [];
289
+ return V.set(S, [...Q, m]), f.current = V, s(V), t(null), { success: !0 };
290
+ }, [r, o]), y = P((S) => {
291
+ if (S !== void 0) {
292
+ if (!r.some((i) => i.id === S)) {
293
+ const i = `Vehicle '${S}' not found`;
294
294
  return t(i), { success: !1, error: i };
295
295
  }
296
296
  const p = new Map(f.current);
297
- p.delete(L), f.current = p, s(p);
297
+ p.delete(S), f.current = p, s(p);
298
298
  } else
299
299
  f.current = /* @__PURE__ */ new Map(), s(/* @__PURE__ */ new Map());
300
300
  return t(null), { success: !0 };
@@ -302,7 +302,7 @@ function ce({ vehicles: r, lines: o }) {
302
302
  return {
303
303
  vehicleQueues: x,
304
304
  getVehicleQueues: I,
305
- queueMovement: q,
305
+ queueMovement: T,
306
306
  clearQueue: y,
307
307
  error: d,
308
308
  _loadQueues: O
@@ -318,11 +318,11 @@ function Ie({
318
318
  curves: f,
319
319
  eventEmitter: I
320
320
  }) {
321
- const [O, q] = _([]), y = A([]), L = P((w) => {
322
- typeof w == "function" ? L((e) => {
321
+ const [O, T] = _([]), y = A([]), S = P((w) => {
322
+ typeof w == "function" ? T((e) => {
323
323
  const c = w(e);
324
324
  return y.current = c, c;
325
- }) : (y.current = w, q(w));
325
+ }) : (y.current = w, T(w));
326
326
  }, []), v = P(() => y.current, []), p = z(() => ({
327
327
  wheelbase: d,
328
328
  tangentMode: t
@@ -334,7 +334,7 @@ function Ie({
334
334
  const { movingVehicles: w, stateMap: e } = ee(r, i);
335
335
  n.current = e;
336
336
  const c = setTimeout(() => {
337
- L(w);
337
+ S(w);
338
338
  }, 0);
339
339
  return () => clearTimeout(c);
340
340
  }, [r, i]);
@@ -360,9 +360,9 @@ function Ie({
360
360
  if (M.front.currentSegmentIndex < M.path.segments.length) {
361
361
  const j = M.path.segments[M.front.currentSegmentIndex];
362
362
  if (j.type === "line") {
363
- const S = i.get(j.lineId);
364
- S && (C = Math.sqrt(
365
- Math.pow(S.end.x - S.start.x, 2) + Math.pow(S.end.y - S.start.y, 2)
363
+ const L = i.get(j.lineId);
364
+ L && (C = Math.sqrt(
365
+ Math.pow(L.end.x - L.start.x, 2) + Math.pow(L.end.y - L.start.y, 2)
366
366
  ));
367
367
  }
368
368
  }
@@ -373,7 +373,7 @@ function Ie({
373
373
  w,
374
374
  i,
375
375
  M.curveDataMap
376
- ), T = te(
376
+ ), q = te(
377
377
  g.vehicle.front,
378
378
  M.front,
379
379
  M.path,
@@ -385,9 +385,9 @@ function Ie({
385
385
  if (g.vehicle = {
386
386
  ...g.vehicle,
387
387
  rear: b.axleState,
388
- front: T.axleState
389
- }, g.execution.rear = b.execution, g.execution.front = T.execution, b.completed) {
390
- const S = de(g, {
388
+ front: q.axleState
389
+ }, g.execution.rear = b.execution, g.execution.front = q.execution, b.completed) {
390
+ const L = de(g, {
391
391
  linesMap: i,
392
392
  config: p,
393
393
  vehicleQueues: x,
@@ -397,11 +397,11 @@ function Ie({
397
397
  onCommandComplete: (k) => c.push({ type: "commandComplete", data: k }),
398
398
  onCommandStart: (k) => c.push({ type: "commandStart", data: k })
399
399
  });
400
- g.vehicle = S.vehicle, S.newExecution !== void 0 && (g.execution = S.newExecution), S.vehicle.state !== "moving" && c.push({
400
+ g.vehicle = L.vehicle, L.newExecution !== void 0 && (g.execution = L.newExecution), L.vehicle.state !== "moving" && c.push({
401
401
  type: "stateChange",
402
- data: { vehicleId: u, from: "moving", to: S.vehicle.state }
402
+ data: { vehicleId: u, from: "moving", to: L.vehicle.state }
403
403
  });
404
- const E = S.vehicle.rear.position, R = S.vehicle.front.position;
404
+ const E = L.vehicle.rear.position, R = L.vehicle.front.position;
405
405
  c.push({
406
406
  type: "positionUpdate",
407
407
  data: {
@@ -414,7 +414,7 @@ function Ie({
414
414
  });
415
415
  }
416
416
  }
417
- if (L((u) => u.map((g) => {
417
+ if (S((u) => u.map((g) => {
418
418
  const M = n.current.get(g.id);
419
419
  return M ? M.vehicle : g;
420
420
  })), I && c.length > 0) {
@@ -438,17 +438,17 @@ function Ie({
438
438
  for (const [g, M] of n.current) {
439
439
  const C = M.vehicle, b = e.get(g);
440
440
  if (!b || b.length === 0) continue;
441
- const T = b[0], S = H(C, T, { graph: w, linesMap: i, curves: f, config: p });
442
- if (!S) {
441
+ const q = b[0], L = H(C, q, { graph: w, linesMap: i, curves: f, config: p });
442
+ if (!L) {
443
443
  console.warn(`No path found for vehicle ${g}`);
444
444
  continue;
445
445
  }
446
- const E = re(S.path, 0, 0, d);
446
+ const E = re(L.path, 0, 0, d);
447
447
  n.current.set(g, {
448
448
  ...M,
449
449
  execution: {
450
- path: S.path,
451
- curveDataMap: S.curveDataMap,
450
+ path: L.path,
451
+ curveDataMap: L.curveDataMap,
452
452
  currentCommandIndex: 0,
453
453
  rear: { currentSegmentIndex: 0, segmentDistance: 0 },
454
454
  front: E ? { currentSegmentIndex: E.segmentIndex, segmentDistance: E.segmentDistance } : { currentSegmentIndex: 0, segmentDistance: 0 }
@@ -457,7 +457,7 @@ function Ie({
457
457
  }), u = !0, C.state !== "moving" && c.push({
458
458
  id: g,
459
459
  fromState: C.state,
460
- command: T,
460
+ command: q,
461
461
  startPosition: {
462
462
  lineId: C.rear.lineId,
463
463
  absoluteOffset: C.rear.absoluteOffset,
@@ -466,18 +466,18 @@ function Ie({
466
466
  });
467
467
  }
468
468
  if (!u) return !1;
469
- if (m.current = !0, L((g) => g.map((M) => {
469
+ if (m.current = !0, S((g) => g.map((M) => {
470
470
  const C = n.current.get(M.id);
471
471
  return C ? C.vehicle : M;
472
472
  })), I && c.length > 0) {
473
473
  const g = a.current;
474
474
  setTimeout(() => {
475
- a.current === g && c.forEach(({ id: M, fromState: C, command: b, startPosition: T }) => {
475
+ a.current === g && c.forEach(({ id: M, fromState: C, command: b, startPosition: q }) => {
476
476
  I.emit("commandStart", {
477
477
  vehicleId: M,
478
478
  command: b,
479
479
  commandIndex: 0,
480
- startPosition: T
480
+ startPosition: q
481
481
  }), I.emit("stateChange", {
482
482
  vehicleId: M,
483
483
  from: C,
@@ -490,7 +490,7 @@ function Ie({
490
490
  }, [i, f, x, s, p, d, I]), l = P(() => {
491
491
  a.current++, m.current = !1;
492
492
  const { movingVehicles: w, stateMap: e } = ee(r, i);
493
- n.current = e, L(w);
493
+ n.current = e, S(w);
494
494
  }, [r, i]), D = P((w) => {
495
495
  const e = n.current.get(w);
496
496
  if (!e || e.vehicle.state !== "waiting")
@@ -501,19 +501,19 @@ function Ie({
501
501
  if (c && g < c.length) {
502
502
  const M = h.current;
503
503
  if (M) {
504
- const C = c[g], b = { graph: M, linesMap: i, curves: f, config: p }, T = H(e.vehicle, C, b);
505
- if (T) {
506
- const j = re(T.path, 0, 0, d);
504
+ const C = c[g], b = { graph: M, linesMap: i, curves: f, config: p }, q = H(e.vehicle, C, b);
505
+ if (q) {
506
+ const j = re(q.path, 0, 0, d);
507
507
  if (e.execution = {
508
- path: T.path,
509
- curveDataMap: T.curveDataMap,
508
+ path: q.path,
509
+ curveDataMap: q.curveDataMap,
510
510
  currentCommandIndex: g,
511
511
  rear: { currentSegmentIndex: 0, segmentDistance: 0 },
512
512
  front: j ? { currentSegmentIndex: j.segmentIndex, segmentDistance: j.segmentDistance } : { currentSegmentIndex: 0, segmentDistance: 0 }
513
- }, e.vehicle = { ...e.vehicle, state: "moving" }, L((S) => S.map((E) => E.id === w ? e.vehicle : E)), I) {
514
- const S = a.current;
513
+ }, e.vehicle = { ...e.vehicle, state: "moving" }, S((L) => L.map((E) => E.id === w ? e.vehicle : E)), I) {
514
+ const L = a.current;
515
515
  setTimeout(() => {
516
- a.current === S && I.emit("stateChange", {
516
+ a.current === L && I.emit("stateChange", {
517
517
  vehicleId: w,
518
518
  from: "waiting",
519
519
  to: "moving"
@@ -524,7 +524,7 @@ function Ie({
524
524
  }
525
525
  }
526
526
  }
527
- if (e.vehicle = { ...e.vehicle, state: "idle" }, e.execution = null, L((M) => M.map((C) => C.id === w ? e.vehicle : C)), I) {
527
+ if (e.vehicle = { ...e.vehicle, state: "idle" }, e.execution = null, S((M) => M.map((C) => C.id === w ? e.vehicle : C)), I) {
528
528
  const M = a.current;
529
529
  setTimeout(() => {
530
530
  a.current === M && I.emit("stateChange", {
@@ -570,13 +570,13 @@ function Se({
570
570
  tangentMode: o,
571
571
  curves: s.curves,
572
572
  eventEmitter: x
573
- }), I = P((e) => d.vehicles.filter((c) => c.lineId === e || c.rear.lineId === e), [d.vehicles]), O = P((e) => I(e).length > 0, [I]), q = P((e) => {
573
+ }), I = P((e) => d.vehicles.filter((c) => c.lineId === e || c.rear.lineId === e), [d.vehicles]), O = P((e) => I(e).length > 0, [I]), T = P((e) => {
574
574
  const c = s.addLine(e);
575
575
  return c.success ? { success: !0 } : { success: !1, error: c.error };
576
576
  }, [s]), y = P((e, c) => {
577
577
  const u = s.updateLine(e, c);
578
578
  return u.success ? { success: !0 } : { success: !1, error: u.error };
579
- }, [s]), L = P((e) => {
579
+ }, [s]), S = P((e) => {
580
580
  const c = [], u = I(e);
581
581
  u.length > 0 && (c.push({
582
582
  type: "vehicle_on_removed_line",
@@ -659,14 +659,14 @@ function Se({
659
659
  }, [t]), D = P((e) => {
660
660
  const c = [], u = [], { scene: g, vehicles: M, movements: C } = me(e);
661
661
  g.errors.length > 0 && u.push(...g.errors), M.errors.length > 0 && u.push(...M.errors), C.errors.length > 0 && u.push(...C.errors);
662
- const b = g.data.lines.map(J), T = (g.data.connections || []).map(U), j = M.data.map(X), { vehicles: S, errors: E } = K(j, b, r);
662
+ const b = g.data.lines.map(J), q = (g.data.connections || []).map(U), j = M.data.map(X), { vehicles: L, errors: E } = K(j, b, r);
663
663
  E.length > 0 && u.push(...E);
664
664
  const R = /* @__PURE__ */ new Map();
665
665
  for (const k of C.data) {
666
666
  const Z = R.get(k.vehicleId) || [];
667
667
  Z.push(Y(k)), R.set(k.vehicleId, Z);
668
668
  }
669
- return s._loadScene(b, T), d._loadVehicles(S), t._loadQueues(R), u.length > 0 && c.push({
669
+ return s._loadScene(b, q), d._loadVehicles(L), t._loadQueues(R), u.length > 0 && c.push({
670
670
  type: "dsl_parse_error",
671
671
  message: `DSL loading had ${u.length} error(s)`,
672
672
  details: { errors: u }
@@ -675,19 +675,19 @@ function Se({
675
675
  warnings: c.length > 0 ? c : void 0
676
676
  };
677
677
  }, [s, d, t, r]), $ = P((e) => {
678
- const c = [], u = [], g = e.lines.map(J), M = (e.connections || []).map(U), C = (e.vehicles || []).map(X), { vehicles: b, errors: T } = K(C, g, r);
679
- T.length > 0 && u.push(...T);
678
+ const c = [], u = [], g = e.lines.map(J), M = (e.connections || []).map(U), C = (e.vehicles || []).map(X), { vehicles: b, errors: q } = K(C, g, r);
679
+ q.length > 0 && u.push(...q);
680
680
  const j = /* @__PURE__ */ new Map();
681
- for (const S of e.movements || []) {
682
- const E = j.get(S.vehicleId) || [];
681
+ for (const L of e.movements || []) {
682
+ const E = j.get(L.vehicleId) || [];
683
683
  E.push(Y({
684
- vehicleId: S.vehicleId,
685
- targetLineId: S.targetLineId,
686
- targetPosition: S.targetPosition,
687
- isPercentage: S.isPercentage,
688
- wait: S.wait,
689
- payload: S.payload
690
- })), j.set(S.vehicleId, E);
684
+ vehicleId: L.vehicleId,
685
+ targetLineId: L.targetLineId,
686
+ targetPosition: L.targetPosition,
687
+ isPercentage: L.isPercentage,
688
+ wait: L.wait,
689
+ payload: L.payload
690
+ })), j.set(L.vehicleId, E);
691
691
  }
692
692
  return s._loadScene(g, M), d._loadVehicles(b), t._loadQueues(j), u.length > 0 && c.push({
693
693
  type: "dsl_parse_error",
@@ -708,9 +708,9 @@ function Se({
708
708
  vehicleQueues: t.vehicleQueues,
709
709
  error: w,
710
710
  // Scene operations
711
- addLine: q,
711
+ addLine: T,
712
712
  updateLine: y,
713
- removeLine: L,
713
+ removeLine: S,
714
714
  clearScene: v,
715
715
  // Connection operations
716
716
  connect: p,
@@ -772,7 +772,7 @@ function we() {
772
772
  I.current = !1;
773
773
  }, 50));
774
774
  }, [d, t]);
775
- const q = P((v) => {
775
+ const T = P((v) => {
776
776
  I.current = !0, o(v);
777
777
  try {
778
778
  const { data: p, errors: i } = ge(v);
@@ -798,7 +798,7 @@ function we() {
798
798
  I.current = !0, o(h), setTimeout(() => {
799
799
  I.current = !1;
800
800
  }, 50);
801
- }, [d, t, f]), L = P((v) => {
801
+ }, [d, t, f]), S = P((v) => {
802
802
  const p = typeof v == "function" ? v(t) : v, i = W(p);
803
803
  f({
804
804
  lines: F(d),
@@ -822,12 +822,12 @@ function we() {
822
822
  debounceKey: 0,
823
823
  // Kept for API compatibility
824
824
  setLines: y,
825
- setCurves: L,
826
- setSceneDefinitionText: q
825
+ setCurves: S,
826
+ setSceneDefinitionText: T
827
827
  };
828
828
  }
829
829
  function $e({ lines: r, wheelbase: o }) {
830
- const [x, s] = _(""), [d, t] = _(null), { vehicles: f, addVehicles: I, clear: O, error: q } = oe({ lines: r, wheelbase: o }), y = A(!1), L = P((v) => {
830
+ const [x, s] = _(""), [d, t] = _(null), { vehicles: f, addVehicles: I, clear: O, error: T } = oe({ lines: r, wheelbase: o }), y = A(!1), S = P((v) => {
831
831
  y.current = !0, s(v);
832
832
  try {
833
833
  const { data: p, errors: i } = he(v), n = [...i];
@@ -848,16 +848,16 @@ function $e({ lines: r, wheelbase: o }) {
848
848
  return {
849
849
  vehicles: f,
850
850
  initialMovementText: x,
851
- movementError: d || q,
851
+ movementError: d || T,
852
852
  isDebouncing: !1,
853
853
  // No debouncing - parsing is immediate
854
854
  debounceKey: 0,
855
855
  // Kept for API compatibility
856
- setInitialMovementText: L
856
+ setInitialMovementText: S
857
857
  };
858
858
  }
859
859
  function ye({ lines: r, vehicles: o }) {
860
- const [x, s] = _(""), [d, t] = _([]), [f, I] = _(null), { vehicleQueues: O, queueMovement: q, clearQueue: y, error: L } = ce({
860
+ const [x, s] = _(""), [d, t] = _([]), [f, I] = _(null), { vehicleQueues: O, queueMovement: T, clearQueue: y, error: S } = ce({
861
861
  vehicles: o,
862
862
  lines: r
863
863
  }), v = A(!1), p = P((i) => {
@@ -866,7 +866,7 @@ function ye({ lines: r, vehicles: o }) {
866
866
  const { data: n, errors: h } = ve(i), a = [...h];
867
867
  y();
868
868
  for (const m of n) {
869
- const V = q(m.vehicleId, {
869
+ const V = T(m.vehicleId, {
870
870
  targetLineId: m.targetLineId,
871
871
  targetPosition: m.targetPosition,
872
872
  isPercentage: m.isPercentage,
@@ -883,12 +883,12 @@ function ye({ lines: r, vehicles: o }) {
883
883
  setTimeout(() => {
884
884
  v.current = !1;
885
885
  }, 50);
886
- }, [q, y]);
886
+ }, [T, y]);
887
887
  return {
888
888
  movementSequenceText: x,
889
889
  gotoCommands: d,
890
890
  vehicleQueues: O,
891
- sequenceError: f || L,
891
+ sequenceError: f || S,
892
892
  isDebouncing: !1,
893
893
  // No debouncing - parsing is immediate
894
894
  debounceKey: 0,
@@ -1,3 +1,3 @@
1
- "use strict";const o=require("react"),A=require("./core.cjs"),R=require("./vehicle-helpers-82D2V4MI.cjs"),te=require("react/jsx-runtime");function U(s){return Array.isArray(s)?{x:s[0],y:s[1]}:s}function G(s){return{id:s.id,start:U(s.start),end:U(s.end)}}function z(s){const c=s.fromIsPercentage!==!1,I=s.toIsPercentage!==!1;return{fromLineId:s.from,toLineId:s.to,fromOffset:s.fromPosition,fromIsPercentage:s.fromPosition!==void 0?c:void 0,toOffset:s.toPosition,toIsPercentage:s.toPosition!==void 0?I:void 0}}function N(s){const c=s.position??0,I=s.isPercentage!==!1;return{vehicleId:s.id,lineId:s.lineId,offset:c,isPercentage:I}}function H(s){const c=s.isPercentage!==!1,I=s.targetPosition??1;return{vehicleId:s.vehicleId,targetLineId:s.targetLineId,targetOffset:I,isPercentage:c,awaitConfirmation:s.wait,payload:s.payload}}function se(s){const c=[],I=new Set;for(const r of s.lines)I.has(r.id)&&c.push(`Duplicate line ID: ${r.id}`),I.add(r.id);if(s.connections)for(const r of s.connections){I.has(r.from)||c.push(`Connection references non-existent line: ${r.from}`),I.has(r.to)||c.push(`Connection references non-existent line: ${r.to}`);const m=r.fromIsPercentage!==!1,t=r.toIsPercentage!==!1;!m&&r.fromPosition===void 0&&c.push("fromPosition is required when fromIsPercentage is false"),!t&&r.toPosition===void 0&&c.push("toPosition is required when toIsPercentage is false"),r.fromPosition!==void 0&&(m&&(r.fromPosition<0||r.fromPosition>1)?c.push(`Invalid fromPosition: ${r.fromPosition} (must be 0-1 for percentage)`):!m&&r.fromPosition<0&&c.push(`Invalid fromPosition: ${r.fromPosition} (must be >= 0 for absolute distance)`)),r.toPosition!==void 0&&(t&&(r.toPosition<0||r.toPosition>1)?c.push(`Invalid toPosition: ${r.toPosition} (must be 0-1 for percentage)`):!t&&r.toPosition<0&&c.push(`Invalid toPosition: ${r.toPosition} (must be >= 0 for absolute distance)`))}return{valid:c.length===0,errors:c}}function J(){const[s,c]=o.useState([]),[I,r]=o.useState([]),[m,t]=o.useState(null),d=o.useCallback((n,v)=>{c(n),r(v),t(null)},[]),C=o.useCallback(n=>{const v=se(n);if(!v.valid)return t(v.errors.join("; ")),{success:!1,errors:v.errors};const u=n.lines.map(G),g=n.connections?.map(z)||[];return d(u,g),{success:!0}},[d]),y=o.useCallback(n=>{if(s.some(u=>u.id===n.id)){const u=`Line with ID '${n.id}' already exists`;return t(u),{success:!1,error:u}}return c(u=>[...u,G(n)]),t(null),{success:!0}},[s]),q=o.useCallback((n,v)=>{if(s.findIndex(g=>g.id===n)===-1){const g=`Line with ID '${n}' not found`;return t(g),{success:!1,error:g}}return c(g=>g.map(M=>M.id!==n?M:{...M,start:v.start?U(v.start):M.start,end:v.end?U(v.end):M.end})),t(null),{success:!0}},[s]),k=o.useCallback(n=>{if(!s.some(u=>u.id===n)){const u=`Line with ID '${n}' not found`;return t(u),{success:!1,error:u}}return c(u=>u.filter(g=>g.id!==n)),r(u=>u.filter(g=>g.fromLineId!==n&&g.toLineId!==n)),t(null),{success:!0}},[s]),b=o.useCallback(n=>{const v=s.some(f=>f.id===n.from),u=s.some(f=>f.id===n.to);if(!v){const f=`Line '${n.from}' not found`;return t(f),{success:!1,error:f}}if(!u){const f=`Line '${n.to}' not found`;return t(f),{success:!1,error:f}}const g=n.fromIsPercentage!==!1,M=n.toIsPercentage!==!1;if(!g&&n.fromPosition===void 0){const f="fromPosition is required when fromIsPercentage is false";return t(f),{success:!1,error:f}}if(!M&&n.toPosition===void 0){const f="toPosition is required when toIsPercentage is false";return t(f),{success:!1,error:f}}if(I.some(f=>f.fromLineId===n.from&&f.toLineId===n.to)){const f=`Connection from '${n.from}' to '${n.to}' already exists`;return t(f),{success:!1,error:f}}return r(f=>[...f,z(n)]),t(null),{success:!0}},[s,I]),p=o.useCallback((n,v,u)=>{const g=I.findIndex(e=>e.fromLineId===n&&e.toLineId===v);if(g===-1){const e=`Connection from '${n}' to '${v}' not found`;return t(e),{success:!1,error:e}}const M=I[g],Q=u.fromIsPercentage??M.fromIsPercentage,f=u.toIsPercentage??M.toIsPercentage;let $;u.fromOffset!==void 0?$=u.fromOffset:M.fromOffset!==void 0&&($=M.fromOffset);let L;if(u.toOffset!==void 0?L=u.toOffset:M.toOffset!==void 0&&(L=M.toOffset),$!==void 0){if(Q!==!1&&($<0||$>1)){const e=`Invalid fromOffset: ${$} (must be 0-1 for percentage)`;return t(e),{success:!1,error:e}}if(Q===!1&&$<0){const e=`Invalid fromOffset: ${$} (must be >= 0 for absolute distance)`;return t(e),{success:!1,error:e}}}if(L!==void 0){if(f!==!1&&(L<0||L>1)){const e=`Invalid toOffset: ${L} (must be 0-1 for percentage)`;return t(e),{success:!1,error:e}}if(f===!1&&L<0){const e=`Invalid toOffset: ${L} (must be >= 0 for absolute distance)`;return t(e),{success:!1,error:e}}}if(Q===!1&&$===void 0){const e="fromOffset is required when fromIsPercentage is false";return t(e),{success:!1,error:e}}if(f===!1&&L===void 0){const e="toOffset is required when toIsPercentage is false";return t(e),{success:!1,error:e}}const E={from:n,to:v,fromPosition:$,fromIsPercentage:Q,toPosition:L,toIsPercentage:f};return r(e=>e.map((i,l)=>l===g?z(E):i)),t(null),{success:!0}},[I]),P=o.useCallback((n,v)=>{if(!I.some(g=>g.fromLineId===n&&g.toLineId===v)){const g=`Connection from '${n}' to '${v}' not found`;return t(g),{success:!1,error:g}}return r(g=>g.filter(M=>!(M.fromLineId===n&&M.toLineId===v))),t(null),{success:!0}},[I]),a=o.useCallback(()=>{c([]),r([]),t(null)},[]);return{lines:s,curves:I,setScene:C,addLine:y,updateLine:q,removeLine:k,addConnection:b,updateConnection:p,removeConnection:P,clear:a,error:m,_loadScene:d}}function B({lines:s,wheelbase:c}){const[I,r]=o.useState([]),[m,t]=o.useState(null),d=o.useRef([]),C=o.useCallback(p=>{d.current=p,r(p),t(null)},[]),y=o.useCallback(p=>{const P=Array.isArray(p)?p:[p],a=[];for(const g of P)d.current.some(Q=>Q.id===g.id)&&a.push(`Vehicle with ID '${g.id}' already exists`);if(a.length>0)return t(a.join("; ")),{success:!1,errors:a};const n=P.map(N),{vehicles:v,errors:u}=R.validateAndCreateVehicles(n,s,c);return u.length>0?(t(u.join("; ")),{success:!1,errors:u}):(d.current=[...d.current,...v],r(d.current),t(null),{success:!0})},[s,c]),q=o.useCallback((p,P)=>{const a=d.current.findIndex(L=>L.id===p);if(a===-1){const L=`Vehicle with ID '${p}' not found`;return t(L),{success:!1,error:L}}const n=d.current[a];if(n.state!=="idle"){const L=`Cannot update vehicle '${p}' while it is ${n.state}. Vehicle must be idle.`;return t(L),{success:!1,error:L}}const v=P.lineId??n.lineId;if(!s.find(L=>L.id===v)){const L=`Line '${v}' not found`;return t(L),{success:!1,error:L}}let g,M;P.lineId!==void 0&&P.position===void 0?(g=0,M=!0):P.position!==void 0?(g=P.position,M=P.isPercentage??!0):(g=n.offset,M=n.isPercentage);const Q={vehicleId:p,lineId:v,offset:g,isPercentage:M},{vehicles:f,errors:$}=R.validateAndCreateVehicles([Q],s,c);return $.length>0?(t($.join("; ")),{success:!1,error:$.join("; ")}):(d.current=d.current.map((L,E)=>E===a?f[0]:L),r(d.current),t(null),{success:!0})},[s,c]),k=o.useCallback(p=>{if(!d.current.some(a=>a.id===p)){const a=`Vehicle with ID '${p}' not found`;return t(a),{success:!1,error:a}}return d.current=d.current.filter(a=>a.id!==p),r(d.current),t(null),{success:!0}},[]),b=o.useCallback(()=>{d.current=[],r([]),t(null)},[]);return{vehicles:I,addVehicles:y,updateVehicle:q,removeVehicle:k,clear:b,error:m,_loadVehicles:C}}function W({vehicles:s,lines:c}){const[I,r]=o.useState(new Map),[m,t]=o.useState(null),d=o.useRef(new Map),C=o.useCallback(()=>d.current,[]),y=o.useCallback(b=>{d.current=b,r(b),t(null)},[]),q=o.useCallback((b,p)=>{if(!s.some(f=>f.id===b)){const f=`Vehicle '${b}' not found`;return t(f),{success:!1,error:f}}const a=c.find(f=>f.id===p.targetLineId);if(!a){const f=`Line '${p.targetLineId}' not found`;return t(f),{success:!1,error:f}}const n=p.isPercentage!==!1,v=A.distance(a.start,a.end);if(!n&&p.targetPosition===void 0){const f="targetPosition is required when isPercentage is false";return t(f),{success:!1,error:f}}const u=p.targetPosition??1;if(n){if(u<0||u>1){const f=`Invalid targetPosition: ${u} (must be 0-1 for percentage)`;return t(f),{success:!1,error:f}}}else{if(u<0){const f=`Invalid targetPosition: ${u} (must be >= 0 for absolute distance)`;return t(f),{success:!1,error:f}}if(u>v){const f=`Position ${u} exceeds line length ${v}`;return t(f),{success:!1,error:f}}}const g=H({vehicleId:b,...p}),M=new Map(d.current),Q=M.get(b)||[];return M.set(b,[...Q,g]),d.current=M,r(M),t(null),{success:!0}},[s,c]),k=o.useCallback(b=>{if(b!==void 0){if(!s.some(a=>a.id===b)){const a=`Vehicle '${b}' not found`;return t(a),{success:!1,error:a}}const P=new Map(d.current);P.delete(b),d.current=P,r(P)}else d.current=new Map,r(new Map);return t(null),{success:!0}},[s]);return{vehicleQueues:I,getVehicleQueues:C,queueMovement:q,clearQueue:k,error:m,_loadQueues:y}}function Z({vehicles:s,lines:c,vehicleQueues:I,getVehicleQueues:r,wheelbase:m,tangentMode:t,curves:d,eventEmitter:C}){const[y,q]=o.useState([]),k=o.useRef([]),b=o.useCallback(E=>{typeof E=="function"?b(e=>{const i=E(e);return k.current=i,i}):(k.current=E,q(E))},[]),p=o.useCallback(()=>k.current,[]),P=o.useMemo(()=>({wheelbase:m,tangentMode:t}),[m,t]),a=o.useMemo(()=>new Map(c.map(E=>[E.id,E])),[c]),n=o.useRef(new Map);o.useEffect(()=>{const{movingVehicles:E,stateMap:e}=A.initializeAllVehicles(s,a);n.current=e;const i=setTimeout(()=>{b(E)},0);return()=>clearTimeout(i)},[s,a]);const v=o.useRef(null);o.useEffect(()=>{c.length>0&&(v.current=A.buildGraph(c,d,P))},[c,d,P]);const u=o.useRef(0),g=o.useRef(!1),M=o.useCallback(E=>{if(!g.current)return!1;let e=!1;for(const[,l]of n.current)if(l.vehicle.state==="moving"){e=!0;break}if(!e)return!1;const i=[];for(const[l,h]of n.current){if(h.vehicle.state!=="moving"||!h.execution)continue;const x=h.execution;let S;if(x.front.currentSegmentIndex<x.path.segments.length){const T=x.path.segments[x.front.currentSegmentIndex];if(T.type==="line"){const V=a.get(T.lineId);V&&(S=Math.sqrt(Math.pow(V.end.x-V.start.x,2)+Math.pow(V.end.y-V.start.y,2)))}}const O=A.updateAxlePosition(h.vehicle.rear,x.rear,x.path,E,a,x.curveDataMap),D=A.updateAxlePosition(h.vehicle.front,x.front,x.path,E,a,x.curveDataMap,S);if(h.vehicle={...h.vehicle,rear:O.axleState,front:D.axleState},h.execution.rear=O.execution,h.execution.front=D.execution,O.completed){const T={linesMap:a,config:P,vehicleQueues:I,curves:d,graphRef:v,prepareCommandPath:A.prepareCommandPath,onCommandComplete:j=>i.push({type:"commandComplete",data:j}),onCommandStart:j=>i.push({type:"commandStart",data:j})},V=A.handleArrival(h,T);h.vehicle=V.vehicle,V.newExecution!==void 0&&(h.execution=V.newExecution),V.vehicle.state!=="moving"&&i.push({type:"stateChange",data:{vehicleId:l,from:"moving",to:V.vehicle.state}});const w=V.vehicle.rear.position,_=V.vehicle.front.position;i.push({type:"positionUpdate",data:{vehicleId:l,rear:w,front:_,center:{x:(w.x+_.x)/2,y:(w.y+_.y)/2},angle:Math.atan2(_.y-w.y,_.x-w.x)}})}}if(b(l=>l.map(h=>{const x=n.current.get(h.id);return x?x.vehicle:h})),C&&i.length>0){const l=u.current;setTimeout(()=>{u.current===l&&i.forEach(({type:h,data:x})=>{C.emit(h,x)})},0)}for(const[,l]of n.current)if(l.vehicle.state==="moving")return!0;return g.current=!1,!1},[a,d,P,I,C]),Q=o.useCallback(()=>{if(g.current)return!0;const E=v.current;if(!E)return!1;const e=r?r():I,i=[];let l=!1;for(const[h,x]of n.current){const S=x.vehicle,O=e.get(h);if(!O||O.length===0)continue;const D=O[0],T={graph:E,linesMap:a,curves:d,config:P},V=A.prepareCommandPath(S,D,T);if(!V){console.warn(`No path found for vehicle ${h}`);continue}const w=A.calculateFrontAxlePosition(V.path,0,0,m);n.current.set(h,{...x,execution:{path:V.path,curveDataMap:V.curveDataMap,currentCommandIndex:0,rear:{currentSegmentIndex:0,segmentDistance:0},front:w?{currentSegmentIndex:w.segmentIndex,segmentDistance:w.segmentDistance}:{currentSegmentIndex:0,segmentDistance:0}},vehicle:{...S,state:"moving"}}),l=!0,S.state!=="moving"&&i.push({id:h,fromState:S.state,command:D,startPosition:{lineId:S.rear.lineId,absoluteOffset:S.rear.absoluteOffset,position:S.rear.position}})}if(!l)return!1;if(g.current=!0,b(h=>h.map(x=>{const S=n.current.get(x.id);return S?S.vehicle:x})),C&&i.length>0){const h=u.current;setTimeout(()=>{u.current===h&&i.forEach(({id:x,fromState:S,command:O,startPosition:D})=>{C.emit("commandStart",{vehicleId:x,command:O,commandIndex:0,startPosition:D}),C.emit("stateChange",{vehicleId:x,from:S,to:"moving"})})},0)}return!0},[a,d,I,r,P,m,C]),f=o.useCallback(()=>{u.current++,g.current=!1;const{movingVehicles:E,stateMap:e}=A.initializeAllVehicles(s,a);n.current=e,b(E)},[s,a]),$=o.useCallback(E=>{const e=n.current.get(E);if(!e||e.vehicle.state!=="waiting")return!1;const i=I.get(E),l=e.execution;if(!l)return!1;const h=l.currentCommandIndex+1;if(i&&h<i.length){const x=v.current;if(x){const S=i[h],O={graph:x,linesMap:a,curves:d,config:P},D=A.prepareCommandPath(e.vehicle,S,O);if(D){const T=A.calculateFrontAxlePosition(D.path,0,0,m);if(e.execution={path:D.path,curveDataMap:D.curveDataMap,currentCommandIndex:h,rear:{currentSegmentIndex:0,segmentDistance:0},front:T?{currentSegmentIndex:T.segmentIndex,segmentDistance:T.segmentDistance}:{currentSegmentIndex:0,segmentDistance:0}},e.vehicle={...e.vehicle,state:"moving"},b(V=>V.map(w=>w.id===E?e.vehicle:w)),C){const V=u.current;setTimeout(()=>{u.current===V&&C.emit("stateChange",{vehicleId:E,from:"waiting",to:"moving"})},0)}return!0}}}if(e.vehicle={...e.vehicle,state:"idle"},e.execution=null,b(x=>x.map(S=>S.id===E?e.vehicle:S)),C){const x=u.current;setTimeout(()=>{u.current===x&&C.emit("stateChange",{vehicleId:E,from:"waiting",to:"idle"})},0)}return!0},[I,a,d,P,m,C]),L=o.useCallback(()=>{for(const[,E]of n.current)if(E.vehicle.state==="moving")return!0;return!1},[]);return{movingVehicles:y,getMovingVehicles:p,prepare:Q,tick:M,reset:f,continueVehicle:$,isMoving:L,isPrepared:g.current}}function re({wheelbase:s,tangentMode:c="proportional-40",eventEmitter:I}){const r=J(),m=B({lines:r.lines,wheelbase:s}),t=W({vehicles:m.vehicles,lines:r.lines,curves:r.curves}),d=Z({vehicles:m.vehicles,lines:r.lines,vehicleQueues:t.vehicleQueues,getVehicleQueues:t.getVehicleQueues,wheelbase:s,tangentMode:c,curves:r.curves,eventEmitter:I}),C=o.useCallback(e=>m.vehicles.filter(i=>i.lineId===e||i.rear.lineId===e),[m.vehicles]),y=o.useCallback(e=>C(e).length>0,[C]),q=o.useCallback(e=>{const i=r.addLine(e);return i.success?{success:!0}:{success:!1,error:i.error}},[r]),k=o.useCallback((e,i)=>{const l=r.updateLine(e,i);return l.success?{success:!0}:{success:!1,error:l.error}},[r]),b=o.useCallback(e=>{const i=[],l=C(e);l.length>0&&(i.push({type:"vehicle_on_removed_line",message:`${l.length} vehicle(s) are on line '${e}'`,details:{lineId:e,vehicleIds:l.map(S=>S.id)}}),l.forEach(S=>{m.removeVehicle(S.id),t.clearQueue(S.id)}));const h=r.curves.filter(S=>S.fromLineId===e||S.toLineId===e);h.length>0&&i.push({type:"orphaned_connection",message:`${h.length} connection(s) will be removed`,details:{lineId:e,connectionCount:h.length}});const x=r.removeLine(e);return x.success?{success:!0,warnings:i.length>0?i:void 0}:{success:!1,error:x.error}},[r,C,m,t]),p=o.useCallback(()=>{r.clear(),m.clear(),t.clearQueue()},[r,m,t]),P=o.useCallback((e,i,l)=>{const h=r.addConnection({from:e,to:i,fromPosition:l?.fromOffset,fromIsPercentage:l?.fromIsPercentage,toPosition:l?.toOffset,toIsPercentage:l?.toIsPercentage});return h.success?{success:!0}:{success:!1,error:h.error}},[r]),a=o.useCallback((e,i,l)=>{const h=r.updateConnection(e,i,l);return h.success?{success:!0}:{success:!1,error:h.error}},[r]),n=o.useCallback((e,i)=>{const l=r.removeConnection(e,i);return l.success?{success:!0}:{success:!1,error:l.error}},[r]),v=o.useCallback(e=>{const i=m.addVehicles(e);return i.success?{success:!0}:{success:!1,error:i.errors?.join("; ")}},[m]),u=o.useCallback((e,i)=>{const l=m.updateVehicle(e,i);return l.success?{success:!0}:{success:!1,error:l.error}},[m]),g=o.useCallback(e=>{const i=[],l=t.vehicleQueues.get(e);l&&l.length>0&&(i.push({type:"movement_queue_cleared",message:`${l.length} queued movement(s) will be cleared for vehicle '${e}'`,details:{vehicleId:e}}),t.clearQueue(e));const h=m.removeVehicle(e);return h.success?{success:!0,warnings:i.length>0?i:void 0}:{success:!1,error:h.error}},[m,t]),M=o.useCallback(()=>{m.clear(),t.clearQueue()},[m,t]),Q=o.useCallback(e=>{const i={targetLineId:e.lineId,targetPosition:e.position??1,isPercentage:e.isPercentage,wait:e.wait,payload:e.payload},l=t.queueMovement(e.id,i);return l.success?{success:!0}:{success:!1,error:l.error}},[t]),f=o.useCallback(e=>{const i=t.clearQueue(e);return i.success?{success:!0}:{success:!1,error:i.error}},[t]),$=o.useCallback(e=>{const i=[],l=[],{scene:h,vehicles:x,movements:S}=R.parseAllDSL(e);h.errors.length>0&&l.push(...h.errors),x.errors.length>0&&l.push(...x.errors),S.errors.length>0&&l.push(...S.errors);const O=h.data.lines.map(G),D=(h.data.connections||[]).map(z),T=x.data.map(N),{vehicles:V,errors:w}=R.validateAndCreateVehicles(T,O,s);w.length>0&&l.push(...w);const _=new Map;for(const j of S.data){const Y=_.get(j.vehicleId)||[];Y.push(H(j)),_.set(j.vehicleId,Y)}return r._loadScene(O,D),m._loadVehicles(V),t._loadQueues(_),l.length>0&&i.push({type:"dsl_parse_error",message:`DSL loading had ${l.length} error(s)`,details:{errors:l}}),{success:!0,warnings:i.length>0?i:void 0}},[r,m,t,s]),L=o.useCallback(e=>{const i=[],l=[],h=e.lines.map(G),x=(e.connections||[]).map(z),S=(e.vehicles||[]).map(N),{vehicles:O,errors:D}=R.validateAndCreateVehicles(S,h,s);D.length>0&&l.push(...D);const T=new Map;for(const V of e.movements||[]){const w=T.get(V.vehicleId)||[];w.push(H({vehicleId:V.vehicleId,targetLineId:V.targetLineId,targetPosition:V.targetPosition,isPercentage:V.isPercentage,wait:V.wait,payload:V.payload})),T.set(V.vehicleId,w)}return r._loadScene(h,x),m._loadVehicles(O),t._loadQueues(T),l.length>0&&i.push({type:"dsl_parse_error",message:`JSON loading had ${l.length} error(s)`,details:{errors:l}}),{success:!0,warnings:i.length>0?i:void 0}},[r,m,t,s]),E=o.useMemo(()=>r.error||m.error||t.error,[r.error,m.error,t.error]);return{lines:r.lines,curves:r.curves,vehicles:m.vehicles,movingVehicles:d.movingVehicles,getMovingVehicles:d.getMovingVehicles,vehicleQueues:t.vehicleQueues,error:E,addLine:q,updateLine:k,removeLine:b,clearScene:p,connect:P,updateConnection:a,disconnect:n,addVehicles:v,updateVehicle:u,removeVehicle:g,clearVehicles:M,goto:Q,clearQueue:f,prepare:d.prepare,tick:d.tick,reset:d.reset,continueVehicle:d.continueVehicle,isMoving:d.isMoving,loadFromDSL:$,loadFromJSON:L,getVehiclesOnLine:C,hasVehiclesOnLine:y}}function F(s){return s.map(c=>({id:c.id,start:c.start,end:c.end}))}function K(s){return s.map(c=>({from:c.fromLineId,to:c.toLineId,fromPosition:c.fromOffset,fromIsPercentage:c.fromIsPercentage,toPosition:c.toOffset,toIsPercentage:c.toIsPercentage}))}function ne(){const[s,c]=o.useState(""),[I,r]=o.useState(null),{lines:m,curves:t,setScene:d}=J(),C=o.useRef(!1),y=o.useRef("");o.useEffect(()=>{y.current=s},[s]),o.useEffect(()=>{if(C.current)return;const p={lines:F(m),connections:t.length>0?K(t):void 0},P=R.generateSceneDSL(p);P!==y.current&&(C.current=!0,c(P),setTimeout(()=>{C.current=!1},50))},[m,t]);const q=o.useCallback(p=>{C.current=!0,c(p);try{const{data:P,errors:a}=R.parseSceneDSL(p);a.length>0&&r(a.join("; "));const n=d(P);!n.success&&n.errors?r(v=>v?`${v}; ${n.errors.join("; ")}`:n.errors.join("; ")):a.length===0&&r(null)}catch(P){r(P instanceof Error?P.message:"Invalid scene definition")}setTimeout(()=>{C.current=!1},50)},[d]),k=o.useCallback(p=>{const P=typeof p=="function"?p(m):p,a=K(t);d({lines:F(P),connections:a.length>0?a:void 0});const n={lines:F(P),connections:a.length>0?a:void 0},v=R.generateSceneDSL(n);C.current=!0,c(v),setTimeout(()=>{C.current=!1},50)},[m,t,d]),b=o.useCallback(p=>{const P=typeof p=="function"?p(t):p,a=K(P);d({lines:F(m),connections:a.length>0?a:void 0});const n={lines:F(m),connections:a.length>0?a:void 0},v=R.generateSceneDSL(n);C.current=!0,c(v),setTimeout(()=>{C.current=!1},50)},[m,t,d]);return{lines:m,curves:t,sceneDefinitionText:s,sceneError:I,isDebouncing:!1,debounceKey:0,setLines:k,setCurves:b,setSceneDefinitionText:q}}function oe({lines:s,wheelbase:c}){const[I,r]=o.useState(""),[m,t]=o.useState(null),{vehicles:d,addVehicles:C,clear:y,error:q}=B({lines:s,wheelbase:c}),k=o.useRef(!1),b=o.useCallback(p=>{k.current=!0,r(p);try{const{data:P,errors:a}=R.parseVehiclesDSL(p),n=[...a];y();for(const v of P){const u=C(v);!u.success&&u.errors&&n.push(...u.errors)}n.length>0?t(n.join(`
2
- `)):t(null)}catch(P){t(P instanceof Error?P.message:"Invalid initial movement")}setTimeout(()=>{k.current=!1},50)},[C,y]);return{vehicles:d,initialMovementText:I,movementError:m||q,isDebouncing:!1,debounceKey:0,setInitialMovementText:b}}function ce({lines:s,vehicles:c}){const[I,r]=o.useState(""),[m,t]=o.useState([]),[d,C]=o.useState(null),{vehicleQueues:y,queueMovement:q,clearQueue:k,error:b}=W({vehicles:c,lines:s}),p=o.useRef(!1),P=o.useCallback(a=>{p.current=!0,r(a);try{const{data:n,errors:v}=R.parseMovementDSL(a),u=[...v];k();for(const g of n){const M=q(g.vehicleId,{targetLineId:g.targetLineId,targetPosition:g.targetPosition,isPercentage:g.isPercentage,wait:g.wait,payload:g.payload});!M.success&&M.error&&u.push(M.error)}t(n),u.length>0?C(u.join(`
3
- `)):C(null)}catch(n){C(n instanceof Error?n.message:"Invalid movement sequence"),t([])}setTimeout(()=>{p.current=!1},50)},[q,k]);return{movementSequenceText:I,gotoCommands:m,vehicleQueues:y,sequenceError:d||b,isDebouncing:!1,debounceKey:0,setMovementSequenceText:P}}const X=o.createContext(null);function ee(){const s=o.useContext(X);if(!s)throw new Error("useVehicleEventEmitter must be used within a VehicleEventProvider");return s}function ie(){return o.useMemo(()=>new R.VehicleEventEmitter,[])}function ae(s,c,I=[]){const r=ee();o.useEffect(()=>r.on(s,c),[r,s,...I])}function ue({children:s}){const c=o.useMemo(()=>new R.VehicleEventEmitter,[]);return te.jsx(X.Provider,{value:c,children:s})}exports.VehicleEventContext=X;exports.VehicleEventProvider=ue;exports.useAnimation=Z;exports.useCreateVehicleEventEmitter=ie;exports.useInitialMovement=oe;exports.useMovementQueue=W;exports.useMovementSequence=ce;exports.useScene=J;exports.useSceneDefinition=ne;exports.useVehicleEvent=ae;exports.useVehicleEventEmitter=ee;exports.useVehicleSimulation=re;exports.useVehicles=B;
1
+ "use strict";const o=require("react"),A=require("./core.cjs"),R=require("./vehicle-helpers-82D2V4MI.cjs"),te=require("react/jsx-runtime");function U(s){return Array.isArray(s)?{x:s[0],y:s[1]}:s}function G(s){return{id:s.id,start:U(s.start),end:U(s.end)}}function z(s){const c=s.fromIsPercentage!==!1,I=s.toIsPercentage!==!1;return{fromLineId:s.from,toLineId:s.to,fromOffset:s.fromPosition,fromIsPercentage:s.fromPosition!==void 0?c:void 0,toOffset:s.toPosition,toIsPercentage:s.toPosition!==void 0?I:void 0}}function N(s){const c=s.position??0,I=s.isPercentage!==!1;return{vehicleId:s.id,lineId:s.lineId,offset:c,isPercentage:I}}function H(s){const c=s.isPercentage!==!1,I=s.targetPosition??1;return{vehicleId:s.vehicleId,targetLineId:s.targetLineId,targetOffset:I,isPercentage:c,awaitConfirmation:s.wait,payload:s.payload}}function se(s){const c=[],I=new Set;for(const r of s.lines)I.has(r.id)&&c.push(`Duplicate line ID: ${r.id}`),I.add(r.id);if(s.connections)for(const r of s.connections){I.has(r.from)||c.push(`Connection references non-existent line: ${r.from}`),I.has(r.to)||c.push(`Connection references non-existent line: ${r.to}`);const m=r.fromIsPercentage!==!1,t=r.toIsPercentage!==!1;!m&&r.fromPosition===void 0&&c.push("fromPosition is required when fromIsPercentage is false"),!t&&r.toPosition===void 0&&c.push("toPosition is required when toIsPercentage is false"),r.fromPosition!==void 0&&(m&&(r.fromPosition<0||r.fromPosition>1)?c.push(`Invalid fromPosition: ${r.fromPosition} (must be 0-1 for percentage)`):!m&&r.fromPosition<0&&c.push(`Invalid fromPosition: ${r.fromPosition} (must be >= 0 for absolute distance)`)),r.toPosition!==void 0&&(t&&(r.toPosition<0||r.toPosition>1)?c.push(`Invalid toPosition: ${r.toPosition} (must be 0-1 for percentage)`):!t&&r.toPosition<0&&c.push(`Invalid toPosition: ${r.toPosition} (must be >= 0 for absolute distance)`))}return{valid:c.length===0,errors:c}}function J(){const[s,c]=o.useState([]),[I,r]=o.useState([]),[m,t]=o.useState(null),d=o.useCallback((n,v)=>{c(n),r(v),t(null)},[]),C=o.useCallback(n=>{const v=se(n);if(!v.valid)return t(v.errors.join("; ")),{success:!1,errors:v.errors};const u=n.lines.map(G),g=n.connections?.map(z)||[];return d(u,g),{success:!0}},[d]),y=o.useCallback(n=>{if(s.some(u=>u.id===n.id)){const u=`Line with ID '${n.id}' already exists`;return t(u),{success:!1,error:u}}return c(u=>[...u,G(n)]),t(null),{success:!0}},[s]),D=o.useCallback((n,v)=>{if(s.findIndex(g=>g.id===n)===-1){const g=`Line with ID '${n}' not found`;return t(g),{success:!1,error:g}}return c(g=>g.map(M=>M.id!==n?M:{...M,start:v.start?U(v.start):M.start,end:v.end?U(v.end):M.end})),t(null),{success:!0}},[s]),k=o.useCallback(n=>{if(!s.some(u=>u.id===n)){const u=`Line with ID '${n}' not found`;return t(u),{success:!1,error:u}}return c(u=>u.filter(g=>g.id!==n)),r(u=>u.filter(g=>g.fromLineId!==n&&g.toLineId!==n)),t(null),{success:!0}},[s]),V=o.useCallback(n=>{const v=s.some(f=>f.id===n.from),u=s.some(f=>f.id===n.to);if(!v){const f=`Line '${n.from}' not found`;return t(f),{success:!1,error:f}}if(!u){const f=`Line '${n.to}' not found`;return t(f),{success:!1,error:f}}const g=n.fromIsPercentage!==!1,M=n.toIsPercentage!==!1;if(!g&&n.fromPosition===void 0){const f="fromPosition is required when fromIsPercentage is false";return t(f),{success:!1,error:f}}if(!M&&n.toPosition===void 0){const f="toPosition is required when toIsPercentage is false";return t(f),{success:!1,error:f}}if(I.some(f=>f.fromLineId===n.from&&f.toLineId===n.to)){const f=`Connection from '${n.from}' to '${n.to}' already exists`;return t(f),{success:!1,error:f}}return r(f=>[...f,z(n)]),t(null),{success:!0}},[s,I]),p=o.useCallback((n,v,u)=>{const g=I.findIndex(e=>e.fromLineId===n&&e.toLineId===v);if(g===-1){const e=`Connection from '${n}' to '${v}' not found`;return t(e),{success:!1,error:e}}const M=I[g],Q=u.fromIsPercentage??M.fromIsPercentage,f=u.toIsPercentage??M.toIsPercentage;let $;u.fromOffset!==void 0?$=u.fromOffset:M.fromOffset!==void 0&&($=M.fromOffset);let L;if(u.toOffset!==void 0?L=u.toOffset:M.toOffset!==void 0&&(L=M.toOffset),$!==void 0){if(Q!==!1&&($<0||$>1)){const e=`Invalid fromOffset: ${$} (must be 0-1 for percentage)`;return t(e),{success:!1,error:e}}if(Q===!1&&$<0){const e=`Invalid fromOffset: ${$} (must be >= 0 for absolute distance)`;return t(e),{success:!1,error:e}}}if(L!==void 0){if(f!==!1&&(L<0||L>1)){const e=`Invalid toOffset: ${L} (must be 0-1 for percentage)`;return t(e),{success:!1,error:e}}if(f===!1&&L<0){const e=`Invalid toOffset: ${L} (must be >= 0 for absolute distance)`;return t(e),{success:!1,error:e}}}if(Q===!1&&$===void 0){const e="fromOffset is required when fromIsPercentage is false";return t(e),{success:!1,error:e}}if(f===!1&&L===void 0){const e="toOffset is required when toIsPercentage is false";return t(e),{success:!1,error:e}}const E={from:n,to:v,fromPosition:$,fromIsPercentage:Q,toPosition:L,toIsPercentage:f};return r(e=>e.map((i,l)=>l===g?z(E):i)),t(null),{success:!0}},[I]),P=o.useCallback((n,v)=>{if(!I.some(g=>g.fromLineId===n&&g.toLineId===v)){const g=`Connection from '${n}' to '${v}' not found`;return t(g),{success:!1,error:g}}return r(g=>g.filter(M=>!(M.fromLineId===n&&M.toLineId===v))),t(null),{success:!0}},[I]),a=o.useCallback(()=>{c([]),r([]),t(null)},[]);return{lines:s,curves:I,setScene:C,addLine:y,updateLine:D,removeLine:k,addConnection:V,updateConnection:p,removeConnection:P,clear:a,error:m,_loadScene:d}}function B({lines:s,wheelbase:c}){const[I,r]=o.useState([]),[m,t]=o.useState(null),d=o.useRef([]),C=o.useCallback(p=>{d.current=p,r(p),t(null)},[]),y=o.useCallback(p=>{const P=Array.isArray(p)?p:[p],a=[];for(const g of P)d.current.some(Q=>Q.id===g.id)&&a.push(`Vehicle with ID '${g.id}' already exists`);if(a.length>0)return t(a.join("; ")),{success:!1,errors:a};const n=P.map(N),{vehicles:v,errors:u}=R.validateAndCreateVehicles(n,s,c);return u.length>0?(t(u.join("; ")),{success:!1,errors:u}):(d.current=[...d.current,...v],r(d.current),t(null),{success:!0})},[s,c]),D=o.useCallback((p,P)=>{const a=d.current.findIndex(L=>L.id===p);if(a===-1){const L=`Vehicle with ID '${p}' not found`;return t(L),{success:!1,error:L}}const n=d.current[a];if(n.state!=="idle"){const L=`Cannot update vehicle '${p}' while it is ${n.state}. Vehicle must be idle.`;return t(L),{success:!1,error:L}}const v=P.lineId??n.lineId;if(!s.find(L=>L.id===v)){const L=`Line '${v}' not found`;return t(L),{success:!1,error:L}}let g,M;P.lineId!==void 0&&P.position===void 0?(g=0,M=!0):P.position!==void 0?(g=P.position,M=P.isPercentage??!0):(g=n.offset,M=n.isPercentage);const Q={vehicleId:p,lineId:v,offset:g,isPercentage:M},{vehicles:f,errors:$}=R.validateAndCreateVehicles([Q],s,c);return $.length>0?(t($.join("; ")),{success:!1,error:$.join("; ")}):(d.current=d.current.map((L,E)=>E===a?f[0]:L),r(d.current),t(null),{success:!0})},[s,c]),k=o.useCallback(p=>{if(!d.current.some(a=>a.id===p)){const a=`Vehicle with ID '${p}' not found`;return t(a),{success:!1,error:a}}return d.current=d.current.filter(a=>a.id!==p),r(d.current),t(null),{success:!0}},[]),V=o.useCallback(()=>{d.current=[],r([]),t(null)},[]);return{vehicles:I,addVehicles:y,updateVehicle:D,removeVehicle:k,clear:V,error:m,_loadVehicles:C}}function W({vehicles:s,lines:c}){const[I,r]=o.useState(new Map),[m,t]=o.useState(null),d=o.useRef(new Map),C=o.useCallback(()=>d.current,[]),y=o.useCallback(V=>{d.current=V,r(V),t(null)},[]),D=o.useCallback((V,p)=>{if(!s.some(f=>f.id===V)){const f=`Vehicle '${V}' not found`;return t(f),{success:!1,error:f}}const a=c.find(f=>f.id===p.targetLineId);if(!a){const f=`Line '${p.targetLineId}' not found`;return t(f),{success:!1,error:f}}const n=p.isPercentage!==!1,v=A.distance(a.start,a.end);if(!n&&p.targetPosition===void 0){const f="targetPosition is required when isPercentage is false";return t(f),{success:!1,error:f}}const u=p.targetPosition??1;if(n){if(u<0||u>1){const f=`Invalid targetPosition: ${u} (must be 0-1 for percentage)`;return t(f),{success:!1,error:f}}}else{if(u<0){const f=`Invalid targetPosition: ${u} (must be >= 0 for absolute distance)`;return t(f),{success:!1,error:f}}if(u>v){const f=`Position ${u} exceeds line length ${v}`;return t(f),{success:!1,error:f}}}const g=H({vehicleId:V,...p}),M=new Map(d.current),Q=M.get(V)||[];return M.set(V,[...Q,g]),d.current=M,r(M),t(null),{success:!0}},[s,c]),k=o.useCallback(V=>{if(V!==void 0){if(!s.some(a=>a.id===V)){const a=`Vehicle '${V}' not found`;return t(a),{success:!1,error:a}}const P=new Map(d.current);P.delete(V),d.current=P,r(P)}else d.current=new Map,r(new Map);return t(null),{success:!0}},[s]);return{vehicleQueues:I,getVehicleQueues:C,queueMovement:D,clearQueue:k,error:m,_loadQueues:y}}function Z({vehicles:s,lines:c,vehicleQueues:I,getVehicleQueues:r,wheelbase:m,tangentMode:t,curves:d,eventEmitter:C}){const[y,D]=o.useState([]),k=o.useRef([]),V=o.useCallback(E=>{typeof E=="function"?D(e=>{const i=E(e);return k.current=i,i}):(k.current=E,D(E))},[]),p=o.useCallback(()=>k.current,[]),P=o.useMemo(()=>({wheelbase:m,tangentMode:t}),[m,t]),a=o.useMemo(()=>new Map(c.map(E=>[E.id,E])),[c]),n=o.useRef(new Map);o.useEffect(()=>{const{movingVehicles:E,stateMap:e}=A.initializeAllVehicles(s,a);n.current=e;const i=setTimeout(()=>{V(E)},0);return()=>clearTimeout(i)},[s,a]);const v=o.useRef(null);o.useEffect(()=>{c.length>0&&(v.current=A.buildGraph(c,d,P))},[c,d,P]);const u=o.useRef(0),g=o.useRef(!1),M=o.useCallback(E=>{if(!g.current)return!1;let e=!1;for(const[,l]of n.current)if(l.vehicle.state==="moving"){e=!0;break}if(!e)return!1;const i=[];for(const[l,h]of n.current){if(h.vehicle.state!=="moving"||!h.execution)continue;const x=h.execution;let S;if(x.front.currentSegmentIndex<x.path.segments.length){const T=x.path.segments[x.front.currentSegmentIndex];if(T.type==="line"){const b=a.get(T.lineId);b&&(S=Math.sqrt(Math.pow(b.end.x-b.start.x,2)+Math.pow(b.end.y-b.start.y,2)))}}const O=A.updateAxlePosition(h.vehicle.rear,x.rear,x.path,E,a,x.curveDataMap),q=A.updateAxlePosition(h.vehicle.front,x.front,x.path,E,a,x.curveDataMap,S);if(h.vehicle={...h.vehicle,rear:O.axleState,front:q.axleState},h.execution.rear=O.execution,h.execution.front=q.execution,O.completed){const T={linesMap:a,config:P,vehicleQueues:I,curves:d,graphRef:v,prepareCommandPath:A.prepareCommandPath,onCommandComplete:j=>i.push({type:"commandComplete",data:j}),onCommandStart:j=>i.push({type:"commandStart",data:j})},b=A.handleArrival(h,T);h.vehicle=b.vehicle,b.newExecution!==void 0&&(h.execution=b.newExecution),b.vehicle.state!=="moving"&&i.push({type:"stateChange",data:{vehicleId:l,from:"moving",to:b.vehicle.state}});const w=b.vehicle.rear.position,_=b.vehicle.front.position;i.push({type:"positionUpdate",data:{vehicleId:l,rear:w,front:_,center:{x:(w.x+_.x)/2,y:(w.y+_.y)/2},angle:Math.atan2(_.y-w.y,_.x-w.x)}})}}if(V(l=>l.map(h=>{const x=n.current.get(h.id);return x?x.vehicle:h})),C&&i.length>0){const l=u.current;setTimeout(()=>{u.current===l&&i.forEach(({type:h,data:x})=>{C.emit(h,x)})},0)}for(const[,l]of n.current)if(l.vehicle.state==="moving")return!0;return g.current=!1,!1},[a,d,P,I,C]),Q=o.useCallback(()=>{if(g.current)return!0;const E=v.current;if(!E)return!1;const e=r?r():I,i=[];let l=!1;for(const[h,x]of n.current){const S=x.vehicle,O=e.get(h);if(!O||O.length===0)continue;const q=O[0],T={graph:E,linesMap:a,curves:d,config:P},b=A.prepareCommandPath(S,q,T);if(!b){console.warn(`No path found for vehicle ${h}`);continue}const w=A.calculateFrontAxlePosition(b.path,0,0,m);n.current.set(h,{...x,execution:{path:b.path,curveDataMap:b.curveDataMap,currentCommandIndex:0,rear:{currentSegmentIndex:0,segmentDistance:0},front:w?{currentSegmentIndex:w.segmentIndex,segmentDistance:w.segmentDistance}:{currentSegmentIndex:0,segmentDistance:0}},vehicle:{...S,state:"moving"}}),l=!0,S.state!=="moving"&&i.push({id:h,fromState:S.state,command:q,startPosition:{lineId:S.rear.lineId,absoluteOffset:S.rear.absoluteOffset,position:S.rear.position}})}if(!l)return!1;if(g.current=!0,V(h=>h.map(x=>{const S=n.current.get(x.id);return S?S.vehicle:x})),C&&i.length>0){const h=u.current;setTimeout(()=>{u.current===h&&i.forEach(({id:x,fromState:S,command:O,startPosition:q})=>{C.emit("commandStart",{vehicleId:x,command:O,commandIndex:0,startPosition:q}),C.emit("stateChange",{vehicleId:x,from:S,to:"moving"})})},0)}return!0},[a,d,I,r,P,m,C]),f=o.useCallback(()=>{u.current++,g.current=!1;const{movingVehicles:E,stateMap:e}=A.initializeAllVehicles(s,a);n.current=e,V(E)},[s,a]),$=o.useCallback(E=>{const e=n.current.get(E);if(!e||e.vehicle.state!=="waiting")return!1;const i=I.get(E),l=e.execution;if(!l)return!1;const h=l.currentCommandIndex+1;if(i&&h<i.length){const x=v.current;if(x){const S=i[h],O={graph:x,linesMap:a,curves:d,config:P},q=A.prepareCommandPath(e.vehicle,S,O);if(q){const T=A.calculateFrontAxlePosition(q.path,0,0,m);if(e.execution={path:q.path,curveDataMap:q.curveDataMap,currentCommandIndex:h,rear:{currentSegmentIndex:0,segmentDistance:0},front:T?{currentSegmentIndex:T.segmentIndex,segmentDistance:T.segmentDistance}:{currentSegmentIndex:0,segmentDistance:0}},e.vehicle={...e.vehicle,state:"moving"},V(b=>b.map(w=>w.id===E?e.vehicle:w)),C){const b=u.current;setTimeout(()=>{u.current===b&&C.emit("stateChange",{vehicleId:E,from:"waiting",to:"moving"})},0)}return!0}}}if(e.vehicle={...e.vehicle,state:"idle"},e.execution=null,V(x=>x.map(S=>S.id===E?e.vehicle:S)),C){const x=u.current;setTimeout(()=>{u.current===x&&C.emit("stateChange",{vehicleId:E,from:"waiting",to:"idle"})},0)}return!0},[I,a,d,P,m,C]),L=o.useCallback(()=>{for(const[,E]of n.current)if(E.vehicle.state==="moving")return!0;return!1},[]);return{movingVehicles:y,getMovingVehicles:p,prepare:Q,tick:M,reset:f,continueVehicle:$,isMoving:L,isPrepared:g.current}}function re({wheelbase:s,tangentMode:c="proportional-40",eventEmitter:I}){const r=J(),m=B({lines:r.lines,wheelbase:s}),t=W({vehicles:m.vehicles,lines:r.lines,curves:r.curves}),d=Z({vehicles:m.vehicles,lines:r.lines,vehicleQueues:t.vehicleQueues,getVehicleQueues:t.getVehicleQueues,wheelbase:s,tangentMode:c,curves:r.curves,eventEmitter:I}),C=o.useCallback(e=>m.vehicles.filter(i=>i.lineId===e||i.rear.lineId===e),[m.vehicles]),y=o.useCallback(e=>C(e).length>0,[C]),D=o.useCallback(e=>{const i=r.addLine(e);return i.success?{success:!0}:{success:!1,error:i.error}},[r]),k=o.useCallback((e,i)=>{const l=r.updateLine(e,i);return l.success?{success:!0}:{success:!1,error:l.error}},[r]),V=o.useCallback(e=>{const i=[],l=C(e);l.length>0&&(i.push({type:"vehicle_on_removed_line",message:`${l.length} vehicle(s) are on line '${e}'`,details:{lineId:e,vehicleIds:l.map(S=>S.id)}}),l.forEach(S=>{m.removeVehicle(S.id),t.clearQueue(S.id)}));const h=r.curves.filter(S=>S.fromLineId===e||S.toLineId===e);h.length>0&&i.push({type:"orphaned_connection",message:`${h.length} connection(s) will be removed`,details:{lineId:e,connectionCount:h.length}});const x=r.removeLine(e);return x.success?{success:!0,warnings:i.length>0?i:void 0}:{success:!1,error:x.error}},[r,C,m,t]),p=o.useCallback(()=>{r.clear(),m.clear(),t.clearQueue()},[r,m,t]),P=o.useCallback((e,i,l)=>{const h=r.addConnection({from:e,to:i,fromPosition:l?.fromOffset,fromIsPercentage:l?.fromIsPercentage,toPosition:l?.toOffset,toIsPercentage:l?.toIsPercentage});return h.success?{success:!0}:{success:!1,error:h.error}},[r]),a=o.useCallback((e,i,l)=>{const h=r.updateConnection(e,i,l);return h.success?{success:!0}:{success:!1,error:h.error}},[r]),n=o.useCallback((e,i)=>{const l=r.removeConnection(e,i);return l.success?{success:!0}:{success:!1,error:l.error}},[r]),v=o.useCallback(e=>{const i=m.addVehicles(e);return i.success?{success:!0}:{success:!1,error:i.errors?.join("; ")}},[m]),u=o.useCallback((e,i)=>{const l=m.updateVehicle(e,i);return l.success?{success:!0}:{success:!1,error:l.error}},[m]),g=o.useCallback(e=>{const i=[],l=t.vehicleQueues.get(e);l&&l.length>0&&(i.push({type:"movement_queue_cleared",message:`${l.length} queued movement(s) will be cleared for vehicle '${e}'`,details:{vehicleId:e}}),t.clearQueue(e));const h=m.removeVehicle(e);return h.success?{success:!0,warnings:i.length>0?i:void 0}:{success:!1,error:h.error}},[m,t]),M=o.useCallback(()=>{m.clear(),t.clearQueue()},[m,t]),Q=o.useCallback(e=>{const i={targetLineId:e.lineId,targetPosition:e.position??1,isPercentage:e.isPercentage,wait:e.wait,payload:e.payload},l=t.queueMovement(e.id,i);return l.success?{success:!0}:{success:!1,error:l.error}},[t]),f=o.useCallback(e=>{const i=t.clearQueue(e);return i.success?{success:!0}:{success:!1,error:i.error}},[t]),$=o.useCallback(e=>{const i=[],l=[],{scene:h,vehicles:x,movements:S}=R.parseAllDSL(e);h.errors.length>0&&l.push(...h.errors),x.errors.length>0&&l.push(...x.errors),S.errors.length>0&&l.push(...S.errors);const O=h.data.lines.map(G),q=(h.data.connections||[]).map(z),T=x.data.map(N),{vehicles:b,errors:w}=R.validateAndCreateVehicles(T,O,s);w.length>0&&l.push(...w);const _=new Map;for(const j of S.data){const Y=_.get(j.vehicleId)||[];Y.push(H(j)),_.set(j.vehicleId,Y)}return r._loadScene(O,q),m._loadVehicles(b),t._loadQueues(_),l.length>0&&i.push({type:"dsl_parse_error",message:`DSL loading had ${l.length} error(s)`,details:{errors:l}}),{success:!0,warnings:i.length>0?i:void 0}},[r,m,t,s]),L=o.useCallback(e=>{const i=[],l=[],h=e.lines.map(G),x=(e.connections||[]).map(z),S=(e.vehicles||[]).map(N),{vehicles:O,errors:q}=R.validateAndCreateVehicles(S,h,s);q.length>0&&l.push(...q);const T=new Map;for(const b of e.movements||[]){const w=T.get(b.vehicleId)||[];w.push(H({vehicleId:b.vehicleId,targetLineId:b.targetLineId,targetPosition:b.targetPosition,isPercentage:b.isPercentage,wait:b.wait,payload:b.payload})),T.set(b.vehicleId,w)}return r._loadScene(h,x),m._loadVehicles(O),t._loadQueues(T),l.length>0&&i.push({type:"dsl_parse_error",message:`JSON loading had ${l.length} error(s)`,details:{errors:l}}),{success:!0,warnings:i.length>0?i:void 0}},[r,m,t,s]),E=o.useMemo(()=>r.error||m.error||t.error,[r.error,m.error,t.error]);return{lines:r.lines,curves:r.curves,vehicles:m.vehicles,movingVehicles:d.movingVehicles,getMovingVehicles:d.getMovingVehicles,vehicleQueues:t.vehicleQueues,error:E,addLine:D,updateLine:k,removeLine:V,clearScene:p,connect:P,updateConnection:a,disconnect:n,addVehicles:v,updateVehicle:u,removeVehicle:g,clearVehicles:M,goto:Q,clearQueue:f,prepare:d.prepare,tick:d.tick,reset:d.reset,continueVehicle:d.continueVehicle,isMoving:d.isMoving,loadFromDSL:$,loadFromJSON:L,getVehiclesOnLine:C,hasVehiclesOnLine:y}}function F(s){return s.map(c=>({id:c.id,start:c.start,end:c.end}))}function K(s){return s.map(c=>({from:c.fromLineId,to:c.toLineId,fromPosition:c.fromOffset,fromIsPercentage:c.fromIsPercentage,toPosition:c.toOffset,toIsPercentage:c.toIsPercentage}))}function ne(){const[s,c]=o.useState(""),[I,r]=o.useState(null),{lines:m,curves:t,setScene:d}=J(),C=o.useRef(!1),y=o.useRef("");o.useEffect(()=>{y.current=s},[s]),o.useEffect(()=>{if(C.current)return;const p={lines:F(m),connections:t.length>0?K(t):void 0},P=R.generateSceneDSL(p);P!==y.current&&(C.current=!0,c(P),setTimeout(()=>{C.current=!1},50))},[m,t]);const D=o.useCallback(p=>{C.current=!0,c(p);try{const{data:P,errors:a}=R.parseSceneDSL(p);a.length>0&&r(a.join("; "));const n=d(P);!n.success&&n.errors?r(v=>v?`${v}; ${n.errors.join("; ")}`:n.errors.join("; ")):a.length===0&&r(null)}catch(P){r(P instanceof Error?P.message:"Invalid scene definition")}setTimeout(()=>{C.current=!1},50)},[d]),k=o.useCallback(p=>{const P=typeof p=="function"?p(m):p,a=K(t);d({lines:F(P),connections:a.length>0?a:void 0});const n={lines:F(P),connections:a.length>0?a:void 0},v=R.generateSceneDSL(n);C.current=!0,c(v),setTimeout(()=>{C.current=!1},50)},[m,t,d]),V=o.useCallback(p=>{const P=typeof p=="function"?p(t):p,a=K(P);d({lines:F(m),connections:a.length>0?a:void 0});const n={lines:F(m),connections:a.length>0?a:void 0},v=R.generateSceneDSL(n);C.current=!0,c(v),setTimeout(()=>{C.current=!1},50)},[m,t,d]);return{lines:m,curves:t,sceneDefinitionText:s,sceneError:I,isDebouncing:!1,debounceKey:0,setLines:k,setCurves:V,setSceneDefinitionText:D}}function oe({lines:s,wheelbase:c}){const[I,r]=o.useState(""),[m,t]=o.useState(null),{vehicles:d,addVehicles:C,clear:y,error:D}=B({lines:s,wheelbase:c}),k=o.useRef(!1),V=o.useCallback(p=>{k.current=!0,r(p);try{const{data:P,errors:a}=R.parseVehiclesDSL(p),n=[...a];y();for(const v of P){const u=C(v);!u.success&&u.errors&&n.push(...u.errors)}n.length>0?t(n.join(`
2
+ `)):t(null)}catch(P){t(P instanceof Error?P.message:"Invalid initial movement")}setTimeout(()=>{k.current=!1},50)},[C,y]);return{vehicles:d,initialMovementText:I,movementError:m||D,isDebouncing:!1,debounceKey:0,setInitialMovementText:V}}function ce({lines:s,vehicles:c}){const[I,r]=o.useState(""),[m,t]=o.useState([]),[d,C]=o.useState(null),{vehicleQueues:y,queueMovement:D,clearQueue:k,error:V}=W({vehicles:c,lines:s}),p=o.useRef(!1),P=o.useCallback(a=>{p.current=!0,r(a);try{const{data:n,errors:v}=R.parseMovementDSL(a),u=[...v];k();for(const g of n){const M=D(g.vehicleId,{targetLineId:g.targetLineId,targetPosition:g.targetPosition,isPercentage:g.isPercentage,wait:g.wait,payload:g.payload});!M.success&&M.error&&u.push(M.error)}t(n),u.length>0?C(u.join(`
3
+ `)):C(null)}catch(n){C(n instanceof Error?n.message:"Invalid movement sequence"),t([])}setTimeout(()=>{p.current=!1},50)},[D,k]);return{movementSequenceText:I,gotoCommands:m,vehicleQueues:y,sequenceError:d||V,isDebouncing:!1,debounceKey:0,setMovementSequenceText:P}}const X=o.createContext(null);function ee(){const s=o.useContext(X);if(!s)throw new Error("useVehicleEventEmitter must be used within a VehicleEventProvider");return s}function ie(){return o.useMemo(()=>new R.VehicleEventEmitter,[])}function ae(s,c,I=[]){const r=ee();o.useEffect(()=>r.on(s,c),[r,s,...I])}function ue({children:s}){const c=o.useMemo(()=>new R.VehicleEventEmitter,[]);return te.jsx(X.Provider,{value:c,children:s})}exports.VehicleEventContext=X;exports.VehicleEventProvider=ue;exports.useAnimation=Z;exports.useCreateVehicleEventEmitter=ie;exports.useInitialMovement=oe;exports.useMovementQueue=W;exports.useMovementSequence=ce;exports.useScene=J;exports.useSceneDefinition=ne;exports.useVehicleEvent=ae;exports.useVehicleEventEmitter=ee;exports.useVehicleSimulation=re;exports.useVehicles=B;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./core.cjs"),i=require("./vehicle-helpers-82D2V4MI.cjs"),n=require("./animation-loop-fC2LjxCd.cjs"),t=require("./useVehicleEvents-B1_CZyWq.cjs");exports.arcLengthToSegmentPosition=e.arcLengthToSegmentPosition;exports.buildArcLengthTable=e.buildArcLengthTable;exports.buildGraph=e.buildGraph;exports.calculateBezierArcLength=e.calculateBezierArcLength;exports.calculateFrontAxlePosition=e.calculateFrontAxlePosition;exports.calculateInitialFrontPosition=e.calculateInitialFrontPosition;exports.calculatePositionOnCurve=e.calculatePositionOnCurve;exports.calculatePositionOnLine=e.calculatePositionOnLine;exports.createBezierCurve=e.createBezierCurve;exports.createInitialMovementState=e.createInitialMovementState;exports.distance=e.distance;exports.distanceToT=e.distanceToT;exports.findPath=e.findPath;exports.getArcLength=e.getArcLength;exports.getCumulativeArcLength=e.getCumulativeArcLength;exports.getLineLength=e.getLineLength;exports.getPointOnBezier=e.getPointOnBezier;exports.getPointOnLine=e.getPointOnLine;exports.getPointOnLineByOffset=e.getPointOnLineByOffset;exports.getPositionFromOffset=e.getPositionFromOffset;exports.handleArrival=e.handleArrival;exports.initializeAllVehicles=e.initializeAllVehicles;exports.initializeMovingVehicle=e.initializeMovingVehicle;exports.normalize=e.normalize;exports.prepareCommandPath=e.prepareCommandPath;exports.resolveFromLineOffset=e.resolveFromLineOffset;exports.resolveToLineOffset=e.resolveToLineOffset;exports.updateAxlePosition=e.updateAxlePosition;exports.VehicleEventEmitter=i.VehicleEventEmitter;exports.generateMovementDSL=i.generateMovementDSL;exports.generateSceneDSL=i.generateSceneDSL;exports.generateVehiclesDSL=i.generateVehiclesDSL;exports.getNextGotoVehicleId=i.getNextGotoVehicleId;exports.getNextStartVehicleId=i.getNextStartVehicleId;exports.parseAllDSL=i.parseAllDSL;exports.parseMovementDSL=i.parseMovementDSL;exports.parseSceneDSL=i.parseSceneDSL;exports.parseVehiclesDSL=i.parseVehiclesDSL;exports.validateAndCreateVehicles=i.validateAndCreateVehicles;exports.createAnimationLoop=n.createAnimationLoop;exports.useAnimationLoop=n.useAnimationLoop;exports.VehicleEventContext=t.VehicleEventContext;exports.VehicleEventProvider=t.VehicleEventProvider;exports.useAnimation=t.useAnimation;exports.useCreateVehicleEventEmitter=t.useCreateVehicleEventEmitter;exports.useInitialMovement=t.useInitialMovement;exports.useMovement=t.useMovementQueue;exports.useMovementQueue=t.useMovementQueue;exports.useMovementSequence=t.useMovementSequence;exports.useScene=t.useScene;exports.useSceneDefinition=t.useSceneDefinition;exports.useVehicleEvent=t.useVehicleEvent;exports.useVehicleEventEmitter=t.useVehicleEventEmitter;exports.useVehicleMovement=t.useAnimation;exports.useVehicleSimulation=t.useVehicleSimulation;exports.useVehicles=t.useVehicles;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./core.cjs"),i=require("./vehicle-helpers-82D2V4MI.cjs"),n=require("./animation-loop-fC2LjxCd.cjs"),t=require("./useVehicleEvents-DngnyUej.cjs");exports.arcLengthToSegmentPosition=e.arcLengthToSegmentPosition;exports.buildArcLengthTable=e.buildArcLengthTable;exports.buildGraph=e.buildGraph;exports.calculateBezierArcLength=e.calculateBezierArcLength;exports.calculateFrontAxlePosition=e.calculateFrontAxlePosition;exports.calculateInitialFrontPosition=e.calculateInitialFrontPosition;exports.calculatePositionOnCurve=e.calculatePositionOnCurve;exports.calculatePositionOnLine=e.calculatePositionOnLine;exports.createBezierCurve=e.createBezierCurve;exports.createInitialMovementState=e.createInitialMovementState;exports.distance=e.distance;exports.distanceToT=e.distanceToT;exports.findPath=e.findPath;exports.getArcLength=e.getArcLength;exports.getCumulativeArcLength=e.getCumulativeArcLength;exports.getLineLength=e.getLineLength;exports.getPointOnBezier=e.getPointOnBezier;exports.getPointOnLine=e.getPointOnLine;exports.getPointOnLineByOffset=e.getPointOnLineByOffset;exports.getPositionFromOffset=e.getPositionFromOffset;exports.handleArrival=e.handleArrival;exports.initializeAllVehicles=e.initializeAllVehicles;exports.initializeMovingVehicle=e.initializeMovingVehicle;exports.normalize=e.normalize;exports.prepareCommandPath=e.prepareCommandPath;exports.resolveFromLineOffset=e.resolveFromLineOffset;exports.resolveToLineOffset=e.resolveToLineOffset;exports.updateAxlePosition=e.updateAxlePosition;exports.VehicleEventEmitter=i.VehicleEventEmitter;exports.generateMovementDSL=i.generateMovementDSL;exports.generateSceneDSL=i.generateSceneDSL;exports.generateVehiclesDSL=i.generateVehiclesDSL;exports.getNextGotoVehicleId=i.getNextGotoVehicleId;exports.getNextStartVehicleId=i.getNextStartVehicleId;exports.parseAllDSL=i.parseAllDSL;exports.parseMovementDSL=i.parseMovementDSL;exports.parseSceneDSL=i.parseSceneDSL;exports.parseVehiclesDSL=i.parseVehiclesDSL;exports.validateAndCreateVehicles=i.validateAndCreateVehicles;exports.createAnimationLoop=n.createAnimationLoop;exports.useAnimationLoop=n.useAnimationLoop;exports.VehicleEventContext=t.VehicleEventContext;exports.VehicleEventProvider=t.VehicleEventProvider;exports.useAnimation=t.useAnimation;exports.useCreateVehicleEventEmitter=t.useCreateVehicleEventEmitter;exports.useInitialMovement=t.useInitialMovement;exports.useMovement=t.useMovementQueue;exports.useMovementQueue=t.useMovementQueue;exports.useMovementSequence=t.useMovementSequence;exports.useScene=t.useScene;exports.useSceneDefinition=t.useSceneDefinition;exports.useVehicleEvent=t.useVehicleEvent;exports.useVehicleEventEmitter=t.useVehicleEventEmitter;exports.useVehicleMovement=t.useAnimation;exports.useVehicleSimulation=t.useVehicleSimulation;exports.useVehicles=t.useVehicles;
@@ -1,7 +1,7 @@
1
1
  import { arcLengthToSegmentPosition as i, buildArcLengthTable as a, buildGraph as n, calculateBezierArcLength as s, calculateFrontAxlePosition as o, calculateInitialFrontPosition as l, calculatePositionOnCurve as r, calculatePositionOnLine as c, createBezierCurve as u, createInitialMovementState as h, distance as m, distanceToT as v, findPath as g, getArcLength as L, getCumulativeArcLength as V, getLineLength as d, getPointOnBezier as f, getPointOnLine as S, getPointOnLineByOffset as p, getPositionFromOffset as A, handleArrival as P, initializeAllVehicles as x, initializeMovingVehicle as E, normalize as M, prepareCommandPath as O, resolveFromLineOffset as D, resolveToLineOffset as C, updateAxlePosition as z } from "./core.js";
2
2
  import { V as I, g as T, a as B, b as F, c as G, d as N, p as j, e as k, f as q, h as y, v as Q } from "./vehicle-helpers-BXX3GPzk.js";
3
3
  import { c as H, u as J } from "./animation-loop-bZEm2pMN.js";
4
- import { V as R, a as U, u as W, b as X, c as Y, d as Z, d as _, e as $, f as ee, g as te, h as ie, i as ae, u as ne, j as se, k as oe } from "./useVehicleEvents-Cv-YgfXB.js";
4
+ import { V as R, a as U, u as W, b as X, c as Y, d as Z, d as _, e as $, f as ee, g as te, h as ie, i as ae, u as ne, j as se, k as oe } from "./useVehicleEvents-5-uvxZme.js";
5
5
  export {
6
6
  R as VehicleEventContext,
7
7
  I as VehicleEventEmitter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vehicle-path2",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Vehicle motion simulator library for dual-axle vehicle movement along paths composed of lines and Bezier curves",
5
5
  "type": "module",
6
6
  "main": "./dist/vehicle-path.cjs",