@portabletext/editor 2.7.1 → 2.8.0

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.
Files changed (48) hide show
  1. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +3 -1
  2. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
  3. package/lib/_chunks-cjs/util.slice-blocks.cjs +60 -6
  4. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  5. package/lib/_chunks-dts/behavior.types.action.d.cts +95 -95
  6. package/lib/_chunks-dts/behavior.types.action.d.ts +86 -86
  7. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +4 -2
  8. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
  9. package/lib/_chunks-es/util.slice-blocks.js +56 -5
  10. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  11. package/lib/index.cjs +94 -121
  12. package/lib/index.cjs.map +1 -1
  13. package/lib/index.js +90 -118
  14. package/lib/index.js.map +1 -1
  15. package/lib/plugins/index.d.cts +3 -3
  16. package/lib/selectors/index.d.cts +13 -3
  17. package/lib/selectors/index.d.ts +13 -3
  18. package/package.json +12 -13
  19. package/src/behaviors/behavior.abstract.insert.ts +58 -1
  20. package/src/behaviors/behavior.core.annotations.ts +24 -2
  21. package/src/behaviors/behavior.core.ts +1 -1
  22. package/src/behaviors/behavior.types.event.ts +18 -18
  23. package/src/converters/converter.text-html.serialize.test.ts +27 -17
  24. package/src/converters/converter.text-plain.test.ts +1 -1
  25. package/src/editor/plugins/createWithEditableAPI.ts +16 -0
  26. package/src/internal-utils/parse-blocks.ts +2 -1
  27. package/src/operations/behavior.operation.annotation.add.ts +1 -12
  28. package/src/operations/behavior.operations.ts +0 -18
  29. package/src/selectors/selector.is-active-annotation.test.ts +320 -0
  30. package/src/selectors/selector.is-active-annotation.ts +24 -0
  31. package/src/utils/util.slice-blocks.test.ts +39 -5
  32. package/src/utils/util.slice-blocks.ts +36 -3
  33. package/src/editor/__tests__/PortableTextEditor.test.tsx +0 -430
  34. package/src/editor/__tests__/PortableTextEditorTester.tsx +0 -58
  35. package/src/editor/__tests__/RangeDecorations.test.tsx +0 -213
  36. package/src/editor/__tests__/insert-block.test.tsx +0 -224
  37. package/src/editor/__tests__/self-solving.test.tsx +0 -183
  38. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +0 -298
  39. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +0 -177
  40. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +0 -538
  41. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +0 -162
  42. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +0 -65
  43. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +0 -612
  44. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +0 -103
  45. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +0 -147
  46. package/src/internal-utils/__tests__/valueNormalization.test.tsx +0 -79
  47. package/src/operations/behavior.operation.insert-inline-object.ts +0 -59
  48. package/src/operations/behavior.operation.insert-span.ts +0 -48
