@vitessce/neuroglancer 3.9.6 → 4.0.0-test.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.
- package/dist/{ReactNeuroglancer-BSLfuCt9.js → ReactNeuroglancer-Bg6f79hO.js} +193 -200
- package/dist/{index-DvhFVdN_.js → index-DZhbMDug.js} +274 -3036
- package/dist/index.js +1 -1
- package/dist-tsc/Neuroglancer.d.ts +1 -3
- package/dist-tsc/Neuroglancer.d.ts.map +1 -1
- package/dist-tsc/Neuroglancer.js +4 -26
- package/dist-tsc/NeuroglancerSubscriber.d.ts +1 -1
- package/dist-tsc/NeuroglancerSubscriber.d.ts.map +1 -1
- package/dist-tsc/NeuroglancerSubscriber.js +4 -1
- package/dist-tsc/ReactNeuroglancer.d.ts +1 -1
- package/dist-tsc/ReactNeuroglancer.d.ts.map +1 -1
- package/package.json +20 -12
- package/src/Neuroglancer.js +7 -26
- package/src/NeuroglancerSubscriber.js +5 -0
package/dist/index.js
CHANGED
|
@@ -3,8 +3,6 @@ export class NeuroglancerComp {
|
|
|
3
3
|
bundleRoot: any;
|
|
4
4
|
cellColorMapping: any;
|
|
5
5
|
justReceivedExternalUpdate: boolean;
|
|
6
|
-
prevElement: any;
|
|
7
|
-
prevClickHandler: ((event: any) => void) | null;
|
|
8
6
|
prevMouseStateChanged: any;
|
|
9
7
|
prevHoverHandler: (() => void) | null;
|
|
10
8
|
onViewerStateChanged(nextState: any): void;
|
|
@@ -12,6 +10,6 @@ export class NeuroglancerComp {
|
|
|
12
10
|
latestOnSegmentClick: any;
|
|
13
11
|
latestOnSelectHoveredCoords: any;
|
|
14
12
|
componentDidUpdate(prevProps: any): void;
|
|
15
|
-
render():
|
|
13
|
+
render(): any;
|
|
16
14
|
}
|
|
17
15
|
//# sourceMappingURL=Neuroglancer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Neuroglancer.d.ts","sourceRoot":"","sources":["../src/Neuroglancer.js"],"names":[],"mappings":"AAUA;IACE,
|
|
1
|
+
{"version":3,"file":"Neuroglancer.d.ts","sourceRoot":"","sources":["../src/Neuroglancer.js"],"names":[],"mappings":"AAUA;IACE,wBAYC;IAVC,gBAAgC;IAChC,sBAA8C;IAC9C,oCAAuC;IACvC,2BAAiC;IACjC,sCAA4B;IAwC9B,2CAGC;IAnCD,4BA8BC;IAlCC,0BAAgD;IAChD,iCAA8D;IAwChE,yCAKC;IAED,cAoBC;CACF"}
|
package/dist-tsc/Neuroglancer.js
CHANGED
|
@@ -13,8 +13,6 @@ export class NeuroglancerComp extends PureComponent {
|
|
|
13
13
|
this.bundleRoot = createWorker();
|
|
14
14
|
this.cellColorMapping = props.cellColorMapping;
|
|
15
15
|
this.justReceivedExternalUpdate = false;
|
|
16
|
-
this.prevElement = null;
|
|
17
|
-
this.prevClickHandler = null;
|
|
18
16
|
this.prevMouseStateChanged = null;
|
|
19
17
|
this.prevHoverHandler = null;
|
|
20
18
|
this.onViewerStateChanged = this.onViewerStateChanged.bind(this);
|
|
@@ -29,42 +27,25 @@ export class NeuroglancerComp extends PureComponent {
|
|
|
29
27
|
if (viewerRef) {
|
|
30
28
|
// Mount
|
|
31
29
|
const { viewer } = viewerRef;
|
|
32
|
-
this.prevElement = viewer.element;
|
|
33
30
|
this.prevMouseStateChanged = viewer.mouseState.changed;
|
|
34
31
|
viewer.inputEventBindings.sliceView.set('at:dblclick0', () => { });
|
|
35
32
|
viewer.inputEventBindings.perspectiveView.set('at:dblclick0', () => { });
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
requestAnimationFrame(() => {
|
|
40
|
-
const { pickedValue, pickedRenderLayer } = viewer.mouseState;
|
|
41
|
-
// Only trigger selection when a segment is clicked rather than any click on the view
|
|
42
|
-
if (pickedValue && pickedValue.low !== undefined && pickedRenderLayer) {
|
|
43
|
-
this.latestOnSegmentClick?.(pickedValue.low);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
};
|
|
33
|
+
// To disable space interaction causing 4panels layout
|
|
34
|
+
viewer.inputEventBindings.sliceView.set('at:space', () => { });
|
|
35
|
+
viewer.inputEventBindings.perspectiveView.set('at:space', () => { });
|
|
48
36
|
this.prevHoverHandler = () => {
|
|
49
37
|
if (viewer.mouseState.pickedValue !== undefined) {
|
|
50
38
|
const pickedSegment = viewer.mouseState.pickedValue;
|
|
51
39
|
this.latestOnSelectHoveredCoords?.(pickedSegment?.low);
|
|
52
40
|
}
|
|
53
41
|
};
|
|
54
|
-
viewer.element.addEventListener('mouseup', this.prevClickHandler);
|
|
55
42
|
viewer.mouseState.changed.add(this.prevHoverHandler);
|
|
56
43
|
}
|
|
57
44
|
else {
|
|
58
|
-
// Unmount (viewerRef is null)
|
|
59
|
-
if (this.prevElement && this.prevClickHandler) {
|
|
60
|
-
this.prevElement.removeEventListener('mouseup', this.prevClickHandler);
|
|
61
|
-
this.prevClickHandler = null;
|
|
62
|
-
}
|
|
63
45
|
if (this.prevMouseStateChanged && this.prevHoverHandler) {
|
|
64
46
|
this.prevMouseStateChanged.remove(this.prevHoverHandler);
|
|
65
47
|
this.prevHoverHandler = null;
|
|
66
48
|
}
|
|
67
|
-
this.prevElement = null;
|
|
68
49
|
this.prevMouseStateChanged = null;
|
|
69
50
|
}
|
|
70
51
|
}
|
|
@@ -73,10 +54,7 @@ export class NeuroglancerComp extends PureComponent {
|
|
|
73
54
|
setViewerState(nextState);
|
|
74
55
|
}
|
|
75
56
|
componentDidUpdate(prevProps) {
|
|
76
|
-
const {
|
|
77
|
-
if (prevProps.onSegmentClick !== onSegmentClick) {
|
|
78
|
-
this.latestOnSegmentClick = onSegmentClick;
|
|
79
|
-
}
|
|
57
|
+
const { onSelectHoveredCoords } = this.props;
|
|
80
58
|
if (prevProps.onSelectHoveredCoords !== onSelectHoveredCoords) {
|
|
81
59
|
this.latestOnSelectHoveredCoords = onSelectHoveredCoords;
|
|
82
60
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export function NeuroglancerSubscriber(props: any):
|
|
1
|
+
export function NeuroglancerSubscriber(props: any): any;
|
|
2
2
|
//# sourceMappingURL=NeuroglancerSubscriber.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NeuroglancerSubscriber.d.ts","sourceRoot":"","sources":["../src/NeuroglancerSubscriber.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NeuroglancerSubscriber.d.ts","sourceRoot":"","sources":["../src/NeuroglancerSubscriber.js"],"names":[],"mappings":"AAwEA,wDA0sBC"}
|
|
@@ -17,6 +17,7 @@ const ZOOM_EPS = 1e-2;
|
|
|
17
17
|
const ROTATION_EPS = 1e-3;
|
|
18
18
|
const TARGET_EPS = 0.5;
|
|
19
19
|
const NG_ROT_COOLDOWN_MS = 120;
|
|
20
|
+
const GUIDE_URL = 'https://vitessce.io/docs/ng-guide/';
|
|
20
21
|
const LAST_INTERACTION_SOURCE = {
|
|
21
22
|
vitessce: 'vitessce',
|
|
22
23
|
neuroglancer: 'neuroglancer',
|
|
@@ -324,6 +325,8 @@ export function NeuroglancerSubscriber(props) {
|
|
|
324
325
|
};
|
|
325
326
|
}, []);
|
|
326
327
|
const onSegmentClick = useCallback((value) => {
|
|
328
|
+
// Note: this callback is no longer called by the child component.
|
|
329
|
+
// Reference: https://github.com/vitessce/vitessce/pull/2439
|
|
327
330
|
if (value) {
|
|
328
331
|
const id = String(value);
|
|
329
332
|
const selectedCellIds = [id];
|
|
@@ -498,5 +501,5 @@ export function NeuroglancerSubscriber(props) {
|
|
|
498
501
|
// }
|
|
499
502
|
const hasLayers = derivedViewerState?.layers?.length > 0;
|
|
500
503
|
// console.log(derivedViewerState);
|
|
501
|
-
return (_jsx(TitleInfo, { title: title, info: subtitle, helpText: helpText, isSpatial: true, theme: theme, closeButtonVisible: closeButtonVisible, downloadButtonVisible: downloadButtonVisible, removeGridComponent: removeGridComponent, isReady: isReady, errors: errors, withPadding: false, children: _jsxs("div", { style: { position: 'relative', width: '100%', height: '100%' }, ref: containerRef, children: [_jsx("div", { style: { position: 'absolute', top: 0, right: 0, zIndex: 50 }, children: _jsx(MultiLegend, { theme: "dark", maxHeight: ngHeight, segmentationLayerScopes: segmentationLayerScopes, segmentationLayerCoordination: segmentationLayerCoordination, segmentationChannelScopesByLayer: segmentationChannelScopesByLayer, segmentationChannelCoordination: segmentationChannelCoordination }) }), hasLayers ? (_jsx(NeuroglancerComp, { classes: classes, onSegmentClick: onSegmentClick, onSelectHoveredCoords: onSegmentHighlight, viewerState: derivedViewerState, cellColorMapping: cellColorMapping, setViewerState: handleStateUpdate })) : null] }) }));
|
|
504
|
+
return (_jsx(TitleInfo, { title: title, info: subtitle, helpText: helpText, isSpatial: true, theme: theme, closeButtonVisible: closeButtonVisible, downloadButtonVisible: downloadButtonVisible, removeGridComponent: removeGridComponent, isReady: isReady, errors: errors, withPadding: false, guideUrl: GUIDE_URL, children: _jsxs("div", { style: { position: 'relative', width: '100%', height: '100%' }, ref: containerRef, children: [_jsx("div", { style: { position: 'absolute', top: 0, right: 0, zIndex: 50 }, children: _jsx(MultiLegend, { theme: "dark", maxHeight: ngHeight, segmentationLayerScopes: segmentationLayerScopes, segmentationLayerCoordination: segmentationLayerCoordination, segmentationChannelScopesByLayer: segmentationChannelScopesByLayer, segmentationChannelCoordination: segmentationChannelCoordination }) }), hasLayers ? (_jsx(NeuroglancerComp, { classes: classes, onSegmentClick: onSegmentClick, onSelectHoveredCoords: onSegmentHighlight, viewerState: derivedViewerState, cellColorMapping: cellColorMapping, setViewerState: handleStateUpdate })) : null] }) }));
|
|
502
505
|
}
|
|
@@ -97,7 +97,7 @@ export default class Neuroglancer {
|
|
|
97
97
|
handlerRemovers: any[] | undefined;
|
|
98
98
|
selectedChanged: (layer: any) => void;
|
|
99
99
|
visibleChanged: (layer: any) => void;
|
|
100
|
-
render():
|
|
100
|
+
render(): any;
|
|
101
101
|
}
|
|
102
102
|
export type NgProps = {
|
|
103
103
|
perspectiveZoom: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactNeuroglancer.d.ts","sourceRoot":"","sources":["../src/ReactNeuroglancer.js"],"names":[],"mappings":"AAiCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,4CAsBC;AAED,0DAGC;AAED,gEA2BC;AAED,kDAKC;AAED,+CAMC;AAED,0DAMC;AAED,6DAMC;AAED,8DAWC;AAED,+EAYC;AAED,yFAcC;AAED,+EA6BC;AAmFD,2FAwBC;AAED,kGAeC;AAED,gFAUC;AAED,uEA0BC;AAED,0CAA0C;AAC1C;IACE;;;;;;;;;;;;MAYE;IAEF,wBAYC;IAVC,iBAAoC;IACpC,YAAkB;IAElB,2BAA8B;IAC9B,yBAA+B;IAC/B,kBAAwB;IACxB,iBAAmB;IACnB,6BAAmC;IACnC,wBAA6C;IAC7C,sBAA4B;IAG9B;;;;MASE;IAGF,+BAWE;IAGF,mCAKE;IAGF,uDASE;IAGF,0DAgCE;IAEF,0BA+GC;IAED,yDAgIC;IAED,6BAUC;IAcD,mCAQC;IAED,0DAyCE;IAEF,yCAOE;IAEF,0BAsCE;IA5BI,mCAAyB;IA+B/B,sCAWE;IAEF,qCAUE;IAEF,
|
|
1
|
+
{"version":3,"file":"ReactNeuroglancer.d.ts","sourceRoot":"","sources":["../src/ReactNeuroglancer.js"],"names":[],"mappings":"AAiCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,4CAsBC;AAED,0DAGC;AAED,gEA2BC;AAED,kDAKC;AAED,+CAMC;AAED,0DAMC;AAED,6DAMC;AAED,8DAWC;AAED,+EAYC;AAED,yFAcC;AAED,+EA6BC;AAmFD,2FAwBC;AAED,kGAeC;AAED,gFAUC;AAED,uEA0BC;AAED,0CAA0C;AAC1C;IACE;;;;;;;;;;;;MAYE;IAEF,wBAYC;IAVC,iBAAoC;IACpC,YAAkB;IAElB,2BAA8B;IAC9B,yBAA+B;IAC/B,kBAAwB;IACxB,iBAAmB;IACnB,6BAAmC;IACnC,wBAA6C;IAC7C,sBAA4B;IAG9B;;;;MASE;IAGF,+BAWE;IAGF,mCAKE;IAGF,uDASE;IAGF,0DAgCE;IAEF,0BA+GC;IAED,yDAgIC;IAED,6BAUC;IAcD,mCAQC;IAED,0DAyCE;IAEF,yCAOE;IAEF,0BAsCE;IA5BI,mCAAyB;IA+B/B,sCAWE;IAEF,qCAUE;IAEF,cAOC;CACF;;qBAh3Ba,MAAM;iBACN,MAAM;uBACN,MAAM;SACN,MAAM;sBACN;YAAO,MAAM,GAAE,MAAM;KAAC;;;;;;;;;;;;;;;;;;;uBAWtB,CAAC,OAAO,EAAC,GAAG,GAAC,IAAI,EAAE,KAAK,EAAC,GAAG,KAAK,IAAI;;;;;;;;;sBAQrC,CAAC,QAAQ,EAAC,GAAG,EAAE,KAAK,EAAC,GAAG,KAAK,IAAI;;;;oCAQjC,MAAM,IAAI;0BAEV,MAAM,IAAI;;;;eAEV,KAAK,CAAC,MAAM,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitessce/neuroglancer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-test.0",
|
|
4
4
|
"author": "Gehlenborg Lab",
|
|
5
5
|
"homepage": "http://vitessce.io",
|
|
6
6
|
"repository": {
|
|
@@ -18,24 +18,32 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@janelia-flyem/neuroglancer": "2.37.5",
|
|
20
20
|
"lodash-es": "^4.17.21",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"@vitessce/
|
|
24
|
-
"@vitessce/
|
|
25
|
-
"@vitessce/
|
|
26
|
-
"@vitessce/utils": "
|
|
27
|
-
"@vitessce/
|
|
28
|
-
"@vitessce/
|
|
29
|
-
"@vitessce/
|
|
30
|
-
"@vitessce/legend": "3.9.6"
|
|
21
|
+
"react": "19.1.0",
|
|
22
|
+
"@vitessce/styles": "4.0.0-test.0",
|
|
23
|
+
"@vitessce/vit-s": "4.0.0-test.0",
|
|
24
|
+
"@vitessce/constants-internal": "4.0.0-test.0",
|
|
25
|
+
"@vitessce/sets-utils": "4.0.0-test.0",
|
|
26
|
+
"@vitessce/utils": "4.0.0-test.0",
|
|
27
|
+
"@vitessce/legend": "4.0.0-test.0",
|
|
28
|
+
"@vitessce/tooltip": "4.0.0-test.0",
|
|
29
|
+
"@vitessce/neuroglancer-workers": "4.0.0-test.0"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
32
|
"@testing-library/jest-dom": "^6.6.3",
|
|
34
33
|
"@testing-library/react": "^16.3.0",
|
|
35
|
-
"
|
|
34
|
+
"three": "^0.159.0",
|
|
35
|
+
"react-dom": "19.1.0",
|
|
36
36
|
"vite": "^7.0.0",
|
|
37
37
|
"vitest": "^3.1.4"
|
|
38
38
|
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"three": ">=0.159.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"three": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
39
47
|
"scripts": {
|
|
40
48
|
"bundle": "pnpm exec vite build -c ../../../scripts/vite.config.mjs",
|
|
41
49
|
"test": "pnpm exec vitest --run"
|
package/src/Neuroglancer.js
CHANGED
|
@@ -14,8 +14,6 @@ export class NeuroglancerComp extends PureComponent {
|
|
|
14
14
|
this.bundleRoot = createWorker();
|
|
15
15
|
this.cellColorMapping = props.cellColorMapping;
|
|
16
16
|
this.justReceivedExternalUpdate = false;
|
|
17
|
-
this.prevElement = null;
|
|
18
|
-
this.prevClickHandler = null;
|
|
19
17
|
this.prevMouseStateChanged = null;
|
|
20
18
|
this.prevHoverHandler = null;
|
|
21
19
|
this.onViewerStateChanged = this.onViewerStateChanged.bind(this);
|
|
@@ -32,41 +30,27 @@ export class NeuroglancerComp extends PureComponent {
|
|
|
32
30
|
if (viewerRef) {
|
|
33
31
|
// Mount
|
|
34
32
|
const { viewer } = viewerRef;
|
|
35
|
-
this.prevElement = viewer.element;
|
|
36
33
|
this.prevMouseStateChanged = viewer.mouseState.changed;
|
|
37
34
|
viewer.inputEventBindings.sliceView.set('at:dblclick0', () => {});
|
|
38
35
|
viewer.inputEventBindings.perspectiveView.set('at:dblclick0', () => {});
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// Only trigger selection when a segment is clicked rather than any click on the view
|
|
45
|
-
if (pickedValue && pickedValue.low !== undefined && pickedRenderLayer) {
|
|
46
|
-
this.latestOnSegmentClick?.(pickedValue.low);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
};
|
|
36
|
+
|
|
37
|
+
// To disable space interaction causing 4panels layout
|
|
38
|
+
viewer.inputEventBindings.sliceView.set('at:space', () => {});
|
|
39
|
+
viewer.inputEventBindings.perspectiveView.set('at:space', () => {});
|
|
40
|
+
|
|
51
41
|
this.prevHoverHandler = () => {
|
|
52
42
|
if (viewer.mouseState.pickedValue !== undefined) {
|
|
53
43
|
const pickedSegment = viewer.mouseState.pickedValue;
|
|
54
44
|
this.latestOnSelectHoveredCoords?.(pickedSegment?.low);
|
|
55
45
|
}
|
|
56
46
|
};
|
|
57
|
-
|
|
47
|
+
|
|
58
48
|
viewer.mouseState.changed.add(this.prevHoverHandler);
|
|
59
49
|
} else {
|
|
60
|
-
// Unmount (viewerRef is null)
|
|
61
|
-
if (this.prevElement && this.prevClickHandler) {
|
|
62
|
-
this.prevElement.removeEventListener('mouseup', this.prevClickHandler);
|
|
63
|
-
this.prevClickHandler = null;
|
|
64
|
-
}
|
|
65
50
|
if (this.prevMouseStateChanged && this.prevHoverHandler) {
|
|
66
51
|
this.prevMouseStateChanged.remove(this.prevHoverHandler);
|
|
67
52
|
this.prevHoverHandler = null;
|
|
68
53
|
}
|
|
69
|
-
this.prevElement = null;
|
|
70
54
|
this.prevMouseStateChanged = null;
|
|
71
55
|
}
|
|
72
56
|
}
|
|
@@ -77,10 +61,7 @@ export class NeuroglancerComp extends PureComponent {
|
|
|
77
61
|
}
|
|
78
62
|
|
|
79
63
|
componentDidUpdate(prevProps) {
|
|
80
|
-
const {
|
|
81
|
-
if (prevProps.onSegmentClick !== onSegmentClick) {
|
|
82
|
-
this.latestOnSegmentClick = onSegmentClick;
|
|
83
|
-
}
|
|
64
|
+
const { onSelectHoveredCoords } = this.props;
|
|
84
65
|
if (prevProps.onSelectHoveredCoords !== onSelectHoveredCoords) {
|
|
85
66
|
this.latestOnSelectHoveredCoords = onSelectHoveredCoords;
|
|
86
67
|
}
|
|
@@ -57,6 +57,8 @@ const ROTATION_EPS = 1e-3;
|
|
|
57
57
|
const TARGET_EPS = 0.5;
|
|
58
58
|
const NG_ROT_COOLDOWN_MS = 120;
|
|
59
59
|
|
|
60
|
+
const GUIDE_URL = 'https://vitessce.io/docs/ng-guide/';
|
|
61
|
+
|
|
60
62
|
const LAST_INTERACTION_SOURCE = {
|
|
61
63
|
vitessce: 'vitessce',
|
|
62
64
|
neuroglancer: 'neuroglancer',
|
|
@@ -512,6 +514,8 @@ export function NeuroglancerSubscriber(props) {
|
|
|
512
514
|
}, []);
|
|
513
515
|
|
|
514
516
|
const onSegmentClick = useCallback((value) => {
|
|
517
|
+
// Note: this callback is no longer called by the child component.
|
|
518
|
+
// Reference: https://github.com/vitessce/vitessce/pull/2439
|
|
515
519
|
if (value) {
|
|
516
520
|
const id = String(value);
|
|
517
521
|
const selectedCellIds = [id];
|
|
@@ -753,6 +757,7 @@ export function NeuroglancerSubscriber(props) {
|
|
|
753
757
|
isReady={isReady}
|
|
754
758
|
errors={errors}
|
|
755
759
|
withPadding={false}
|
|
760
|
+
guideUrl={GUIDE_URL}
|
|
756
761
|
>
|
|
757
762
|
<div style={{ position: 'relative', width: '100%', height: '100%' }} ref={containerRef}>
|
|
758
763
|
<div style={{ position: 'absolute', top: 0, right: 0, zIndex: 50 }}>
|