@luxonis/visualizer-protobuf 2.66.9 → 2.66.10

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.
Files changed (35) hide show
  1. package/dist/{index-C41fk9FJ.js → index-BHSCyWTx.js} +22 -22
  2. package/dist/{index-Clq69yV3.js → index-BOSTLpqR.js} +101 -31
  3. package/dist/{index-Ct1D6II_.js → index-BwR3Iw0A.js} +1 -1
  4. package/dist/{index-0xvyd9_r.js → index-C5g4sPQV.js} +1 -1
  5. package/dist/{index-Bb6PcuFb.js → index-CFJCMpe3.js} +1 -1
  6. package/dist/{index-BZBENqR3.js → index-CMk3yuIe.js} +1 -1
  7. package/dist/{index-DuwwCf0Y.js → index-CT4S0Kky.js} +1 -1
  8. package/dist/{index-BWnke17_.js → index-Cux47RKo.js} +1 -1
  9. package/dist/{index-Cyl0afzE.js → index-DKiZ2X4o.js} +1 -1
  10. package/dist/{index-AReJXz0b.js → index-DgB4MyqP.js} +1 -1
  11. package/dist/{index-CyYbEgIe.js → index-DgsLl2EF.js} +1 -1
  12. package/dist/{index-CAKA0YwJ.js → index-DjfMAVx2.js} +2 -2
  13. package/dist/{index-BJslJPfz.js → index-DoUU7hig.js} +1 -1
  14. package/dist/{index-DnFWiYGu.js → index-Dq_6x13l.js} +1 -1
  15. package/dist/{index-DkTZCwWX.js → index-H7DkPNZj.js} +1 -1
  16. package/dist/{index-nO2O7il5.js → index-QTvh2vP4.js} +1 -1
  17. package/dist/{index-JFZDeEB8.js → index-kNDsHDY4.js} +1 -1
  18. package/dist/{index-CRGrBIhH.js → index-v8qHRTgH.js} +1 -1
  19. package/dist/{index-D-mDIWK_.js → index-w7ND8d2T.js} +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/lib/src/messaging/deserialization/pointcloud/pointcloudFromDepth.worker.js +54 -39
  22. package/dist/lib/src/messaging/deserialization/pointcloud/pointcloudFromDepth.worker.js.map +1 -1
  23. package/dist/lib/src/messaging/deserialization/pointcloud/poitcloudPoolManager.d.ts +1 -1
  24. package/dist/lib/src/messaging/deserialization/pointcloud/poitcloudPoolManager.d.ts.map +1 -1
  25. package/dist/lib/src/messaging/deserialization/pointcloud/poitcloudPoolManager.js +1 -1
  26. package/dist/lib/src/messaging/deserialization/pointcloud/poitcloudPoolManager.js.map +1 -1
  27. package/dist/lib/src/messaging/deserialization.worker.js.map +1 -1
  28. package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandler.d.ts +1 -0
  29. package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandler.d.ts.map +1 -1
  30. package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandler.js +95 -28
  31. package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/MessageHandler.js.map +1 -1
  32. package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/annotations/ImageAnnotations.d.ts.map +1 -1
  33. package/dist/packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/annotations/ImageAnnotations.js.map +1 -1
  34. package/dist/{pointcloudFromDepth.worker-hil48rbC.js → pointcloudFromDepth.worker-CoUfUVnZ.js} +55 -40
  35. package/package.json +1 -1