@@ -1,177 +0,0 @@
1
- import {compileSchema, isTextBlock} from '@portabletext/schema'
2
- import {createTestKeyGenerator} from '@portabletext/test'
3
- import {render, waitFor} from '@testing-library/react'
4
- import {createRef, type RefObject} from 'react'
5
- import {describe, expect, it, vi} from 'vitest'
6
- import {
7
- PortableTextEditorTester,
8
- schemaDefinition,
9
- } from '../../__tests__/PortableTextEditorTester'
10
- import {PortableTextEditor} from '../../PortableTextEditor'
11
-
12
- const initialValue = [
13
- {
14
- _key: 'a',
15
- _type: 'block',
16
- children: [
17
- {
18
- _key: 'a1',
19
- _type: 'span',
20
- marks: [],
21
- text: 'Block A',
22
- },
23
- ],
24
- markDefs: [],
25
- style: 'normal',
26
- },
27
- {
28
- _key: 'b',
29
- _type: 'block',
30
- children: [
31
- {
32
- _key: 'b1',
33
- _type: 'span',
34
- marks: [],
35
- text: 'Block B ',
36
- },
37
- {
38
- _key: 'b2',
39
- _type: 'someObject',
40
- },
41
- {
42
- _key: 'b3',
43
- _type: 'span',
44
- marks: [],
45
- text: ' contains a inline object',
46
- },
47
- ],
48
- markDefs: [],
49
- style: 'normal',
50
- },
51
- ]
52
-
53
- describe('plugin:withEditableAPI: .getFragment()', () => {
54
- it('can get a Portable Text fragment of the current selection in a single block', async () => {
55
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
56
- const onChange = vi.fn()
57
-
58
- render(
59
- <PortableTextEditorTester
60
- keyGenerator={createTestKeyGenerator()}
61
- onChange={onChange}
62
- ref={editorRef}
63
- value={initialValue}
64
- />,
65
- )
66
- const initialSelection = {
67
- focus: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 6},
68
- anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 7},
69
- }
70
-
71
- await waitFor(() => {
72
- if (editorRef.current) {
73
- expect(onChange).toHaveBeenCalledWith({
74
- type: 'value',
75
- value: initialValue,
76
- })
77
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
78
- }
79
- })
80
-
81
- await waitFor(() => {
82
- if (editorRef.current) {
83
- PortableTextEditor.focus(editorRef.current)
84
- PortableTextEditor.select(editorRef.current, initialSelection)
85
- const fragment = PortableTextEditor.getFragment(editorRef.current)
86
- expect(
87
- fragment &&
88
- isTextBlock(
89
- {
90
- schema: compileSchema(schemaDefinition),
91
- },
92
- fragment[0],
93
- ) &&
94
- fragment[0]?.children[0]?.text,
95
- ).toBe('A')
96
- }
97
- })
98
- })
99
-
100
- it('can get a Portable Text fragment of the current selection in multiple blocks', async () => {
101
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
102
- const onChange = vi.fn()
103
-
104
- render(
105
- <PortableTextEditorTester
106
- keyGenerator={createTestKeyGenerator()}
107
- onChange={onChange}
108
- ref={editorRef}
109
- value={initialValue}
110
- />,
111
- )
112
- const initialSelection = {
113
- anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 6},
114
- focus: {path: [{_key: 'b'}, 'children', {_key: 'b3'}], offset: 9},
115
- }
116
-
117
- await waitFor(() => {
118
- if (editorRef.current) {
119
- expect(onChange).toHaveBeenCalledWith({
120
- type: 'value',
121
- value: initialValue,
122
- })
123
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
124
- }
125
- })
126
-
127
- await waitFor(() => {
128
- if (editorRef.current) {
129
- PortableTextEditor.focus(editorRef.current)
130
- PortableTextEditor.select(editorRef.current, initialSelection)
131
- const fragment = PortableTextEditor.getFragment(editorRef.current)
132
- expect(fragment).toMatchInlineSnapshot(`
133
- [
134
- {
135
- "_key": "a",
136
- "_type": "block",
137
- "children": [
138
- {
139
- "_key": "a1",
140
- "_type": "span",
141
- "marks": [],
142
- "text": "A",
143
- },
144
- ],
145
- "markDefs": [],
146
- "style": "normal",
147
- },
148
- {
149
- "_key": "b",
150
- "_type": "block",
151
- "children": [
152
- {
153
- "_key": "b1",
154
- "_type": "span",
155
- "marks": [],
156
- "text": "Block B ",
157
- },
158
- {
159
- "_key": "b2",
160
- "_type": "someObject",
161
- },
162
- {
163
- "_key": "b3",
164
- "_type": "span",
165
- "marks": [],
166
- "text": " contains",
167
- },
168
- ],
169
- "markDefs": [],
170
- "style": "normal",
171
- },
172
- ]
173
- `)
174
- }
175
- })
176
- })
177
- })
@@ -1,538 +0,0 @@
1
- import {createTestKeyGenerator} from '@portabletext/test'
2
- import {render, waitFor} from '@testing-library/react'
3
- import {createRef, type RefObject} from 'react'
4
- import {describe, expect, it, vi} from 'vitest'
5
- import {PortableTextEditorTester} from '../../__tests__/PortableTextEditorTester'
6
- import {PortableTextEditor} from '../../PortableTextEditor'
7
-
8
- const initialValue = [
9
- {
10
- _key: 'a',
11
- _type: 'block',
12
- children: [
13
- {
14
- _key: 'a1',
15
- _type: 'span',
16
- marks: [],
17
- text: 'Block A',
18
- },
19
- ],
20
- markDefs: [],
21
- style: 'normal',
22
- },
23
- ]
24
- const initialSelection = {
25
- focus: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 7},
26
- anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 7},
27
- }
28
-
29
- const emptyTextBlock = [
30
- {
31
- _key: 'emptyBlock',
32
- _type: 'block',
33
- children: [
34
- {
35
- _key: 'emptySpan',
36
- _type: 'span',
37
- marks: [],
38
- text: '',
39
- },
40
- ],
41
- markDefs: [],
42
- style: 'normal',
43
- },
44
- ]
45
- const emptyBlockSelection = {
46
- focus: {
47
- path: [{_key: 'emptyBlock'}, 'children', {_key: 'emptySpan'}],
48
- offset: 0,
49
- },
50
- anchor: {
51
- path: [{_key: 'emptyBlock'}, 'children', {_key: 'emptySpan'}],
52
- offset: 0,
53
- },
54
- }
55
-
56
- describe('plugin:withEditableAPI: .insertChild()', () => {
57
- it('inserts child nodes correctly', async () => {
58
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
59
- const onChange = vi.fn()
60
-
61
- render(
62
- <PortableTextEditorTester
63
- keyGenerator={createTestKeyGenerator()}
64
- onChange={onChange}
65
- ref={editorRef}
66
- value={initialValue}
67
- />,
68
- )
69
-
70
- await waitFor(() => {
71
- if (editorRef.current) {
72
- expect(onChange).toHaveBeenCalledWith({
73
- type: 'value',
74
- value: initialValue,
75
- })
76
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
77
- }
78
- })
79
-
80
- await waitFor(() => {
81
- if (editorRef.current) {
82
- PortableTextEditor.focus(editorRef.current)
83
- PortableTextEditor.select(editorRef.current, initialSelection)
84
- }
85
- })
86
-
87
- await waitFor(() => {
88
- if (editorRef.current) {
89
- const inlineType = editorRef.current.schemaTypes.inlineObjects.find(
90
- (t) => t.name === 'someObject',
91
- )!
92
- PortableTextEditor.insertChild(editorRef.current, inlineType, {
93
- color: 'red',
94
- })
95
- }
96
- })
97
-
98
- await waitFor(() => {
99
- if (editorRef.current) {
100
- expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
101
- {
102
- _key: 'a',
103
- _type: 'block',
104
- children: [
105
- {
106
- _key: 'a1',
107
- _type: 'span',
108
- marks: [],
109
- text: 'Block A',
110
- },
111
- {
112
- _key: 'k2',
113
- _type: 'someObject',
114
- color: 'red',
115
- },
116
- {
117
- _key: 'k4',
118
- _type: 'span',
119
- marks: [],
120
- text: '',
121
- },
122
- ],
123
- markDefs: [],
124
- style: 'normal',
125
- },
126
- ])
127
- }
128
- })
129
-
130
- await waitFor(() => {
131
- if (editorRef.current) {
132
- PortableTextEditor.insertChild(
133
- editorRef.current,
134
- editorRef.current.schemaTypes.span,
135
- {
136
- text: ' ',
137
- },
138
- )
139
- }
140
- })
141
-
142
- await waitFor(() => {
143
- if (editorRef.current) {
144
- expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
145
- {
146
- _key: 'a',
147
- _type: 'block',
148
- children: [
149
- {
150
- _key: 'a1',
151
- _type: 'span',
152
- marks: [],
153
- text: 'Block A',
154
- },
155
- {
156
- _key: 'k2',
157
- _type: 'someObject',
158
- color: 'red',
159
- },
160
- {
161
- _key: 'k6',
162
- _type: 'span',
163
- marks: [],
164
- text: ' ',
165
- },
166
- ],
167
- markDefs: [],
168
- style: 'normal',
169
- },
170
- ])
171
-
172
- expect(PortableTextEditor.getSelection(editorRef.current)).toEqual({
173
- anchor: {path: [{_key: 'a'}, 'children', {_key: 'k6'}], offset: 1},
174
- focus: {path: [{_key: 'a'}, 'children', {_key: 'k6'}], offset: 1},
175
- backward: false,
176
- })
177
- }
178
- })
179
- })
180
- })
181
-
182
- describe('plugin:withEditableAPI: .insertBlock()', () => {
183
- it('should not add empty blank blocks: empty block', async () => {
184
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
185
- const value = [
186
- {
187
- _key: 'emptyBlock',
188
- _type: 'block',
189
- children: [
190
- {
191
- _key: 'emptySpan',
192
- _type: 'span',
193
- marks: [],
194
- text: '',
195
- },
196
- ],
197
- markDefs: [],
198
- style: 'normal',
199
- },
200
- ]
201
- const onChange = vi.fn()
202
-
203
- render(
204
- <PortableTextEditorTester
205
- ref={editorRef}
206
- value={emptyTextBlock}
207
- onChange={onChange}
208
- keyGenerator={createTestKeyGenerator()}
209
- />,
210
- )
211
-
212
- await waitFor(() => {
213
- if (editorRef.current) {
214
- expect(onChange).toHaveBeenCalledWith({type: 'value', value})
215
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
216
- }
217
- })
218
-
219
- await waitFor(() => {
220
- if (editorRef.current) {
221
- PortableTextEditor.focus(editorRef.current)
222
- PortableTextEditor.select(editorRef.current, emptyBlockSelection)
223
- }
224
- })
225
-
226
- await waitFor(() => {
227
- if (editorRef.current) {
228
- PortableTextEditor.insertBlock(
229
- editorRef.current,
230
- {name: 'custom image'},
231
- {
232
- src: 'https://example.com/image.jpg',
233
- },
234
- )
235
- }
236
- })
237
-
238
- await waitFor(() => {
239
- if (editorRef.current) {
240
- expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
241
- {
242
- _key: 'k2',
243
- _type: 'custom image',
244
- src: 'https://example.com/image.jpg',
245
- },
246
- ])
247
- }
248
- })
249
- })
250
-
251
- it('should not add empty blank blocks: non-empty block', async () => {
252
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
253
- const onChange = vi.fn()
254
-
255
- render(
256
- <PortableTextEditorTester
257
- ref={editorRef}
258
- value={initialValue}
259
- onChange={onChange}
260
- keyGenerator={createTestKeyGenerator()}
261
- />,
262
- )
263
-
264
- await waitFor(() => {
265
- if (editorRef.current) {
266
- expect(onChange).toHaveBeenCalledWith({
267
- type: 'value',
268
- value: initialValue,
269
- })
270
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
271
- }
272
- })
273
-
274
- await waitFor(() => {
275
- if (editorRef.current) {
276
- PortableTextEditor.focus(editorRef.current)
277
- PortableTextEditor.select(editorRef.current, initialSelection)
278
- }
279
- })
280
-
281
- await waitFor(() => {
282
- if (editorRef.current) {
283
- PortableTextEditor.insertBlock(
284
- editorRef.current,
285
- {name: 'custom image'},
286
- {
287
- src: 'https://example.com/image.jpg',
288
- },
289
- )
290
- }
291
- })
292
-
293
- await waitFor(() => {
294
- if (editorRef.current) {
295
- expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
296
- ...initialValue,
297
- {
298
- _key: 'k2',
299
- _type: 'custom image',
300
- src: 'https://example.com/image.jpg',
301
- },
302
- ])
303
- }
304
- })
305
- })
306
-
307
- it('should be inserted before if focus is on start of block', async () => {
308
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
309
- const onChange = vi.fn()
310
-
311
- render(
312
- <PortableTextEditorTester
313
- onChange={onChange}
314
- ref={editorRef}
315
- value={initialValue}
316
- keyGenerator={createTestKeyGenerator()}
317
- />,
318
- )
319
-
320
- await waitFor(() => {
321
- if (editorRef.current) {
322
- expect(onChange).toHaveBeenCalledWith({
323
- type: 'value',
324
- value: initialValue,
325
- })
326
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
327
- }
328
- })
329
-
330
- await waitFor(() => {
331
- if (editorRef.current) {
332
- PortableTextEditor.focus(editorRef.current)
333
- PortableTextEditor.select(editorRef.current, {
334
- focus: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 0},
335
- anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 0},
336
- })
337
- }
338
- })
339
-
340
- await waitFor(() => {
341
- if (editorRef.current) {
342
- PortableTextEditor.insertBlock(
343
- editorRef.current,
344
- {name: 'custom image'},
345
- {
346
- src: 'https://example.com/image.jpg',
347
- },
348
- )
349
- }
350
- })
351
-
352
- await waitFor(() => {
353
- if (editorRef.current) {
354
- expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
355
- {
356
- _key: 'k2',
357
- _type: 'custom image',
358
- src: 'https://example.com/image.jpg',
359
- },
360
- ...initialValue,
361
- ])
362
- }
363
- })
364
- })
365
-
366
- it('should not add empty blank blocks: non text block', async () => {
367
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
368
- const value = [
369
- ...initialValue,
370
- {_key: 'b', _type: 'custom image', src: 'https://example.com/image.jpg'},
371
- ]
372
- const onChange = vi.fn()
373
-
374
- render(
375
- <PortableTextEditorTester
376
- ref={editorRef}
377
- value={value}
378
- onChange={onChange}
379
- keyGenerator={createTestKeyGenerator()}
380
- />,
381
- )
382
-
383
- await waitFor(() => {
384
- if (editorRef.current) {
385
- expect(onChange).toHaveBeenCalledWith({type: 'value', value})
386
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
387
- }
388
- })
389
-
390
- await waitFor(() => {
391
- if (editorRef.current) {
392
- PortableTextEditor.focus(editorRef.current)
393
- // Focus the `custom image` block
394
- PortableTextEditor.select(editorRef.current, {
395
- focus: {path: [{_key: 'b'}], offset: 0},
396
- anchor: {path: [{_key: 'b'}], offset: 0},
397
- })
398
- }
399
- })
400
-
401
- await waitFor(() => {
402
- if (editorRef.current) {
403
- PortableTextEditor.insertBlock(
404
- editorRef.current,
405
- {name: 'custom image'},
406
- {
407
- src: 'https://example.com/image2.jpg',
408
- },
409
- )
410
- }
411
- })
412
-
413
- await waitFor(() => {
414
- if (editorRef.current) {
415
- expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
416
- ...value,
417
- {
418
- _key: 'k2',
419
- _type: 'custom image',
420
- src: 'https://example.com/image2.jpg',
421
- },
422
- ])
423
- }
424
- })
425
- })
426
-
427
- it('should not add empty blank blocks: in between blocks', async () => {
428
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
429
- const value = [
430
- ...initialValue,
431
- {_key: 'b', _type: 'custom image', src: 'https://example.com/image.jpg'},
432
- ]
433
- const onChange = vi.fn()
434
-
435
- render(
436
- <PortableTextEditorTester
437
- ref={editorRef}
438
- value={value}
439
- onChange={onChange}
440
- keyGenerator={createTestKeyGenerator()}
441
- />,
442
- )
443
-
444
- await waitFor(() => {
445
- if (editorRef.current) {
446
- expect(onChange).toHaveBeenCalledWith({type: 'value', value})
447
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
448
- }
449
- })
450
-
451
- await waitFor(() => {
452
- if (editorRef.current) {
453
- PortableTextEditor.focus(editorRef.current)
454
- // Focus the `text` block
455
- PortableTextEditor.select(editorRef.current, initialSelection)
456
- }
457
- })
458
-
459
- await waitFor(() => {
460
- if (editorRef.current) {
461
- PortableTextEditor.insertBlock(
462
- editorRef.current,
463
- {name: 'custom image'},
464
- {
465
- src: 'https://example.com/image2.jpg',
466
- },
467
- )
468
- }
469
- })
470
-
471
- await waitFor(() => {
472
- if (editorRef.current) {
473
- expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
474
- value[0],
475
- {
476
- _key: 'k2',
477
- _type: 'custom image',
478
- src: 'https://example.com/image2.jpg',
479
- },
480
- value[1],
481
- ])
482
- }
483
- })
484
- })
485
-
486
- it('should not add empty blank blocks: in new empty text block', async () => {
487
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
488
- const value = [...initialValue, ...emptyTextBlock]
489
- const onChange = vi.fn()
490
-
491
- render(
492
- <PortableTextEditorTester
493
- ref={editorRef}
494
- value={value}
495
- onChange={onChange}
496
- keyGenerator={createTestKeyGenerator()}
497
- />,
498
- )
499
-
500
- await waitFor(() => {
501
- if (editorRef.current) {
502
- expect(onChange).toHaveBeenCalledWith({type: 'value', value})
503
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
504
- }
505
- })
506
-
507
- await waitFor(() => {
508
- if (editorRef.current) {
509
- PortableTextEditor.select(editorRef.current, emptyBlockSelection)
510
- }
511
- })
512
-
513
- await waitFor(() => {
514
- if (editorRef.current) {
515
- PortableTextEditor.insertBlock(
516
- editorRef.current,
517
- {name: 'custom image'},
518
- {
519
- src: 'https://example.com/image.jpg',
520
- },
521
- )
522
- }
523
- })
524
-
525
- await waitFor(() => {
526
- if (editorRef.current) {
527
- expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
528
- value[0],
529
- {
530
- _key: 'k2',
531
- _type: 'custom image',
532
- src: 'https://example.com/image.jpg',
533
- },
534
- ])
535
- }
536
- })
537
- })
538
- })