@jax-data-science/sci-image-visualizer 0.9.0 → 0.10.0

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 (131) hide show
  1. package/esm2022/index.mjs +7 -1
  2. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  3. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  4. package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
  5. package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
  6. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  7. package/esm2022/lib/contracts/viz-config.mjs +1 -1
  8. package/esm2022/lib/geometry/loft.mjs +128 -0
  9. package/esm2022/lib/geometry/polylabel.mjs +156 -0
  10. package/esm2022/lib/geometry/reconstruct.mjs +315 -0
  11. package/esm2022/lib/geometry/reslice-image.mjs +57 -0
  12. package/esm2022/lib/geometry/section.mjs +215 -0
  13. package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +11 -7
  14. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +20 -3
  15. package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
  16. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +28 -5
  17. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
  18. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +9 -2
  19. package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +5 -2
  20. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +81 -1
  21. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
  22. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +115 -4
  23. package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
  24. package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +15 -3
  25. package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +18 -7
  26. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +38 -8
  27. package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +1 -1
  28. package/esm2022/lib/models/class-preset.mjs +1 -1
  29. package/esm2022/lib/models/polygon-factory.mjs +17 -1
  30. package/esm2022/lib/models/region-geojson.mjs +44 -6
  31. package/esm2022/lib/models/region.mjs +1 -1
  32. package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
  33. package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
  34. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +77 -13
  35. package/esm2022/lib/region-editor/region-editor.component.mjs +527 -42
  36. package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
  37. package/esm2022/lib/region-editor/region-persistence.service.mjs +36 -10
  38. package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
  39. package/esm2022/lib/region-overlay/region-geometry.mjs +3 -3
  40. package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
  41. package/esm2022/lib/region-overlay/region-style.mjs +97 -0
  42. package/esm2022/lib/region-source/http-region-source.mjs +104 -0
  43. package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
  44. package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
  45. package/esm2022/lib/region-source/region-source.mjs +67 -0
  46. package/esm2022/lib/region-source/region-tiles.mjs +708 -0
  47. package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
  48. package/esm2022/lib/routing-visualizer.service.mjs +418 -22
  49. package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
  50. package/esm2022/lib/store/class-color.util.mjs +10 -5
  51. package/esm2022/lib/store/class-signatures.mjs +63 -0
  52. package/esm2022/lib/store/region-scope-cache.mjs +5 -1
  53. package/esm2022/lib/store/region-source-scope.mjs +171 -0
  54. package/esm2022/lib/store/region-store.service.mjs +724 -12
  55. package/esm2022/lib/store/visualizer-store.service.mjs +33 -6
  56. package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +8 -2
  57. package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +55 -15
  58. package/esm2022/lib/toolbar/toolbar.component.mjs +19 -5
  59. package/esm2022/lib/visualizer/region-load.mjs +67 -4
  60. package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
  61. package/esm2022/lib/visualizer.component.mjs +128 -6
  62. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs} +7239 -1153
  63. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
  64. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs} +4 -4
  65. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map} +1 -1
  66. package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
  67. package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
  68. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -3
  69. package/fesm2022/region-source.worker.js +1067 -0
  70. package/index.d.ts +6 -0
  71. package/lib/contracts/image.contract.d.ts +4 -0
  72. package/lib/contracts/region-editor-api.contract.d.ts +84 -0
  73. package/lib/contracts/region-store.contract.d.ts +22 -0
  74. package/lib/contracts/section-view.contract.d.ts +44 -0
  75. package/lib/contracts/visualizer.contract.d.ts +10 -0
  76. package/lib/contracts/viz-config.d.ts +8 -0
  77. package/lib/geometry/loft.d.ts +22 -0
  78. package/lib/geometry/polylabel.d.ts +23 -0
  79. package/lib/geometry/reconstruct.d.ts +54 -0
  80. package/lib/geometry/reslice-image.d.ts +33 -0
  81. package/lib/geometry/section.d.ts +52 -0
  82. package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -2
  83. package/lib/implementations/napari-js/napari-loading-state.d.ts +8 -1
  84. package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
  85. package/lib/implementations/napari-js/napari-region-overlay.d.ts +6 -1
  86. package/lib/implementations/napari-js/napari-scene.d.ts +33 -0
  87. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +3 -1
  88. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +48 -0
  89. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
  90. package/lib/implementations/napari-js/napari-volume-scene.d.ts +45 -1
  91. package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
  92. package/lib/implementations/osd/osd-region-overlay-draw.d.ts +4 -3
  93. package/lib/implementations/osd/osd-region-overlay.d.ts +10 -3
  94. package/lib/implementations/tile-server/tile-protocol.d.ts +3 -0
  95. package/lib/models/class-preset.d.ts +7 -0
  96. package/lib/models/polygon-factory.d.ts +5 -0
  97. package/lib/models/region-geojson.d.ts +40 -0
  98. package/lib/models/region.d.ts +19 -0
  99. package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
  100. package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
  101. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +36 -6
  102. package/lib/region-editor/region-editor.component.d.ts +133 -17
  103. package/lib/region-editor/region-metrics.d.ts +8 -0
  104. package/lib/region-editor/region-persistence.service.d.ts +12 -4
  105. package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
  106. package/lib/region-overlay/region-geometry.d.ts +4 -3
  107. package/lib/region-overlay/region-source-layer.d.ts +96 -0
  108. package/lib/region-overlay/region-style.d.ts +52 -0
  109. package/lib/region-source/http-region-source.d.ts +45 -0
  110. package/lib/region-source/region-source-ops.d.ts +89 -0
  111. package/lib/region-source/region-source-worker.d.ts +7 -0
  112. package/lib/region-source/region-source.d.ts +82 -0
  113. package/lib/region-source/region-tiles.d.ts +289 -0
  114. package/lib/region-source/worker-region-source.d.ts +65 -0
  115. package/lib/routing-visualizer.service.d.ts +138 -1
  116. package/lib/section-pane/section-pane.component.d.ts +47 -0
  117. package/lib/store/class-color.util.d.ts +6 -3
  118. package/lib/store/class-signatures.d.ts +11 -0
  119. package/lib/store/region-scope-cache.d.ts +2 -0
  120. package/lib/store/region-source-scope.d.ts +68 -0
  121. package/lib/store/region-store.service.d.ts +206 -2
  122. package/lib/store/visualizer-store.service.d.ts +10 -0
  123. package/lib/toolbar/region-tools/region-tools.component.d.ts +3 -1
  124. package/lib/toolbar/stack-controls/stack-controls.component.d.ts +20 -9
  125. package/lib/toolbar/toolbar.component.d.ts +9 -2
  126. package/lib/visualizer/region-load.d.ts +23 -4
  127. package/lib/visualizer/volume-sections.d.ts +64 -0
  128. package/lib/visualizer.component.d.ts +31 -0
  129. package/package.json +2 -2
  130. package/src/lib/assets/slice.svg +23 -0
  131. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +0 -1
