gbs-add-block 2.0.4 → 2.3.0

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 (129) hide show
  1. package/.gbs/skills/gbs-components/SKILL.md +190 -134
  2. package/.gbs/skills/gbs-components/references/install.md +25 -3
  3. package/.gbs/skills/gbs-components/references/styling.md +246 -201
  4. package/CHANGELOG.md +74 -0
  5. package/README.md +157 -11
  6. package/index.cjs +212 -3
  7. package/package.json +41 -10
  8. package/schema/passport-v1.schema.json +204 -0
  9. package/source/beta-components/accordion/passport.json +259 -0
  10. package/source/beta-components/accordion/styles.css +207 -208
  11. package/source/beta-components/alert/passport.json +250 -0
  12. package/source/beta-components/alert/styles.css +154 -155
  13. package/source/beta-components/avatar/passport.json +294 -0
  14. package/source/beta-components/avatar/styles.css +201 -203
  15. package/source/beta-components/badge/passport.json +332 -0
  16. package/source/beta-components/badge/styles.css +203 -204
  17. package/source/beta-components/breadcrumb/passport.json +243 -0
  18. package/source/beta-components/breadcrumb/styles.css +138 -139
  19. package/source/beta-components/button/passport.json +402 -0
  20. package/source/beta-components/button/passport.manual.json +31 -0
  21. package/source/beta-components/button/styles.css +232 -233
  22. package/source/beta-components/card/passport.json +337 -0
  23. package/source/beta-components/card/styles.css +230 -231
  24. package/source/beta-components/checkbox/passport.json +456 -0
  25. package/source/beta-components/checkbox/styles.css +211 -212
  26. package/source/beta-components/combobox/passport.json +456 -0
  27. package/source/beta-components/combobox/styles.css +419 -417
  28. package/source/beta-components/data-grid/agent/coerce.ts +368 -0
  29. package/source/beta-components/data-grid/agent/contract.ts +410 -0
  30. package/source/beta-components/data-grid/agent/dataset.ts +92 -0
  31. package/source/beta-components/data-grid/agent/engine.ts +470 -0
  32. package/source/beta-components/data-grid/agent/executors.ts +155 -0
  33. package/source/beta-components/data-grid/agent/index.ts +79 -0
  34. package/source/beta-components/data-grid/agent/intent.ts +324 -0
  35. package/source/beta-components/data-grid/agent/operations.ts +335 -0
  36. package/source/beta-components/data-grid/agent/validate.ts +630 -0
  37. package/source/beta-components/data-grid/agent/webmcp.ts +107 -0
  38. package/source/beta-components/data-grid/index.ts +14 -7
  39. package/source/beta-components/data-grid/passport.json +1051 -0
  40. package/source/beta-components/data-grid/passport.manual.json +255 -0
  41. package/source/beta-components/data-grid/react/AskGrid.tsx +164 -0
  42. package/source/beta-components/data-grid/react/DataGrid.tsx +39 -0
  43. package/source/beta-components/data-grid/styles.css +874 -717
  44. package/source/beta-components/date-picker/passport.json +407 -0
  45. package/source/beta-components/date-picker/styles.css +445 -446
  46. package/source/beta-components/dialog/passport.json +344 -0
  47. package/source/beta-components/dialog/styles.css +280 -278
  48. package/source/beta-components/file-uploader/passport.json +518 -0
  49. package/source/beta-components/file-uploader/styles.css +394 -395
  50. package/source/beta-components/input/passport.json +536 -0
  51. package/source/beta-components/input/styles.css +295 -296
  52. package/source/beta-components/menu/passport.json +322 -0
  53. package/source/beta-components/menu/styles.css +224 -222
  54. package/source/beta-components/modal/passport.json +289 -0
  55. package/source/beta-components/modal/styles.css +241 -239
  56. package/source/beta-components/number-input/passport.json +541 -0
  57. package/source/beta-components/number-input/styles.css +230 -231
  58. package/source/beta-components/popover/passport.json +238 -0
  59. package/source/beta-components/popover/styles.css +148 -146
  60. package/source/beta-components/progress/passport.json +270 -0
  61. package/source/beta-components/progress/styles.css +200 -202
  62. package/source/beta-components/radio-group/passport.json +477 -0
  63. package/source/beta-components/radio-group/styles.css +241 -242
  64. package/source/beta-components/shared/core/agent/adapter.ts +65 -0
  65. package/source/beta-components/shared/core/agent/history.ts +120 -0
  66. package/source/beta-components/shared/core/agent/index.ts +46 -0
  67. package/source/beta-components/shared/core/agent/numbers.ts +217 -0
  68. package/source/beta-components/shared/core/agent/schema.ts +180 -0
  69. package/source/beta-components/shared/core/agent/types.ts +169 -0
  70. package/source/beta-components/shared/core/agent/webmcp.ts +328 -0
  71. package/source/beta-components/shared/index.ts +9 -0
  72. package/source/beta-components/shared/react/GramproAIProvider.tsx +50 -0
  73. package/source/beta-components/shared/react/useAskAgent.ts +217 -0
  74. package/source/beta-components/shared/styles.css +79 -0
  75. package/source/beta-components/shared/version.json +4 -4
  76. package/source/beta-components/shared/version.ts +6 -6
  77. package/source/beta-components/skeleton/passport.json +251 -0
  78. package/source/beta-components/skeleton/styles.css +185 -186
  79. package/source/beta-components/spinner/passport.json +245 -0
  80. package/source/beta-components/spinner/styles.css +145 -146
  81. package/source/beta-components/switch/passport.json +421 -0
  82. package/source/beta-components/switch/styles.css +194 -196
  83. package/source/beta-components/tabs/passport.json +315 -0
  84. package/source/beta-components/tabs/styles.css +234 -235
  85. package/source/beta-components/textarea/passport.json +382 -0
  86. package/source/beta-components/textarea/styles.css +158 -159
  87. package/source/beta-components/toaster/passport.json +221 -0
  88. package/source/beta-components/toaster/styles.css +282 -283
  89. package/source/beta-components/tooltip/passport.json +170 -0
  90. package/source/beta-components/tooltip/styles.css +71 -72
  91. package/tools/env.cjs +61 -0
  92. package/tools/passport/cli.cjs +79 -0
  93. package/tools/passport/extract.cjs +493 -0
  94. package/tools/passport/index.cjs +185 -0
  95. package/tools/passport/merge.cjs +131 -0
  96. package/tools/passport/policy.cjs +65 -0
  97. package/tools/passport/validate.cjs +277 -0
  98. package/tools/ts-require.cjs +79 -0
  99. package/source/beta-components/accordion/__tests__/core.test.ts +0 -58
  100. package/source/beta-components/alert/__tests__/core.test.ts +0 -17
  101. package/source/beta-components/avatar/__tests__/core.test.ts +0 -88
  102. package/source/beta-components/badge/__tests__/core.test.ts +0 -46
  103. package/source/beta-components/breadcrumb/__tests__/core.test.ts +0 -58
  104. package/source/beta-components/button/__tests__/core.test.ts +0 -31
  105. package/source/beta-components/card/__tests__/core.test.ts +0 -57
  106. package/source/beta-components/checkbox/__tests__/core.test.ts +0 -40
  107. package/source/beta-components/combobox/__tests__/core.test.ts +0 -134
  108. package/source/beta-components/data-grid/__tests__/core.test.ts +0 -356
  109. package/source/beta-components/data-grid/__tests__/export.test.ts +0 -70
  110. package/source/beta-components/data-grid/__tests__/pdf.test.ts +0 -209
  111. package/source/beta-components/date-picker/__tests__/core.test.ts +0 -273
  112. package/source/beta-components/dialog/__tests__/core.test.ts +0 -86
  113. package/source/beta-components/file-uploader/__tests__/core.test.ts +0 -395
  114. package/source/beta-components/input/__tests__/core.test.ts +0 -75
  115. package/source/beta-components/menu/__tests__/core.test.ts +0 -120
  116. package/source/beta-components/modal/__tests__/core.test.ts +0 -55
  117. package/source/beta-components/number-input/__tests__/core.test.ts +0 -151
  118. package/source/beta-components/progress/__tests__/core.test.ts +0 -56
  119. package/source/beta-components/radio-group/__tests__/core.test.ts +0 -64
  120. package/source/beta-components/shared/__tests__/boundaries.test.ts +0 -95
  121. package/source/beta-components/shared/__tests__/core.test.ts +0 -55
  122. package/source/beta-components/shared/__tests__/position.test.ts +0 -143
  123. package/source/beta-components/skeleton/__tests__/core.test.ts +0 -41
  124. package/source/beta-components/spinner/__tests__/core.test.ts +0 -48
  125. package/source/beta-components/switch/__tests__/core.test.ts +0 -64
  126. package/source/beta-components/tabs/__tests__/core.test.ts +0 -51
  127. package/source/beta-components/textarea/__tests__/core.test.ts +0 -38
  128. package/source/beta-components/toaster/__tests__/core.test.ts +0 -256
  129. package/source/beta-components/tooltip/__tests__/core.test.ts +0 -42
