datastake-daf 0.6.148 → 0.6.150
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/components/index.js +84 -50
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/PdfView/index.jsx +59 -44
- package/src/@daf/core/components/Dashboard/Widget/ExpandableMapWidget/ExpandableMapWidget.stories.js +1693 -0
- package/src/@daf/core/components/Dashboard/Widget/ExpandableMapWidget/hook.js +44 -0
- package/src/@daf/core/components/Dashboard/Widget/ExpandableMapWidget/index.js +55 -0
- package/src/@daf/core/components/Dashboard/Widget/ProjectWidget/index.jsx +9 -3
- package/src/@daf/core/components/Dashboard/Widget/index.jsx +2 -1
- package/.vscode/settings.json +0 -13
package/dist/components/index.js
CHANGED
|
@@ -11984,7 +11984,7 @@ GoToSelect.propTypes = {
|
|
|
11984
11984
|
|
|
11985
11985
|
const _excluded$k = ["options", "defaultSelected", "onChange", "textWhenMultiple", "withCount", "oneAlwaysSelected", "canUnselectLast", "isAvatarGroup", "maxAvatarCount", "dropDownWidth", "topAvatarValue", "isSingle", "selectionType"];
|
|
11986
11986
|
const {
|
|
11987
|
-
useToken: useToken$
|
|
11987
|
+
useToken: useToken$j
|
|
11988
11988
|
} = antd.theme;
|
|
11989
11989
|
|
|
11990
11990
|
/**
|
|
@@ -12078,7 +12078,7 @@ function Multiselect(_ref) {
|
|
|
12078
12078
|
restProps = _objectWithoutProperties(_ref, _excluded$k);
|
|
12079
12079
|
const {
|
|
12080
12080
|
token
|
|
12081
|
-
} = useToken$
|
|
12081
|
+
} = useToken$j();
|
|
12082
12082
|
const [selectValue, setSelectValue] = React.useState(Array.isArray(defaultSelected) ? defaultSelected.length > 0 ? defaultSelected : [] : [defaultSelected]);
|
|
12083
12083
|
function onSelectChange(value) {
|
|
12084
12084
|
if (!canUnselectLast && value.length === 0) {
|
|
@@ -12582,7 +12582,7 @@ const useHeader = _ref => {
|
|
|
12582
12582
|
};
|
|
12583
12583
|
|
|
12584
12584
|
const {
|
|
12585
|
-
useToken: useToken$
|
|
12585
|
+
useToken: useToken$i
|
|
12586
12586
|
} = antd.theme;
|
|
12587
12587
|
function BreadCrumbs({
|
|
12588
12588
|
breadcrumbs = [],
|
|
@@ -12591,7 +12591,7 @@ function BreadCrumbs({
|
|
|
12591
12591
|
const [splitIndex, setSplitIndex] = React.useState(0);
|
|
12592
12592
|
const {
|
|
12593
12593
|
token
|
|
12594
|
-
} = useToken$
|
|
12594
|
+
} = useToken$i();
|
|
12595
12595
|
const _renderBreadcrumb = (b, i, isLast, noOnClickLast = false) => {
|
|
12596
12596
|
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
12597
12597
|
className: "flex breadcrumb-item",
|
|
@@ -12956,9 +12956,11 @@ DAFFooter.propTypes = {
|
|
|
12956
12956
|
};
|
|
12957
12957
|
|
|
12958
12958
|
const PAGE_HEIGHT = 1587;
|
|
12959
|
-
// margin-top: 20, bottom: 20;
|
|
12960
12959
|
const FOOTER_HEIGHT = 70;
|
|
12961
12960
|
const HEADER_HEIGHT = 100;
|
|
12961
|
+
const ROW_SPACING = 24; // Spacing between content rows
|
|
12962
|
+
const CONTENT_BOTTOM_PADDING = 30; // Extra padding at the very bottom of the last section of the document
|
|
12963
|
+
|
|
12962
12964
|
const Row = _ref => {
|
|
12963
12965
|
let {
|
|
12964
12966
|
widgets,
|
|
@@ -13007,49 +13009,84 @@ function PdfView(_ref2) {
|
|
|
13007
13009
|
const keys = Object.keys(sectionsConfig);
|
|
13008
13010
|
let _pages = [1];
|
|
13009
13011
|
let _page = 1;
|
|
13012
|
+
|
|
13013
|
+
// The total vertical space available for flowing content on each page,
|
|
13014
|
+
// considering that HEADER_HEIGHT and FOOTER_HEIGHT are for absolutely positioned elements
|
|
13015
|
+
// and content should flow between them.
|
|
13016
|
+
const usableContentHeightPerPage = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT;
|
|
13010
13017
|
if (keys.length === config.length) {
|
|
13011
|
-
let
|
|
13018
|
+
let currentFlowHeight = 0; // Tracks height accumulated within the `usableContentHeightPerPage` for the current page
|
|
13019
|
+
|
|
13020
|
+
// Reset all margins/paddings first for a clean slate
|
|
13012
13021
|
keys.forEach(k => {
|
|
13013
13022
|
const {
|
|
13014
13023
|
ref
|
|
13015
13024
|
} = sectionsConfig[k];
|
|
13016
|
-
ref.current
|
|
13017
|
-
|
|
13025
|
+
if (ref.current) {
|
|
13026
|
+
ref.current.style.marginBottom = '0px';
|
|
13027
|
+
ref.current.style.marginTop = '0px';
|
|
13028
|
+
ref.current.style.paddingBottom = '0px';
|
|
13029
|
+
}
|
|
13018
13030
|
});
|
|
13019
13031
|
keys.forEach((k, i) => {
|
|
13020
13032
|
const {
|
|
13021
13033
|
height,
|
|
13022
13034
|
ref
|
|
13023
13035
|
} = sectionsConfig[k];
|
|
13024
|
-
if (
|
|
13025
|
-
|
|
13026
|
-
|
|
13036
|
+
if (!ref.current) return; // Skip if ref is not available yet
|
|
13037
|
+
|
|
13038
|
+
let sectionTopMargin = ROW_SPACING; // Default margin for sections that follow another on the same page
|
|
13039
|
+
|
|
13040
|
+
// The first section on *any* page (either global first or first on a new page)
|
|
13041
|
+
// needs to be offset by HEADER_HEIGHT from the top of the page.
|
|
13042
|
+
if (i === 0 || currentFlowHeight === 0) {
|
|
13043
|
+
sectionTopMargin = HEADER_HEIGHT;
|
|
13027
13044
|
}
|
|
13028
|
-
|
|
13029
|
-
|
|
13030
|
-
|
|
13045
|
+
|
|
13046
|
+
// Calculate the total height this section would occupy *including its immediate top margin and its own height*.
|
|
13047
|
+
let totalHeightForThisSection = sectionTopMargin + height;
|
|
13048
|
+
|
|
13049
|
+
// If it's not the very last section of the document, add the standard row spacing.
|
|
13050
|
+
if (i < keys.length - 1) {
|
|
13051
|
+
totalHeightForThisSection += ROW_SPACING;
|
|
13052
|
+
} else {
|
|
13053
|
+
// For the very last section, add the document-level bottom padding.
|
|
13054
|
+
totalHeightForThisSection += CONTENT_BOTTOM_PADDING;
|
|
13031
13055
|
}
|
|
13032
|
-
|
|
13033
|
-
|
|
13034
|
-
|
|
13056
|
+
|
|
13057
|
+
// Check if placing this section (with its calculated space) on the current page
|
|
13058
|
+
// would exceed the usable content area for a theoretical page.
|
|
13059
|
+
if (currentFlowHeight + totalHeightForThisSection > usableContentHeightPerPage) {
|
|
13060
|
+
// This section overflows, so it starts on a new page.
|
|
13035
13061
|
_page += 1;
|
|
13036
13062
|
_pages.push(_page);
|
|
13037
|
-
|
|
13038
|
-
|
|
13039
|
-
|
|
13040
|
-
|
|
13041
|
-
|
|
13042
|
-
|
|
13043
|
-
|
|
13063
|
+
|
|
13064
|
+
// Reset flow height for the new page.
|
|
13065
|
+
// This section is now the first on a new page, so its top margin is HEADER_HEIGHT.
|
|
13066
|
+
ref.current.style.marginTop = "".concat(HEADER_HEIGHT, "px");
|
|
13067
|
+
currentFlowHeight = HEADER_HEIGHT + height; // Start accumulated height for new page
|
|
13068
|
+
|
|
13069
|
+
// Add row spacing or bottom padding for this section on its new page
|
|
13070
|
+
if (i < keys.length - 1) {
|
|
13071
|
+
currentFlowHeight += ROW_SPACING;
|
|
13072
|
+
} else {
|
|
13073
|
+
ref.current.style.paddingBottom = "".concat(CONTENT_BOTTOM_PADDING, "px");
|
|
13074
|
+
currentFlowHeight += CONTENT_BOTTOM_PADDING;
|
|
13044
13075
|
}
|
|
13045
13076
|
} else {
|
|
13046
|
-
|
|
13077
|
+
// This section fits on the current page.
|
|
13078
|
+
ref.current.style.marginTop = "".concat(sectionTopMargin, "px");
|
|
13079
|
+
currentFlowHeight += totalHeightForThisSection; // Accumulate the height this section takes
|
|
13080
|
+
|
|
13081
|
+
// Apply special padding for the very last section of the document if it fits on current page
|
|
13082
|
+
if (i === keys.length - 1) {
|
|
13083
|
+
ref.current.style.paddingBottom = "".concat(CONTENT_BOTTOM_PADDING, "px");
|
|
13084
|
+
}
|
|
13047
13085
|
}
|
|
13048
|
-
// console.groupEnd();
|
|
13049
13086
|
});
|
|
13050
13087
|
setPages(_pages);
|
|
13051
13088
|
}
|
|
13052
|
-
}, [sectionsConfig]);
|
|
13089
|
+
}, [sectionsConfig, config.length]);
|
|
13053
13090
|
React.useEffect(() => {
|
|
13054
13091
|
doSizing();
|
|
13055
13092
|
}, [doSizing]);
|
|
@@ -13075,16 +13112,6 @@ function PdfView(_ref2) {
|
|
|
13075
13112
|
})
|
|
13076
13113
|
});
|
|
13077
13114
|
}, [config, onChangeHeight]);
|
|
13078
|
-
|
|
13079
|
-
// <div className="daf-analysis">
|
|
13080
|
-
// <Header title={t('Dashboard Title')} />
|
|
13081
|
-
|
|
13082
|
-
// <div className="content">
|
|
13083
|
-
// <div className="view-content">
|
|
13084
|
-
// <div className="daf-analysis-layout">
|
|
13085
|
-
// <div className='sections-cont w-pt'>
|
|
13086
|
-
// <section>
|
|
13087
|
-
|
|
13088
13115
|
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
13089
13116
|
className: contClassName,
|
|
13090
13117
|
style: {
|
|
@@ -13095,11 +13122,13 @@ function PdfView(_ref2) {
|
|
|
13095
13122
|
style: {
|
|
13096
13123
|
top: (page - 1) * PAGE_HEIGHT,
|
|
13097
13124
|
width: '100%',
|
|
13098
|
-
height: HEADER_HEIGHT
|
|
13125
|
+
height: HEADER_HEIGHT,
|
|
13099
13126
|
position: 'absolute',
|
|
13100
13127
|
left: 0,
|
|
13101
13128
|
zIndex: 1000000
|
|
13102
|
-
}
|
|
13129
|
+
} // Changed height from HEADER_HEIGHT - 24 to HEADER_HEIGHT for consistency
|
|
13130
|
+
,
|
|
13131
|
+
|
|
13103
13132
|
className: "flex-row dashboard-header",
|
|
13104
13133
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
13105
13134
|
className: "flex flex-column justify-center flex-1",
|
|
@@ -13160,15 +13189,6 @@ function PdfView(_ref2) {
|
|
|
13160
13189
|
}))]
|
|
13161
13190
|
});
|
|
13162
13191
|
}
|
|
13163
|
-
PdfView.propTypes = {
|
|
13164
|
-
config: PropTypes__default["default"].array,
|
|
13165
|
-
customClassName: PropTypes__default["default"].any,
|
|
13166
|
-
title: PropTypes__default["default"].string,
|
|
13167
|
-
imgSrc: PropTypes__default["default"].string,
|
|
13168
|
-
userId: PropTypes__default["default"].string,
|
|
13169
|
-
accountId: PropTypes__default["default"].string,
|
|
13170
|
-
documentId: PropTypes__default["default"].string
|
|
13171
|
-
};
|
|
13172
13192
|
|
|
13173
13193
|
const ajaxSelectFieldData = async (value, config, getApiBaseUrl = () => {}, getAppHeader = () => {}, app, formValues = {}) => {
|
|
13174
13194
|
const url = getApiBaseUrl();
|
|
@@ -15269,7 +15289,11 @@ function Widget(_ref) {
|
|
|
15269
15289
|
className: "flex justify-content-end",
|
|
15270
15290
|
children: /*#__PURE__*/jsxRuntime.jsx(antd.Button, {
|
|
15271
15291
|
size: "small",
|
|
15272
|
-
className: "
|
|
15292
|
+
className: "squareIconButton no-min-width",
|
|
15293
|
+
style: {
|
|
15294
|
+
height: '25px',
|
|
15295
|
+
width: '25px'
|
|
15296
|
+
},
|
|
15273
15297
|
onClick: handleCollapseToggle,
|
|
15274
15298
|
icon: isCollapsed ? /*#__PURE__*/jsxRuntime.jsx(Icons.RightOutlined, {
|
|
15275
15299
|
style: {
|
|
@@ -20375,6 +20399,9 @@ const Label = dt.span`
|
|
|
20375
20399
|
const {
|
|
20376
20400
|
Meta
|
|
20377
20401
|
} = antd.Card;
|
|
20402
|
+
const {
|
|
20403
|
+
useToken: useToken$h
|
|
20404
|
+
} = antd.theme;
|
|
20378
20405
|
function ProjectWidget(_ref) {
|
|
20379
20406
|
let {
|
|
20380
20407
|
title,
|
|
@@ -20387,10 +20414,17 @@ function ProjectWidget(_ref) {
|
|
|
20387
20414
|
hideSDGList = false,
|
|
20388
20415
|
t = x => x
|
|
20389
20416
|
} = _ref;
|
|
20417
|
+
const [isHovered, setIsHovered] = React__default["default"].useState(false);
|
|
20418
|
+
const {
|
|
20419
|
+
token
|
|
20420
|
+
} = useToken$h();
|
|
20390
20421
|
return /*#__PURE__*/jsxRuntime.jsxs(antd.Card, {
|
|
20391
20422
|
style: {
|
|
20392
20423
|
flex: 1
|
|
20393
20424
|
},
|
|
20425
|
+
hoverable: true,
|
|
20426
|
+
onMouseEnter: () => setIsHovered(true),
|
|
20427
|
+
onMouseLeave: () => setIsHovered(false),
|
|
20394
20428
|
cover: /*#__PURE__*/jsxRuntime.jsxs(ImageContainer, {
|
|
20395
20429
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
20396
20430
|
className: "image",
|
|
@@ -20404,7 +20438,7 @@ function ProjectWidget(_ref) {
|
|
|
20404
20438
|
name: linkIcon,
|
|
20405
20439
|
width: 16,
|
|
20406
20440
|
height: 16,
|
|
20407
|
-
color: "black"
|
|
20441
|
+
color: isHovered ? token.colorPrimary7 : "black"
|
|
20408
20442
|
})
|
|
20409
20443
|
})]
|
|
20410
20444
|
}),
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
// Dashboard/PdfView/index.jsx
|
|
1
2
|
import moment from "moment";
|
|
2
3
|
import PropTypes from 'prop-types';
|
|
3
4
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
5
|
import { formatClassname } from "../../../../../helpers/ClassesHelper";
|
|
5
6
|
|
|
6
7
|
const PAGE_HEIGHT = 1587;
|
|
7
|
-
// margin-top: 20, bottom: 20;
|
|
8
8
|
const FOOTER_HEIGHT = 70;
|
|
9
9
|
const HEADER_HEIGHT = 100;
|
|
10
|
+
const ROW_SPACING = 24; // Spacing between content rows
|
|
11
|
+
const CONTENT_BOTTOM_PADDING = 30; // Extra padding at the very bottom of the last section of the document
|
|
10
12
|
|
|
11
13
|
const Row = ({ widgets, i, onChangeHeight = () => { } }) => {
|
|
12
14
|
const ref = useRef();
|
|
@@ -55,49 +57,81 @@ export default function PdfView({
|
|
|
55
57
|
let _pages = [1];
|
|
56
58
|
let _page = 1;
|
|
57
59
|
|
|
60
|
+
// The total vertical space available for flowing content on each page,
|
|
61
|
+
// considering that HEADER_HEIGHT and FOOTER_HEIGHT are for absolutely positioned elements
|
|
62
|
+
// and content should flow between them.
|
|
63
|
+
const usableContentHeightPerPage = PAGE_HEIGHT - HEADER_HEIGHT - FOOTER_HEIGHT;
|
|
64
|
+
|
|
58
65
|
if (keys.length === config.length) {
|
|
59
|
-
let
|
|
66
|
+
let currentFlowHeight = 0; // Tracks height accumulated within the `usableContentHeightPerPage` for the current page
|
|
60
67
|
|
|
68
|
+
// Reset all margins/paddings first for a clean slate
|
|
61
69
|
keys.forEach(k => {
|
|
62
70
|
const { ref } = sectionsConfig[k];
|
|
63
|
-
ref.current
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
if (ref.current) {
|
|
72
|
+
ref.current.style.marginBottom = '0px';
|
|
73
|
+
ref.current.style.marginTop = '0px';
|
|
74
|
+
ref.current.style.paddingBottom = '0px';
|
|
75
|
+
}
|
|
76
|
+
});
|
|
66
77
|
|
|
67
78
|
keys.forEach((k, i) => {
|
|
68
79
|
const { height, ref } = sectionsConfig[k];
|
|
80
|
+
if (!ref.current) return; // Skip if ref is not available yet
|
|
69
81
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
let sectionTopMargin = ROW_SPACING; // Default margin for sections that follow another on the same page
|
|
83
|
+
|
|
84
|
+
// The first section on *any* page (either global first or first on a new page)
|
|
85
|
+
// needs to be offset by HEADER_HEIGHT from the top of the page.
|
|
86
|
+
if (i === 0 || currentFlowHeight === 0) {
|
|
87
|
+
sectionTopMargin = HEADER_HEIGHT;
|
|
73
88
|
}
|
|
74
89
|
|
|
75
|
-
|
|
90
|
+
// Calculate the total height this section would occupy *including its immediate top margin and its own height*.
|
|
91
|
+
let totalHeightForThisSection = sectionTopMargin + height;
|
|
76
92
|
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
// If it's not the very last section of the document, add the standard row spacing.
|
|
94
|
+
if (i < keys.length - 1) {
|
|
95
|
+
totalHeightForThisSection += ROW_SPACING;
|
|
96
|
+
} else {
|
|
97
|
+
// For the very last section, add the document-level bottom padding.
|
|
98
|
+
totalHeightForThisSection += CONTENT_BOTTOM_PADDING;
|
|
79
99
|
}
|
|
80
100
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
// Check if placing this section (with its calculated space) on the current page
|
|
102
|
+
// would exceed the usable content area for a theoretical page.
|
|
103
|
+
if (currentFlowHeight + totalHeightForThisSection > usableContentHeightPerPage) {
|
|
104
|
+
// This section overflows, so it starts on a new page.
|
|
84
105
|
_page += 1;
|
|
85
106
|
_pages.push(_page);
|
|
86
107
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
108
|
+
// Reset flow height for the new page.
|
|
109
|
+
// This section is now the first on a new page, so its top margin is HEADER_HEIGHT.
|
|
110
|
+
ref.current.style.marginTop = `${HEADER_HEIGHT}px`;
|
|
111
|
+
currentFlowHeight = HEADER_HEIGHT + height; // Start accumulated height for new page
|
|
112
|
+
|
|
113
|
+
// Add row spacing or bottom padding for this section on its new page
|
|
114
|
+
if (i < keys.length - 1) {
|
|
115
|
+
currentFlowHeight += ROW_SPACING;
|
|
116
|
+
} else {
|
|
117
|
+
ref.current.style.paddingBottom = `${CONTENT_BOTTOM_PADDING}px`;
|
|
118
|
+
currentFlowHeight += CONTENT_BOTTOM_PADDING;
|
|
92
119
|
}
|
|
120
|
+
|
|
93
121
|
} else {
|
|
94
|
-
|
|
122
|
+
// This section fits on the current page.
|
|
123
|
+
ref.current.style.marginTop = `${sectionTopMargin}px`;
|
|
124
|
+
currentFlowHeight += totalHeightForThisSection; // Accumulate the height this section takes
|
|
125
|
+
|
|
126
|
+
// Apply special padding for the very last section of the document if it fits on current page
|
|
127
|
+
if (i === keys.length - 1) {
|
|
128
|
+
ref.current.style.paddingBottom = `${CONTENT_BOTTOM_PADDING}px`;
|
|
129
|
+
}
|
|
95
130
|
}
|
|
96
|
-
|
|
97
|
-
})
|
|
131
|
+
});
|
|
98
132
|
setPages(_pages);
|
|
99
133
|
}
|
|
100
|
-
}, [sectionsConfig]);
|
|
134
|
+
}, [sectionsConfig, config.length]);
|
|
101
135
|
|
|
102
136
|
useEffect(() => {
|
|
103
137
|
doSizing();
|
|
@@ -128,22 +162,13 @@ export default function PdfView({
|
|
|
128
162
|
);
|
|
129
163
|
}, [config, onChangeHeight]);
|
|
130
164
|
|
|
131
|
-
// <div className="daf-analysis">
|
|
132
|
-
// <Header title={t('Dashboard Title')} />
|
|
133
|
-
|
|
134
|
-
// <div className="content">
|
|
135
|
-
// <div className="view-content">
|
|
136
|
-
// <div className="daf-analysis-layout">
|
|
137
|
-
// <div className='sections-cont w-pt'>
|
|
138
|
-
// <section>
|
|
139
|
-
|
|
140
165
|
return (
|
|
141
166
|
<div className={contClassName} style={{ position: 'relative' }}>
|
|
142
167
|
{renderDashboard()}
|
|
143
168
|
{pages.map((page) => (
|
|
144
169
|
<>
|
|
145
170
|
<div
|
|
146
|
-
style={{ top: ((page - 1) * PAGE_HEIGHT), width: '100%', height: HEADER_HEIGHT
|
|
171
|
+
style={{ top: ((page - 1) * PAGE_HEIGHT), width: '100%', height: HEADER_HEIGHT, position: 'absolute', left: 0, zIndex: 1000000 }} // Changed height from HEADER_HEIGHT - 24 to HEADER_HEIGHT for consistency
|
|
147
172
|
key={`headers-${page}`}
|
|
148
173
|
className="flex-row dashboard-header"
|
|
149
174
|
>
|
|
@@ -194,14 +219,4 @@ export default function PdfView({
|
|
|
194
219
|
))}
|
|
195
220
|
</div>
|
|
196
221
|
);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
PdfView.propTypes = {
|
|
200
|
-
config: PropTypes.array,
|
|
201
|
-
customClassName: PropTypes.any,
|
|
202
|
-
title: PropTypes.string,
|
|
203
|
-
imgSrc: PropTypes.string,
|
|
204
|
-
userId: PropTypes.string,
|
|
205
|
-
accountId: PropTypes.string,
|
|
206
|
-
documentId: PropTypes.string,
|
|
207
|
-
}
|
|
222
|
+
}
|