@zohodesk/dot 1.0.0-temp-229.2 → 1.0.0-temp-230.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +7 -5
  2. package/assets/Appearance/dark/mode/Dot_DarkMode.module.css +0 -3
  3. package/assets/Appearance/light/mode/Dot_LightMode.module.css +0 -3
  4. package/assets/Appearance/pureDark/mode/Dot_PureDarkMode.module.css +0 -3
  5. package/es/AttachmentViewer/AttachmentImage.js +3 -1
  6. package/es/AttachmentViewer/AttachmentViewer.js +119 -23
  7. package/es/AttachmentViewer/AttachmentViewer.module.css +1 -1
  8. package/es/AttachmentViewer/props/defaultProps.js +2 -1
  9. package/es/AttachmentViewer/props/propTypes.js +9 -1
  10. package/es/Link/Link.js +4 -3
  11. package/es/Link/props/propTypes.js +1 -0
  12. package/es/common/dot_boxShadow.module.css +0 -2
  13. package/es/form/fields/SelectField/SelectField.js +2 -4
  14. package/es/form/fields/SelectField/props/defaultProps.js +0 -1
  15. package/es/form/fields/SelectField/props/propTypes.js +0 -1
  16. package/es/list/status/StatusDropdown/StatusDropdown.js +79 -121
  17. package/es/list/status/StatusDropdown/StatusDropdown.module.css +7 -54
  18. package/es/list/status/StatusDropdown/props/defaultProps.js +1 -2
  19. package/es/list/status/StatusDropdown/props/propTypes.js +1 -2
  20. package/lib/AttachmentViewer/AttachmentImage.js +3 -1
  21. package/lib/AttachmentViewer/AttachmentViewer.js +181 -80
  22. package/lib/AttachmentViewer/AttachmentViewer.module.css +1 -1
  23. package/lib/AttachmentViewer/props/defaultProps.js +2 -1
  24. package/lib/AttachmentViewer/props/propTypes.js +9 -1
  25. package/lib/Link/Link.js +4 -3
  26. package/lib/Link/props/propTypes.js +1 -0
  27. package/lib/common/dot_boxShadow.module.css +0 -2
  28. package/lib/form/fields/SelectField/SelectField.js +2 -4
  29. package/lib/form/fields/SelectField/props/defaultProps.js +0 -1
  30. package/lib/form/fields/SelectField/props/propTypes.js +0 -1
  31. package/lib/list/status/StatusDropdown/StatusDropdown.js +81 -133
  32. package/lib/list/status/StatusDropdown/StatusDropdown.module.css +7 -54
  33. package/lib/list/status/StatusDropdown/props/defaultProps.js +1 -2
  34. package/lib/list/status/StatusDropdown/props/propTypes.js +1 -1
  35. package/package.json +8 -8
package/README.md CHANGED
@@ -4,12 +4,13 @@ In this Library, we Provide Some Basic Components to Build Your Application
4
4
 
5
5
  # 1.9.13
6
6
 
7
- - **StatusDropdown**
8
- - Added `renderCustomDropBoxHeader` prop to render a custom node (e.g. suggested status, banner, info message) at the top of the dropdown, above the options list.
9
- - Added `customDropBoxHeader` key under the `customClass` prop to style the custom header wrapper.
7
+ - **AttachmentViewer**
8
+ - Added support for updating existing attachment list items.
9
+ - Increased header bar height.
10
+ - Added support for `showCount`, `renderCustomIcons`, annotation URL re-rendering, and `downloadName`.
10
11
 
11
- - **SelectField**
12
- - Added `renderCustomDropBoxHeader` prop, forwarded to the underlying `Select` component to render a custom node at the top of the dropdown.
12
+ - **Link**
13
+ - Added `downloadName` prop for custom file download names.
13
14
 
14
15
  # 1.9.12
15
16
 
@@ -35,6 +36,7 @@ In this Library, we Provide Some Basic Components to Build Your Application
35
36
 
36
37
  - PX to variable conversion was not applied due to the CBT migration. The issue has now been fixed.
37
38
 
39
+
38
40
  # 1.9.8
39
41
 
40
42
  - **DotProvider** - Variables package handled and separated the component & variable import files
@@ -259,9 +259,6 @@
259
259
 
