@topconsultnpm/sdkui-react-beta 6.14.82 → 6.14.83

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.
@@ -222,7 +222,7 @@ const TMBlogCommentForm = (props) => {
222
222
  // Update the state with selected draft items
223
223
  setCurrentDraftAttachments(selectedDraftItems);
224
224
  };
225
- return _jsx(TMSaveForm, { id: 1, title: SDKUI_Localizator.Comment, showErrorCount: false, showSaveButton: !showAttachmentsForm, showUndoButton: false, hasNavigation: false, skipIsModifiedCheck: true, isModal: true, width: calcResponsiveSizes(deviceType, '800px', '800px', '95%'), height: '550px', formMode: FormModes.Create, validationItems: validationItems, exception: exception, isModified: calcIsModified(formData, formDataOrig), onSaveAsync: onSaveAsync, onClose: onCloseCallback, customToolbarElements: _jsx("div", { style: { display: 'flex', gap: '2px' }, children: showAttachmentsForm === false && _jsx(TMButton, { btnStyle: "toolbar", icon: isEditorEnabled ? _jsx("i", { className: 'dx-icon-font' }) : _jsx("i", { className: 'dx-icon-background' }), caption: isEditorEnabled ? SDKUI_Localizator.HideFormattingOptions : SDKUI_Localizator.ShowFormattingOptions, onClick: toggleEditorMode }) }), children: _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx("div", { style: { width: "100%", height: showAttachmentsSection ? "calc(100% - 60px)" : "100%" }, children: _jsx(TMHtmlEditor, { width: '100%', height: '100%', isEditorEnabled: isEditorEnabled, validationItems: validationItems, onValueChanged: onValueChanged, mentionsConfig: mentionsConfig, autoFocus: true }) }), showAttachmentsSection && _jsxs("div", { style: { display: 'flex', alignItems: 'center', height: '60px', marginTop: '10px' }, children: [_jsx("div", { style: {
225
+ return _jsx(TMSaveForm, { id: 1, title: SDKUI_Localizator.AddNewComment, showTitleFormMode: false, showErrorCount: false, showSaveButton: !showAttachmentsForm, showUndoButton: false, hasNavigation: false, skipIsModifiedCheck: true, isModal: true, width: calcResponsiveSizes(deviceType, '800px', '800px', '95%'), height: '550px', formMode: FormModes.Create, validationItems: validationItems, exception: exception, isModified: calcIsModified(formData, formDataOrig), onSaveAsync: onSaveAsync, onClose: onCloseCallback, customToolbarElements: _jsx("div", { style: { display: 'flex', gap: '2px' }, children: _jsx(TMButton, { btnStyle: "toolbar", icon: isEditorEnabled ? _jsx("i", { className: 'dx-icon-font' }) : _jsx("i", { className: 'dx-icon-background' }), caption: isEditorEnabled ? SDKUI_Localizator.HideFormattingOptions : SDKUI_Localizator.ShowFormattingOptions, onClick: toggleEditorMode }) }), children: _jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsxs("div", { style: { width: "100%", height: "100%" }, children: [_jsx("div", { style: { width: "100%", height: showAttachmentsSection ? "calc(100% - 60px)" : "100%" }, children: _jsx(TMHtmlEditor, { width: '100%', height: '100%', isEditorEnabled: isEditorEnabled, validationItems: validationItems, onValueChanged: onValueChanged, mentionsConfig: mentionsConfig, autoFocus: true }) }), showAttachmentsSection && _jsxs("div", { style: { display: 'flex', alignItems: 'center', height: '60px', marginTop: '10px' }, children: [_jsx("div", { style: {
226
226
  width: 'calc(100% - 60px)',
227
227
  overflowX: 'auto',
228
228
  whiteSpace: 'nowrap',
@@ -11,7 +11,7 @@ import { TMColors } from '../../utils/theme';
11
11
  import TMValidationItemsList from '../grids/TMValidationItemsList';
12
12
  import TMModal from '../base/TMModal';
13
13
  import { DeviceType, useDeviceType } from '../base/TMDeviceProvider';
14
- const TMSaveForm = ({ id, formMode = FormModes.Update, showToolbar = true, skipIsModifiedCheck = false, title, children, isModal, exception, customToolbarElements, hasNavigation, showSaveButton = true, showBackButton, showWarningsCount = true, showErrorCount = true, showUndoButton = true, onClose, onSaveAsync, onNext, onPrev, canNext, canPrev, isModified, onShowList, validationItems = [], onUndo, onCancel, width, height, askClosingConfirm = false, showTitleFormMode = true }) => {
14
+ const TMSaveForm = ({ id, formMode = FormModes.Update, showToolbar = true, skipIsModifiedCheck = false, title, children, isModal, exception, customToolbarElements, hasNavigation, showSaveButton = true, customSaveButton, showBackButton, showWarningsCount = true, showErrorCount = true, showUndoButton = true, onClose, onSaveAsync, onNext, onPrev, canNext, canPrev, isModified, onShowList, validationItems = [], onUndo, onCancel, width, height, askClosingConfirm = false, showTitleFormMode = true }) => {
15
15
  const [showList, setShowList] = useState(true);
16
16
  const [showErrorGrid, setShowErrorGrid] = useState(false);
17
17
  const deviceType = useDeviceType();
@@ -93,7 +93,7 @@ const TMSaveForm = ({ id, formMode = FormModes.Update, showToolbar = true, skipI
93
93
  const warningsCount = validationItems.filter(o => o.ResultType == ResultTypes.WARNING).length;
94
94
  const errorsCount = validationItems.filter(o => o.ResultType == ResultTypes.ERROR).length;
95
95
  const renderSaveForm = () => {
96
- return (_jsxs(TMLayoutContainer, { direction: 'vertical', children: [showToolbar && _jsx(TMLayoutItem, { height: 'max-content', children: _jsxs(StyledToolbarForm, { children: [showBackButton && _jsx(TMButton, { btnStyle: 'toolbar', color: 'tertiary', caption: SDKUI_Localizator.Back, icon: _jsx(IconArrowLeft, {}), elementStyle: { marginRight: '10px' }, onClick: () => { doClose(); } }), showSaveButton && _jsx(TMButton, { caption: SDKUI_Localizator.Save, icon: _jsx(IconSave, {}), keyGesture: "alt+s", backgroundColor: errorsCount > 0 ? TMColors.error : isModified ? TMColors.success : TMColors.disabled, onClick: doSaveAsync, color: "success", btnStyle: "toolbar", disabled: !(isModified && errorsCount <= 0) }), hasNavigation && _jsx(TMButton, { caption: SDKUI_Localizator.Previous, icon: _jsx(IconArrowUp, {}), btnStyle: "toolbar", disabled: !canPrev || isModified || formMode == FormModes.Create || formMode == FormModes.Duplicate, onClick: doPrev }), hasNavigation && _jsx(TMButton, { caption: SDKUI_Localizator.Next, icon: _jsx(IconArrowDown, {}), btnStyle: "toolbar", disabled: !canNext || isModified || formMode == FormModes.Create || formMode == FormModes.Duplicate, onClick: doNext }), showUndoButton && _jsx(TMButton, { caption: SDKUI_Localizator.Undo, icon: _jsx(IconUndo, {}), keyGesture: "alt+z", color: "tertiary", btnStyle: "toolbar", disabled: isModified ? false : true, onClick: onUndo }), customToolbarElements, Boolean(showWarningsCount && warningsCount > 0) &&
96
+ return (_jsxs(TMLayoutContainer, { direction: 'vertical', children: [showToolbar && _jsx(TMLayoutItem, { height: 'max-content', children: _jsxs(StyledToolbarForm, { children: [showBackButton && _jsx(TMButton, { btnStyle: 'toolbar', color: 'tertiary', caption: SDKUI_Localizator.Back, icon: _jsx(IconArrowLeft, {}), elementStyle: { marginRight: '10px' }, onClick: () => { doClose(); } }), showSaveButton && _jsx(TMButton, { caption: SDKUI_Localizator.Save, icon: customSaveButton ?? _jsx(IconSave, {}), keyGesture: "alt+s", backgroundColor: errorsCount > 0 ? TMColors.error : isModified ? TMColors.success : TMColors.disabled, onClick: doSaveAsync, color: "success", btnStyle: "toolbar", disabled: !(isModified && errorsCount <= 0) }), hasNavigation && _jsx(TMButton, { caption: SDKUI_Localizator.Previous, icon: _jsx(IconArrowUp, {}), btnStyle: "toolbar", disabled: !canPrev || isModified || formMode == FormModes.Create || formMode == FormModes.Duplicate, onClick: doPrev }), hasNavigation && _jsx(TMButton, { caption: SDKUI_Localizator.Next, icon: _jsx(IconArrowDown, {}), btnStyle: "toolbar", disabled: !canNext || isModified || formMode == FormModes.Create || formMode == FormModes.Duplicate, onClick: doNext }), showUndoButton && _jsx(TMButton, { caption: SDKUI_Localizator.Undo, icon: _jsx(IconUndo, {}), keyGesture: "alt+z", color: "tertiary", btnStyle: "toolbar", disabled: isModified ? false : true, onClick: onUndo }), customToolbarElements, Boolean(showWarningsCount && warningsCount > 0) &&
97
97
  _jsx(TMLayoutItem, { width: 'fit-content', height: '90%', children: _jsxs(StyledResultTypeContainer, { style: { marginLeft: '10px' }, onClick: () => setShowErrorGrid(!showErrorGrid), "$resultType": ResultTypes.WARNING, children: [" ", _jsx(IconWarning, { fontSize: 16 }), " ", _jsx("span", { children: warningsCount })] }) }), Boolean(showErrorCount && errorsCount > 0) &&
98
98
  _jsx(TMLayoutItem, { width: 'fit-content', height: '90%', children: _jsxs(StyledResultTypeContainer, { style: { marginLeft: warningsCount <= 0 ? '10px' : '0' }, onClick: () => setShowErrorGrid(!showErrorGrid), "$resultType": ResultTypes.ERROR, children: [" ", _jsx(IconCloseCircle, { fontSize: 16 }), " ", _jsx("span", { children: errorsCount })] }) }), onShowList &&
99
99
  _jsx("div", { style: { right: '10px', position: 'absolute' }, children: deviceType !== DeviceType.MOBILE && _jsx(TMButton, { caption: showList ? SDKUI_Localizator.List_Hide : SDKUI_Localizator.List_Show, icon: showList ? _jsx(IconHide, {}) : _jsx(IconShow, {}), keyGesture: "alt+h", onClick: () => { setShowList(!showList); onShowList?.(!showList); }, btnStyle: 'toolbar' }) }), (formMode == FormModes.Create || formMode == FormModes.Duplicate) &&
@@ -89,6 +89,8 @@ interface TMBlogsProps {
89
89
  context?: TMBlogContextDescriptor;
90
90
  /** Optional layout mode */
91
91
  layoutMode?: 'stacked' | 'chat';
92
+ /** Optional callback to mark blog as read */
93
+ markBlogAsRead?: (blog: BlogPost | undefined) => Promise<void>;
92
94
  }
93
95
  declare const TMBlogs: (props: TMBlogsProps) => import("react/jsx-runtime").JSX.Element;
94
96
  export default TMBlogs;
@@ -30,7 +30,7 @@ const TMBlogs = (props) => {
30
30
  isRestoreEnabled: false,
31
31
  isRefreshEnabled: false,
32
32
  isCreateContextualTask: false,
33
- }, refreshCallback, newPosts = [], showCommentFormCallback, showTaskFormCallback, showContextMenu = true, handleAttachmentFocus, showFloatingCommentButton = false, context, layoutMode = 'stacked' } = props;
33
+ }, refreshCallback, newPosts = [], showCommentFormCallback, showTaskFormCallback, showContextMenu = true, handleAttachmentFocus, showFloatingCommentButton = false, context, layoutMode = 'stacked', markBlogAsRead } = props;
34
34
  // Get the current device type (e.g., mobile, tablet, desktop) using a custom hook.
35
35
  const deviceType = useDeviceType();
36
36
  const { abortController, showWaitPanel, waitPanelTitle, showPrimary, waitPanelTextPrimary, waitPanelValuePrimary, waitPanelMaxValuePrimary, showSecondary, waitPanelTextSecondary, waitPanelValueSecondary, waitPanelMaxValueSecondary, downloadDcmtsAsync } = useDcmtOperations();
@@ -38,6 +38,7 @@ const TMBlogs = (props) => {
38
38
  let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
39
39
  // State to store an array of blog posts, which can be either BlogPost or HomeBlogPost type
40
40
  const [blogPosts, setBlogPosts] = useState([]);
41
+ const [firstNewPost, setFirstNewPost] = useState(undefined);
41
42
  // State to manage the data source for a tree component
42
43
  const [treeDataSource, setTreeDataSource] = useState([]);
43
44
  // State to store the user's search input for filtering or searching posts/messages
@@ -61,11 +62,6 @@ const TMBlogs = (props) => {
61
62
  const [isHeaderHidden, setIsHeaderHidden] = useState(isHeaderFullyHidden(currentHeader));
62
63
  // showId is a state variable that determines whether an ID-related component or feature should be displayed
63
64
  const [localShowId, setLocalShowId] = useState(false);
64
- // State variable to track the new posts
65
- const [newPostIds, setNewPostIds] = useState(new Set());
66
- const firstNewPostIndex = useMemo(() => {
67
- return blogPosts.findIndex(post => post.id !== undefined && newPostIds.has(post.id));
68
- }, [blogPosts, newPostIds]);
69
65
  // Ref to the container
70
66
  const containerRef = useRef(null);
71
67
  // State variable to control the visibility of the wait panel.
@@ -180,6 +176,8 @@ const TMBlogs = (props) => {
180
176
  setFocusedAttachment(undefined);
181
177
  if (handleAttachmentFocus)
182
178
  handleAttachmentFocus(undefined);
179
+ if (markBlogAsRead)
180
+ markBlogAsRead(blog);
183
181
  };
184
182
  const refresh = () => {
185
183
  if (refreshCallback)
@@ -290,24 +288,6 @@ const TMBlogs = (props) => {
290
288
  ];
291
289
  return menuItemsElements;
292
290
  }, [isHeaderHidden, localShowId, setLocalShowId, focusedBlog, focusedAttachment, showDcmtForm]);
293
- useEffect(() => {
294
- // Check if context exists, the engine is 'WorkingGroupEngine',
295
- if (context && context.engine === 'WorkingGroupEngine' && context.object && context.object.id) {
296
- // Find the number of new posts for the active working group
297
- const newPostsCount = newPosts?.find(d => d.id === context.object?.id)?.count ?? 0;
298
- // If there are no blog posts or the count of new posts is 0 or less, reset the set of new post IDs to an empty set and exit early
299
- if (blogPosts.length === 0 || newPostsCount <= 0) {
300
- setNewPostIds(new Set());
301
- return;
302
- }
303
- // Calculate the starting index for slicing the blogPosts array to get only
304
- const startIndex = Math.max(blogPosts.length - newPostsCount, 0);
305
- // Extract the IDs of the posts from that slice and filter out undefined IDs
306
- const ids = blogPosts.slice(startIndex).map(post => post.id).filter((id) => id !== undefined);
307
- // Update the state with the new set of post IDs considered 'new'
308
- setNewPostIds(new Set(ids));
309
- }
310
- }, [blogPosts, newPosts, context]);
311
291
  useEffect(() => {
312
292
  if (showId !== undefined)
313
293
  setLocalShowId(showId);
@@ -326,7 +306,6 @@ const TMBlogs = (props) => {
326
306
  if (blogPost.attachments) {
327
307
  for (const attachment of blogPost.attachments) {
328
308
  const dcmtTypeDescriptor = await DcmtTypeListCacheService.GetAsync(attachment.tid, true);
329
- // console.log('TMBlogs - getDcmtTypeDescriptor', dcmtTypeDescriptor);
330
309
  if (dcmtTypeDescriptor && attachment.tid) {
331
310
  dcmtTypeMap.set(attachment.tid, dcmtTypeDescriptor);
332
311
  }
@@ -408,6 +387,7 @@ const TMBlogs = (props) => {
408
387
  }
409
388
  // Update the state with the filtered and limited list of blogs
410
389
  setBlogPosts(filteredBlogs);
390
+ setFirstNewPost(filteredBlogs.find(blog => blog.customData1 === 1));
411
391
  if (focusedBlog && focusedBlog.id && filteredBlogs.find(filteredBlog => focusedBlog.id === filteredBlog.id) === undefined)
412
392
  handleFocusedBlog(undefined);
413
393
  }, [allData, appliedGlobalFilters, searchText, postsToShow, currentHeader]);
@@ -442,7 +422,7 @@ const TMBlogs = (props) => {
442
422
  };
443
423
  const renderBlogPostContent = (blogPost, index, isOwnComment) => {
444
424
  const isSelected = focusedBlog?.id === blogPost.id;
445
- const isNew = Boolean((blogPost.newPosts ?? 0) || (blogPost.id !== undefined && blogPost.id !== null && newPostIds.has(blogPost.id)));
425
+ const isNew = Boolean((blogPost.newPosts ?? 0) || blogPost.customData1);
446
426
  const backgroundColors = {
447
427
  default: layoutMode === 'stacked' ? colors.LIGHT_GRAY : isOwnComment ? '#D9EFE0' : '#F3E6E6',
448
428
  selectedItems: isSelected ? color ?? colors.PRIMARY_BLUE : colors.PRIMARY_BLUE,
@@ -507,13 +487,13 @@ const TMBlogs = (props) => {
507
487
  handleFocusedBlog(blogPost);
508
488
  handleFocusedAttachment(undefined);
509
489
  };
510
- return (_jsxs(BlogPostContainer, { id: id + "-" + blogPost.id.toString(), ref: containerRef, "$color": textColor, "$textDecoration": blogPost.isDel ? 'line-through' : 'none', "$backgroundColor": bgColor, "$isNew": Boolean(blogPost.newPosts ?? 0) || isNew, "$canNavigate": canNavigate(), "$paddingRight": layoutMode === 'chat' ? "50px" : "10px", onClick: onClickCallback, onDoubleClick: headerClickCallback, tabIndex: 0, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onContextMenu: onContextMenu, children: [_jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [OwnerInitialsBadge(blogPost), _jsx("div", { style: { flex: "1 1 auto", minWidth: "0" }, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: "wrap", overflow: "hidden" }, children: [_jsxs("div", { children: [_jsxs("div", { style: { fontWeight: "bold", fontSize: '1rem', display: "flex", alignItems: "center" }, children: [showIconHeader && blogPost.header && blogPost.classID
490
+ return (_jsxs(BlogPostContainer, { id: id + "-" + blogPost.id.toString(), ref: containerRef, "$color": textColor, "$textDecoration": blogPost.isDel ? 'line-through' : 'none', "$backgroundColor": bgColor, "$isNew": isNew, "$canNavigate": canNavigate(), "$paddingRight": layoutMode === 'chat' ? "50px" : "10px", onClick: onClickCallback, onDoubleClick: headerClickCallback, tabIndex: 0, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onContextMenu: onContextMenu, children: [_jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [(layoutMode !== 'chat' || !isOwnComment) && OwnerInitialsBadge(blogPost), _jsx("div", { style: { flex: "1 1 auto", minWidth: "0" }, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: "wrap", overflow: "hidden" }, children: [_jsxs("div", { children: [_jsxs("div", { style: { fontWeight: "bold", fontSize: '1rem', display: "flex", alignItems: "center" }, children: [showIconHeader && blogPost.header && blogPost.classID
511
491
  ? IconAndHeaderElement(blogPost, iconColor, isSelected, () => {
512
492
  if (handleNavigateToWGs && blogPost.id && blogPost.classID === 'WG') {
513
493
  handleNavigateToWGs(blogPost.id);
514
494
  }
515
495
  }, searchText)
516
- : _jsx("span", { style: { marginLeft: showIconHeader ? "5px" : "0", color: isSelected ? "#fff" : !blogPost.isSys ? TMColors.primary : colors.RED }, children: highlightText(blogPost.ownerName ?? '', searchText, isSelected) }), (blogPost?.newPosts ?? 0) > 0 && (_jsx("div", { style: {
496
+ : !isOwnComment && _jsx("span", { style: { marginLeft: showIconHeader ? "5px" : "0", color: isSelected ? "#fff" : !blogPost.isSys ? TMColors.primary : colors.RED }, children: highlightText(blogPost.ownerName ?? '', searchText, isSelected) }), (blogPost?.newPosts ?? 0) > 0 && (_jsx("div", { style: {
517
497
  marginLeft: "5px",
518
498
  minWidth: "20px",
519
499
  height: "20px",
@@ -540,8 +520,8 @@ const TMBlogs = (props) => {
540
520
  _jsx("div", { style: { fontSize: "15px", marginTop: "10px" }, children: SDKUI_Localizator.NoMessages })] })
541
521
  : blogPosts.map((blogPost, index) => {
542
522
  const isOwnComment = blogPost.ownerID === SDK_Globals.tmSession?.SessionDescr?.userID;
543
- return (_jsxs(React.Fragment, { children: [index === firstNewPostIndex && (_jsxs("div", { style: { display: 'flex', alignItems: 'center', width: '100%', color: TMColors.primary, fontWeight: '600', fontSize: '0.9rem', userSelect: 'none', }, children: [_jsx("hr", { style: { flex: 1, border: 'none', borderTop: `1px solid ${TMColors.primary}`, marginRight: '10px' } }), _jsx("span", { children: SDKUI_Localizator.LastRead }), _jsx("hr", { style: { flex: 1, border: 'none', borderTop: `1px solid ${TMColors.primary}`, marginLeft: '10px' } })] })), layoutMode === 'stacked' ? renderBlogPostContent(blogPost, index, isOwnComment) :
544
- _jsx("div", { id: 'blogPostChat-' + id + "-" + blogPost.id.toString(), style: {
523
+ return (_jsxs(React.Fragment, { children: [(firstNewPost && blogPost.id === firstNewPost.id) && (_jsxs("div", { style: { display: 'flex', alignItems: 'center', width: '100%', color: TMColors.primary, fontWeight: '600', fontSize: '0.9rem', userSelect: 'none', }, children: [_jsx("hr", { style: { flex: 1, border: 'none', borderTop: `1px solid ${TMColors.primary}`, marginRight: '10px' } }), _jsx("span", { children: SDKUI_Localizator.LastRead }), _jsx("hr", { style: { flex: 1, border: 'none', borderTop: `1px solid ${TMColors.primary}`, marginLeft: '10px' } })] })), layoutMode === 'stacked' ? renderBlogPostContent(blogPost, index, isOwnComment) :
524
+ _jsx("div", { style: {
545
525
  display: "flex",
546
526
  flexDirection: "row",
547
527
  alignItems: "flex-start",
@@ -556,7 +536,7 @@ const TMBlogs = (props) => {
556
536
  textAlign: "left",
557
537
  maxWidth: '90%',
558
538
  borderRadius: '8px',
559
- }, children: renderBlogPostContent(blogPost, index, isOwnComment) }) }, 'blogPostChat-' + id + "-" + blogPost.id)] }, "blog-post-wrapper-" + id + "-" + blogPost.id));
539
+ }, children: renderBlogPostContent(blogPost, index, isOwnComment) }) })] }, "blog-post-wrapper-" + id + "-" + blogPost.id));
560
540
  }) }) });
561
541
  };
562
542
  // Function to handle changes in the search text
package/lib/ts/types.d.ts CHANGED
@@ -134,6 +134,7 @@ export interface ITMSaveFormBaseProps {
134
134
  height?: string;
135
135
  signal?: AbortSignal;
136
136
  showSaveButton?: boolean;
137
+ customSaveButton?: JSX.Element;
137
138
  showBackButton?: boolean;
138
139
  showUndoButton?: boolean;
139
140
  showWarningsCount?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.14.82",
3
+ "version": "6.14.83",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",