@marigold/system 0.9.0 → 1.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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Simplify, PolymorphicPropsWithRef, PolymorphicComponentWithRef, ComponentProps } from '@marigold/types';
1
+ import { Simplify, PolymorphicPropsWithRef, PolymorphicComponentWithRef, ComponentProps, KebabCase } from '@marigold/types';
2
2
  import * as _theme_ui_css from '@theme-ui/css';
3
3
  import { ResponsiveStyleValue as ResponsiveStyleValue$1, ThemeUIStyleObject, ThemeUICSSObject, ThemeUICSSProperties, NestedScaleDict } from '@theme-ui/css';
4
4
  import * as react from 'react';
@@ -10,28 +10,6 @@ declare type StyleObject = ThemeUIStyleObject;
10
10
  declare type CSSObject = Simplify<ThemeUICSSObject>;
11
11
  declare type CSSProperties = Simplify<ThemeUICSSProperties>;
12
12
 
13
- interface StyleProps extends Pick<CSSObject, 'display' | 'height' | 'width' | 'minWidth' | 'maxWidth' | 'position' | 'top' | 'bottom' | 'right' | 'left' | 'zIndex' | 'p' | 'px' | 'py' | 'pt' | 'pb' | 'pl' | 'pr' | 'm' | 'mx' | 'my' | 'mt' | 'mb' | 'ml' | 'mr' | 'flexDirection' | 'flexWrap' | 'flexShrink' | 'flexGrow' | 'alignItems' | 'justifyContent' | 'bg' | 'border' | 'borderRadius' | 'boxShadow' | 'opacity' | 'overflow' | 'transition'> {
14
- }
15
- interface BoxOwnProps extends StyleProps {
16
- css?: CSSObject;
17
- variant?: string | string[];
18
- /**
19
- * Use to set base styles for the component
20
- * @internal Used to set default styles for Marigold components
21
- */
22
- __baseCSS?: CSSObject;
23
- }
24
- interface BoxProps extends PolymorphicPropsWithRef<BoxOwnProps, 'div'> {
25
- }
26
- declare const Box: PolymorphicComponentWithRef<BoxOwnProps, 'div'>;
27
-
28
- declare const Global: () => JSX.Element;
29
-
30
- interface SVGProps extends ComponentProps<'svg'> {
31
- size?: number | string | number[] | string[];
32
- }
33
- declare const SVG: ({ size, fill, children, ...props }: SVGProps) => react.ReactSVGElement;
34
-
35
13
  /**
36
14
  * Props that every component should accepts to change the styling
37
15
  */
@@ -219,6 +197,27 @@ interface Theme {
219
197
  transitions?: Scale<CSS.Property.Transition>;
220
198
  }
221
199
 
