@db-ux/react-core-components 3.0.0 → 3.0.1

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.
@@ -14,7 +14,7 @@ function DBCheckboxFn(props, component) {
14
14
  const [_validMessageId, set_validMessageId] = useState(() => undefined);
15
15
  const [_invalidMessageId, set_invalidMessageId] = useState(() => undefined);
16
16
  const [_invalidMessage, set_invalidMessage] = useState(() => undefined);
17
- const [_descByIds, set_descByIds] = useState(() => "");
17
+ const [_descByIds, set_descByIds] = useState(() => undefined);
18
18
  const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
19
19
  function hasValidState() {
20
20
  var _a;
@@ -46,7 +46,7 @@ function DBCheckboxFn(props, component) {
46
46
  set_descByIds(_messageId);
47
47
  }
48
48
  else {
49
- set_descByIds("");
49
+ set_descByIds(undefined);
50
50
  }
51
51
  }
52
52
  function handleChange(event) {
@@ -90,6 +90,7 @@ function DBCheckboxFn(props, component) {
90
90
  if (stringPropVisible(props.message, props.showMessage)) {
91
91
  set_descByIds(messageId);
92
92
  }
93
+ handleValidation();
93
94
  }
94
95
  }, [_id]);
95
96
  useEffect(() => {
@@ -34,7 +34,8 @@ function DBCustomSelectFn(props, component) {
34
34
  const [_placeholderId, set_placeholderId] = useState(() => undefined);
35
35
  const [_infoTextId, set_infoTextId] = useState(() => undefined);
36
36
  const [_validity, set_validity] = useState(() => "no-validation");
37
- const [_descByIds, set_descByIds] = useState(() => "");
37
+ const [_userInteraction, set_userInteraction] = useState(() => false);
38
+ const [_descByIds, set_descByIds] = useState(() => undefined);
38
39
  const [_selectedLabels, set_selectedLabels] = useState(() => "");
39
40
  const [_selectedLabelsId, set_selectedLabelsId] = useState(() => undefined);
40
41
  const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
@@ -76,7 +77,9 @@ function DBCustomSelectFn(props, component) {
76
77
  set_voiceOverFallback(_invalidMessage);
77
78
  delay(() => set_voiceOverFallback(""), 1000);
78
79
  }
79
- set_validity((_c = props.validation) !== null && _c !== void 0 ? _c : "invalid");
80
+ if (_userInteraction) {
81
+ set_validity((_c = props.validation) !== null && _c !== void 0 ? _c : "invalid");
82
+ }
80
83
  }
81
84
  else if (hasValidState() &&
82
85
  ((_d = selectRef.current) === null || _d === void 0 ? void 0 : _d.validity.valid) &&
@@ -300,6 +303,7 @@ function DBCustomSelectFn(props, component) {
300
303
  if (skip)
301
304
  return;
302
305
  set_values(values);
306
+ set_userInteraction(true);
303
307
  if (props.onOptionSelected) {
304
308
  props.onOptionSelected(values !== null && values !== void 0 ? values : []);
305
309
  }
@@ -485,7 +489,7 @@ function DBCustomSelectFn(props, component) {
485
489
  else if (_options) {
486
490
  set_hasNoOptions(_options.length === 0);
487
491
  }
488
- }, [props.showNoResults, _options]);
492
+ }, [props.showNoResults, props.showLoading, _options]);
489
493
  useEffect(() => {
490
494
  var _a;
491
495
  setSelectAllEnabled(Boolean(props.multiple && ((_a = props.showSelectAll) !== null && _a !== void 0 ? _a : amountOptions > 5)));
@@ -503,8 +507,10 @@ function DBCustomSelectFn(props, component) {
503
507
  }
504
508
  }, [props.values]);
505
509
  useEffect(() => {
506
- handleValidation();
507
- }, [_values]);
510
+ if (selectRef.current) {
511
+ handleValidation();
512
+ }
513
+ }, [_values, selectRef.current]);
508
514
  useEffect(() => {
509
515
  set_validity(props.validation);
510
516
  }, [props.validation]);
@@ -611,7 +617,9 @@ function DBCustomSelectFn(props, component) {
611
617
  React.createElement(DBInput, { type: "search", ref: searchInputRef, name: _id, form: _id, showLabel: false, value: _searchValue, label: (_d = props.searchLabel) !== null && _d !== void 0 ? _d : DEFAULT_LABEL, placeholder: (_e = props.searchPlaceholder) !== null && _e !== void 0 ? _e : props.searchLabel, ariaDescribedBy: _hasNoOptions || props.showLoading
612
618
  ? _infoTextId
613
619
  : undefined, onInput: (event) => handleSearch(event) }))) : null,