@@ -0,0 +1,47 @@
1
+ import { AfterViewInit, EventEmitter, NgZone, OnChanges, OnDestroy } from '@angular/core';
2
+ import type { SectionAxis, SectionView } from '../contracts/section-view.contract';
3
+ import * as i0 from "@angular/core";
4
+ export declare class SectionPaneComponent implements AfterViewInit, OnChanges, OnDestroy {
5
+ private readonly zone;
6
+ axis: SectionAxis;
7
+ view: SectionView | null;
8
+ /** A point clicked, in section coordinates (u across, v down). */
9
+ readonly pick: EventEmitter<{
10
+ u: number;
11
+ v: number;
12
+ }>;
13
+ private canvasRef;
14
+ private zoom;
15
+ private pan;
16
+ private press;
17
+ private image;
18
+ private resize?;
19
+ private frame;
20
+ constructor(zone: NgZone);
21
+ protected get axisColor(): string;
22
+ protected get label(): string;
23
+ ngAfterViewInit(): void;
24
+ ngOnChanges(): void;
25
+ ngOnDestroy(): void;
26
+ /** Back to the whole section, centred. */
27
+ fit(): void;
28
+ protected onWheel(e: WheelEvent): void;
29
+ protected onDown(e: PointerEvent): void;
30
+ protected onMove(e: PointerEvent): void;
31
+ protected onUp(e: PointerEvent): void;
32
+ private local;
33
+ /** Section units → CSS px in the pane: scale per unit across and down, and the origin. */
34
+ private transform;
35
+ private toSection;
36
+ /** Redraw on the next frame (outside Angular: a canvas paint needs no change detection). */
37
+ private draw;
38
+ private paint;
39
+ /** Each class's cut: its outlines filled and stroked, its lines drawn (a dot for one point). */
40
+ private paintRegions;
41
+ /** The other planes: across (u) and down (v), dashed in their axis colours. */
42
+ private paintCrosshair;
43
+ /** The section's image on a canvas of its own size (made again only for a new image). */
44
+ private imageCanvas;
45
+ static ɵfac: i0.ɵɵFactoryDeclaration<SectionPaneComponent, never>;
46
+ static ɵcmp: i0.ɵɵComponentDeclaration<SectionPaneComponent, "viz-section-pane", never, { "axis": { "alias": "axis"; "required": true; }; "view": { "alias": "view"; "required": false; }; }, { "pick": "pick"; }, never, never, true, never>;
47
+ }
@@ -30,7 +30,10 @@ export declare function findPreset(label: string, set: PresetSet): ClassPreset |
30
30
  * HSL hue. Same name -> same colour, every run.
31
31
  */
32
32
  export declare function fallbackColorFor(label: string, palette: string[]): string;
33
- /** Resolve a colour for `label`: a matching preset's colour, else the deterministic fallback. */
33
+ /**
34
+ * Resolve a colour for `label`: a matching preset's colour, else the colour an imported file
35
+ * gave the class, else the deterministic fallback.
36
+ */
34
37
  export declare function colorForLabel(label: string, set: PresetSet): string;
35
38
  /** Options for {@link applyPresetColors}. */
