Skip to content

Commit 28b1c79

Browse files
committed
chore(objectstorage): migrate to new SDK structure
relates to STACKITCLI-369
1 parent d1a943f commit 28b1c79

File tree

29 files changed

+217
-271
lines changed

29 files changed

+217
-271
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ require (
1515
github.com/spf13/cobra v1.10.2
1616
github.com/spf13/pflag v1.0.10
1717
github.com/spf13/viper v1.21.0
18-
github.com/stackitcloud/stackit-sdk-go/core v0.22.0
18+
github.com/stackitcloud/stackit-sdk-go/core v0.23.0
1919
github.com/stackitcloud/stackit-sdk-go/services/alb v0.10.0
2020
github.com/stackitcloud/stackit-sdk-go/services/authorization v0.12.0
2121
github.com/stackitcloud/stackit-sdk-go/services/cdn v1.10.0
@@ -269,7 +269,7 @@ require (
269269
github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v1.8.0
270270
github.com/stackitcloud/stackit-sdk-go/services/logme v0.25.6
271271
github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.25.6
272-
github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.4.5
272+
github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.7.0
273273
github.com/stackitcloud/stackit-sdk-go/services/observability v0.17.0
274274
github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v0.26.0
275275
github.com/stackitcloud/stackit-sdk-go/services/redis v0.25.6

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -596,8 +596,8 @@ github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
596596
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
597597
github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0=
598598
github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
599-
github.com/stackitcloud/stackit-sdk-go/core v0.22.0 h1:6rViz7GnNwXSh51Lur5xuDzO8EWSZfN9J0HvEkBKq6c=
600-
github.com/stackitcloud/stackit-sdk-go/core v0.22.0/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI=
599+
github.com/stackitcloud/stackit-sdk-go/core v0.23.0 h1:zPrOhf3Xe47rKRs1fg/AqKYUiJJRYjdcv+3qsS50mEs=
600+
github.com/stackitcloud/stackit-sdk-go/core v0.23.0/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI=
601601
github.com/stackitcloud/stackit-sdk-go/services/alb v0.10.0 h1:V9+885qkSv621rZZatg1YE5ENM1ElALxQDJsh+hDIUg=
602602
github.com/stackitcloud/stackit-sdk-go/services/alb v0.10.0/go.mod h1:V6+MolxM/M2FWyWZA+FRFKEzzUe10MU9eEVfMvxHGi8=
603603
github.com/stackitcloud/stackit-sdk-go/services/authorization v0.12.0 h1:HxPgBu04j5tj6nfZ2r0l6v4VXC0/tYOGe4sA5Addra8=
@@ -626,8 +626,8 @@ github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.25.6 h1:Y/byRjX2u/OZl
626626
github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.25.6/go.mod h1:sY66ZgCgBc1mScPV95ek5WtUEGYizdP1RMsGaqbdbhw=
627627
github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v1.5.8 h1:S7t4wcT6SN8ZzdoY8d6VbF903zFpGjzqrU0FN27rJPg=
628628
github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v1.5.8/go.mod h1:CdrhFUsBO7/iJleCc2yQjDChIbG6YaxKNBQRNCjgcF4=
629-
github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.4.5 h1:4gpvB6t7d2lLjInoTxcvjL9jCpBl5EDfYe5yUtR1MvA=
630-
github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.4.5/go.mod h1:Bdcd59sRySyhfSUCy+5BNkp5w9PECmrywdvt+ORMKnI=
629+
github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.7.0 h1:UxnbsKm6PQV8Gudw/EhySaEh9q1xSaTG8mzJz1EvhnE=
630+
github.com/stackitcloud/stackit-sdk-go/services/objectstorage v1.7.0/go.mod h1:RFL4h6JZvpsyFYbdJ3+eINEkletzJQTfrPdd+yPT/fU=
631631
github.com/stackitcloud/stackit-sdk-go/services/observability v0.17.0 h1:LGwCvvST0fwUgZ6bOxYIfu45qqTgv421ZS07UhKjZL8=
632632
github.com/stackitcloud/stackit-sdk-go/services/observability v0.17.0/go.mod h1:9KdrXC5JS30Ay3mR0adb3vNdhca+qxiy/cPF5P4wehQ=
633633
github.com/stackitcloud/stackit-sdk-go/services/opensearch v0.24.6 h1:oTVx1+O177Ojn8OvXIOUbRSwtx7L59jhxDPrZEQFOfQ=

internal/cmd/object-storage/bucket/create/create.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import (
1616
"github.com/stackitcloud/stackit-cli/internal/pkg/spinner"
1717

1818
"github.com/spf13/cobra"
19-
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage"
20-
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage/wait"
19+
objectstorage "github.com/stackitcloud/stackit-sdk-go/services/objectstorage/v2api"
20+
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage/v2api/wait"
2121
)
2222

2323
const (
@@ -60,7 +60,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
6060
}
6161

6262
// Check if the project is enabled before trying to create
63-
enabled, err := utils.ProjectEnabled(ctx, apiClient, model.ProjectId, model.Region)
63+
enabled, err := utils.ProjectEnabled(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region)
6464
if err != nil {
6565
return fmt.Errorf("check if Object Storage is enabled: %w", err)
6666
}
@@ -81,7 +81,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
8181
if !model.Async {
8282
s := spinner.New(params.Printer)
8383
s.Start("Creating bucket")
84-
_, err = wait.CreateBucketWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.BucketName).WaitWithContext(ctx)
84+
_, err = wait.CreateBucketWaitHandler(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.BucketName).WaitWithContext(ctx)
8585
if err != nil {
8686
return fmt.Errorf("wait for Object Storage bucket creation: %w", err)
8787
}
@@ -112,7 +112,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu
112112
}
113113

114114
func buildRequest(ctx context.Context, model *inputModel, apiClient *objectstorage.APIClient) objectstorage.ApiCreateBucketRequest {
115-
req := apiClient.CreateBucket(ctx, model.ProjectId, model.Region, model.BucketName)
115+
req := apiClient.DefaultAPI.CreateBucket(ctx, model.ProjectId, model.Region, model.BucketName)
116116
return req
117117
}
118118

internal/cmd/object-storage/bucket/create/create_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import (
1313
"github.com/google/go-cmp/cmp"
1414
"github.com/google/go-cmp/cmp/cmpopts"
1515
"github.com/google/uuid"
16-
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage"
16+
objectstorage "github.com/stackitcloud/stackit-sdk-go/services/objectstorage/v2api"
1717
)
1818

1919
type testCtxKey struct{}
2020

2121
var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo")
22-
var testClient = &objectstorage.APIClient{}
22+
var testClient = &objectstorage.APIClient{DefaultAPI: &objectstorage.DefaultAPIService{}}
2323
var testProjectId = uuid.NewString()
2424

2525
const (
@@ -64,7 +64,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel {
6464
}
6565

6666
func fixtureRequest(mods ...func(request *objectstorage.ApiCreateBucketRequest)) objectstorage.ApiCreateBucketRequest {
67-
request := testClient.CreateBucket(testCtx, testProjectId, testRegion, testBucketName)
67+
request := testClient.DefaultAPI.CreateBucket(testCtx, testProjectId, testRegion, testBucketName)
6868
for _, mod := range mods {
6969
mod(&request)
7070
}
@@ -161,7 +161,7 @@ func TestBuildRequest(t *testing.T) {
161161
request := buildRequest(testCtx, tt.model, testClient)
162162

163163
diff := cmp.Diff(request, tt.expectedRequest,
164-
cmp.AllowUnexported(tt.expectedRequest),
164+
cmp.AllowUnexported(tt.expectedRequest, objectstorage.DefaultAPIService{}),
165165
cmpopts.EquateComparable(testCtx),
166166
)
167167
if diff != "" {

internal/cmd/object-storage/bucket/delete/delete.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import (
1515
"github.com/stackitcloud/stackit-cli/internal/pkg/spinner"
1616

1717
"github.com/spf13/cobra"
18-
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage"
19-
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage/wait"
18+
objectstorage "github.com/stackitcloud/stackit-sdk-go/services/objectstorage/v2api"
19+
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage/v2api/wait"
2020
)
2121

2222
const (
@@ -69,7 +69,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
6969
if !model.Async {
7070
s := spinner.New(params.Printer)
7171
s.Start("Deleting bucket")
72-
_, err = wait.DeleteBucketWaitHandler(ctx, apiClient, model.ProjectId, model.Region, model.BucketName).WaitWithContext(ctx)
72+
_, err = wait.DeleteBucketWaitHandler(ctx, apiClient.DefaultAPI, model.ProjectId, model.Region, model.BucketName).WaitWithContext(ctx)
7373
if err != nil {
7474
return fmt.Errorf("wait for Object Storage bucket deletion: %w", err)
7575
}
@@ -105,6 +105,6 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu
105105
}
106106

107107
func buildRequest(ctx context.Context, model *inputModel, apiClient *objectstorage.APIClient) objectstorage.ApiDeleteBucketRequest {
108-
req := apiClient.DeleteBucket(ctx, model.ProjectId, model.Region, model.BucketName)
108+
req := apiClient.DefaultAPI.DeleteBucket(ctx, model.ProjectId, model.Region, model.BucketName)
109109
return req
110110
}

internal/cmd/object-storage/bucket/delete/delete_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import (
1010
"github.com/google/go-cmp/cmp"
1111
"github.com/google/go-cmp/cmp/cmpopts"
1212
"github.com/google/uuid"
13-
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage"
13+
objectstorage "github.com/stackitcloud/stackit-sdk-go/services/objectstorage/v2api"
1414
)
1515

1616
type testCtxKey struct{}
1717

1818
var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo")
19-
var testClient = &objectstorage.APIClient{}
19+
var testClient = &objectstorage.APIClient{DefaultAPI: &objectstorage.DefaultAPIService{}}
2020
var testProjectId = uuid.NewString()
2121

2222
const (
@@ -61,7 +61,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel {
6161
}
6262

6363
func fixtureRequest(mods ...func(request *objectstorage.ApiDeleteBucketRequest)) objectstorage.ApiDeleteBucketRequest {
64-
request := testClient.DeleteBucket(testCtx, testProjectId, testRegion, testBucketName)
64+
request := testClient.DefaultAPI.DeleteBucket(testCtx, testProjectId, testRegion, testBucketName)
6565
for _, mod := range mods {
6666
mod(&request)
6767
}
@@ -158,7 +158,7 @@ func TestBuildRequest(t *testing.T) {
158158
request := buildRequest(testCtx, tt.model, testClient)
159159

160160
diff := cmp.Diff(request, tt.expectedRequest,
161-
cmp.AllowUnexported(tt.expectedRequest),
161+
cmp.AllowUnexported(tt.expectedRequest, objectstorage.DefaultAPIService{}),
162162
cmpopts.EquateComparable(testCtx),
163163
)
164164
if diff != "" {

internal/cmd/object-storage/bucket/describe/describe.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ import (
1313
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
1414
"github.com/stackitcloud/stackit-cli/internal/pkg/services/object-storage/client"
1515
"github.com/stackitcloud/stackit-cli/internal/pkg/tables"
16-
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
1716

1817
"github.com/spf13/cobra"
19-
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage"
18+
objectstorage "github.com/stackitcloud/stackit-sdk-go/services/objectstorage/v2api"
2019
)
2120

2221
const (
@@ -61,7 +60,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
6160
return fmt.Errorf("read Object Storage bucket: %w", err)
6261
}
6362

64-
return outputResult(params.Printer, model.OutputFormat, resp.Bucket)
63+
return outputResult(params.Printer, model.OutputFormat, resp)
6564
},
6665
}
6766
return cmd
@@ -85,24 +84,24 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu
8584
}
8685

8786
func buildRequest(ctx context.Context, model *inputModel, apiClient *objectstorage.APIClient) objectstorage.ApiGetBucketRequest {
88-
req := apiClient.GetBucket(ctx, model.ProjectId, model.Region, model.BucketName)
87+
req := apiClient.DefaultAPI.GetBucket(ctx, model.ProjectId, model.Region, model.BucketName)
8988
return req
9089
}
9190

92-
func outputResult(p *print.Printer, outputFormat string, bucket *objectstorage.Bucket) error {
93-
if bucket == nil {
94-
return fmt.Errorf("bucket is empty")
91+
func outputResult(p *print.Printer, outputFormat string, resp *objectstorage.GetBucketResponse) error {
92+
if resp == nil {
93+
return fmt.Errorf("response is nil")
9594
}
9695

97-
return p.OutputResult(outputFormat, bucket, func() error {
96+
return p.OutputResult(outputFormat, resp.Bucket, func() error {
9897
table := tables.NewTable()
99-
table.AddRow("Name", utils.PtrString(bucket.Name))
98+
table.AddRow("Name", resp.Bucket.Name)
10099
table.AddSeparator()
101-
table.AddRow("Region", utils.PtrString(bucket.Region))
100+
table.AddRow("Region", resp.Bucket.Region)
102101
table.AddSeparator()
103-
table.AddRow("URL (Path Style)", utils.PtrString(bucket.UrlPathStyle))
102+
table.AddRow("URL (Path Style)", resp.Bucket.UrlPathStyle)
104103
table.AddSeparator()
105-
table.AddRow("URL (Virtual Hosted Style)", utils.PtrString(bucket.UrlVirtualHostedStyle))
104+
table.AddRow("URL (Virtual Hosted Style)", resp.Bucket.UrlVirtualHostedStyle)
106105
table.AddSeparator()
107106
err := table.Display(p)
108107
if err != nil {

internal/cmd/object-storage/bucket/describe/describe_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import (
1313
"github.com/google/go-cmp/cmp"
1414
"github.com/google/go-cmp/cmp/cmpopts"
1515
"github.com/google/uuid"
16-
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage"
16+
objectstorage "github.com/stackitcloud/stackit-sdk-go/services/objectstorage/v2api"
1717
)
1818

1919
type testCtxKey struct{}
2020

2121
var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo")
22-
var testClient = &objectstorage.APIClient{}
22+
var testClient = &objectstorage.APIClient{DefaultAPI: &objectstorage.DefaultAPIService{}}
2323
var testProjectId = uuid.NewString()
2424

2525
const (
@@ -64,7 +64,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel {
6464
}
6565

6666
func fixtureRequest(mods ...func(request *objectstorage.ApiGetBucketRequest)) objectstorage.ApiGetBucketRequest {
67-
request := testClient.GetBucket(testCtx, testProjectId, testRegion, testBucketName)
67+
request := testClient.DefaultAPI.GetBucket(testCtx, testProjectId, testRegion, testBucketName)
6868
for _, mod := range mods {
6969
mod(&request)
7070
}
@@ -161,7 +161,7 @@ func TestBuildRequest(t *testing.T) {
161161
request := buildRequest(testCtx, tt.model, testClient)
162162

163163
diff := cmp.Diff(request, tt.expectedRequest,
164-
cmp.AllowUnexported(tt.expectedRequest),
164+
cmp.AllowUnexported(tt.expectedRequest, objectstorage.DefaultAPIService{}),
165165
cmpopts.EquateComparable(testCtx),
166166
)
167167
if diff != "" {
@@ -174,7 +174,7 @@ func TestBuildRequest(t *testing.T) {
174174
func TestOutputResult(t *testing.T) {
175175
type args struct {
176176
outputFormat string
177-
bucket *objectstorage.Bucket
177+
resp *objectstorage.GetBucketResponse
178178
}
179179
tests := []struct {
180180
name string
@@ -187,9 +187,9 @@ func TestOutputResult(t *testing.T) {
187187
wantErr: true,
188188
},
189189
{
190-
name: "set empty bucket",
190+
name: "set empty response",
191191
args: args{
192-
bucket: &objectstorage.Bucket{},
192+
resp: &objectstorage.GetBucketResponse{},
193193
},
194194
wantErr: false,
195195
},
@@ -198,7 +198,7 @@ func TestOutputResult(t *testing.T) {
198198
p.Cmd = NewCmd(&types.CmdParams{Printer: p})
199199
for _, tt := range tests {
200200
t.Run(tt.name, func(t *testing.T) {
201-
if err := outputResult(p, tt.args.outputFormat, tt.args.bucket); (err != nil) != tt.wantErr {
201+
if err := outputResult(p, tt.args.outputFormat, tt.args.resp); (err != nil) != tt.wantErr {
202202
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
203203
}
204204
})

internal/cmd/object-storage/bucket/list/list.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ import (
1616
"github.com/stackitcloud/stackit-cli/internal/pkg/projectname"
1717
"github.com/stackitcloud/stackit-cli/internal/pkg/services/object-storage/client"
1818
"github.com/stackitcloud/stackit-cli/internal/pkg/tables"
19-
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
20-
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage"
19+
objectstorage "github.com/stackitcloud/stackit-sdk-go/services/objectstorage/v2api"
2120
)
2221

2322
const (
@@ -114,7 +113,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
114113
}
115114

116115
func buildRequest(ctx context.Context, model *inputModel, apiClient *objectstorage.APIClient) objectstorage.ApiListBucketsRequest {
117-
req := apiClient.ListBuckets(ctx, model.ProjectId, model.Region)
116+
req := apiClient.DefaultAPI.ListBuckets(ctx, model.ProjectId, model.Region)
118117
return req
119118
}
120119

@@ -134,10 +133,10 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, buckets [
134133
for i := range buckets {
135134
bucket := buckets[i]
136135
table.AddRow(
137-
utils.PtrString(bucket.Name),
138-
utils.PtrString(bucket.Region),
139-
utils.PtrString(bucket.UrlPathStyle),
140-
utils.PtrString(bucket.UrlVirtualHostedStyle),
136+
bucket.Name,
137+
bucket.Region,
138+
bucket.UrlPathStyle,
139+
bucket.UrlVirtualHostedStyle,
141140
)
142141
}
143142
err := table.Display(p)

internal/cmd/object-storage/bucket/list/list_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ import (
1414
"github.com/google/go-cmp/cmp"
1515
"github.com/google/go-cmp/cmp/cmpopts"
1616
"github.com/google/uuid"
17-
"github.com/stackitcloud/stackit-sdk-go/services/objectstorage"
17+
objectstorage "github.com/stackitcloud/stackit-sdk-go/services/objectstorage/v2api"
1818
)
1919

2020
type testCtxKey struct{}
2121

2222
var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo")
23-
var testClient = &objectstorage.APIClient{}
23+
var testClient = &objectstorage.APIClient{DefaultAPI: &objectstorage.DefaultAPIService{}}
2424
var testProjectId = uuid.NewString()
2525
var testRegion = "eu01"
2626

@@ -52,7 +52,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel {
5252
}
5353

5454
func fixtureRequest(mods ...func(request *objectstorage.ApiListBucketsRequest)) objectstorage.ApiListBucketsRequest {
55-
request := testClient.ListBuckets(testCtx, testProjectId, testRegion)
55+
request := testClient.DefaultAPI.ListBuckets(testCtx, testProjectId, testRegion)
5656
for _, mod := range mods {
5757
mod(&request)
5858
}
@@ -140,7 +140,7 @@ func TestBuildRequest(t *testing.T) {
140140
request := buildRequest(testCtx, tt.model, testClient)
141141

142142
diff := cmp.Diff(request, tt.expectedRequest,
143-
cmp.AllowUnexported(tt.expectedRequest),
143+
cmp.AllowUnexported(tt.expectedRequest, objectstorage.DefaultAPIService{}),
144144
cmpopts.EquateComparable(testCtx),
145145
)
146146
if diff != "" {

0 commit comments

Comments
 (0)