@capillarytech/creatives-library 8.0.330-alpha.0 → 8.0.330
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/constants/unified.js +0 -18
- package/package.json +1 -1
- package/services/api.js +0 -17
- package/services/tests/api.test.js +0 -85
- package/utils/commonUtils.js +0 -28
- package/utils/tests/commonUtil.test.js +0 -169
- package/v2Components/CapTagList/index.js +0 -10
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -70
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +53 -87
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +1 -20
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +34 -145
- package/v2Components/CommonTestAndPreview/actions.js +0 -10
- package/v2Components/CommonTestAndPreview/constants.js +1 -53
- package/v2Components/CommonTestAndPreview/index.js +168 -998
- package/v2Components/CommonTestAndPreview/messages.js +3 -147
- package/v2Components/CommonTestAndPreview/reducer.js +0 -10
- package/v2Components/CommonTestAndPreview/sagas.js +6 -15
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +286 -328
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +24 -65
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
- package/v2Components/CommonTestAndPreview/tests/constants.test.js +1 -31
- package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -168
- package/v2Components/CommonTestAndPreview/tests/reducer.test.js +0 -71
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
- package/v2Components/CommonTestAndPreview/tests/selectors.test.js +0 -17
- package/v2Components/FormBuilder/index.js +1 -7
- package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
- package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
- package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -10
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
- package/v2Containers/CreativesContainer/constants.js +0 -9
- package/v2Containers/CreativesContainer/index.js +93 -292
- package/v2Containers/CreativesContainer/index.scss +1 -51
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +98 -357
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +10 -20
- package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
- package/v2Containers/Rcs/constants.js +3 -40
- package/v2Containers/Rcs/index.js +895 -1145
- package/v2Containers/Rcs/index.scss +6 -85
- package/v2Containers/Rcs/messages.js +2 -12
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +2236 -41719
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
- package/v2Containers/Rcs/tests/index.test.js +38 -41
- package/v2Containers/Rcs/tests/mockData.js +0 -38
- package/v2Containers/Rcs/tests/utils.test.js +1 -435
- package/v2Containers/Rcs/utils.js +10 -405
- package/v2Containers/Sms/Create/index.js +38 -100
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +128 -636
- package/v2Containers/SmsTrai/Edit/messages.js +4 -14
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2604 -4590
- package/v2Containers/SmsWrapper/index.js +8 -37
- package/v2Containers/TagList/index.js +0 -6
- package/v2Containers/Templates/_templates.scss +2 -63
- package/v2Containers/Templates/actions.js +0 -11
- package/v2Containers/Templates/constants.js +0 -2
- package/v2Containers/Templates/index.js +40 -90
- package/v2Containers/Templates/sagas.js +12 -57
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1079 -1043
- package/v2Containers/Templates/tests/sagas.test.js +123 -193
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
- package/v2Containers/TemplatesV2/index.js +23 -86
- package/v2Containers/Whatsapp/index.js +20 -3
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +4872 -5790
- package/utils/templateVarUtils.js +0 -201
- package/utils/tests/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/AddTestCustomer.js +0 -42
- package/v2Components/CommonTestAndPreview/CustomerCreationModal.js +0 -155
- package/v2Components/CommonTestAndPreview/ExistingCustomerModal.js +0 -93
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/AddTestCustomer.test.js +0 -66
- package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +0 -648
- package/v2Components/CommonTestAndPreview/tests/CustomerCreationModal.test.js +0 -174
- package/v2Components/CommonTestAndPreview/tests/ExistingCustomerModal.test.js +0 -114
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -87
- package/v2Components/SmsFallback/constants.js +0 -73
- package/v2Components/SmsFallback/index.js +0 -955
- package/v2Components/SmsFallback/index.scss +0 -265
- package/v2Components/SmsFallback/messages.js +0 -78
- package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -197
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
- package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
- package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/index.js +0 -125
- package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -43
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -67
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
- package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
- package/v2Containers/SmsTrai/Edit/index.scss +0 -121
- package/v2Containers/Templates/TemplatesActionBar.js +0 -101
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
|
@@ -301,6 +301,11 @@ exports[`RCS utils getRCSContent renders RCS content with no media 1`] = `
|
|
|
301
301
|
<div
|
|
302
302
|
className="cap-rcs-creatives"
|
|
303
303
|
>
|
|
304
|
+
<div
|
|
305
|
+
className="CapLabel-n7zsf5-0 gtGqsG rcs-listing-content title"
|
|
306
|
+
fontWeight="bold"
|
|
307
|
+
type="label19"
|
|
308
|
+
/>
|
|
304
309
|
<div
|
|
305
310
|
className="CapLabel-n7zsf5-0 ekUKMg rcs-listing-content desc"
|
|
306
311
|
type="label19"
|
|
@@ -15,14 +15,6 @@ import CapActionButton from '../../../v2Components/CapActionButton';
|
|
|
15
15
|
import { INITIAL_SUGGESTIONS_DATA_STOP } from '../constants';
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
jest.mock('react-redux', () => {
|
|
19
|
-
const actual = jest.requireActual('react-redux');
|
|
20
|
-
return {
|
|
21
|
-
...actual,
|
|
22
|
-
useDispatch: jest.fn(() => jest.fn()),
|
|
23
|
-
};
|
|
24
|
-
});
|
|
25
|
-
|
|
26
18
|
jest.mock('../../../v2Containers/TagList/index.js', () => ({
|
|
27
19
|
__esModule: true,
|
|
28
20
|
default: (props) => (
|
|
@@ -150,7 +142,7 @@ const renderHelper = (args) => {
|
|
|
150
142
|
isEditFlow={args.isEditFlow || false}
|
|
151
143
|
loadingTags={false}
|
|
152
144
|
metaEntities={[]}
|
|
153
|
-
|
|
145
|
+
getDefaultTags
|
|
154
146
|
isDltEnabled={args.isDltEnabled || false}
|
|
155
147
|
smsRegister={'DLT'}
|
|
156
148
|
/>
|
|
@@ -453,8 +445,8 @@ describe('Creatives rcs test/>', () => {
|
|
|
453
445
|
});
|
|
454
446
|
|
|
455
447
|
it('should call fetchSchemaForEntity when TagList context changes (non-full mode)', () => {
|
|
456
|
-
//
|
|
457
|
-
renderHelper({ isFullMode: false
|
|
448
|
+
// Re-render in non-full mode so TagList is visible
|
|
449
|
+
renderHelper({ isFullMode: false });
|
|
458
450
|
const tagList = renderedComponent.find('.tag-mock').at(0);
|
|
459
451
|
expect(tagList.exists()).toBe(true);
|
|
460
452
|
const before = fetchSchemaForEntity.mock.calls.length;
|
|
@@ -462,7 +454,7 @@ describe('Creatives rcs test/>', () => {
|
|
|
462
454
|
tagList.prop('onContextChange')('ALL');
|
|
463
455
|
});
|
|
464
456
|
const after = fetchSchemaForEntity.mock.calls.length;
|
|
465
|
-
expect(after).
|
|
457
|
+
expect(after).toBe(before + 1);
|
|
466
458
|
const lastArg = fetchSchemaForEntity.mock.calls[after - 1][0];
|
|
467
459
|
expect(lastArg).toEqual(expect.objectContaining({ layout: 'SMS', type: 'TAG', context: 'default' }));
|
|
468
460
|
});
|
|
@@ -638,16 +630,15 @@ describe('RCS createPayload', () => {
|
|
|
638
630
|
expect(payloadArg.versions.base.content.RCS.rcsContent.accessToken).toBe('secret-token');
|
|
639
631
|
expect(payloadArg.versions.base.content.RCS.rcsContent.hostName).toBe('rcs.host.example.com');
|
|
640
632
|
expect(payloadArg.versions.base.content.RCS.rcsContent.accountName).toBe('Brand RCS Account');
|
|
641
|
-
// templateType effect (text_message → rich_card) can reset selectedDimension after hydration on first mount;
|
|
642
|
-
// payload cardSettings follow `selectedDimension` state (see Rcs createPayload).
|
|
643
633
|
expect(payloadArg.versions.base.content.RCS.rcsContent.cardSettings).toEqual(
|
|
644
|
-
expect.objectContaining({ cardOrientation: '
|
|
634
|
+
expect.objectContaining({ cardOrientation: 'HORIZONTAL', mediaAlignment: 'LEFT', cardWidth: 'SMALL' }),
|
|
645
635
|
);
|
|
646
|
-
|
|
647
|
-
expect(card.
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
636
|
+
expect(card.mediaType).toBe('IMAGE');
|
|
637
|
+
expect(card.media).toEqual(expect.objectContaining({ mediaUrl: 'https://cdn.example.com/img.png' }));
|
|
638
|
+
expect(payloadArg.versions.base.content.RCS.smsFallBackContent).toEqual(
|
|
639
|
+
expect.objectContaining({ message: '' }),
|
|
640
|
+
);
|
|
641
|
+
});
|
|
651
642
|
|
|
652
643
|
it('should include empty account metadata when no account is selected', async () => {
|
|
653
644
|
const createRcsTemplate = jest.fn();
|
|
@@ -713,7 +704,7 @@ describe('RCS createPayload', () => {
|
|
|
713
704
|
expect(rcsContent.accountName).toBe('');
|
|
714
705
|
});
|
|
715
706
|
|
|
716
|
-
it('
|
|
707
|
+
it('should attach DLT template configs when enabled', async () => {
|
|
717
708
|
const createRcsTemplate = jest.fn();
|
|
718
709
|
const getFormData = jest.fn();
|
|
719
710
|
const { createPayloadFullMode } = mockData;
|
|
@@ -766,7 +757,16 @@ describe('RCS createPayload', () => {
|
|
|
766
757
|
createRcsTemplate.mock.calls[0]?.[0] ||
|
|
767
758
|
getFormData.mock.calls[0]?.[0]?.value;
|
|
768
759
|
expect(payloadArg).toBeDefined();
|
|
769
|
-
expect(payloadArg.versions.base.content.RCS.smsFallBackContent).
|
|
760
|
+
expect(payloadArg.versions.base.content.RCS.smsFallBackContent).toEqual(
|
|
761
|
+
expect.objectContaining({
|
|
762
|
+
templateConfigs: expect.objectContaining({
|
|
763
|
+
templateId: '',
|
|
764
|
+
templateName: '',
|
|
765
|
+
template: '',
|
|
766
|
+
registeredSenderIds: [],
|
|
767
|
+
}),
|
|
768
|
+
}),
|
|
769
|
+
);
|
|
770
770
|
});
|
|
771
771
|
|
|
772
772
|
it('should build expected payload in non-full mode (VIDEO, vertical medium)', () => {
|
|
@@ -818,7 +818,7 @@ describe('RCS createPayload', () => {
|
|
|
818
818
|
expect(payloadArg.type).toBe('RCS');
|
|
819
819
|
expect(payloadArg.versions.base.content.RCS.rcsContent.contentType).toBe('RICHCARD');
|
|
820
820
|
expect(payloadArg.versions.base.content.RCS.rcsContent.cardSettings).toEqual(
|
|
821
|
-
expect.objectContaining({ cardOrientation: 'VERTICAL', cardWidth: '
|
|
821
|
+
expect.objectContaining({ cardOrientation: 'VERTICAL', cardWidth: 'SMALL' }),
|
|
822
822
|
);
|
|
823
823
|
expect(card.mediaType).toBe('VIDEO');
|
|
824
824
|
expect(card.media).toEqual(
|
|
@@ -843,9 +843,7 @@ describe('RCS createPayload', () => {
|
|
|
843
843
|
// same placeholder appears twice
|
|
844
844
|
title: 'Hello {{user_name}} and {{user_name}}',
|
|
845
845
|
description: 'Hi {{user_name}}',
|
|
846
|
-
|
|
847
|
-
mediaType: 'IMAGE',
|
|
848
|
-
media: { mediaUrl: 'https://cdn.example.com/card.png' },
|
|
846
|
+
mediaType: 'NONE',
|
|
849
847
|
cardVarMapped: {}, // empty on load
|
|
850
848
|
suggestions: [],
|
|
851
849
|
},
|
|
@@ -913,8 +911,6 @@ describe('RCS createPayload', () => {
|
|
|
913
911
|
});
|
|
914
912
|
|
|
915
913
|
it('should insert TagList label into focused placeholder and sync duplicates in non-full mode', () => {
|
|
916
|
-
// One title slot so numeric slot key + semantic user_name stay aligned (duplicate {{user_name}} would
|
|
917
|
-
// leave other slots on empty "2","3",… keys from hydration).
|
|
918
914
|
const templateData = {
|
|
919
915
|
name: 'DupVarsTemplate2',
|
|
920
916
|
versions: {
|
|
@@ -926,11 +922,9 @@ describe('RCS createPayload', () => {
|
|
|
926
922
|
cardSettings: { cardOrientation: 'VERTICAL', cardWidth: 'SMALL' },
|
|
927
923
|
cardContent: [
|
|
928
924
|
{
|
|
929
|
-
title: 'Hello {{user_name}}',
|
|
930
|
-
description: 'Hi',
|
|
931
|
-
|
|
932
|
-
mediaType: 'IMAGE',
|
|
933
|
-
media: { mediaUrl: 'https://cdn.example.com/card.png' },
|
|
925
|
+
title: 'Hello {{user_name}} and {{user_name}}',
|
|
926
|
+
description: 'Hi {{user_name}}',
|
|
927
|
+
mediaType: 'NONE',
|
|
934
928
|
cardVarMapped: {},
|
|
935
929
|
suggestions: [],
|
|
936
930
|
},
|
|
@@ -978,12 +972,12 @@ describe('RCS createPayload', () => {
|
|
|
978
972
|
const id = n.prop('id') || '';
|
|
979
973
|
return id.includes('{{user_name}}_');
|
|
980
974
|
});
|
|
981
|
-
expect(titleVarAreas.length).toBeGreaterThanOrEqual(
|
|
975
|
+
expect(titleVarAreas.length).toBeGreaterThanOrEqual(2);
|
|
982
976
|
|
|
983
|
-
//
|
|
977
|
+
// Focus the first variable textarea so TagList knows where to insert
|
|
984
978
|
act(() => {
|
|
985
979
|
const id = titleVarAreas.at(0).prop('id');
|
|
986
|
-
titleVarAreas.at(0).props().onFocus(id);
|
|
980
|
+
titleVarAreas.at(0).props().onFocus({ target: { id } });
|
|
987
981
|
});
|
|
988
982
|
wrapper.update();
|
|
989
983
|
|
|
@@ -999,6 +993,7 @@ describe('RCS createPayload', () => {
|
|
|
999
993
|
return id.includes('{{user_name}}_');
|
|
1000
994
|
});
|
|
1001
995
|
expect(updatedTitleVarAreas.at(0).prop('value')).toBe('{{first_name}}');
|
|
996
|
+
expect(updatedTitleVarAreas.at(1).prop('value')).toBe('{{first_name}}');
|
|
1002
997
|
});
|
|
1003
998
|
|
|
1004
999
|
it('should keep two tags + freetext inside the variable textarea in non-full mode edit (not merged into static text)', () => {
|
|
@@ -1066,11 +1061,13 @@ describe('RCS createPayload', () => {
|
|
|
1066
1061
|
|
|
1067
1062
|
wrapper.update();
|
|
1068
1063
|
|
|
1069
|
-
//
|
|
1070
|
-
const
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1064
|
+
// The placeholder {{service_type}} should exist as a variable textarea id, and its value should be the mixed string.
|
|
1065
|
+
const serviceTypeAreas = wrapper.find('TextArea').filterWhere((n) => {
|
|
1066
|
+
const id = n.prop('id') || '';
|
|
1067
|
+
return id.includes('{{service_type}}_');
|
|
1068
|
+
});
|
|
1069
|
+
expect(serviceTypeAreas.length).toBeGreaterThanOrEqual(1);
|
|
1070
|
+
expect(serviceTypeAreas.at(0).prop('value')).toBe('{{first_name}}{{adv}}freeText');
|
|
1074
1071
|
|
|
1075
1072
|
// Ensure freetext does NOT leak into static text blocks.
|
|
1076
1073
|
const staticAreas = wrapper.find('TextArea').filterWhere((n) => !!n.prop('disabled'));
|
|
@@ -148,7 +148,6 @@ export const mockData = {
|
|
|
148
148
|
},
|
|
149
149
|
accountData: {
|
|
150
150
|
selectedRcsAccount: {
|
|
151
|
-
id: 'we-crm-account-id-42',
|
|
152
151
|
sourceAccountIdentifier: 'rcs-account-123',
|
|
153
152
|
configs: { accessToken: 'secret-token' },
|
|
154
153
|
hostName: 'rcs.host.example.com',
|
|
@@ -286,41 +285,4 @@ export const mockData = {
|
|
|
286
285
|
},
|
|
287
286
|
},
|
|
288
287
|
},
|
|
289
|
-
// RCS template with SMS fallback for edit-flow tests
|
|
290
|
-
rcsTemplateWithSmsFallback: {
|
|
291
|
-
templateDetails: {
|
|
292
|
-
_id: 'rcs_with_fallback_1',
|
|
293
|
-
name: 'RCSWithFallback',
|
|
294
|
-
type: 'RCS',
|
|
295
|
-
versions: {
|
|
296
|
-
base: {
|
|
297
|
-
content: {
|
|
298
|
-
RCS: {
|
|
299
|
-
rcsContent: {
|
|
300
|
-
cardSettings: { cardOrientation: 'VERTICAL' },
|
|
301
|
-
cardContent: [
|
|
302
|
-
{
|
|
303
|
-
description: 'RCS description',
|
|
304
|
-
mediaType: 'TEXT',
|
|
305
|
-
suggestions: [],
|
|
306
|
-
},
|
|
307
|
-
],
|
|
308
|
-
contentType: 'text_message',
|
|
309
|
-
},
|
|
310
|
-
smsFallBackContent: {
|
|
311
|
-
smsTemplateId: 'sms_fb_001',
|
|
312
|
-
smsTemplateName: 'Fallback Template',
|
|
313
|
-
smsContent: 'SMS fallback message',
|
|
314
|
-
message: 'SMS fallback message',
|
|
315
|
-
smsTemplateContent: 'SMS fallback message',
|
|
316
|
-
smsVariables: [],
|
|
317
|
-
smsVarMapped: {},
|
|
318
|
-
smsUnicodeValidity: true,
|
|
319
|
-
},
|
|
320
|
-
},
|
|
321
|
-
},
|
|
322
|
-
},
|
|
323
|
-
},
|
|
324
|
-
},
|
|
325
|
-
},
|
|
326
288
|
};
|