cloudmr-ux 4.7.6 → 4.7.7

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.
@@ -1051,6 +1051,67 @@ export default function CloudMrNiivueViewer(props) {
1051
1051
  nvSetDrawingEnabled(true);
1052
1052
  }
1053
1053
  }
1054
+ function deleteShapeDraftHandler() {
1055
+ var draft = shapeDraftRef.current;
1056
+ if (!(draft === null || draft === void 0 ? void 0 : draft.baseBitmap))
1057
+ return;
1058
+ // Clear tool-kind tags for voxels this shape occupied
1059
+ if (nv._cloudMrToolKindBitmap) {
1060
+ for (var i = 0; i < nv.drawBitmap.length; i++) {
1061
+ if (nv.drawBitmap[i] === draft.penValue && draft.baseBitmap[i] !== draft.penValue) {
1062
+ nv._cloudMrToolKindBitmap[i] = 0;
1063
+ }
1064
+ }
1065
+ }
1066
+ nv.drawBitmap.set(draft.baseBitmap);
1067
+ nv.refreshDrawing(true, false);
1068
+ nv.drawScene();
1069
+ nv.drawAddUndoBitmap(nv.drawFillOverwrites);
1070
+ setShapeDraft(null);
1071
+ shapeDraftRef.current = null;
1072
+ nv._cloudMrShapeDraftActive = false;
1073
+ setDrawingChanged(true);
1074
+ setDrawShapeTool(null);
1075
+ nv.opts.deferShapeCommit = false;
1076
+ nv.opts.penType = NI_PEN_TYPE.PEN;
1077
+ nvSetDrawingEnabled(false);
1078
+ resampleImage();
1079
+ }
1080
+ function deletePenDraftHandler() {
1081
+ var _a;
1082
+ var draft = penDraftRef.current;
1083
+ if (!(draft === null || draft === void 0 ? void 0 : draft.baseBitmap))
1084
+ return;
1085
+ // Clear tool-kind tags for voxels this ROI occupied
1086
+ if (nv._cloudMrToolKindBitmap) {
1087
+ for (var i = 0; i < nv.drawBitmap.length; i++) {
1088
+ if (nv.drawBitmap[i] === draft.penValue && draft.baseBitmap[i] !== draft.penValue) {
1089
+ nv._cloudMrToolKindBitmap[i] = 0;
1090
+ }
1091
+ }
1092
+ }
1093
+ nv.drawBitmap.set(draft.baseBitmap);
1094
+ nv.refreshDrawing(true, false);
1095
+ nv.drawScene();
1096
+ nv.drawAddUndoBitmap(nv.drawFillOverwrites);
1097
+ // Remove from polyline registry if this was a registered polyline
1098
+ if (draft._registryId != null && nv._cloudMrPolylineRegistry) {
1099
+ nv._cloudMrPolylineRegistry = nv._cloudMrPolylineRegistry.filter(function (e) { return e.id !== draft._registryId; });
1100
+ }
1101
+ if (draft.kind === "polyline") {
1102
+ (_a = nv.cloudMrResetPolyline) === null || _a === void 0 ? void 0 : _a.call(nv);
1103
+ setPolylineVertexCount(0);
1104
+ }
1105
+ setPenDraft(null);
1106
+ penDraftRef.current = null;
1107
+ nv._cloudMrPenDraftActive = false;
1108
+ setDrawingChanged(true);
1109
+ setDrawShapeTool(null);
1110
+ nv.opts.deferFreehandCommit = false;
1111
+ nv.opts.polylinePenMode = false;
1112
+ nvSetDrawingEnabled(false);
1113
+ resampleImage();
1114
+ }
1054
1115
  function ensureToolKindBitmap() {
1055
1116
  if (!nv.drawBitmap)
1056
1117
  return;
@@ -1692,6 +1753,8 @@ export default function CloudMrNiivueViewer(props) {
1692
1753
  onCancelPolyline: cancelPolylineDraft,
1693
1754
  onApplyPenDraft: applyPenDraftHandler,
1694
1755
  onCancelPenDraft: cancelPenDraftHandler,
1756
+ onDeletePenDraft: deletePenDraftHandler,
1757
+ onDeleteShapeDraft: deleteShapeDraftHandler,
1695
1758
  onFillPenDraft: fillPolylineDraftHandler,
1696
1759
  penDraftActive: penDraft != null,
1697
1760
  penDraftKind: penDraft === null || penDraft === void 0 ? void 0 : penDraft.kind,
@@ -1,4 +1,4 @@
1
- export default function DrawColorPlatte({ expanded, updateDrawPen, setDrawingEnabled, showPenModes, penDrawMode, onPenDrawModeChange, polylineVertexCount, penDraftActive, penDraftKind, penDraftFilled, onApplyPenDraft, onFillPenDraft, brushSize, updateBrushSize, shapeDraftActive, onApplyShapeDraft, }: {
1
+ export default function DrawColorPlatte({ expanded, updateDrawPen, setDrawingEnabled, showPenModes, penDrawMode, onPenDrawModeChange, polylineVertexCount, penDraftActive, penDraftKind, penDraftFilled, onApplyPenDraft, onDeletePenDraft, onFillPenDraft, brushSize, updateBrushSize, shapeDraftActive, onApplyShapeDraft, onDeleteShapeDraft, }: {
2
2
  expanded: any;
3
3
  updateDrawPen: any;
4
4
  setDrawingEnabled: any;
@@ -10,9 +10,11 @@ export default function DrawColorPlatte({ expanded, updateDrawPen, setDrawingEna
10
10
  penDraftKind: any;
11
11
  penDraftFilled?: boolean | undefined;
12
12
  onApplyPenDraft: any;
13
+ onDeletePenDraft: any;
13
14
  onFillPenDraft: any;
14
15
  brushSize?: number | undefined;
15
16
  updateBrushSize: any;
16
17
  shapeDraftActive?: boolean | undefined;
17
18
  onApplyShapeDraft: any;
19
+ onDeleteShapeDraft: any;
18
20
  }): import("react/jsx-runtime").JSX.Element;
@@ -16,6 +16,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
16
  import { Stack, IconButton, Button, Tooltip, Typography } from "@mui/material";
17
17
  import FiberManualRecordIcon from "@mui/icons-material/FiberManualRecord";
18
18
  import CheckIcon from "@mui/icons-material/Check";
19
+ import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
19
20
  import { BrushSizeSlider } from "./BrushSizeSlider";
20
21
  var FILLED_COLORS = [
21
22
  { sx: { color: "red" } },
@@ -36,7 +37,7 @@ var modeBtnSx = function (active) { return ({
36
37
  px: 0.75
37
38
  }); };
38
39
  export default function DrawColorPlatte(_a) {
39
- var expanded = _a.expanded, updateDrawPen = _a.updateDrawPen, setDrawingEnabled = _a.setDrawingEnabled, _b = _a.showPenModes, showPenModes = _b === void 0 ? false : _b, _c = _a.penDrawMode, penDrawMode = _c === void 0 ? "freehand" : _c, onPenDrawModeChange = _a.onPenDrawModeChange, _d = _a.polylineVertexCount, polylineVertexCount = _d === void 0 ? 0 : _d, _e = _a.penDraftActive, penDraftActive = _e === void 0 ? false : _e, penDraftKind = _a.penDraftKind, _f = _a.penDraftFilled, penDraftFilled = _f === void 0 ? false : _f, onApplyPenDraft = _a.onApplyPenDraft, onFillPenDraft = _a.onFillPenDraft, _g = _a.brushSize, brushSize = _g === void 0 ? 1 : _g, updateBrushSize = _a.updateBrushSize, _h = _a.shapeDraftActive, shapeDraftActive = _h === void 0 ? false : _h, onApplyShapeDraft = _a.onApplyShapeDraft;
40
+ var expanded = _a.expanded, updateDrawPen = _a.updateDrawPen, setDrawingEnabled = _a.setDrawingEnabled, _b = _a.showPenModes, showPenModes = _b === void 0 ? false : _b, _c = _a.penDrawMode, penDrawMode = _c === void 0 ? "freehand" : _c, onPenDrawModeChange = _a.onPenDrawModeChange, _d = _a.polylineVertexCount, polylineVertexCount = _d === void 0 ? 0 : _d, _e = _a.penDraftActive, penDraftActive = _e === void 0 ? false : _e, penDraftKind = _a.penDraftKind, _f = _a.penDraftFilled, penDraftFilled = _f === void 0 ? false : _f, onApplyPenDraft = _a.onApplyPenDraft, onDeletePenDraft = _a.onDeletePenDraft, onFillPenDraft = _a.onFillPenDraft, _g = _a.brushSize, brushSize = _g === void 0 ? 1 : _g, updateBrushSize = _a.updateBrushSize, _h = _a.shapeDraftActive, shapeDraftActive = _h === void 0 ? false : _h, onApplyShapeDraft = _a.onApplyShapeDraft, onDeleteShapeDraft = _a.onDeleteShapeDraft;
40
41
  return (_jsxs(Stack, __assign({ style: {
41
42
  position: "absolute",
42
43
  top: "100%",
@@ -56,30 +57,38 @@ export default function DrawColorPlatte(_a) {
56
57
  } }, { children: _jsx(FiberManualRecordIcon, { sx: color.sx }) }), index)); }) })), showPenModes && penDrawMode === "polyline" && expanded && polylineVertexCount === 0 && (_jsx(Typography, __assign({ sx: { px: 1, pb: 0.5, fontSize: "0.68rem", color: "#aaa", userSelect: "none" } }, { children: "Click each vertex to draw connected line segments" }))), showPenModes &&
57
58
  penDraftActive &&
58
59
  (penDrawMode === "polyline" || penDraftKind === "freehand") &&
59
- expanded && (_jsxs(Stack, __assign({ direction: "row", alignItems: "center", justifyContent: "flex-end", spacing: 1, sx: { px: 1, py: 0.5, borderTop: "1px solid #555", width: "100%" } }, { children: [penDrawMode === "polyline" && polylineVertexCount >= 3 && (_jsx(Tooltip, __assign({ title: penDraftFilled
60
- ? "Remove fill (keeps outline editable)"
61
- : "Fill interior (keeps outline editable until Apply)" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": penDraftFilled ? "undo fill polyline" : "fill polyline", onClick: function () { return onFillPenDraft === null || onFillPenDraft === void 0 ? void 0 : onFillPenDraft(); }, sx: {
62
- color: penDraftFilled ? "#ffb74d" : "#c9a0e8",
63
- fontSize: ACTION_FONT_SIZE,
64
- textTransform: "none",
65
- minWidth: 0,
66
- py: 0.25,
67
- px: 0.75
68
- } }, { children: penDraftFilled ? "Undo Fill" : "Fill" })) }))), _jsx(Tooltip, __assign({ title: "Apply shape (enter or right-click)" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": "apply pen draft", onClick: function () { return onApplyPenDraft === null || onApplyPenDraft === void 0 ? void 0 : onApplyPenDraft(); }, startIcon: _jsx(CheckIcon, { sx: { fontSize: ACTION_ICON_SIZE } }), sx: {
69
- color: "#c9a0e8",
60
+ expanded && (_jsxs(Stack, __assign({ direction: "row", alignItems: "center", justifyContent: "space-between", sx: { px: 1, py: 0.5, borderTop: "1px solid #555", width: "100%" } }, { children: [_jsx(Tooltip, __assign({ title: "Delete this ROI drawing" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": "delete pen draft", onClick: function () { return onDeletePenDraft === null || onDeletePenDraft === void 0 ? void 0 : onDeletePenDraft(); }, startIcon: _jsx(DeleteOutlineIcon, { sx: { fontSize: ACTION_ICON_SIZE } }), sx: {
61
+ color: "#f44336",
70
62
  fontSize: ACTION_FONT_SIZE,
71
63
  textTransform: "none",
72
64
  minWidth: 0,
73
65
  py: 0.25,
74
66
  px: 0.75,
75
67
  "& .MuiButton-startIcon": { mr: 0.5, ml: 0 }
76
- } }, { children: "Apply" })) }))] }))), shapeDraftActive && expanded && (_jsx(Stack, __assign({ direction: "row", alignItems: "center", justifyContent: "flex-end", sx: { px: 1, py: 0.5, borderTop: "1px solid #555", width: "100%" } }, { children: _jsx(Tooltip, __assign({ title: "Apply shape (enter or right-click)" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": "apply shape", onClick: function () { return onApplyShapeDraft === null || onApplyShapeDraft === void 0 ? void 0 : onApplyShapeDraft(); }, startIcon: _jsx(CheckIcon, { sx: { fontSize: ACTION_ICON_SIZE } }), sx: {
77
- color: "#c9a0e8",
68
+ } }, { children: "Delete" })) })), _jsxs(Stack, __assign({ direction: "row", spacing: 1, alignItems: "center" }, { children: [penDrawMode === "polyline" && polylineVertexCount >= 3 && (_jsx(Tooltip, __assign({ title: penDraftFilled
69
+ ? "Remove fill (keeps outline editable)"
70
+ : "Fill interior (keeps outline editable until Apply)" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": penDraftFilled ? "undo fill polyline" : "fill polyline", onClick: function () { return onFillPenDraft === null || onFillPenDraft === void 0 ? void 0 : onFillPenDraft(); }, sx: {
71
+ color: penDraftFilled ? "#ffb74d" : "#c9a0e8",
72
+ fontSize: ACTION_FONT_SIZE,
73
+ textTransform: "none",
74
+ minWidth: 0,
75
+ py: 0.25,
76
+ px: 0.75
77
+ } }, { children: penDraftFilled ? "Undo Fill" : "Fill" })) }))), penDrawMode === "polyline" && (_jsx(Tooltip, __assign({ title: "Apply polyline (Enter or right-click)" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": "apply pen draft", onClick: function () { return onApplyPenDraft === null || onApplyPenDraft === void 0 ? void 0 : onApplyPenDraft(); }, startIcon: _jsx(CheckIcon, { sx: { fontSize: ACTION_ICON_SIZE } }), sx: {
78
+ color: "#c9a0e8",
79
+ fontSize: ACTION_FONT_SIZE,
80
+ textTransform: "none",
81
+ minWidth: 0,
82
+ py: 0.25,
83
+ px: 0.75,
84
+ "& .MuiButton-startIcon": { mr: 0.5, ml: 0 }
85
+ } }, { children: "Apply" })) })))] }))] }))), shapeDraftActive && expanded && (_jsx(Stack, __assign({ direction: "row", alignItems: "center", justifyContent: "flex-start", sx: { px: 1, py: 0.5, borderTop: "1px solid #555", width: "100%" } }, { children: _jsx(Tooltip, __assign({ title: "Delete this ROI drawing" }, { children: _jsx(Button, __assign({ size: "small", "aria-label": "delete shape draft", onClick: function () { return onDeleteShapeDraft === null || onDeleteShapeDraft === void 0 ? void 0 : onDeleteShapeDraft(); }, startIcon: _jsx(DeleteOutlineIcon, { sx: { fontSize: ACTION_ICON_SIZE } }), sx: {
86
+ color: "#f44336",
78
87
  fontSize: ACTION_FONT_SIZE,
79
88
  textTransform: "none",
80
89
  minWidth: 0,
81
90
  py: 0.25,
82
91
  px: 0.75,
83
92
  "& .MuiButton-startIcon": { mr: 0.5, ml: 0 }
84
- } }, { children: "Apply" })) })) })))] })));
93
+ } }, { children: "Delete" })) })) })))] })));
85
94
  }
