@fastkit/vui 0.16.80 → 0.16.81
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/vui.d.ts +458 -679
- package/dist/vui.mjs +680 -652
- package/dist/vui.mjs.map +1 -1
- package/package.json +23 -23
- package/src/components/VCheckbox/VCheckbox.tsx +36 -29
- package/src/components/VForm/VForm.tsx +12 -24
- package/src/components/VFormControl/VFormControl.tsx +7 -4
- package/src/components/VFormGroup/VFormGroup.tsx +45 -0
- package/src/components/VFormGroup/index.ts +1 -0
- package/src/components/VOption/VOption.tsx +12 -18
- package/src/components/VOptionGroup/VOptionGroup.tsx +13 -14
- package/src/components/VRadio/VRadio.tsx +25 -28
- package/src/components/VSelect/VSelect.tsx +185 -174
- package/src/components/VSwitch/VSwitch.tsx +36 -33
- package/src/components/VTextField/VTextField.tsx +54 -44
- package/src/components/VTextarea/VTextarea.tsx +53 -47
- package/src/components/index.ts +1 -0
- package/src/composables/form-selector.tsx +80 -77
- package/src/injections.ts +1 -0
- package/src/plugin.tsx +18 -1
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
import { VUI_SELECT_SYMBOL, useVui } from '../../injections';
|
|
38
38
|
import { VIcon } from '../VIcon';
|
|
39
39
|
import { VMenu } from '../VMenu';
|
|
40
|
+
import { VStackActivatorPayload } from '@fastkit/vue-stack';
|
|
40
41
|
import { VOptionGroup } from '../VOptionGroup';
|
|
41
42
|
import { VOption } from '../VOption';
|
|
42
43
|
import { VButton } from '../VButton';
|
|
@@ -46,12 +47,14 @@ export const ARROW_KEY_TYPES = useKeyboard.Key(['ArrowUp', 'ArrowDown']);
|
|
|
46
47
|
|
|
47
48
|
export const CHOICE_KEY_TYPES = useKeyboard.Key(['Enter', ' ']);
|
|
48
49
|
|
|
49
|
-
export const
|
|
50
|
+
export const KEYBOARD_EVENT_TYPES = useKeyboard.Key([
|
|
50
51
|
...ARROW_KEY_TYPES,
|
|
51
52
|
...CHOICE_KEY_TYPES,
|
|
52
53
|
]);
|
|
53
54
|
|
|
54
|
-
const { props, emits } = createFormSelectorSettings(
|
|
55
|
+
const { props, emits } = createFormSelectorSettings({
|
|
56
|
+
defaultValidateTiming: 'blur',
|
|
57
|
+
});
|
|
55
58
|
|
|
56
59
|
const slots = defineSlots<
|
|
57
60
|
FormControlSlots &
|
|
@@ -265,189 +268,197 @@ export const VSelect = defineComponent({
|
|
|
265
268
|
useKeyboard(
|
|
266
269
|
[
|
|
267
270
|
{
|
|
268
|
-
key:
|
|
271
|
+
key: KEYBOARD_EVENT_TYPES,
|
|
269
272
|
handler: keyboardEventHandler,
|
|
270
273
|
},
|
|
271
274
|
],
|
|
272
275
|
{ autorun: true },
|
|
273
276
|
);
|
|
274
277
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
...control,
|
|
278
|
-
iconName,
|
|
279
|
-
menuOpened,
|
|
280
|
-
fieldRef: () => fieldRef,
|
|
278
|
+
ctx.expose({
|
|
279
|
+
control: inputControl,
|
|
281
280
|
focus,
|
|
282
281
|
showMenu,
|
|
283
282
|
closeMenu,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const handleClickLabel = (ev: MouseEvent) => {
|
|
286
|
+
focus();
|
|
287
287
|
};
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
288
|
+
|
|
289
|
+
return () => {
|
|
290
|
+
const children = ctx.slots.default?.() || [];
|
|
291
|
+
const propGroups = inputControl.propGroups.map((group) => {
|
|
292
|
+
return (
|
|
293
|
+
<VOptionGroup
|
|
294
|
+
key={group.id}
|
|
295
|
+
groupId={group.id}
|
|
296
|
+
label={group.label(inputControl)}
|
|
297
|
+
disabled={group.disabled}>
|
|
298
|
+
{group.items.map((item) => (
|
|
299
|
+
<VOption
|
|
300
|
+
disabled={item.disabled}
|
|
301
|
+
value={item.value}
|
|
302
|
+
key={item.value}>
|
|
303
|
+
{item.label(inputControl)}
|
|
304
|
+
</VOption>
|
|
305
|
+
))}
|
|
306
|
+
</VOptionGroup>
|
|
307
|
+
);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
const classes = computed(() => [
|
|
311
|
+
'v-select',
|
|
312
|
+
control.classes.value,
|
|
313
|
+
{
|
|
314
|
+
'v-select--multiple': inputControl.multiple,
|
|
315
|
+
},
|
|
316
|
+
]);
|
|
317
|
+
|
|
318
|
+
const controlDefaultSlot = () => {
|
|
319
|
+
return [
|
|
320
|
+
<select
|
|
321
|
+
class="v-select__input__element"
|
|
322
|
+
name={inputControl.name}
|
|
323
|
+
tabindex={inputControl.tabindex}
|
|
324
|
+
disabled={inputControl.isDisabled}
|
|
325
|
+
multiple={inputControl.multiple}
|
|
326
|
+
onFocus={inputControl.focusHandler}
|
|
327
|
+
onBlur={inputControl.blurHandler}
|
|
328
|
+
v-model={inputControl.value}>
|
|
329
|
+
{inputControl.items.map((item) => {
|
|
330
|
+
return (
|
|
331
|
+
<option value={item.propValue} key={item.propValue}>
|
|
332
|
+
{item.renderDefaultSlot()}
|
|
333
|
+
</option>
|
|
334
|
+
);
|
|
335
|
+
})}
|
|
336
|
+
</select>,
|
|
337
|
+
<div class="v-select__selections">
|
|
338
|
+
<div class="v-select__selections__inner">
|
|
339
|
+
{renderSelections(inputControl.selectedItems)}
|
|
340
|
+
</div>
|
|
341
|
+
</div>,
|
|
342
|
+
];
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const endAdornmentSlot = () => {
|
|
346
|
+
if (inputControl.itemsLoadFailed) {
|
|
347
|
+
return (
|
|
348
|
+
<VButton
|
|
349
|
+
key="reload"
|
|
350
|
+
icon={vui.icon('reload')}
|
|
351
|
+
rounded
|
|
352
|
+
onClick={(ev) => {
|
|
353
|
+
ev.stopPropagation();
|
|
354
|
+
inputControl.loadItems();
|
|
306
355
|
}}
|
|
307
|
-
|
|
308
|
-
)
|
|
309
|
-
|
|
310
|
-
);
|
|
311
|
-
});
|
|
356
|
+
/>
|
|
357
|
+
);
|
|
358
|
+
}
|
|
312
359
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
if (this.clearable && this.nodeControl.value != null) {
|
|
418
|
-
return (
|
|
419
|
-
<VButton
|
|
420
|
-
key="clear"
|
|
421
|
-
icon={this.$vui.icon('clear')}
|
|
422
|
-
rounded
|
|
423
|
-
onClick={(ev) => {
|
|
424
|
-
ev.stopPropagation();
|
|
425
|
-
this.nodeControl.clear();
|
|
426
|
-
}}
|
|
427
|
-
/>
|
|
428
|
-
);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
return (
|
|
432
|
-
<VIcon
|
|
433
|
-
key="icon"
|
|
434
|
-
name={this.iconName}
|
|
435
|
-
rotate={this.menuOpened ? 180 : 0}
|
|
436
|
-
/>
|
|
437
|
-
);
|
|
438
|
-
},
|
|
439
|
-
}}
|
|
440
|
-
/>,
|
|
441
|
-
],
|
|
442
|
-
}}>
|
|
443
|
-
<div class={['v-select__body', this.classes]}>
|
|
444
|
-
{children}
|
|
445
|
-
{propGroups}
|
|
446
|
-
</div>
|
|
447
|
-
</VMenu>
|
|
448
|
-
),
|
|
449
|
-
}}
|
|
450
|
-
/>
|
|
451
|
-
);
|
|
360
|
+
if (props.clearable && inputControl.value != null) {
|
|
361
|
+
return (
|
|
362
|
+
<VButton
|
|
363
|
+
key="clear"
|
|
364
|
+
icon={vui.icon('clear')}
|
|
365
|
+
rounded
|
|
366
|
+
onClick={(ev) => {
|
|
367
|
+
ev.stopPropagation();
|
|
368
|
+
inputControl.clear();
|
|
369
|
+
}}
|
|
370
|
+
/>
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return (
|
|
375
|
+
<VIcon
|
|
376
|
+
key="icon"
|
|
377
|
+
name={iconName}
|
|
378
|
+
rotate={menuOpened.value ? 180 : 0}
|
|
379
|
+
/>
|
|
380
|
+
);
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const menuActivatorSlot = ({ control: menu }: VStackActivatorPayload) => {
|
|
384
|
+
return (
|
|
385
|
+
<VControlField
|
|
386
|
+
class="v-select__input"
|
|
387
|
+
ref={fieldRef}
|
|
388
|
+
loading={inputControl.itemsLoading}
|
|
389
|
+
error={inputControl.itemsLoadFailed}
|
|
390
|
+
startAdornment={props.startAdornment}
|
|
391
|
+
endAdornment={props.endAdornment}
|
|
392
|
+
size={control.size.value}
|
|
393
|
+
focused={menuOpened.value}
|
|
394
|
+
autoHeight={inputControl.multiple}
|
|
395
|
+
onClick={(ev) => {
|
|
396
|
+
if (inputControl.canOperation && !menu.isActive) {
|
|
397
|
+
let t = ev.target as HTMLElement;
|
|
398
|
+
const count = 0;
|
|
399
|
+
let hit = false;
|
|
400
|
+
while (count < 5) {
|
|
401
|
+
if (t.classList.contains('v-select__input')) {
|
|
402
|
+
hit = true;
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
405
|
+
t = t.parentElement as HTMLElement;
|
|
406
|
+
}
|
|
407
|
+
menu.setActivator(hit ? t : ev).show();
|
|
408
|
+
}
|
|
409
|
+
}}
|
|
410
|
+
v-slots={{
|
|
411
|
+
...ctx.slots,
|
|
412
|
+
default: controlDefaultSlot,
|
|
413
|
+
endAdornment: endAdornmentSlot,
|
|
414
|
+
}}
|
|
415
|
+
/>
|
|
416
|
+
);
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
const menuSlots = {
|
|
420
|
+
activator: menuActivatorSlot,
|
|
421
|
+
default: () => (
|
|
422
|
+
<div class={['v-select__body', control.classes.value]}>
|
|
423
|
+
{children}
|
|
424
|
+
{propGroups}
|
|
425
|
+
</div>
|
|
426
|
+
),
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
const defaultSlot = () => {
|
|
430
|
+
return (
|
|
431
|
+
<VMenu
|
|
432
|
+
width="fit"
|
|
433
|
+
maxWidth="fit"
|
|
434
|
+
closeOnNavigation={props.closeOnNavigation}
|
|
435
|
+
distance={0}
|
|
436
|
+
alwaysRender
|
|
437
|
+
v-model={menuOpened.value}
|
|
438
|
+
ref={menuRef}
|
|
439
|
+
onClose={clearKeyFocused}
|
|
440
|
+
v-slots={menuSlots}
|
|
441
|
+
/>
|
|
442
|
+
);
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
return (
|
|
446
|
+
<VFormControl
|
|
447
|
+
nodeControl={inputControl}
|
|
448
|
+
// focused={this.nodeControl.focused}
|
|
449
|
+
class={classes.value}
|
|
450
|
+
label={props.label}
|
|
451
|
+
hint={props.hint}
|
|
452
|
+
hinttip={props.hinttip}
|
|
453
|
+
hiddenInfo={props.hiddenInfo}
|
|
454
|
+
requiredChip={props.requiredChip}
|
|
455
|
+
onClickLabel={handleClickLabel}
|
|
456
|
+
v-slots={{
|
|
457
|
+
...ctx.slots,
|
|
458
|
+
default: defaultSlot,
|
|
459
|
+
}}
|
|
460
|
+
/>
|
|
461
|
+
);
|
|
462
|
+
};
|
|
452
463
|
},
|
|
453
464
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import './VSwitch.scss';
|
|
2
|
-
import { defineComponent } from 'vue';
|
|
2
|
+
import { defineComponent, computed } from 'vue';
|
|
3
3
|
import {
|
|
4
4
|
createFormSelectorItemSettings,
|
|
5
5
|
useFormSelectorItemControl,
|
|
@@ -27,38 +27,41 @@ export const VSwitch = defineComponent({
|
|
|
27
27
|
(window as any).yy = {};
|
|
28
28
|
(window as any).yy[String(Date.now())] = nodeControl;
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
|
|
31
|
+
const classes = computed(() => [
|
|
32
|
+
'v-switch',
|
|
33
|
+
{
|
|
34
|
+
'v-switch--selected': nodeControl.selected,
|
|
35
|
+
'v-switch--disabled': nodeControl.isDisabled,
|
|
36
|
+
},
|
|
37
|
+
control.classes.value,
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
const slots = {
|
|
41
|
+
input: () => nodeControl.createInputElement({ type: 'checkbox' }),
|
|
42
|
+
icon: () => (
|
|
43
|
+
<span class="v-switch__faux">
|
|
44
|
+
<span class="v-switch__faux__pin"></span>
|
|
45
|
+
</span>
|
|
46
|
+
),
|
|
47
|
+
label: () => ctx.slots.default?.(),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
ctx.expose({
|
|
51
|
+
control: nodeControl,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return () => {
|
|
55
|
+
return (
|
|
56
|
+
<VCheckable
|
|
57
|
+
class={classes.value}
|
|
58
|
+
checked={nodeControl.selected}
|
|
59
|
+
invalid={nodeControl.invalid}
|
|
60
|
+
disabled={nodeControl.isDisabled}
|
|
61
|
+
readonly={nodeControl.isReadonly}
|
|
62
|
+
v-slots={slots}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
33
65
|
};
|
|
34
|
-
},
|
|
35
|
-
render() {
|
|
36
|
-
const { selectorItemControl } = this;
|
|
37
|
-
return (
|
|
38
|
-
<VCheckable
|
|
39
|
-
class={[
|
|
40
|
-
'v-switch',
|
|
41
|
-
{
|
|
42
|
-
'v-switch--selected': selectorItemControl.selected,
|
|
43
|
-
'v-switch--disabled': selectorItemControl.isDisabled,
|
|
44
|
-
},
|
|
45
|
-
this.classes,
|
|
46
|
-
]}
|
|
47
|
-
checked={this.selected}
|
|
48
|
-
invalid={this.invalid}
|
|
49
|
-
disabled={this.isDisabled}
|
|
50
|
-
readonly={this.isReadonly}
|
|
51
|
-
v-slots={{
|
|
52
|
-
input: () =>
|
|
53
|
-
selectorItemControl.createInputElement({ type: 'checkbox' }),
|
|
54
|
-
icon: () => (
|
|
55
|
-
<span class="v-switch__faux">
|
|
56
|
-
<span class="v-switch__faux__pin"></span>
|
|
57
|
-
</span>
|
|
58
|
-
),
|
|
59
|
-
label: () => this.$slots.default?.(),
|
|
60
|
-
}}
|
|
61
|
-
/>
|
|
62
|
-
);
|
|
63
66
|
},
|
|
64
67
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import './VTextField.scss';
|
|
2
|
-
import { defineComponent } from 'vue';
|
|
2
|
+
import { defineComponent, computed } from 'vue';
|
|
3
3
|
import {
|
|
4
4
|
createTextInputSettings,
|
|
5
5
|
useTextInputControl,
|
|
@@ -58,49 +58,59 @@ export const VTextField = defineComponent({
|
|
|
58
58
|
const control = useControl(props);
|
|
59
59
|
useControlField(props);
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
const classes = computed(() => ['v-text-field', control.classes.value]);
|
|
62
|
+
|
|
63
|
+
const handleClickLabel = (ev: MouseEvent) => {
|
|
64
|
+
inputControl.focus();
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const defaultSlot = () => {
|
|
68
|
+
return (
|
|
69
|
+
<VControlField
|
|
70
|
+
class="v-text-field__input"
|
|
71
|
+
startAdornment={props.startAdornment}
|
|
72
|
+
endAdornment={props.endAdornment}
|
|
73
|
+
size={control.size.value}
|
|
74
|
+
v-slots={{
|
|
75
|
+
...ctx.slots,
|
|
76
|
+
default: () =>
|
|
77
|
+
inputControl.createInputElement({
|
|
78
|
+
class: 'v-text-field__input__element',
|
|
79
|
+
}),
|
|
80
|
+
}}
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const infoAppendsSlot = () => {
|
|
86
|
+
const { counterResult } = inputControl;
|
|
87
|
+
if (!counterResult) return;
|
|
88
|
+
return <VTextCounter {...counterResult} />;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
ctx.expose({
|
|
92
|
+
control: inputControl,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return () => {
|
|
96
|
+
return (
|
|
97
|
+
<VFormControl
|
|
98
|
+
nodeControl={inputControl}
|
|
99
|
+
focused={inputControl.focused}
|
|
100
|
+
hiddenInfo={props.hiddenInfo}
|
|
101
|
+
class={classes.value}
|
|
102
|
+
label={props.label}
|
|
103
|
+
hint={props.hint}
|
|
104
|
+
hinttip={props.hinttip}
|
|
105
|
+
requiredChip={props.requiredChip}
|
|
106
|
+
onClickLabel={handleClickLabel}
|
|
107
|
+
v-slots={{
|
|
108
|
+
...ctx.slots,
|
|
109
|
+
default: defaultSlot,
|
|
110
|
+
infoAppends: infoAppendsSlot,
|
|
111
|
+
}}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
64
114
|
};
|
|
65
|
-
},
|
|
66
|
-
render() {
|
|
67
|
-
return (
|
|
68
|
-
<VFormControl
|
|
69
|
-
nodeControl={this.nodeControl}
|
|
70
|
-
focused={this.nodeControl.focused}
|
|
71
|
-
hiddenInfo={this.hiddenInfo}
|
|
72
|
-
class={['v-text-field', this.classes]}
|
|
73
|
-
label={this.label}
|
|
74
|
-
hint={this.hint}
|
|
75
|
-
hinttip={this.hinttip}
|
|
76
|
-
requiredChip={this.requiredChip}
|
|
77
|
-
onClickLabel={(ev) => {
|
|
78
|
-
this.focus();
|
|
79
|
-
}}
|
|
80
|
-
v-slots={{
|
|
81
|
-
...this.$slots,
|
|
82
|
-
default: () => (
|
|
83
|
-
<VControlField
|
|
84
|
-
class="v-text-field__input"
|
|
85
|
-
startAdornment={this.startAdornment}
|
|
86
|
-
endAdornment={this.endAdornment}
|
|
87
|
-
size={this.size}
|
|
88
|
-
v-slots={{
|
|
89
|
-
...this.$slots,
|
|
90
|
-
default: () =>
|
|
91
|
-
this.textInputControl.createInputElement({
|
|
92
|
-
class: 'v-text-field__input__element',
|
|
93
|
-
}),
|
|
94
|
-
}}
|
|
95
|
-
/>
|
|
96
|
-
),
|
|
97
|
-
infoAppends: () => {
|
|
98
|
-
const { counterResult } = this;
|
|
99
|
-
if (!counterResult) return;
|
|
100
|
-
return <VTextCounter {...counterResult} />;
|
|
101
|
-
},
|
|
102
|
-
}}
|
|
103
|
-
/>
|
|
104
|
-
);
|
|
105
115
|
},
|
|
106
116
|
});
|