36
39
  export interface ApplyPresetColorsOptions {
@@ -49,8 +52,8 @@ export interface ApplyPresetColorsOptions {
49
52
  /**
50
53
  * Resolve each labelled region's colour from the preset set (jit-ui#70). The
51
54
  * presets are the source of truth: a matching preset gives the class colour,
52
- * an unknown class its deterministic fallback, **overriding any colour already
53
- * on the region** (e.g. embedded in imported GeoJSON). Unlabelled regions and
55
+ * an unknown class the colour an imported file gave it (`importedColors`) or else
56
+ * its deterministic fallback, **overriding any colour already on the region**. Unlabelled regions and
54
57
  * ones the user recoloured (`colorOverridden`) are left untouched. Unknown
55
58
  * classes are reported through `onPromote` when `autoPromote` is on.
56
59
  *
@@ -0,0 +1,11 @@
1
+ import { Region } from '../models/region';
2
+ /**
3
+ * A fingerprint of each class's regions (by label): their ids and geometry folded into one number
4
+ * per class. Two sets give the same fingerprint for a class when its regions did not change, so
5
+ * comparing a slice's fingerprints before and after an edit names the classes the edit touched
6
+ * (a recoloured or relabelled region touches its old class and its new one). Profile lines and
7
+ * unlabelled regions are left out: they are in no class.
8
+ */
9
+ export declare function classSignatures(regions: readonly Region[]): Map<string, number>;
10
+ /** The classes whose fingerprints differ between `before` and `after` (added and removed included). */
11
+ export declare function changedClasses(before: ReadonlyMap<string, number>, after: ReadonlyMap<string, number>): Set<string>;
@@ -26,6 +26,8 @@ export declare class RegionScopeCache {
26
26
  private initialNonEmpty;
27
27
  /** The cache key for an image: its first URL, else its file name. */
28
28
  static imageKey(imageInfo: IImageInfo | undefined): string | undefined;
29
+ /** The active image's cache key (see {@link imageKey}). */
30
+ get activeImage(): string | undefined;
29
31
  /** True while a z-stack is loaded and regions are held per slice. */
30
32
  get stackMode(): boolean;
31
33
  /** The current display slice (zero-based; 0 outside stack mode unless set). */
@@ -0,0 +1,68 @@
1
+ import type { RegionSource } from '../region-source/region-source';
2
+ /** Opens a region source on demand (and again after it was closed to save memory). */
3
+ export type RegionSourceOpener = () => Promise<RegionSource>;
4
+ /** Which slices a source serves: one slice (plane `plane` of the source), or every slice z
5
+ * from the source's plane z (a z-indexed GeoJSON over a whole stack). */
6
+ export type RegionSourceSlices = {
7
+ slice: number;
8
+ plane?: number;
9
+ } | 'planes';
10
+ /** The region source behind one slice: the source and which of its planes the slice shows. */
11
+ export interface RegionSourceBinding {
12
+ source: RegionSource;
13
+ plane: number;
14
+ }
15
+ /** Sources held open, past which the least recently used one is closed (never the one shown). */
16
+ export declare const OPEN_REGION_SOURCES = 6;
17
+ /**
18
+ * The region sources of every image the store has seen, per slice, and per slice the ids of
19
+ * the source features taken out of the source (into the working set, or deleted) — those the
20
+ * source no longer draws and an export leaves out.
21
+ *
22
+ * Sources open lazily, the first time their slice is shown or read, and at most
23
+ * {@link OPEN_REGION_SOURCES} stay open: the least recently used are closed and re-opened from
24
+ * their opener when used again (a source's ids are stable, so what was taken stays taken). The
25
+ * source of the slice on screen ({@link show}) is never closed for another: a read across every
26
+ * slice must not close the source the viewer draws and takes from.
27
+ */
28
+ export declare class RegionSourceScope {
29
+ private readonly images;
30
+ /** Open entries, least recently used first. */
31
+ private readonly openOrder;
32
+ /** The entry of the slice on screen: kept open. */
33
+ private shown;
34
+ /** Attach `open` to `image` for `slices`, replacing (and closing) what was there. */
35
+ attach(image: string, open: RegionSourceOpener, slices: RegionSourceSlices): void;
36
+ /** Drop every source of `image` (closing the open ones) and what was taken from them. */
37
+ detachImage(image: string): void;
38
+ /** Drop the source of one slice of `image`. */
39
+ detachSlice(image: string, slice: number): void;
40
+ /** The slice on screen (null: none): its source stays open while others are read. */
41
+ show(image: string | undefined, slice: number | null): void;
42
+ /** Whether `image` has a source for `slice`. */
43
+ has(image: string | undefined, slice: number): boolean;
44
+ /** Whether `slice` of `image` has a source of its own (not a `'planes'` source's plane). */
45
+ hasOwnSource(image: string | undefined, slice: number): boolean;
46
+ /** Every slice of `image` with a source of its own (not counting a `'planes'` source). */
47
+ slicesWithSource(image: string | undefined): number[];
48
+ /** Whether `image` has one source over all its slices. */
49
+ hasPlanesSource(image: string | undefined): boolean;
50
+ /**
51
+ * The source behind `slice` of `image`, opening it if needed. Resolves null when there is
52
+ * none, and rejects when it cannot be opened.
53
+ */
54
+ binding(image: string | undefined, slice: number): Promise<RegionSourceBinding | null>;
55
+ /** The ids taken from `slice`'s source. */
56
+ taken(image: string | undefined, slice: number): ReadonlySet<string>;
57
+ /** Every id taken from any slice of `image` (a `'planes'` source's ids are unique across them). */
58
+ allTaken(image: string | undefined): string[];
59
+ /** The slices of `image` with anything taken from their source. */
60
+ slicesWithTaken(image: string | undefined): number[];
61
+ /** Replace the ids taken from `slice`'s source (copy-on-write: `ids` is kept as given). */
62
+ setTaken(image: string | undefined, slice: number, ids: ReadonlySet<string>): void;
63
+ private entry;
64
+ private imageSources;
65
+ private openEntry;
66
+ private close;
67
+ private closeSource;
68
+ }
@@ -3,9 +3,17 @@ import { IImageInfo } from '../contracts/image.contract';
3
3
  import { Region, Rectangle, Polygon, MultiPolygon } from '../models/region';
4
4
  import { VisualizerStore } from './visualizer-store.service';
5
5
  import { IRegionStore } from '../contracts/visualizer.contract';
6
- import { IRegionEditApi } from '../contracts/region-store.contract';
6
+ import { IRegionEditApi, IRegionSourceApi } from '../contracts/region-store.contract';
7
+ import type { Mesh } from 'napari-js/geometry';
8
+ import { SliceOutlines } from '../geometry/reconstruct';
7
9
  import { StackSaveLayout } from './region-scope-cache';
10
+ import { RegionSourceOpener, RegionSourceSlices } from './region-source-scope';
11
+ import type { RegionSource, RegionSourceView } from '../region-source/region-source';
12
+ import type { RegionIndexPage, RegionIndexQuery } from '../region-source/region-tiles';
13
+ import { RegionStyle } from '../region-overlay/region-style';
8
14
  import * as i0 from "@angular/core";
15
+ /** Selecting classes takes at most this many region-source features into the regions. */
16
+ export declare const SELECT_CLASSES_LIMIT = 5000;
9
17
  /**
10
18
  * Backend-neutral region store — the single source of truth for region state.
11
19
  *
@@ -34,7 +42,7 @@ import * as i0 from "@angular/core";
34
42
  * backends); GeoJSON import/export is `models/region-geojson`. All coordinates
35
43
  * are image pixels.
36
44
  */
37
- export declare class RegionStore implements IRegionStore, IRegionEditApi {
45
+ export declare class RegionStore implements IRegionStore, IRegionEditApi, IRegionSourceApi {
38
46
  private store;
39
47
  private static readonly UNDO_LIMIT;
40
48
  private static readonly UNDO_COALESCE_MS;
@@ -78,6 +86,35 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi {
78
86
  /** Emit coalescing for live drags (see IRegionEditApi.beginBatch). */
79
87
  private batchDepth;
80
88
  private pendingEmit;
89
+ /**
90
+ * Large region sets held as tiled region sources rather than as regions (see
91
+ * {@link attachRegionSource}): per image and slice, with the ids taken out of each.
92
+ */
93
+ private readonly sources;
94
+ private readonly sourceView$;
95
+ /** The region look the user chose (overrides the source's hint), field by field. */
96
+ private userStyle;
97
+ /** The current source's style hint. */
98
+ private hintStyle;
99
+ private readonly regionStyle$;
100
+ /** Bumped on every change of the slice's source, so a late open is dropped. */
101
+ private sourceGeneration;
102
+ /** The source last published as the view: a source shown again does not turn the labels back on. */
103
+ private shownSource;
104
+ /** Bumped when a region source is attached or dropped: what is read from the sources is stale. */
105
+ private sourcesVersion;
106
+ /**
107
+ * The region sources' part of {@link classVolumes}, by class and what the sources hold (see
108
+ * {@link sourceStateKey}): an edit of the regions leaves it, so the volumes of a slice being drawn
109
+ * on cost no source reads.
110
+ */
111
+ private readonly sourceVolumeCache;
112
+ /** The region sources' outlines of the class sets reconstructed last (see {@link sourceOutlines}). */
113
+ private readonly sourceOutlineCache;
114
+ /** The classes hidden from view (names as given); every class is shown at first. */
115
+ private readonly hiddenClasses$;
116
+ /** {@link hiddenClasses$} by {@link presetKey}, as a region's label is matched. */
117
+ private hiddenKeys;
81
118
  constructor(store: VisualizerStore);
82
119
  /**
83
120
  * Replace (or, with `append`, add to) the current image's regions. Mints ids
@@ -236,6 +273,10 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi {
236
273
  * region it edits) rather than changing them, so it never changes after this.
237
274
  */
238
275
  private recordUndoSnapshot;
276
+ /** The state an undo step restores. */
277
+ private snapshot;
278
+ /** Parse GeoJSON into regions, remembering the class colours the file carries so they are
279
+ * kept for classes with no preset (see VisualizerStore.rememberImportedClassColors). */
239
280
  importRegions(geoJsonStr: string): Region[];
240
281
  /** Download `regions` as GeoJSON, named after `fileName` (extension
241
282
  * replaced by `.geojson`) or `rois.geojson` without one. */
@@ -286,6 +327,169 @@ export declare class RegionStore implements IRegionStore, IRegionEditApi {
286
327
  beginGesture(): void;
287
328
  /** End the gesture opened by {@link beginGesture}; the next commit starts a new step. */
288
329
  endGesture(): void;
330
+ /**
331
+ * Hold a large region set as a tiled region source instead of as regions: the backends that
332
+ * draw sources (OpenSeadragon, napari) draw its features at the detail the zoom shows, from
333
+ * the tiles in view, and a feature joins the regions — exactly, as an ordinary editable
334
+ * {@link Region} with its {@link Region.sourceId} — only when it is selected or edited
335
+ * ({@link takeSourceFeatures}). Until then {@link getRegions} does not include it.
336
+ *
337
+ * `source` may be an opener, called the first time its slice is shown (and again if the
338
+ * source was closed to save memory). `slices` says which slice of the current image it
339
+ * serves: one (default: the slice shown; plane 0 of the source), or `'planes'`, every slice z
340
+ * from plane z of a z-indexed source. Replaces the source those slices had.
341
+ */
342
+ attachRegionSource(source: RegionSource | RegionSourceOpener, slices?: RegionSourceSlices): void;
343
+ /** Drop the current image's region sources (closing them) and what was taken from them. */
344
+ detachRegionSources(): void;
345
+ /**
346
+ * Drop the slice's region source, for regions imported in place of the slice's (a small file
347
+ * replacing a large one): a source of the slice's own is detached; a z-indexed source over every
348
+ * slice has this slice's features taken out (as deleted). The other slices keep theirs.
349
+ */
350
+ dropSliceRegionSource(): Promise<void>;
351
+ /** Whether the slice shown has a region source. */
352
+ hasRegionSource(): boolean;
353
+ /** The slice's region source as a source layer draws it; null without one (or until it opens). */
354
+ getRegionSourceView(): RegionSourceView | null;
355
+ /** {@link getRegionSourceView} and every change of it (slice, taken ids, class colours). */
356
+ getRegionSourceView$(): Observable<RegionSourceView | null>;
357
+ /**
358
+ * Take source features into the working set for editing: their exact geometry becomes
359
+ * ordinary regions (minted, coloured and slice-tagged as any region entering the store) and
360
+ * the source stops drawing them. Not an undo step of its own — undoing past it puts the
361
+ * features back in the source. Resolves the region ids, in the order asked (a feature already
362
+ * taken resolves to its region); [] when the slice changed meanwhile.
363
+ */
364
+ takeSourceFeatures(ids: readonly string[]): Promise<number[]>;
365
+ /** {@link takeSourceFeatures}, then select them (added to the selection with `additive`). */
366
+ selectSourceFeatures(ids: readonly string[], additive?: boolean): Promise<number[]>;
367
+ /**
368
+ * Features per class still in the slice's region source (not taken); {} without one. With
369
+ * `stack`, a z-stack's over every slice: its source's planes, or each slice's source added up.
370
+ */
371
+ getRegionSourceClassCounts(stack?: boolean): Promise<Record<string, number>>;
372
+ /**
373
+ * Select every region of these classes on the slice — the regions', and the region source's,
374
+ * which are taken into the regions (at most {@link SELECT_CLASSES_LIMIT} of them). Added to the
375
+ * selection with `additive`. Resolves the selected region ids.
376
+ */
377
+ selectClasses(classes: readonly string[], additive?: boolean): Promise<number[]>;
378
+ /**
379
+ * The 3D reconstruction of each group of classes over every slice of the stack (an atlas
380
+ * structure with its substructures, say): the outlines of the regions of those classes on every
381
+ * slice — the region sources' and those drawn or taken — stacked and meshed in a worker. Meshes
382
+ * are in image px (x, y) and slice indices (z). `pixelStep` is the in-plane voxel size (image
383
+ * px); the outlines are read at the matching level of detail. A group with no outline gets an
384
+ * empty mesh.
385
+ */
386
+ reconstructClasses(groups: ReadonlyArray<{
387
+ key: string;
388
+ classes: readonly string[];
389
+ }>, pixelStep?: number): Promise<Array<{
390
+ key: string;
391
+ mesh: Mesh;
392
+ }>>;
393
+ /**
394
+ * Each class's volume over the whole stack, in px² × slices: its outlines' area on every slice
395
+ * (its features' union, see `outlinesArea`), one slice thick (Cavalieri's estimator), from the
396
+ * exact outlines. Where a feature is, a region source's or a drawn or taken region, does not
397
+ * change it: taking one leaves the volume as it was. The region sources' part is cached until
398
+ * what they hold changes (a feature taken or deleted, another source); only the slices with
399
+ * drawn or taken regions of the class are measured again.
400
+ */
401
+ classVolumes(classes: readonly string[]): Promise<Map<string, number>>;
402
+ /** The region sources' part of a class's volume, cached by what they hold (see classVolumes). */
403
+ private sourceVolume;
404
+ /**
405
+ * Every slice's outlines of these classes, the region sources' then the regions': closed shapes'
406
+ * rings, and open polylines as `lines`.
407
+ */
408
+ private classOutlines;
409
+ /**
410
+ * The region sources' outlines of these classes on every slice, without the features taken or
411
+ * deleted. The last few class sets are kept until what the sources hold changes: rebuilding a
412
+ * surface after an edit reads nothing again.
413
+ */
414
+ private sourceOutlines;
415
+ private readSourceOutlines;
416
+ /**
417
+ * Every class's outlines on every slice, by class: the region sources' (one read for all, kept
418
+ * like {@link sourceOutlines}) and the drawn and taken regions'. What a section through the
419
+ * stack cuts (see `geometry/section`).
420
+ */
421
+ outlinesByClass(level: number): Promise<Map<string, SliceOutlines[]>>;
422
+ /** The drawn and taken regions' outlines of these classes, by slice. */
423
+ private regionOutlines;
424
+ /** Each drawn or taken region's outlines (of the `wanted` classes; null: every class) with its class. */
425
+ private labelledRegionOutlines;
426
+ /** What the region sources of the image hold (see {@link sourceStateKey}): it changes when a
427
+ * feature is taken or deleted, or that is undone. */
428
+ getSourceStateKey(): string;
429
+ /**
430
+ * What the region sources of the image hold: the image, its sources (one attached or dropped
431
+ * bumps the version) and the features taken from them. A key for what is read from them.
432
+ */
433
+ private sourceStateKey;
434
+ /** Delete source features without taking them (one undo step). */
435
+ deleteSourceFeatures(ids: readonly string[]): void;
436
+ /**
437
+ * A page of the slice source's features not taken from it (file order), e.g. for the Region
438
+ * Editor's list; an empty page without a source.
439
+ */
440
+ getRegionSourceIndex(query: Omit<RegionIndexQuery, 'exclude'>): Promise<RegionIndexPage>;
441
+ /**
442
+ * `regions` as a GeoJSON FeatureCollection string merged with the region source behind them:
443
+ * the source's features that were not taken (or deleted), then `regions`. Without a source,
444
+ * {@link getGeoJsonString}. `slice` names a folder stack's slice (default the one shown);
445
+ * on a z-indexed stack's source (`'planes'`) the export spans every slice.
446
+ */
447
+ getGeoJsonWithSource(regions: Region[], slice?: number): Promise<string>;
448
+ /**
449
+ * Whether a region of class `label` goes unlabelled because a subclass of it (by the region
450
+ * source's class hierarchy) is among the regions too — an atlas's "Isocortex" under its areas.
451
+ * False without a hierarchy.
452
+ */
453
+ isLabelCovered(label: string | undefined): boolean;
454
+ private coveredFor;
455
+ /** The classes hidden from view (see {@link setClassesHidden}). */
456
+ getHiddenClasses(): ReadonlySet<string>;
457
+ /** {@link getHiddenClasses} and every change of it. */
458
+ getHiddenClasses$(): Observable<ReadonlySet<string>>;
459
+ /**
460
+ * Hide (or show again) these classes' regions: the overlays and the region source's layer stop
461
+ * drawing them, and a hidden region can be neither picked nor kept selected. The regions stay in
462
+ * the set (the table lists them; a save keeps them).
463
+ */
464
+ setClassesHidden(classes: readonly string[], hidden: boolean): void;
465
+ /** Whether regions labelled `label` are hidden (an unlabelled region never is). */
466
+ isClassHidden(label: string | null | undefined): boolean;
467
+ /** The region look: outlines, or filled (an atlas's look); see `region-style`. */
468
+ getRegionStyle(): RegionStyle;
469
+ /** {@link getRegionStyle} and every change of it. */
470
+ getRegionStyle$(): Observable<RegionStyle>;
471
+ /**
472
+ * Choose the region look, field by field; it overrides a region source's hint for the session.
473
+ * The overlays redraw.
474
+ */
475
+ setRegionStyle(patch: Partial<RegionStyle>): void;
476
+ /** The look now: the user's choice, else the source's hint, else outlines. */
477
+ private effectiveStyle;
478
+ /** Publish the look when it changed: the overlays redraw the regions, the source layer its features. */
479
+ private restyle;
480
+ /** Re-emit the source view with the current look and label setting. */
481
+ private republishView;
482
+ /** The slice a region source is keyed by: the display slice in stack mode, else 0. */
483
+ private get sourceSlice();
484
+ private currentTaken;
485
+ /** Replace the slice's taken ids and tell the source layers. */
486
+ private setTaken;
487
+ /**
488
+ * Look up (opening it if needed) the slice's source and publish it as the source view. The view
489
+ * is withdrawn at once: until the incoming source opens, nothing reads, takes or deletes from the
490
+ * outgoing one into the slice now shown.
491
+ */
492
+ private refreshSourceView;
289
493
  /**
290
494
  * Switch the active image: snapshot the outgoing regions, restore the
291
495
  * incoming image's (or [] if none), clear selection, and notify. Idempotent
@@ -36,6 +36,8 @@ export declare class VisualizerStore {
36
36
  private readonly grayscale$;
37
37
  private readonly invert$;
38
38
  private presetSet;
39
+ /** Session-only class colours from imported files (see PresetSet.importedColors). */
40
+ private importedColors;
39
41
  private readonly presetSet$;
40
42
  private readonly savePresets$;
41
43
  private presetsLoaded;
@@ -46,6 +48,8 @@ export declare class VisualizerStore {
46
48
  private readonly spatialView$;
47
49
  constructor(prefsPort?: PreferencesPort | null);
48
50
  private initPresetPersistence;
51
+ /** Publish the preset set with this session's imported class colours. */
52
+ private emitPresetSet;
49
53
  private normalizePresetSet;
50
54
  /** Queue a debounced save. No-ops until the initial load resolves (and when no port is bound). */
51
55
  private queuePresetSave;
@@ -114,6 +118,12 @@ export declare class VisualizerStore {
114
118
  /** Upsert a single class colour (used by the editor's per-class colour picker). */
115
119
  setClassificationColor(label: string, color: string): void;
116
120
  getPresetSet(): PresetSet;
121
+ /**
122
+ * Remember the class colours an imported file carried (label → colour), so its regions keep
123
+ * them: a class with a preset keeps the preset's colour, and the latest import wins for the
124
+ * rest. Not persisted.
125
+ */
126
+ rememberImportedClassColors(colors: ReadonlyMap<string, string>): void;
117
127
  getPresetSet$(): Observable<PresetSet>;
118
128
  setPresetSet(set: PresetSet): void;
119
129
  /** Add or update a class (keyed by exact stored `name`). */
@@ -12,6 +12,8 @@ export declare class RegionToolsComponent {
12
12
  activeDragMode: string | null;
13
13
  /** The 3D cloud's screen-space lasso: no brush or polyline. */
14
14
  is3dRegions: boolean;
15
+ /** Only the selection tool (a volume view: it picks the regions' surfaces in 3D). */
16
+ selectOnly: boolean;
15
17
  /** The backend has a vertex-editing overlay (OSD + napari-js image). */
16
18
  vertexTools: boolean;
17
19
  /** Magic-wand sensitivity (the wand's slider value). */
@@ -56,5 +58,5 @@ export declare class RegionToolsComponent {
56
58
  /** A single slider's value (a range slider never feeds these). */
57
59
  protected asNumber(v: number | number[] | undefined): number | undefined;
58
60
  static ɵfac: i0.ɵɵFactoryDeclaration<RegionToolsComponent, never>;
59
- static ɵcmp: i0.ɵɵComponentDeclaration<RegionToolsComponent, "toolbar-region-tools", never, { "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "is3dRegions": { "alias": "is3dRegions"; "required": false; }; "vertexTools": { "alias": "vertexTools"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; }, { "openRegionEditor": "openRegionEditor"; "toggleDragMode": "toggleDragMode"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "deleteRegion": "deleteRegion"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, never, true, never>;
61
+ static ɵcmp: i0.ɵɵComponentDeclaration<RegionToolsComponent, "toolbar-region-tools", never, { "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "is3dRegions": { "alias": "is3dRegions"; "required": false; }; "selectOnly": { "alias": "selectOnly"; "required": false; }; "vertexTools": { "alias": "vertexTools"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; }, { "openRegionEditor": "openRegionEditor"; "toggleDragMode": "toggleDragMode"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "deleteRegion": "deleteRegion"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, never, true, never>;
60
62
  }
@@ -1,4 +1,4 @@
1
- import { EventEmitter } from '@angular/core';
1
+ import { EventEmitter, OnDestroy } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
3
  /** A stack-mode choice (`val` 'false' = single image, 'true' = stack). */
4
4
  export interface StackOption {
@@ -6,11 +6,11 @@ export interface StackOption {
6
6
  val: string;
7
7
  }
8
8
  /**
9
- * The toolbar's z-stack group: a live slice scrubber for the views that swap
10
- * slices in place, or (Plotly heatmap) the single-image / stack toggle with a
11
- * slice-number field. Presentational: the host owns `zIndex`.
9
+ * The toolbar's z-stack group: the slice bar, and (Plotly heatmap) the single-image / stack
10
+ * toggle. The views that swap slices in place follow the bar as it moves; the heatmap's single
11
+ * image is re-plotted at the slice it settles on. Presentational: the host owns `zIndex`.
12
12
  */
13
- export declare class StackControlsComponent {
13
+ export declare class StackControlsComponent implements OnDestroy {
14
14
  /** Show the live slice scrubber. */
15
15
  liveScrubber: boolean;
16
16
  /** Show the single-image / stack toggle (Plotly heatmap). */
@@ -29,12 +29,23 @@ export declare class StackControlsComponent {
29
29
  zSlide: EventEmitter<number | undefined>;
30
30
  /** A stack-mode choice was picked. */
31
31
  selectStackOption: EventEmitter<StackOption>;
32
- /** A slice number was typed (blank reports the current slice). */
32
+ /** The heatmap's slice bar moved to a slice (the host shows its number). */
33
33
  zIndexInput: EventEmitter<number>;
34
- /** Enter in the slice field / the reload button: re-plot at the typed slice. */
34
+ /** The heatmap's slice bar settled: re-plot at that slice. */
35
35
  reloadAndPlot: EventEmitter<void>;
36
- /** The slice field reports what was typed (blank keeps the current slice). */
37
- protected onSliceInput(value: string | number | null): void;
36
+ /** How long key steps on the heatmap's bar pause before the slice is re-plotted. */
37
+ static readonly REPLOT_DELAY_MS = 400;
38
+ /** A drag of the bar is under way (its end re-plots the heatmap, not each step). */
39
+ protected dragging: boolean;
40
+ private replot;
41
+ /** The heatmap in single-image mode: its bar re-plots the slice it settles on. */
42
+ protected get singleImage(): boolean;
43
+ /** The bar moved: a live view follows it; the heatmap shows the number, and re-plots after key steps pause. */
44
+ protected onSliceChange(z: number | undefined): void;
45
+ /** The bar was let go (a drag's end, or a click on its track). */
46
+ protected onSliceEnd(z: number | undefined): void;
47
+ private cancelReplot;
48
+ ngOnDestroy(): void;
38
49
  static ɵfac: i0.ɵɵFactoryDeclaration<StackControlsComponent, never>;
39
50
  static ɵcmp: i0.ɵɵComponentDeclaration<StackControlsComponent, "toolbar-stack-controls", never, { "liveScrubber": { "alias": "liveScrubber"; "required": false; }; "stackToggle": { "alias": "stackToggle"; "required": false; }; "showStack": { "alias": "showStack"; "required": false; }; "stackOptions": { "alias": "stackOptions"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "maxIndex": { "alias": "maxIndex"; "required": false; }; }, { "zScrub": "zScrub"; "zSlide": "zSlide"; "selectStackOption": "selectStackOption"; "zIndexInput": "zIndexInput"; "reloadAndPlot": "reloadAndPlot"; }, never, never, true, never>;
40
51
  }
@@ -52,6 +52,10 @@ export declare class ToolbarComponent {
52
52
  * controls — flipping that would show 2D pan/zoom and hide the orbit controls.
53
53
  */
54
54
  is3dRegions: boolean;
55
+ /** A napari volume / isosurface view: the Region Editor (regions in 3D) without drawing tools. */
56
+ isVolumeView: boolean;
57
+ /** Whether the volume view is split with the slice editor (the slice, with every region tool). */
58
+ sliceEditor: boolean;
55
59
  /** The armed tool's mode (zoom, pan, a drawing tool, `samPoint`, …), or null. */
56
60
  activeDragMode: string | null;
57
61
  /** The 3D camera mode (`turntable` / `orbit` / …). */
@@ -118,6 +122,8 @@ export declare class ToolbarComponent {
118
122
  openSpatialControls: EventEmitter<void>;
119
123
  /** Open the Region Editor dialog. */
120
124
  openRegionEditor: EventEmitter<void>;
125
+ /** Split the volume view with the slice editor, or close it. */
126
+ toggleSliceEditor: EventEmitter<void>;
121
127
  /** A single-image / stack choice was picked. */
122
128
  selectStackOption: EventEmitter<{
123
129
  name: string;
@@ -202,7 +208,8 @@ export declare class ToolbarComponent {
202
208
  * view, the napari-js WebGPU image, the napari-js surface — which rebuilds the height field
203
209
  * from the picked slice (jit-ui#102) — and the 2D spatial-omics view, where a 3D dataset's
204
210
  * registered volume is the image and the slider picks the section whose observations are
205
- * drawn. Drives the per-slice slider. */
211
+ * drawn. Also a split volume view, whose slice editor shows the slice picked. Drives the
212
+ * per-slice slider. */
206
213
  protected get showsLiveSliceScrubber(): boolean;
207
214
  /** Any napari-js WebGPU plot type. The single-image/stack toggle + slice-number field are
208
215
  * Plotly-only stack controls, so they're hidden for napari (jit-ui#102). */
@@ -218,5 +225,5 @@ export declare class ToolbarComponent {
218
225
  protected get isIntensityCapable(): boolean;
219
226
  protected showHelp(): void;
220
227
  static ɵfac: i0.ɵɵFactoryDeclaration<ToolbarComponent, never>;
221
- static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarComponent, "plotting-toolbar", never, { "imageInfo": { "alias": "imageInfo"; "required": false; }; "hasSpatialDataset": { "alias": "hasSpatialDataset"; "required": false; }; "plotTypeOptions": { "alias": "plotTypeOptions"; "required": false; }; "selectedPlotType": { "alias": "selectedPlotType"; "required": false; }; "basePlotType": { "alias": "basePlotType"; "required": false; }; "isoRange": { "alias": "isoRange"; "required": false; }; "maxIndex": { "alias": "maxIndex"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "isHeatmap": { "alias": "isHeatmap"; "required": false; }; "is3dRegions": { "alias": "is3dRegions"; "required": false; }; "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "activeSurface3dMode": { "alias": "activeSurface3dMode"; "required": false; }; "axesVisible": { "alias": "axesVisible"; "required": false; }; "wireframeActive": { "alias": "wireframeActive"; "required": false; }; "resolutionScale": { "alias": "resolutionScale"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; "stackOptions": { "alias": "stackOptions"; "required": false; }; "tools": { "alias": "tools"; "required": false; }; "imageSmoothingEnabled": { "alias": "imageSmoothingEnabled"; "required": false; }; "samModels": { "alias": "samModels"; "required": false; }; "samModelId": { "alias": "samModelId"; "required": false; }; "contributedTools": { "alias": "contributedTools"; "required": false; }; "dialogTools": { "alias": "dialogTools"; "required": false; }; "openDialogToolId": { "alias": "openDialogToolId"; "required": false; }; "toolModelIds": { "alias": "toolModelIds"; "required": false; }; }, { "selectPlotType": "selectPlotType"; "addProfileLine": "addProfileLine"; "toggleImageSmoothing": "toggleImageSmoothing"; "isoRangeChange": "isoRangeChange"; "openChannelHistogram": "openChannelHistogram"; "openSpatialControls": "openSpatialControls"; "openRegionEditor": "openRegionEditor"; "selectStackOption": "selectStackOption"; "zScrub": "zScrub"; "zSlide": "zSlide"; "zIndexInput": "zIndexInput"; "reloadAndPlot": "reloadAndPlot"; "downloadImage": "downloadImage"; "autoscaleImage": "autoscaleImage"; "toggleDragMode": "toggleDragMode"; "zoomIn": "zoomIn"; "zoomOut": "zoomOut"; "toggleSurface3dMode": "toggleSurface3dMode"; "resetSurfaceCamera": "resetSurfaceCamera"; "toggleAxes": "toggleAxes"; "toggleWireframe": "toggleWireframe"; "selectResolution": "selectResolution"; "deleteRegion": "deleteRegion"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "segmentRegions": "segmentRegions"; "segmentCellpose": "segmentCellpose"; "runTool": "runTool"; "toggleDialogTool": "toggleDialogTool"; "toolModelChange": "toolModelChange"; "openToolParams": "openToolParams"; "samModelChange": "samModelChange"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, ["*"], true, never>;
228
+ static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarComponent, "plotting-toolbar", never, { "imageInfo": { "alias": "imageInfo"; "required": false; }; "hasSpatialDataset": { "alias": "hasSpatialDataset"; "required": false; }; "plotTypeOptions": { "alias": "plotTypeOptions"; "required": false; }; "selectedPlotType": { "alias": "selectedPlotType"; "required": false; }; "basePlotType": { "alias": "basePlotType"; "required": false; }; "isoRange": { "alias": "isoRange"; "required": false; }; "maxIndex": { "alias": "maxIndex"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "isHeatmap": { "alias": "isHeatmap"; "required": false; }; "is3dRegions": { "alias": "is3dRegions"; "required": false; }; "isVolumeView": { "alias": "isVolumeView"; "required": false; }; "sliceEditor": { "alias": "sliceEditor"; "required": false; }; "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "activeSurface3dMode": { "alias": "activeSurface3dMode"; "required": false; }; "axesVisible": { "alias": "axesVisible"; "required": false; }; "wireframeActive": { "alias": "wireframeActive"; "required": false; }; "resolutionScale": { "alias": "resolutionScale"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; "stackOptions": { "alias": "stackOptions"; "required": false; }; "tools": { "alias": "tools"; "required": false; }; "imageSmoothingEnabled": { "alias": "imageSmoothingEnabled"; "required": false; }; "samModels": { "alias": "samModels"; "required": false; }; "samModelId": { "alias": "samModelId"; "required": false; }; "contributedTools": { "alias": "contributedTools"; "required": false; }; "dialogTools": { "alias": "dialogTools"; "required": false; }; "openDialogToolId": { "alias": "openDialogToolId"; "required": false; }; "toolModelIds": { "alias": "toolModelIds"; "required": false; }; }, { "selectPlotType": "selectPlotType"; "addProfileLine": "addProfileLine"; "toggleImageSmoothing": "toggleImageSmoothing"; "isoRangeChange": "isoRangeChange"; "openChannelHistogram": "openChannelHistogram"; "openSpatialControls": "openSpatialControls"; "openRegionEditor": "openRegionEditor"; "toggleSliceEditor": "toggleSliceEditor"; "selectStackOption": "selectStackOption"; "zScrub": "zScrub"; "zSlide": "zSlide"; "zIndexInput": "zIndexInput"; "reloadAndPlot": "reloadAndPlot"; "downloadImage": "downloadImage"; "autoscaleImage": "autoscaleImage"; "toggleDragMode": "toggleDragMode"; "zoomIn": "zoomIn"; "zoomOut": "zoomOut"; "toggleSurface3dMode": "toggleSurface3dMode"; "resetSurfaceCamera": "resetSurfaceCamera"; "toggleAxes": "toggleAxes"; "toggleWireframe": "toggleWireframe"; "selectResolution": "selectResolution"; "deleteRegion": "deleteRegion"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "segmentRegions": "segmentRegions"; "segmentCellpose": "segmentCellpose"; "runTool": "runTool"; "toggleDialogTool": "toggleDialogTool"; "toolModelChange": "toolModelChange"; "openToolParams": "openToolParams"; "samModelChange": "samModelChange"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, ["*"], true, never>;
222
229
  }
@@ -1,7 +1,18 @@
1
+ import type { HttpClient } from '@angular/common/http';
1
2
  import { IImageInfo } from '../contracts/image.contract';
2
3
  import { IRegionStore } from '../contracts/visualizer.contract';
3
- /** The region-store members {@link applyImageRois} writes through. */
4
- export type RegionLoadTarget = Pick<IRegionStore, 'importRegions' | 'enterStackMode' | 'setRegions' | 'resetUndoHistory'>;
4
+ import { RegionSource } from '../region-source/region-source';
5
+ import type { RegionSourceOpener, RegionSourceSlices } from '../store/region-source-scope';
6
+ /** The region-store members {@link applyImageRois} writes through. A target without
7
+ * `attachRegionSource` loads every ROI file as regions. */
8
+ export type RegionLoadTarget = Pick<IRegionStore, 'importRegions' | 'enterStackMode' | 'setRegions' | 'resetUndoHistory'> & {
9
+ attachRegionSource?(source: RegionSource | RegionSourceOpener, slices?: RegionSourceSlices): void;
10
+ /** The slice shown now (what a stack's source, laid out once it opens, makes live). */
11
+ getDisplaySlice?(): number;
12
+ /** Record the slice shown (outside stack mode it only records it): see {@link applyImageRois}. */
13
+ setDisplaySlice?(z: number): void;
14
+ isStackMode?(): boolean;
15
+ };
5
16
  /**
6
17
  * Apply an image's saved ROIs once its render has landed, choosing the region
7
18
  * layout from the image's shape:
@@ -22,6 +33,14 @@ export type RegionLoadTarget = Pick<IRegionStore, 'importRegions' | 'enterStackM
22
33
  * Loading saved ROIs is not a user edit, so the undo history starts fresh and the
23
34
  * first undo cannot wipe them (jit-ui#85).
24
35
  *
25
- * `z` is the slice shown now; entering stack mode makes it live and resets undo.
36
+ * Large ROI files (`minSourceChars` and up) and a server-side source (`regionSourceUrl`)
37
+ * become tiled region sources instead of regions; a z-indexed one serves each slice its own
38
+ * plane. On a single-file stack the source is opened first, to tell which: one on the default
39
+ * plane only stays global, as its regions would. A folder stack's sources open lazily, the first
40
+ * time their slice is shown.
41
+ *
42
+ * `z` is the slice shown now; entering stack mode makes it live and resets undo. `http`, the
43
+ * host's `HttpClient`, carries a server-side source's requests, so the host's interceptors (its
44
+ * auth) apply to them as to the image tiles.
26
45
  */
27
- export declare function applyImageRois(info: IImageInfo, target: RegionLoadTarget, z: number): void;
46
+ export declare function applyImageRois(info: IImageInfo, target: RegionLoadTarget, z: number, minSourceChars?: number, http?: HttpClient): void;