614
- _hasNoOptions || props.showLoading ? (React.createElement(DBInfotext, { id: _infoTextId, icon: _hasNoOptions ? undefined : "circular_arrows", semantic: _hasNoOptions ? "warning" : "informational" }, (_f = (_hasNoOptions ? props.noResultsText : props.loadingText)) !== null && _f !== void 0 ? _f : DEFAULT_MESSAGE)) : (React.createElement(React.Fragment, null,
620
+ _hasNoOptions || props.showLoading ? (React.createElement(DBInfotext, { id: _infoTextId, icon: props.showLoading ? "circular_arrows" : undefined, semantic: props.showLoading ? "informational" : "warning" }, (_f = (props.showLoading
621
+ ? props.loadingText
622
+ : props.noResultsText)) !== null && _f !== void 0 ? _f : DEFAULT_MESSAGE)) : (React.createElement(React.Fragment, null,
615
623
  React.createElement(React.Fragment, null,
616
624
  selectAllEnabled ? (React.createElement("div", null,
617
625
  React.createElement("div", { className: "db-checkbox db-custom-select-list-item" },
@@ -190,6 +190,7 @@ export type DBCustomSelectDefaultState = {
190
190
  _internalChangeTimestamp: number;
191
191
  _documentClickListenerCallbackId?: string;
192
192
  _searchValue?: string;
193
+ _userInteraction?: boolean;
193
194
  getNativeSelectValue: () => string;
194
195
  getOptionLabel: (option: CustomSelectOptionType) => string;
195
196
  getOptionChecked: (value?: string) => boolean;
@@ -2,15 +2,14 @@
2
2
  import * as React from "react";
3
3
  import { filterPassingProps, getRootProps } from "../../utils/react";
4
4
  import { useState, useRef, useEffect, forwardRef } from "react";
5
- import { DEFAULT_BURGER_MENU, DEFAULT_ID } from "../../shared/constants";
6
- import { addAttributeToChildren, cls, getBoolean, uuid } from "../../utils";
5
+ import { DEFAULT_BURGER_MENU } from "../../shared/constants";
6
+ import { addAttributeToChildren, cls, getBoolean } from "../../utils";
7
7
  import { isEventTargetNavigationItem } from "../../utils/navigation";
8
8
  import DBButton from "../button/button";
9
9
  import DBDrawer from "../drawer/drawer";
10
10
  function DBHeaderFn(props, component) {
11
11
  var _a;
12
12
  const _ref = component || useRef(component);
13
- const [_id, set_id] = useState(() => DEFAULT_ID);
14
13
  const [initialized, setInitialized] = useState(() => false);
15
14
  const [forcedToMobile, setForcedToMobile] = useState(() => false);
16
15
  function handleToggle(event) {
@@ -29,23 +28,19 @@ function DBHeaderFn(props, component) {
29
28
  }
30
29
  useEffect(() => {
31
30
  setInitialized(true);
32
- set_id(props.id || "header-" + uuid());
33
31
  }, []);
34
32
  useEffect(() => {
35
- if (initialized && document && _id && props.forceMobile) {
36
- const headerElement = document.getElementById(_id !== null && _id !== void 0 ? _id : "");
37
- if (headerElement) {
38
- // Adds this attribute to the header to enable all styling which would have
39
- // @media screen and (min-width: $db-screens-m) to show mobile navigation on a desktop device
40
- addAttributeToChildren(headerElement, {
41
- key: "data-force-mobile",
42
- value: "true",
43
- });
44
- }
33
+ if (initialized && _ref.current && props.forceMobile) {
34
+ // Adds this attribute to the header to enable all styling which would have
35
+ // @media screen and (min-width: $db-screens-m) to show mobile navigation on a desktop device
36
+ addAttributeToChildren(_ref.current, {
37
+ key: "data-force-mobile",
38
+ value: "true",
39
+ });
45
40
  setForcedToMobile(true);
46
41
  }
47
- }, [initialized]);
48
- return (React.createElement("header", Object.assign({ ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font", "onToggle"]), getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-header", props.className), id: _id, "data-width": props.width, "data-on-forcing-mobile": props.forceMobile && !forcedToMobile }),
42
+ }, [initialized, _ref.current]);
43
+ return (React.createElement("header", Object.assign({ ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font", "onToggle"]), getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-header", props.className), id: props.id, "data-width": props.width, "data-on-forcing-mobile": props.forceMobile && !forcedToMobile }),
49
44
  React.createElement(DBDrawer, { className: "db-header-drawer", spacing: "small", rounded: true, open: getBoolean(props.drawerOpen), onClose: (event) => handleToggle() },
50
45
  React.createElement("div", { className: "db-header-drawer-navigation" },
51
46
  React.createElement("div", { className: "db-header-navigation", onClick: (event) => handleNavigationItemClick(event) }, props.children),
@@ -64,7 +59,7 @@ function DBHeaderFn(props, component) {
64
59
  React.createElement(React.Fragment, null, props.primaryAction))),
65
60
  React.createElement("div", { className: "db-header-action-container" },
66
61
  React.createElement("div", { className: "db-header-burger-menu-container" },
67
- React.createElement(DBButton, { icon: "menu", variant: "ghost", id: _id + "-burger-menu", noText: true, onClick: (event) => handleToggle() }, (_a = props.burgerMenuLabel) !== null && _a !== void 0 ? _a : DEFAULT_BURGER_MENU)),
62
+ React.createElement(DBButton, { icon: "menu", variant: "ghost", noText: true, onClick: (event) => handleToggle() }, (_a = props.burgerMenuLabel) !== null && _a !== void 0 ? _a : DEFAULT_BURGER_MENU)),
68
63
  React.createElement("div", { className: "db-header-secondary-action" },
69
64
  React.createElement(React.Fragment, null, props.secondaryAction))))));
70
65
  }
@@ -14,8 +14,8 @@ function DBInputFn(props, component) {
14
14
  const [_invalidMessageId, set_invalidMessageId] = useState(() => undefined);
15
15
  const [_invalidMessage, set_invalidMessage] = useState(() => undefined);
16
16
  const [_dataListId, set_dataListId] = useState(() => undefined);
17
- const [_descByIds, set_descByIds] = useState(() => "");
18
- const [_value, set_value] = useState(() => "");
17
+ const [_descByIds, set_descByIds] = useState(() => undefined);
18
+ const [_value, set_value] = useState(() => undefined);
19
19
  const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
20
20
  function hasValidState() {
21
21
  var _a;
@@ -47,7 +47,7 @@ function DBInputFn(props, component) {
47
47
  set_descByIds(_messageId);
48
48
  }
49
49
  else {
50
- set_descByIds("");
50
+ set_descByIds(undefined);
51
51
  }
52
52
  }
53
53
  function handleInput(event) {
@@ -108,6 +108,7 @@ function DBInputFn(props, component) {
108
108
  if (stringPropVisible(props.message, props.showMessage)) {
109
109
  set_descByIds(messageId);
110
110
  }
111
+ handleValidation();
111
112
  }
112
113
  }, [_id]);
113
114
  useEffect(() => {
@@ -14,7 +14,7 @@ function DBSelectFn(props, component) {
14
14
  const [_invalidMessageId, set_invalidMessageId] = useState(() => undefined);
15
15
  const [_invalidMessage, set_invalidMessage] = useState(() => undefined);
16
16
  const [_placeholderId, set_placeholderId] = useState(() => "");
17
- const [_descByIds, set_descByIds] = useState(() => "");
17
+ const [_descByIds, set_descByIds] = useState(() => undefined);
18
18
  const [_value, set_value] = useState(() => "");
19
19
  const [initialized, setInitialized] = useState(() => false);
20
20
  const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
@@ -113,6 +113,7 @@ function DBSelectFn(props, component) {
113
113
  else {
114
114
  set_descByIds(placeholderId);
115
115
  }
116
+ handleValidation();
116
117
  setInitialized(false);
117
118
  }
118
119
  }, [_id, initialized]);
@@ -13,7 +13,7 @@ function DBTextareaFn(props, component) {
13
13
  const [_validMessageId, set_validMessageId] = useState(() => undefined);
14
14
  const [_invalidMessageId, set_invalidMessageId] = useState(() => undefined);
15
15
  const [_invalidMessage, set_invalidMessage] = useState(() => undefined);
16
- const [_descByIds, set_descByIds] = useState(() => "");
16
+ const [_descByIds, set_descByIds] = useState(() => undefined);
17
17
  const [_value, set_value] = useState(() => "");
18
18
  const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
19
19
  function hasValidState() {
@@ -46,7 +46,7 @@ function DBTextareaFn(props, component) {
46
46
  set_descByIds(_messageId);
47
47
  }
48
48
  else {
49
- set_descByIds("");
49
+ set_descByIds(undefined);
50
50
  }
51
51
  }
52
52
  function handleInput(event) {
@@ -95,6 +95,7 @@ function DBTextareaFn(props, component) {
95
95
  if (stringPropVisible(props.message, props.showMessage)) {
96
96
  set_descByIds(messageId);
97
97
  }
98
+ handleValidation();
98
99
  }
99
100
  }, [_id]);
100
101
  useEffect(() => {
package/dist/index.d.ts CHANGED
@@ -1,40 +1,79 @@
1
1
  export * from './components/accordion';
2
2
  export * from './components/accordion-item';
3
+ export * from './components/accordion-item/model';
4
+ export * from './components/accordion/model';
3
5
  export * from './components/badge';
6
+ export * from './components/badge/model';
4
7
  export * from './components/brand';
8
+ export * from './components/brand/model';
5
9
  export * from './components/button';
10
+ export * from './components/button/model';
6
11
  export * from './components/card';
12
+ export * from './components/card/model';
7
13
  export * from './components/checkbox';
14
+ export * from './components/checkbox/model';
8
15
  export * from './components/custom-select';
9
16
  export * from './components/custom-select-dropdown';
17
+ export * from './components/custom-select-dropdown/model';
10
18
  export * from './components/custom-select-form-field';
19
+ export * from './components/custom-select-form-field/model';
11
20
  export * from './components/custom-select-list';
12
21
  export * from './components/custom-select-list-item';
22
+ export * from './components/custom-select-list-item/model';
23
+ export * from './components/custom-select-list/model';
24
+ export * from './components/custom-select/model';
13
25
  export * from './components/divider';
26
+ export * from './components/divider/model';
14
27
  export * from './components/drawer';
28
+ export * from './components/drawer/model';
15
29
  export * from './components/header';
30
+ export * from './components/header/model';
16
31
  export * from './components/icon';
32
+ export * from './components/icon/model';
17
33
  export * from './components/infotext';
34
+ export * from './components/infotext/model';
18
35
  export * from './components/input';
36
+ export * from './components/input/model';
19
37
  export * from './components/link';
38
+ export * from './components/link/model';
20
39
  export * from './components/navigation';
21
40
  export * from './components/navigation-item';
41
+ export * from './components/navigation-item/model';
42
+ export * from './components/navigation/model';
22
43
  export * from './components/notification';
44
+ export * from './components/notification/model';
23
45
  export * from './components/page';
46
+ export * from './components/page/model';
24
47
  export * from './components/popover';
48
+ export * from './components/popover/model';
25
49
  export * from './components/radio';
50
+ export * from './components/radio/model';
26
51
  export * from './components/section';
52
+ export * from './components/section/model';
27
53
  export * from './components/select';
54
+ export * from './components/select/model';
28
55
  export * from './components/stack';
56
+ export * from './components/stack/model';
29
57
  export * from './components/switch';
58
+ export * from './components/switch/model';
30
59
  export * from './components/tab-item';
60
+ export * from './components/tab-item/model';
31
61
  export * from './components/tab-list';
62
+ export * from './components/tab-list/model';
32
63
  export * from './components/tab-panel';
64
+ export * from './components/tab-panel/model';
33
65
  export * from './components/tabs';
66
+ export * from './components/tabs/model';
34
67
  export * from './components/tag';
68
+ export * from './components/tag/model';
35
69
  export * from './components/textarea';
70
+ export * from './components/textarea/model';
36
71
  export * from './components/tooltip';
72
+ export * from './components/tooltip/model';
37
73
  export * from './shared/constants';
38
74
  export * from './shared/model';
75
+ export * from './utils/document-click-listener';
76
+ export * from './utils/document-scroll-listener';
77
+ export * from './utils/floating-components';
39
78
  export * from './utils/index';
40
79
  export * from './utils/navigation';
package/dist/index.js CHANGED
@@ -1,40 +1,79 @@
1
1
  export * from './components/accordion';
2
2
  export * from './components/accordion-item';
3
+ export * from './components/accordion-item/model';
4
+ export * from './components/accordion/model';
3
5
  export * from './components/badge';
6
+ export * from './components/badge/model';
4
7
  export * from './components/brand';
8
+ export * from './components/brand/model';
5
9
  export * from './components/button';
10
+ export * from './components/button/model';
6
11
  export * from './components/card';
12
+ export * from './components/card/model';
7
13
  export * from './components/checkbox';
14
+ export * from './components/checkbox/model';
8
15
  export * from './components/custom-select';
9
16
  export * from './components/custom-select-dropdown';
17
+ export * from './components/custom-select-dropdown/model';
10
18
  export * from './components/custom-select-form-field';
19
+ export * from './components/custom-select-form-field/model';
11
20
  export * from './components/custom-select-list';
12
21
  export * from './components/custom-select-list-item';
22
+ export * from './components/custom-select-list-item/model';
23
+ export * from './components/custom-select-list/model';
24
+ export * from './components/custom-select/model';
13
25
  export * from './components/divider';
26
+ export * from './components/divider/model';
14
27
  export * from './components/drawer';
28
+ export * from './components/drawer/model';
15
29
  export * from './components/header';
30
+ export * from './components/header/model';
16
31
  export * from './components/icon';
32
+ export * from './components/icon/model';
17
33
  export * from './components/infotext';
34
+ export * from './components/infotext/model';
18
35
  export * from './components/input';
36
+ export * from './components/input/model';
19
37
  export * from './components/link';
38
+ export * from './components/link/model';
20
39
  export * from './components/navigation';
21
40
  export * from './components/navigation-item';
41
+ export * from './components/navigation-item/model';
42
+ export * from './components/navigation/model';
22
43
  export * from './components/notification';
44
+ export * from './components/notification/model';
23
45
  export * from './components/page';
46
+ export * from './components/page/model';
24
47
  export * from './components/popover';
48
+ export * from './components/popover/model';
25
49
  export * from './components/radio';
50
+ export * from './components/radio/model';
26
51
  export * from './components/section';
52
+ export * from './components/section/model';
27
53
  export * from './components/select';
54
+ export * from './components/select/model';
28
55
  export * from './components/stack';
56
+ export * from './components/stack/model';
29
57
  export * from './components/switch';
58
+ export * from './components/switch/model';
30
59
  export * from './components/tab-item';
60
+ export * from './components/tab-item/model';
31
61
  export * from './components/tab-list';
62
+ export * from './components/tab-list/model';
32
63
  export * from './components/tab-panel';
64
+ export * from './components/tab-panel/model';
33
65
  export * from './components/tabs';
66
+ export * from './components/tabs/model';
34
67
  export * from './components/tag';
68
+ export * from './components/tag/model';
35
69
  export * from './components/textarea';
70
+ export * from './components/textarea/model';
36
71
  export * from './components/tooltip';
72
+ export * from './components/tooltip/model';
37
73
  export * from './shared/constants';
38
74
  export * from './shared/model';
75
+ export * from './utils/document-click-listener';
76
+ export * from './utils/document-scroll-listener';
77
+ export * from './utils/floating-components';
39
78
  export * from './utils/index';
40
79
  export * from './utils/navigation';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@db-ux/react-core-components",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "React components for @db-ux/core-components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,22 +15,22 @@
15
15
  ],
16
16
  "scripts": {
17
17
  "build": "npm-run-all tsc",
18
- "mv:dist": "cpr dist ../../build-outputs/react/dist -o",
19
- "mv:package.json": "cpr package.json ../../build-outputs/react/package.json -o",
20
- "mv:readme": "cpr README.md ../../build-outputs/react/README.md -o",
18
+ "mv:dist": "cpr dist ../../build-outputs/react/dist --overwrite",
19
+ "mv:package.json": "cpr package.json ../../build-outputs/react/package.json --overwrite",
20
+ "mv:readme": "cpr README.md ../../build-outputs/react/README.md --overwrite",
21
21
  "open:report": "npx playwright show-report",
22
22
  "postbuild": "npm-run-all --parallel mv:*",
23
- "regenerate:screenshots": "playwright test -c playwright.config.ts --update-snapshots",
24
- "test:components": "playwright test -c playwright.config.ts",
25
- "test:windows": "playwright test -c playwright.screen-reader.win.ts",
26
- "test:components:ui": "playwright test -c playwright.config.ts --ui",
27
- "tsc": "tsc -p . --sourceMap false"
23
+ "regenerate:screenshots": "playwright test --config playwright.config.ts --update-snapshots",
24
+ "test:components": "playwright test --config playwright.config.ts",
25
+ "test:windows": "playwright test --config playwright.screen-reader.win.ts",
26
+ "test:components:ui": "playwright test --config playwright.config.ts --ui",
27
+ "tsc": "tsc --project . --sourceMap false"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@playwright/experimental-ct-react": "1.54.1",
31
- "@types/react": "^18.3.13",
32
- "react": "^18.3.1",
33
- "react-dom": "^18.3.1"
31
+ "@types/react": "18.3.13",
32
+ "react": "18.3.1",
33
+ "react-dom": "18.3.1"
34
34
  },
35
35
  "publishConfig": {
36
36
  "registry": "https://registry.npmjs.org/",
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "sideEffects": false,
40
40
  "dependencies": {
41
- "@db-ux/core-components": "3.0.0",
42
- "@db-ux/core-foundations": "3.0.0"
41
+ "@db-ux/core-components": "3.0.1",
42
+ "@db-ux/core-foundations": "3.0.1"
43
43
  }
44
44
  }