@moises.ai/design-system 4.16.9 → 4.16.11

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 (34) hide show
  1. package/dist/{ChordDiagramGridIcon-CxpGQmg4.js → DynamicMicrophone2Icon-BBVZw0ZO.js} +794 -782
  2. package/dist/icons.js +484 -483
  3. package/dist/index.js +5450 -5769
  4. package/package.json +1 -1
  5. package/src/components/DropdownButton/DropdownButton.jsx +7 -0
  6. package/src/components/DropdownButton/DropdownButton.stories.jsx +4 -1
  7. package/src/components/InstrumentSelector/InstrumentSelector.stories.jsx +9 -1
  8. package/src/components/MessageWithAction/MessageWithAction.jsx +7 -0
  9. package/src/components/MessageWithAction/MessageWithAction.stories.jsx +4 -1
  10. package/src/components/ToolsDropdown/ToolsDropdown.module.css +12 -0
  11. package/src/components/ToolsDropdown/ToolsDropdown.stories.jsx +2 -1
  12. package/src/components/TrackControlsToggle/TrackControlsToggle.stories.jsx +7 -3
  13. package/src/icons/DynamicMicrophone2Icon.jsx +13 -0
  14. package/src/icons.jsx +1 -0
  15. package/src/index.jsx +2 -2
  16. package/src/components/PlayerBar/PlayerBar.jsx +0 -250
  17. package/src/components/PlayerBar/PlayerBar.module.css +0 -135
  18. package/src/components/PlayerBar/PlayerBar.stories.jsx +0 -519
  19. package/src/components/PlayerMasterVolume/PlayerMasterVolume.jsx +0 -54
  20. package/src/components/PlayerMasterVolume/PlayerMasterVolume.module.css +0 -31
  21. package/src/components/PlayerMasterVolume/PlayerMasterVolume.stories.jsx +0 -182
  22. package/src/components/PlayerSlider/PlayerSlider.jsx +0 -80
  23. package/src/components/PlayerSlider/PlayerSlider.module.css +0 -180
  24. package/src/components/PlayerSlider/PlayerSlider.stories.jsx +0 -97
  25. package/src/components/PlayerSlider/PlayerSliderWaveform.jsx +0 -70
  26. package/src/components/PlayerSmartMetronome/PlayerSmartMetronome.jsx +0 -79
  27. package/src/components/PlayerSmartMetronome/PlayerSmartMetronome.module.css +0 -23
  28. package/src/components/PlayerSmartMetronome/PlayerSmartMetronome.stories.jsx +0 -225
  29. package/src/components/PlayerSmartMetronome/SegmentedField.jsx +0 -19
  30. package/src/components/PlayerTempoPitch/PlayerTempoPitch.jsx +0 -123
  31. package/src/components/PlayerTempoPitch/PlayerTempoPitch.module.css +0 -25
  32. package/src/components/PlayerTempoPitch/PlayerTempoPitch.stories.jsx +0 -215
  33. package/src/components/PlayerTempoPitch/StepperField.jsx +0 -57
  34. package/src/components/PlayerTempoPitch/constants.js +0 -40
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moises.ai/design-system",
3
- "version": "4.16.9",
3
+ "version": "4.16.11",
4
4
  "description": "Design System package based on @radix-ui/themes with custom defaults",
5
5
  "private": false,
6
6
  "type": "module",
@@ -6,6 +6,13 @@ import { ChevronDownIcon } from '../../icons/ChevronDownIcon'
6
6
  import { Button } from '../Button/Button'
7
7
  import styles from './DropdownButton.module.css'
8
8
 
