Completed
Push — master ( 2c7bf5...e478d4 )
by Song
02:58 queued 11s
created

Field::removeElementClass()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 6
nop 1
dl 0
loc 16
rs 9.4222
c 0
b 0
f 0
1
<?php
2
3
namespace Encore\Admin\Form;
4
5
use Encore\Admin\Admin;
6
use Encore\Admin\Form;
7
use Illuminate\Contracts\Support\Arrayable;
8
use Illuminate\Contracts\Support\Renderable;
9
use Illuminate\Support\Arr;
10
use Illuminate\Support\Facades\Validator;
11
use Illuminate\Support\Traits\Macroable;
12
13
/**
14
 * Class Field.
15
 */
16
class Field implements Renderable
17
{
18
    use Macroable;
19
20
    const FILE_DELETE_FLAG = '_file_del_';
21
22
    /**
23
     * Element id.
24
     *
25
     * @var array|string
26
     */
27
    protected $id;
28
29
    /**
30
     * Element value.
31
     *
32
     * @var mixed
33
     */
34
    protected $value;
35
36
    /**
37
     * Data of all original columns of value.
38
     *
39
     * @var mixed
40
     */
41
    protected $data;
42
43
    /**
44
     * Field original value.
45
     *
46
     * @var mixed
47
     */
48
    protected $original;
49
50
    /**
51
     * Field default value.
52
     *
53
     * @var mixed
54
     */
55
    protected $default;
56
57
    /**
58
     * Element label.
59
     *
60
     * @var string
61
     */
62
    protected $label = '';
63
64
    /**
65
     * Column name.
66
     *
67
     * @var string|array
68
     */
69
    protected $column = '';
70
71
    /**
72
     * Form element name.
73
     *
74
     * @var string
75
     */
76
    protected $elementName = [];
77
78
    /**
79
     * Form element classes.
80
     *
81
     * @var array
82
     */
83
    protected $elementClass = [];
84
85
    /**
86
     * Variables of elements.
87
     *
88
     * @var array
89
     */
90
    protected $variables = [];
91
92
    /**
93
     * Options for specify elements.
94
     *
95
     * @var array
96
     */
97
    protected $options = [];
98
99
    /**
100
     * Checked for specify elements.
101
     *
102
     * @var array
103
     */
104
    protected $checked = [];
105
106
    /**
107
     * Validation rules.
108
     *
109
     * @var string|\Closure
110
     */
111
    protected $rules = '';
112
113
    /**
114
     * @var callable
115
     */
116
    protected $validator;
117
118
    /**
119
     * Validation messages.
120
     *
121
     * @var array
122
     */
123
    protected $validationMessages = [];
124
125
    /**
126
     * Css required by this field.
127
     *
128
     * @var array
129
     */
130
    protected static $css = [];
131
132
    /**
133
     * Js required by this field.
134
     *
135
     * @var array
136
     */
137
    protected static $js = [];
138
139
    /**
140
     * Script for field.
141
     *
142
     * @var string
143
     */
144
    protected $script = '';
145
146
    /**
147
     * Element attributes.
148
     *
149
     * @var array
150
     */
151
    protected $attributes = [];
152
153
    /**
154
     * Parent form.
155
     *
156
     * @var Form
157
     */
158
    protected $form = null;
159
160
    /**
161
     * View for field to render.
162
     *
163
     * @var string
164
     */
165
    protected $view = '';
166
167
    /**
168
     * Help block.
169
     *
170
     * @var array
171
     */
172
    protected $help = [];
173
174
    /**
175
     * Key for errors.
176
     *
177
     * @var mixed
178
     */
179
    protected $errorKey;
180
181
    /**
182
     * Placeholder for this field.
183
     *
184
     * @var string|array
185
     */
186
    protected $placeholder;
187
188
    /**
189
     * Width for label and field.
190
     *
191
     * @var array
192
     */
193
    protected $width = [
194
        'label' => 2,
195
        'field' => 8,
196
    ];
197
198
    /**
199
     * If the form horizontal layout.
200
     *
201
     * @var bool
202
     */
203
    protected $horizontal = true;
204
205
    /**
206
     * column data format.
207
     *
208
     * @var \Closure
209
     */
210
    protected $customFormat = null;
211
212
    /**
213
     * @var bool
214
     */
215
    protected $display = true;
216
217
    /**
218
     * @var array
219
     */
220
    protected $labelClass = [];
221
222
    /**
223
     * Field constructor.
224
     *
225
     * @param       $column
226
     * @param array $arguments
227
     */
228
    public function __construct($column, $arguments = [])
229
    {
230
        $this->column = $column;
231
        $this->label = $this->formatLabel($arguments);
232
        $this->id = $this->formatId($column);
233
    }
234
235
    /**
236
     * Get assets required by this field.
237
     *
238
     * @return array
239
     */
240
    public static function getAssets()
241
    {
242
        return [
243
            'css' => static::$css,
244
            'js'  => static::$js,
245
        ];
246
    }
247
248
    /**
249
     * Format the field element id.
250
     *
251
     * @param string|array $column
252
     *
253
     * @return string|array
254
     */
255
    protected function formatId($column)
256
    {
257
        return str_replace('.', '_', $column);
258
    }
259
260
    /**
261
     * Format the label value.
262
     *
263
     * @param array $arguments
264
     *
265
     * @return string
266
     */
267
    protected function formatLabel($arguments = [])
268
    {
269
        $column = is_array($this->column) ? current($this->column) : $this->column;
270
271
        $label = isset($arguments[0]) ? $arguments[0] : ucfirst($column);
272
273
        return str_replace(['.', '_'], ' ', $label);
274
    }
275
276
    /**
277
     * Format the name of the field.
278
     *
279
     * @param string $column
280
     *
281
     * @return array|mixed|string
282
     */
283
    protected function formatName($column)
284
    {
285
        if (is_string($column)) {
286
            $name = explode('.', $column);
287
288
            if (count($name) == 1) {
289
                return $name[0];
290
            }
291
292
            $html = array_shift($name);
293
            foreach ($name as $piece) {
294
                $html .= "[$piece]";
295
            }
296
297
            return $html;
298
        }
299
300
        if (is_array($this->column)) {
301
            $names = [];
302
            foreach ($this->column as $key => $name) {
303
                $names[$key] = $this->formatName($name);
304
            }
305
306
            return $names;
307
        }
308
309
        return '';
310
    }
311
312
    /**
313
     * Set form element name.
314
     *
315
     * @param string $name
316
     *
317
     * @return $this
318
     *
319
     * @author Edwin Hui
320
     */
321
    public function setElementName($name)
322
    {
323
        $this->elementName = $name;
324
325
        return $this;
326
    }
327
328
    /**
329
     * Fill data to the field.
330
     *
331
     * @param array $data
332
     *
333
     * @return void
334
     */
335
    public function fill($data)
336
    {
337
        // Field value is already setted.
338
//        if (!is_null($this->value)) {
339
//            return;
340
//        }
341
342
        $this->data = $data;
343
344
        if (is_array($this->column)) {
345
            foreach ($this->column as $key => $column) {
346
                $this->value[$key] = array_get($data, $column);
347
            }
348
349
            return;
350
        }
351
352
        $this->value = array_get($data, $this->column);
353
        if (isset($this->customFormat) && $this->customFormat instanceof \Closure) {
354
            $this->value = call_user_func($this->customFormat, $this->value);
355
        }
356
    }
357
358
    /**
359
     * custom format form column data when edit.
360
     *
361
     * @param \Closure $call
362
     *
363
     * @return $this
364
     */
365
    public function customFormat(\Closure $call)
366
    {
367
        $this->customFormat = $call;
368
369
        return $this;
370
    }
371
372
    /**
373
     * Set original value to the field.
374
     *
375
     * @param array $data
376
     *
377
     * @return void
378
     */
379
    public function setOriginal($data)
380
    {
381
        if (is_array($this->column)) {
382
            foreach ($this->column as $key => $column) {
383
                $this->original[$key] = array_get($data, $column);
384
            }
385
386
            return;
387
        }
388
389
        $this->original = array_get($data, $this->column);
390
    }
391
392
    /**
393
     * @param Form $form
394
     *
395
     * @return $this
396
     */
397
    public function setForm(Form $form = null)
398
    {
399
        $this->form = $form;
400
401
        return $this;
402
    }
403
404
    /**
405
     * Set width for field and label.
406
     *
407
     * @param int $field
408
     * @param int $label
409
     *
410
     * @return $this
411
     */
412
    public function setWidth($field = 8, $label = 2)
413
    {
414
        $this->width = [
415
            'label' => $label,
416
            'field' => $field,
417
        ];
418
419
        return $this;
420
    }
421
422
    /**
423
     * Set the field options.
424
     *
425
     * @param array $options
426
     *
427
     * @return $this
428
     */
429
    public function options($options = [])
430
    {
431
        if ($options instanceof Arrayable) {
432
            $options = $options->toArray();
433
        }
434
435
        $this->options = array_merge($this->options, $options);
436
437
        return $this;
438
    }
439
440
    /**
441
     * Set the field option checked.
442
     *
443
     * @param array $checked
444
     *
445
     * @return $this
446
     */
447
    public function checked($checked = [])
448
    {
449
        if ($checked instanceof Arrayable) {
450
            $checked = $checked->toArray();
451
        }
452
453
        $this->checked = array_merge($this->checked, $checked);
454
455
        return $this;
456
    }
457
458
    /**
459
     * Get or set rules.
460
     *
461
     * @param null  $rules
462
     * @param array $messages
463
     *
464
     * @return $this
465
     */
466
    public function rules($rules = null, $messages = [])
467
    {
468
        if ($rules instanceof \Closure) {
469
            $this->rules = $rules;
470
        }
471
472
        if (is_array($rules)) {
473
            $thisRuleArr = array_filter(explode('|', $this->rules));
474
475
            $this->rules = array_merge($thisRuleArr, $rules);
476
        } elseif (is_string($rules)) {
477
            $rules = array_filter(explode('|', "{$this->rules}|$rules"));
478
479
            $this->rules = implode('|', $rules);
480
        }
481
482
        $this->validationMessages = $messages;
483
484
        return $this;
485
    }
486
487
    /**
488
     * Get field validation rules.
489
     *
490
     * @return string
491
     */
492
    protected function getRules()
493
    {
494
        if ($this->rules instanceof \Closure) {
495
            return $this->rules->call($this, $this->form);
496
        }
497
498
        return $this->rules;
499
    }
500
501
    /**
502
     * Remove a specific rule by keyword.
503
     *
504
     * @param string $rule
505
     *
506
     * @return void
507
     */
508
    protected function removeRule($rule)
509
    {
510
        if (!is_string($this->rules)) {
511
            return;
512
        }
513
514
        $pattern = "/{$rule}[^\|]?(\||$)/";
515
        $this->rules = preg_replace($pattern, '', $this->rules, -1);
516
    }
517
518
    /**
519
     * Set field validator.
520
     *
521
     * @param callable $validator
522
     *
523
     * @return $this
524
     */
525
    public function validator(callable $validator)
526
    {
527
        $this->validator = $validator;
528
529
        return $this;
530
    }
531
532
    /**
533
     * Get key for error message.
534
     *
535
     * @return string
536
     */
537
    public function getErrorKey()
538
    {
539
        return $this->errorKey ?: $this->column;
540
    }
541
542
    /**
543
     * Set key for error message.
544
     *
545
     * @param string $key
546
     *
547
     * @return $this
548
     */
549
    public function setErrorKey($key)
550
    {
551
        $this->errorKey = $key;
552
553
        return $this;
554
    }
555
556
    /**
557
     * Set or get value of the field.
558
     *
559
     * @param null $value
560
     *
561
     * @return mixed
562
     */
563
    public function value($value = null)
564
    {
565
        if (is_null($value)) {
566
            return is_null($this->value) ? $this->getDefault() : $this->value;
567
        }
568
569
        $this->value = $value;
570
571
        return $this;
572
    }
573
574
    /**
575
     * Set or get data.
576
     *
577
     * @param array $data
578
     *
579
     * @return $this
580
     */
581
    public function data(array $data = null)
582
    {
583
        if (is_null($data)) {
584
            return $this->data;
585
        }
586
587
        $this->data = $data;
588
589
        return $this;
590
    }
591
592
    /**
593
     * Set default value for field.
594
     *
595
     * @param $default
596
     *
597
     * @return $this
598
     */
599
    public function default($default)
600
    {
601
        $this->default = $default;
602
603
        return $this;
604
    }
605
606
    /**
607
     * Get default value.
608
     *
609
     * @return mixed
610
     */
611
    public function getDefault()
612
    {
613
        if ($this->default instanceof \Closure) {
614
            return call_user_func($this->default, $this->form);
615
        }
616
617
        return $this->default;
618
    }
619
620
    /**
621
     * Set help block for current field.
622
     *
623
     * @param string $text
624
     * @param string $icon
625
     *
626
     * @return $this
627
     */
628
    public function help($text = '', $icon = 'fa-info-circle')
629
    {
630
        $this->help = compact('text', 'icon');
631
632
        return $this;
633
    }
634
635
    /**
636
     * Get column of the field.
637
     *
638
     * @return string|array
639
     */
640
    public function column()
641
    {
642
        return $this->column;
643
    }
644
645
    /**
646
     * Get label of the field.
647
     *
648
     * @return string
649
     */
650
    public function label()
651
    {
652
        return $this->label;
653
    }
654
655
    /**
656
     * Get original value of the field.
657
     *
658
     * @return mixed
659
     */
660
    public function original()
661
    {
662
        return $this->original;
663
    }
664
665
    /**
666
     * Get validator for this field.
667
     *
668
     * @param array $input
669
     *
670
     * @return bool|Validator
671
     */
672
    public function getValidator(array $input)
673
    {
674
        if ($this->validator) {
675
            return $this->validator->call($this, $input);
676
        }
677
678
        $rules = $attributes = [];
679
680
        if (!$fieldRules = $this->getRules()) {
681
            return false;
682
        }
683
684
        if (is_string($this->column)) {
685
            if (!array_has($input, $this->column)) {
686
                return false;
687
            }
688
689
            $input = $this->sanitizeInput($input, $this->column);
690
691
            $rules[$this->column] = $fieldRules;
692
            $attributes[$this->column] = $this->label;
693
        }
694
695
        if (is_array($this->column)) {
696
            foreach ($this->column as $key => $column) {
697
                if (!array_key_exists($column, $input)) {
698
                    continue;
699
                }
700
                $input[$column.$key] = array_get($input, $column);
701
                $rules[$column.$key] = $fieldRules;
702
                $attributes[$column.$key] = $this->label."[$column]";
703
            }
704
        }
705
706
        return Validator::make($input, $rules, $this->validationMessages, $attributes);
707
    }
708
709
    /**
710
     * Sanitize input data.
711
     *
712
     * @param array  $input
713
     * @param string $column
714
     *
715
     * @return array
716
     */
717
    protected function sanitizeInput($input, $column)
718
    {
719
        if ($this instanceof Field\MultipleSelect) {
720
            $value = array_get($input, $column);
721
            array_set($input, $column, array_filter($value));
722
        }
723
724
        return $input;
725
    }
726
727
    /**
728
     * Add html attributes to elements.
729
     *
730
     * @param array|string $attribute
731
     * @param mixed        $value
732
     *
733
     * @return $this
734
     */
735
    public function attribute($attribute, $value = null)
736
    {
737
        if (is_array($attribute)) {
738
            $this->attributes = array_merge($this->attributes, $attribute);
739
        } else {
740
            $this->attributes[$attribute] = (string) $value;
741
        }
742
743
        return $this;
744
    }
745
746
    /**
747
     * Specifies a regular expression against which to validate the value of the input.
748
     *
749
     * @param string $regexp
750
     *
751
     * @return Field
752
     */
753
    public function pattern($regexp)
754
    {
755
        return $this->attribute('pattern', $regexp);
756
    }
757
758
    /**
759
     * set the input filed required.
760
     *
761
     * @param bool $isLabelAsterisked
762
     *
763
     * @return Field
764
     */
765
    public function required($isLabelAsterisked = true)
766
    {
767
        if ($isLabelAsterisked) {
768
            $this->setLabelClass(['asterisk']);
769
        }
770
771
        return $this->attribute('required', true);
772
    }
773
774
    /**
775
     * Set the field automatically get focus.
776
     *
777
     * @return Field
778
     */
779
    public function autofocus()
780
    {
781
        return $this->attribute('autofocus', true);
782
    }
783
784
    /**
785
     * Set the field as readonly mode.
786
     *
787
     * @return Field
788
     */
789
    public function readOnly()
790
    {
791
        return $this->attribute('readonly', true);
792
    }
793
794
    /**
795
     * Set field as disabled.
796
     *
797
     * @return Field
798
     */
799
    public function disable()
800
    {
801
        return $this->attribute('disabled', true);
802
    }
803
804
    /**
805
     * Set field placeholder.
806
     *
807
     * @param string $placeholder
808
     *
809
     * @return Field
810
     */
811
    public function placeholder($placeholder = '')
812
    {
813
        $this->placeholder = $placeholder;
814
815
        return $this;
816
    }
817
818
    /**
819
     * Get placeholder.
820
     *
821
     * @return string
822
     */
823
    public function getPlaceholder()
824
    {
825
        return $this->placeholder ?: trans('admin.input').' '.$this->label;
826
    }
827
828
    /**
829
     * Prepare for a field value before update or insert.
830
     *
831
     * @param $value
832
     *
833
     * @return mixed
834
     */
835
    public function prepare($value)
836
    {
837
        return $value;
838
    }
839
840
    /**
841
     * Format the field attributes.
842
     *
843
     * @return string
844
     */
845
    protected function formatAttributes()
846
    {
847
        $html = [];
848
849
        foreach ($this->attributes as $name => $value) {
850
            $html[] = $name.'="'.e($value).'"';
851
        }
852
853
        return implode(' ', $html);
854
    }
855
856
    /**
857
     * @return $this
858
     */
859
    public function disableHorizontal()
860
    {
861
        $this->horizontal = false;
862
863
        return $this;
864
    }
865
866
    /**
867
     * @return array
868
     */
869
    public function getViewElementClasses()
870
    {
871
        if ($this->horizontal) {
872
            return [
873
                'label'      => "col-sm-{$this->width['label']} {$this->getLabelClass()}",
874
                'field'      => "col-sm-{$this->width['field']}",
875
                'form-group' => 'form-group ',
876
            ];
877
        }
878
879
        return ['label' => "{$this->getLabelClass()}", 'field' => '', 'form-group' => ''];
880
    }
881
882
    /**
883
     * Set form element class.
884
     *
885
     * @param string|array $class
886
     *
887
     * @return $this
888
     */
889
    public function setElementClass($class)
890
    {
891
        $this->elementClass = array_merge($this->elementClass, (array) $class);
892
893
        return $this;
894
    }
895
896
    /**
897
     * Get element class.
898
     *
899
     * @return array
900
     */
901
    protected function getElementClass()
902
    {
903
        if (!$this->elementClass) {
904
            $name = $this->elementName ?: $this->formatName($this->column);
905
906
            $this->elementClass = (array) str_replace(['[', ']'], '_', $name);
907
        }
908
909
        return $this->elementClass;
910
    }
911
912
    /**
913
     * Get element class string.
914
     *
915
     * @return mixed
916
     */
917
    protected function getElementClassString()
918
    {
919
        $elementClass = $this->getElementClass();
920
921
        if (Arr::isAssoc($elementClass)) {
922
            $classes = [];
923
924
            foreach ($elementClass as $index => $class) {
925
                $classes[$index] = is_array($class) ? implode(' ', $class) : $class;
926
            }
927
928
            return $classes;
929
        }
930
931
        return implode(' ', $elementClass);
932
    }
933
934
    /**
935
     * Get element class selector.
936
     *
937
     * @return string|array
938
     */
939
    protected function getElementClassSelector()
940
    {
941
        $elementClass = $this->getElementClass();
942
943
        if (Arr::isAssoc($elementClass)) {
944
            $classes = [];
945
946
            foreach ($elementClass as $index => $class) {
947
                $classes[$index] = '.'.(is_array($class) ? implode('.', $class) : $class);
948
            }
949
950
            return $classes;
951
        }
952
953
        return '.'.implode('.', $elementClass);
954
    }
955
956
    /**
957
     * Add the element class.
958
     *
959
     * @param $class
960
     *
961
     * @return $this
962
     */
963
    public function addElementClass($class)
964
    {
965
        if (is_array($class) || is_string($class)) {
966
            $this->elementClass = array_merge($this->elementClass, (array) $class);
967
968
            $this->elementClass = array_unique($this->elementClass);
969
        }
970
971
        return $this;
972
    }
973
974
    /**
975
     * Remove element class.
976
     *
977
     * @param $class
978
     *
979
     * @return $this
980
     */
981
    public function removeElementClass($class)
982
    {
983
        $delClass = [];
984
985
        if (is_string($class) || is_array($class)) {
986
            $delClass = (array) $class;
987
        }
988
989
        foreach ($delClass as $del) {
990
            if (($key = array_search($del, $this->elementClass))) {
991
                unset($this->elementClass[$key]);
992
            }
993
        }
994
995
        return $this;
996
    }
997
998
    /**
999
     * Add variables to field view.
1000
     *
1001
     * @param array $variables
1002
     *
1003
     * @return $this
1004
     */
1005
    protected function addVariables(array $variables = [])
1006
    {
1007
        $this->variables = array_merge($this->variables, $variables);
1008
1009
        return $this;
1010
    }
1011
1012
    /**
1013
     * @return string
1014
     */
1015
    public function getLabelClass()
1016
    : string
1017
    {
1018
        return implode(' ', $this->labelClass);
1019
    }
1020
1021
    /**
1022
     * @param array $labelClass
1023
     *
1024
     * @return self
1025
     */
1026
    public function setLabelClass(array $labelClass)
1027
    : self
1028
    {
1029
        $this->labelClass = $labelClass;
1030
1031
        return $this;
1032
    }
1033
1034
    /**
1035
     * Get the view variables of this field.
1036
     *
1037
     * @return array
1038
     */
1039
    public function variables()
1040
    {
1041
        return array_merge($this->variables, [
1042
            'id'          => $this->id,
1043
            'name'        => $this->elementName ?: $this->formatName($this->column),
1044
            'help'        => $this->help,
1045
            'class'       => $this->getElementClassString(),
1046
            'value'       => $this->value(),
1047
            'label'       => $this->label,
1048
            'viewClass'   => $this->getViewElementClasses(),
1049
            'column'      => $this->column,
1050
            'errorKey'    => $this->getErrorKey(),
1051
            'attributes'  => $this->formatAttributes(),
1052
            'placeholder' => $this->getPlaceholder(),
1053
        ]);
1054
    }
1055
1056
    /**
1057
     * Get view of this field.
1058
     *
1059
     * @return string
1060
     */
1061
    public function getView()
1062
    {
1063
        if (!empty($this->view)) {
1064
            return $this->view;
1065
        }
1066
1067
        $class = explode('\\', get_called_class());
1068
1069
        return 'admin::form.'.strtolower(end($class));
1070
    }
1071
1072
    /**
1073
     * Get script of current field.
1074
     *
1075
     * @return string
1076
     */
1077
    public function getScript()
1078
    {
1079
        return $this->script;
1080
    }
1081
1082
    /**
1083
     * Set script of current field
1084
     *
1085
     * @return self
1086
     */
1087
    public functiion setScript($script)
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
1088
    {
1089
       $this->script = $script;
1090
       return $this;
1091
    }
1092
1093
    /**
1094
     * To set this field should render or not.
1095
     *
1096
     * @return self
1097
     */
1098
    public function setDisplay(bool $display)
1099
    {
1100
        $this->display = $display;
1101
1102
        return $this;
1103
    }
1104
1105
    /**
1106
     * If this field should render.
1107
     *
1108
     * @return bool
1109
     */
1110
    protected function shouldRender()
1111
    {
1112
        if (!$this->display) {
1113
            return false;
1114
        }
1115
1116
        return true;
1117
    }
1118
1119
    /**
1120
     * Render this filed.
1121
     *
1122
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|string
1123
     */
1124
    public function render()
1125
    {
1126
        if (!$this->shouldRender()) {
1127
            return '';
1128
        }
1129
1130
        Admin::script($this->script);
1131
1132
        return view($this->getView(), $this->variables());
1133
    }
1134
1135
    /**
1136
     * @return string
1137
     */
1138
    public function __toString()
1139
    {
1140
        return $this->render()->render();
1141
    }
1142
}
1143