260
260
  /* status dropdown */
261
261
  --zdt_statusdropdown_line_border:var(--zdt_cta_grey_15_border);
262
- --zdt_statusdropdown_wrapper_container_border:hsla(0, calc(var(--zd-saturation, 1) * 0.00%), calc(100.00% + var(--zdc_default_inverse_low)), calc( 0.2 + var(--zdc_alpha_low)));
263
- --zdt_statusdropdown_wrapper_container_bg:hsla(0, calc(var(--zd-saturation, 1) * 0.00%), 100.00%, 0.03);
264
- --zdt_statusdropdown_wrapper_dropdown_bg:hsla(217, calc(var(--zd-saturation, 1) * 23.08%), calc(17.84% + var(--zdc_default)), calc(1 + var(--zdc_alpha_high)));
265
262
 
266
263
  /* status listitem */
267
264
  --zdt_statuslistitem_list_text:hsla(210, calc(var(--zd-saturation, 1) * 7.41%), calc(89.41% + var(--zdc_default_inverse)), calc(1 + var(--zdc_alpha_high)));
@@ -259,9 +259,6 @@
259
259
 
260
260
  /* status dropdown */
261
261
  --zdt_statusdropdown_line_border:var(--zdt_cta_grey_15_border);
262
- --zdt_statusdropdown_wrapper_container_border:hsla(218, calc(var(--zd-saturation, 1) * 42.22%), calc(91.18% + var(--zdc_default_inverse_low)), calc(1 + var(--zdc_alpha_low)));
263
- --zdt_statusdropdown_wrapper_container_bg:hsla(216, calc(var(--zd-saturation, 1) * 38.46%), 97.45%, 1);
264
- --zdt_statusdropdown_wrapper_dropdown_bg:hsla(0, calc(var(--zd-saturation, 1) * 0.00%), calc(100.00% + var(--zdc_default)), calc(1 + var(--zdc_alpha_high)));
265
262
 
266
263
  /* status listitem */
267
264
  --zdt_statuslistitem_list_text:hsla(0, calc(var(--zd-saturation, 1) * 0.00%), calc(0.00% + var(--zdc_default_inverse)), calc(1 + var(--zdc_alpha_high)));
@@ -259,9 +259,6 @@
259
259
 
260
260
  /* status dropdown */
261
261
  --zdt_statusdropdown_line_border:var(--zdt_cta_grey_15_border);
262
- --zdt_statusdropdown_wrapper_container_border:hsla(0, calc(var(--zd-saturation, 1) * 0.00%), calc(100.00% + var(--zdc_default_inverse_low)), calc( 0.2 + var(--zdc_alpha_low)));
263
- --zdt_statusdropdown_wrapper_container_bg:hsla(0, calc(var(--zd-saturation, 1) * 0.00%), 100.00%, 0.03);
264
- --zdt_statusdropdown_wrapper_dropdown_bg:hsla(0, calc(var(--zd-saturation, 1) * 0.00%), calc(12.94% + var(--zdc_default)), calc(1 + var(--zdc_alpha_high)));
265
262
 
266
263
  /* status listitem */
267
264
  --zdt_statuslistitem_list_text:hsla(210, calc(var(--zd-saturation, 1) * 7.41%), calc(89.41% + var(--zdc_default_inverse)), calc(1 + var(--zdc_alpha_high)));
@@ -43,7 +43,8 @@ export default class AttachmentImage extends Component {
43
43
  isCover,
44
44
  customClass,
45
45
  onLoad,
46
- onError
46
+ onError,
47
+ imageRef
47
48
  } = this.props;
48
49
  const {
49
50
  isImageValid
@@ -59,6 +60,7 @@ export default class AttachmentImage extends Component {
59
60
  className: customImageClass,
60
61
  alt: alt,
61
62
  isCover: isCover,
63
+ eleRef: imageRef,
62
64
  onLoad: onLoad,
63
65
  onError: onError
64
66
  });