9
+ /**
10
+ * @deprecated Use `ToolsDropdown` instead. `DropdownButton` will be removed in a
11
+ * future release. The new component is built on Radix DropdownMenu and supports the
12
+ * same trigger/chevron split, controlled open state, and custom panel content.
13
+ *
14
+ * @see ToolsDropdown
15
+ */
9
16
  export const DropdownButton = ({
10
17
  children,
11
18
  trigger,
@@ -7,13 +7,16 @@ import { Stop2Icon } from '../../icons/Stop2Icon'
7
7
  import { RecordIcon } from '../../icons/RecordIcon'
8
8
 
9
9
  export default {
10
- title: 'Components/DropdownButton',
10
+ title: 'Deprecated/DropdownButton',
11
11
  component: DropdownButton,
12
12
  parameters: {
13
13
  layout: 'centered',
14
14
  docs: {
15
15
  description: {
16
16
  component: `
17
+ > **Deprecated:** Use [\`ToolsDropdown\`](/docs/components-toolsdropdown--docs) instead.
18
+ > \`DropdownButton\` will be removed in a future release.
19
+
17
20
  ## Usage
18
21
 
19
22
  The DropdownButton is a component that combines a trigger button with a dropdown chevron.
@@ -9,10 +9,18 @@ import {
9
9
  } from '../../icons'
10
10
 
11
11
  export default {
12
- title: 'Components/InstrumentSelector',
12
+ title: 'Deprecated/InstrumentSelector',
13
13
  component: InstrumentSelector,
14
14
  parameters: {
15
15
  layout: 'centered',
16
+ docs: {
17
+ description: {
18
+ component: `
19
+ > **Deprecated:** Use [\`InstrumentSelect\`](/docs/components-instrumentselect--docs) instead.
20
+ > \`InstrumentSelector\` will be removed in a future release.
21
+ `,
22
+ },
23
+ },
16
24
  },
17
25
  tags: ['autodocs'],
18
26
  }
@@ -5,6 +5,13 @@ import React from 'react'
5
5
  import styles from './MessageWithAction.module.css'
6
6
  import classNames from 'classnames'
7
7
 
8
+ /**
9
+ * @deprecated Use `Callout` instead. `MessageWithAction` will be removed in a
10
+ * future release. Map `message` to `text`, `type` to `color` (`error` → `error`,
11
+ * `warn` → `warning`), and `ctaLabel`/`onClick` to `buttonProps`.
12
+ *
13
+ * @see Callout
14
+ */
8
15
  export const MessageWithAction = ({
9
16
  type,
10
17
  message,
@@ -4,13 +4,16 @@ import { Flex, Text, Tooltip } from '@radix-ui/themes'
4
4
  import { InfoIcon } from '../../icons'
5
5
 
6
6
  export default {
7
- title: 'Components/MessageWithAction',
7
+ title: 'Deprecated/MessageWithAction',
8
8
  component: MessageWithAction,
9
9
  parameters: {
10
10
  layout: 'centered',
11
11
  docs: {
12
12
  description: {
13
13
  component: `
14
+ > **Deprecated:** Use [\`Callout\`](/docs/components-callout--docs) instead.
15
+ > \`MessageWithAction\` will be removed in a future release.
16
+
14
17
  ## Basic Usage
15
18
 
16
19
  ### MessageWithAction
@@ -137,4 +137,16 @@
137
137
 
138
138
  .contentPanel {
139
139
  outline: none;
140
+ }
141
+
142
+ .triggerWithoutClick {
143
+ color: var(--neutral-alpha-11);
144
+
145
+ &:hover {
146
+ color: var(--neutral-alpha-12);
147
+ }
148
+
149
+ &:active {
150
+ color: var(--neutral-alpha-11);
151
+ }
140
152
  }
@@ -120,7 +120,8 @@ export const ControlledOpen = {
120
120
  <ToolsDropdown
121
121
  open={isOpen}
122
122
  onOpenChange={setIsOpen}
123
- trigger={<Text color='blue'>Controlled</Text>}
123
+ trigger={<Text>Controlled</Text>}
124
+ showSeparator={false}
124
125
  >
125
126
  <Text size="2">Controlled menu content</Text>
126
127
  </ToolsDropdown>
@@ -2,14 +2,18 @@ import { useState } from 'react'
2
2
  import { TrackControlsToggle } from './TrackControlsToggle'
3
3
 
4
4
  export default {
5
- title: 'Components/TrackControlsToggle',
5
+ title: 'Deprecated/TrackControlsToggle',
6
6
  component: TrackControlsToggle,
7
7
  parameters: {
8
8
  layout: 'centered',
9
9
  docs: {
10
10
  description: {
11
- component:
12
- 'Toggle button for track controls (Record, Mute, Auto Mute, and Solo). For `type="autoMute"`, o Figma define um único visual (amarelo em fundo alpha-2); `selected` só afeta `aria-pressed`, não as cores.',
11
+ component: `
12
+ > **Deprecated:** Use [\`TrackControlButton\`](/docs/components-trackcontrolbutton--docs) with \`variant={type}\` and \`isActive={selected}\` instead.
13
+ > \`TrackControlsToggle\` will be removed in a future release.
14
+
15
+ Toggle button for track controls (Record, Mute, Auto Mute, and Solo). For \`type="autoMute"\`, o Figma define um único visual (amarelo em fundo alpha-2); \`selected\` só afeta \`aria-pressed\`, não as cores.
16
+ `,
13
17
  },
14
18
  },
15
19
  },
@@ -0,0 +1,13 @@
1
+ export const DynamicMicrophone2Icon = ({ width = 16, height = 16, className, ...props }) => (
2
+ <svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} viewBox="0 0 16 16" fill="none" className={className} {...props}>
3
+ <path
4
+ d="M10.5846 8.14349L3.4361 14.6667L1.33331 12.5639L7.8565 5.41543M7.30522 8.69477L6.37888 9.62111M13.6616 7.19124C12.3215 8.53131 10.1488 8.53131 8.80876 7.19124C7.46868 5.85116 7.46868 3.67847 8.80876 2.3384C10.1488 0.998325 12.3215 0.998325 13.6616 2.3384C15.0017 3.67847 15.0017 5.85116 13.6616 7.19124Z"
5
+ stroke="currentColor"
6
+ strokeWidth="0.666667"
7
+ strokeLinecap="round"
8
+ strokeLinejoin="round"
9
+ />
10
+ </svg>
11
+ )
12
+
13
+ DynamicMicrophone2Icon.displayName = 'DynamicMicrophone2Icon'
package/src/icons.jsx CHANGED
@@ -437,3 +437,4 @@ export { RewindBarFillIcon } from './icons/RewindBarFillIcon'
437
437
  export { ForwardBarFillIcon } from './icons/ForwardBarFillIcon'
438
438
  export { ChordGrid3Icon } from './icons/ChordGrid3Icon'
439
439
  export { ChordDiagramGridIcon } from './icons/ChordDiagramGridIcon'
440
+ export { DynamicMicrophone2Icon } from './icons/DynamicMicrophone2Icon'
package/src/index.jsx CHANGED
@@ -51,6 +51,7 @@ export { CigarBar } from './components/CigarBar/CigarBar'
51
51
  export { ContextMenu } from './components/ContextMenu/ContextMenu'
52
52
  export { Countdown } from './components/Countdown/Countdown'
53
53
  export { DataTable } from './components/DataTable/DataTable'
54
+ /** @deprecated Use `ToolsDropdown` instead. */
54
55
  export { DropdownButton } from './components/DropdownButton/DropdownButton'
55
56
  export { DropdownMenu } from './components/DropdownMenu/DropdownMenu'
56
57
  export { ToolsDropdown } from './components/ToolsDropdown/ToolsDropdown'
@@ -75,6 +76,7 @@ export { InstrumentSelectCard } from './components/InstrumentSelect/InstrumentSe
75
76
  export { InstrumentSelector } from './components/InstrumentSelector/InstrumentSelector'
76
77
  export { Knob } from './components/Knob/Knob'
77
78
  export { ListCards } from './components/ListCards/ListCards'
79
+ /** @deprecated Use `Callout` instead. */
78
80
  export { MessageWithAction } from './components/MessageWithAction/MessageWithAction'
79
81
  export { MetronomeForm } from './components/MetronomeForm/MetronomeForm'
80
82
  export { MoreButton } from './components/MoreButton/MoreButton'
@@ -82,8 +84,6 @@ export { MultiSelect } from './components/MultiSelect/MultiSelect'
82
84
  export { MultiSelectCards } from './components/MultiSelectCards/MultiSelectCards'
83
85
  export { PanControl } from './components/PanControl/PanControl'
84
86
  export { PeakLevel } from './components/PeakLevel/PeakLevel'
85
- export { PlayerBar } from './components/PlayerBar/PlayerBar'
86
- export { PlayerSlider } from './components/PlayerSlider/PlayerSlider'
87
87
  export { PreviewCard } from './components/PreviewCard/PreviewCard'
88
88
  export { ProductsBrandPattern } from './components/ProductsBrandPattern/ProductsBrandPattern'
89
89
  export { ProductsList } from './components/ProductsList/ProductsList'
@@ -1,250 +0,0 @@
1
- import classNames from 'classnames'
2
- import {
3
- MusicNoteIcon,
4
- PlayIcon,
5
- More2Icon,
6
- Volume2Icon,
7
- RewindBarFillIcon,
8
- ForwardBarFillIcon,
9
- PauseFilledIcon,
10
- PlayOnRepeatIcon,
11
- KaraokeMicIcon,
12
- ChordsDetectionIcon,
13
- MetronomeIcon,
14
- ChevronDownIcon,
15
- Share2Icon,
16
- Video2Icon,
17
- ChevronUpIcon,
18
- } from '../../icons'
19
- import { Text, Flex, IconButton, DropdownMenu, DropdownButton, Separator, Popover } from '../../index'
20
- import styles from './PlayerBar.module.css'
21
- import { PlayerSlider } from '../PlayerSlider/PlayerSlider'
22
-
23
- const formatTime = (time) => {
24
- const totalSeconds = Math.floor(time)
25
- const minutes = Math.floor(totalSeconds / 60)
26
- const seconds = totalSeconds % 60
27
- return `${minutes}:${seconds.toString().padStart(2, '0')}`
28
- }
29
-
30
- export const PlayerBar = ({
31
- title = 'Untitled track',
32
- subtitle,
33
- cover,
34
- menuOptions,
35
- showSlider = true,
36
- color = 'gray', // can be 'gray' or 'dark'
37
- className,
38
- // playback time
39
- currentTime = 0,
40
- duration = 0,
41
- // transport
42
- onSeekBackward,
43
- onSeekForward,
44
- onPlayPause,
45
- isPlaying = false,
46
- // timeline
47
- audio,
48
- onSeek,
49
- // version dropdown
50
- versionTrigger,
51
- versionContent,
52
- // tempo and pitch dropdown
53
- tempoPitchContent,
54
- tempo,
55
- pitch,
56
- // metronome dropdown
57
- metronomeContent,
58
- metronomeEnabled,
59
- onMetronomeToggle,
60
- // volume popover
61
- volumeContent,
62
- onVolumeClick,
63
- // lyrics
64
- lyricsEnabled,
65
- onLyricsToggle,
66
- // chords detection
67
- chordsEnabled = false,
68
- onChordsToggle,
69
- // loop
70
- loopEnabled,
71
- onLoopToggle,
72
- // video and share
73
- onVideoClick,
74
- onShareClick,
75
- // expand
76
- expanded,
77
- onExpandToggle,
78
- }) => {
79
- return (
80
- <section
81
- aria-label="Player controls"
82
- className={classNames(styles.playerBarContainer, className)}
83
- >
84
- {showSlider && (
85
- <PlayerSlider
86
- currentTime={currentTime}
87
- duration={duration}
88
- audio={audio}
89
- onSeek={onSeek}
90
- />
91
- )}
92
- <Flex
93
- gap="6"
94
- className={classNames(styles.playerBar, {
95
- [styles.gray]: color === 'gray',
96
- [styles.dark]: color === 'dark',
97
- })}
98
- align="start"
99
- >
100
- <Flex align="center" gap="3" className={styles.flex2}>
101
- <Flex align="center" gap="4">
102
- {cover ? (
103
- <img src={cover} alt="Cover" className={styles.cover} />
104
- ) : (
105
- <div className={styles.cover}>
106
- <MusicNoteIcon width={16} height={16} />
107
- </div>
108
- )}
109
- </Flex>
110
- <Flex gap="3" pt="5px" align="start">
111
- <Flex direction="column" gap="0" className={styles.trackMeta}>
112
- <Text size="2" weight="medium" className={classNames(styles.trackLabel, styles.neutral12)}>
113
- {title}
114
- </Text>
115
- {subtitle ? (
116
- <Text size="1" weight="regular" className={classNames(styles.trackLabel, styles.neutralAlpha10)}>
117
- {subtitle}
118
- </Text>
119
- ) : null}
120
- </Flex>
121
- <Flex align="center" gap="2">{menuOptions && (
122
- <DropdownMenu
123
- trigger={
124
- <IconButton variant="ghost" size="2" className={styles.menuOptionsTrigger}>
125
- <More2Icon width={16} height={16} />
126
- </IconButton>}
127
- options={menuOptions}
128
- />
129
- )}
130
- {versionContent && versionTrigger && (
131
- <DropdownButton trigger={versionTrigger} showSeparator={false} className={styles.customDropdownButton}>
132
- {versionContent}
133
- </DropdownButton>
134
- )}
135
- </Flex>
136
- </Flex>
137
-
138
- </Flex>
139
-
140
- <Flex className={styles.flex1} direction="column" gap="0" align="center">
141
- <Flex align="center" gap="3">
142
- {volumeContent && (
143
- <Popover.Root>
144
- <Popover.Trigger>
145
- <IconButton variant="ghost" size="2" onClick={onVolumeClick}>
146
- <Volume2Icon width={16} height={16} />
147
- </IconButton>
148
- </Popover.Trigger>
149
- <Popover.Content>
150
- {volumeContent}
151
- </Popover.Content>
152
- </Popover.Root>
153
- )}
154
- <Flex gap='0' >
155
- <IconButton variant="ghost" size="4" onClick={onSeekBackward} className={styles.controlsIconButton}>
156
- <RewindBarFillIcon width={30} height={30} />
157
- </IconButton>
158
- <IconButton variant="ghost" size="4" onClick={onPlayPause} className={styles.controlsIconButton}>
159
- {isPlaying ? <PauseFilledIcon width={30} height={30} /> : <PlayIcon width={30} height={30} />}
160
- </IconButton>
161
- <IconButton variant="ghost" size="4" onClick={onSeekForward} className={styles.controlsIconButton}>
162
- <ForwardBarFillIcon width={30} height={30} />
163
- </IconButton>
164
- </Flex>
165
- <IconButton variant="ghost" size="2" onClick={onLoopToggle}>
166
- <PlayOnRepeatIcon width={16} height={16}
167
- className={classNames({
168
- [styles.actionIconActive]: !loopEnabled,
169
- [styles.actionIconDefault]: loopEnabled
170
- })}
171
- />
172
- </IconButton>
173
- </Flex>
174
- <Text size="1" weight="regular" className={styles.neutralAlpha10}>
175
- {formatTime(currentTime)} / {formatTime(duration)}
176
- </Text>
177
- </Flex>
178
-
179
- <Flex align="center" gap="3" className={classNames(styles.flex2, styles.actionsContainer)}>
180
- {tempoPitchContent && (
181
- <DropdownButton trigger={
182
- <Text className={styles.neutralAlpha11}>
183
- {tempo} bpm
184
- <Text className={styles.neutralAlpha6}> / </Text>
185
- {pitch}
186
- </Text>
187
- } showSeparator={false} className={styles.customDropdownButton}>
188
- {tempoPitchContent}
189
- </DropdownButton>
190
- )}
191
- {metronomeContent && (
192
- <DropdownButton
193
- trigger={
194
- <MetronomeIcon width={16} height={16}
195
- className={classNames({
196
- [styles.actionIconActive]: !metronomeEnabled,
197
- [styles.actionIconDefault]: metronomeEnabled
198
- })}
199
- />
200
- }
201
- onTriggerClick={onMetronomeToggle}
202
- >
203
- {metronomeContent}
204
- </DropdownButton>
205
- )}
206
- {onLyricsToggle && (
207
- <IconButton variant="ghost" size="2" onClick={onLyricsToggle}>
208
- <KaraokeMicIcon width={16} height={16}
209
- className={classNames({
210
- [styles.actionIconActive]: !lyricsEnabled,
211
- [styles.actionIconDefault]: lyricsEnabled
212
- })}
213
- />
214
- </IconButton>
215
- )}
216
- {onChordsToggle && (
217
- <IconButton variant="ghost" size="2" onClick={onChordsToggle}>
218
- <ChordsDetectionIcon width={16} height={16}
219
- className={classNames({
220
- [styles.actionIconActive]: !chordsEnabled,
221
- [styles.actionIconDefault]: chordsEnabled
222
- })} />
223
- </IconButton>
224
- )}
225
- {onVideoClick && (
226
- <IconButton variant="ghost" size="2" onClick={onVideoClick}>
227
- <Video2Icon width={16} height={16} />
228
- </IconButton>
229
- )}
230
-
231
- <Separator orientation="vertical" />
232
-
233
- {onShareClick && (
234
- <IconButton variant="ghost" size="2" onClick={onShareClick}>
235
- <Share2Icon width={16} height={16} />
236
- </IconButton>
237
- )}
238
-
239
- {onExpandToggle && (
240
- <IconButton variant="soft" color={expanded ? 'accent' : 'neutral'} size="2" onClick={onExpandToggle}>
241
- {expanded ? <ChevronDownIcon width={16} height={16} /> : <ChevronUpIcon width={16} height={16} />}
242
- </IconButton>
243
- )}
244
- </Flex>
245
- </Flex>
246
- </section >
247
- )
248
- }
249
-
250
- PlayerBar.displayName = 'PlayerBar'
@@ -1,135 +0,0 @@
1
- .playerBar {
2
- width: 100%;
3
- padding: 20px 20px 12px 20px;
4
- }
5
-
6
- .playerBarContainer {
7
- position: relative;
8
- width: 100%;
9
- }
10
-
11
- .playerBarContainer:has([data-interacting='true']) {
12
- z-index: 1;
13
- }
14
-
15
- .playerBar.gray {
16
- background: var(--neutral-2);
17
- }
18
-
19
- .playerBar.dark {
20
- background: var(--neutral-1);
21
- }
22
-
23
- .cover {
24
- display: flex;
25
- width: 48px;
26
- height: 48px;
27
- justify-content: center;
28
- align-items: center;
29
- gap: 8px;
30
- aspect-ratio: 1/1;
31
- background: var(--neutral-alpha-3);
32
- border-radius: 6px;
33
- }
34
-
35
- .trackMeta {
36
- min-width: 0;
37
- }
38
-
39
- .trackLabel {
40
- display: block;
41
- max-width: 89px;
42
- min-width: 89px;
43
- overflow: hidden;
44
- text-overflow: ellipsis;
45
- white-space: nowrap;
46
- }
47
-
48
- .neutral12 {
49
- color: var(--neutral-12);
50
- }
51
-
52
- .neutralAlpha10 {
53
- color: var(--neutral-alpha-10);
54
- }
55
-
56
- .neutralAlpha8 {
57
- color: var(--neutral-alpha-8);
58
- }
59
-
60
- .neutralAlpha11 {
61
- color: var(--neutral-alpha-11);
62
- }
63
-
64
- .neutralAlpha6 {
65
- color: var(--neutral-alpha-6);
66
- }
67
-
68
- .menuOptionsTrigger {
69
- svg {
70
- color: var(--neutral-alpha-8);
71
- }
72
-
73
- &:hover {
74
- svg {
75
- color: var(--neutral-alpha-12);
76
- }
77
- }
78
- }
79
-
80
- .customDropdownButton> :first-child {
81
- padding: 0px 4px !important;
82
- box-shadow: inset 0 0 0 1px var(--neutral-alpha-3) !important;
83
- border: 0 !important;
84
- }
85
-
86
- .flex1 {
87
- flex: 1;
88
- }
89
-
90
- .flex2 {
91
- flex: 2;
92
- }
93
-
94
- .controlsIconButton {
95
- svg {
96
- color: var(--neutral-12)
97
- }
98
-
99
-
100
- &:hover {
101
- svg {
102
- color: #fff !important;
103
- }
104
- }
105
-
106
- &:active {
107
- svg {
108
- color: var(--neutral-10) !important;
109
- }
110
- }
111
-
112
- }
113
-
114
- .actionIconActive,
115
- .actionIconActive:active {
116
- color: var(--neutral-11) !important;
117
- }
118
-
119
- .actionIconActive:hover {
120
- color: var(--neutral-12) !important;
121
- }
122
-
123
- .actionIconDefault,
124
- .actionIconDefault:active {
125
- color: #0AFFA7 !important;
126
- }
127
-
128
- .actionIconDefault:hover {
129
- color: #07db8d !important;
130
- }
131
-
132
- .actionsContainer {
133
- padding-top: 8px;
134
- justify-content: flex-end;
135
- }