@@ -189,7 +189,7 @@ export function MroDrawToolkit(props) {
189
189
  alignItems: "center",
190
190
  gap: 4,
191
191
  overflow: "visible"
192
- } }, { children: [_jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "d" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Pen" }, { children: _jsx(IconButton, __assign({ "aria-label": "pen", size: "small", onClick: clickPen, sx: __assign(__assign({}, toolBtnSx), shapeSelectedSx("pen")) }, { children: _jsx(DrawIcon, { sx: { color: "inherit" } }) })) })), _jsx(DrawColorPlatte, { expanded: expandedOption === "d", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, showPenModes: true, penDrawMode: props.penDrawMode, onPenDrawModeChange: props.onPenDrawModeChange, polylineVertexCount: props.polylineVertexCount, onCancelPolyline: props.onCancelPolyline, penDraftActive: props.penDraftActive, penDraftKind: props.penDraftKind, penDraftFilled: props.penDraftFilled, onApplyPenDraft: props.onApplyPenDraft, onFillPenDraft: props.onFillPenDraft, brushSize: props.brushSize, updateBrushSize: props.updateBrushSize })] })), _jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "r" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Rectangle" }, { children: _jsx(IconButton, __assign({ "aria-label": "rectangle", size: "small", onClick: clickRectangle, sx: __assign(__assign({}, toolBtnSx), shapeSelectedSx("rectangle")) }, { children: _jsx(CropSquareOutlinedIcon, { sx: { color: "inherit" } }) })) })), _jsx(DrawColorPlatte, { expanded: expandedOption === "r", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, shapeDraftActive: props.shapeDraftActive && drawShapeTool === "rectangle", onApplyShapeDraft: props.onApplyShapeDraft })] })), _jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "l" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Ellipse" }, { children: _jsx(IconButton, __assign({ "aria-label": "ellipse", size: "small", onClick: clickEllipse, sx: __assign(__assign({}, toolBtnSx), shapeSelectedSx("ellipse")) }, { children: _jsx(CircleOutlinedIcon, { sx: { color: "inherit" } }) })) })), _jsx(DrawColorPlatte, { expanded: expandedOption === "l", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, shapeDraftActive: props.shapeDraftActive && drawShapeTool === "ellipse", onApplyShapeDraft: props.onApplyShapeDraft })] })), _jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "e" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Eraser" }, { children: _jsx(IconButton, __assign({ "aria-label": "erase", size: "small", onClick: clickEraser, sx: __assign(__assign({}, toolBtnSx), (eraserActive
192
+ } }, { children: [_jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "d" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Pen" }, { children: _jsx(IconButton, __assign({ "aria-label": "pen", size: "small", onClick: clickPen, sx: __assign(__assign({}, toolBtnSx), shapeSelectedSx("pen")) }, { children: _jsx(DrawIcon, { sx: { color: "inherit" } }) })) })), _jsx(DrawColorPlatte, { expanded: expandedOption === "d", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, showPenModes: true, penDrawMode: props.penDrawMode, onPenDrawModeChange: props.onPenDrawModeChange, polylineVertexCount: props.polylineVertexCount, onCancelPolyline: props.onCancelPolyline, penDraftActive: props.penDraftActive, penDraftKind: props.penDraftKind, penDraftFilled: props.penDraftFilled, onApplyPenDraft: props.onApplyPenDraft, onDeletePenDraft: props.onDeletePenDraft, onFillPenDraft: props.onFillPenDraft, brushSize: props.brushSize, updateBrushSize: props.updateBrushSize })] })), _jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "r" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Rectangle" }, { children: _jsx(IconButton, __assign({ "aria-label": "rectangle", size: "small", onClick: clickRectangle, sx: __assign(__assign({}, toolBtnSx), shapeSelectedSx("rectangle")) }, { children: _jsx(CropSquareOutlinedIcon, { sx: { color: "inherit" } }) })) })), _jsx(DrawColorPlatte, { expanded: expandedOption === "r", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, shapeDraftActive: props.shapeDraftActive && drawShapeTool === "rectangle", onApplyShapeDraft: props.onApplyShapeDraft, onDeleteShapeDraft: props.onDeleteShapeDraft })] })), _jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "l" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Ellipse" }, { children: _jsx(IconButton, __assign({ "aria-label": "ellipse", size: "small", onClick: clickEllipse, sx: __assign(__assign({}, toolBtnSx), shapeSelectedSx("ellipse")) }, { children: _jsx(CircleOutlinedIcon, { sx: { color: "inherit" } }) })) })), _jsx(DrawColorPlatte, { expanded: expandedOption === "l", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, shapeDraftActive: props.shapeDraftActive && drawShapeTool === "ellipse", onApplyShapeDraft: props.onApplyShapeDraft, onDeleteShapeDraft: props.onDeleteShapeDraft })] })), _jsxs(Box, __assign({ sx: { position: "relative", zIndex: expandedOption === "e" ? 1600 : "auto", display: "inline-flex", alignItems: "center" } }, { children: [_jsx(Tooltip, __assign({ title: "Eraser" }, { children: _jsx(IconButton, __assign({ "aria-label": "erase", size: "small", onClick: clickEraser, sx: __assign(__assign({}, toolBtnSx), (eraserActive
193
193
  ? { backgroundColor: "rgba(88, 15, 139, 0.12)", color: "#580f8b" }
