@wix/headless-bookings 0.0.51 → 0.0.53
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/cjs/dist/react/booking/Booking.d.ts +3 -3
- package/cjs/dist/react/booking/Booking.js +11 -6
- package/cjs/dist/react/core/booking/Booking.js +14 -3
- package/cjs/dist/react/index.d.ts +1 -0
- package/cjs/dist/react/index.js +1 -0
- package/cjs/dist/react/location/Location.js +2 -2
- package/cjs/dist/services/booking/book-action/buildBookingRequest.js +1 -0
- package/cjs/dist/services/payment/payment.def.d.ts +1 -1
- package/cjs/dist/services/payment/payment.js +11 -5
- package/dist/react/booking/Booking.d.ts +3 -3
- package/dist/react/booking/Booking.js +11 -6
- package/dist/react/core/booking/Booking.js +14 -3
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/react/location/Location.js +2 -2
- package/dist/services/booking/book-action/buildBookingRequest.js +1 -0
- package/dist/services/payment/payment.def.d.ts +1 -1
- package/dist/services/payment/payment.js +11 -5
- package/package.json +2 -2
|
@@ -227,9 +227,9 @@ export interface BookingLocationProps {
|
|
|
227
227
|
children: React.ReactNode;
|
|
228
228
|
}
|
|
229
229
|
/**
|
|
230
|
-
* Wraps Location
|
|
230
|
+
* Wraps Location context with the location from the booking context.
|
|
231
231
|
* Children can use all Location.* components (Location.Name, Location.Address, etc.).
|
|
232
|
-
*
|
|
232
|
+
* Returns null if no location is set.
|
|
233
233
|
*
|
|
234
234
|
* @component
|
|
235
235
|
* @example
|
|
@@ -254,7 +254,7 @@ export interface StaffNameProps {
|
|
|
254
254
|
}
|
|
255
255
|
/**
|
|
256
256
|
* Displays the first staff member's name from the current booking item.
|
|
257
|
-
*
|
|
257
|
+
* Returns null when staff name is empty.
|
|
258
258
|
*
|
|
259
259
|
* @component
|
|
260
260
|
* @example
|
|
@@ -10,7 +10,7 @@ import { AsChildSlot } from '@wix/headless-utils/react';
|
|
|
10
10
|
import * as ServiceComponent from '../service/Service.js';
|
|
11
11
|
import * as TimeSlotComponent from '../time-slot-list/TimeSlot.js';
|
|
12
12
|
import * as PaymentComponent from '../payment/Payment.js';
|
|
13
|
-
import * as
|
|
13
|
+
import * as CoreLocation from '../core/location/Location.js';
|
|
14
14
|
import { GenericList } from '@wix/headless-components/react';
|
|
15
15
|
// ============================================================================
|
|
16
16
|
// TestIds
|
|
@@ -230,9 +230,9 @@ export function Payment(props) {
|
|
|
230
230
|
return (_jsx(CoreBooking.PaymentData, { children: ({ slotServices }) => (_jsx(PaymentComponent.Root, { slotServices: slotServices, children: children })) }));
|
|
231
231
|
}
|
|
232
232
|
/**
|
|
233
|
-
* Wraps Location
|
|
233
|
+
* Wraps Location context with the location from the booking context.
|
|
234
234
|
* Children can use all Location.* components (Location.Name, Location.Address, etc.).
|
|
235
|
-
*
|
|
235
|
+
* Returns null if no location is set.
|
|
236
236
|
*
|
|
237
237
|
* @component
|
|
238
238
|
* @example
|
|
@@ -246,11 +246,11 @@ export function Payment(props) {
|
|
|
246
246
|
*/
|
|
247
247
|
export function Location(props) {
|
|
248
248
|
const { children } = props;
|
|
249
|
-
return (_jsx(CoreBooking.Data, { children: ({ location }) => location ? (_jsx(
|
|
249
|
+
return (_jsx(CoreBooking.Data, { children: ({ location }) => location ? (_jsx(CoreLocation.Root, { location: location, children: children })) : null }));
|
|
250
250
|
}
|
|
251
251
|
/**
|
|
252
252
|
* Displays the first staff member's name from the current booking item.
|
|
253
|
-
*
|
|
253
|
+
* Returns null when staff name is empty.
|
|
254
254
|
*
|
|
255
255
|
* @component
|
|
256
256
|
* @example
|
|
@@ -260,6 +260,11 @@ export function Location(props) {
|
|
|
260
260
|
*/
|
|
261
261
|
export const StaffName = React.forwardRef((props, ref) => {
|
|
262
262
|
const { asChild, children, className } = props;
|
|
263
|
-
return (_jsx(CoreBooking.BookingItemInfo, { children: ({ staffName }) =>
|
|
263
|
+
return (_jsx(CoreBooking.BookingItemInfo, { children: ({ staffName }) => {
|
|
264
|
+
if (!staffName) {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.bookingStaffName, customElement: children, customElementProps: { name: staffName }, children: _jsx("span", { children: staffName }) }));
|
|
268
|
+
} }));
|
|
264
269
|
});
|
|
265
270
|
StaffName.displayName = 'Booking.StaffName';
|
|
@@ -46,13 +46,24 @@ export function Root(props) {
|
|
|
46
46
|
*/
|
|
47
47
|
/**
|
|
48
48
|
* Maps a TimeSlotLocationType to ServiceLocationType.
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* TimeSlot location has flat structure: { name, formattedAddress, locationType }
|
|
50
|
+
* Service location has nested structure: { business: { name, address }, type }
|
|
51
51
|
*/
|
|
52
52
|
function mapTimeSlotLocationToServiceLocation(timeSlotLocation) {
|
|
53
|
+
// TimeSlot location has flat name/formattedAddress at top level
|
|
54
|
+
// Convert to nested business structure that CoreLocation expects
|
|
53
55
|
return {
|
|
54
|
-
...timeSlotLocation,
|
|
55
56
|
_id: timeSlotLocation._id ?? undefined,
|
|
57
|
+
type: timeSlotLocation.locationType,
|
|
58
|
+
business: {
|
|
59
|
+
_id: timeSlotLocation._id ?? undefined,
|
|
60
|
+
name: timeSlotLocation.name ?? undefined,
|
|
61
|
+
address: timeSlotLocation.formattedAddress
|
|
62
|
+
? {
|
|
63
|
+
addressLine: timeSlotLocation.formattedAddress,
|
|
64
|
+
}
|
|
65
|
+
: undefined,
|
|
66
|
+
},
|
|
56
67
|
};
|
|
57
68
|
}
|
|
58
69
|
/**
|
|
@@ -3,6 +3,7 @@ export * as BookingForm from './booking-form/BookingForm.js';
|
|
|
3
3
|
export * as Service from './service/Service.js';
|
|
4
4
|
export * as ServiceMedia from './service/ServiceMedia.js';
|
|
5
5
|
export * as TimeSlotList from './time-slot-list/TimeSlotList.js';
|
|
6
|
+
export * as TimeSlot from './time-slot-list/TimeSlot.js';
|
|
6
7
|
export * as ServiceList from './service-list/ServiceList.js';
|
|
7
8
|
export * as Location from './location/Location.js';
|
|
8
9
|
export * as LocationList from './location/LocationList.js';
|
package/cjs/dist/react/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export * as BookingForm from './booking-form/BookingForm.js';
|
|
|
3
3
|
export * as Service from './service/Service.js';
|
|
4
4
|
export * as ServiceMedia from './service/ServiceMedia.js';
|
|
5
5
|
export * as TimeSlotList from './time-slot-list/TimeSlotList.js';
|
|
6
|
+
export * as TimeSlot from './time-slot-list/TimeSlot.js';
|
|
6
7
|
export * as ServiceList from './service-list/ServiceList.js';
|
|
7
8
|
export * as Location from './location/Location.js';
|
|
8
9
|
export * as LocationList from './location/LocationList.js';
|
|
@@ -89,7 +89,7 @@ Root.displayName = 'Location.Root';
|
|
|
89
89
|
export const Name = React.forwardRef((props, ref) => {
|
|
90
90
|
const { asChild, children, className, ...attrs } = props;
|
|
91
91
|
const { name } = useLocationContext();
|
|
92
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.locationName, customElement: children, customElementProps: { name: name ?? '' }, ...attrs, children: _jsx("span", { children: name }) }));
|
|
92
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.locationName, customElement: children, customElementProps: { name: name ?? '' }, ...attrs, children: name ? _jsx("span", { children: name }) : null }));
|
|
93
93
|
});
|
|
94
94
|
Name.displayName = 'Location.Name';
|
|
95
95
|
/**
|
|
@@ -117,7 +117,7 @@ export const Type = React.forwardRef((props, ref) => {
|
|
|
117
117
|
locationType,
|
|
118
118
|
isCustomerLocation,
|
|
119
119
|
isCustomLocation,
|
|
120
|
-
}, ...attrs, children: _jsx("span", { children: locationType }) }));
|
|
120
|
+
}, ...attrs, children: locationType ? _jsx("span", { children: locationType }) : null }));
|
|
121
121
|
});
|
|
122
122
|
Type.displayName = 'Location.Type';
|
|
123
123
|
/**
|
|
@@ -8,7 +8,7 @@ import type { Service } from '@wix/auto_sdk_bookings_services';
|
|
|
8
8
|
/**
|
|
9
9
|
* Payment option for line items
|
|
10
10
|
*/
|
|
11
|
-
export type PaymentOption = 'FULL_PAYMENT_ONLINE' | 'FULL_PAYMENT_OFFLINE';
|
|
11
|
+
export type PaymentOption = 'FULL_PAYMENT_ONLINE' | 'FULL_PAYMENT_OFFLINE' | 'DEPOSIT_ONLINE';
|
|
12
12
|
/**
|
|
13
13
|
* Additional computed info for a line item (not in SDK response)
|
|
14
14
|
*/
|
|
@@ -25,11 +25,15 @@ function getAdditionalInfo(service, lineItemId) {
|
|
|
25
25
|
: undefined;
|
|
26
26
|
return { lineItemId, priceText };
|
|
27
27
|
}
|
|
28
|
-
function getPaymentOption(service) {
|
|
28
|
+
function getPaymentOption(service, hasDeposit) {
|
|
29
29
|
const options = service.payment?.options;
|
|
30
30
|
if (options?.inPerson) {
|
|
31
31
|
return 'FULL_PAYMENT_OFFLINE';
|
|
32
32
|
}
|
|
33
|
+
// If deposit is configured, use DEPOSIT_ONLINE to get correct payNow/payLater split
|
|
34
|
+
if (hasDeposit) {
|
|
35
|
+
return 'DEPOSIT_ONLINE';
|
|
36
|
+
}
|
|
33
37
|
return 'FULL_PAYMENT_ONLINE';
|
|
34
38
|
}
|
|
35
39
|
function buildLineItem(service, numberOfParticipants, lineItemId) {
|
|
@@ -37,11 +41,13 @@ function buildLineItem(service, numberOfParticipants, lineItemId) {
|
|
|
37
41
|
const servicePrice = service.payment?.fixed?.price?.value;
|
|
38
42
|
const price = Number(servicePrice || 0) * numberOfParticipants;
|
|
39
43
|
// Get deposit if configured
|
|
40
|
-
const
|
|
41
|
-
|
|
44
|
+
const depositValue = service.payment?.fixed?.deposit?.value;
|
|
45
|
+
const hasDeposit = !!depositValue && Number(depositValue) > 0;
|
|
46
|
+
const deposit = hasDeposit
|
|
47
|
+
? Number(depositValue) * numberOfParticipants
|
|
42
48
|
: undefined;
|
|
43
|
-
// Get payment option from service configuration
|
|
44
|
-
const paymentOption = getPaymentOption(service);
|
|
49
|
+
// Get payment option from service configuration (pass hasDeposit for correct API behavior)
|
|
50
|
+
const paymentOption = getPaymentOption(service, hasDeposit);
|
|
45
51
|
return {
|
|
46
52
|
_id: lineItemId,
|
|
47
53
|
catalogReference: {
|
|
@@ -227,9 +227,9 @@ export interface BookingLocationProps {
|
|
|
227
227
|
children: React.ReactNode;
|
|
228
228
|
}
|
|
229
229
|
/**
|
|
230
|
-
* Wraps Location
|
|
230
|
+
* Wraps Location context with the location from the booking context.
|
|
231
231
|
* Children can use all Location.* components (Location.Name, Location.Address, etc.).
|
|
232
|
-
*
|
|
232
|
+
* Returns null if no location is set.
|
|
233
233
|
*
|
|
234
234
|
* @component
|
|
235
235
|
* @example
|
|
@@ -254,7 +254,7 @@ export interface StaffNameProps {
|
|
|
254
254
|
}
|
|
255
255
|
/**
|
|
256
256
|
* Displays the first staff member's name from the current booking item.
|
|
257
|
-
*
|
|
257
|
+
* Returns null when staff name is empty.
|
|
258
258
|
*
|
|
259
259
|
* @component
|
|
260
260
|
* @example
|
|
@@ -10,7 +10,7 @@ import { AsChildSlot } from '@wix/headless-utils/react';
|
|
|
10
10
|
import * as ServiceComponent from '../service/Service.js';
|
|
11
11
|
import * as TimeSlotComponent from '../time-slot-list/TimeSlot.js';
|
|
12
12
|
import * as PaymentComponent from '../payment/Payment.js';
|
|
13
|
-
import * as
|
|
13
|
+
import * as CoreLocation from '../core/location/Location.js';
|
|
14
14
|
import { GenericList } from '@wix/headless-components/react';
|
|
15
15
|
// ============================================================================
|
|
16
16
|
// TestIds
|
|
@@ -230,9 +230,9 @@ export function Payment(props) {
|
|
|
230
230
|
return (_jsx(CoreBooking.PaymentData, { children: ({ slotServices }) => (_jsx(PaymentComponent.Root, { slotServices: slotServices, children: children })) }));
|
|
231
231
|
}
|
|
232
232
|
/**
|
|
233
|
-
* Wraps Location
|
|
233
|
+
* Wraps Location context with the location from the booking context.
|
|
234
234
|
* Children can use all Location.* components (Location.Name, Location.Address, etc.).
|
|
235
|
-
*
|
|
235
|
+
* Returns null if no location is set.
|
|
236
236
|
*
|
|
237
237
|
* @component
|
|
238
238
|
* @example
|
|
@@ -246,11 +246,11 @@ export function Payment(props) {
|
|
|
246
246
|
*/
|
|
247
247
|
export function Location(props) {
|
|
248
248
|
const { children } = props;
|
|
249
|
-
return (_jsx(CoreBooking.Data, { children: ({ location }) => location ? (_jsx(
|
|
249
|
+
return (_jsx(CoreBooking.Data, { children: ({ location }) => location ? (_jsx(CoreLocation.Root, { location: location, children: children })) : null }));
|
|
250
250
|
}
|
|
251
251
|
/**
|
|
252
252
|
* Displays the first staff member's name from the current booking item.
|
|
253
|
-
*
|
|
253
|
+
* Returns null when staff name is empty.
|
|
254
254
|
*
|
|
255
255
|
* @component
|
|
256
256
|
* @example
|
|
@@ -260,6 +260,11 @@ export function Location(props) {
|
|
|
260
260
|
*/
|
|
261
261
|
export const StaffName = React.forwardRef((props, ref) => {
|
|
262
262
|
const { asChild, children, className } = props;
|
|
263
|
-
return (_jsx(CoreBooking.BookingItemInfo, { children: ({ staffName }) =>
|
|
263
|
+
return (_jsx(CoreBooking.BookingItemInfo, { children: ({ staffName }) => {
|
|
264
|
+
if (!staffName) {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.bookingStaffName, customElement: children, customElementProps: { name: staffName }, children: _jsx("span", { children: staffName }) }));
|
|
268
|
+
} }));
|
|
264
269
|
});
|
|
265
270
|
StaffName.displayName = 'Booking.StaffName';
|
|
@@ -46,13 +46,24 @@ export function Root(props) {
|
|
|
46
46
|
*/
|
|
47
47
|
/**
|
|
48
48
|
* Maps a TimeSlotLocationType to ServiceLocationType.
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* TimeSlot location has flat structure: { name, formattedAddress, locationType }
|
|
50
|
+
* Service location has nested structure: { business: { name, address }, type }
|
|
51
51
|
*/
|
|
52
52
|
function mapTimeSlotLocationToServiceLocation(timeSlotLocation) {
|
|
53
|
+
// TimeSlot location has flat name/formattedAddress at top level
|
|
54
|
+
// Convert to nested business structure that CoreLocation expects
|
|
53
55
|
return {
|
|
54
|
-
...timeSlotLocation,
|
|
55
56
|
_id: timeSlotLocation._id ?? undefined,
|
|
57
|
+
type: timeSlotLocation.locationType,
|
|
58
|
+
business: {
|
|
59
|
+
_id: timeSlotLocation._id ?? undefined,
|
|
60
|
+
name: timeSlotLocation.name ?? undefined,
|
|
61
|
+
address: timeSlotLocation.formattedAddress
|
|
62
|
+
? {
|
|
63
|
+
addressLine: timeSlotLocation.formattedAddress,
|
|
64
|
+
}
|
|
65
|
+
: undefined,
|
|
66
|
+
},
|
|
56
67
|
};
|
|
57
68
|
}
|
|
58
69
|
/**
|
package/dist/react/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * as BookingForm from './booking-form/BookingForm.js';
|
|
|
3
3
|
export * as Service from './service/Service.js';
|
|
4
4
|
export * as ServiceMedia from './service/ServiceMedia.js';
|
|
5
5
|
export * as TimeSlotList from './time-slot-list/TimeSlotList.js';
|
|
6
|
+
export * as TimeSlot from './time-slot-list/TimeSlot.js';
|
|
6
7
|
export * as ServiceList from './service-list/ServiceList.js';
|
|
7
8
|
export * as Location from './location/Location.js';
|
|
8
9
|
export * as LocationList from './location/LocationList.js';
|
package/dist/react/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export * as BookingForm from './booking-form/BookingForm.js';
|
|
|
3
3
|
export * as Service from './service/Service.js';
|
|
4
4
|
export * as ServiceMedia from './service/ServiceMedia.js';
|
|
5
5
|
export * as TimeSlotList from './time-slot-list/TimeSlotList.js';
|
|
6
|
+
export * as TimeSlot from './time-slot-list/TimeSlot.js';
|
|
6
7
|
export * as ServiceList from './service-list/ServiceList.js';
|
|
7
8
|
export * as Location from './location/Location.js';
|
|
8
9
|
export * as LocationList from './location/LocationList.js';
|
|
@@ -89,7 +89,7 @@ Root.displayName = 'Location.Root';
|
|
|
89
89
|
export const Name = React.forwardRef((props, ref) => {
|
|
90
90
|
const { asChild, children, className, ...attrs } = props;
|
|
91
91
|
const { name } = useLocationContext();
|
|
92
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.locationName, customElement: children, customElementProps: { name: name ?? '' }, ...attrs, children: _jsx("span", { children: name }) }));
|
|
92
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.locationName, customElement: children, customElementProps: { name: name ?? '' }, ...attrs, children: name ? _jsx("span", { children: name }) : null }));
|
|
93
93
|
});
|
|
94
94
|
Name.displayName = 'Location.Name';
|
|
95
95
|
/**
|
|
@@ -117,7 +117,7 @@ export const Type = React.forwardRef((props, ref) => {
|
|
|
117
117
|
locationType,
|
|
118
118
|
isCustomerLocation,
|
|
119
119
|
isCustomLocation,
|
|
120
|
-
}, ...attrs, children: _jsx("span", { children: locationType }) }));
|
|
120
|
+
}, ...attrs, children: locationType ? _jsx("span", { children: locationType }) : null }));
|
|
121
121
|
});
|
|
122
122
|
Type.displayName = 'Location.Type';
|
|
123
123
|
/**
|
|
@@ -8,7 +8,7 @@ import type { Service } from '@wix/auto_sdk_bookings_services';
|
|
|
8
8
|
/**
|
|
9
9
|
* Payment option for line items
|
|
10
10
|
*/
|
|
11
|
-
export type PaymentOption = 'FULL_PAYMENT_ONLINE' | 'FULL_PAYMENT_OFFLINE';
|
|
11
|
+
export type PaymentOption = 'FULL_PAYMENT_ONLINE' | 'FULL_PAYMENT_OFFLINE' | 'DEPOSIT_ONLINE';
|
|
12
12
|
/**
|
|
13
13
|
* Additional computed info for a line item (not in SDK response)
|
|
14
14
|
*/
|
|
@@ -25,11 +25,15 @@ function getAdditionalInfo(service, lineItemId) {
|
|
|
25
25
|
: undefined;
|
|
26
26
|
return { lineItemId, priceText };
|
|
27
27
|
}
|
|
28
|
-
function getPaymentOption(service) {
|
|
28
|
+
function getPaymentOption(service, hasDeposit) {
|
|
29
29
|
const options = service.payment?.options;
|
|
30
30
|
if (options?.inPerson) {
|
|
31
31
|
return 'FULL_PAYMENT_OFFLINE';
|
|
32
32
|
}
|
|
33
|
+
// If deposit is configured, use DEPOSIT_ONLINE to get correct payNow/payLater split
|
|
34
|
+
if (hasDeposit) {
|
|
35
|
+
return 'DEPOSIT_ONLINE';
|
|
36
|
+
}
|
|
33
37
|
return 'FULL_PAYMENT_ONLINE';
|
|
34
38
|
}
|
|
35
39
|
function buildLineItem(service, numberOfParticipants, lineItemId) {
|
|
@@ -37,11 +41,13 @@ function buildLineItem(service, numberOfParticipants, lineItemId) {
|
|
|
37
41
|
const servicePrice = service.payment?.fixed?.price?.value;
|
|
38
42
|
const price = Number(servicePrice || 0) * numberOfParticipants;
|
|
39
43
|
// Get deposit if configured
|
|
40
|
-
const
|
|
41
|
-
|
|
44
|
+
const depositValue = service.payment?.fixed?.deposit?.value;
|
|
45
|
+
const hasDeposit = !!depositValue && Number(depositValue) > 0;
|
|
46
|
+
const deposit = hasDeposit
|
|
47
|
+
? Number(depositValue) * numberOfParticipants
|
|
42
48
|
: undefined;
|
|
43
|
-
// Get payment option from service configuration
|
|
44
|
-
const paymentOption = getPaymentOption(service);
|
|
49
|
+
// Get payment option from service configuration (pass hasDeposit for correct API behavior)
|
|
50
|
+
const paymentOption = getPaymentOption(service, hasDeposit);
|
|
45
51
|
return {
|
|
46
52
|
_id: lineItemId,
|
|
47
53
|
catalogReference: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/headless-bookings",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.53",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"groupId": "com.wixpress.headless-components"
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
|
-
"falconPackageHash": "
|
|
75
|
+
"falconPackageHash": "e2a82b9d4a1150c6bc5f6996ccc4f53eebcda6e1aa624a3eab20fbe7"
|
|
76
76
|
}
|