@@ -47,8 +47,35 @@ export default class AttachmentViewer extends Component {
47
47
  this.zoomMaintain = this.zoomMaintain.bind(this);
48
48
  this.handleMenuValidation = this.handleMenuValidation.bind(this);
49
49
  this.getPreviewIconData = this.getPreviewIconData.bind(this);
50
- this.renderIframe = this.renderIframe.bind(this);
51
- }
50
+ this.renderIframe = this.renderIframe.bind(this); // this.updateItem = this.updateItem.bind(this);
51
+ } // updateItem(idOrIndex, changes) {
52
+ // if (!changes || typeof changes !== 'object') {
53
+ // return false;
54
+ // }
55
+ // const { data } = this.state;
56
+ // const targetIdx = typeof idOrIndex === 'number'
57
+ // ? idOrIndex
58
+ // : data.findIndex((item) => item && item.id === idOrIndex);
59
+ // if (targetIdx < 0 || targetIdx >= data.length) {
60
+ // return false;
61
+ // }
62
+ // this.setState((prevState) => {
63
+ // const nextData = prevState.data.slice();
64
+ // nextData[targetIdx] = { ...nextData[targetIdx], ...changes };
65
+ // let nextDataList = prevState.dataList;
66
+ // if (targetIdx < prevState.dataList.length) {
67
+ // nextDataList = prevState.dataList.slice();
68
+ // nextDataList[targetIdx] = { ...nextDataList[targetIdx], ...changes };
69
+ // }
70
+ // return { data: nextData, dataList: nextDataList };
71
+ // }, () => {
72
+ // if (this.state.selectedIndex === targetIdx) {
73
+ // this.handleMenuValidation();
74
+ // }
75
+ // });
76
+ // return true;
77
+ // }
78
+
52
79
 
53
80
  isImageFileType(fileName) {
54
81
  const extension = (getExtensionFromFileName(fileName) || '').toLowerCase();
@@ -80,8 +107,9 @@ export default class AttachmentViewer extends Component {
80
107
  selectedIndex
81
108
  } = this.state;
82
109
  let indexChanged = previewObj.selectedIndex != prevProps.previewObj.selectedIndex;
110
+ const attachmentPreviewUrlChanged = previewObj.previewData[0]?.viewUrl !== prevState.data[0]?.viewUrl; // Triggers an update if the previewed attachment is edited by the Attachment Annotator.
83
111
 
84
- if (previewObj.previewData.length != prevProps.previewObj.previewData.length || indexChanged) {
112
+ if (previewObj.previewData.length != prevProps.previewObj.previewData.length || indexChanged || attachmentPreviewUrlChanged) {
85
113
  let objChanged = previewObj.previewData.some((value, index) => {
86
114
  return shallowDiff(value, prevProps.previewObj[index]);
87
115
  });
@@ -100,7 +128,7 @@ export default class AttachmentViewer extends Component {
100
128
  }
101
129
  }
102
130
 
103
- if (prevState.selectedIndex != selectedIndex) {
131
+ if (prevState.selectedIndex != selectedIndex || attachmentPreviewUrlChanged) {
104
132
  this.handleMenuValidation();
105
133
  }
106
134
  }
@@ -308,6 +336,77 @@ export default class AttachmentViewer extends Component {
308
336
  }, this.props.customProps.iframeProps));
309
337
  }
310
338
 
