@vitessce/all 4.0.1 → 4.0.2

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.
@@ -3,7 +3,7 @@ import { useRef, useEffect, useState } from "react";
3
3
  import { useThree, useFrame } from "@react-three/fiber";
4
4
  import { Bvh } from "@react-three/drei";
5
5
  import { Matrix4, Vector3, Box3, FrontSide } from "three";
6
- import { g as getXRModule, i as isValidGeometrySize, M as MeasureLine, s as stringifyLineData } from "./index-0nuepTVk.js";
6
+ import { g as getXRModule, i as isValidGeometrySize, M as MeasureLine, s as stringifyLineData } from "./index-CwGBUQIk.js";
7
7
  const { useXR, useXRInputSourceState } = getXRModule();
8
8
  function getHandJoint(hand, jointName) {
9
9
  return hand.get(jointName);
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import React__default from "react";
3
- import { a as getDefaultExportFromCjs, d as requireAssign, f as require_export, h as require_core, j as require_fails, k as require_toObject, m as require_objectKeys, n as require_cof, o as require_wks, p as require_iterators, q as requireWeb_dom_iterable, s as requireEs6_string_iterator, t as require_anObject, v as require_hide, w as require_ctx, x as require_toLength, y as require_global, z as require_objectDp, A as require_descriptors, D as require_isObject, E as require_objectCreate, F as require_iterDefine, G as require_iterStep, H as require_meta, I as require_isArray, J as require_iobject, K as require_setToStringTag, M as require_aFunction, N as requireIterator, O as require_propertyDesc, c as commonjsGlobal, P as requireEs6_symbol, Q as requireDefineProperty, R as require_toIobject, S as require_objectGopd, T as require_html, U as require_domCreate, V as require_library, W as requireSymbol, X as require_objectPie, Y as require_has, Z as require_redefine, _ as require_objectAssign, $ as diffCameraState } from "./index-moreUHDf.js";
3
+ import { a as getDefaultExportFromCjs, d as requireAssign, f as require_export, h as require_core, j as require_fails, k as require_toObject, m as require_objectKeys, n as require_cof, o as require_wks, p as require_iterators, q as requireWeb_dom_iterable, s as requireEs6_string_iterator, t as require_anObject, v as require_hide, w as require_ctx, x as require_toLength, y as require_global, z as require_objectDp, A as require_descriptors, D as require_isObject, E as require_objectCreate, F as require_iterDefine, G as require_iterStep, H as require_meta, I as require_isArray, J as require_iobject, K as require_setToStringTag, M as require_aFunction, N as requireIterator, O as require_propertyDesc, c as commonjsGlobal, P as requireEs6_symbol, Q as requireDefineProperty, R as require_toIobject, S as require_objectGopd, T as require_html, U as require_domCreate, V as require_library, W as requireSymbol, X as require_objectPie, Y as require_has, Z as require_redefine, _ as require_objectAssign, $ as GREY_HEX, a0 as diffCameraState } from "./index-B8FH88N6.js";
4
4
  var assignExports = requireAssign();
5
5
  const _Object$assign = /* @__PURE__ */ getDefaultExportFromCjs(assignExports);
6
6
  var es6_object_keys = {};
@@ -65179,7 +65179,6 @@ function setupDefaultViewer(options) {
65179
65179
  disableContextMenu(options.target);
65180
65180
  return viewer;
65181
65181
  }
65182
- const GREY_HEX = "#323232";
65183
65182
  const viewersKeyed = {};
65184
65183
  let viewerNoKey;
65185
65184
  function parseUrlHash(url) {
@@ -65499,21 +65498,50 @@ class Neuroglancer extends React__default.Component {
65499
65498
  const stripColors = (layers) => (layers || []).map((l) => {
65500
65499
  if (!l)
65501
65500
  return l;
65502
- const { segmentColors, ...rest } = l;
65501
+ const { segmentColors, visible, shader, objectAlpha, segments, ...rest } = l;
65503
65502
  return rest;
65504
65503
  });
65505
65504
  const prevLayers = stripColors(prevVS?.layers);
65506
65505
  const nextLayers = stripColors(nextVS?.layers);
65507
65506
  return JSON.stringify(prevLayers) !== JSON.stringify(nextLayers);
65508
65507
  };
65508
+ // Helper to preserve dimensions across restoreState calls to prevent
65509
+ // NG from permanently switching to the data source's native coordinate space.
65510
+ preserveDimensions = (restoreFn) => {
65511
+ const currentDimensions = this.viewer.state.toJSON().dimensions;
65512
+ restoreFn();
65513
+ if (currentDimensions) {
65514
+ this.viewer.state.restoreState({ dimensions: currentDimensions });
65515
+ }
65516
+ };
65517
+ // Convert hex color string to NG's BGR integer format
65518
+ hexToNgColor = (hex) => {
65519
+ if (!hex || hex.length < 7)
65520
+ return 0;
65521
+ const r = parseInt(hex.slice(1, 3), 16);
65522
+ const g = parseInt(hex.slice(3, 5), 16);
65523
+ const b = parseInt(hex.slice(5, 7), 16);
65524
+ return b * 65536 + g * 256 + r;
65525
+ };
65509
65526
  /* To add colors to the segments, turning unselected to grey */
65510
65527
  applyColorsAndVisibility = (cellColorMappingByLayer) => {
65511
65528
  if (!this.viewer)
65512
65529
  return;
65513
65530
  const baseLayers = this.props.viewerState?.layers ?? (this.viewer.state.toJSON().layers || []);
65531
+ let defaultColor;
65514
65532
  const newLayers = baseLayers.map((layer) => {
65515
65533
  const layerScope = Object.keys(cellColorMappingByLayer).find((scope) => layer.name?.includes(scope));
65516
65534
  const selected = { ...cellColorMappingByLayer[layerScope]?.colors || {} };
65535
+ defaultColor = cellColorMappingByLayer[layerScope]?.defaultColor ?? GREY_HEX;
65536
+ const currentSegments = layer.segments ?? [];
65537
+ if (currentSegments.length > 0) {
65538
+ const segmentSet = new Set(currentSegments.map(String));
65539
+ const fullSegmentColors2 = {};
65540
+ for (const id of segmentSet) {
65541
+ fullSegmentColors2[id] = selected[id] || defaultColor;
65542
+ }
65543
+ return { ...layer, segmentColors: fullSegmentColors2 };
65544
+ }
65517
65545
  if (!this.allKnownIdsByLayer)
65518
65546
  this.allKnownIdsByLayer = {};
65519
65547
  if (!this.allKnownIdsByLayer[layerScope]) {
@@ -65523,17 +65551,47 @@ class Neuroglancer extends React__default.Component {
65523
65551
  this.allKnownIdsByLayer[layerScope].add(id);
65524
65552
  }
65525
65553
  const fullSegmentColors = {};
65526
- for (const id of this.allKnownIdsByLayer[layerScope] || []) {
65527
- fullSegmentColors[id] = selected[id] || GREY_HEX;
65554
+ for (const id of this.allKnownIdsByLayer[layerScope]) {
65555
+ fullSegmentColors[id] = selected[id] || defaultColor;
65528
65556
  }
65529
- if (layer.type === "segmentation") {
65530
- return { ...layer, segmentColors: fullSegmentColors };
65531
- }
65532
- return layer;
65533
- });
65534
- this.withoutEmitting(() => {
65535
- this.viewer.state.restoreState({ layers: newLayers });
65557
+ return { ...layer, segmentColors: fullSegmentColors };
65536
65558
  });
65559
+ let usedDirectUpdate = false;
65560
+ for (const managedLayer of this.viewer.layerManager.managedLayers) {
65561
+ if (!(managedLayer.layer instanceof SegmentationUserLayer))
65562
+ continue;
65563
+ const matchingNewLayer = newLayers.find((l) => l.name === managedLayer.name);
65564
+ if (!matchingNewLayer?.segmentColors)
65565
+ continue;
65566
+ const segGroupState = managedLayer.layer.displayState.segmentationColorGroupState?.value;
65567
+ const statedColors = segGroupState?.segmentStatedColors;
65568
+ if (!statedColors)
65569
+ continue;
65570
+ const currentJson = statedColors.toJSON();
65571
+ const newColors = matchingNewLayer.segmentColors;
65572
+ for (const id of Object.keys(currentJson)) {
65573
+ if (!newColors[id]) {
65574
+ const colorInt = this.hexToNgColor(defaultColor || GREY_HEX);
65575
+ statedColors.delete_({ low: Number(id), high: 0 });
65576
+ statedColors.set_({ low: Number(id), high: 0 }, { low: colorInt, high: 0 });
65577
+ }
65578
+ }
65579
+ for (const [id, hex] of Object.entries(newColors)) {
65580
+ const colorInt = this.hexToNgColor(hex);
65581
+ statedColors.delete_({ low: Number(id), high: 0 });
65582
+ statedColors.set_({ low: Number(id), high: 0 }, { low: colorInt, high: 0 });
65583
+ }
65584
+ statedColors.changed.dispatch();
65585
+ usedDirectUpdate = true;
65586
+ }
65587
+ if (!usedDirectUpdate) {
65588
+ this.withoutEmitting(() => {
65589
+ this.preserveDimensions(() => {
65590
+ this.viewer.state.restoreState({ layers: newLayers });
65591
+ });
65592
+ });
65593
+ }
65594
+ this.viewer.display.scheduleRedraw();
65537
65595
  };
65538
65596
  componentDidMount() {
65539
65597
  const {
@@ -65575,32 +65633,83 @@ class Neuroglancer extends React__default.Component {
65575
65633
  }
65576
65634
  const { visibleChunksChanged } = this.viewer.chunkQueueManager;
65577
65635
  let firstChunkLoaded = false;
65578
- this.disposers.push(visibleChunksChanged.add(() => {
65579
- if (!firstChunkLoaded) {
65580
- for (const layer of this.viewer.layerManager.managedLayers) {
65581
- if (layer.layer instanceof SegmentationUserLayer) {
65582
- const hasVisibleChunk = layer.layer.renderLayers?.some((rl) => {
65583
- const { numVisibleChunksAvailable, numVisibleChunksNeeded } = rl.layerChunkProgressInfo || {};
65584
- if (!numVisibleChunksNeeded || !numVisibleChunksAvailable)
65585
- return false;
65586
- return numVisibleChunksAvailable / numVisibleChunksNeeded > 0.25;
65587
- });
65588
- if (hasVisibleChunk) {
65589
- firstChunkLoaded = true;
65590
- requestAnimationFrame(() => {
65591
- requestAnimationFrame(() => {
65592
- this.props.onLayerLoadingChange?.(true);
65593
- });
65636
+ const checkAndMarkLoaded = () => {
65637
+ if (firstChunkLoaded)
65638
+ return false;
65639
+ for (const layer of this.viewer.layerManager.managedLayers) {
65640
+ if (layer.layer instanceof SegmentationUserLayer) {
65641
+ const hasVisibleChunk = layer.layer.renderLayers?.some((rl) => {
65642
+ const { numVisibleChunksAvailable, numVisibleChunksNeeded } = rl.layerChunkProgressInfo || {};
65643
+ if (!numVisibleChunksNeeded || !numVisibleChunksAvailable)
65644
+ return false;
65645
+ return numVisibleChunksAvailable / numVisibleChunksNeeded > 0.25;
65646
+ });
65647
+ if (hasVisibleChunk) {
65648
+ firstChunkLoaded = true;
65649
+ requestAnimationFrame(() => requestAnimationFrame(() => {
65650
+ this.props.onLayerLoadingChange?.(true);
65651
+ }));
65652
+ return true;
65653
+ }
65654
+ }
65655
+ if (layer.layer instanceof AnnotationUserLayer) {
65656
+ const hasVisibleChunk = layer.layer.renderLayers?.some((rl) => {
65657
+ const { numVisibleChunksNeeded } = rl.layerChunkProgressInfo || {};
65658
+ return numVisibleChunksNeeded > 0;
65659
+ });
65660
+ if (hasVisibleChunk) {
65661
+ firstChunkLoaded = true;
65662
+ requestAnimationFrame(() => requestAnimationFrame(() => {
65663
+ this.props.onLayerLoadingChange?.(true);
65664
+ }));
65665
+ const annotState = layer.layer.annotationStates?.states[0];
65666
+ const t = annotState?.chunkTransform?.value?.layerToChunkTransform;
65667
+ const serializers = annotState?.source?.annotationPropertySerializers;
65668
+ if (t && serializers) {
65669
+ this.props.onAnnotationSourceReady?.({
65670
+ x: t[0],
65671
+ y: t[5],
65672
+ z: t[10],
65673
+ serializers,
65674
+ // pass all serializers
65675
+ serializer: serializers[0]
65676
+ // keep default for backward compat
65594
65677
  });
65595
- return;
65596
65678
  }
65679
+ return true;
65597
65680
  }
65598
65681
  }
65599
65682
  }
65600
- }));
65683
+ return false;
65684
+ };
65685
+ this.disposers.push(visibleChunksChanged.add(checkAndMarkLoaded));
65686
+ setTimeout(() => {
65687
+ if (!firstChunkLoaded)
65688
+ checkAndMarkLoaded();
65689
+ }, 100);
65690
+ setTimeout(() => {
65691
+ if (!firstChunkLoaded)
65692
+ checkAndMarkLoaded();
65693
+ }, 1e3);
65601
65694
  this.disposers.push(() => {
65602
65695
  firstChunkLoaded = false;
65603
65696
  });
65697
+ document.addEventListener("wheel", (e) => {
65698
+ if (e.ctrlKey)
65699
+ e.preventDefault();
65700
+ }, { passive: false });
65701
+ this.disposers.push(() => {
65702
+ document.removeEventListener("wheel", (e) => {
65703
+ if (e.ctrlKey)
65704
+ e.preventDefault();
65705
+ });
65706
+ });
65707
+ this.disposers.push(this.viewer.chunkQueueManager.visibleChunksChanged.add(() => {
65708
+ if (this.props.cellColorMapping) {
65709
+ this.applyColorsAndVisibility(this.props.cellColorMapping);
65710
+ }
65711
+ }));
65712
+ window.viewer = this.viewer;
65604
65713
  }
65605
65714
  componentDidUpdate(prevProps, prevState) {
65606
65715
  const { viewerState, cellColorMapping: cellColorMappingByLayer } = this.props;
@@ -65611,13 +65720,19 @@ class Neuroglancer extends React__default.Component {
65611
65720
  selectedSegments[layer.name] = segmentSelectionState.selectedSegment;
65612
65721
  }
65613
65722
  }
65723
+ for (const managedLayer of this.viewer.layerManager.managedLayers) {
65724
+ const matchingLayer = (viewerState?.layers || []).find((l) => l.name === managedLayer.name);
65725
+ if (matchingLayer && typeof matchingLayer.visible === "boolean" && managedLayer.visible !== matchingLayer.visible) {
65726
+ managedLayer.setVisible(matchingLayer.visible);
65727
+ }
65728
+ }
65614
65729
  for (const layer of this.viewer.layerManager.managedLayers) {
65615
65730
  if (layer.layer instanceof SegmentationUserLayer) {
65616
65731
  const { segmentSelectionState } = layer.layer.displayState;
65617
65732
  segmentSelectionState.set(selectedSegments[layer.name]);
65618
65733
  const layerScope = Object.keys(cellColorMappingByLayer).find((scope) => layer.name?.includes(scope));
65619
65734
  if (layerScope) {
65620
- const opacity = cellColorMappingByLayer[layerScope]?.opacity ?? 1;
65735
+ const opacity = this.props.meshOpacity !== void 0 ? this.props.meshOpacity : cellColorMappingByLayer[layerScope]?.opacity ?? 1;
65621
65736
  layer.layer.displayState.objectAlpha.value = opacity;
65622
65737
  }
65623
65738
  }
@@ -65634,6 +65749,8 @@ class Neuroglancer extends React__default.Component {
65634
65749
  if (!viewerState)
65635
65750
  return;
65636
65751
  const prevVS = prevProps.viewerState;
65752
+ const prevLayers = prevProps.viewerState?.layers;
65753
+ const nextLayers = viewerState?.layers;
65637
65754
  const camState = diffCameraState(prevVS, viewerState);
65638
65755
  if (camState.changed) {
65639
65756
  const patch = {};
@@ -65650,39 +65767,34 @@ class Neuroglancer extends React__default.Component {
65650
65767
  }
65651
65768
  if (this.didLayersChange(prevVS, viewerState)) {
65652
65769
  this.withoutEmitting(() => {
65653
- const layers = Array.isArray(viewerState.layers) ? viewerState.layers : [];
65654
- this.viewer.state.restoreState({ layers });
65655
- if (cellColorMappingByLayer && Object.keys(cellColorMappingByLayer).length) {
65656
- this.applyColorsAndVisibility(cellColorMappingByLayer);
65657
- }
65770
+ this.preserveDimensions(() => {
65771
+ this.viewer.state.restoreState({ layers: nextLayers });
65772
+ });
65658
65773
  });
65659
65774
  }
65660
- const prevSize = prevProps.cellColorMapping ? Object.values(prevProps.cellColorMapping).reduce((acc, v) => acc + Object.keys(v?.colors || {}).length, 0) : 0;
65661
- const currSize = cellColorMappingByLayer ? Object.values(cellColorMappingByLayer).reduce((acc, v) => acc + Object.keys(v?.colors || {}).length, 0) : 0;
65662
- const mappingRefChanged = prevProps.cellColorMapping !== this.props.cellColorMapping;
65663
- if (!this.didLayersChange(prevVS, viewerState) && (mappingRefChanged || prevSize !== currSize)) {
65775
+ const stripOpacity = (mapping) => {
65776
+ const result = {};
65777
+ Object.entries(mapping || {}).forEach(([k, v]) => {
65778
+ result[k] = { colors: v?.colors };
65779
+ });
65780
+ return result;
65781
+ };
65782
+ const prevColorsJSON = JSON.stringify(stripOpacity(prevProps.cellColorMapping));
65783
+ const currColorsJSON = JSON.stringify(stripOpacity(cellColorMappingByLayer));
65784
+ const colorsActuallyChanged = prevColorsJSON !== currColorsJSON;
65785
+ if (!this.didLayersChange(prevVS, viewerState) && colorsActuallyChanged) {
65664
65786
  this.withoutEmitting(() => {
65665
65787
  this.applyColorsAndVisibility(cellColorMappingByLayer);
65666
65788
  });
65667
65789
  }
65668
- const stripSegFields = (layers) => (layers || []).map((l) => {
65669
- if (!l)
65670
- return l;
65671
- const { segments, segmentColors, objectAlpha, ...rest } = l;
65672
- return rest;
65673
- });
65674
- const prevLayers = prevProps.viewerState?.layers;
65675
- const nextLayers = viewerState?.layers;
65676
- const prevCore = JSON.stringify(stripSegFields(prevLayers));
65677
- const nextCore = JSON.stringify(stripSegFields(nextLayers));
65678
- const sourcesChanged = prevCore !== nextCore;
65679
- const prevSegCount = prevLayers && prevLayers[0] && Array.isArray(prevLayers[0].segments) ? prevLayers[0].segments.length : 0;
65680
- const nextSegCount = nextLayers && nextLayers[0] && Array.isArray(nextLayers[0].segments) ? nextLayers[0].segments.length : 0;
65681
- const initialSegmentsAdded = prevSegCount === 0 && nextSegCount > 0;
65682
- if (sourcesChanged || initialSegmentsAdded) {
65683
- this.withoutEmitting(() => {
65790
+ const prevSegIds = prevLayers?.[0]?.segments ?? [];
65791
+ const nextSegIds = nextLayers?.[0]?.segments ?? [];
65792
+ const segmentsChanged = prevSegIds.length !== nextSegIds.length || prevSegIds[0] !== nextSegIds[0] || prevSegIds[prevSegIds.length - 1] !== nextSegIds[nextSegIds.length - 1];
65793
+ if (segmentsChanged && nextSegIds.length > 0) {
65794
+ this.preserveDimensions(() => {
65684
65795
  this.viewer.state.restoreState({ layers: nextLayers });
65685
65796
  });
65797
+ this.applyColorsAndVisibility(cellColorMappingByLayer);
65686
65798
  }
65687
65799
  }
65688
65800
  componentWillUnmount() {
@@ -65713,7 +65825,7 @@ class Neuroglancer extends React__default.Component {
65713
65825
  *
65714
65826
  */
65715
65827
  setCallbacks(callbacks) {
65716
- callbacks.forEach((callback) => {
65828
+ (callbacks ?? []).forEach((callback) => {
65717
65829
  this.viewer.bindCallback(callback.name, callback.function);
65718
65830
  this.viewer.inputEventBindings.sliceView.set(callback.event, callback.name);
65719
65831
  });
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useState, useEffect } from "react";
3
- import { x as xrStore } from "./xrStore-gGt4Wkvz.js";
3
+ import { x as xrStore } from "./xrStore-Dhi1LSJi.js";
4
4
  function XREnterButton() {
5
5
  const [supported, setSupported] = useState(false);
6
6
  const [entered, setEntered] = useState(false);
@@ -1,7 +1,7 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import { useRef } from "react";
3
3
  import { useThree, useFrame } from "@react-three/fiber";
4
- import { g as getXRModule } from "./index-0nuepTVk.js";
4
+ import { g as getXRModule } from "./index-CwGBUQIk.js";
5
5
  const { useXRInputSourceState } = getXRModule();
6
6
  function getHandJoint(hand, jointName) {
7
7
  return hand.get(jointName);
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { g as getXRModule } from "./index-0nuepTVk.js";
3
- import { x as xrStore } from "./xrStore-gGt4Wkvz.js";
2
+ import { g as getXRModule } from "./index-CwGBUQIk.js";
3
+ import { x as xrStore } from "./xrStore-Dhi1LSJi.js";
4
4
  const { XR } = getXRModule();
5
5
  function XRWrapper({ children }) {
6
6
  return jsx(XR, { store: xrStore, children });
@@ -1,5 +1,5 @@
1
1
  import { i as inflate_1 } from "./pako.esm-SxljTded.js";
2
- import { B as BaseDecoder } from "./index-moreUHDf.js";
2
+ import { B as BaseDecoder } from "./index-B8FH88N6.js";
3
3
  class DeflateDecoder extends BaseDecoder {
4
4
  decodeBlock(buffer) {
5
5
  return inflate_1(new Uint8Array(buffer)).buffer;
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import React__default, { createContext, isValidElement, PureComponent, Component, useMemo, useState, useRef, useEffect, useCallback, memo, useContext, useReducer, useLayoutEffect } from "react";
3
- import { r as requireObjectAssign, a as getDefaultExportFromCjs$1, c as commonjsGlobal, e as earcut } from "./index-moreUHDf.js";
3
+ import { r as requireObjectAssign, a as getDefaultExportFromCjs$1, c as commonjsGlobal, e as earcut } from "./index-B8FH88N6.js";
4
4
  import ReactDOM__default, { unstable_batchedUpdates, createPortal } from "react-dom";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  function finallyConstructor(callback) {