194
194
  : {})) }, { children: filled || !eraserActive ? (_jsx(EraserIcon, {})) : (_jsx(AutoFixNormalOutlinedIcon, { sx: { color: ICON_COLOR } })) })) })), _jsx(EraserPlatte, { expandEraseOptions: expandedOption === "e", updateDrawPen: props.updateDrawPen, setDrawingEnabled: props.setDrawingEnabled, brushSize: props.brushSize, updateBrushSize: props.updateBrushSize })] })), _jsx(Tooltip, __assign({ title: "Undo" }, { children: _jsx(IconButton, __assign({ "aria-label": "revert", size: "small", onClick: function () { return props.drawUndo(); }, sx: toolBtnSx }, { children: _jsx(ReplyIcon, { sx: { color: ICON_COLOR } }) })) })), _jsx(Tooltip, __assign({ title: "Save screenshot" }, { children: _jsx("span", { children: _jsx(IconButton, __assign({ "aria-label": "capture", size: "small", disabled: !vol, onClick: function () { return vol && props.nv.saveScene("".concat(vol.name, "_drawing.png")); }, sx: toolBtnSx }, { children: _jsx(CameraAltIcon, { sx: { color: ICON_COLOR } }) })) }) })), _jsx(Tooltip, __assign({ title: "Clear drawing" }, { children: _jsx(IconButton, __assign({ "aria-label": "delete", size: "small", onClick: function () {
195
195
  var _a;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudmr-ux",
3
- "version": "4.7.6",
3
+ "version": "4.7.7",
4
4
  "author": "erosmontin@gmail.com",
5
5
  "license": "MIT",
6
6
  "repository": "erosmontin/cloudmr-ux",