339
+ getRenderImageFrameCustomClass(_ref3) {
340
+ let {
341
+ canZoom,
342
+ retainZoom,
343
+ isZoomed,
344
+ customImageClass,
345
+ customChildrenClass
346
+ } = _ref3;
347
+ return {
348
+ customImageClass: `${style.img} ${style.altText} ${canZoom || retainZoom ? isZoomed ? `${style.zoomedImg} ${style.zoomOutCursor}` : `${style.normalImg} ${style.zoomInCursor}` : ''} ${customImageClass}`,
349
+ customChildrenClass
350
+ };
351
+ }
352
+
353
+ renderImageFrame(data, i) {
354
+ const {
355
+ selectedIndex,
356
+ isZoomed,
357
+ canZoom,
358
+ isPreviewAttachmentValid
359
+ } = this.state;
360
+ const {
361
+ maintainZoom,
362
+ renderCustomImagePreviewElement
363
+ } = this.props;
364
+ const {
365
+ viewUrl,
366
+ name,
367
+ children,
368
+ dataId = 'attachViewer',
369
+ customClass = {},
370
+ customProps = {},
371
+ imageRef
372
+ } = data;
373
+ const {
374
+ imageProps = {}
375
+ } = customProps;
376
+ const {
377
+ customImageClass = '',
378
+ customChildrenClass = ''
379
+ } = customClass;
380
+ const resolvedImageRef = imageRef;
381
+ const retainZoom = canZoom && selectedIndex == i && maintainZoom;
382
+ const handleZoomOut = isPreviewAttachmentValid && isZoomed ? this.zoomOut.bind(this, i) : undefined;
383
+ const handleZoomIn = isPreviewAttachmentValid && !isZoomed ? e => this.zoomIn(e, i, true) : undefined;
384
+ const handleImageClick = isPreviewAttachmentValid ? isZoomed ? handleZoomOut : handleZoomIn : undefined;
385
+ const imageFrameCustomClass = this.getRenderImageFrameCustomClass({
386
+ canZoom,
387
+ retainZoom,
388
+ isZoomed,
389
+ customImageClass,
390
+ customChildrenClass
391
+ });
392
+ const img = /*#__PURE__*/React.createElement(AttachmentImage, _extends({
393
+ customClass: imageFrameCustomClass,
394
+ src: viewUrl,
395
+ onClick: handleImageClick,
396
+ alt: name,
397
+ dataId: dataId,
398
+ id: `img${i}`,
399
+ isCover: false
400
+ }, imageProps, {
401
+ imageRef: resolvedImageRef
402
+ }), children);
403
+ return typeof renderCustomImagePreviewElement === 'function' ? renderCustomImagePreviewElement({
404
+ defaultView: img,
405
+ data,
406
+ index: i
407
+ }) : img;
408
+ }
409
+
311
410
  imgPreviewView(downloadUrl) {
312
411
  var _this = this;
313
412
 
@@ -404,18 +503,7 @@ export default class AttachmentViewer extends Component {
404
503
  }, videoProps), /*#__PURE__*/React.createElement("source", {
405
504
  src: viewUrl,
406
505
  type: `video/${extension}`
407
- })) : _this.isImageFileType(name) || children ? /*#__PURE__*/React.createElement(AttachmentImage, _extends({
408
- customClass: {
409
- customImageClass: `${style.img} ${style.altText} ${canZoom || retainZoom ? isZoomed ? `${style.zoomedImg} ${style.zoomOutCursor}` : `${style.normalImg} ${style.zoomInCursor}` : ''} ${customImageClass}`,
410
- customChildrenClass
411
- },
412
- src: viewUrl,
413
- onClick: isPreviewAttachmentValid ? isZoomed ? _this.zoomOut.bind(_this, i) : e => _this.zoomIn(e, i, true) : undefined,
414
- alt: name,
415
- dataId: dataId,
416
- id: `img${i}`,
417
- isCover: false
418
- }, imageProps), children) : type === "document" && previewurl != null ? _this.renderIframe(previewurl) : typeof renderUnSupportedElement === 'function' ? renderUnSupportedElement(data) : /*#__PURE__*/React.createElement("div", {
506
+ })) : _this.isImageFileType(name) || children ? _this.renderImageFrame(data, i) : type === "document" && previewurl != null ? _this.renderIframe(previewurl) : typeof renderUnSupportedElement === 'function' ? renderUnSupportedElement(data) : /*#__PURE__*/React.createElement("div", {
419
507
  className: style.previewNone
420
508
  }, /*#__PURE__*/React.createElement("div", {
421
509
  className: style.fileTypeImg
@@ -424,9 +512,10 @@ export default class AttachmentViewer extends Component {
424
512
  $ui_weight: "semibold"
425
513
  }, previewUnsupportedText), downloadUrl ? /*#__PURE__*/React.createElement(Link, {
426
514
  href: downloadUrl,
515
+ download: true,
516
+ downloadName: name,
427
517
  className: style.downloadLink,
428
- hasReload: true,
429
- download: true
518
+ hasReload: true
430
519
  }, /*#__PURE__*/React.createElement(Button, {
431
520
  palette: "primaryFilled",
432
521
  text: downloadText
@@ -449,7 +538,9 @@ export default class AttachmentViewer extends Component {
449
538
  i18nKeys,
450
539
  isActive,
451
540
  dataId,
452
- customProps
541
+ customProps,
542
+ showCount,
543
+ renderCustomIcons
453
544
  } = this.props;
454
545
  const {
455
546
  avatarProps = {}
@@ -477,10 +568,10 @@ export default class AttachmentViewer extends Component {
477
568
  }, /*#__PURE__*/React.createElement(ResponsiveReceiver, {
478
569
  responsiveId: responsiveId,
479
570
  query: this.responsiveFunc
480
- }, _ref3 => {
571
+ }, _ref4 => {
481
572
  let {
482
573
  uptoTablet
483
- } = _ref3;
574
+ } = _ref4;
484
575
  return /*#__PURE__*/React.createElement(Container, {
485
576
  scroll: "none",
486
577
  "data-scroll-palette": "dark"
@@ -495,7 +586,7 @@ export default class AttachmentViewer extends Component {
495
586
  "data-title": selectedAttachment.name,
496
587
  dataId: "attachName",
497
588
  id: ariaId
498
- }, selectedAttachment.name), /*#__PURE__*/React.createElement(Box, {
589
+ }, selectedAttachment.name), showCount && /*#__PURE__*/React.createElement(Box, {
499
590
  flexible: true,
500
591
  className: style.count,
501
592
  dataId: "attachCountContainer"
@@ -507,7 +598,11 @@ export default class AttachmentViewer extends Component {
507
598
  align: uptoTablet ? 'bottom' : 'center',
508
599
  wrap: "wrap",
509
600
  isCover: false
510
- }, canZoom ? isZoomed ? /*#__PURE__*/React.createElement("div", {
601
+ }, typeof renderCustomIcons === 'function' && renderCustomIcons({
602
+ selectedAttachment,
603
+ selectedIndex,
604
+ totalLen
605
+ }), canZoom ? isZoomed ? /*#__PURE__*/React.createElement("div", {
511
606
  className: uptoTablet ? style.mobileMenu : style.menu,
512
607
  onClick: this.zoomOut.bind(this, selectedIndex),
513
608
  "data-id": "zoomOut",
@@ -555,6 +650,7 @@ export default class AttachmentViewer extends Component {
555
650
  className: uptoTablet ? style.mobileMenu : style.menu
556
651
  }, /*#__PURE__*/React.createElement(Link, {
557
652
  href: downloadUrl,
653
+ downloadName: selectedAttachment.name,
558
654
  target: "_parent",
559
655
  hasReload: true,
560
656
  download: true,
@@ -1,5 +1,5 @@
1
1
  .header {
2
- height: var(--zd_size40) ;
2
+ height: var(--zd_size48) ;
3
3
  position: relative;
4
4
  z-index: 1;
5
5
  padding-block:0 ;
@@ -12,5 +12,6 @@ export const AttachmentViewer_defaultProps = {
12
12
  isActive: false,
13
13
  dataId: 'AttachmentViewer',
14
14
  i18nKeys: {},
15
- customProps: {}
15
+ customProps: {},
16
+ showCount: true
16
17
  };
@@ -2,6 +2,9 @@ import PropTypes from 'prop-types';
2
2
  import { propTypes as AvatarProps } from '@zohodesk/components/es/Avatar/props/propTypes';
3
3
  export const AttachmentImage_propTypes = {
4
4
  alt: PropTypes.string,
5
+ imageRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
6
+ current: PropTypes.any
7
+ })]),
5
8
  customClass: PropTypes.shape({
6
9
  customImageClass: PropTypes.string,
7
10
  customChildrenClass: PropTypes.string
@@ -17,6 +20,9 @@ export const AttachmentImage_propTypes = {
17
20
  };
18
21
  export const AttachmentViewer_propTypes = {
19
22
  hideAttachmentViewer: PropTypes.func,
23
+ imageRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
24
+ current: PropTypes.any
25
+ })]),
20
26
  i18nKeys: PropTypes.shape({
21
27
  nextText: PropTypes.string,
22
28
  previousText: PropTypes.string,
@@ -44,5 +50,7 @@ export const AttachmentViewer_propTypes = {
44
50
  renderUnSupportedElement: PropTypes.func,
45
51
  customProps: PropTypes.shape({
46
52
  avatarProps: PropTypes.exact(AvatarProps)
47
- })
53
+ }),
54
+ showCount: PropTypes.bool,
55
+ renderCustomIcons: PropTypes.func
48
56
  };
package/es/Link/Link.js CHANGED
@@ -61,7 +61,8 @@ export default class Link extends React.Component {
61
61
  rel,
62
62
  dataId,
63
63
  customProps,
64
- ariaLabel
64
+ ariaLabel,
65
+ downloadName
65
66
  } = this.props;
66
67
  let {
67
68
  isLink,
@@ -71,10 +72,10 @@ export default class Link extends React.Component {
71
72
  let option = {};
72
73
 
73
74
  if (download) {
74
- option.download = true;
75
+ option.download = downloadName || true;
75
76
  }
76
77
 
77
- let ignoreKeys = ['children', 'href', 'target', 'urlData', 'urlName', 'className', 'title', 'download', 'rel', 'dataId', 'hasReload', 'customProps', 'option', 'ariaLabel'];
78
+ let ignoreKeys = ['children', 'href', 'target', 'urlData', 'urlName', 'className', 'title', 'download', 'downloadName', 'rel', 'dataId', 'hasReload', 'customProps', 'option', 'ariaLabel'];
78
79
  let others = Object.keys(this.props).filter(key => ignoreKeys.indexOf(key) == -1).reduce((res, key) => {
79
80
  res[key] = this.props[key];
80
81
  return res;
@@ -13,6 +13,7 @@ export const propTypes = {
13
13
  customProps: PropTypes.object,
14
14
  onClick: PropTypes.func,
15
15
  download: PropTypes.bool,
16
+ downloadName: PropTypes.string,
16
17
  ariaLabel: PropTypes.string,
17
18
  key: PropTypes.string
18
19
  };
@@ -40,6 +40,4 @@
40
40
  --zd_bs_onboarding_close_icon: var(--zd_bs_contrast_outline, 0px 2px 15px var(--zd-shadow-saturation, rgba(0, 0, 0, 0.09)));
41
41
  --zd_bs_onboarding_gradient: var(--zd_bs_contrast_outline, 0px 20px 30px 0px var(--zdt_onboarding_bg_box_shadow));
42
42
  --zd_bs_onboarding_primary_button: var(--zd_bs_contrast_outline, 0px 4px 20px 0px var(--zdt_onboarding_primary_button_shadow));
43
- /* status dropdown */
44
- --zd_bs_statusdropdown_wrapper_container: var(--zd_bs_contrast_outline, 3px 3px 26px 0 var(--zdt_texteditor_menu_after_box_shadow));
45
43
  }
@@ -97,8 +97,7 @@ export default class SelectField extends PureComponent {
97
97
  onFocus,
98
98
  iconOnHover,
99
99
  customProps,
100
- renderLabelProps,
101
- renderCustomDropBoxHeader
100
+ renderLabelProps
102
101
  } = this.props;
103
102
  const {
104
103
  LabelProps = {},
@@ -168,8 +167,7 @@ export default class SelectField extends PureComponent {
168
167
  iconOnHover: iconOnHover,
169
168
  title: title
170
169
  }, SelectProps, {
171
- ariaLabelledby: uniqueId,
172
- renderCustomDropBoxHeader: renderCustomDropBoxHeader
170
+ ariaLabelledby: uniqueId
173
171
  }), children ? children : null)), validationMessage && /*#__PURE__*/React.createElement(ValidationMessage, _extends({
174
172
  text: validationMessage,
175
173
  palette: validationPalette,
@@ -13,7 +13,6 @@ export const defaultProps = {
13
13
  isDefaultSelectValue: true,
14
14
  placeHolder: '',
15
15
  customProps: {},
16
- renderCustomDropBoxHeader: null,
17
16
  dataSelectorId: 'selectField',
18
17
  ...FieldCommonDefaultProps()
19
18
  };
@@ -45,7 +45,6 @@ export const propTypes = {
45
45
  ValidationMessageProps1: PropTypes.object,
46
46
  ValidationMessageProps2: PropTypes.object
47
47
  }),
48
- renderCustomDropBoxHeader: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
49
48
  htmlId: PropTypes.string,
50
49
  ...FieldCommonPropTypes
51
50
  };