react-native-varia 0.2.3 → 0.2.4

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/bin/cli.js +24 -34
  2. package/lib/components/Accordion.tsx +113 -0
  3. package/lib/components/Button.tsx +10 -1
  4. package/lib/components/CircleProgress.tsx +30 -21
  5. package/lib/components/Divider.tsx +18 -15
  6. package/lib/components/Drawer.tsx +5 -48
  7. package/lib/components/Field.tsx +24 -39
  8. package/lib/components/GradientBackground.tsx +25 -7
  9. package/lib/components/GradientText.tsx +38 -11
  10. package/lib/components/IconWrapper.tsx +20 -14
  11. package/lib/components/Input.tsx +106 -25
  12. package/lib/components/NumberInput.tsx +54 -11
  13. package/lib/components/OldSlider.tsx +327 -0
  14. package/lib/components/RadioGroup.tsx +55 -17
  15. package/lib/components/ReText.tsx +1 -1
  16. package/lib/components/Select.tsx +58 -22
  17. package/lib/components/Slider.tsx +176 -115
  18. package/lib/components/Slideshow.tsx +65 -63
  19. package/lib/components/SlidingDrawer.tsx +20 -21
  20. package/lib/components/Spinner.tsx +6 -2
  21. package/lib/components/Toast.tsx +89 -0
  22. package/lib/components/context/Field.tsx +27 -0
  23. package/lib/theme/Button.recipe.tsx +11 -1
  24. package/lib/theme/CircleProgress.recipe.tsx +3 -3
  25. package/lib/theme/Field.recipe.tsx +17 -2
  26. package/lib/theme/Input.recipe.tsx +12 -3
  27. package/lib/theme/NumberInput.recipe.tsx +8 -3
  28. package/lib/theme/RadioGroup.recipe.tsx +7 -1
  29. package/lib/theme/Select.recipe.tsx +7 -7
  30. package/lib/theme/Slider.recipe.tsx +366 -22
  31. package/lib/theme/Slideshow.recipe.tsx +1 -1
  32. package/lib/theme/SlidingDrawer.recipe.tsx +58 -4
  33. package/lib/theme/Toast.recipe.tsx +71 -0
  34. package/package.json +1 -1
  35. package/lib/theme/Button.recipe-old.tsx +0 -67
@@ -1,36 +1,21 @@
1
- import React, {createContext, useContext} from 'react'
2
- import {UnistylesVariants} from 'react-native-unistyles'
1
+ import React from 'react'
3
2
  import Text from './Text'
4
- import {VStack} from '../patterns'
5
3
  import {DefaultFieldVariants, FieldStyles} from '../theme/Field.recipe'
6
- import {PalettesWithNestedKeys} from '../style/varia/types'
7
-
8
- type FieldVariants = UnistylesVariants<typeof FieldStyles>
9
-
10
- type FieldContextType = {
11
- error?: string
12
- variant?: FieldVariants['variant']
13
- size?: FieldVariants['size']
14
- colorPalette?: PalettesWithNestedKeys
15
- }
16
-
17
- const FieldContext = createContext<FieldContextType | undefined>(undefined)
18
-
19
- function useField() {
20
- const context = useContext(FieldContext)
21
- if (!context) {
22
- throw new Error(
23
- 'Field subcomponents (Label, Error) must be used inside Field.Root',
24
- )
25
- }
26
- return context
27
- }
4
+ import {Flex, PalettesWithNestedKeys} from '../style/varia/types'
5
+ import FieldContext, {
6
+ FieldContextType,
7
+ FieldVariants,
8
+ useField,
9
+ } from './context/Field'
10
+ import {StyleProp, View, ViewStyle} from 'react-native'
11
+ import {StyleSheet} from 'react-native-unistyles'
28
12
 
29
13
  type FieldRootProps = FieldVariants & {
30
14
  children: React.ReactNode
31
15
  error?: string
32
16
  colorPalette?: PalettesWithNestedKeys
33
17
  flex?: number
18
+ style?: StyleProp<ViewStyle>
34
19
  }
35
20
 