@@ -1,222 +1,224 @@
1
- /*
2
- * Menu styles.
3
- *
4
- * Tokens read the shared --gbs-* variables when they are set on an ancestor
5
- * (set them on :root to theme every component at once) and fall back to the
6
- * same default palette otherwise. Rules live in the `components` layer, so utility classes passed
7
- * through `className` / `classNames` override them.
8
- */
9
- @layer theme, base, components, utilities;
10
-
11
- @layer components {
12
- .mn-root {
13
- --mn-bg: var(--gbs-bg, var(--dg-bg, light-dark(#ffffff, #0b0b0e)));
14
- --mn-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
15
- --mn-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
16
- --mn-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
17
- --mn-hover: var(--gbs-hover, var(--dg-hover, light-dark(#f4f4f5, #1f1f23)));
18
- --mn-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa)));
19
- --mn-focus: var(--gbs-focus, var(--dg-focus, light-dark(#2563eb, #60a5fa)));
20
- --mn-danger: var(--gbs-danger, var(--dg-danger, light-dark(#dc2626, #f87171)));
21
- --mn-shadow: var(--gbs-shadow, var(--dg-shadow, 0 10px 30px -8px light-dark(rgb(0 0 0 / 0.18), rgb(0 0 0 / 0.6))));
22
- --mn-radius: var(--gbs-radius, var(--dg-radius, 8px));
23
- --mn-font-size: var(--gbs-font-size, var(--dg-font-size, 13px));
24
- --mn-item-radius: 5px;
25
- --mn-min-width: 180px;
26
- --mn-duration: 120ms;
27
-
28
- position: fixed;
29
- inset: auto;
30
- z-index: 60;
31
- min-width: var(--mn-min-width);
32
- max-width: min(320px, calc(100vw - 16px));
33
- margin: 0;
34
- padding: 4px;
35
- overflow: auto;
36
- overscroll-behavior: contain;
37
- border: 1px solid var(--mn-border);
38
- border-radius: var(--mn-radius);
39
- background: var(--mn-bg);
40
- color: var(--mn-fg);
41
- box-shadow: var(--mn-shadow);
42
- color-scheme: inherit;
43
- font-size: var(--mn-font-size);
44
- line-height: 1.4;
45
- }
46
-
47
- :where(.dark, [data-theme="dark"]) .mn-root {
48
- color-scheme: dark;
49
- }
50
- :where(.light, [data-theme="light"]) .mn-root {
51
- color-scheme: light;
52
- }
53
-
54
- :where(.mn-root) *,
55
- :where(.mn-root) *::before,
56
- :where(.mn-root) *::after {
57
- box-sizing: border-box;
58
- }
59
-
60
- /* The list takes focus before the first item does; that flash of an outline
61
- around the whole menu is not useful. */
62
- .mn-root:focus,
63
- .mn-list:focus {
64
- outline: none;
65
- }
66
-
67
- .mn-root:popover-open {
68
- animation: mn-in var(--mn-duration) ease;
69
- }
70
- @keyframes mn-in {
71
- from {
72
- opacity: 0;
73
- translate: 0 -2px;
74
- }
75
- }
76
- .mn-root[data-side="top"]:popover-open {
77
- animation-name: mn-in-top;
78
- }
79
- @keyframes mn-in-top {
80
- from {
81
- opacity: 0;
82
- translate: 0 2px;
83
- }
84
- }
85
-
86
- .mn-list {
87
- display: flex;
88
- flex-direction: column;
89
- min-width: 0;
90
- }
91
-
92
- /* --------------------------------------------------------------- items */
93
-
94
- .mn-item {
95
- display: flex;
96
- align-items: center;
97
- gap: 8px;
98
- min-width: 0;
99
- padding: 6px 8px;
100
- border-radius: var(--mn-item-radius);
101
- cursor: default;
102
- user-select: none;
103
- }
104
- .mn-item:hover:not([data-disabled]) {
105
- background: var(--mn-hover);
106
- }
107
- /* Menus move focus rather than tracking a separate active item, so the
108
- focused item is the highlighted one. */
109
- .mn-item:focus {
110
- background: var(--mn-hover);
111
- outline: none;
112
- }
113
- .mn-item:focus-visible {
114
- outline: 2px solid var(--mn-focus);
115
- outline-offset: -2px;
116
- }
117
- .mn-item[data-disabled] {
118
- color: var(--mn-muted);
119
- cursor: not-allowed;
120
- }
121
- .mn-item[data-destructive]:not([data-disabled]) {
122
- color: var(--mn-danger);
123
- }
124
-
125
- .mn-label {
126
- flex: 1 1 auto;
127
- min-width: 0;
128
- overflow: hidden;
129
- text-overflow: ellipsis;
130
- white-space: nowrap;
131
- }
132
-
133
- .mn-icon {
134
- display: inline-flex;
135
- flex: none;
136
- align-items: center;
137
- color: var(--mn-muted);
138
- }
139
- .mn-item[data-destructive] .mn-icon {
140
- color: inherit;
141
- }
142
-
143
- .mn-shortcut {
144
- flex: none;
145
- margin-inline-start: auto;
146
- padding-inline-start: 12px;
147
- color: var(--mn-muted);
148
- font-size: 0.92em;
149
- font-variant-numeric: tabular-nums;
150
- }
151
-
152
- /* The indicator column keeps labels aligned whether or not an item is
153
- checked, so the list does not shift as things are toggled. */
154
- .mn-indicator {
155
- display: inline-flex;
156
- flex: none;
157
- align-items: center;
158
- justify-content: center;
159
- width: 14px;
160
- height: 14px;
161
- color: var(--mn-accent);
162
- }
163
- .mn-dot {
164
- width: 6px;
165
- height: 6px;
166
- border-radius: 50%;
167
- background: currentColor;
168
- }
169
-
170
- /* -------------------------------------------------------------- groups */
171
-
172
- .mn-group {
173
- display: flex;
174
- flex-direction: column;
175
- min-width: 0;
176
- }
177
- .mn-group-label {
178
- padding: 6px 8px 2px;
179
- color: var(--mn-muted);
180
- font-size: 0.85em;
181
- font-weight: 600;
182
- letter-spacing: 0.02em;
183
- text-transform: uppercase;
184
- }
185
-
186
- .mn-separator {
187
- height: 1px;
188
- margin: 4px -4px;
189
- background: var(--mn-border);
190
- }
191
-
192
- /* ------------------------------------------------------------ submenus */
193
-
194
- .mn-sub-trigger .mn-sub-arrow {
195
- flex: none;
196
- margin-inline-start: auto;
197
- color: var(--mn-muted);
198
- }
199
- /* The arrow points into the submenu, which is on the other side in RTL. */
200
- .mn-root:dir(rtl) .mn-sub-arrow {
201
- rotate: 180deg;
202
- }
203
- .mn-sub-trigger[aria-expanded="true"] {
204
- background: var(--mn-hover);
205
- }
206
-
207
- @media (prefers-reduced-motion: reduce) {
208
- .mn-root:popover-open {
209
- animation: none;
210
- }
211
- }
212
-
213
- @media (forced-colors: active) {
214
- .mn-root {
215
- border: 1px solid CanvasText;
216
- }
217
- .mn-item:focus {
218
- outline: 2px solid Highlight;
219
- outline-offset: -2px;
220
- }
221
- }
222
- }
1
+ /*
2
+ * Menu styles.
3
+ *
4
+ * Tokens read the shared --gbs-* variables when they are set on an ancestor
5
+ * (set them on :root to theme every component at once) and fall back to the
6
+ * same default palette otherwise. Rules are unlayered: they beat a framework
7
+ * reset on specificity, and lose to anything you pass through `className`.
8
+ * With Tailwind v4, import this file after the framework and inside its
9
+ * components layer - see the README.
10
+ */
11
+
12
+ .mn-root {
13
+ --mn-bg: var(--gbs-bg, var(--dg-bg, light-dark(#ffffff, #0b0b0e)));
14
+ --mn-fg: var(--gbs-fg, var(--dg-fg, light-dark(#18181b, #f4f4f5)));
15
+ --mn-muted: var(--gbs-muted, var(--dg-muted, light-dark(#71717a, #a1a1aa)));
16
+ --mn-border: var(--gbs-border, var(--dg-border, light-dark(#e4e4e7, #27272a)));
17
+ --mn-hover: var(--gbs-hover, var(--dg-hover, light-dark(#f4f4f5, #1f1f23)));
18
+ --mn-accent: var(--gbs-accent, var(--dg-accent, light-dark(#2563eb, #60a5fa)));
19
+ --mn-focus: var(--gbs-focus, var(--dg-focus, light-dark(#2563eb, #60a5fa)));
20
+ --mn-danger: var(--gbs-danger, var(--dg-danger, light-dark(#dc2626, #f87171)));
21
+ --mn-shadow: var(--gbs-shadow, var(--dg-shadow, 0 10px 30px -8px light-dark(rgb(0 0 0 / 0.18), rgb(0 0 0 / 0.6))));
22
+ --mn-radius: var(--gbs-radius, var(--dg-radius, 8px));
23
+ --mn-font-size: var(--gbs-font-size, var(--dg-font-size, 13px));
24
+ --mn-item-radius: 5px;
25
+ --mn-min-width: 180px;
26
+ --mn-duration: 120ms;
27
+
28
+ position: fixed;
29
+ inset: auto;
30
+ z-index: 60;
31
+ min-width: var(--mn-min-width);
32
+ max-width: min(320px, calc(100vw - 16px));
33
+ margin: 0;
34
+ padding: 4px;
35
+ overflow: auto;
36
+ overscroll-behavior: contain;
37
+ border: 1px solid var(--mn-border);
38
+ border-radius: var(--mn-radius);
39
+ background: var(--mn-bg);
40
+ color: var(--mn-fg);
41
+ box-shadow: var(--mn-shadow);
42
+ color-scheme: inherit;
43
+ font-size: var(--mn-font-size);
44
+ line-height: 1.4;
45
+ scrollbar-width: var(--gbs-scrollbar-width, thin);
46
+ scrollbar-color: var(--gbs-scrollbar-thumb, light-dark(#c4c4ca, #3f3f46))
47
+ var(--gbs-scrollbar-track, transparent);
48
+ }
49
+
50
+ :where(.dark, [data-theme="dark"]) .mn-root {
51
+ color-scheme: dark;
52
+ }
53
+ :where(.light, [data-theme="light"]) .mn-root {
54
+ color-scheme: light;
55
+ }
56
+
57
+ :where(.mn-root) *,
58
+ :where(.mn-root) *::before,
59
+ :where(.mn-root) *::after {
60
+ box-sizing: border-box;
61
+ }
62
+
63
+ /* The list takes focus before the first item does; that flash of an outline
64
+ around the whole menu is not useful. */
65
+ .mn-root:focus,
66
+ .mn-list:focus {
67
+ outline: none;
68
+ }
69
+
70
+ .mn-root:popover-open {
71
+ animation: mn-in var(--mn-duration) ease;
72
+ }
73
+ @keyframes mn-in {
74
+ from {
75
+ opacity: 0;
76
+ translate: 0 -2px;
77
+ }
78
+ }
79
+ .mn-root[data-side="top"]:popover-open {
80
+ animation-name: mn-in-top;
81
+ }
82
+ @keyframes mn-in-top {
83
+ from {
84
+ opacity: 0;
85
+ translate: 0 2px;
86
+ }
87
+ }
88
+
89
+ .mn-list {
90
+ display: flex;
91
+ flex-direction: column;
92
+ min-width: 0;
93
+ }
94
+
95
+ /* --------------------------------------------------------------- items */
96
+
97
+ .mn-item {
98
+ display: flex;
99
+ align-items: center;
100
+ gap: 8px;
101
+ min-width: 0;
102
+ padding: 6px 8px;
103
+ border-radius: var(--mn-item-radius);
104
+ cursor: default;
105
+ user-select: none;
106
+ }
107
+ .mn-item:hover:not([data-disabled]) {
108
+ background: var(--mn-hover);
109
+ }
110
+ /* Menus move focus rather than tracking a separate active item, so the
111
+ focused item is the highlighted one. */
112
+ .mn-item:focus {
113
+ background: var(--mn-hover);
114
+ outline: none;
115
+ }
116
+ .mn-item:focus-visible {
117
+ outline: 2px solid var(--mn-focus);
118
+ outline-offset: -2px;
119
+ }
120
+ .mn-item[data-disabled] {
121
+ color: var(--mn-muted);
122
+ cursor: not-allowed;
123
+ }
124
+ .mn-item[data-destructive]:not([data-disabled]) {
125
+ color: var(--mn-danger);
126
+ }
127
+
128
+ .mn-label {
129
+ flex: 1 1 auto;
130
+ min-width: 0;
131
+ overflow: hidden;
132
+ text-overflow: ellipsis;
133
+ white-space: nowrap;
134
+ }
135
+
136
+ .mn-icon {
137
+ display: inline-flex;
138
+ flex: none;
139
+ align-items: center;
140
+ color: var(--mn-muted);
141
+ }
142
+ .mn-item[data-destructive] .mn-icon {
143
+ color: inherit;
144
+ }
145
+
146
+ .mn-shortcut {
147
+ flex: none;
148
+ margin-inline-start: auto;
149
+ padding-inline-start: 12px;
150
+ color: var(--mn-muted);
151
+ font-size: 0.92em;
152
+ font-variant-numeric: tabular-nums;
153
+ }
154
+
155
+ /* The indicator column keeps labels aligned whether or not an item is
156
+ checked, so the list does not shift as things are toggled. */
157
+ .mn-indicator {
158
+ display: inline-flex;
159
+ flex: none;
160
+ align-items: center;
161
+ justify-content: center;
162
+ width: 14px;
163
+ height: 14px;
164
+ color: var(--mn-accent);
165
+ }
166
+ .mn-dot {
167
+ width: 6px;
168
+ height: 6px;
169
+ border-radius: 50%;
170
+ background: currentColor;
171
+ }
172
+
173
+ /* -------------------------------------------------------------- groups */
174
+
175
+ .mn-group {
176
+ display: flex;
177
+ flex-direction: column;
178
+ min-width: 0;
179
+ }
180
+ .mn-group-label {
181
+ padding: 6px 8px 2px;
182
+ color: var(--mn-muted);
183
+ font-size: 0.85em;
184
+ font-weight: 600;
185
+ letter-spacing: 0.02em;
186
+ text-transform: uppercase;
187
+ }
188
+
189
+ .mn-separator {
190
+ height: 1px;
191
+ margin: 4px -4px;
192
+ background: var(--mn-border);
193
+ }
194
+
195
+ /* ------------------------------------------------------------ submenus */
196
+
197
+ .mn-sub-trigger .mn-sub-arrow {
198
+ flex: none;
199
+ margin-inline-start: auto;
200
+ color: var(--mn-muted);
201
+ }
202
+ /* The arrow points into the submenu, which is on the other side in RTL. */
203
+ .mn-root:dir(rtl) .mn-sub-arrow {
204
+ rotate: 180deg;
205
+ }
206
+ .mn-sub-trigger[aria-expanded="true"] {
207
+ background: var(--mn-hover);
208
+ }
209
+
210
+ @media (prefers-reduced-motion: reduce) {
211
+ .mn-root:popover-open {
212
+ animation: none;
213
+ }
214
+ }
215
+
216
+ @media (forced-colors: active) {
217
+ .mn-root {
218
+ border: 1px solid CanvasText;
219
+ }
220
+ .mn-item:focus {
221
+ outline: 2px solid Highlight;
222
+ outline-offset: -2px;
223
+ }
224
+ }