n20-common-lib 2.22.44 → 2.22.45
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/package.json
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
<div class="n20-date-picker" :class="{ 'has-long-term': showLongTerm }">
|
|
3
|
+
<el-date-picker
|
|
4
|
+
ref="date-picker"
|
|
5
|
+
class="n20-date-editor"
|
|
6
|
+
:class="{ 'has-value': clearable && value }"
|
|
7
|
+
v-bind="$attrs"
|
|
8
|
+
:value="value"
|
|
9
|
+
:clearable="clearable"
|
|
10
|
+
:disabled="datePickerDisabled"
|
|
11
|
+
v-on="listeners"
|
|
12
|
+
/>
|
|
13
|
+
<el-checkbox
|
|
14
|
+
v-if="showLongTerm"
|
|
15
|
+
v-model="longTermC"
|
|
16
|
+
class="n20-date-picker__long-term"
|
|
17
|
+
:disabled="checkboxDisabled"
|
|
18
|
+
>
|
|
19
|
+
{{ longTermLabel | $lc }}
|
|
20
|
+
</el-checkbox>
|
|
21
|
+
</div>
|
|
11
22
|
</template>
|
|
12
23
|
|
|
13
24
|
<script>
|
|
25
|
+
const LONG_TERM_DATE = new Date(9999, 11, 31, 23, 59, 59)
|
|
26
|
+
|
|
14
27
|
export default {
|
|
15
28
|
name: 'DatePicker',
|
|
16
29
|
props: {
|
|
@@ -21,7 +34,139 @@ export default {
|
|
|
21
34
|
clearable: {
|
|
22
35
|
type: Boolean,
|
|
23
36
|
default: true
|
|
37
|
+
},
|
|
38
|
+
showLongTerm: {
|
|
39
|
+
type: Boolean,
|
|
40
|
+
default: false
|
|
41
|
+
},
|
|
42
|
+
longTerm: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: false
|
|
45
|
+
},
|
|
46
|
+
longTermLabel: {
|
|
47
|
+
type: String,
|
|
48
|
+
default: '长期'
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
computed: {
|
|
52
|
+
listeners() {
|
|
53
|
+
return Object.assign({}, this.$listeners, {
|
|
54
|
+
input: (val) => {
|
|
55
|
+
this.$emit('input', val)
|
|
56
|
+
if (this.longTerm) {
|
|
57
|
+
this.$emit('update:long-term', false)
|
|
58
|
+
this.$emit('changeLongTerm', {
|
|
59
|
+
longTerm: false,
|
|
60
|
+
value: val
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
},
|
|
66
|
+
longTermC: {
|
|
67
|
+
get() {
|
|
68
|
+
return this.longTerm
|
|
69
|
+
},
|
|
70
|
+
set(val) {
|
|
71
|
+
this.handleLongTermChange(val)
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
datePickerDisabled() {
|
|
75
|
+
return this.longTerm || this.isDisabled
|
|
76
|
+
},
|
|
77
|
+
checkboxDisabled() {
|
|
78
|
+
return this.isDisabled
|
|
79
|
+
},
|
|
80
|
+
isDisabled() {
|
|
81
|
+
return this.$attrs.disabled === '' || this.$attrs.disabled === true || this.$attrs.disabled === 'disabled'
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
methods: {
|
|
85
|
+
handleLongTermChange(val) {
|
|
86
|
+
this.$emit('update:long-term', val)
|
|
87
|
+
|
|
88
|
+
if (val) {
|
|
89
|
+
const longTermValue = this.getLongTermValue()
|
|
90
|
+
this.$emit('input', longTermValue)
|
|
91
|
+
this.$emit('change', longTermValue)
|
|
92
|
+
this.$emit('changeLongTerm', {
|
|
93
|
+
longTerm: true,
|
|
94
|
+
value: longTermValue
|
|
95
|
+
})
|
|
96
|
+
} else {
|
|
97
|
+
const currentValue = this.getCurrentValue()
|
|
98
|
+
this.$emit('input', currentValue)
|
|
99
|
+
this.$emit('change', currentValue)
|
|
100
|
+
this.$emit('changeLongTerm', {
|
|
101
|
+
longTerm: false,
|
|
102
|
+
value: currentValue
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
getLongTermValue() {
|
|
107
|
+
return this.getDateValue(LONG_TERM_DATE)
|
|
108
|
+
},
|
|
109
|
+
getCurrentValue() {
|
|
110
|
+
return this.getDateValue(new Date())
|
|
111
|
+
},
|
|
112
|
+
getDateValue(date) {
|
|
113
|
+
const valueFormat = this.$attrs['value-format']
|
|
114
|
+
|
|
115
|
+
if (valueFormat === 'timestamp') {
|
|
116
|
+
return date.getTime()
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!valueFormat) {
|
|
120
|
+
return new Date(date.getTime())
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const year = date.getFullYear() + ''
|
|
124
|
+
const month = this.padDateValue(date.getMonth() + 1)
|
|
125
|
+
const day = this.padDateValue(date.getDate())
|
|
126
|
+
const hours = this.padDateValue(date.getHours())
|
|
127
|
+
const minutes = this.padDateValue(date.getMinutes())
|
|
128
|
+
const seconds = this.padDateValue(date.getSeconds())
|
|
129
|
+
|
|
130
|
+
return valueFormat
|
|
131
|
+
.replace(/yyyy/g, year)
|
|
132
|
+
.replace(/YYYY/g, year)
|
|
133
|
+
.replace(/MM/g, month)
|
|
134
|
+
.replace(/dd/g, day)
|
|
135
|
+
.replace(/DD/g, day)
|
|
136
|
+
.replace(/HH/g, hours)
|
|
137
|
+
.replace(/hh/g, hours)
|
|
138
|
+
.replace(/mm/g, minutes)
|
|
139
|
+
.replace(/ss/g, seconds)
|
|
140
|
+
},
|
|
141
|
+
padDateValue(value) {
|
|
142
|
+
return value > 9 ? value + '' : '0' + value
|
|
24
143
|
}
|
|
25
144
|
}
|
|
26
145
|
}
|
|
27
146
|
</script>
|
|
147
|
+
|
|
148
|
+
<style scoped>
|
|
149
|
+
.n20-date-picker {
|
|
150
|
+
display: inline-block;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.n20-date-picker > .n20-date-editor {
|
|
154
|
+
width: 100%;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.n20-date-picker.has-long-term {
|
|
158
|
+
display: inline-flex;
|
|
159
|
+
align-items: center;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.n20-date-picker.has-long-term > .n20-date-editor {
|
|
163
|
+
flex: 1;
|
|
164
|
+
width: auto;
|
|
165
|
+
min-width: 0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.n20-date-picker__long-term {
|
|
169
|
+
margin-left: 8px;
|
|
170
|
+
white-space: nowrap;
|
|
171
|
+
}
|
|
172
|
+
</style>
|
|
@@ -1,43 +1,32 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/>
|
|
26
|
-
<el-checkbox
|
|
27
|
-
v-if="showLongTermCheckbox"
|
|
28
|
-
v-model="longTermC"
|
|
29
|
-
class="n20-date-picker-por__long-term"
|
|
30
|
-
:disabled="longTermDisabled"
|
|
31
|
-
>
|
|
32
|
-
{{ '长期' | $lc }}
|
|
33
|
-
</el-checkbox>
|
|
34
|
-
</div>
|
|
2
|
+
<el-date-picker
|
|
3
|
+
ref="date-picker"
|
|
4
|
+
v-model="valueC"
|
|
5
|
+
class="n20-date-editor"
|
|
6
|
+
:class="{
|
|
7
|
+
'has-value': clearable && valueC,
|
|
8
|
+
[this.$attrs && this.$attrs['rule-form']]: !valueC
|
|
9
|
+
}"
|
|
10
|
+
:popper-class="
|
|
11
|
+
!clearable && type === 'datetimerange'
|
|
12
|
+
? 'clearable-datetimerange' + ' ' + $attrs['popper-class']
|
|
13
|
+
: $attrs['popper-class']
|
|
14
|
+
"
|
|
15
|
+
:type="type"
|
|
16
|
+
:value-format="valueFormat"
|
|
17
|
+
:placeholder="'选择日期' | $lc"
|
|
18
|
+
:start-placeholder="'开始日期' | $lc"
|
|
19
|
+
:end-placeholder="'结束日期' | $lc"
|
|
20
|
+
:picker-options="pickerOptionsAs"
|
|
21
|
+
:clearable="clearable"
|
|
22
|
+
v-bind="$attrs"
|
|
23
|
+
v-on="listeners"
|
|
24
|
+
/>
|
|
35
25
|
</template>
|
|
36
26
|
|
|
37
27
|
<script>
|
|
38
|
-
import dayjs from 'dayjs'
|
|
39
|
-
|
|
40
28
|
import { $lc } from '../../utils/i18n/index'
|
|
29
|
+
import dayjs from 'dayjs'
|
|
41
30
|
|
|
42
31
|
let startDate = ''
|
|
43
32
|
|
|
@@ -263,20 +252,25 @@ export default {
|
|
|
263
252
|
type: Boolean,
|
|
264
253
|
default: true
|
|
265
254
|
},
|
|
266
|
-
showLongTerm: {
|
|
267
|
-
type: Boolean,
|
|
268
|
-
default: false
|
|
269
|
-
},
|
|
270
|
-
longTerm: {
|
|
271
|
-
type: Boolean,
|
|
272
|
-
default: false
|
|
273
|
-
},
|
|
274
255
|
pickerOptions: {
|
|
275
256
|
type: Object,
|
|
276
257
|
default: () => ({})
|
|
277
258
|
}
|
|
278
259
|
},
|
|
279
260
|
data() {
|
|
261
|
+
let shortcuts = undefined
|
|
262
|
+
if (this.shortcuts && ['daterange', 'datetimerange'].includes(this.type))
|
|
263
|
+
shortcuts = this.startStop ? shortcuts_2 : shortcuts_1
|
|
264
|
+
|
|
265
|
+
this.pickerOptionsAs = Object.assign(
|
|
266
|
+
{
|
|
267
|
+
disabledDate: this.minNow ? disabledDate_1 : this.maxNow ? disabledDate_2 : undefined,
|
|
268
|
+
shortcuts
|
|
269
|
+
// onPick
|
|
270
|
+
},
|
|
271
|
+
this.pickerOptions
|
|
272
|
+
)
|
|
273
|
+
|
|
280
274
|
this.listeners = Object.assign({}, this.$listeners, {
|
|
281
275
|
input: () => {},
|
|
282
276
|
change: () => {}
|
|
@@ -285,56 +279,9 @@ export default {
|
|
|
285
279
|
return {}
|
|
286
280
|
},
|
|
287
281
|
computed: {
|
|
288
|
-
isRangeType() {
|
|
289
|
-
return ['daterange', 'monthrange', 'datetimerange'].includes(this.type)
|
|
290
|
-
},
|
|
291
|
-
showLongTermCheckbox() {
|
|
292
|
-
return this.showLongTerm && this.isRangeType
|
|
293
|
-
},
|
|
294
|
-
isLongTerm() {
|
|
295
|
-
return this.showLongTermCheckbox && this.longTerm
|
|
296
|
-
},
|
|
297
|
-
pickerType() {
|
|
298
|
-
if (!this.isLongTerm) return this.type
|
|
299
|
-
const typeMap = {
|
|
300
|
-
daterange: 'date',
|
|
301
|
-
datetimerange: 'datetime',
|
|
302
|
-
monthrange: 'month'
|
|
303
|
-
}
|
|
304
|
-
return typeMap[this.type] || this.type
|
|
305
|
-
},
|
|
306
|
-
pickerOptionsAs() {
|
|
307
|
-
let shortcuts = undefined
|
|
308
|
-
if (!this.isLongTerm && this.shortcuts && ['daterange', 'datetimerange'].includes(this.type)) {
|
|
309
|
-
shortcuts = this.startStop ? shortcuts_2 : shortcuts_1
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return Object.assign(
|
|
313
|
-
{
|
|
314
|
-
disabledDate: this.minNow ? disabledDate_1 : this.maxNow ? disabledDate_2 : undefined,
|
|
315
|
-
shortcuts
|
|
316
|
-
// onPick
|
|
317
|
-
},
|
|
318
|
-
this.pickerOptions
|
|
319
|
-
)
|
|
320
|
-
},
|
|
321
|
-
longTermC: {
|
|
322
|
-
get() {
|
|
323
|
-
return this.longTerm
|
|
324
|
-
},
|
|
325
|
-
set(val) {
|
|
326
|
-
this.handleLongTermChange(val)
|
|
327
|
-
}
|
|
328
|
-
},
|
|
329
|
-
longTermDisabled() {
|
|
330
|
-
return this.$attrs.disabled === '' || this.$attrs.disabled === true || this.$attrs.disabled === 'disabled'
|
|
331
|
-
},
|
|
332
282
|
valueC: {
|
|
333
283
|
get() {
|
|
334
|
-
if (this.
|
|
335
|
-
if (this.isLongTerm) {
|
|
336
|
-
return this.startDate || null
|
|
337
|
-
}
|
|
284
|
+
if (['daterange', 'monthrange', 'datetimerange'].includes(this.type)) {
|
|
338
285
|
if (this.startDate && this.endDate) {
|
|
339
286
|
return [this.startDate, this.endDate]
|
|
340
287
|
} else {
|
|
@@ -345,11 +292,7 @@ export default {
|
|
|
345
292
|
}
|
|
346
293
|
},
|
|
347
294
|
set(val) {
|
|
348
|
-
if (this.
|
|
349
|
-
if (this.isLongTerm) {
|
|
350
|
-
this.handleLongTermDateChange(val)
|
|
351
|
-
return
|
|
352
|
-
}
|
|
295
|
+
if (['daterange', 'monthrange', 'datetimerange'].includes(this.type)) {
|
|
353
296
|
if (val && val[0]) {
|
|
354
297
|
if (this.type === 'monthrange' && ['yyyy-MM-dd', 'yyyy-MM-dd HH:mm:ss'].includes(this.valueFormat)) {
|
|
355
298
|
let end = new Date(val[1])
|
|
@@ -387,51 +330,6 @@ export default {
|
|
|
387
330
|
}
|
|
388
331
|
},
|
|
389
332
|
methods: {
|
|
390
|
-
handleLongTermChange(val) {
|
|
391
|
-
this.$emit('update:long-term', val)
|
|
392
|
-
|
|
393
|
-
if (val) {
|
|
394
|
-
this.$emit('update:end-date', undefined)
|
|
395
|
-
this.$emit('end', undefined)
|
|
396
|
-
this.$emit('changeLongTerm', {
|
|
397
|
-
longTerm: true,
|
|
398
|
-
startTime: this.startDate || null
|
|
399
|
-
})
|
|
400
|
-
} else {
|
|
401
|
-
this.$emit('update:start-date', null)
|
|
402
|
-
this.$emit('update:end-date', null)
|
|
403
|
-
this.$emit('start', null)
|
|
404
|
-
this.$emit('end', null)
|
|
405
|
-
this.$emit('changeLongTerm', {
|
|
406
|
-
longTerm: false,
|
|
407
|
-
startTime: null
|
|
408
|
-
})
|
|
409
|
-
this.$emit('change', null)
|
|
410
|
-
}
|
|
411
|
-
},
|
|
412
|
-
handleLongTermDateChange(val) {
|
|
413
|
-
if (val) {
|
|
414
|
-
this.$emit('update:start-date', val)
|
|
415
|
-
this.$emit('update:end-date', undefined)
|
|
416
|
-
this.$emit('start', val)
|
|
417
|
-
this.$emit('end', undefined)
|
|
418
|
-
this.$emit('change', [val, undefined])
|
|
419
|
-
this.$emit('changeLongTerm', {
|
|
420
|
-
longTerm: true,
|
|
421
|
-
startTime: val
|
|
422
|
-
})
|
|
423
|
-
} else {
|
|
424
|
-
this.$emit('update:start-date', null)
|
|
425
|
-
this.$emit('update:end-date', undefined)
|
|
426
|
-
this.$emit('start', null)
|
|
427
|
-
this.$emit('end', undefined)
|
|
428
|
-
this.$emit('change', val)
|
|
429
|
-
this.$emit('changeLongTerm', {
|
|
430
|
-
longTerm: true,
|
|
431
|
-
startTime: null
|
|
432
|
-
})
|
|
433
|
-
}
|
|
434
|
-
},
|
|
435
333
|
HandleBlur() {
|
|
436
334
|
let startSh = shortcuts_2.find((s) => s.text.includes($lc('开始')))
|
|
437
335
|
let endSh = shortcuts_2.find((s) => s.text.includes($lc('截止')))
|
|
@@ -451,29 +349,3 @@ export default {
|
|
|
451
349
|
}
|
|
452
350
|
}
|
|
453
351
|
</script>
|
|
454
|
-
|
|
455
|
-
<style scoped>
|
|
456
|
-
.n20-date-picker-por {
|
|
457
|
-
display: inline-block;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
.n20-date-picker-por > .n20-date-editor {
|
|
461
|
-
width: 100%;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
.n20-date-picker-por.has-long-term {
|
|
465
|
-
display: inline-flex;
|
|
466
|
-
align-items: center;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
.n20-date-picker-por.has-long-term > .n20-date-editor {
|
|
470
|
-
flex: 1;
|
|
471
|
-
width: auto;
|
|
472
|
-
min-width: 0;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
.n20-date-picker-por__long-term {
|
|
476
|
-
margin-left: 8px;
|
|
477
|
-
white-space: nowrap;
|
|
478
|
-
}
|
|
479
|
-
</style>
|
|
@@ -268,7 +268,7 @@
|
|
|
268
268
|
:close-on-click-modal="false"
|
|
269
269
|
:destroy-on-open="true"
|
|
270
270
|
>
|
|
271
|
-
<el-select v-model="bathType" class="m-b-s" clearable @change="handleBathChange">
|
|
271
|
+
<el-select v-model="bathType" class="m-b-s w-100p" clearable @change="handleBathChange">
|
|
272
272
|
<el-option
|
|
273
273
|
v-for="item in typeOptions"
|
|
274
274
|
:key="item.type"
|
|
@@ -288,7 +288,7 @@
|
|
|
288
288
|
:multiple="true"
|
|
289
289
|
:show-file-list="true"
|
|
290
290
|
:action="apiPrefix ? apiPrefix + action : action"
|
|
291
|
-
:data="fileData"
|
|
291
|
+
:data="_batchFileData || fileData"
|
|
292
292
|
:headers="headers"
|
|
293
293
|
:accept="fileAccept"
|
|
294
294
|
:size="fileSize"
|
|
@@ -501,7 +501,9 @@ export default {
|
|
|
501
501
|
previewName: undefined,
|
|
502
502
|
previewSameOrg: false,
|
|
503
503
|
seeRow: {},
|
|
504
|
-
officeStatus: false
|
|
504
|
+
officeStatus: false,
|
|
505
|
+
// 批量上传使用的文件数据(避免直接修改计算属性)
|
|
506
|
+
_batchFileData: null
|
|
505
507
|
}
|
|
506
508
|
},
|
|
507
509
|
computed: {
|
|
@@ -745,20 +747,32 @@ export default {
|
|
|
745
747
|
if (bu) return bu(file)
|
|
746
748
|
},
|
|
747
749
|
handleBathChange() {
|
|
748
|
-
|
|
750
|
+
// 创建新的文件数据对象,避免直接修改计算属性
|
|
751
|
+
let fileData = this.fileData || {}
|
|
752
|
+
let dto = JSON.parse(fileData.data || '{}')
|
|
749
753
|
dto[this.keys.type] = this.bathType
|
|
750
|
-
this.
|
|
754
|
+
this._batchFileData = {
|
|
755
|
+
...fileData,
|
|
756
|
+
data: JSON.stringify(dto)
|
|
757
|
+
}
|
|
751
758
|
},
|
|
752
759
|
batchUploadFn() {
|
|
753
760
|
let $uploadwrap = this.$refs['upload-batch']
|
|
754
|
-
|
|
755
|
-
if (fileList.length !== 0 && fileList.every((f) => f.status === 'success')) {
|
|
756
|
-
this.visibleBatch = false
|
|
757
|
-
}
|
|
761
|
+
// 直接提交上传,关闭对话框的逻辑在 batchSuccess 回调中处理
|
|
758
762
|
$uploadwrap.submit()
|
|
759
763
|
},
|
|
760
764
|
batchSuccess(response, file, fileList) {
|
|
761
|
-
|
|
765
|
+
// 创建完整的行对象,初始化状态字段
|
|
766
|
+
let row = {
|
|
767
|
+
id: 'n' + Math.random(),
|
|
768
|
+
[this.keys.name]: '',
|
|
769
|
+
[this.keys.type]: this.bathType,
|
|
770
|
+
[this.keys.time]: '',
|
|
771
|
+
[this.keys.user]: JSON.parse(sessionStorage.getItem('userInfo')).uname,
|
|
772
|
+
_percent: 0,
|
|
773
|
+
_status: undefined,
|
|
774
|
+
_typeDisabled: false
|
|
775
|
+
}
|
|
762
776
|
this.tableData.splice(0, 0, row)
|
|
763
777
|
this.$nextTick(() => {
|
|
764
778
|
this.onSuccessFn(response, file, fileList, row)
|
|
@@ -916,13 +930,8 @@ export default {
|
|
|
916
930
|
let FD = new FormData()
|
|
917
931
|
FD.append(opt.filename, opt.file)
|
|
918
932
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
data = window._fileData
|
|
922
|
-
delete window._fileData
|
|
923
|
-
} else {
|
|
924
|
-
data = opt.data
|
|
925
|
-
}
|
|
933
|
+
// 优先使用 opt.data,其次使用 this.fileData,移除全局变量 window._fileData 的使用
|
|
934
|
+
let data = opt.data || this.fileData
|
|
926
935
|
|
|
927
936
|
if (data) {
|
|
928
937
|
let dto = JSON.parse(data.data)
|
|
@@ -996,7 +1005,7 @@ export default {
|
|
|
996
1005
|
_percent = 99
|
|
997
1006
|
_status = 'error'
|
|
998
1007
|
} else {
|
|
999
|
-
_percent =
|
|
1008
|
+
_percent = 100
|
|
1000
1009
|
_status = 'success'
|
|
1001
1010
|
}
|
|
1002
1011
|
setTimeout(() => {
|