react-admin-base-bootstrap 0.8.18 → 0.8.20

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/bun.lockb ADDED
Binary file
@@ -1,5 +1,3 @@
1
- /** @jsx jsx */
2
- import { jsx } from '@emotion/react';
3
1
  import React from 'react';
4
2
  export interface ApiSelectProps<Option = any> {
5
3
  url?: string;
@@ -19,8 +17,8 @@ export interface ApiSelectProps<Option = any> {
19
17
  onAddOrEdit?: (item: any) => void;
20
18
  getNewOptionData?: (name: string, elem: React.ReactNode) => any | null;
21
19
  }
22
- export default function ApiSelect<Option = any>(props: ApiSelectProps<Option>): jsx.JSX.Element;
20
+ export default function ApiSelect<Option = any>(props: ApiSelectProps<Option>): React.JSX.Element;
23
21
  export interface CreateSelectProps<Option = any> extends ApiSelectProps<Option> {
24
22
  Component: any;
25
23
  }
26
- export declare function CreateSelect(props: CreateSelectProps): jsx.JSX.Element;
24
+ export declare function CreateSelect(props: CreateSelectProps): React.JSX.Element;
@@ -7,25 +7,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- /** @jsx jsx */
11
- import { jsx } from '@emotion/react';
12
10
  import React, { Fragment, useCallback, useMemo, useState } from 'react';
13
11
  import { RefreshScope, useFetch, useRefresh } from 'react-admin-base';
14
12
  import { FormattedMessage, useIntl } from 'react-intl';
15
13
  import Select, { components } from "react-select";
16
14
  import CreatableSelect from 'react-select/creatable';
17
15
  function Option(props) {
18
- return jsx(components.Option, Object.assign({}, props), (props.selectProps.children && props.selectProps.children(props.data)) || (props.data.__isNew__ ? jsx(FormattedMessage, { id: "CREATE_VALUE", values: { text: props.children } }) : props.children));
16
+ return React.createElement(components.Option, Object.assign({}, props), (props.selectProps.children && props.selectProps.children(props.data)) || (props.data.__isNew__ ? React.createElement(FormattedMessage, { id: "CREATE_VALUE", values: { text: props.children } }) : props.children));
19
17
  }
20
18
  function SingleValue(props) {
21
- return jsx(components.SingleValue, Object.assign({}, props), (props.selectProps.children && props.selectProps.children(props.data)) || (props.data.__isNew__ ? jsx(FormattedMessage, { id: "CREATE_VALUE", values: { text: props.children } }) : props.children));
19
+ return React.createElement(components.SingleValue, Object.assign({}, props), (props.selectProps.children && props.selectProps.children(props.data)) || (props.data.__isNew__ ? React.createElement(FormattedMessage, { id: "CREATE_VALUE", values: { text: props.children } }) : props.children));
22
20
  }
23
21
  function MultiValue(props) {
24
- return jsx(components.MultiValue, Object.assign({}, props), (props.selectProps.children && props.selectProps.children(props.data)) || props.children);
22
+ return React.createElement(components.MultiValue, Object.assign({}, props), (props.selectProps.children && props.selectProps.children(props.data)) || props.children);
25
23
  }
26
24
  function EditOrAddIndicator(props) {
27
25
  const { className, cx, getStyles, innerProps, isMulti } = props;
28
- return (jsx("div", Object.assign({}, innerProps, { className: cx({
26
+ return (React.createElement("div", Object.assign({}, innerProps, { className: cx({
29
27
  indicator: true,
30
28
  'clear-indicator': true
31
29
  }, className), css: getStyles('clearIndicator', props), onMouseDown: e => {
@@ -33,20 +31,20 @@ function EditOrAddIndicator(props) {
33
31
  e.preventDefault();
34
32
  props.selectProps.onAddOrEdit();
35
33
  } }),
36
- jsx("i", { className: "fas " + (props.hasValue && !isMulti ? 'fa-pencil-alt' : 'fa-plus') })));
34
+ React.createElement("i", { className: "fas " + (props.hasValue && !isMulti ? 'fa-pencil-alt' : 'fa-plus') })));
37
35
  }
38
36
  function IndicatorsContainer(props) {
39
- return jsx(components.IndicatorsContainer, Object.assign({}, props),
40
- props.selectProps.onAddOrEdit && jsx(React.Fragment, null,
41
- jsx(EditOrAddIndicator, Object.assign({}, props)),
42
- jsx(components.IndicatorSeparator, Object.assign({}, props))),
37
+ return React.createElement(components.IndicatorsContainer, Object.assign({}, props),
38
+ props.selectProps.onAddOrEdit && React.createElement(React.Fragment, null,
39
+ React.createElement(EditOrAddIndicator, Object.assign({}, props)),
40
+ React.createElement(components.IndicatorSeparator, Object.assign({}, props))),
43
41
  props.children);
44
42
  }
45
43
  function MultiValueRemove(props) {
46
- return jsx(Fragment, null,
47
- props.selectProps.onAddOrEdit && jsx(components.MultiValueRemove, Object.assign({}, props, { innerProps: Object.assign(Object.assign({}, props.innerProps), { onClick: () => props.selectProps.onAddOrEdit(props.data) }) }),
48
- jsx("i", { className: "fas fa-pencil", style: { fontSize: '.75em' } })),
49
- jsx(components.MultiValueRemove, Object.assign({}, props)));
44
+ return React.createElement(Fragment, null,
45
+ props.selectProps.onAddOrEdit && React.createElement(components.MultiValueRemove, Object.assign({}, props, { innerProps: Object.assign(Object.assign({}, props.innerProps), { onClick: () => props.selectProps.onAddOrEdit(props.data) }) }),
46
+ React.createElement("i", { className: "fas fa-pencil", style: { fontSize: '.75em' } })),
47
+ React.createElement(components.MultiValueRemove, Object.assign({}, props)));
50
48
  }
51
49
  const Components = { Option, SingleValue, MultiValue, IndicatorsContainer, MultiValueRemove };
52
50
  export default function ApiSelect(props) {
@@ -89,8 +87,8 @@ export default function ApiSelect(props) {
89
87
  setIsMenuOpen(false);
90
88
  }, [setIsMenuOpen]);
91
89
  const Component = onCreateOption ? CreatableSelect : Select;
92
- return jsx(RefreshScope, { update: update },
93
- jsx(Component, Object.assign({}, props, { className: 'react-select-container', classNamePrefix: "react-select", onCreateOption: onCreateOption && handleCreateOption, getNewOptionData: (onCreateOption && (getNewOptionData || ((inputValue) => ({ [nameKey || 'name']: inputValue, __isNew__: true })))) || undefined, inputValue: search, onInputChange: a => setSearch(a), components: Components, isLoading: !!loading || creating, getOptionLabel: getOptionLabel || ((row) => row[nameKey || 'name']), getOptionValue: getOptionValue || ((row) => row[idKey || 'id']), isDisabled: !!disabled || creating, isClearable: true, isSearchable: true, placeholder: placeholder || intl.formatMessage({ id: 'SELECT' }), options: !options ? [] : ((filter && options.filter(filter)) || options), onMenuOpen: onMenuOpen, onMenuClose: onMenuClose })));
90
+ return React.createElement(RefreshScope, { update: update },
91
+ React.createElement(Component, Object.assign({}, props, { className: 'react-select-container', classNamePrefix: "react-select", onCreateOption: onCreateOption && handleCreateOption, getNewOptionData: (onCreateOption && (getNewOptionData || ((inputValue) => ({ [nameKey || 'name']: inputValue, __isNew__: true })))) || undefined, inputValue: search, onInputChange: a => setSearch(a), components: Components, isLoading: !!loading || creating, getOptionLabel: getOptionLabel || ((row) => row[nameKey || 'name']), getOptionValue: getOptionValue || ((row) => row[idKey || 'id']), isDisabled: !!disabled || creating, isClearable: true, isSearchable: true, placeholder: placeholder || intl.formatMessage({ id: 'SELECT' }), options: !options ? [] : ((filter && options.filter(filter)) || options), onMenuOpen: onMenuOpen, onMenuClose: onMenuClose })));
94
92
  }
95
93
  export function CreateSelect(props) {
96
94
  const { Component, onChange, value, isMulti, idKey } = props;
@@ -102,7 +100,7 @@ export function CreateSelect(props) {
102
100
  data && onChange(isMulti ? isOpenId ? value.map(b => b.id === isOpenId ? data : b) : (value || []).concat([data]) : data);
103
101
  update && update();
104
102
  }, [value, onChange, isMulti, isOpenId, isOpen, update, setIsOpen]);
105
- return jsx(Fragment, null,
106
- isOpen && jsx(Component, { id: isOpenId || (!isMulti && value && value[idKey || "id"]), onReload: onReload }),
107
- jsx(ApiSelect, Object.assign({}, props, { onAddOrEdit: item => setIsOpen(item || true) })));
103
+ return React.createElement(Fragment, null,
104
+ isOpen && React.createElement(Component, { id: isOpenId || (!isMulti && value && value[idKey || "id"]), onReload: onReload }),
105
+ React.createElement(ApiSelect, Object.assign({}, props, { onAddOrEdit: item => setIsOpen(item || true) })));
108
106
  }
@@ -20,7 +20,7 @@ var __rest = (this && this.__rest) || function (s, e) {
20
20
  };
21
21
  import React, { useCallback, useContext, useRef, useState } from 'react';
22
22
  import { ValidatorProvider } from "react-admin-base";
23
- import { FormattedMessage, useIntl } from 'react-intl';
23
+ import { FormattedMessage } from 'react-intl';
24
24
  import { Navigate, Routes, useParams, Route } from 'react-router-dom';
25
25
  import { Alert, Button, Col, Form, ModalFooter, ModalHeader, Row } from "reactstrap";
26
26
  import LoadingButton from '../Components/LoadingButton';
@@ -28,7 +28,7 @@ import BootstrapDataTable, { Actions } from './BootstrapDataTable';
28
28
  import BootstrapModal from './BootstrapModal';
29
29
  import { useBootstrapOptions } from "./BootstrapOptions";
30
30
  export function ModalEntityEditor({ entity, title, size, url, onReload, disabled, children }) {
31
- const [, , save, loading, dirty] = entity;
31
+ const [data, , save, loading, dirty] = entity;
32
32
  const bsOptions = useBootstrapOptions();
33
33
  const [open, setOpen] = useState(true);
34
34
  const [saved, setSaved] = useState(false);
@@ -60,26 +60,11 @@ export function ModalEntityEditor({ entity, title, size, url, onReload, disabled
60
60
  }
61
61
  });
62
62
  }, [save, saved, error, onReload, url]);
63
- const check = bsOptions.noCloseOnSave && dirty;
64
- const intl = useIntl();
65
- const checkConfirmText = intl.formatMessage({ id: 'CANCEL_ENTITY_SAVE' });
66
- const onClose = useCallback(function () {
67
- if (check) {
68
- const ok = confirm(checkConfirmText);
69
- if (!ok)
70
- return;
71
- }
72
- if (url) {
73
- setOpen(false);
74
- }
75
- else {
76
- onReload(null);
77
- }
78
- }, [setOpen, onReload, url, check, checkConfirmText]);
79
63
  return React.createElement(React.Fragment, null,
80
64
  ((!bsOptions.noCloseOnSave && saved) || !open) && url && React.createElement(Navigate, { to: url, replace: true }),
81
- React.createElement(BootstrapModal, { isOpen: true, size: size, toggle: onClose, fade: false },
82
- title && React.createElement(ModalHeader, { toggle: onClose },
65
+ ((bsOptions.noCloseOnSave && saved) || !open) && url && React.createElement(Navigate, { to: url + "/" + data.id + "/edit", replace: true }),
66
+ React.createElement(BootstrapModal, { isOpen: true, size: size, toggle: () => url ? setOpen(false) : onReload(null), fade: false },
67
+ title && React.createElement(ModalHeader, { toggle: () => url ? setOpen(false) : onReload(null) },
83
68
  React.createElement("b", null, title)),
84
69
  React.createElement(ValidatorProvider, null,
85
70
  React.createElement(Form, { onSubmit: onSubmit, disabled: !!loading || disabled },
@@ -97,7 +82,7 @@ export function ModalEntityEditor({ entity, title, size, url, onReload, disabled
97
82
  ' ',
98
83
  React.createElement(FormattedMessage, { id: "ENTITY.SAVE" }))),
99
84
  React.createElement(Col, null,
100
- React.createElement(Button, { block: true, outline: true, color: "danger", onClick: (e) => { e.preventDefault(); onClose(); } },
85
+ React.createElement(Button, { block: true, outline: true, color: "danger", onClick: (e) => { e.preventDefault(); (url ? setOpen(false) : onReload(null)); } },
101
86
  React.createElement("i", { className: "fas fa-times-circle" }),
102
87
  ' ',
103
88
  React.createElement(FormattedMessage, { id: "ENTITY.CANCEL" })))))))));
@@ -38,6 +38,5 @@
38
38
  "ACTIONS.DELETE.CONFIRM": "Ja, löschen!",
39
39
  "PLEASE_WAIT": "Warten Sie mal.",
40
40
  "AUTHORIZATION_CODE": "Zugangscode",
41
- "RECORDS": "{count, plural, =0 {kein eintrag} one {# datensatz} other {# datensätze}}",
42
- "CANCEL_ENTITY_SAVE": "Es gibt Änderungen auf der Seite. Sind Sie sicher, dass Sie sie rückgängig machen wollen?"
41
+ "RECORDS": "{count, plural, =0 {kein eintrag} one {# datensatz} other {# datensätze}}"
43
42
  }
@@ -40,6 +40,5 @@
40
40
  "ACTIONS.DELETE.CONFIRM": "Yes, delete it!",
41
41
  "PLEASE_WAIT": "Please wait.",
42
42
  "AUTHORIZATION_CODE": "Authorization Code",
43
- "RECORDS": "{count, plural, =0 {no records} one {# record} other {# records}}",
44
- "CANCEL_ENTITY_SAVE": "There are changes on the page. Are you sure you want to undo them?"
43
+ "RECORDS": "{count, plural, =0 {no records} one {# record} other {# records}}"
45
44
  }
@@ -39,6 +39,5 @@
39
39
  "ACTIONS.DELETE.CONFIRM": "Evet, sil!",
40
40
  "PLEASE_WAIT": "Lütfen bekleyiniz.",
41
41
  "AUTHORIZATION_CODE": "Yetki Kodu",
42
- "RECORDS": "{count, plural, =0 {Kayıt yok} one {# kayıt} other {# kayıt}}",
43
- "CANCEL_ENTITY_SAVE": "Sayfada değişiklikler var. Geri almak istediğinizden emin misiniz?"
42
+ "RECORDS": "{count, plural, =0 {Kayıt yok} one {# kayıt} other {# kayıt}}"
44
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-admin-base-bootstrap",
3
- "version": "0.8.18",
3
+ "version": "0.8.20",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -28,7 +28,7 @@
28
28
  "react": "^18.2.0",
29
29
  "react-dom": "^18.2.0",
30
30
  "react-intl": "^6.2.10",
31
- "react-router-dom": "^6.13.0"
31
+ "react-router-dom": "^6.18.0"
32
32
  },
33
33
  "dependencies": {
34
34
  "@emotion/react": "^11.11.1",
@@ -1,4 +1,3 @@
1
- /** @jsx jsx */
2
1
  import { jsx } from '@emotion/react';
3
2
  import React, {Fragment, useCallback, useMemo, useState} from 'react';
4
3
  import {RefreshScope, useFetch, useRefresh} from 'react-admin-base';
@@ -1,6 +1,6 @@
1
1
  import React, { useCallback, useContext, useRef, useState } from 'react';
2
2
  import { ValidatorProvider } from "react-admin-base";
3
- import {FormattedMessage, useIntl} from 'react-intl';
3
+ import { FormattedMessage } from 'react-intl';
4
4
  import { Navigate, Routes, useParams, Route } from 'react-router-dom';
5
5
  import { Alert, Button, Col, Form, Modal, ModalFooter, ModalHeader, Row } from "reactstrap";
6
6
  import LoadingButton from '../Components/LoadingButton';
@@ -19,7 +19,7 @@ type ModalEntityEditorParams = {
19
19
  }
20
20
 
21
21
  export function ModalEntityEditor({ entity, title, size, url, onReload, disabled, children } : ModalEntityEditorParams) {
22
- const [ , , save, loading, dirty ] = entity;
22
+ const [ data, , save, loading, dirty ] = entity;
23
23
  const bsOptions = useBootstrapOptions();
24
24
 
25
25
  const [ open, setOpen ] = useState(true);
@@ -58,27 +58,11 @@ export function ModalEntityEditor({ entity, title, size, url, onReload, disabled
58
58
  }
59
59
  }, [save, saved, error, onReload, url]);
60
60
 
61
- const check = bsOptions.noCloseOnSave && dirty;
62
- const intl = useIntl();
63
- const checkConfirmText = intl.formatMessage({ id: 'CANCEL_ENTITY_SAVE' });
64
- const onClose = useCallback(function() {
65
- if (check) {
66
- const ok = confirm(checkConfirmText);
67
- if (!ok)
68
- return ;
69
- }
70
-
71
- if (url) {
72
- setOpen(false);
73
- } else {
74
- onReload(null);
75
- }
76
- }, [ setOpen, onReload, url, check, checkConfirmText ]);
77
-
78
61
  return <>
79
62
  { ((!bsOptions.noCloseOnSave && saved) || !open) && url && <Navigate to={url} replace />}
80
- <BootstrapModal isOpen size={size} toggle={onClose} fade={false}>
81
- { title && <ModalHeader toggle={onClose}>
63
+ { ((bsOptions.noCloseOnSave && saved) || !open) && url && <Navigate to={url + "/" + data.id + "/edit"} replace />}
64
+ <BootstrapModal isOpen size={size} toggle={() => url ? setOpen(false) : onReload(null)} fade={false}>
65
+ { title && <ModalHeader toggle={() => url ? setOpen(false) : onReload(null)}>
82
66
  <b>{ title }</b>
83
67
  </ModalHeader> }
84
68
  <ValidatorProvider>
@@ -96,7 +80,7 @@ export function ModalEntityEditor({ entity, title, size, url, onReload, disabled
96
80
  </LoadingButton>
97
81
  </Col>
98
82
  <Col>
99
- <Button block outline color="danger" onClick={(e) => { e.preventDefault(); onClose(); }}>
83
+ <Button block outline color="danger" onClick={(e) => { e.preventDefault(); (url ? setOpen(false) : onReload(null)); }}>
100
84
  <i className="fas fa-times-circle" />{' '}<FormattedMessage id="ENTITY.CANCEL" />
101
85
  </Button>
102
86
  </Col>
package/src/i18n/de.json CHANGED
@@ -38,6 +38,5 @@
38
38
  "ACTIONS.DELETE.CONFIRM": "Ja, löschen!",
39
39
  "PLEASE_WAIT": "Warten Sie mal.",
40
40
  "AUTHORIZATION_CODE": "Zugangscode",
41
- "RECORDS": "{count, plural, =0 {kein eintrag} one {# datensatz} other {# datensätze}}",
42
- "CANCEL_ENTITY_SAVE": "Es gibt Änderungen auf der Seite. Sind Sie sicher, dass Sie sie rückgängig machen wollen?"
41
+ "RECORDS": "{count, plural, =0 {kein eintrag} one {# datensatz} other {# datensätze}}"
43
42
  }
package/src/i18n/en.json CHANGED
@@ -40,6 +40,5 @@
40
40
  "ACTIONS.DELETE.CONFIRM": "Yes, delete it!",
41
41
  "PLEASE_WAIT": "Please wait.",
42
42
  "AUTHORIZATION_CODE": "Authorization Code",
43
- "RECORDS": "{count, plural, =0 {no records} one {# record} other {# records}}",
44
- "CANCEL_ENTITY_SAVE": "There are changes on the page. Are you sure you want to undo them?"
43
+ "RECORDS": "{count, plural, =0 {no records} one {# record} other {# records}}"
45
44
  }
package/src/i18n/tr.json CHANGED
@@ -39,6 +39,5 @@
39
39
  "ACTIONS.DELETE.CONFIRM": "Evet, sil!",
40
40
  "PLEASE_WAIT": "Lütfen bekleyiniz.",
41
41
  "AUTHORIZATION_CODE": "Yetki Kodu",
42
- "RECORDS": "{count, plural, =0 {Kayıt yok} one {# kayıt} other {# kayıt}}",
43
- "CANCEL_ENTITY_SAVE": "Sayfada değişiklikler var. Geri almak istediğinizden emin misiniz?"
42
+ "RECORDS": "{count, plural, =0 {Kayıt yok} one {# kayıt} other {# kayıt}}"
44
43
  }
@@ -1,2 +0,0 @@
1
- import { ButtonProps } from "reactstrap";
2
- export declare function DragAndDropArrow(props: ButtonProps): JSX.Element | null;
@@ -1,11 +0,0 @@
1
- import React from "react";
2
- import { Button } from "reactstrap";
3
- import { useDragContext } from "react-admin-base";
4
- export function DragAndDropArrow(props) {
5
- const [ref, isDragging] = useDragContext();
6
- if (!ref)
7
- return null;
8
- return React.createElement(Button, Object.assign({ type: "button", innerRef: ref, outline: true, size: "sm", color: "primary" }, props),
9
- React.createElement("i", { className: "fas fa-arrows-up-down-left-right" }),
10
- props.children);
11
- }
@@ -1,4 +0,0 @@
1
- export default function RichTextEditor({ value, onChange }: {
2
- value: any;
3
- onChange: any;
4
- }): JSX.Element;
@@ -1,52 +0,0 @@
1
- import React from 'react';
2
- import { LexicalComposer } from "@lexical/react/LexicalComposer";
3
- import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
4
- import { ContentEditable } from "@lexical/react/LexicalContentEditable";
5
- import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
6
- import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
7
- import { HeadingNode, QuoteNode } from "@lexical/rich-text";
8
- import { TableCellNode, TableNode, TableRowNode } from "@lexical/table";
9
- import { ListItemNode, ListNode } from "@lexical/list";
10
- import { CodeHighlightNode, CodeNode } from "@lexical/code";
11
- import { AutoLinkNode, LinkNode } from "@lexical/link";
12
- import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
13
- import { ListPlugin } from "@lexical/react/LexicalListPlugin";
14
- import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
15
- import { TRANSFORMERS } from "@lexical/markdown";
16
- import ToolbarPlugin from '../Lexical/ToolbarPlugin';
17
- function Placeholder() {
18
- return React.createElement("div", { className: "editor-placeholder" }, "Enter some rich text...");
19
- }
20
- const editorConfig = {
21
- namespace: '',
22
- // Handling of errors during update
23
- onError(error) {
24
- throw error;
25
- },
26
- // Any custom nodes go here
27
- nodes: [
28
- HeadingNode,
29
- ListNode,
30
- ListItemNode,
31
- QuoteNode,
32
- CodeNode,
33
- CodeHighlightNode,
34
- TableNode,
35
- TableCellNode,
36
- TableRowNode,
37
- AutoLinkNode,
38
- LinkNode
39
- ]
40
- };
41
- export default function RichTextEditor({ value, onChange }) {
42
- return React.createElement(LexicalComposer, { initialConfig: editorConfig },
43
- React.createElement("div", { className: "editor-container" },
44
- React.createElement(ToolbarPlugin, null),
45
- React.createElement("div", { className: "editor-inner" },
46
- React.createElement(RichTextPlugin, { contentEditable: React.createElement(ContentEditable, { className: "editor-input" }), placeholder: React.createElement(Placeholder, null) }),
47
- React.createElement(HistoryPlugin, null),
48
- React.createElement(AutoFocusPlugin, null),
49
- React.createElement(ListPlugin, null),
50
- React.createElement(LinkPlugin, null),
51
- React.createElement(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }))));
52
- }