@@ -575,7 +575,7 @@ class DepthToPointcloudWorkerPool {
575
575
  this.#FRAME_BATCH_SIZE = Math.max(1, batchSize);
576
576
  this.#targetDispatchIntervalMs = DISPATCH_INTERVAL_MS / Math.max(1, Math.round(targetFps / DISPATCH_INTERVAL_FRACTION)) * this.#calculateBatchMultiplier();
577
577
  this.#maxProcessedQueueSize = Math.max(1, maxProcessedQueueSize);
578
- this.workerApis = new Array(WORKER_COUNT).fill(undefined).map(() => wrap$3(new Worker(new URL("pointcloudFromDepth.worker-hil48rbC.js", import.meta.url), {
578
+ this.workerApis = new Array(WORKER_COUNT).fill(undefined).map(() => wrap$3(new Worker(new URL("pointcloudFromDepth.worker-CoUfUVnZ.js", import.meta.url), {
579
579
  type: "module"
580
580
  })));
581
581
  this.#metrics = globalInputEventMetricsManager;
@@ -653,7 +653,7 @@ class DepthToPointcloudWorkerPool {
653
653
  // biome-ignore lint/style/noNonNullAssertion: <explanation>
654
654
  const workerApi = this.workerApis[workerIndex];
655
655
  this.lastUsedWorkerIndex = (this.lastUsedWorkerIndex + 1) % WORKER_COUNT;
656
- workerApi.depthToPointcloudGPU(depthDataArray, width, height, fx, fy, cx, cy, i420DataArray, i420Width, i420Height, {
656
+ workerApi.depthToPointcloudGPU(depthDataArray, width, height, fx, fy, cx, cy, i420DataArray, i420Width, i420Height, Number(localStorage.getItem("stereoDepthMaxValue") ?? "5.0"), {
657
657
  hasGPU: this.#isWebGpuSupported
658
658
  }).then(results => {
659
659
  if (results.length === batchToProcess.length) {
@@ -86841,7 +86841,7 @@ function legacy(parser) {
86841
86841
  return new LanguageSupport(StreamLanguage.define(parser));
86842
86842
  }
86843
86843
  function sql$1(dialectName) {
86844
- return import('./index-Cyl0afzE.js').then(m => m.sql({ dialect: m[dialectName] }));
86844
+ return import('./index-DKiZ2X4o.js').then(m => m.sql({ dialect: m[dialectName] }));
86845
86845
  }
86846
86846
  /**
86847
86847
  An array of language descriptions for known language packages.
@@ -86852,7 +86852,7 @@ const languages = [
86852
86852
  name: "C",
86853
86853
  extensions: ["c", "h", "ino"],
86854
86854
  load() {
86855
- return import('./index-DnFWiYGu.js').then(m => m.cpp());
86855
+ return import('./index-Dq_6x13l.js').then(m => m.cpp());
86856
86856
  }
86857
86857
  }),
86858
86858
  /*@__PURE__*/LanguageDescription.of({
@@ -86860,7 +86860,7 @@ const languages = [
86860
86860
  alias: ["cpp"],
86861
86861
  extensions: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"],
86862
86862
  load() {
86863
- return import('./index-DnFWiYGu.js').then(m => m.cpp());
86863
+ return import('./index-Dq_6x13l.js').then(m => m.cpp());
86864
86864
  }
86865
86865
  }),
86866
86866
  /*@__PURE__*/LanguageDescription.of({
@@ -86880,7 +86880,7 @@ const languages = [
86880
86880
  name: "Go",
86881
86881
  extensions: ["go"],
86882
86882
  load() {
86883
- return import('./index-BZBENqR3.js').then(m => m.go());
86883
+ return import('./index-CMk3yuIe.js').then(m => m.go());
86884
86884
  }
86885
86885
  }),
86886
86886
  /*@__PURE__*/LanguageDescription.of({
@@ -86895,7 +86895,7 @@ const languages = [
86895
86895
  name: "Java",
86896
86896
  extensions: ["java"],
86897
86897
  load() {
86898
- return import('./index-0xvyd9_r.js').then(m => m.java());
86898
+ return import('./index-C5g4sPQV.js').then(m => m.java());
86899
86899
  }
86900
86900
  }),
86901
86901
  /*@__PURE__*/LanguageDescription.of({
@@ -86911,7 +86911,7 @@ const languages = [
86911
86911
  alias: ["json5"],
86912
86912
  extensions: ["json", "map"],
86913
86913
  load() {
86914
- return import('./index-AReJXz0b.js').then(m => m.json());
86914
+ return import('./index-DgB4MyqP.js').then(m => m.json());
86915
86915
  }
86916
86916
  }),
86917
86917
  /*@__PURE__*/LanguageDescription.of({
@@ -86925,14 +86925,14 @@ const languages = [
86925
86925
  name: "LESS",
86926
86926
  extensions: ["less"],
86927
86927
  load() {
86928
- return import('./index-BWnke17_.js').then(m => m.less());
86928
+ return import('./index-Cux47RKo.js').then(m => m.less());
86929
86929
  }
86930
86930
  }),
86931
86931
  /*@__PURE__*/LanguageDescription.of({
86932
86932
  name: "Liquid",
86933
86933
  extensions: ["liquid"],
86934
86934
  load() {
86935
- return import('./index-DkTZCwWX.js').then(m => m.liquid());
86935
+ return import('./index-H7DkPNZj.js').then(m => m.liquid());
86936
86936
  }
86937
86937
  }),
86938
86938
  /*@__PURE__*/LanguageDescription.of({
@@ -86958,7 +86958,7 @@ const languages = [
86958
86958
  name: "PHP",
86959
86959
  extensions: ["php", "php3", "php4", "php5", "php7", "phtml"],
86960
86960
  load() {
86961
- return import('./index-BJslJPfz.js').then(m => m.php());
86961
+ return import('./index-DoUU7hig.js').then(m => m.php());
86962
86962
  }
86963
86963
  }),
86964
86964
  /*@__PURE__*/LanguageDescription.of({
@@ -86975,28 +86975,28 @@ const languages = [
86975
86975
  extensions: ["BUILD", "bzl", "py", "pyw"],
86976
86976
  filename: /^(BUCK|BUILD)$/,
86977
86977
  load() {
86978
- return import('./index-Ct1D6II_.js').then(m => m.python());
86978
+ return import('./index-BwR3Iw0A.js').then(m => m.python());
86979
86979
  }
86980
86980
  }),
86981
86981
  /*@__PURE__*/LanguageDescription.of({
86982
86982
  name: "Rust",
86983
86983
  extensions: ["rs"],
86984
86984
  load() {
86985
- return import('./index-CyYbEgIe.js').then(m => m.rust());
86985
+ return import('./index-DgsLl2EF.js').then(m => m.rust());
86986
86986
  }
86987
86987
  }),
86988
86988
  /*@__PURE__*/LanguageDescription.of({
86989
86989
  name: "Sass",
86990
86990
  extensions: ["sass"],
86991
86991
  load() {
86992
- return import('./index-D-mDIWK_.js').then(m => m.sass({ indented: true }));
86992
+ return import('./index-w7ND8d2T.js').then(m => m.sass({ indented: true }));
86993
86993
  }
86994
86994
  }),
86995
86995
  /*@__PURE__*/LanguageDescription.of({
86996
86996
  name: "SCSS",
86997
86997
  extensions: ["scss"],
86998
86998
  load() {
86999
- return import('./index-D-mDIWK_.js').then(m => m.sass());
86999
+ return import('./index-w7ND8d2T.js').then(m => m.sass());
87000
87000
  }
87001
87001
  }),
87002
87002
  /*@__PURE__*/LanguageDescription.of({
@@ -87027,7 +87027,7 @@ const languages = [
87027
87027
  name: "WebAssembly",
87028
87028
  extensions: ["wat", "wast"],
87029
87029
  load() {
87030
- return import('./index-DuwwCf0Y.js').then(m => m.wast());
87030
+ return import('./index-CT4S0Kky.js').then(m => m.wast());
87031
87031
  }
87032
87032
  }),
87033
87033
  /*@__PURE__*/LanguageDescription.of({
@@ -87035,7 +87035,7 @@ const languages = [
87035
87035
  alias: ["rss", "wsdl", "xsd"],
87036
87036
  extensions: ["xml", "xsl", "xsd", "svg"],
87037
87037
  load() {
87038
- return import('./index-nO2O7il5.js').then(m => m.xml());
87038
+ return import('./index-QTvh2vP4.js').then(m => m.xml());
87039
87039
  }
87040
87040
  }),
87041
87041
  /*@__PURE__*/LanguageDescription.of({
@@ -87043,7 +87043,7 @@ const languages = [
87043
87043
  alias: ["yml"],
87044
87044
  extensions: ["yaml", "yml"],
87045
87045
  load() {
87046
- return import('./index-Bb6PcuFb.js').then(m => m.yaml());
87046
+ return import('./index-CFJCMpe3.js').then(m => m.yaml());
87047
87047
  }
87048
87048
  }),
87049
87049
  // Legacy modes ported from CodeMirror 5
@@ -87839,13 +87839,13 @@ const languages = [
87839
87839
  name: "Vue",
87840
87840
  extensions: ["vue"],
87841
87841
  load() {
87842
- return import('./index-JFZDeEB8.js').then(m => m.vue());
87842
+ return import('./index-kNDsHDY4.js').then(m => m.vue());
87843
87843
  }
87844
87844
  }),
87845
87845
  /*@__PURE__*/LanguageDescription.of({
87846
87846
  name: "Angular Template",
87847
87847
  load() {
87848
- return import('./index-CRGrBIhH.js').then(m => m.angular());
87848
+ return import('./index-v8qHRTgH.js').then(m => m.angular());
87849
87849
  }
87850
87850
  })
87851
87851
  ];
@@ -166554,7 +166554,7 @@ function createRenderDelaySampler() {
166554
166554
  };
166555
166555
  }
166556
166556
 
166557
- const ImagePanelComponent = /*#__PURE__*/React__default.lazy(async () => await import('./index-CAKA0YwJ.js'));
166557
+ const ImagePanelComponent = /*#__PURE__*/React__default.lazy(async () => await import('./index-DjfMAVx2.js'));
166558
166558
  const ImagePanelBody = ({
166559
166559
  topic,
166560
166560
  frameRenderedEvent,
@@ -166649,7 +166649,7 @@ const DEFAULT_CAMERA_STATE = {
166649
166649
  // License, v2.0. If a copy of the MPL was not distributed with this
166650
166650
  // file, You can obtain one at http://mozilla.org/MPL/2.0/
166651
166651
 
166652
- const ThreeDeeRenderComponent = /*#__PURE__*/React__default.lazy(async () => await import('./index-Clq69yV3.js'));
166652
+ const ThreeDeeRenderComponent = /*#__PURE__*/React__default.lazy(async () => await import('./index-BOSTLpqR.js'));
166653
166653
  const PointCloudPanelBody = ({
166654
166654
  topic,
166655
166655
  frameRenderedEvent,
@@ -3,7 +3,7 @@ import React__default, { useReducer, useRef, useCallback, useLayoutEffect, Compo
3
3
  import ReactDOM__default from 'react-dom';
4
4
  import { Y as isSymbol, Z as toString, $ as keys, a0 as getSymbols$1, a1 as stubArray, a2 as arrayPush, a3 as baseGetAllKeys, g as getTag, a4 as getAllKeys, k as baseGet, c as baseIteratee, j as castPath, t as toKey, a5 as arrayMap$1, a6 as baseUniq, b as baseFlatten, a7 as useMustNotChange, a8 as useCurrentLayoutActions, a9 as useCurrentLayoutSelector, r as reportError, A as AppError, L as Logger, u as useGuaranteedContext, aa as usePanelMosaicId, ab as useSelectedPanels, ac as PANEL_TITLE_CONFIG_KEY, ad as noop$4, o as getPanelTypeFromId, M as useShallowMemo, T as TAB_PANEL_TYPE, J as filterMap, d as dist$2, ae as useAppConfiguration, af as useValueChangedDebugLog, ag as useJsonTreeTheme } from './depth-BGin0LSZ.js';
5
5
  import { createStore, useStore } from 'zustand';
6
- import { g as generateUtilityClass, c as createAggregator, f as flatRest, b as baseSet, A as AnalyticsContext, P as PropTypes, E as ErrorDisplay, S as Stack$1, m as makeStyles$1, _ as _extends$1, W as WorkspaceContext, u as useAnalytics, a as AppEvent, L as LeftSidebarItemKeys, R as RightSidebarItemKeys, d as useTranslation, e as usePanelCatalog, h as EmptyState, i as isEmpty, j as PanelContext, k as PanelCatalogContext, l as usePanelStateStore, n as useDefaultPanelTitle, o as useWorkspaceStore, p as WorkspaceStoreSelectors, q as difference, r as usePanelContext, s as useMessagePipeline, v as v4, t as useHoverValue, w as useSetHoverValue, x as useClearHoverValue, y as useMessagePipelineGetter, z as usePanelSettingsTreeUpdate, B as PlayerCapabilities, C as assertNever, D as PlayerPresence, F as isEqual, G as isDesktopApp, H as createTheme, I as propTypesExports, J as DEFAULT_CAMERA_STATE$1, K as format$1, M as z, N as serializeError, O as stringify$1, Q as createIntl, T as createIntlCache } from './index-C41fk9FJ.js';
6
+ import { g as generateUtilityClass, c as createAggregator, f as flatRest, b as baseSet, A as AnalyticsContext, P as PropTypes, E as ErrorDisplay, S as Stack$1, m as makeStyles$1, _ as _extends$1, W as WorkspaceContext, u as useAnalytics, a as AppEvent, L as LeftSidebarItemKeys, R as RightSidebarItemKeys, d as useTranslation, e as usePanelCatalog, h as EmptyState, i as isEmpty, j as PanelContext, k as PanelCatalogContext, l as usePanelStateStore, n as useDefaultPanelTitle, o as useWorkspaceStore, p as WorkspaceStoreSelectors, q as difference, r as usePanelContext, s as useMessagePipeline, v as v4, t as useHoverValue, w as useSetHoverValue, x as useClearHoverValue, y as useMessagePipelineGetter, z as usePanelSettingsTreeUpdate, B as PlayerCapabilities, C as assertNever, D as PlayerPresence, F as isEqual, G as isDesktopApp, H as createTheme, I as propTypesExports, J as DEFAULT_CAMERA_STATE$1, K as format$1, M as z, N as serializeError, O as stringify$1, Q as createIntl, T as createIntlCache } from './index-BHSCyWTx.js';
7
7
  import { MosaicDragType, MosaicContext, MosaicWindowContext, getOtherBranch, getNodeAtPath } from 'react-mosaic-component';
8
8
  import { g as getDefaultExportFromCjs, c as commonjsGlobal, d as getAugmentedNamespace } from './protobuf-BFCtaU7c.js';
9
9
  import { Link, Button, alpha, IconButton, Card, CardActionArea, CardMedia, CardContent, Typography, Container, Tooltip, Fade, ListItem, ListItemButton, ListItemText, List, TextField, InputAdornment, Popper, Grow, Paper, ClickAwayListener, Menu, MenuItem, Divider, buttonClasses, Backdrop, Chip, useTheme, alertClasses, darken, lighten, inputBaseClasses, autocompleteClasses, inputClasses, Checkbox, dialogActionsClasses, filledInputClasses, inputAdornmentClasses, listSubheaderClasses, selectClasses, tableCellClasses, ThemeProvider as ThemeProvider$1, SvgIcon, tabsClasses as tabsClasses$1, tabClasses, Tabs, Tab, ListItemIcon } from '@mui/material';
@@ -32507,6 +32507,9 @@ function getAnnotationAtPath(message, path) {
32507
32507
  const syncToleranceSec = 0.15; // maximum acceptable time difference for selecting a “closest” annotation.
32508
32508
  const maxStalenessSec = 1.1; // how long we can hold the last older annotation if no better match is available. 1s corresponds to 1 FPS + 100ms window for jitter.
32509
32509
  const hysteresisSec = 0.1; // how much “stickiness” we allow before switching candidates.
32510
+ // New: how long (seconds) of recent images we keep around to allow picking an older image that better matches annotations
32511
+ const imageRetentionSec = 5; // keep small window of recent images
32512
+ const maxImageBuffer = 120; // cap number of stored images (e.g. 24 FPS * 5s)
32510
32513
 
32511
32514
  // Have constants for the HUD items so that they don't need to be recreated and GCed every message
32512
32515
  const WAITING_FOR_BOTH_HUD_ITEM = {
@@ -32564,6 +32567,8 @@ class MessageHandler {
32564
32567
 
32565
32568
  #onAnnotationReceivedEvent;
32566
32569
  #annotationsFpsRefreshInterval = null;
32570
+ // New: keep a buffer of recent images for annotation-prioritized synchronization
32571
+ imagesBuffer = [];
32567
32572
  // Store a small buffer of recent annotations per topic with computed seconds timestamps
32568
32573
  annotationsMap = new Map();
32569
32574
  // Track last selected annotation per topic to add hysteresis and reduce flicker
@@ -32612,6 +32617,35 @@ class MessageHandler {
32612
32617
  ...message,
32613
32618
  message: image
32614
32619
  };
32620
+
32621
+ // Compute timestamp seconds for buffer storage (prefer image stamp, then receiveTime, then wall clock)
32622
+ const stamp = getTimestampFromImage(image);
32623
+ let timeSec;
32624
+ const stampSec = stamp?.sec;
32625
+ const stampNsec = stamp?.nsec;
32626
+ if (typeof stampSec === "number" && typeof stampNsec === "number") {
32627
+ timeSec = stampSec + stampNsec / 1e9;
32628
+ } else {
32629
+ const recv = message.receiveTime;
32630
+ const recvSec = recv?.sec;
32631
+ const recvNsec = recv?.nsec;
32632
+ if (typeof recvSec === "number" && typeof recvNsec === "number") {
32633
+ timeSec = recvSec + recvNsec / 1e9;
32634
+ } else {
32635
+ timeSec = performance.now() / 1000;
32636
+ }
32637
+ }
32638
+ this.imagesBuffer.push({
32639
+ image: this.lastImage,
32640
+ timeSec
32641
+ });
32642
+ // Trim by time and length
32643
+ const nowSec = performance.now() / 1000;
32644
+ const cutoff = nowSec - imageRetentionSec;
32645
+ this.imagesBuffer = this.imagesBuffer.filter(e => e.timeSec >= cutoff);
32646
+ if (this.imagesBuffer.length > maxImageBuffer) {
32647
+ this.imagesBuffer.splice(0, this.imagesBuffer.length - maxImageBuffer);
32648
+ }
32615
32649
  this.#emitState();
32616
32650
  }
32617
32651
  handleCameraInfo = message => {
@@ -32706,6 +32740,7 @@ class MessageHandler {
32706
32740
  this.annotationsMap.clear();
32707
32741
  this.lastSelectedByTopic.clear();
32708
32742
  this.lastImage = undefined;
32743
+ this.imagesBuffer = [];
32709
32744
  this.#oldRenderState = undefined;
32710
32745
  this.#emitState();
32711
32746
  }
@@ -32734,30 +32769,45 @@ class MessageHandler {
32734
32769
  this.#hud.displayIfTrue(waitingForImage && calibrationRequired, WAITING_FOR_IMAGE_NOTICE_HUD_ITEM);
32735
32770
  }
32736
32771
  #getRenderState() {
32737
- if (!this.lastImage) {
32772
+ if (this.imagesBuffer.length === 0) {
32738
32773
  return {
32739
32774
  annotationsByTopic: new Map(),
32740
32775
  presentAnnotationTopics: undefined,
32741
32776
  missingAnnotationTopics: undefined
32742
32777
  };
32743
32778
  }
32744
- const state = {
32745
- image: this.lastImage,
32746
- annotationsByTopic: new Map()
32747
- };
32748
- const imageTimestampSec = (() => {
32749
- const stamp = getTimestampFromImage(this.lastImage.message);
32750
- const sec = stamp?.sec;
32751
- const nsec = stamp?.nsec;
32752
- if (typeof sec === "number" && typeof nsec === "number") {
32753
- return sec + nsec / 1e9;
32754
- }
32755
- return performance.now() / 1000;
32756
- })();
32757
- for (const [topic, buffer] of this.annotationsMap.entries()) {
32758
- if (buffer.length === 0) continue;
32759
-
32760
- // Prefer newest annotation older than the image within staleness window
32779
+
32780
+ // Visible topics
32781
+ const visibleTopics = new Set();
32782
+ if (this.#config.annotations) {
32783
+ for (const [topic, settings] of Object.entries(this.#config.annotations)) {
32784
+ if (settings?.visible) visibleTopics.add(topic);
32785
+ }
32786
+ }
32787
+
32788
+ // Required topics (available & visible)
32789
+ const requiredTopics = [];
32790
+ for (const t of visibleTopics) {
32791
+ if (this.availableAnnotationTopics.size === 0 || this.availableAnnotationTopics.has(t)) {
32792
+ requiredTopics.push(t);
32793
+ }
32794
+ }
32795
+
32796
+ // New policy: always start from newest image (do not freeze on older frame).
32797
+ const newestImageEntry = this.imagesBuffer[this.imagesBuffer.length - 1];
32798
+ const imageTimestampSec = newestImageEntry.timeSec;
32799
+ const selectedAnnotations = new Map();
32800
+ const presentTopics = [];
32801
+ const missingTopics = [];
32802
+ for (const topic of visibleTopics) {
32803
+ const buffer = this.annotationsMap.get(topic);
32804
+ if (!buffer || buffer.length === 0) {
32805
+ // No annotations yet for this topic
32806
+ if (requiredTopics.includes(topic)) ;
32807
+ continue;
32808
+ }
32809
+
32810
+ // Find preferred (newest <= image time within staleness)
32761
32811
  let preferred;
32762
32812
  for (let i = buffer.length - 1; i >= 0; i--) {
32763
32813
  const entry = buffer[i];
@@ -32768,28 +32818,28 @@ class MessageHandler {
32768
32818
  }
32769
32819
  }
32770
32820
 
32771
- // If none older within staleness, fall back to closest within tolerance
32772
- let fallback = buffer[0];
32773
- let fallbackDelta = Math.abs(fallback.timeSec - imageTimestampSec);
32821
+ // Fallback: closest within tolerance window
32822
+ let closest = buffer[0];
32823
+ let closestDelta = Math.abs(closest.timeSec - imageTimestampSec);
32774
32824
  for (let i = 1; i < buffer.length; i++) {
32775
32825
  const entry = buffer[i];
32776
32826
  const delta = Math.abs(entry.timeSec - imageTimestampSec);
32777
- if (delta < fallbackDelta) {
32778
- fallback = entry;
32779
- fallbackDelta = delta;
32827
+ if (delta < closestDelta) {
32828
+ closest = entry;
32829
+ closestDelta = delta;
32780
32830
  }
32781
32831
  }
32782
- let candidate = preferred ?? fallback;
32832
+ let candidate = preferred ?? closest;
32783
32833
  if (!candidate) continue;
32784
32834
  const candidateDelta = Math.abs(candidate.timeSec - imageTimestampSec);
32785
32835
  const candidateAge = imageTimestampSec - candidate.timeSec;
32786
- const acceptable = preferred != undefined && candidateAge >= 0 && candidateAge <= maxStalenessSec || preferred == undefined && candidateDelta <= syncToleranceSec;
32836
+ const acceptable = preferred && candidateAge >= 0 && candidateAge <= maxStalenessSec || !preferred && candidateDelta <= syncToleranceSec;
32787
32837
  const notFutureFar = candidate.timeSec <= imageTimestampSec + syncToleranceSec;
32788
32838
  if (!acceptable || !notFutureFar) {
32839
+ // can't use for now
32789
32840
  continue;
32790
32841
  }
32791
-
32792
- // Hysteresis: if previous selection is very close and still valid, keep it to avoid flicker
32842
+ // Hysteresis: keep previous if close
32793
32843
  const prevTime = this.lastSelectedByTopic.get(topic);
32794
32844
  if (prevTime != undefined) {
32795
32845
  const prevEntry = buffer.find(e => Math.abs(e.timeSec - prevTime) < 1e-6);
@@ -32802,10 +32852,30 @@ class MessageHandler {
32802
32852
  }
32803
32853
  }
32804
32854
  }
32805
- state.annotationsByTopic.set(topic, candidate.annotation);
32855
+ selectedAnnotations.set(topic, candidate.annotation);
32856
+ presentTopics.push(topic);
32806
32857
  this.lastSelectedByTopic.set(topic, candidate.timeSec);
32807
32858
  }
32808
- return state;
32859
+
32860
+ // Determine missing topics (we have at least some annotation messages for them but could not align one this frame)
32861
+ for (const t of requiredTopics) {
32862
+ if (!presentTopics.includes(t)) {
32863
+ const buf = this.annotationsMap.get(t);
32864
+ if (buf && buf.length > 0) {
32865
+ // We received data but could not synchronize within tolerance -> mark missing
32866
+ missingTopics.push(t);
32867
+ }
32868
+ }
32869
+ }
32870
+
32871
+ // Always return newest image; do not block rendering if annotations incomplete
32872
+ return {
32873
+ image: newestImageEntry.image,
32874
+ annotationsByTopic: selectedAnnotations,
32875
+ // Provide mismatch info only if we have both present and missing; otherwise undefined to reduce HUD noise
32876
+ presentAnnotationTopics: presentTopics.length > 0 && missingTopics.length > 0 ? presentTopics.sort() : undefined,
32877
+ missingAnnotationTopics: presentTopics.length > 0 && missingTopics.length > 0 ? missingTopics.sort() : undefined
32878
+ };
32809
32879
  }
32810
32880
  }
32811
32881
 
@@ -1,4 +1,4 @@
1
- import { a1 as ExternalTokenizer, a9 as ContextTracker, Y as styleTags, Z as tags, a2 as LRParser, a5 as syntaxTree, a3 as ifNotIn, $ as LRLanguage, U as indentNodeProp, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport, ac as IterMode, a4 as completeFromList, ad as NodeWeakMap, ab as snippetCompletion } from './index-C41fk9FJ.js';
1
+ import { a1 as ExternalTokenizer, a9 as ContextTracker, Y as styleTags, Z as tags, a2 as LRParser, a5 as syntaxTree, a3 as ifNotIn, $ as LRLanguage, U as indentNodeProp, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport, ac as IterMode, a4 as completeFromList, ad as NodeWeakMap, ab as snippetCompletion } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, a6 as flatIndent, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport } from './index-C41fk9FJ.js';
1
+ import { Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, a6 as flatIndent, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { a9 as ContextTracker, a1 as ExternalTokenizer, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport, ai as parseMixed } from './index-C41fk9FJ.js';
1
+ import { a9 as ContextTracker, a1 as ExternalTokenizer, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport, ai as parseMixed } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { a1 as ExternalTokenizer, a9 as ContextTracker, Y as styleTags, Z as tags, a2 as LRParser, aa as LocalTokenGroup, ab as snippetCompletion, a5 as syntaxTree, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, a6 as flatIndent, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport, a3 as ifNotIn, a4 as completeFromList, ac as IterMode, ad as NodeWeakMap } from './index-C41fk9FJ.js';
1
+ import { a1 as ExternalTokenizer, a9 as ContextTracker, Y as styleTags, Z as tags, a2 as LRParser, aa as LocalTokenGroup, ab as snippetCompletion, a5 as syntaxTree, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, a6 as flatIndent, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport, a3 as ifNotIn, a4 as completeFromList, ac as IterMode, ad as NodeWeakMap } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { $ as LRLanguage, U as indentNodeProp, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, Y as styleTags, Z as tags, a0 as LanguageSupport, a2 as LRParser } from './index-C41fk9FJ.js';
1
+ import { $ as LRLanguage, U as indentNodeProp, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, Y as styleTags, Z as tags, a0 as LanguageSupport, a2 as LRParser } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { Y as styleTags, Z as tags, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, X as foldNodeProp, a8 as foldInside, ae as defineCSSCompletionSource, a0 as LanguageSupport, a2 as LRParser, a1 as ExternalTokenizer } from './index-C41fk9FJ.js';
1
+ import { Y as styleTags, Z as tags, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, X as foldNodeProp, a8 as foldInside, ae as defineCSSCompletionSource, a0 as LanguageSupport, a2 as LRParser, a1 as ExternalTokenizer } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { U as indentNodeProp, V as continuedIndent, X as foldNodeProp, Y as styleTags, Z as tags, $ as LRLanguage, a0 as LanguageSupport, a1 as ExternalTokenizer, a2 as LRParser, a3 as ifNotIn, a4 as completeFromList, a5 as syntaxTree } from './index-C41fk9FJ.js';
1
+ import { U as indentNodeProp, V as continuedIndent, X as foldNodeProp, Y as styleTags, Z as tags, $ as LRLanguage, a0 as LanguageSupport, a1 as ExternalTokenizer, a2 as LRParser, a3 as ifNotIn, a4 as completeFromList, a5 as syntaxTree } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport } from './index-C41fk9FJ.js';
1
+ import { Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { a1 as ExternalTokenizer, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport } from './index-C41fk9FJ.js';
1
+ import { a1 as ExternalTokenizer, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { ImagePanel } from './index-Clq69yV3.js';
1
+ import { ImagePanel } from './index-BOSTLpqR.js';
2
2
  import 'react';
3
3
  import 'react-dom';
4
4
  import './depth-BGin0LSZ.js';
@@ -9,7 +9,7 @@ import './protobuf-BFCtaU7c.js';
9
9
  import 'protobufjs/minimal';
10
10
  import '@mui/material';
11
11
  import './isArrayLikeObject-Bytw9p-q.js';
12
- import './index-C41fk9FJ.js';
12
+ import './index-BHSCyWTx.js';
13
13
  import './utils-Hzt3wxhG.js';
14
14
  import './FoxgloveServer-h5m-pXp3.js';
15
15
  import 'ms';
@@ -1,4 +1,4 @@
1
- import { a1 as ExternalTokenizer, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, ah as html, a0 as LanguageSupport, ai as parseMixed } from './index-C41fk9FJ.js';
1
+ import { a1 as ExternalTokenizer, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, ah as html, a0 as LanguageSupport, ai as parseMixed } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { a1 as ExternalTokenizer, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, a6 as flatIndent, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport } from './index-C41fk9FJ.js';
1
+ import { a1 as ExternalTokenizer, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, V as continuedIndent, a6 as flatIndent, a7 as delimitedIndent, X as foldNodeProp, a8 as foldInside, a0 as LanguageSupport } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { af as EditorView, ag as EditorSelection, $ as LRLanguage, Y as styleTags, Z as tags, U as indentNodeProp, a7 as delimitedIndent, X as foldNodeProp, a0 as LanguageSupport, a2 as LRParser, a5 as syntaxTree, ah as html, ai as parseMixed, a1 as ExternalTokenizer } from './index-C41fk9FJ.js';
1
+ import { af as EditorView, ag as EditorSelection, $ as LRLanguage, Y as styleTags, Z as tags, U as indentNodeProp, a7 as delimitedIndent, X as foldNodeProp, a0 as LanguageSupport, a2 as LRParser, a5 as syntaxTree, ah as html, ai as parseMixed, a1 as ExternalTokenizer } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { a9 as ContextTracker, a1 as ExternalTokenizer, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, X as foldNodeProp, aj as bracketMatchingHandle, a0 as LanguageSupport, af as EditorView, a5 as syntaxTree, ag as EditorSelection } from './index-C41fk9FJ.js';
1
+ import { a9 as ContextTracker, a1 as ExternalTokenizer, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, U as indentNodeProp, X as foldNodeProp, aj as bracketMatchingHandle, a0 as LanguageSupport, af as EditorView, a5 as syntaxTree, ag as EditorSelection } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { Y as styleTags, Z as tags, $ as LRLanguage, a0 as LanguageSupport, a2 as LRParser, aa as LocalTokenGroup, ah as html, ai as parseMixed, ak as javascriptLanguage } from './index-C41fk9FJ.js';
1
+ import { Y as styleTags, Z as tags, $ as LRLanguage, a0 as LanguageSupport, a2 as LRParser, aa as LocalTokenGroup, ah as html, ai as parseMixed, ak as javascriptLanguage } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { Y as styleTags, Z as tags, ak as javascriptLanguage, $ as LRLanguage, a0 as LanguageSupport, a2 as LRParser, ah as html, ai as parseMixed, a1 as ExternalTokenizer } from './index-C41fk9FJ.js';
1
+ import { Y as styleTags, Z as tags, ak as javascriptLanguage, $ as LRLanguage, a0 as LanguageSupport, a2 as LRParser, ah as html, ai as parseMixed, a1 as ExternalTokenizer } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
@@ -1,4 +1,4 @@
1
- import { a1 as ExternalTokenizer, a9 as ContextTracker, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, X as foldNodeProp, a8 as foldInside, U as indentNodeProp, V as continuedIndent, ae as defineCSSCompletionSource, a0 as LanguageSupport } from './index-C41fk9FJ.js';
1
+ import { a1 as ExternalTokenizer, a9 as ContextTracker, Y as styleTags, Z as tags, a2 as LRParser, $ as LRLanguage, X as foldNodeProp, a8 as foldInside, U as indentNodeProp, V as continuedIndent, ae as defineCSSCompletionSource, a0 as LanguageSupport } from './index-BHSCyWTx.js';
2
2
  import './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import 'react';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { av as FrameStore, ao as ImagePanel, an as PanelLayout, ap as PointCloudPanel, al as VisualizerConnection, am as VisualizerContext, aq as constructKeyForTopicRenderMetrics, aw as getIMUEventEmitter, as as globalDecodeMetricsManager, ar as globalInputEventMetricsManager, at as globalRenderMetricsManager, au as globalThroughputMetricsManager } from './index-C41fk9FJ.js';
1
+ export { av as FrameStore, ao as ImagePanel, an as PanelLayout, ap as PointCloudPanel, al as VisualizerConnection, am as VisualizerContext, aq as constructKeyForTopicRenderMetrics, aw as getIMUEventEmitter, as as globalDecodeMetricsManager, ar as globalInputEventMetricsManager, at as globalRenderMetricsManager, au as globalThroughputMetricsManager } from './index-BHSCyWTx.js';
2
2
  export { S as getDistanceFromDepthDataForOffset } from './depth-BGin0LSZ.js';
3
3
  import './comlink-DHMAu6X7.js';
4
4
  import './utils-Hzt3wxhG.js';