@reactionary/commercetools 0.6.6 → 0.6.8
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/capabilities/company-registration.capability.js +137 -0
- package/capabilities/company.capability.js +306 -0
- package/capabilities/employee-invitation.capability.js +398 -0
- package/capabilities/employee.capability.js +346 -0
- package/capabilities/index.js +3 -0
- package/capabilities/profile.capability.js +10 -0
- package/core/capability-descriptors.js +65 -1
- package/core/client.js +2 -2
- package/factories/checkout/checkout.factory.js +6 -1
- package/factories/company/company.factory.js +80 -0
- package/factories/company-registration/company-registration.factory.js +36 -0
- package/factories/employee/employee.factory.js +61 -0
- package/factories/employee-invitation/employee-invitation.factory.js +61 -0
- package/index.js +8 -0
- package/package.json +2 -2
- package/schema/capabilities.schema.js +4 -0
- package/schema/commercetools.schema.js +18 -1
- package/src/capabilities/company-registration.capability.d.ts +21 -0
- package/src/capabilities/company.capability.d.ts +30 -0
- package/src/capabilities/employee-invitation.capability.d.ts +34 -0
- package/src/capabilities/employee.capability.d.ts +33 -0
- package/src/capabilities/index.d.ts +3 -0
- package/src/core/capability-descriptors.d.ts +1 -1
- package/src/core/initialize.types.d.ts +20 -0
- package/src/factories/company/company.factory.d.ts +25 -0
- package/src/factories/company-registration/company-registration.factory.d.ts +25 -0
- package/src/factories/employee/employee.factory.d.ts +22 -0
- package/src/factories/employee-invitation/employee-invitation.factory.d.ts +94 -0
- package/src/index.d.ts +8 -0
- package/src/schema/capabilities.schema.d.ts +24 -1
- package/src/schema/commercetools.schema.d.ts +57 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result)
|
|
9
|
+
__defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
import {
|
|
13
|
+
error,
|
|
14
|
+
CompanyRegistrationCapability,
|
|
15
|
+
CompanyRegistrationMutationRegisterSchema,
|
|
16
|
+
CompanyRegistrationQueryCheckRegistrationStatusSchema,
|
|
17
|
+
CompanyRegistrationRequestSchema,
|
|
18
|
+
Reactionary,
|
|
19
|
+
success
|
|
20
|
+
} from "@reactionary/core";
|
|
21
|
+
class CommercetoolsCompanyRegistrationCapability extends CompanyRegistrationCapability {
|
|
22
|
+
config;
|
|
23
|
+
commercetools;
|
|
24
|
+
factory;
|
|
25
|
+
constructor(config, cache, context, commercetools, factory) {
|
|
26
|
+
super(cache, context);
|
|
27
|
+
this.config = config;
|
|
28
|
+
this.commercetools = commercetools;
|
|
29
|
+
this.factory = factory;
|
|
30
|
+
}
|
|
31
|
+
async getClient() {
|
|
32
|
+
const client = await this.commercetools.getClient();
|
|
33
|
+
return client.withProjectKey({ projectKey: this.config.projectKey }).me();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Extension point.
|
|
37
|
+
* @param payload
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
40
|
+
requestRegistrationPayload(payload) {
|
|
41
|
+
const draft = {
|
|
42
|
+
unitType: "Company",
|
|
43
|
+
key: payload.taxIdentifier,
|
|
44
|
+
name: payload.name,
|
|
45
|
+
contactEmail: payload.pointOfContact.email,
|
|
46
|
+
addresses: [
|
|
47
|
+
{
|
|
48
|
+
key: payload.billingAddress.identifier.nickName,
|
|
49
|
+
country: payload.billingAddress.countryCode,
|
|
50
|
+
city: payload.billingAddress.city,
|
|
51
|
+
streetName: payload.billingAddress.streetAddress,
|
|
52
|
+
streetNumber: payload.billingAddress.streetNumber,
|
|
53
|
+
postalCode: payload.billingAddress.postalCode,
|
|
54
|
+
firstName: payload.billingAddress.firstName,
|
|
55
|
+
lastName: payload.billingAddress.lastName,
|
|
56
|
+
region: payload.billingAddress.region
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
key: "default-shipping-address",
|
|
60
|
+
country: payload.billingAddress.countryCode,
|
|
61
|
+
firstName: payload.billingAddress.firstName,
|
|
62
|
+
lastName: payload.billingAddress.lastName,
|
|
63
|
+
city: payload.billingAddress.city,
|
|
64
|
+
streetName: payload.billingAddress.streetAddress,
|
|
65
|
+
streetNumber: payload.billingAddress.streetNumber,
|
|
66
|
+
postalCode: payload.billingAddress.postalCode,
|
|
67
|
+
region: payload.billingAddress.region
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
billingAddresses: [0],
|
|
71
|
+
shippingAddresses: [1],
|
|
72
|
+
defaultBillingAddress: 0,
|
|
73
|
+
defaultShippingAddress: 1,
|
|
74
|
+
custom: {
|
|
75
|
+
type: {
|
|
76
|
+
key: "reactionaryOrganizationEntityRegistrationRequest",
|
|
77
|
+
typeId: "type"
|
|
78
|
+
},
|
|
79
|
+
fields: {
|
|
80
|
+
dunsIdentifier: payload.dunsIdentifier,
|
|
81
|
+
tinIdentifier: payload.tinIdentifier,
|
|
82
|
+
pointOfContactPhone: payload.pointOfContact.phone
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
return draft;
|
|
87
|
+
}
|
|
88
|
+
async requestRegistration(payload) {
|
|
89
|
+
const client = await this.getClient();
|
|
90
|
+
if ("Registered" !== this.context.session.identityContext.identity.type) {
|
|
91
|
+
return error({
|
|
92
|
+
type: "Generic",
|
|
93
|
+
message: "Only registered users can request company registration"
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const draft = this.requestRegistrationPayload(payload);
|
|
97
|
+
const response = await client.businessUnits().post({ body: draft }).execute();
|
|
98
|
+
return success(this.factory.parseCompanyRegistrationRequest(this.context, response.body));
|
|
99
|
+
}
|
|
100
|
+
async checkRequestStatus(payload) {
|
|
101
|
+
const client = await this.getClient();
|
|
102
|
+
if ("Registered" !== this.context.session.identityContext.identity.type) {
|
|
103
|
+
return error({
|
|
104
|
+
type: "Generic",
|
|
105
|
+
message: "Only registered users can check company registration status"
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const response = await client.businessUnits().withId({ ID: payload.requestIdentifier.key }).get().execute().catch((error2) => {
|
|
109
|
+
if (error2?.statusCode === 404) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
throw error2;
|
|
113
|
+
});
|
|
114
|
+
if (!response) {
|
|
115
|
+
return error({
|
|
116
|
+
type: "NotFound",
|
|
117
|
+
identifier: payload.requestIdentifier
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return success(this.factory.parseCompanyRegistrationRequest(this.context, response.body));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
__decorateClass([
|
|
124
|
+
Reactionary({
|
|
125
|
+
inputSchema: CompanyRegistrationMutationRegisterSchema,
|
|
126
|
+
outputSchema: CompanyRegistrationRequestSchema
|
|
127
|
+
})
|
|
128
|
+
], CommercetoolsCompanyRegistrationCapability.prototype, "requestRegistration", 1);
|
|
129
|
+
__decorateClass([
|
|
130
|
+
Reactionary({
|
|
131
|
+
inputSchema: CompanyRegistrationQueryCheckRegistrationStatusSchema,
|
|
132
|
+
outputSchema: CompanyRegistrationRequestSchema
|
|
133
|
+
})
|
|
134
|
+
], CommercetoolsCompanyRegistrationCapability.prototype, "checkRequestStatus", 1);
|
|
135
|
+
export {
|
|
136
|
+
CommercetoolsCompanyRegistrationCapability
|
|
137
|
+
};
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result)
|
|
9
|
+
__defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
import {
|
|
13
|
+
CompanyCapability,
|
|
14
|
+
CompanySchema,
|
|
15
|
+
CompanyQueryByIdSchema,
|
|
16
|
+
CompanyMutationAddShippingAddressSchema,
|
|
17
|
+
CompanyMutationUpdateShippingAddressSchema,
|
|
18
|
+
CompanyMutationRemoveShippingAddressSchema,
|
|
19
|
+
CompanyMutationMakeShippingAddressDefaultSchema,
|
|
20
|
+
Reactionary,
|
|
21
|
+
success,
|
|
22
|
+
error,
|
|
23
|
+
CompanyQueryListSchema,
|
|
24
|
+
CompanyPaginatedListSchema
|
|
25
|
+
} from "@reactionary/core";
|
|
26
|
+
class CommercetoolsCompanyCapability extends CompanyCapability {
|
|
27
|
+
config;
|
|
28
|
+
commercetools;
|
|
29
|
+
factory;
|
|
30
|
+
constructor(config, cache, context, commercetools, factory) {
|
|
31
|
+
super(cache, context);
|
|
32
|
+
this.config = config;
|
|
33
|
+
this.commercetools = commercetools;
|
|
34
|
+
this.factory = factory;
|
|
35
|
+
}
|
|
36
|
+
async getClient() {
|
|
37
|
+
const client = await this.commercetools.getClient();
|
|
38
|
+
return client.withProjectKey({ projectKey: this.config.projectKey }).me();
|
|
39
|
+
}
|
|
40
|
+
createCTAddressDraft(address) {
|
|
41
|
+
return {
|
|
42
|
+
key: address.identifier.nickName,
|
|
43
|
+
firstName: address.firstName,
|
|
44
|
+
lastName: address.lastName,
|
|
45
|
+
streetName: address.streetAddress,
|
|
46
|
+
streetNumber: address.streetNumber,
|
|
47
|
+
postalCode: address.postalCode,
|
|
48
|
+
city: address.city,
|
|
49
|
+
region: address.region,
|
|
50
|
+
country: address.countryCode || this.context.taxJurisdiction.countryCode
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async getBusinessUnit(key) {
|
|
54
|
+
const client = await this.getClient();
|
|
55
|
+
const response = await client.businessUnits().withKey({ key }).get().execute().catch((err) => {
|
|
56
|
+
if (err.statusCode === 404) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
throw err;
|
|
60
|
+
});
|
|
61
|
+
return response ? response.body : null;
|
|
62
|
+
}
|
|
63
|
+
async updateBusinessUnit(key, version, actions) {
|
|
64
|
+
const client = await this.getClient();
|
|
65
|
+
const response = await client.businessUnits().withKey({ key }).post({
|
|
66
|
+
body: {
|
|
67
|
+
version,
|
|
68
|
+
actions
|
|
69
|
+
}
|
|
70
|
+
}).execute();
|
|
71
|
+
return response.body;
|
|
72
|
+
}
|
|
73
|
+
async getById(payload) {
|
|
74
|
+
const businessUnit = await this.getBusinessUnit(
|
|
75
|
+
payload.identifier.taxIdentifier
|
|
76
|
+
);
|
|
77
|
+
if (!businessUnit) {
|
|
78
|
+
return error({
|
|
79
|
+
type: "NotFound",
|
|
80
|
+
identifier: payload.identifier
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return success(
|
|
84
|
+
this.factory.parseCompany(this.context, businessUnit)
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
addShippingAddressPayload(payload) {
|
|
88
|
+
return [
|
|
89
|
+
{
|
|
90
|
+
action: "addAddress",
|
|
91
|
+
address: this.createCTAddressDraft(payload.address)
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
action: "addShippingAddressId",
|
|
95
|
+
addressKey: payload.address.identifier.nickName
|
|
96
|
+
}
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
async addShippingAddress(payload) {
|
|
100
|
+
const key = payload.company.taxIdentifier;
|
|
101
|
+
const businessUnit = await this.getBusinessUnit(key);
|
|
102
|
+
if (!businessUnit) {
|
|
103
|
+
return error({
|
|
104
|
+
type: "NotFound",
|
|
105
|
+
identifier: payload.company
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const actions = this.addShippingAddressPayload(payload);
|
|
109
|
+
const updated = await this.updateBusinessUnit(
|
|
110
|
+
key,
|
|
111
|
+
businessUnit.version,
|
|
112
|
+
actions
|
|
113
|
+
);
|
|
114
|
+
return success(
|
|
115
|
+
this.factory.parseCompany(this.context, updated)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
updateShippingAddressPayload(payload, businessUnit) {
|
|
119
|
+
const targetAddress = businessUnit.addresses.find(
|
|
120
|
+
(addr) => addr.key === payload.address.identifier.nickName
|
|
121
|
+
);
|
|
122
|
+
if (!targetAddress) {
|
|
123
|
+
return void 0;
|
|
124
|
+
}
|
|
125
|
+
return [
|
|
126
|
+
{
|
|
127
|
+
action: "changeAddress",
|
|
128
|
+
addressId: targetAddress.id,
|
|
129
|
+
address: this.createCTAddressDraft(payload.address)
|
|
130
|
+
}
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
async updateShippingAddress(payload) {
|
|
134
|
+
const key = payload.company.taxIdentifier;
|
|
135
|
+
const businessUnit = await this.getBusinessUnit(key);
|
|
136
|
+
if (!businessUnit) {
|
|
137
|
+
return error({
|
|
138
|
+
type: "NotFound",
|
|
139
|
+
identifier: payload.company
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const actions = this.updateShippingAddressPayload(payload, businessUnit);
|
|
143
|
+
if (!actions) {
|
|
144
|
+
return error({
|
|
145
|
+
type: "NotFound",
|
|
146
|
+
identifier: payload.address.identifier
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
const updated = await this.updateBusinessUnit(
|
|
150
|
+
key,
|
|
151
|
+
businessUnit.version,
|
|
152
|
+
actions
|
|
153
|
+
);
|
|
154
|
+
return success(
|
|
155
|
+
this.factory.parseCompany(this.context, updated)
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
removeShippingAddressPayload(payload, businessUnit) {
|
|
159
|
+
const addressToRemove = businessUnit.addresses.find(
|
|
160
|
+
(addr) => addr.key === payload.addressIdentifier.nickName
|
|
161
|
+
);
|
|
162
|
+
if (!addressToRemove) {
|
|
163
|
+
return void 0;
|
|
164
|
+
}
|
|
165
|
+
const actions = [
|
|
166
|
+
{
|
|
167
|
+
action: "removeAddress",
|
|
168
|
+
addressId: addressToRemove.id
|
|
169
|
+
}
|
|
170
|
+
];
|
|
171
|
+
const needsNewDefaultShippingAddress = businessUnit.defaultShippingAddressId === addressToRemove.id;
|
|
172
|
+
if (needsNewDefaultShippingAddress) {
|
|
173
|
+
const newDefault = businessUnit.addresses.find(
|
|
174
|
+
(addr) => addr.id !== addressToRemove.id && addr.id !== businessUnit.defaultBillingAddressId
|
|
175
|
+
);
|
|
176
|
+
if (newDefault) {
|
|
177
|
+
actions.push({
|
|
178
|
+
action: "setDefaultShippingAddress",
|
|
179
|
+
addressKey: newDefault.key
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return actions;
|
|
184
|
+
}
|
|
185
|
+
async removeShippingAddress(payload) {
|
|
186
|
+
const key = payload.company.taxIdentifier;
|
|
187
|
+
const businessUnit = await this.getBusinessUnit(key);
|
|
188
|
+
if (!businessUnit) {
|
|
189
|
+
return error({
|
|
190
|
+
type: "NotFound",
|
|
191
|
+
identifier: payload.company
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
const actions = this.removeShippingAddressPayload(payload, businessUnit);
|
|
195
|
+
if (!actions) {
|
|
196
|
+
return error({
|
|
197
|
+
type: "NotFound",
|
|
198
|
+
identifier: payload.addressIdentifier
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
const updated = await this.updateBusinessUnit(
|
|
202
|
+
key,
|
|
203
|
+
businessUnit.version,
|
|
204
|
+
actions
|
|
205
|
+
);
|
|
206
|
+
return success(
|
|
207
|
+
this.factory.parseCompany(this.context, updated)
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
makeShippingAddressDefaultPayload(payload, businessUnit) {
|
|
211
|
+
const addressToMakeDefault = businessUnit.addresses.find(
|
|
212
|
+
(addr) => addr.key === payload.addressIdentifier.nickName
|
|
213
|
+
);
|
|
214
|
+
if (!addressToMakeDefault) {
|
|
215
|
+
return void 0;
|
|
216
|
+
}
|
|
217
|
+
return [
|
|
218
|
+
{
|
|
219
|
+
action: "setDefaultShippingAddress",
|
|
220
|
+
addressKey: addressToMakeDefault.key
|
|
221
|
+
}
|
|
222
|
+
];
|
|
223
|
+
}
|
|
224
|
+
async makeShippingAddressDefault(payload) {
|
|
225
|
+
const key = payload.company.taxIdentifier;
|
|
226
|
+
const businessUnit = await this.getBusinessUnit(key);
|
|
227
|
+
if (!businessUnit) {
|
|
228
|
+
return error({
|
|
229
|
+
type: "NotFound",
|
|
230
|
+
identifier: payload.company
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
const actions = this.makeShippingAddressDefaultPayload(
|
|
234
|
+
payload,
|
|
235
|
+
businessUnit
|
|
236
|
+
);
|
|
237
|
+
if (!actions) {
|
|
238
|
+
return error({
|
|
239
|
+
type: "NotFound",
|
|
240
|
+
identifier: payload.addressIdentifier
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
const updated = await this.updateBusinessUnit(
|
|
244
|
+
key,
|
|
245
|
+
businessUnit.version,
|
|
246
|
+
actions
|
|
247
|
+
);
|
|
248
|
+
return success(
|
|
249
|
+
this.factory.parseCompany(this.context, updated)
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
listCompaniesPayload(payload) {
|
|
253
|
+
const offset = (payload.search.paginationOptions.pageNumber - 1) * payload.search.paginationOptions.pageSize;
|
|
254
|
+
const limit = payload.search.paginationOptions.pageSize;
|
|
255
|
+
return {
|
|
256
|
+
limit,
|
|
257
|
+
offset
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
async listCompanies(payload) {
|
|
261
|
+
const client = await this.getClient();
|
|
262
|
+
const response = await client.businessUnits().get({
|
|
263
|
+
queryArgs: this.listCompaniesPayload(payload)
|
|
264
|
+
}).execute();
|
|
265
|
+
return success(this.factory.parseCompanyPaginatedList(this.context, response.body, payload));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
__decorateClass([
|
|
269
|
+
Reactionary({
|
|
270
|
+
inputSchema: CompanyQueryByIdSchema,
|
|
271
|
+
outputSchema: CompanySchema
|
|
272
|
+
})
|
|
273
|
+
], CommercetoolsCompanyCapability.prototype, "getById", 1);
|
|
274
|
+
__decorateClass([
|
|
275
|
+
Reactionary({
|
|
276
|
+
inputSchema: CompanyMutationAddShippingAddressSchema,
|
|
277
|
+
outputSchema: CompanySchema
|
|
278
|
+
})
|
|
279
|
+
], CommercetoolsCompanyCapability.prototype, "addShippingAddress", 1);
|
|
280
|
+
__decorateClass([
|
|
281
|
+
Reactionary({
|
|
282
|
+
inputSchema: CompanyMutationUpdateShippingAddressSchema,
|
|
283
|
+
outputSchema: CompanySchema
|
|
284
|
+
})
|
|
285
|
+
], CommercetoolsCompanyCapability.prototype, "updateShippingAddress", 1);
|
|
286
|
+
__decorateClass([
|
|
287
|
+
Reactionary({
|
|
288
|
+
inputSchema: CompanyMutationRemoveShippingAddressSchema,
|
|
289
|
+
outputSchema: CompanySchema
|
|
290
|
+
})
|
|
291
|
+
], CommercetoolsCompanyCapability.prototype, "removeShippingAddress", 1);
|
|
292
|
+
__decorateClass([
|
|
293
|
+
Reactionary({
|
|
294
|
+
inputSchema: CompanyMutationMakeShippingAddressDefaultSchema,
|
|
295
|
+
outputSchema: CompanySchema
|
|
296
|
+
})
|
|
297
|
+
], CommercetoolsCompanyCapability.prototype, "makeShippingAddressDefault", 1);
|
|
298
|
+
__decorateClass([
|
|
299
|
+
Reactionary({
|
|
300
|
+
inputSchema: CompanyQueryListSchema,
|
|
301
|
+
outputSchema: CompanyPaginatedListSchema
|
|
302
|
+
})
|
|
303
|
+
], CommercetoolsCompanyCapability.prototype, "listCompanies", 1);
|
|
304
|
+
export {
|
|
305
|
+
CommercetoolsCompanyCapability
|
|
306
|
+
};
|