36
21
  const FieldRoot = ({
@@ -39,7 +24,8 @@ const FieldRoot = ({
39
24
  variant = DefaultFieldVariants.variant,
40
25
  size = DefaultFieldVariants.size,
41
26
  colorPalette = 'accent',
42
- flex = 1,
27
+ flex = 0,
28
+ style,
43
29
  }: FieldRootProps) => {
44
30
  FieldStyles.useVariants({size})
45
31
 
@@ -53,20 +39,16 @@ const FieldRoot = ({
53
39
  FieldStyles.useVariants({variant, size})
54
40
 
55
41
  return (
56
- <VStack
42
+ <View
57
43
  style={[
58
- {
59
- flexShrink: 1,
60
- flexGrow: flex,
61
- alignItems: 'stretch',
62
- alignSelf: 'stretch',
63
- },
44
+ styles.root(flex),
64
45
  FieldStyles.root(colorPalette),
46
+ style && style,
65
47
  ]}>
66
48
  <FieldContext.Provider value={contextValue}>
67
49
  {children}
68
50
  </FieldContext.Provider>
69
- </VStack>
51
+ </View>
70
52
  )
71
53
  }
72
54
 
@@ -89,11 +71,7 @@ const FieldLabel = ({children, ...props}: FieldLabelProps) => {
89
71
 
90
72
  FieldStyles.useVariants({variant, size})
91
73
 
92
- return (
93
- <Text size={size} color={FieldStyles.label(colorPalette).color}>
94
- {children}
95
- </Text>
96
- )
74
+ return <Text style={FieldStyles.label(colorPalette)}>{children}</Text>
97
75
  }
98
76
 
99
77
  type FieldErrorProps = {
@@ -124,6 +102,13 @@ const FieldError = ({...props}: FieldErrorProps) => {
124
102
  )
125
103
  }
126
104
 
105
+ const styles = StyleSheet.create({
106
+ root: (flex: Flex) => ({
107
+ flex,
108
+ flexDirection: 'column',
109
+ }),
110
+ })
111
+
127
112
  export const Field = Object.assign(FieldRoot, {
128
113
  Root: FieldRoot,
129
114
  Label: FieldLabel,
@@ -1,16 +1,23 @@
1
- import {View, StyleSheet, StyleProp, ViewStyle} from 'react-native'
1
+ import {View, StyleProp, ViewStyle} from 'react-native'
2
2
  import Svg, {Defs, LinearGradient, Stop, Rect} from 'react-native-svg'
3
3
  import {withUnistyles} from 'react-native-unistyles'
4
4
  import {gradientBackgroundTokens} from '../theme/GradientBackground.recipe'
5
- import {PalettesWithNestedKeys} from '../style/varia/types'
5
+ import {
6
+ NestedColorsType,
7
+ PalettesWithNestedKeys,
8
+ ThemeColors,
9
+ } from '../style/varia/types'
6
10
  import {resolveColor} from '../style/varia/utils'
11
+ import {StyleSheet} from 'react-native-unistyles'
7
12
 
8
13
  interface GradientBackgroundProps {
9
14
  colorPalette?: PalettesWithNestedKeys
10
15
  variant?: keyof typeof gradientBackgroundTokens.variants.variant
11
16
  direction?: keyof typeof gradientBackgroundTokens.variants.direction
12
17
  containerStyles?: StyleProp<ViewStyle>
13
- colors: any
18
+ colors: NestedColorsType
19
+ startColor?: ThemeColors
20
+ endColor?: ThemeColors
14
21
  }
15
22
 
16
23
  const BaseGradientBackground = ({
@@ -19,10 +26,20 @@ const BaseGradientBackground = ({
19
26
  direction = gradientBackgroundTokens.defaultProps.direction,
20
27
  containerStyles,
21
28
  colors,
29
+ startColor,
30
+ endColor,
22
31
  }: GradientBackgroundProps) => {
23
32
  const colorValue = gradientBackgroundTokens.variants.variant[variant]
24
- const startColor = resolveColor(colorValue.startColor, colors, colorPalette)
25
- const endColor = resolveColor(colorValue.endColor, colors, colorPalette)
33
+ const resolvedStartColor = resolveColor(
34
+ startColor || colorValue.startColor,
35
+ colors,
36
+ colorPalette,
37
+ )
38
+ const resolvedEndColor = resolveColor(
39
+ endColor || colorValue.endColor,
40
+ colors,
41
+ colorPalette,
42
+ )
26
43
 
27
44
  const directionVariant =
28
45
  gradientBackgroundTokens.variants.direction[direction]
@@ -41,8 +58,8 @@ const BaseGradientBackground = ({
41
58
  y1={directionVariant?.y1}
42
59
  x2={directionVariant?.x2}
43
60
  y2={directionVariant?.y2}>
44
- <Stop offset="0%" stopColor={startColor} stopOpacity="1" />
45
- <Stop offset="100%" stopColor={endColor} stopOpacity="1" />
61
+ <Stop offset="0%" stopColor={resolvedStartColor} stopOpacity="1" />
62
+ <Stop offset="100%" stopColor={resolvedEndColor} stopOpacity="1" />
46
63
  </LinearGradient>
47
64
  </Defs>
48
65
  <Rect width="100" height="100" fill="url(#grad)" />
@@ -54,6 +71,7 @@ const BaseGradientBackground = ({
54
71
  const styles = StyleSheet.create({
55
72
  container: {
56
73
  ...StyleSheet.absoluteFillObject,
74
+ alignSelf: 'stretch',
57
75
  borderWidth: 0,
58
76
  overflow: 'hidden',
59
77
  borderColor: 'transparent',
@@ -1,4 +1,4 @@
1
- import {View, type ColorValue} from 'react-native'
1
+ import {StyleSheet, TextStyle, View, type ColorValue} from 'react-native'
2
2
  import Svg, {
3
3
  Defs,
4
4
  LinearGradient,
@@ -8,16 +8,23 @@ import Svg, {
8
8
  } from 'react-native-svg'
9
9
  import {withUnistyles} from 'react-native-unistyles'
10
10
  import {gradientTextTokens} from '../theme/GradientText.recipe'
11
- import {PalettesWithNestedKeys} from '../style/varia/types'
11
+ import {
12
+ NestedColorsType,
13
+ PalettesWithNestedKeys,
14
+ ThemeType,
15
+ } from '../style/varia/types'
12
16
  import {resolveColor, resolveFontSize} from '../style/varia/utils'
17
+ import {ThemeColors} from '../style/varia/types'
13
18
 
14
19
  interface GradientTextProps {
15
20
  colorPalette: PalettesWithNestedKeys
16
21
  variant?: keyof typeof gradientTextTokens.variants.variant
17
22
  direction?: keyof typeof gradientTextTokens.variants.direction
18
- colors: any
19
- fontSizes: any
20
- fontSize?: number | undefined
23
+ colors: NestedColorsType
24
+ startColor?: ThemeColors
25
+ endColor?: ThemeColors
26
+ fontSizes: ThemeType['fontSizes']
27
+ fontSize?: TextStyle['fontSize']
21
28
  children?: React.ReactNode
22
29
  size?: keyof typeof gradientTextTokens.variants.size
23
30
  }
@@ -28,13 +35,24 @@ const BaseGradientText = ({
28
35
  colorPalette = 'accent',
29
36
  direction = gradientTextTokens.defaultProps.direction,
30
37
  colors,
38
+ startColor,
39
+ endColor,
31
40
  fontSizes,
32
41
  children,
33
42
  size = gradientTextTokens.defaultProps.size,
34
43
  }: GradientTextProps) => {
35
44
  const colorValue = gradientTextTokens.variants.variant[variant]
36
- const startColor = resolveColor(colorValue.startColor, colors, colorPalette)
37
- const endColor = resolveColor(colorValue.endColor, colors, colorPalette)
45
+
46
+ const resolvedStartColor = resolveColor(
47
+ startColor || colorValue.startColor,
48
+ colors,
49
+ colorPalette,
50
+ )
51
+ const resolvedEndColor = resolveColor(
52
+ endColor || colorValue.endColor,
53
+ colors,
54
+ colorPalette,
55
+ )
38
56
 
39
57
  const fontSizeValue = gradientTextTokens.variants.size[size].fontSize
40
58
  const resolvedFontSize = fontSize || resolveFontSize(fontSizeValue, fontSizes)
@@ -42,8 +60,8 @@ const BaseGradientText = ({
42
60
  const directionVariant = gradientTextTokens.variants.direction[direction]
43
61
 
44
62
  return (
45
- <View style={{flexDirection: 'row'}}>
46
- <View style={{width: '100%'}}>
63
+ <View style={styles.root}>
64
+ <View style={styles.innerContainer}>
47
65
  <Svg height={resolvedFontSize + 20} width="100%">
48
66
  <Defs>
49
67
  <LinearGradient
@@ -52,8 +70,8 @@ const BaseGradientText = ({
52
70
  y1={directionVariant?.y1 as NumberProp}
53
71
  x2={directionVariant?.x2 as NumberProp}
54
72
  y2={directionVariant?.y2 as NumberProp}>
55
- <Stop offset="0%" stopColor={startColor as ColorValue} />
56
- <Stop offset="100%" stopColor={endColor as ColorValue} />
73
+ <Stop offset="0%" stopColor={resolvedStartColor as ColorValue} />
74
+ <Stop offset="100%" stopColor={resolvedEndColor as ColorValue} />
57
75
  </LinearGradient>
58
76
  </Defs>
59
77
  <Text
@@ -74,6 +92,15 @@ const BaseGradientText = ({
74
92
  )
75
93
  }
76
94
 
95
+ const styles = StyleSheet.create({
96
+ root: {
97
+ flexDirection: 'row',
98
+ },
99
+ innerContainer: {
100
+ width: '100%',
101
+ },
102
+ })
103
+
77
104
  const GradientText = withUnistyles(BaseGradientText, theme => ({
78
105
  colors: theme.colors,
79
106
  fontSizes: theme.fontSizes,
@@ -7,20 +7,20 @@ import {
7
7
  type ReactNode,
8
8
  } from 'react'
9
9
  import Svg from 'react-native-svg'
10
- import {View} from 'react-native'
11
- import {withUnistyles} from 'react-native-unistyles'
10
+ import {StyleProp, View, ViewStyle} from 'react-native'
11
+ import {StyleSheet, withUnistyles} from 'react-native-unistyles'
12
12
  import {IconTokens} from '../theme/IconWrapper.recipe'
13
13
  import {
14
14
  NestedColorsType,
15
15
  PalettesWithNestedKeys,
16
16
  ThemeColors,
17
+ ThemeType,
17
18
  } from '../style/varia/types'
18
19
  import {resolveColor} from '../style/varia/utils'
19
20
 
20
21
  interface SVGChildProps {
21
22
  color?: string
22
23
  }
23
-
24
24
  export type IconWrapperProps = {
25
25
  variant?: keyof typeof IconTokens.variants.variant
26
26
  size?: number
@@ -30,7 +30,8 @@ export type IconWrapperProps = {
30
30
  scale?: number
31
31
  color?: ThemeColors
32
32
  rotation?: number
33
- colors?: any
33
+ colors?: NestedColorsType
34
+ style?: StyleProp<ViewStyle>
34
35
  }
35
36
 
36
37
  /**
@@ -50,12 +51,13 @@ const Icon = ({
50
51
  color,
51
52
  rotation,
52
53
  colors,
54
+ style,
53
55
  ...rest
54
56
  }: IconWrapperProps) => {
55
57
  const colorValue = IconTokens.variants.variant[variant].color
56
58
  const resolvedColor = color
57
- ? resolveColor(color, colors, colorPalette)
58
- : resolveColor(colorValue, colors, colorPalette)
59
+ ? resolveColor(color, colors as NestedColorsType, colorPalette)
60
+ : resolveColor(colorValue, colors as NestedColorsType, colorPalette)
59
61
 
60
62
  const width = IconTokens.variants.sizeVariant[sizeVariant].width ?? 0
61
63
  const height = IconTokens.variants.sizeVariant[sizeVariant].height ?? 0
@@ -63,14 +65,7 @@ const Icon = ({
63
65
  // const viewBoxHeight = IconTokens.variants.size[size].viewBoxHeight ?? 0
64
66
 
65
67
  return (
66
- <View
67
- style={{
68
- width: size || width,
69
- height: size || height,
70
- justifyContent: 'center',
71
- alignItems: 'center',
72
- transform: rotation ? [{rotate: `${rotation}deg`}] : [],
73
- }}>
68
+ <View style={[styles.root(size, width, height, rotation), style]}>
74
69
  <Svg
75
70
  width={size || width}
76
71
  height={size || height}
@@ -105,6 +100,17 @@ const Icon = ({
105
100
 
106
101
  export default Icon
107
102
 
103
+ const styles = StyleSheet.create({
104
+ root: (size, width, height, rotation) => ({
105
+ width: size || width,
106
+ height: size || height,
107
+ justifyContent: 'center',
108
+ alignItems: 'center',
109
+ ...(rotation && {transform: [{rotate: `${rotation}deg`}]}),
110
+ // transform: rotation ? [{rotate: `${rotation}deg`}] : [],
111
+ }),
112
+ })
113
+
108
114
  export const ThemedIcon = withUnistyles(Icon, theme => ({
109
115
  colors: theme.colors,
110
116
  }))
@@ -5,85 +5,141 @@ import {
5
5
  TextInput,
6
6
  TextInputProps,
7
7
  TextStyle,
8
+ View,
8
9
  type ViewStyle,
9
10
  } from 'react-native'
10
11
  import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
11
12
  import {InputStyles, InputDefaultVariants} from '../theme/Input.recipe'
12
- import {PalettesWithNestedKeys} from '../style/varia/types'
13
+ import {
14
+ AlignSelf,
15
+ Flex,
16
+ MaxWidth,
17
+ PalettesWithNestedKeys,
18
+ StackDirection,
19
+ } from '../style/varia/types'
13
20
  import {useState} from 'react'
14
- import {HStack} from '../patterns'
21
+ import {IconWrapperProps} from './IconWrapper'
15
22
 
16
23
  type InputVariants = UnistylesVariants<typeof InputStyles>
17
24
 
18
25
  type InputProps = InputVariants &
19
26
  TextInputProps & {
20
27
  colorPalette?: PalettesWithNestedKeys
21
- onChange?: (value: string) => void
28
+ onChangeText?: (value: string) => void
22
29
  placeholder: string
23
30
  inputMode?: InputModeOptions
24
31
  keyboardType?: KeyboardTypeOptions
25
- flex?: number
26
- maxWidth?: number | string
32
+ flex?: Flex
33
+ maxWidth?: MaxWidth
27
34
  password?: boolean
28
35
  onFocus?: () => void
29
36
  onBlur?: () => void
30
- value: any
37
+ value: string
31
38
  disabled?: boolean
32
39
  containerMixins?: StyleProp<ViewStyle> | StyleProp<ViewStyle>[]
40
+ alignSelf?: AlignSelf
33
41
  labelMixins?:
34
42
  | StyleProp<ViewStyle>
35
43
  | StyleProp<ViewStyle>[]
36
44
  | StyleProp<TextStyle>
37
45
  | StyleProp<TextStyle>[]
38
46
  inputMixins?: StyleProp<ViewStyle> | StyleProp<ViewStyle>[]
47
+ icon?: {
48
+ component: React.ComponentType<IconWrapperProps>
49
+ position?: 'left' | 'right'
50
+ scale?: number
51
+ rotation?: number
52
+ size?: number
53
+ }
54
+ style?: StyleProp<ViewStyle>
55
+ direction?: StackDirection
39
56
  }
40
57
 
41
58
  const Input = ({
42
59
  colorPalette = 'accent',
43
60
  size = InputDefaultVariants.size,
61
+ variant = InputDefaultVariants.variant,
44
62
  placeholder,
45
- onChange,
46
- inputMode,
63
+ onChangeText,
64
+ inputMode = 'text',
47
65
  keyboardType,
48
- flex = 1,
66
+ flex = 0,
49
67
  maxWidth = '100%',
50
68
  password = false,
51
69
  onFocus = () => {},
52
70
  onBlur = () => {},
53
71
  value,
54
72
  containerMixins,
73
+ alignSelf = 'auto',
55
74
  labelMixins,
56
75
  inputMixins,
57
76
  disabled,
58
77
  invalid,
78
+ style,
79
+ icon,
80
+ textAlignVertical = 'center',
81
+ direction = 'column',
59
82
  ...props
60
83
  }: InputProps) => {
61
84
  const [focused, setFocused] = useState(false)
62
85
  InputStyles.useVariants({
63
86
  size,
87
+ variant,
64
88
  focused,
65
89
  disabled,
66
90
  invalid,
67
91
  })
92
+ const iconPosition = icon ? !icon.position && 'left' : null
68
93
 
69
94
  const placeholderStyle = InputStyles.placeholder(colorPalette) as {
70
95
  color: string
71
96
  }
72
97
  const placeholderColor = placeholderStyle.color
73
98
 
99
+ const inputResolvedVariantStyle = InputStyles.input(colorPalette) as {
100
+ paddingHorizontal?: number
101
+ }
102
+ const paddingHorizontal = inputResolvedVariantStyle.paddingHorizontal ?? 0
103
+
104
+ const IconComponent = icon?.component
105
+ const IconRendered = IconComponent ? (
106
+ <IconComponent
107
+ {...{
108
+ rotation: icon.rotation,
109
+ scale: icon.scale,
110
+ colorPalette,
111
+ size: icon.size,
112
+ color: InputStyles.input(colorPalette).color,
113
+ style: styles.icon(iconPosition, paddingHorizontal, textAlignVertical),
114
+ }}
115
+ />
116
+ ) : null
117
+
118
+ console.log(
119
+ iconPosition === 'left'
120
+ ? (icon?.size || 0) + paddingHorizontal * 2
121
+ : paddingHorizontal,
122
+ )
123
+
74
124
  return (
75
- <HStack
76
- style={{
77
- flexGrow: flex,
78
- flexShrink: 0,
79
- alignSelf: 'stretch',
80
- }}>
125
+ <View
126
+ style={styles.container(flex, direction, alignSelf, textAlignVertical)}>
127
+ {IconRendered}
81
128
  <TextInput
82
129
  editable={!disabled}
83
130
  style={[
84
- styles.input(flex, maxWidth),
131
+ styles.input(
132
+ flex,
133
+ maxWidth,
134
+ iconPosition,
135
+ paddingHorizontal,
136
+ textAlignVertical,
137
+ (icon?.size || 0) + paddingHorizontal * 2,
138
+ alignSelf,
139
+ ),
85
140
  InputStyles.input(colorPalette),
86
141
  inputMixins && inputMixins,
142
+ style && style,
87
143
  ]}
88
144
  value={value}
89
145
  placeholder={placeholder}
@@ -99,23 +155,48 @@ const Input = ({
99
155
  onBlur()
100
156
  setFocused(false)
101
157
  }}
102
- onChangeText={onChange}
103
- multiline={false}
158
+ onChangeText={onChangeText}
104
159
  {...props}
105
160
  />
106
- </HStack>
161
+ </View>
107
162
  )
108
163
  }
109
164
 
110
165
  const styles = StyleSheet.create({
111
- input: (flex, maxWidth) => ({
166
+ container: (flex, direction, alignSelf, textAlignVertical) => ({
167
+ flex,
168
+ flexDirection: direction,
169
+ alignSelf,
170
+ alignItems: 'stretch',
171
+ justifyContent:
172
+ textAlignVertical === 'center'
173
+ ? 'center'
174
+ : textAlignVertical === 'bottom'
175
+ ? 'flex-end'
176
+ : 'flex-start',
177
+ }),
178
+ input: (
112
179
  flex,
113
- paddingVertical: 0,
114
- flexDirection: 'row',
115
- flexGrow: 1,
116
- flexShrink: 0,
117
- alignSelf: 'stretch',
118
180
  maxWidth,
181
+ iconPosition,
182
+ paddingHorizontal,
183
+ textAlignVertical,
184
+ padding,
185
+ alignSelf,
186
+ ) => ({
187
+ flex,
188
+ paddingLeft: iconPosition === 'left' ? padding : paddingHorizontal,
189
+ paddingRight: iconPosition === 'right' ? padding : paddingHorizontal,
190
+ textAlignVertical,
191
+ maxWidth,
192
+ alignSelf,
193
+ }),
194
+ icon: (iconPosition, paddingHorizontal, textAlignVertical) => ({
195
+ position: 'absolute',
196
+ ...(iconPosition === 'left' && {left: paddingHorizontal}),
197
+ ...(iconPosition === 'right' && {right: paddingHorizontal}),
198
+ top: textAlignVertical !== 'top' ? 'auto' : 10,
199
+ bottom: textAlignVertical !== 'bottom' ? 'auto' : 10,
119
200
  }),
120
201
  })
121
202