@rescui/chip-list 0.14.0 → 0.14.1-RUI-296-Build-docs-md-files-for-each-docs-section-b138dd5bf.19

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.
@@ -0,0 +1,615 @@
1
+ # ChipList
2
+
3
+ Created with adaptivity in mind, ChipList is the component for radiogroup-like controls and navigational panels. It wraps items onto a new line if the screen is too narrow to fit all of the content.
4
+
5
+ ## Usage
6
+
7
+ ### Features showcase
8
+
9
+ `ChipList` component can only be a controlled component. It requires `value` and `onChange` props to function properly.
10
+
11
+ By default, `ChipList` uses `pattern="auto"`. It renders native `input[type="radio"]` elements with `role="radiogroup"` when chips do not have `href`, switches to `role="navigation"` when at least one chip has `href`, and switches to `role="tablist"` when chips use `aria-controls`.
12
+
13
+ `ChipList` interactive overview:
14
+
15
+ #### Content Switcher made of ChipList with default values
16
+
17
+ `ChipList` enumerates `Chip` children components, so by default it has different keys for `onChange` prop function. When chips switch panels, add `aria-controls` to every chip so `pattern="auto"` resolves to `role="tablist"`.
18
+
19
+ ```tsx
20
+ import { useState } from 'react';
21
+ import { ChipList, Chip } from '@rescui/chip-list';
22
+ import { Switcher } from '@rescui/switcher';
23
+
24
+ const ContentSwitcher = ({ index, children }) => {
25
+ return children[index];
26
+ };
27
+ const Demo = () => {
28
+ const [activeIndex, setActiveIndex] = useState(1);
29
+ return (
30
+ <div>
31
+ <Switcher
32
+ size="xs"
33
+ value={activeIndex}
34
+ options={[
35
+ { label: 'First', value: 0 },
36
+ { label: 'Second', value: 1 },
37
+ { label: 'Third', value: 2 }
38
+ ]}
39
+ onChange={v => setActiveIndex(v)}
40
+ className="rs-docs-offset-top-12"
41
+ />
42
+ <ChipList
43
+ value={activeIndex}
44
+ onChange={v => setActiveIndex(v)}
45
+ className="rs-docs-offset-top-12"
46
+ >
47
+ <Chip id="first-default-tab" aria-controls="first-default-panel">
48
+ First
49
+ </Chip>
50
+ <Chip id="second-default-tab" aria-controls="second-default-panel">
51
+ Second
52
+ </Chip>
53
+ <Chip id="third-default-tab" aria-controls="third-default-panel">
54
+ Third
55
+ </Chip>
56
+ </ChipList>
57
+ <div className="rs-docs-offset-top-12">
58
+ <ContentSwitcher index={activeIndex}>
59
+ <div
60
+ id="first-default-panel"
61
+ role="tabpanel"
62
+ aria-labelledby="first-default-tab"
63
+ >
64
+ First
65
+ </div>
66
+ <div
67
+ id="second-default-panel"
68
+ role="tabpanel"
69
+ aria-labelledby="second-default-tab"
70
+ >
71
+ Second
72
+ </div>
73
+ <div
74
+ id="third-default-panel"
75
+ role="tabpanel"
76
+ aria-labelledby="third-default-tab"
77
+ >
78
+ Third
79
+ </div>
80
+ </ContentSwitcher>
81
+ </div>
82
+ </div>
83
+ );
84
+ };
85
+
86
+ render(<Demo />);
87
+ ```
88
+
89
+ #### Switcher with custom values on Chips and component for tab content
90
+
91
+ `ChipList` component works as radiogroup-like control with custom `value` on `Chip` components.
92
+
93
+ ```tsx
94
+ import { useState } from 'react';
95
+ import { ChipList, Chip } from '@rescui/chip-list';
96
+ import { Switcher } from '@rescui/switcher';
97
+
98
+ const Content = ({ activeChip }) => {
99
+ switch (activeChip) {
100
+ case 'first':
101
+ return <div>First</div>;
102
+ case 'second':
103
+ return <div>Second</div>;
104
+ case 'third':
105
+ return <div>Third</div>;
106
+ }
107
+ };
108
+ const Demo = () => {
109
+ const [activeChip, setActiveChip] = useState('second');
110
+ return (
111
+ <div>
112
+ <div>
113
+ <Switcher
114
+ size="xs"
115
+ value={activeChip}
116
+ options={[
117
+ { label: 'First', value: 'first' },
118
+ { label: 'Second', value: 'second' },
119
+ { label: 'Third', value: 'third' }
120
+ ]}
121
+ onChange={tab => setActiveChip(tab)}
122
+ className="rs-docs-offset-top-12"
123
+ />
124
+ </div>
125
+ <ChipList
126
+ value={activeChip}
127
+ onChange={v => setActiveChip(v)}
128
+ className="rs-docs-offset-top-12"
129
+ >
130
+ <Chip value="first">First</Chip>
131
+ <Chip value="second">Second</Chip>
132
+ <Chip value="third">Third</Chip>
133
+ </ChipList>
134
+ <div className="rs-docs-offset-top-12">
135
+ <Content activeChip={activeChip} />
136
+ </div>
137
+ </div>
138
+ );
139
+ };
140
+
141
+ render(<Demo />);
142
+ ```
143
+
144
+ #### SEO tip: render the content from every tab and hide it with display: none
145
+
146
+ Content could be rendered to DOM and hidden with CSS. This is a usefull trick for SEO optimization. This is also the most complete tablist pattern because every controlled panel stays in the DOM.
147
+
148
+ ```tsx
149
+ import { useState, cloneElement } from 'react';
150
+ import { ChipList, Chip } from '@rescui/chip-list';
151
+
152
+ const CSSContentSwitcher = ({ index, children }) => {
153
+ return children.map((ch, i) => {
154
+ const chStyles = ch.props.style || {};
155
+ const addStyles = i === index ? {} : { display: 'none' };
156
+ return cloneElement(ch, { key: i, style: { ...chStyles, ...addStyles } });
157
+ });
158
+ };
159
+
160
+ const Demo = () => {
161
+ const [activeIndex, setActiveIndex] = useState(0);
162
+ return (
163
+ <div className="rs-docs-offset-top-24">
164
+ <ChipList value={activeIndex} onChange={v => setActiveIndex(v)}>
165
+ <Chip id="first-seo-tab" aria-controls="first-seo-panel">
166
+ First
167
+ </Chip>
168
+ <Chip id="second-seo-tab" aria-controls="second-seo-panel">
169
+ Second
170
+ </Chip>
171
+ <Chip id="third-seo-tab" aria-controls="third-seo-panel">
172
+ Third
173
+ </Chip>
174
+ </ChipList>
175
+ <CSSContentSwitcher index={activeIndex}>
176
+ <div
177
+ id="first-seo-panel"
178
+ role="tabpanel"
179
+ aria-labelledby="first-seo-tab"
180
+ >
181
+ First
182
+ </div>
183
+ <div
184
+ id="second-seo-panel"
185
+ role="tabpanel"
186
+ aria-labelledby="second-seo-tab"
187
+ >
188
+ Second
189
+ </div>
190
+ <div
191
+ id="third-seo-panel"
192
+ role="tabpanel"
193
+ aria-labelledby="third-seo-tab"
194
+ >
195
+ Third
196
+ </div>
197
+ </CSSContentSwitcher>
198
+ </div>
199
+ );
200
+ };
201
+
202
+ render(<Demo />);
203
+ ```
204
+
205
+ #### Controls for the e2e tests
206
+
207
+ When testing the page, you can get access to the arrows with `data-e2e` attributes. You should set the scope with the `data-e2e` attribute from the outside.
208
+
209
+ ```tsx
210
+ import { useState, cloneElement } from 'react';
211
+ import { ChipList, Chip } from '@rescui/chip-list';
212
+
213
+ const CSSContentSwitcher = ({ index, children }) => {
214
+ return children.map((ch, i) => {
215
+ const chStyles = ch.props.style || {};
216
+ const addStyles = i === index ? {} : { display: 'none' };
217
+ return cloneElement(ch, { key: i, style: { ...chStyles, ...addStyles } });
218
+ });
219
+ };
220
+
221
+ const Demo = () => {
222
+ const [activeIndex, setActiveIndex] = useState(0);
223
+ return (
224
+ <div className="rs-docs-offset-top-24">
225
+ <ChipList
226
+ value={activeIndex}
227
+ onChange={v => setActiveIndex(v)}
228
+ data-e2e={'example-chips'}
229
+ >
230
+ <Chip id="first-e2e-tab" aria-controls="first-e2e-panel">
231
+ First
232
+ </Chip>
233
+ <Chip id="second-e2e-tab" aria-controls="second-e2e-panel">
234
+ Second
235
+ </Chip>
236
+ <Chip id="third-e2e-tab" aria-controls="third-e2e-panel">
237
+ Third
238
+ </Chip>
239
+ </ChipList>
240
+ <CSSContentSwitcher index={activeIndex}>
241
+ <div
242
+ id="first-e2e-panel"
243
+ role="tabpanel"
244
+ aria-labelledby="first-e2e-tab"
245
+ >
246
+ First
247
+ </div>
248
+ <div
249
+ id="second-e2e-panel"
250
+ role="tabpanel"
251
+ aria-labelledby="second-e2e-tab"
252
+ >
253
+ Second
254
+ </div>
255
+ <div
256
+ id="third-e2e-panel"
257
+ role="tabpanel"
258
+ aria-labelledby="third-e2e-tab"
259
+ >
260
+ Third
261
+ </div>
262
+ </CSSContentSwitcher>
263
+ </div>
264
+ );
265
+ };
266
+
267
+ render(<Demo />);
268
+ ```
269
+
270
+ #### Usage with Icons
271
+
272
+ ```tsx
273
+ import { useState } from 'react';
274
+ import { ChipList, Chip } from '@rescui/chip-list';
275
+ import {
276
+ TeamOutlineIcon,
277
+ WinOutlineIcon,
278
+ ThumbsUpOutlineIcon
279
+ } from '@rescui/icons';
280
+
281
+ const Demo = () => {
282
+ const [activeChip, setActiveChip] = useState('second');
283
+ return (
284
+ <div>
285
+ <ChipList
286
+ value={activeChip}
287
+ onChange={v => setActiveChip(v)}
288
+ className="rs-docs-offset-top-12"
289
+ >
290
+ <Chip icon={<TeamOutlineIcon />} value="first">
291
+ First
292
+ </Chip>
293
+ <Chip icon={<WinOutlineIcon />} value="second">
294
+ Second
295
+ </Chip>
296
+ <Chip icon={<ThumbsUpOutlineIcon />} value="third">
297
+ Third
298
+ </Chip>
299
+ </ChipList>
300
+ </div>
301
+ );
302
+ };
303
+
304
+ render(<Demo />);
305
+ ```
306
+
307
+ #### Chips as links
308
+
309
+ With the default `pattern="auto"`, chips with `href` switch the whole list to navigation behavior. You can also set `pattern="navigation"` explicitly. In `pattern="radiogroup"`, `href` is ignored and a development warning is printed.
310
+
311
+ ```tsx
312
+ import { useState } from 'react';
313
+ import { ChipList, Chip } from '@rescui/chip-list';
314
+
315
+ const Demo = () => {
316
+ const [activeChip, setActiveChip] = useState('second');
317
+ return (
318
+ <div>
319
+ <div>
320
+ <h4 id="first">First</h4>
321
+ <h4 id="second">Second</h4>
322
+ <h4 id="third">Third</h4>
323
+ </div>
324
+ <ChipList
325
+ value={activeChip}
326
+ onChange={v => setActiveChip(v)}
327
+ className="rs-docs-offset-top-24"
328
+ >
329
+ <Chip href="#first" value="first">
330
+ First
331
+ </Chip>
332
+ <Chip href="#second" value="second">
333
+ Second
334
+ </Chip>
335
+ <Chip href="#third" value="third">
336
+ Third
337
+ </Chip>
338
+ </ChipList>
339
+ </div>
340
+ );
341
+ };
342
+
343
+ render(<Demo />);
344
+ ```
345
+
346
+ #### Chips as navigation buttons
347
+
348
+ Use `pattern="navigation"` when chips without `href` should control page navigation through JavaScript.
349
+
350
+ ```tsx
351
+ import { useState } from 'react';
352
+ import { ChipList, Chip } from '@rescui/chip-list';
353
+
354
+ const Demo = () => {
355
+ const [activeChip, setActiveChip] = useState('second');
356
+ const navigateToSection = value => {
357
+ setActiveChip(value);
358
+ window.location.hash = `${value}-buttons`;
359
+ };
360
+
361
+ return (
362
+ <div>
363
+ <div>
364
+ <h4 id="first-buttons">First</h4>
365
+ <h4 id="second-buttons">Second</h4>
366
+ <h4 id="third-buttons">Third</h4>
367
+ </div>
368
+ <ChipList
369
+ value={activeChip}
370
+ onChange={navigateToSection}
371
+ pattern="navigation"
372
+ className="rs-docs-offset-top-24"
373
+ >
374
+ <Chip value="first">First</Chip>
375
+ <Chip value="second">Second</Chip>
376
+ <Chip value="third">Third</Chip>
377
+ </ChipList>
378
+ </div>
379
+ );
380
+ };
381
+
382
+ render(<Demo />);
383
+ ```
384
+
385
+ #### Compact mode
386
+
387
+ ```tsx
388
+ import { useState } from 'react';
389
+ import { ChipList, Chip } from '@rescui/chip-list';
390
+
391
+ const Demo = () => {
392
+ const [activeChip, setActiveChip] = useState('second');
393
+ return (
394
+ <div>
395
+ <ChipList
396
+ value={activeChip}
397
+ onChange={v => setActiveChip(v)}
398
+ compact
399
+ className="rs-docs-offset-top-12"
400
+ >
401
+ <Chip value="first">First</Chip>
402
+ <Chip value="second">Second</Chip>
403
+ <Chip value="third">Third</Chip>
404
+ </ChipList>
405
+ </div>
406
+ );
407
+ };
408
+
409
+ render(<Demo />);
410
+ ```
411
+
412
+ ## ChipListMulti
413
+
414
+ ### Features showcase
415
+
416
+ `ChipListMulti` component can only be a controlled component. It requires `value` and `onChange` props to function properly.
417
+
418
+ `ChipListMulti` interactive overview:
419
+
420
+ #### Usage with Icons
421
+
422
+ ```tsx
423
+ import { useState } from 'react';
424
+ import { ChipListMulti, Chip } from '@rescui/chip-list';
425
+ import {
426
+ TeamOutlineIcon,
427
+ WinOutlineIcon,
428
+ ThumbsUpOutlineIcon
429
+ } from '@rescui/icons';
430
+
431
+ const Demo = () => {
432
+ const [activeChips, setActiveChips] = useState(['second', 'third']);
433
+ return (
434
+ <div>
435
+ <ChipListMulti
436
+ value={activeChips}
437
+ onChange={setActiveChips}
438
+ className="rs-docs-offset-top-12"
439
+ >
440
+ <Chip icon={<TeamOutlineIcon />} value="first">
441
+ First
442
+ </Chip>
443
+ <Chip icon={<WinOutlineIcon />} value="second">
444
+ Second
445
+ </Chip>
446
+ <Chip icon={<ThumbsUpOutlineIcon />} value="third">
447
+ Third
448
+ </Chip>
449
+ </ChipListMulti>
450
+ </div>
451
+ );
452
+ };
453
+
454
+ render(<Demo />);
455
+ ```
456
+
457
+ ## CSS Mixins API
458
+
459
+ #### `Chip` mixins
460
+
461
+ | Mixin name | Details |
462
+ | --- | --- |
463
+ | `rs-chip-icon-left` | prop: `iconPosition`<br><br>value: `"left"` |
464
+ | `rs-chip-icon-right` | prop: `iconPosition`<br><br>value: `"right"` |
465
+
466
+ #### `ChipList` mixins
467
+
468
+ | Mixin name | Details |
469
+ | --- | --- |
470
+ | `rs-chip-list-align-left` | prop: `alignItems`<br><br>value: `"left"` |
471
+ | `rs-chip-list-align-center` | prop: `alignItems`<br><br>value: `"center"` |
472
+ | `rs-chip-list-align-right` | prop: `alignItems`<br><br>value: `"right"` |
473
+ | `rs-chip-list-sparse-true` | prop: `sparse`<br><br>value: `true` |
474
+ | `rs-chip-list-sparse-false` | prop: `sparse`<br><br>value: `false` |
475
+ | `rs-chip-list-size-xs` | prop: `size`<br><br>value: `"xs"` |
476
+ | `rs-chip-list-size-s` | prop: `size`<br><br>value: `"s"` |
477
+ | `rs-chip-list-size-m` | prop: `size`<br><br>value: `"m"` |
478
+ | `rs-chip-list-size-l` | prop: `size`<br><br>value: `"l"` |
479
+ | `rs-chip-list-mode-classic` | prop: `mode`<br><br>value: `"classic"` |
480
+ | `rs-chip-list-mode-rock` | prop: `mode`<br><br>value: `"rock"` |
481
+
482
+ #### `ChipListMulti` mixins
483
+
484
+ | Mixin name | Details |
485
+ | --- | --- |
486
+ | `rs-chip-list-multi-align-left` | prop: `alignItems`<br><br>value: `"left"` |
487
+ | `rs-chip-list-multi-align-center` | prop: `alignItems`<br><br>value: `"center"` |
488
+ | `rs-chip-list-multi-align-right` | prop: `alignItems`<br><br>value: `"right"` |
489
+ | `rs-chip-list-multi-sparse-true` | prop: `sparse`<br><br>value: `true` |
490
+ | `rs-chip-list-multi-sparse-false` | prop: `sparse`<br><br>value: `false` |
491
+ | `rs-chip-list-multi-size-xs` | prop: `size`<br><br>value: `"xs"` |
492
+ | `rs-chip-list-multi-size-s` | prop: `size`<br><br>value: `"s"` |
493
+ | `rs-chip-list-multi-size-m` | prop: `size`<br><br>value: `"m"` |
494
+ | `rs-chip-list-multi-size-l` | prop: `size`<br><br>value: `"l"` |
495
+ | `rs-chip-list-multi-mode-classic` | prop: `mode`<br><br>value: `"classic"` |
496
+ | `rs-chip-list-multi-mode-rock` | prop: `mode`<br><br>value: `"rock"` |
497
+
498
+ #### Demo
499
+
500
+ Instead of separate classes, it may be a single class with `@media` queries inside:
501
+
502
+ ```tsx
503
+ import { ChipList, ChipListMulti, Chip } from '@rescui/chip-list';
504
+ import { useState } from 'react';
505
+ import cn from 'classnames';
506
+ import { TeamOutlineIcon, WinOutlineIcon, ThumbsUpOutlineIcon } from '@rescui/icons';
507
+
508
+ const MyChipLists = ({ singleClassName, multiClassName }) => {
509
+ const [activeIndex, setActiveIndex] = useState(1);
510
+ const [activeChips, setActiveChips] = useState(['second', 'third']);
511
+ return (
512
+ <div style={{ padding: 12, backgroundColor: 'var(--rs-color-black-t5)' }}>
513
+ <ChipList
514
+ value={activeIndex}
515
+ onChange={v => setActiveIndex(v)}
516
+ className={singleClassName}
517
+ >
518
+ <Chip className="my-chip" icon={<TeamOutlineIcon />}>
519
+ First
520
+ </Chip>
521
+ <Chip className="my-chip" icon={<WinOutlineIcon />}>
522
+ Second
523
+ </Chip>
524
+ <Chip className="my-chip" icon={<ThumbsUpOutlineIcon />}>
525
+ Third
526
+ </Chip>
527
+ </ChipList>
528
+ <ChipListMulti
529
+ value={activeChips}
530
+ onChange={v => setActiveChips(v)}
531
+ className={cn(multiClassName, 'rs-docs-offset-top-12')}
532
+ >
533
+ <Chip className="my-chip" icon={<TeamOutlineIcon />} value="first">
534
+ First multi
535
+ </Chip>
536
+ <Chip className="my-chip" icon={<WinOutlineIcon />} value="second">
537
+ Second multi
538
+ </Chip>
539
+ <Chip className="my-chip" icon={<ThumbsUpOutlineIcon />} value="third">
540
+ Third multi
541
+ </Chip>
542
+ </ChipListMulti>
543
+ </div>
544
+ );
545
+ };
546
+
547
+ render(
548
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
549
+ <div>
550
+ <p>Default:</p>
551
+ <MyChipLists />
552
+ </div>
553
+ <div>
554
+ <p>Var1:</p>
555
+ <MyChipLists
556
+ singleClassName={`my-chip-list-var-1`}
557
+ multiClassName={`my-chip-list-multi-var-1`}
558
+ />
559
+ </div>
560
+ <div>
561
+ <p>Var1 & Var2 combined:</p>
562
+ <MyChipLists
563
+ singleClassName={`my-chip-list-var-1 my-chip-list-var-2`}
564
+ multiClassName={`my-chip-list-multi-var-1 my-chip-list-multi-var-2`}
565
+ />
566
+ </div>
567
+ </div>
568
+ );
569
+ ```
570
+
571
+ ```postcss
572
+ @import '@rescui/chip-list/lib/public-api.p.css';
573
+
574
+ .my-chip-list-var-1 {
575
+ @mixin rs-chip-list-size-l;
576
+ @mixin rs-chip-list-mode-rock;
577
+ @mixin rs-chip-list-align-center;
578
+ @mixin rs-chip-list-sparse-true;
579
+
580
+ .my-chip {
581
+ @mixin rs-chip-icon-right;
582
+ }
583
+ }
584
+ .my-chip-list-var-2 {
585
+ @mixin rs-chip-list-size-s;
586
+ @mixin rs-chip-list-mode-classic;
587
+ @mixin rs-chip-list-align-right;
588
+ @mixin rs-chip-list-sparse-false;
589
+
590
+ .my-chip {
591
+ @mixin rs-chip-icon-left;
592
+ }
593
+ }
594
+
595
+ .my-chip-list-multi-var-1 {
596
+ @mixin rs-chip-list-multi-size-l;
597
+ @mixin rs-chip-list-multi-mode-rock;
598
+ @mixin rs-chip-list-multi-align-center;
599
+ @mixin rs-chip-list-multi-sparse-true;
600
+
601
+ .my-chip {
602
+ @mixin rs-chip-icon-right;
603
+ }
604
+ }
605
+ .my-chip-list-multi-var-2 {
606
+ @mixin rs-chip-list-multi-size-s;
607
+ @mixin rs-chip-list-multi-mode-classic;
608
+ @mixin rs-chip-list-multi-align-right;
609
+ @mixin rs-chip-list-multi-sparse-false;
610
+
611
+ .my-chip {
612
+ @mixin rs-chip-icon-left;
613
+ }
614
+ }
615
+ ```
package/llm/index.md ADDED
@@ -0,0 +1,2 @@
1
+ - Components and Hooks
2
+ - [ChipList](./components/chip-list.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rescui/chip-list",
3
- "version": "0.14.0",
3
+ "version": "0.14.1-RUI-296-Build-docs-md-files-for-each-docs-section-b138dd5bf.19+b138dd5bf",
4
4
  "description": "",
5
5
  "license": "Apache-2.0",
6
6
  "author": "JetBrains",
@@ -9,6 +9,7 @@
9
9
  "src:main": "src/index.ts",
10
10
  "files": [
11
11
  "lib",
12
+ "llm",
12
13
  "LICENSE.txt"
13
14
  ],
14
15
  "publishConfig": {
@@ -24,15 +25,15 @@
24
25
  "react": ">=16.8.0 <20"
25
26
  },
26
27
  "devDependencies": {
27
- "@rescui/colors": "^0.3.0",
28
- "@rescui/scripts": "^0.5.1",
29
- "@rescui/typography": "^0.27.0",
30
- "@rescui/visual-regression": "^0.1.4"
28
+ "@rescui/colors": "0.3.1-RUI-296-Build-docs-md-files-for-each-docs-section-b138dd5bf.54+b138dd5bf",
29
+ "@rescui/scripts": "0.5.2",
30
+ "@rescui/typography": "0.27.1-RUI-296-Build-docs-md-files-for-each-docs-section-b138dd5bf.19+b138dd5bf",
31
+ "@rescui/visual-regression": "0.1.4"
31
32
  },
32
33
  "scripts": {
33
34
  "build": "rescui-scripts build && yarn run build-pcss-api",
34
35
  "build-pcss-api": "rescui-scripts build-pcss-api --file public-api.p.css"
35
36
  },
36
37
  "nx": {},
37
- "gitHead": "e9aedd97a4cc372540ec8d75dda4f122baacca10"
38
+ "gitHead": "b138dd5bf3dbdca6c21fa339dd567517d5c5d1d9"
38
39
  }