@devite/shopware-client 1.3.3 → 1.4.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/dist/index.cjs +57 -20
- package/dist/index.d.cts +2798 -8787
- package/dist/index.d.mts +2798 -8787
- package/dist/index.d.ts +2798 -8787
- package/dist/index.mjs +57 -20
- package/dist/types/api/global/dal/PricingCashRoundingConfig.d.ts +6 -0
- package/dist/types/api/global/dal/index.d.ts +1 -0
- package/dist/types/api/global/index.d.ts +1 -0
- package/dist/types/api/store/cart/Cart.d.ts +2 -2
- package/dist/types/api/store/cart/index.d.ts +0 -1
- package/dist/types/api/store/customer/address/CustomerAddress.d.ts +2 -2
- package/dist/types/api/store/customer/address/index.d.ts +2 -0
- package/dist/types/api/store/customer/index.d.ts +1 -0
- package/dist/types/api/store/lineItem/LineItem.d.ts +2 -2
- package/dist/types/api/store/lineItem/LineItemPayload.d.ts +19 -67
- package/dist/types/api/store/price/CalculatedPrice.d.ts +1 -0
- package/dist/types/api/store/salesChannel/SalesChannelContext.d.ts +27 -22
- package/dist/types/clients/store/AccountClient.d.ts +7 -2
- package/dist/types/clients/store/CartClient.d.ts +1 -1
- package/package.json +11 -11
- package/dist/types/api/store/cart/CartItems.d.ts +0 -2
package/dist/index.mjs
CHANGED
|
@@ -11801,7 +11801,12 @@ class ContextTokenEntry {
|
|
|
11801
11801
|
return this.token !== null;
|
|
11802
11802
|
}
|
|
11803
11803
|
save(response) {
|
|
11804
|
-
|
|
11804
|
+
const headerToken = response.headers?.get("sw-context-token") || null;
|
|
11805
|
+
if (headerToken?.includes(", ")) {
|
|
11806
|
+
this.token = headerToken.split(", ")[1];
|
|
11807
|
+
} else {
|
|
11808
|
+
this.token = headerToken;
|
|
11809
|
+
}
|
|
11805
11810
|
}
|
|
11806
11811
|
clear() {
|
|
11807
11812
|
this.token = null;
|
|
@@ -12083,7 +12088,10 @@ class CartClient extends Client {
|
|
|
12083
12088
|
* @throws {Error} if the request failed
|
|
12084
12089
|
*/
|
|
12085
12090
|
async getOrCreateCart() {
|
|
12086
|
-
const response = await this.get(
|
|
12091
|
+
const response = await this.get(
|
|
12092
|
+
"/checkout/cart",
|
|
12093
|
+
this.client.withContextToken()
|
|
12094
|
+
);
|
|
12087
12095
|
if (response.statusCode === 200)
|
|
12088
12096
|
return response.body.data;
|
|
12089
12097
|
throw new ShopwareError("Failed to get or create cart", response);
|
|
@@ -12092,7 +12100,10 @@ class CartClient extends Client {
|
|
|
12092
12100
|
* @throws {Error} if the request failed
|
|
12093
12101
|
*/
|
|
12094
12102
|
async deleteCart() {
|
|
12095
|
-
const response = await this.delete(
|
|
12103
|
+
const response = await this.delete(
|
|
12104
|
+
"/checkout/cart",
|
|
12105
|
+
this.client.withContextToken()
|
|
12106
|
+
);
|
|
12096
12107
|
if (response.statusCode === 200)
|
|
12097
12108
|
return response.body.data;
|
|
12098
12109
|
throw new ShopwareError("Failed to delete cart", response);
|
|
@@ -12101,9 +12112,12 @@ class CartClient extends Client {
|
|
|
12101
12112
|
* @throws {Error} if the request failed
|
|
12102
12113
|
*/
|
|
12103
12114
|
async addLineItems(request) {
|
|
12104
|
-
const response = await this.post(
|
|
12105
|
-
|
|
12106
|
-
|
|
12115
|
+
const response = await this.post(
|
|
12116
|
+
"/checkout/cart/line-item",
|
|
12117
|
+
this.client.withContextToken({
|
|
12118
|
+
body: new JsonPayload(request)
|
|
12119
|
+
})
|
|
12120
|
+
);
|
|
12107
12121
|
if (response.statusCode === 200)
|
|
12108
12122
|
return response.body.data;
|
|
12109
12123
|
throw new ShopwareError("Failed to add line items to cart", response);
|
|
@@ -12112,9 +12126,12 @@ class CartClient extends Client {
|
|
|
12112
12126
|
* @throws {Error} if the request failed
|
|
12113
12127
|
*/
|
|
12114
12128
|
async removeLineItems(request) {
|
|
12115
|
-
const response = await this.post(
|
|
12116
|
-
|
|
12117
|
-
|
|
12129
|
+
const response = await this.post(
|
|
12130
|
+
"/checkout/cart/line-item/delete",
|
|
12131
|
+
this.client.withContextToken({
|
|
12132
|
+
body: new JsonPayload(request)
|
|
12133
|
+
})
|
|
12134
|
+
);
|
|
12118
12135
|
if (response.statusCode === 200)
|
|
12119
12136
|
return response.body.data;
|
|
12120
12137
|
throw new ShopwareError("Failed to remove line items from cart", response);
|
|
@@ -12123,9 +12140,12 @@ class CartClient extends Client {
|
|
|
12123
12140
|
* @throws {Error} if the request failed
|
|
12124
12141
|
*/
|
|
12125
12142
|
async updateLineItems(request) {
|
|
12126
|
-
const response = await this.patch(
|
|
12127
|
-
|
|
12128
|
-
|
|
12143
|
+
const response = await this.patch(
|
|
12144
|
+
"/checkout/cart/line-item",
|
|
12145
|
+
this.client.withContextToken({
|
|
12146
|
+
body: new JsonPayload(request)
|
|
12147
|
+
})
|
|
12148
|
+
);
|
|
12129
12149
|
if (response.statusCode === 200)
|
|
12130
12150
|
return response.body.data;
|
|
12131
12151
|
throw new ShopwareError("Failed to update line items in cart", response);
|
|
@@ -12220,17 +12240,27 @@ class ContextClient extends Client {
|
|
|
12220
12240
|
* @throws {Error} if the request failed
|
|
12221
12241
|
*/
|
|
12222
12242
|
async getContext() {
|
|
12223
|
-
const
|
|
12224
|
-
|
|
12243
|
+
const entry = this.client.authStore.getEntry(
|
|
12244
|
+
AuthenticationType.CONTEXT_TOKEN
|
|
12245
|
+
);
|
|
12246
|
+
const response = await this.get(
|
|
12247
|
+
"/context",
|
|
12248
|
+
entry ? this.client.withContextToken() : void 0
|
|
12249
|
+
);
|
|
12250
|
+
if (response.statusCode === 200) {
|
|
12251
|
+
entry?.save(response);
|
|
12252
|
+
return response.body.data;
|
|
12253
|
+
}
|
|
12225
12254
|
throw new ShopwareError("Failed to fetch context", response);
|
|
12226
12255
|
}
|
|
12227
12256
|
/**
|
|
12228
12257
|
* @throws {Error} if the request failed
|
|
12229
12258
|
*/
|
|
12230
12259
|
async updateContext(context) {
|
|
12231
|
-
const response = await this.patch(
|
|
12232
|
-
|
|
12233
|
-
|
|
12260
|
+
const response = await this.patch(
|
|
12261
|
+
"/context",
|
|
12262
|
+
this.client.withContextToken({ body: new JsonPayload(context) })
|
|
12263
|
+
);
|
|
12234
12264
|
if (response.statusCode === 200)
|
|
12235
12265
|
return response.body.data;
|
|
12236
12266
|
throw new ShopwareError("Failed to update context", response);
|
|
@@ -12312,7 +12342,7 @@ class NewsletterClient extends Client {
|
|
|
12312
12342
|
const response = await this.post(`/newsletter/confirm`, {
|
|
12313
12343
|
body: new JsonPayload(request)
|
|
12314
12344
|
});
|
|
12315
|
-
if (response.statusCode ===
|
|
12345
|
+
if (response.statusCode === 204) return;
|
|
12316
12346
|
throw new ShopwareError("Failed to confirm newsletter subscription", response);
|
|
12317
12347
|
}
|
|
12318
12348
|
/**
|
|
@@ -12322,7 +12352,7 @@ class NewsletterClient extends Client {
|
|
|
12322
12352
|
const response = await this.post(`/newsletter/subscribe`, {
|
|
12323
12353
|
body: new JsonPayload(request)
|
|
12324
12354
|
});
|
|
12325
|
-
if (response.statusCode ===
|
|
12355
|
+
if (response.statusCode === 204) return;
|
|
12326
12356
|
throw new ShopwareError("Failed to update newsletter subscription", response);
|
|
12327
12357
|
}
|
|
12328
12358
|
/**
|
|
@@ -12332,7 +12362,7 @@ class NewsletterClient extends Client {
|
|
|
12332
12362
|
const response = await this.post(`/newsletter/unsubscribe`, {
|
|
12333
12363
|
body: new JsonPayload(request)
|
|
12334
12364
|
});
|
|
12335
|
-
if (response.statusCode ===
|
|
12365
|
+
if (response.statusCode === 204) return;
|
|
12336
12366
|
throw new ShopwareError("Failed to unsubscribe newsletter subscription", response);
|
|
12337
12367
|
}
|
|
12338
12368
|
}
|
|
@@ -12705,6 +12735,13 @@ class StoreShopwareClient extends ShopwareClient {
|
|
|
12705
12735
|
}
|
|
12706
12736
|
});
|
|
12707
12737
|
}
|
|
12738
|
+
setContextToken(token) {
|
|
12739
|
+
this.authStore.getOrCreateEntry(new ContextTokenEntry()).save({
|
|
12740
|
+
statusCode: 200,
|
|
12741
|
+
statusMessage: "OK",
|
|
12742
|
+
headers: new Headers({ "sw-context-token": token })
|
|
12743
|
+
});
|
|
12744
|
+
}
|
|
12708
12745
|
withContextToken(options = {}) {
|
|
12709
12746
|
const entry = this.authStore.getEntry(
|
|
12710
12747
|
AuthenticationType.CONTEXT_TOKEN
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PricingCashRoundingConfig } from "./PricingCashRoundingConfig";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { CalculatedPrice } from "../price/CalculatedPrice";
|
|
2
|
-
import { CartItems } from "./CartItems";
|
|
3
2
|
import { CartError } from "./CartError";
|
|
4
3
|
import { CartDelivery } from "./delivery/CartDelivery";
|
|
4
|
+
import { LineItem } from "#types/api/store";
|
|
5
5
|
export interface Cart {
|
|
6
6
|
name?: string;
|
|
7
7
|
token?: string;
|
|
8
8
|
price?: CalculatedPrice;
|
|
9
|
-
lineItems?:
|
|
9
|
+
lineItems?: Array<LineItem>;
|
|
10
10
|
errors?: Array<CartError>;
|
|
11
11
|
deliveries?: Array<CartDelivery>;
|
|
12
12
|
transactions?: Array<{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Media } from "../media/Media";
|
|
2
2
|
import { CartDeliveryInformation } from "../cart/delivery/CartDeliveryInformation";
|
|
3
3
|
import { LineItemPayload } from "./LineItemPayload";
|
|
4
4
|
import { CalculatedPrice } from "../price/CalculatedPrice";
|
|
@@ -6,7 +6,7 @@ import { CartPriceQuantity } from "../price/cart/CartPriceQuantity";
|
|
|
6
6
|
import { LineItemType } from "./LineItemType";
|
|
7
7
|
export interface LineItem {
|
|
8
8
|
children?: Array<LineItem>;
|
|
9
|
-
cover?:
|
|
9
|
+
cover?: Media;
|
|
10
10
|
dataContextHash?: string;
|
|
11
11
|
dataTimestamp?: string;
|
|
12
12
|
deliveryInformation?: CartDeliveryInformation;
|
|
@@ -1,74 +1,26 @@
|
|
|
1
|
-
import { Links } from "../link/Links";
|
|
2
1
|
import { GenericRecord } from "#types/api/global/GenericRecord";
|
|
3
|
-
import { CalculatedPrice } from "../price/CalculatedPrice";
|
|
4
2
|
export interface LineItemPayload {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
meta?: object;
|
|
11
|
-
versionId?: string;
|
|
12
|
-
parentId?: string;
|
|
13
|
-
parentVersionId?: string;
|
|
14
|
-
manufacturerId?: string;
|
|
15
|
-
productManufacturerVersionId?: string;
|
|
16
|
-
unitId?: string;
|
|
17
|
-
taxId?: string;
|
|
18
|
-
coverId?: string;
|
|
19
|
-
productMediaVersionId?: string;
|
|
20
|
-
deliveryTimeId?: string;
|
|
21
|
-
canonicalProductId?: string;
|
|
22
|
-
canonicalProductVersionId?: string;
|
|
23
|
-
cmsPageId?: string;
|
|
24
|
-
cmsPageVersionId?: string;
|
|
25
|
-
productNumber: string;
|
|
26
|
-
restockTime?: number;
|
|
27
|
-
active?: boolean;
|
|
28
|
-
available?: boolean;
|
|
3
|
+
categoryIds: Array<string>;
|
|
4
|
+
readonly createdAt?: string;
|
|
5
|
+
readonly updatedAt?: string;
|
|
6
|
+
customFields?: GenericRecord;
|
|
7
|
+
features?: Array<string>;
|
|
29
8
|
isCloseout?: boolean;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
displayGroup?: string;
|
|
33
|
-
manufacturerNumber?: string;
|
|
34
|
-
ean?: string;
|
|
35
|
-
purchaseSteps?: number;
|
|
36
|
-
maxPurchase?: number;
|
|
37
|
-
minPurchase?: number;
|
|
38
|
-
purchaseUnit?: number;
|
|
39
|
-
referenceUnit?: number;
|
|
40
|
-
shippingFree?: boolean;
|
|
9
|
+
isNew?: boolean;
|
|
10
|
+
manufacturerId?: string;
|
|
41
11
|
markAsTopseller?: boolean;
|
|
42
|
-
weight?: number;
|
|
43
|
-
width?: number;
|
|
44
|
-
height?: number;
|
|
45
|
-
length?: number;
|
|
46
|
-
releaseDate?: string;
|
|
47
|
-
ratingAverage?: number;
|
|
48
|
-
categoryTree?: Array<string>;
|
|
49
|
-
propertyIds?: Array<string>;
|
|
50
12
|
optionIds?: Array<string>;
|
|
13
|
+
options?: Array<{
|
|
14
|
+
group: string;
|
|
15
|
+
name: string;
|
|
16
|
+
}>;
|
|
17
|
+
parentId?: string;
|
|
18
|
+
productNumber?: string;
|
|
19
|
+
propertyIds?: Array<string>;
|
|
20
|
+
releaseDate?: string;
|
|
21
|
+
stock?: number;
|
|
51
22
|
streamIds?: Array<string>;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
sales?: number;
|
|
56
|
-
states?: Array<string>;
|
|
57
|
-
metaDescription?: string;
|
|
58
|
-
name: string;
|
|
59
|
-
keywords?: string;
|
|
60
|
-
description?: string;
|
|
61
|
-
metaTitle?: string;
|
|
62
|
-
packUnit?: string;
|
|
63
|
-
packUnitPlural?: string;
|
|
64
|
-
customFields?: GenericRecord;
|
|
65
|
-
calculatedPrice?: CalculatedPrice;
|
|
66
|
-
calculatedPrices?: Array<CalculatedPrice>;
|
|
67
|
-
calculatedMaxPurchase?: number;
|
|
68
|
-
calculatedCheapestPrice?: CalculatedPrice;
|
|
69
|
-
isNew?: boolean;
|
|
70
|
-
sortedProperties?: object;
|
|
71
|
-
createdAt?: string;
|
|
72
|
-
updatedAt?: string;
|
|
73
|
-
translated?: object;
|
|
23
|
+
tagsIds?: Array<string>;
|
|
24
|
+
taxId: string;
|
|
25
|
+
[key: string]: any;
|
|
74
26
|
}
|
|
@@ -1,38 +1,43 @@
|
|
|
1
1
|
import { Currency } from "../Currency";
|
|
2
|
+
import { CustomerGroup } from "../customer/CustomerGroup";
|
|
2
3
|
import { SalesChannel } from "./SalesChannel";
|
|
3
4
|
import { Customer } from "../customer/Customer";
|
|
4
5
|
import { PaymentMethod } from "../PaymentMethod";
|
|
5
6
|
import { CartDeliveryShippingLocation } from "../cart/delivery/CartDeliveryShippingLocation";
|
|
6
7
|
import { ShippingMethod } from "../shippingMethod/ShippingMethod";
|
|
8
|
+
import { PricingCashRoundingConfig } from "#types/api/global/dal/PricingCashRoundingConfig";
|
|
7
9
|
export interface SalesChannelContext {
|
|
8
|
-
|
|
9
|
-
currentCustomerGroup?: {
|
|
10
|
-
name?: string;
|
|
11
|
-
displayGross?: boolean;
|
|
12
|
-
};
|
|
13
|
-
fallbackCustomerGroup?: {
|
|
14
|
-
name?: string;
|
|
15
|
-
displayGross?: boolean;
|
|
16
|
-
};
|
|
17
|
-
currency?: Currency;
|
|
18
|
-
salesChannel?: SalesChannel;
|
|
19
|
-
taxRules?: Array<{
|
|
20
|
-
taxRate?: number;
|
|
21
|
-
name?: string;
|
|
22
|
-
}>;
|
|
23
|
-
customer?: Customer;
|
|
24
|
-
paymentMethod?: PaymentMethod;
|
|
25
|
-
shippingLocation?: CartDeliveryShippingLocation;
|
|
26
|
-
shippingMethod?: ShippingMethod;
|
|
10
|
+
apiAlias: "sales_channel_context";
|
|
27
11
|
context?: {
|
|
12
|
+
apiAlias: "context";
|
|
13
|
+
considerInheritance?: boolean;
|
|
28
14
|
versionId?: string;
|
|
29
15
|
currencyId?: string;
|
|
30
16
|
currencyFactor?: number;
|
|
31
17
|
currencyPrecision?: number;
|
|
32
|
-
languageIdChain?: string
|
|
18
|
+
languageIdChain?: Array<string>;
|
|
19
|
+
rounding?: PricingCashRoundingConfig;
|
|
33
20
|
scope?: string;
|
|
34
|
-
source?:
|
|
21
|
+
source?: any;
|
|
35
22
|
taxState?: "gross" | "net";
|
|
36
|
-
useCache?: boolean;
|
|
37
23
|
};
|
|
24
|
+
currency?: Currency;
|
|
25
|
+
currentCustomerGroup?: CustomerGroup;
|
|
26
|
+
fallbackCustomerGroup?: CustomerGroup;
|
|
27
|
+
customer?: Customer;
|
|
28
|
+
imitatingUserId?: string;
|
|
29
|
+
itemRounding?: PricingCashRoundingConfig;
|
|
30
|
+
languageInfo: {
|
|
31
|
+
localeCode: string;
|
|
32
|
+
name: string;
|
|
33
|
+
};
|
|
34
|
+
paymentMethod?: PaymentMethod;
|
|
35
|
+
salesChannel?: SalesChannel;
|
|
36
|
+
shippingLocation?: CartDeliveryShippingLocation;
|
|
37
|
+
shippingMethod?: ShippingMethod;
|
|
38
|
+
taxRules?: Array<{
|
|
39
|
+
taxRate?: number;
|
|
40
|
+
name?: string;
|
|
41
|
+
}>;
|
|
42
|
+
token?: string;
|
|
38
43
|
}
|
|
@@ -81,7 +81,6 @@ export interface CustomerRegisterRequest {
|
|
|
81
81
|
storefrontUrl: string;
|
|
82
82
|
billingAddress: CustomerAddress;
|
|
83
83
|
shippingAddress?: CustomerAddress;
|
|
84
|
-
accountType?: "private" | "business";
|
|
85
84
|
guest?: boolean;
|
|
86
85
|
birthdayDay?: number;
|
|
87
86
|
birthdayMonth?: number;
|
|
@@ -89,8 +88,14 @@ export interface CustomerRegisterRequest {
|
|
|
89
88
|
title?: string;
|
|
90
89
|
affiliateCode?: string;
|
|
91
90
|
campaignCode?: string;
|
|
91
|
+
/** @default "private" */
|
|
92
|
+
accountType?: "private" | "business";
|
|
93
|
+
company?: string;
|
|
94
|
+
vatIds?: Array<string>;
|
|
92
95
|
}
|
|
93
|
-
export type CustomerRegisterResponse =
|
|
96
|
+
export type CustomerRegisterResponse = {
|
|
97
|
+
accountType: "private" | "business";
|
|
98
|
+
};
|
|
94
99
|
export type CustomerRegisterGroupConfigResponse = CustomerGroup;
|
|
95
100
|
export interface CustomerRegistrationConfirmRequest {
|
|
96
101
|
hash: string;
|
|
@@ -9,7 +9,7 @@ export interface CartRemoveItemsRequest {
|
|
|
9
9
|
}
|
|
10
10
|
export type CartRemoveItemsResponse = Cart;
|
|
11
11
|
export interface CartUpdateItemsRequest {
|
|
12
|
-
items?: Array<LineItem
|
|
12
|
+
items?: Array<Partial<LineItem>>;
|
|
13
13
|
}
|
|
14
14
|
export type CartUpdateItemsResponse = Cart;
|
|
15
15
|
export interface CartDeleteResponse {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devite/shopware-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Third party API client for Shopware 6.",
|
|
5
5
|
"repository": "devite-io/shopware-client",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,19 +41,19 @@
|
|
|
41
41
|
"dist"
|
|
42
42
|
],
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@types/node": "^22.10
|
|
44
|
+
"@types/node": "^22.13.10",
|
|
45
45
|
"changelogen": "^0.5.7",
|
|
46
|
-
"eslint": "^9.
|
|
47
|
-
"prettier": "^3.
|
|
48
|
-
"typescript": "^5.
|
|
49
|
-
"typescript-eslint": "^8.
|
|
50
|
-
"unbuild": "^3.
|
|
51
|
-
"vitest": "^2.1.
|
|
46
|
+
"eslint": "^9.22.0",
|
|
47
|
+
"prettier": "^3.5.3",
|
|
48
|
+
"typescript": "^5.8.2",
|
|
49
|
+
"typescript-eslint": "^8.26.1",
|
|
50
|
+
"unbuild": "^3.5.0",
|
|
51
|
+
"vitest": "^2.1.9"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"ofetch": "^1.4.1",
|
|
55
|
-
"ohash": "^1.1.
|
|
56
|
-
"qs": "^6.
|
|
55
|
+
"ohash": "^1.1.6",
|
|
56
|
+
"qs": "^6.14.0"
|
|
57
57
|
},
|
|
58
58
|
"imports": {
|
|
59
59
|
"#types/*": "./dist/types/*.d.ts"
|
|
@@ -64,6 +64,6 @@
|
|
|
64
64
|
"lint": "eslint src/**/*.ts* --fix && tsc --noEmit",
|
|
65
65
|
"test": "vitest run --passWithNoTests --typecheck",
|
|
66
66
|
"test:watch": "vitest watch --typecheck",
|
|
67
|
-
"release": "pnpm lint && pnpm test && pnpm build && changelogen --release && pnpm publish --access=public && git push --follow-tags"
|
|
67
|
+
"release": "pnpm lint && pnpm test && pnpm build && git push && changelogen --release && pnpm publish --access=public && git push --follow-tags"
|
|
68
68
|
}
|
|
69
69
|
}
|