@progress/kendo-vue-editor 6.4.0 → 6.4.1-develop.1
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/config/defaultStyles.js +5 -1
- package/config/defaultStyles.mjs +5 -1
- package/config/toolsSettings.js +1 -1
- package/config/toolsSettings.mjs +15 -14
- package/dialogs/FindReplace.js +1 -1
- package/dialogs/FindReplace.mjs +129 -118
- package/dist/cdn/js/kendo-vue-editor.js +1 -1
- package/messages/main.js +1 -1
- package/messages/main.mjs +34 -32
- package/package-metadata.js +1 -1
- package/package-metadata.mjs +2 -2
- package/package.json +12 -12
package/dialogs/FindReplace.mjs
CHANGED
|
@@ -5,21 +5,22 @@
|
|
|
5
5
|
* Licensed under commercial license. See LICENSE.md in the package root for more information
|
|
6
6
|
*-------------------------------------------------------------------------------------------
|
|
7
7
|
*/
|
|
8
|
-
import { defineComponent as
|
|
8
|
+
import { defineComponent as V, createVNode as t, isVNode as P } from "vue";
|
|
9
9
|
import { Button as f } from "@progress/kendo-vue-buttons";
|
|
10
|
-
import { chevronRightIcon as
|
|
11
|
-
import { Window as
|
|
12
|
-
import { TabStrip as
|
|
13
|
-
import { provideLocalizationService as
|
|
14
|
-
import { messages as
|
|
15
|
-
import { EditorToolsSettings as
|
|
16
|
-
import { formatString as
|
|
17
|
-
import { selectedLineTextOnly as
|
|
18
|
-
import { Icon as
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
import { chevronRightIcon as $, chevronLeftIcon as F } from "@progress/kendo-svg-icons";
|
|
11
|
+
import { Window as q } from "@progress/kendo-vue-dialogs";
|
|
12
|
+
import { TabStrip as H, TabStripTab as E } from "@progress/kendo-vue-layout";
|
|
13
|
+
import { provideLocalizationService as G } from "@progress/kendo-vue-intl";
|
|
14
|
+
import { messages as l } from "../messages/main.mjs";
|
|
15
|
+
import { EditorToolsSettings as J } from "../config/toolsSettings.mjs";
|
|
16
|
+
import { formatString as Q } from "../tools/utils.mjs";
|
|
17
|
+
import { selectedLineTextOnly as X, textHighlightKey as Y, TextSelection as g, find as Z, replace as ee, replaceAll as te, findAll as ne } from "@progress/kendo-editor-common";
|
|
18
|
+
import { Icon as N } from "@progress/kendo-vue-common";
|
|
19
|
+
import { Error as se } from "@progress/kendo-vue-labels";
|
|
20
|
+
function x(e) {
|
|
21
|
+
return typeof e == "function" || Object.prototype.toString.call(e) === "[object Object]" && !P(e);
|
|
21
22
|
}
|
|
22
|
-
const
|
|
23
|
+
const ae = 13, ce = 27, ie = J.findAndReplace, be = /* @__PURE__ */ V({
|
|
23
24
|
name: "KendoFindAndReplaceDialog",
|
|
24
25
|
emits: {
|
|
25
26
|
close: null
|
|
@@ -29,7 +30,7 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
29
30
|
settings: {
|
|
30
31
|
type: Object,
|
|
31
32
|
default: function() {
|
|
32
|
-
return
|
|
33
|
+
return ie;
|
|
33
34
|
}
|
|
34
35
|
},
|
|
35
36
|
dir: String
|
|
@@ -45,7 +46,7 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
45
46
|
data() {
|
|
46
47
|
return {
|
|
47
48
|
selectedTab: 0,
|
|
48
|
-
searchText:
|
|
49
|
+
searchText: X(this.$props.view.state),
|
|
49
50
|
replaceText: "",
|
|
50
51
|
matchCase: !1,
|
|
51
52
|
matchWord: !1,
|
|
@@ -65,18 +66,18 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
65
66
|
* @hidden
|
|
66
67
|
*/
|
|
67
68
|
updated() {
|
|
68
|
-
const e = this.matches || [], n = this.nextMatch,
|
|
69
|
+
const e = this.matches || [], n = this.nextMatch, s = this.$props.view;
|
|
69
70
|
if (this._prevMatch !== n) {
|
|
70
|
-
const a =
|
|
71
|
-
e.forEach((
|
|
72
|
-
|
|
73
|
-
from:
|
|
74
|
-
to:
|
|
71
|
+
const a = s.state, i = a.tr, c = [];
|
|
72
|
+
e.forEach((o) => {
|
|
73
|
+
c.push({
|
|
74
|
+
from: o.from,
|
|
75
|
+
to: o.to,
|
|
75
76
|
attrs: {
|
|
76
|
-
class: n &&
|
|
77
|
+
class: n && o.eq(n) ? "k-text-selected" : "k-text-highlighted"
|
|
77
78
|
}
|
|
78
79
|
});
|
|
79
|
-
}), i.setMeta(
|
|
80
|
+
}), i.setMeta(Y, c), i.setSelection(n || g.create(a.doc, a.selection.from)), s.dispatch(i);
|
|
80
81
|
}
|
|
81
82
|
},
|
|
82
83
|
unmounted() {
|
|
@@ -84,50 +85,51 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
84
85
|
},
|
|
85
86
|
render() {
|
|
86
87
|
let e, n;
|
|
87
|
-
const
|
|
88
|
+
const s = G(this), {
|
|
88
89
|
findReplaceDialogTitle: a,
|
|
89
90
|
findReplaceTabFind: i,
|
|
90
|
-
findReplaceTabReplace:
|
|
91
|
-
findReplaceFindWhat:
|
|
92
|
-
findReplaceReplaceWith:
|
|
93
|
-
findReplaceReplace:
|
|
94
|
-
findReplaceReplaceAll:
|
|
95
|
-
findReplaceMatchCase:
|
|
96
|
-
findReplaceMatchWord:
|
|
97
|
-
findReplaceMatchCyclic:
|
|
98
|
-
findReplaceUseRegExp:
|
|
99
|
-
findReplacePrevMatch:
|
|
100
|
-
findReplaceNextMatch:
|
|
101
|
-
findReplaceMatches:
|
|
91
|
+
findReplaceTabReplace: c,
|
|
92
|
+
findReplaceFindWhat: o,
|
|
93
|
+
findReplaceReplaceWith: r,
|
|
94
|
+
findReplaceReplace: p,
|
|
95
|
+
findReplaceReplaceAll: u,
|
|
96
|
+
findReplaceMatchCase: k,
|
|
97
|
+
findReplaceMatchWord: b,
|
|
98
|
+
findReplaceMatchCyclic: S,
|
|
99
|
+
findReplaceUseRegExp: C,
|
|
100
|
+
findReplacePrevMatch: v,
|
|
101
|
+
findReplaceNextMatch: R,
|
|
102
|
+
findReplaceMatches: M
|
|
102
103
|
} = this.settings.messages, {
|
|
103
|
-
matchCase:
|
|
104
|
-
matchWord:
|
|
104
|
+
matchCase: _,
|
|
105
|
+
matchWord: I,
|
|
105
106
|
matchCyclic: j,
|
|
106
107
|
useRegExp: A,
|
|
107
108
|
searchText: B,
|
|
108
|
-
replaceText:
|
|
109
|
-
nextMatch:
|
|
110
|
-
|
|
109
|
+
replaceText: O,
|
|
110
|
+
nextMatch: y,
|
|
111
|
+
error: m
|
|
112
|
+
} = this, T = t("div", {
|
|
111
113
|
class: "k-search-options"
|
|
112
114
|
}, [t("span", null, [t("input", {
|
|
113
115
|
class: "k-checkbox k-checkbox-md k-rounded-md",
|
|
114
116
|
type: "checkbox",
|
|
115
117
|
id: "match-case",
|
|
116
|
-
checked:
|
|
118
|
+
checked: _,
|
|
117
119
|
onChange: this.onMatchCaseChecked
|
|
118
120
|
}, null), t("label", {
|
|
119
121
|
for: "match-case",
|
|
120
122
|
class: "k-checkbox-label"
|
|
121
|
-
}, [
|
|
123
|
+
}, [s.toLanguageString(k, l[k])])]), t("span", null, [t("input", {
|
|
122
124
|
class: "k-checkbox k-checkbox-md k-rounded-md",
|
|
123
125
|
type: "checkbox",
|
|
124
126
|
id: "match-whole",
|
|
125
|
-
checked:
|
|
127
|
+
checked: I,
|
|
126
128
|
onChange: this.onMatchWordChecked
|
|
127
129
|
}, null), t("label", {
|
|
128
130
|
for: "match-whole",
|
|
129
131
|
class: "k-checkbox-label"
|
|
130
|
-
}, [
|
|
132
|
+
}, [s.toLanguageString(b, l[b])])]), t("span", null, [t("input", {
|
|
131
133
|
class: "k-checkbox k-checkbox-md k-rounded-md",
|
|
132
134
|
type: "checkbox",
|
|
133
135
|
id: "match-cyclic",
|
|
@@ -136,7 +138,7 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
136
138
|
}, null), t("label", {
|
|
137
139
|
for: "match-cyclic",
|
|
138
140
|
class: "k-checkbox-label"
|
|
139
|
-
}, [
|
|
141
|
+
}, [s.toLanguageString(S, l[S])])]), t("span", null, [t("input", {
|
|
140
142
|
class: "k-checkbox k-checkbox-md k-rounded-md",
|
|
141
143
|
type: "checkbox",
|
|
142
144
|
id: "regular-expression",
|
|
@@ -145,58 +147,61 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
145
147
|
}, null), t("label", {
|
|
146
148
|
for: "regular-expression",
|
|
147
149
|
class: "k-checkbox-label"
|
|
148
|
-
}, [
|
|
149
|
-
const
|
|
150
|
+
}, [s.toLanguageString(C, l[C])])])]), w = function(d) {
|
|
151
|
+
const h = this.$props.dir === "rtl", K = t(f, {
|
|
150
152
|
fillMode: "flat",
|
|
151
153
|
themeColor: "primary",
|
|
152
154
|
onClick: this.onFindPrev
|
|
153
155
|
}, {
|
|
154
|
-
default: () => [t(
|
|
155
|
-
name: `chevron-${
|
|
156
|
-
icon:
|
|
157
|
-
}, null),
|
|
158
|
-
}),
|
|
156
|
+
default: () => [t(N, {
|
|
157
|
+
name: `chevron-${h ? "right" : "left"}`,
|
|
158
|
+
icon: h ? $ : F
|
|
159
|
+
}, null), s.toLanguageString(v, l[v])]
|
|
160
|
+
}), U = t(f, {
|
|
159
161
|
fillMode: "flat",
|
|
160
162
|
themeColor: "primary",
|
|
161
163
|
onClick: this.onFindNext
|
|
162
164
|
}, {
|
|
163
|
-
default: () => [
|
|
164
|
-
name: `chevron-${
|
|
165
|
-
icon:
|
|
165
|
+
default: () => [s.toLanguageString(R, l[R]), t(N, {
|
|
166
|
+
name: `chevron-${h ? "left" : "right"}`,
|
|
167
|
+
icon: h ? F : $
|
|
166
168
|
}, null)]
|
|
167
169
|
});
|
|
168
170
|
return t("div", {
|
|
169
171
|
class: "k-matches-container"
|
|
170
|
-
}, [
|
|
171
|
-
ref:
|
|
172
|
-
}, [this.matchesMessage(
|
|
173
|
-
},
|
|
172
|
+
}, [K, this.hasMounted && t("span", {
|
|
173
|
+
ref: d
|
|
174
|
+
}, [this.matchesMessage(s.toLanguageString(M, l[M]))]), U]);
|
|
175
|
+
}, W = function(d) {
|
|
174
176
|
return t("div", {
|
|
175
177
|
class: "k-edit-label"
|
|
176
178
|
}, [t("label", {
|
|
177
|
-
ref:
|
|
178
|
-
for:
|
|
179
|
-
}, [
|
|
180
|
-
},
|
|
179
|
+
ref: d,
|
|
180
|
+
for: d
|
|
181
|
+
}, [s.toLanguageString(o, l[o])])]);
|
|
182
|
+
}, L = function(d) {
|
|
183
|
+
let h;
|
|
181
184
|
return t("div", {
|
|
182
185
|
class: "k-edit-field"
|
|
183
186
|
}, [t("span", {
|
|
184
187
|
class: "k-textbox k-input k-input-md k-rounded-md k-input-solid"
|
|
185
188
|
}, [t("input", {
|
|
186
|
-
id:
|
|
187
|
-
ref:
|
|
189
|
+
id: d,
|
|
190
|
+
ref: d,
|
|
188
191
|
type: "text",
|
|
189
192
|
class: "k-input-inner",
|
|
190
193
|
value: B,
|
|
191
194
|
onInput: this.onSearchChange,
|
|
192
195
|
onFocus: this.onSearchChange,
|
|
193
196
|
onKeydown: this.onKeyDown
|
|
194
|
-
}, null)])])
|
|
195
|
-
|
|
197
|
+
}, null)]), m && t(se, null, x(h = s.toLanguageString(m, l[m])) ? h : {
|
|
198
|
+
default: () => [h]
|
|
199
|
+
})]);
|
|
200
|
+
}, z = t("div", {
|
|
196
201
|
class: "k-edit-label"
|
|
197
202
|
}, [t("label", {
|
|
198
203
|
for: "replaceWith"
|
|
199
|
-
}, [
|
|
204
|
+
}, [s.toLanguageString(r, l[r])])]), D = t("div", {
|
|
200
205
|
class: "k-edit-field"
|
|
201
206
|
}, [t("span", {
|
|
202
207
|
class: "k-textbox k-input k-input-md k-rounded-md k-input-solid"
|
|
@@ -204,11 +209,11 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
204
209
|
id: "replaceWith",
|
|
205
210
|
class: "k-input-inner",
|
|
206
211
|
type: "text",
|
|
207
|
-
value:
|
|
212
|
+
value: O,
|
|
208
213
|
onInput: this.onReplaceChange
|
|
209
214
|
}, null)])]);
|
|
210
|
-
return t(
|
|
211
|
-
title:
|
|
215
|
+
return t(q, {
|
|
216
|
+
title: s.toLanguageString(a, l[a]),
|
|
212
217
|
onClose: this.onClose,
|
|
213
218
|
windowStyle: {
|
|
214
219
|
width: "auto",
|
|
@@ -220,39 +225,39 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
220
225
|
maximizeButton: () => null,
|
|
221
226
|
dir: this.$props.dir
|
|
222
227
|
}, {
|
|
223
|
-
default: () => [t(
|
|
228
|
+
default: () => [t(H, {
|
|
224
229
|
dir: this.$props.dir,
|
|
225
230
|
selected: this.selectedTab,
|
|
226
231
|
class: "k-editor-find-replace",
|
|
227
232
|
onSelect: this.onTabSelect,
|
|
228
233
|
animation: !1
|
|
229
234
|
}, {
|
|
230
|
-
default: () => [t(
|
|
231
|
-
title:
|
|
235
|
+
default: () => [t(E, {
|
|
236
|
+
title: s.toLanguageString(i, l[i])
|
|
232
237
|
}, {
|
|
233
238
|
default: () => [t("div", {
|
|
234
239
|
class: "k-edit-form-container"
|
|
235
|
-
}, [
|
|
240
|
+
}, [W.call(this, "findWhatFind"), L.call(this, "findWhatFind")]), t("div", {
|
|
236
241
|
class: "k-actions k-hstack k-justify-content-end"
|
|
237
|
-
}, null),
|
|
238
|
-
}), t(
|
|
239
|
-
title:
|
|
242
|
+
}, null), T, w.call(this, "findWhatFind")]
|
|
243
|
+
}), t(E, {
|
|
244
|
+
title: s.toLanguageString(c, l[c])
|
|
240
245
|
}, {
|
|
241
246
|
default: () => [t("div", {
|
|
242
247
|
class: "k-edit-form-container"
|
|
243
|
-
}, [
|
|
248
|
+
}, [W.call(this, "findWhatReplace"), L.call(this, "findWhatReplace"), z, D]), t("div", {
|
|
244
249
|
class: "k-actions k-hstack k-justify-content-end"
|
|
245
250
|
}, [t(f, {
|
|
246
|
-
disabled: !
|
|
251
|
+
disabled: !y,
|
|
247
252
|
onClick: this.onReplace
|
|
248
|
-
},
|
|
253
|
+
}, x(e = s.toLanguageString(p, l[p])) ? e : {
|
|
249
254
|
default: () => [e]
|
|
250
255
|
}), t(f, {
|
|
251
|
-
disabled: !
|
|
256
|
+
disabled: !y,
|
|
252
257
|
onClick: this.onReplaceAll
|
|
253
|
-
},
|
|
258
|
+
}, x(n = s.toLanguageString(u, l[u])) ? n : {
|
|
254
259
|
default: () => [n]
|
|
255
|
-
})]),
|
|
260
|
+
})]), T, w.call(this, "findWhatReplace")]
|
|
256
261
|
})]
|
|
257
262
|
})]
|
|
258
263
|
});
|
|
@@ -262,17 +267,17 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
262
267
|
this.selectedTab = e.selected;
|
|
263
268
|
},
|
|
264
269
|
onClose() {
|
|
265
|
-
const e = this.$props.view, n = e.state,
|
|
266
|
-
e.updateState(n.apply(
|
|
270
|
+
const e = this.$props.view, n = e.state, s = n.tr.setSelection(g.create(n.doc, n.selection.from, n.selection.to));
|
|
271
|
+
e.updateState(n.apply(s)), e.focus(), this.$emit("close");
|
|
267
272
|
},
|
|
268
273
|
matchesMessage(e) {
|
|
269
|
-
const n = this.matches,
|
|
274
|
+
const n = this.matches, s = this.nextMatch;
|
|
270
275
|
let a = 0, i = 0;
|
|
271
|
-
if (n &&
|
|
272
|
-
const
|
|
273
|
-
a =
|
|
276
|
+
if (n && s) {
|
|
277
|
+
const c = n.findIndex((o) => o.eq(s));
|
|
278
|
+
a = c === -1 ? n.length : c + 1, i = n.length;
|
|
274
279
|
}
|
|
275
|
-
return
|
|
280
|
+
return Q(e, a, i);
|
|
276
281
|
},
|
|
277
282
|
onFindNext() {
|
|
278
283
|
this.onFind();
|
|
@@ -282,50 +287,50 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
282
287
|
},
|
|
283
288
|
onFind(e = !1) {
|
|
284
289
|
const n = this.$props.view, {
|
|
285
|
-
searchText:
|
|
290
|
+
searchText: s,
|
|
286
291
|
matchCase: a,
|
|
287
292
|
matchCyclic: i,
|
|
288
|
-
matchWord:
|
|
289
|
-
useRegExp:
|
|
290
|
-
} = this.$data,
|
|
291
|
-
text:
|
|
292
|
-
matchWord:
|
|
293
|
+
matchWord: c,
|
|
294
|
+
useRegExp: o
|
|
295
|
+
} = this.$data, r = {
|
|
296
|
+
text: s,
|
|
297
|
+
matchWord: c,
|
|
293
298
|
matchCase: a,
|
|
294
|
-
useRegExp:
|
|
299
|
+
useRegExp: o,
|
|
295
300
|
backward: e,
|
|
296
301
|
matchCyclic: i
|
|
297
|
-
},
|
|
298
|
-
if (
|
|
299
|
-
const
|
|
300
|
-
|
|
302
|
+
}, p = Z(n.state, r);
|
|
303
|
+
if (p) {
|
|
304
|
+
const u = n.state.tr.setSelection(p);
|
|
305
|
+
u.scrollIntoView(), n.updateState(n.state.apply(u)), this._prevMatch = this.nextMatch, this.nextMatch = p, this._prevMatch !== this.nextMatch && this.$forceUpdate();
|
|
301
306
|
}
|
|
302
307
|
},
|
|
303
308
|
onReplace() {
|
|
304
309
|
const e = this.$props.view, n = e.state.selection, {
|
|
305
|
-
replaceText:
|
|
310
|
+
replaceText: s
|
|
306
311
|
} = this.$data;
|
|
307
312
|
if (!n.empty) {
|
|
308
|
-
const a = n.from, i = a +
|
|
309
|
-
|
|
313
|
+
const a = n.from, i = a + s.length, c = ee(n, s, e.state.tr);
|
|
314
|
+
c.setSelection(g.create(c.doc, a, i)), c.scrollIntoView(), e.dispatch(c), this.onFind(), this.setNextState({});
|
|
310
315
|
}
|
|
311
316
|
},
|
|
312
317
|
onReplaceAll() {
|
|
313
318
|
const e = this.$props.view, {
|
|
314
319
|
searchText: n,
|
|
315
|
-
replaceText:
|
|
320
|
+
replaceText: s,
|
|
316
321
|
matchCase: a,
|
|
317
322
|
matchWord: i,
|
|
318
|
-
useRegExp:
|
|
319
|
-
} = this.$data,
|
|
323
|
+
useRegExp: c
|
|
324
|
+
} = this.$data, o = {
|
|
320
325
|
text: n,
|
|
321
326
|
matchWord: i,
|
|
322
327
|
matchCase: a,
|
|
323
|
-
useRegExp:
|
|
324
|
-
};
|
|
325
|
-
e.dispatch(
|
|
328
|
+
useRegExp: c
|
|
329
|
+
}, r = te(e.state, s, o);
|
|
330
|
+
r && (e.dispatch(r), this.setNextState({}));
|
|
326
331
|
},
|
|
327
332
|
onKeyDown(e) {
|
|
328
|
-
e.keyCode ===
|
|
333
|
+
e.keyCode === ae ? this.onFindNext() : e.keyCode === ce && this.onClose();
|
|
329
334
|
},
|
|
330
335
|
onMatchCaseChecked(e) {
|
|
331
336
|
this.matchCase = e.target.checked, this.setNextState();
|
|
@@ -353,14 +358,20 @@ const ne = 13, ce = 27, ae = G.findAndReplace, ge = /* @__PURE__ */ U({
|
|
|
353
358
|
matchWord: this.matchWord,
|
|
354
359
|
matchCase: this.matchCase,
|
|
355
360
|
useRegExp: this.useRegExp
|
|
356
|
-
},
|
|
357
|
-
let
|
|
358
|
-
|
|
361
|
+
}, s = e.state.selection;
|
|
362
|
+
let a = [], i;
|
|
363
|
+
try {
|
|
364
|
+
a = ne(e.state.doc, n);
|
|
365
|
+
} catch (o) {
|
|
366
|
+
o instanceof SyntaxError && (i = this.settings.messages.findReplaceInvalidRegExp);
|
|
367
|
+
}
|
|
368
|
+
const c = !this.searchText && a[0] || a.find((o) => o.from >= s.from) || this.matchCyclic && a[0] || void 0;
|
|
369
|
+
this._prevMatch = this.nextMatch, this.matches = a, this.nextMatch = c, this.error = i;
|
|
359
370
|
} else
|
|
360
|
-
this._prevMatch = this.nextMatch, this.matches = [], this.nextMatch = void 0;
|
|
371
|
+
this._prevMatch = this.nextMatch, this.matches = [], this.nextMatch = void 0, this.error = void 0;
|
|
361
372
|
}
|
|
362
373
|
}
|
|
363
374
|
});
|
|
364
375
|
export {
|
|
365
|
-
|
|
376
|
+
be as FindAndReplaceDialog
|
|
366
377
|
};
|