200
+ interface StyleProps extends Pick<CSSObject, 'display' | 'height' | 'width' | 'minWidth' | 'maxWidth' | 'position' | 'top' | 'bottom' | 'right' | 'left' | 'zIndex' | 'p' | 'px' | 'py' | 'pt' | 'pb' | 'pl' | 'pr' | 'm' | 'mx' | 'my' | 'mt' | 'mb' | 'ml' | 'mr' | 'flexDirection' | 'flexWrap' | 'flexShrink' | 'flexGrow' | 'alignItems' | 'justifyContent' | 'bg' | 'border' | 'borderRadius' | 'boxShadow' | 'opacity' | 'overflow' | 'transition'> {
201
+ }
202
+ interface BoxOwnProps extends StyleProps {
203
+ css?: CSSObject;
204
+ /**
205
+ * Use to set base styles for the component
206
+ * @internal
207
+ */
208
+ __baseCSS?: CSSObject;
209
+ }
210
+ interface BoxProps extends PolymorphicPropsWithRef<BoxOwnProps, 'div'> {
211
+ }
212
+ declare const Box: PolymorphicComponentWithRef<BoxOwnProps, 'div'>;
213
+
214
+ declare const Global: () => JSX.Element;
215
+
216
+ interface SVGProps extends ComponentProps<'svg'> {
217
+ size?: number | string | number[] | string[];
218
+ }
219
+ declare const SVG: ({ size, fill, children, ...props }: SVGProps) => react.ReactSVGElement;
220
+
222
221
  interface ComponentStylesProps {
223
222
  variant?: string;
224
223
  size?: string;
@@ -242,8 +241,8 @@ declare function useComponentStyles<Part extends string, Parts extends ReadonlyA
242
241
  */
243
242
  declare const useResponsiveValue: <T>(values: T[], defaultIndex?: number) => T;
244
243
 
245
- declare type ComponentState = 'hover' | 'focus' | 'active' | 'visited' | 'disabled' | 'readOnly' | 'checked' | 'indeterminate' | 'error';
246
- declare type StateAttrKeyProps = `data-${Lowercase<ComponentState>}`;
244
+ declare type ComponentState = 'hover' | 'focus' | 'focusVisible' | 'active' | 'visited' | 'disabled' | 'readOnly' | 'checked' | 'selected' | 'indeterminate' | 'expanded' | 'error';
245
+ declare type StateAttrKeyProps = `data-${KebabCase<ComponentState>}`;
247
246
  declare type StateAttrProps = {
248
247
  [key in StateAttrKeyProps]?: '';
249
248
  };
@@ -421,34 +420,4 @@ declare const getNormalizedStyles: (val?: ElementType<any> | undefined) => {
421
420
  readonly minWidth: 0;
422
421
  };
423
422
 
424
- /**
425
- * Ensures that the `val` is an array. Will return an empty array if `val` is falsy.
426
- */
427
- declare const ensureArray: <T>(val?: T | T[] | undefined) => T[];
428
- /**
429
- * Removes trailing dot from variant, if necessary. This is necessary to support
430
- * `__default` styles. See https://github.com/system-ui/theme-ui/pull/951
431
- */
432
- declare const ensureVariantDefault: (val: string) => string;
433
- /**
434
- * Ensures that the `variant` is an array and supports the `__default` key.
435
- */
436
- declare const ensureArrayVariant: <T extends string>(variant?: T | T[] | undefined) => string[];
437
- interface State {
438
- checked?: boolean;
439
- focus?: boolean;
440
- hover?: boolean;
441
- disabled?: boolean;
442
- error?: boolean;
443
- }
444
- /**
445
- * Appends given `state` to a `variant`.
446
- */
447
- declare const appendVariantState: (variant: string, state: keyof State) => string;
448
- /**
449
- * Create a variant array from a `variant` and `state` containing
450
- * passed states, if they are truthy.
451
- */
452
- declare const conditional: (variant: string, { disabled, ...states }: State) => string[];
453
-
454
- export { Box, BoxOwnProps, BoxProps, CSSObject, CSSProperties, ComponentState, ComponentStyleParts, ComponentStylesProps, Global, NormalizedElement, ResponsiveStyleValue, SVG, SVGProps, Scale, ScaleValue, SizeScale, State, StateAttrKeyProps, StateAttrProps, StyleObject, StyleProps, Theme, ThemeComponentProps, ThemeExtension, ThemeExtensionsWithParts, ThemeProvider, ThemeProviderProps, UseStateProps, ZeroScale, ZeroSizeScale, __defaultTheme, appendVariantState, conditional, ensureArray, ensureArrayVariant, ensureVariantDefault, getNormalizedStyles, normalize, useComponentStyles, useResponsiveValue, useStateProps, useTheme };
423
+ export { Box, BoxOwnProps, BoxProps, CSSObject, CSSProperties, ComponentState, ComponentStyleParts, ComponentStylesProps, Global, NormalizedElement, ResponsiveStyleValue, SVG, SVGProps, Scale, ScaleValue, SizeScale, StateAttrKeyProps, StateAttrProps, StyleObject, StyleProps, Theme, ThemeComponentProps, ThemeExtension, ThemeExtensionsWithParts, ThemeProvider, ThemeProviderProps, UseStateProps, ZeroScale, ZeroSizeScale, __defaultTheme, getNormalizedStyles, normalize, useComponentStyles, useResponsiveValue, useStateProps, useTheme };
package/dist/index.js CHANGED
@@ -56,11 +56,6 @@ __export(src_exports, {
56
56
  SVG: () => SVG,
57
57
  ThemeProvider: () => ThemeProvider,
58
58
  __defaultTheme: () => __defaultTheme,
59
- appendVariantState: () => appendVariantState,
60
- conditional: () => conditional,
61
- ensureArray: () => ensureArray,
62
- ensureArrayVariant: () => ensureArrayVariant,
63
- ensureVariantDefault: () => ensureVariantDefault,
64
59
  getNormalizedStyles: () => getNormalizedStyles,
65
60
  normalize: () => normalize,
66
61
  useComponentStyles: () => useComponentStyles,
@@ -145,31 +140,45 @@ var normalize = {
145
140
  };
146
141
  var getNormalizedStyles = (val) => typeof val === "string" && val in normalize ? normalize[val] : normalize.base;
147
142
 
148
- // src/variant.ts
149
- var isNil = (value) => value === null || value === void 0;
150
- var ensureArray = (val) => isNil(val) ? [] : Array.isArray(val) ? val : [val];
151
- var ensureVariantDefault = (val) => val.replace(/\.$/, "");
152
- var ensureArrayVariant = (variant) => ensureArray(variant).map(ensureVariantDefault);
153
- var appendVariantState = (variant, state) => {
154
- return `${ensureVariantDefault(variant)}.:${state}`;
143
+ // src/components/Box/utils.ts
144
+ var createteSelector = (selectors, states, suffix = "") => {
145
+ return selectors.map((selector2) => states.map((state2) => `${selector2}${state2}${suffix ? ` ${suffix}` : ""}`)).flat().join(", ");
155
146
  };
156
- var conditional = (variant, _a) => {
157
- var _b = _a, { disabled = false } = _b, states = __objRest(_b, ["disabled"]);
158
- const entries = [...Object.entries(states), ["disabled", disabled]];
159
- const stateVariants = entries.filter(([, val]) => Boolean(val)).map(([key]) => appendVariantState(variant, key));
160
- return [variant, ...stateVariants];
147
+ var selector = {
148
+ self: "&",
149
+ grouped: ["[role=group]", "[data-group]"]
150
+ };
151
+ var state = {
152
+ none: [""],
153
+ hover: [":hover", "[data-hover]"],
154
+ focus: [":focus", "[data-focus]"],
155
+ focusVisible: [":focus-visible", "[data-focus-visible]"],
156
+ active: [":active", "[data-active]"],
157
+ disabled: ["[disabled]", "[aria-disabled=true]", "[data-disabled]"],
158
+ readOnly: ["[readonly]", "[aria-readonly=true]", "[data-read-only]"],
159
+ checked: ["[aria-checked=true]", "[data-checked]"],
160
+ indeterminate: ["[aria-checked=mixed]", "[data-indeterminate]"],
161
+ selected: ["[aria-selected=true]", "[data-selected]"],
162
+ error: [":invalid", "[aria-invalid=true]", "[data-error]"],
163
+ expanded: ["[aria-expanded=true]", "[data-expanded]"]
161
164
  };
162
-
163
- // src/components/Box/utils.ts
164
165
  var pseudos = {
165
- "&:hover": "&:hover, &[data-hover]",
166
- "&:focus": "&:focus, &[data-focus]",
167
- "&:active": "&:active, &[data-active]",
168
- "&:disabled": "&[disabled], &[aria-disabled=true], &[data-disabled]",
169
- "&:read-only": "&[readonly], &[aria-readonly=true], &[data-readonly]",
170
- "&:checked": "&[aria-checked=true], &[data-checked]",
171
- "&:indeterminate": "&:indeterminate, &[aria-checked=mixed], &[data-indeterminate]",
172
- "&:error": "&:invalid, &[aria-invalid=true], &[data-error]"
166
+ "&:hover": createteSelector([selector.self], state.hover),
167
+ "&:focus": createteSelector([selector.self], state.focus),
168
+ "&:focus-visible": createteSelector([selector.self], state.focusVisible),
169
+ "&:active": createteSelector([selector.self], state.active),
170
+ "&:disabled": createteSelector([selector.self], state.disabled),
171
+ "&:read-only": createteSelector([selector.self], state.readOnly),
172
+ "&:checked": createteSelector([selector.self], state.checked),
173
+ "&:selected": createteSelector([selector.self], state.selected),
174
+ "&:indeterminate": createteSelector([selector.self], state.indeterminate),
175
+ "&:error": createteSelector([selector.self], state.error),
176
+ "&:expanded": createteSelector([selector.self], state.expanded),
177
+ "&:in-group": createteSelector(selector.grouped, state.none, selector.self),
178
+ "&:hover-group": createteSelector(selector.grouped, state.hover, selector.self),
179
+ "&:focus-group": createteSelector(selector.grouped, state.focus, selector.self),
180
+ "&:active-group": createteSelector(selector.grouped, state.active, selector.self),
181
+ "&:error-group": createteSelector(selector.grouped, state.error, selector.self)
173
182
  };
174
183
  var transformPseudos = (styles) => {
175
184
  let result = {};
@@ -188,11 +197,10 @@ var transformPseudos = (styles) => {
188
197
  };
189
198
 
190
199
  // src/components/Box/Box.tsx
191
- var createThemedStyle = ({ as, __baseCSS, variant, styles, css }) => (theme) => {
200
+ var createThemedStyle = ({ as, __baseCSS, styles, css }) => (theme) => {
192
201
  const themedStyles = import_deepmerge.default.all([
193
202
  getNormalizedStyles(as),
194
203
  (0, import_css.css)(__baseCSS)(theme),
195
- ...ensureArrayVariant(variant).map((v) => (0, import_css.css)({ variant: v })(theme)),
196
204
  (0, import_css.css)(styles)(theme),
197
205
  (0, import_css.css)(css)(theme)
198
206
  ]);
@@ -203,8 +211,7 @@ var Box = (0, import_react.forwardRef)((_a, ref) => {
203
211
  as = "div",
204
212
  children,
205
213
  __baseCSS,
206
- variant,
207
- css = {},
214
+ css,
208
215
  display,
209
216
  height,
210
217
  width,
@@ -247,7 +254,6 @@ var Box = (0, import_react.forwardRef)((_a, ref) => {
247
254
  "as",
248
255
  "children",
249
256
  "__baseCSS",
250
- "variant",
251
257
  "css",
252
258
  "display",
253
259
  "height",
@@ -292,7 +298,6 @@ var Box = (0, import_react.forwardRef)((_a, ref) => {
292
298
  css: createThemedStyle({
293
299
  as,
294
300
  __baseCSS,
295
- variant,
296
301
  css,
297
302
  styles: {
298
303
  display,
@@ -433,12 +438,14 @@ var useResponsiveValue = (values, defaultIndex = 0) => {
433
438
  // src/hooks/useStateProps.ts
434
439
  var import_react7 = require("react");
435
440
  var import_react_fast_compare2 = __toESM(require("react-fast-compare"));
441
+ var KEBAB_REGEX = /[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g;
442
+ var toKebap = (val) => val.replace(KEBAB_REGEX, (match) => `-${match.toLocaleLowerCase()}`);
436
443
  var useStateProps = (states) => {
437
444
  const statePropsRef = (0, import_react7.useRef)({});
438
445
  let stateProps = {};
439
- for (let state in states) {
440
- if (states[state]) {
441
- const key = `data-${state.toLocaleLowerCase()}`;
446
+ for (let state2 in states) {
447
+ if (states[state2]) {
448
+ const key = `data-${toKebap(state2)}`;
442
449
  stateProps[key] = "";
443
450
  }
444
451
  }
@@ -510,11 +517,6 @@ var SVG = (_a) => {
510
517
  SVG,
511
518
  ThemeProvider,
512
519
  __defaultTheme,
513
- appendVariantState,
514
- conditional,
515
- ensureArray,
516
- ensureArrayVariant,
517
- ensureVariantDefault,
518
520
  getNormalizedStyles,
519
521
  normalize,
520
522
  useComponentStyles,
package/dist/index.mjs CHANGED
@@ -105,31 +105,45 @@ var normalize = {
105
105
  };
106
106
  var getNormalizedStyles = (val) => typeof val === "string" && val in normalize ? normalize[val] : normalize.base;
107
107
 
108
- // src/variant.ts
109
- var isNil = (value) => value === null || value === void 0;
110
- var ensureArray = (val) => isNil(val) ? [] : Array.isArray(val) ? val : [val];
111
- var ensureVariantDefault = (val) => val.replace(/\.$/, "");
112
- var ensureArrayVariant = (variant) => ensureArray(variant).map(ensureVariantDefault);
113
- var appendVariantState = (variant, state) => {
114
- return `${ensureVariantDefault(variant)}.:${state}`;
108
+ // src/components/Box/utils.ts
109
+ var createteSelector = (selectors, states, suffix = "") => {
110
+ return selectors.map((selector2) => states.map((state2) => `${selector2}${state2}${suffix ? ` ${suffix}` : ""}`)).flat().join(", ");
115
111
  };
116
- var conditional = (variant, _a) => {
117
- var _b = _a, { disabled = false } = _b, states = __objRest(_b, ["disabled"]);
118
- const entries = [...Object.entries(states), ["disabled", disabled]];
119
- const stateVariants = entries.filter(([, val]) => Boolean(val)).map(([key]) => appendVariantState(variant, key));
120
- return [variant, ...stateVariants];
112
+ var selector = {
113
+ self: "&",
114
+ grouped: ["[role=group]", "[data-group]"]
115
+ };
116
+ var state = {
117
+ none: [""],
118
+ hover: [":hover", "[data-hover]"],
119
+ focus: [":focus", "[data-focus]"],
120
+ focusVisible: [":focus-visible", "[data-focus-visible]"],
121
+ active: [":active", "[data-active]"],
122
+ disabled: ["[disabled]", "[aria-disabled=true]", "[data-disabled]"],
123
+ readOnly: ["[readonly]", "[aria-readonly=true]", "[data-read-only]"],
124
+ checked: ["[aria-checked=true]", "[data-checked]"],
125
+ indeterminate: ["[aria-checked=mixed]", "[data-indeterminate]"],
126
+ selected: ["[aria-selected=true]", "[data-selected]"],
127
+ error: [":invalid", "[aria-invalid=true]", "[data-error]"],
128
+ expanded: ["[aria-expanded=true]", "[data-expanded]"]
121
129
  };
122
-
123
- // src/components/Box/utils.ts
124
130
  var pseudos = {
125
- "&:hover": "&:hover, &[data-hover]",
126
- "&:focus": "&:focus, &[data-focus]",
127
- "&:active": "&:active, &[data-active]",
128
- "&:disabled": "&[disabled], &[aria-disabled=true], &[data-disabled]",
129
- "&:read-only": "&[readonly], &[aria-readonly=true], &[data-readonly]",
130
- "&:checked": "&[aria-checked=true], &[data-checked]",
131
- "&:indeterminate": "&:indeterminate, &[aria-checked=mixed], &[data-indeterminate]",
132
- "&:error": "&:invalid, &[aria-invalid=true], &[data-error]"
131
+ "&:hover": createteSelector([selector.self], state.hover),
132
+ "&:focus": createteSelector([selector.self], state.focus),
133
+ "&:focus-visible": createteSelector([selector.self], state.focusVisible),
134
+ "&:active": createteSelector([selector.self], state.active),
135
+ "&:disabled": createteSelector([selector.self], state.disabled),
136
+ "&:read-only": createteSelector([selector.self], state.readOnly),
137
+ "&:checked": createteSelector([selector.self], state.checked),
138
+ "&:selected": createteSelector([selector.self], state.selected),
139
+ "&:indeterminate": createteSelector([selector.self], state.indeterminate),
140
+ "&:error": createteSelector([selector.self], state.error),
141
+ "&:expanded": createteSelector([selector.self], state.expanded),
142
+ "&:in-group": createteSelector(selector.grouped, state.none, selector.self),
143
+ "&:hover-group": createteSelector(selector.grouped, state.hover, selector.self),
144
+ "&:focus-group": createteSelector(selector.grouped, state.focus, selector.self),
145
+ "&:active-group": createteSelector(selector.grouped, state.active, selector.self),
146
+ "&:error-group": createteSelector(selector.grouped, state.error, selector.self)
133
147
  };
134
148
  var transformPseudos = (styles) => {
135
149
  let result = {};
@@ -148,11 +162,10 @@ var transformPseudos = (styles) => {
148
162
  };
149
163
 
150
164
  // src/components/Box/Box.tsx
151
- var createThemedStyle = ({ as, __baseCSS, variant, styles, css }) => (theme) => {
165
+ var createThemedStyle = ({ as, __baseCSS, styles, css }) => (theme) => {
152
166
  const themedStyles = merge.all([
153
167
  getNormalizedStyles(as),
154
168
  transformStyleObject(__baseCSS)(theme),
155
- ...ensureArrayVariant(variant).map((v) => transformStyleObject({ variant: v })(theme)),
156
169
  transformStyleObject(styles)(theme),
157
170
  transformStyleObject(css)(theme)
158
171
  ]);
@@ -163,8 +176,7 @@ var Box = forwardRef((_a, ref) => {
163
176
  as = "div",
164
177
  children,
165
178
  __baseCSS,
166
- variant,
167
- css = {},
179
+ css,
168
180
  display,
169
181
  height,
170
182
  width,
@@ -207,7 +219,6 @@ var Box = forwardRef((_a, ref) => {
207
219
  "as",
208
220
  "children",
209
221
  "__baseCSS",
210
- "variant",
211
222
  "css",
212
223
  "display",
213
224
  "height",
@@ -252,7 +263,6 @@ var Box = forwardRef((_a, ref) => {
252
263
  css: createThemedStyle({
253
264
  as,
254
265
  __baseCSS,
255
- variant,
256
266
  css,
257
267
  styles: {
258
268
  display,
@@ -400,12 +410,14 @@ var useResponsiveValue = (values, defaultIndex = 0) => {
400
410
  // src/hooks/useStateProps.ts
401
411
  import { useRef as useRef2 } from "react";
402
412
  import isEqual2 from "react-fast-compare";
413
+ var KEBAB_REGEX = /[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g;
414
+ var toKebap = (val) => val.replace(KEBAB_REGEX, (match) => `-${match.toLocaleLowerCase()}`);
403
415
  var useStateProps = (states) => {
404
416
  const statePropsRef = useRef2({});
405
417
  let stateProps = {};
406
- for (let state in states) {
407
- if (states[state]) {
408
- const key = `data-${state.toLocaleLowerCase()}`;
418
+ for (let state2 in states) {
419
+ if (states[state2]) {
420
+ const key = `data-${toKebap(state2)}`;
409
421
  stateProps[key] = "";
410
422
  }
411
423
  }
@@ -476,11 +488,6 @@ export {
476
488
  SVG,
477
489
  ThemeProvider,
478
490
  __defaultTheme,
479
- appendVariantState,
480
- conditional,
481
- ensureArray,
482
- ensureArrayVariant,
483
- ensureVariantDefault,
484
491
  getNormalizedStyles,
485
492
  normalize,
486
493
  useComponentStyles,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marigold/system",
3
- "version": "0.9.0",
3
+ "version": "1.0.1",
4
4
  "description": "Marigold System Library",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -26,9 +26,9 @@
26
26
  "directory": "packages/system"
27
27
  },
28
28
  "dependencies": {
29
- "@emotion/react": "11.8.2",
30
- "@marigold/types": "0.4.1",
31
- "@theme-ui/css": "0.14.2",
29
+ "@emotion/react": "11.9.0",
30
+ "@marigold/types": "0.5.1",
31
+ "@theme-ui/css": "0.14.5",
32
32
  "csstype": "3.0.11",
33
33
  "deepmerge": "^4.2.2",
34
34
  "react-fast-compare": "^3.2.0"
@@ -38,13 +38,14 @@
38
38
  "react-dom": "^16.x || ^17.0.0"
39
39
  },
40
40
  "devDependencies": {
41
+ "@babel/core": "7.17.12",
41
42
  "@marigold/tsconfig": "0.3.0",
42
- "tsup": "5.12.5"
43
+ "react": "17.0.2",
44
+ "tsup": "5.12.8"
43
45
  },
44
46
  "scripts": {
45
47
  "build": "tsup src/index.ts",
46
48
  "watch": "tsup src/index.ts --watch",
47
49
  "clean": "rm -rf node_modules && rm -rf dist"
48
- },
49
- "readme": "# `@marigold/system`\n\n> Marigold system\n"
50
+ }
50
51
  }