diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 4acfbc302..0d86ecbd7 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: actions/checkout@v2 - name: Set up QEMU uses: docker/setup-qemu-action@v1 @@ -55,11 +55,11 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: actions/checkout@v2 - name: Package charts run: make helm-generate - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: charts path: charts/*.tgz diff --git a/.github/workflows/chart-tests.yml b/.github/workflows/chart-tests.yml index d46f50509..f87933739 100644 --- a/.github/workflows/chart-tests.yml +++ b/.github/workflows/chart-tests.yml @@ -41,7 +41,7 @@ jobs: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: azure/setup-kubectl@v3 with: @@ -176,7 +176,7 @@ jobs: kubectl logs -l "release=harbor-redis" --all-containers > /tmp/harbor/redis.log ls -l /tmp/harbor - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: harbor_chart @@ -189,7 +189,7 @@ jobs: kind export logs --name harbor /tmp/logs ls -l /tmp/logs - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: kind_chart diff --git a/.github/workflows/contour-tests.yml b/.github/workflows/contour-tests.yml index 46c09d3f3..8ea048fc9 100644 --- a/.github/workflows/contour-tests.yml +++ b/.github/workflows/contour-tests.yml @@ -43,7 +43,7 @@ jobs: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: azure/setup-kubectl@v3 with: @@ -198,7 +198,7 @@ jobs: kubectl -n cluster-sample-ns logs -l "app.kubernetes.io/component=redis" --all-containers > /tmp/harbor/redis.log ls -l /tmp/harbor - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: contour_harbor_v${{ matrix.k8sVersion }}_v${{ matrix.certManager }}_${{ matrix.samples }} @@ -211,7 +211,7 @@ jobs: kind export logs --name harbor /tmp/logs ls -l /tmp/logs - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: contour_kind_v${{ matrix.k8sVersion }}_v${{ matrix.certManager }}_${{ matrix.samples }} diff --git a/.github/workflows/harbor-e2e-tests.yml b/.github/workflows/harbor-e2e-tests.yml index 490319432..96424b046 100644 --- a/.github/workflows/harbor-e2e-tests.yml +++ b/.github/workflows/harbor-e2e-tests.yml @@ -46,7 +46,7 @@ jobs: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: azure/setup-kubectl@v3 with: @@ -201,7 +201,7 @@ jobs: kubectl -n cluster-sample-ns logs -l "app.kubernetes.io/component=redis" --all-containers > /tmp/harbor/redis.log ls -l /tmp/harbor - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: harbor_v${{ matrix.k8sVersion }}_v${{ matrix.certManager }}_${{ matrix.samples }} @@ -214,7 +214,7 @@ jobs: kind export logs --name harbor /tmp/logs ls -l /tmp/logs - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: kind_v${{ matrix.k8sVersion }}_v${{ matrix.certManager }}_${{ matrix.samples }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 77fbc6023..7818a29d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: run: git fetch --prune --unshallow - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - name: prepare changelog run: | tag=${{ github.ref }} @@ -45,7 +45,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: actions/checkout@v2 - name: Set up QEMU uses: docker/setup-qemu-action@v1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7466a8611..c5a342541 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,7 +19,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: actions/checkout@v2 - run: | docker buildx create --use @@ -39,7 +39,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: actions/checkout@v2 - run: make go-lint @@ -49,7 +49,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: actions/checkout@v2 - run: make go-dependencies-test @@ -59,7 +59,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: actions/checkout@v2 - run: make generated-diff-test @@ -75,7 +75,7 @@ jobs: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - name: Cache go mod uses: actions/cache@v2 @@ -116,7 +116,7 @@ jobs: kind export logs --name harbor /tmp/logs ls -l /tmp/logs - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: ${{ failure() }} with: name: kind_go-tests @@ -129,7 +129,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: actions/checkout@v2 - run: make manifests - uses: azure/k8s-bake@v1 @@ -144,7 +144,7 @@ jobs: steps: - uses: actions/setup-go@v2 with: - go-version: 1.18 + go-version: 1.22 - uses: actions/checkout@v2 - run: make manifests - uses: azure/k8s-bake@v1 diff --git a/.golangci.yml b/.golangci.yml index 673cfc808..f05a54e4a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,10 +1,11 @@ run: deadline: 10m modules-download-mode: readonly - skip-files: +issue: + exclude-files: - pkged.go - ".*/zz_generated.*\\.go" - skip-dirs: + exclude-dirs: - bin - dist @@ -12,61 +13,54 @@ linters: enable: - asciicheck - bodyclose - - deadcode - - depguard - dogsled - dupl - errcheck - errorlint - exhaustive - - exportloopref - - funlen - - gci - gochecknoinits - - gocognit - goconst - - gocritic - gocyclo - - godot - - goerr113 - gofmt - - gofumpt - goheader - goimports - - revive - - gomnd - gomodguard - goprintffuncname - - gosec - gosimple - - govet - ineffassign # - interfacer # - maligned - misspell - - nakedret - - nestif - - nlreturn - noctx - - nolintlint - prealloc - rowserrcheck - - exportloopref - sqlclosecheck - - staticcheck - - structcheck - stylecheck - testpackage - tparallel - typecheck - unconvert - - unparam - unused - - varcheck + disable: + - gocognit + - err113 + - nestif + - gocritic + - funlen + - godot + - gci - whitespace + - unparam + - nlreturn + - gofumpt - wsl - disable: - - exhaustivestruct + - govet + - gosec + - nakedret + - nolintlint + - revive + - depguard + - staticcheck - lll - gochecknoglobals - godox diff --git a/Dockerfile b/Dockerfile index 13d62062e..01ad7e821 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18.3 as build +FROM golang:1.22.6 as build WORKDIR /workspace COPY . . RUN CGO_ENABLED=0 GOOS=linux GOARCH=$(go env GOARCH) go build -o manager main.go diff --git a/Makefile b/Makefile index 53412c4b1..32cd76d99 100644 --- a/Makefile +++ b/Makefile @@ -139,7 +139,7 @@ helm-postgres-operator: helm $(CHARTS_DIRECTORY)/postgres-operator/values.yaml $(MAKE) kube-namespace $(HELM) repo add zalando https://opensource.zalando.com/postgres-operator/charts/postgres-operator $(HELM) repo update - $(HELM) upgrade --namespace "$(NAMESPACE)" --install postgres-operator zalando/postgres-operator --version 1.7.0 -f $(CHARTS_DIRECTORY)/postgres-operator/values.yaml + $(HELM) upgrade --namespace "$(NAMESPACE)" --install postgres-operator zalando/postgres-operator --version 1.9.0 -f $(CHARTS_DIRECTORY)/postgres-operator/values.yaml helm-install: helm helm-generate helm-minio-operator helm-redis-operator helm-postgres-operator $(MAKE) kube-namespace @@ -530,7 +530,7 @@ clean: # find or download controller-gen # download controller-gen if necessary -CONTROLLER_GEN_VERSION := 0.9.2 +CONTROLLER_GEN_VERSION := 0.16.2 CONTROLLER_GEN := $(BIN)/controller-gen .PHONY: controller-gen @@ -573,7 +573,7 @@ $(MARKDOWNLINT): # find or download golangci-lint # download golangci-lint if necessary GOLANGCI_LINT := $(BIN)/golangci-lint -GOLANGCI_LINT_VERSION := 1.49.0 +GOLANGCI_LINT_VERSION := 1.60.3 .PHONY: golangci-lint golangci-lint: @@ -661,7 +661,7 @@ $(GORELEASER): # find or download stringer # download stringer if necessary -STRINGER_VERSION := v0.11.0 +STRINGER_VERSION := v0.25.0 STRINGER := $(BIN)/stringer .PHONY: stringer diff --git a/apis/goharbor.io/v1alpha3/zz_generated.deepcopy.go b/apis/goharbor.io/v1alpha3/zz_generated.deepcopy.go index 74f87ed7c..e6f02ba2b 100644 --- a/apis/goharbor.io/v1alpha3/zz_generated.deepcopy.go +++ b/apis/goharbor.io/v1alpha3/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // Code generated by controller-gen. DO NOT EDIT. @@ -2886,7 +2885,8 @@ func (in *RegistryHTTPSpec) DeepCopyInto(out *RegistryHTTPSpec) { if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make([]string, len(*in)) copy(*out, *in) } @@ -2952,7 +2952,8 @@ func (in *RegistryHealthHTTPSpec) DeepCopyInto(out *RegistryHealthHTTPSpec) { if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make([]string, len(*in)) copy(*out, *in) } @@ -3261,7 +3262,8 @@ func (in *RegistryNotificationEndpointSpec) DeepCopyInto(out *RegistryNotificati if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make([]string, len(*in)) copy(*out, *in) } diff --git a/apis/goharbor.io/v1beta1/zz_generated.deepcopy.go b/apis/goharbor.io/v1beta1/zz_generated.deepcopy.go index 89393cb92..7833b5d15 100644 --- a/apis/goharbor.io/v1beta1/zz_generated.deepcopy.go +++ b/apis/goharbor.io/v1beta1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // Code generated by controller-gen. DO NOT EDIT. @@ -4009,7 +4008,8 @@ func (in *RegistryHTTPSpec) DeepCopyInto(out *RegistryHTTPSpec) { if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make([]string, len(*in)) copy(*out, *in) } @@ -4075,7 +4075,8 @@ func (in *RegistryHealthHTTPSpec) DeepCopyInto(out *RegistryHealthHTTPSpec) { if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make([]string, len(*in)) copy(*out, *in) } @@ -4384,7 +4385,8 @@ func (in *RegistryNotificationEndpointSpec) DeepCopyInto(out *RegistryNotificati if val == nil { (*out)[key] = nil } else { - in, out := &val, &outVal + inVal := (*in)[key] + in, out := &inVal, &outVal *out = make([]string, len(*in)) copy(*out, *in) } diff --git a/apis/meta/v1alpha1/zz_generated.deepcopy.go b/apis/meta/v1alpha1/zz_generated.deepcopy.go index 0bd50fd50..72cbf8a07 100644 --- a/apis/meta/v1alpha1/zz_generated.deepcopy.go +++ b/apis/meta/v1alpha1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // Code generated by controller-gen. DO NOT EDIT. diff --git a/charts/harbor-operator/Chart.lock b/charts/harbor-operator/Chart.lock index 17f534c52..72e53fdbb 100644 --- a/charts/harbor-operator/Chart.lock +++ b/charts/harbor-operator/Chart.lock @@ -7,6 +7,6 @@ dependencies: version: 3.1.4 - name: postgres-operator repository: https://opensource.zalando.com/postgres-operator/charts/postgres-operator - version: 1.7.0 + version: 1.9.0 digest: sha256:a457f468187c5ac3e0279e64e9a565335b0a5455400ccc818f29e4758c8074d0 generated: "2023-02-22T10:57:46.632256448+01:00" diff --git a/charts/harbor-operator/Chart.yaml b/charts/harbor-operator/Chart.yaml index 08080aec4..d8bb55da1 100644 --- a/charts/harbor-operator/Chart.yaml +++ b/charts/harbor-operator/Chart.yaml @@ -33,7 +33,7 @@ dependencies: tags: - cache - name: postgres-operator - version: 1.7.0 + version: 1.9.0 condition: postgres-operator.enabled repository: https://opensource.zalando.com/postgres-operator/charts/postgres-operator tags: diff --git a/docs/development.md b/docs/development.md index a199a42df..31a3886db 100644 --- a/docs/development.md +++ b/docs/development.md @@ -15,7 +15,7 @@ Have a look in [CONTRIBUTING.md](https://github.com/goharbor/harbor-operator/blo ### Packages -- [Go 1.18+](https://golang.org/) +- [Go 1.22+](https://golang.org/) - [Helm](https://helm.sh/) - [Docker](https://docker.com) & [Docker Compose](https://docs.docker.com/compose/install/) - [OpenSSL](https://www.openssl.org/) diff --git a/docs/installation/enable_minio_console.md b/docs/installation/enable_minio_console.md index d8d98a43b..8bcbb9260 100644 --- a/docs/installation/enable_minio_console.md +++ b/docs/installation/enable_minio_console.md @@ -6,7 +6,7 @@ ## Prerequisites -1. `kubectl` with a proper version(v1.18.6+) is [installed](https://kubernetes.io/docs/tasks/tools/). +1. `kubectl` with a proper version(v1.22.6+) is [installed](https://kubernetes.io/docs/tasks/tools/). 1. `kustomize` (optional)with a proper version(v3.8.7+) is [installed](https://kubectl.docs.kubernetes.io/installation/kustomize/). 1. `git` (optional) is [installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). diff --git a/docs/perf/simple-perf-comprasion.md b/docs/perf/simple-perf-comprasion.md index 6b4bd8f78..5b2d17fec 100644 --- a/docs/perf/simple-perf-comprasion.md +++ b/docs/perf/simple-perf-comprasion.md @@ -24,7 +24,7 @@ Here are the network benchmark for CNI using [knb](https://github.com/InfraBuild ========================================================= Discovered CPU : Intel(R) Xeon(R) Gold 5218 CPU @ 2.30GHz Discovered Kernel : 5.4.0-66-generic - Discovered k8s version : v1.18.16+vmware.1 + Discovered k8s version : v1.22.6+vmware.1 Discovered MTU : 1450 Idle : bandwidth = 0 Mbit/s diff --git a/go.mod b/go.mod index 318f16578..f8d8e0837 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/goharbor/harbor-operator -go 1.18 +go 1.22.5 require ( github.com/Masterminds/semver v1.5.0 diff --git a/go.sum b/go.sum index 5159f46ae..ae24c2de0 100644 --- a/go.sum +++ b/go.sum @@ -130,6 +130,7 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -394,6 +395,7 @@ github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= @@ -1369,6 +1371,7 @@ go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= diff --git a/manifests/samples/full_stack.yaml b/manifests/samples/full_stack.yaml index 7fa00d43a..f79e38758 100644 --- a/manifests/samples/full_stack.yaml +++ b/manifests/samples/full_stack.yaml @@ -93,6 +93,7 @@ spec: internalTLS: enabled: true portal: {} + jobservice: {} registry: metrics: enabled: true diff --git a/pkged.go b/pkged.go index 3cb46b3e4..ba0e4bb2d 100644 --- a/pkged.go +++ b/pkged.go @@ -1,7 +1,8 @@ package main -import "github.com/markbates/pkger" - -import "github.com/markbates/pkger/pkging/mem" +import ( + "github.com/markbates/pkger" + "github.com/markbates/pkger/pkging/mem" +) var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec5ceb73a3b8b2ff5ffcf56637208c6352753e181230049331362fdd3ab5858403d8c2b0c660e353f3bfdf92c08fc97866b2b393b3f7436a6a0adbe8d16af5e3d7ad56fed34bd72f79d9bbff4f2f4eb749857ec779761be749b841f9e6b67dfc96178b4db8cd37b4d943bae9ddf76e9d72b1296fcb435eddba935db859dc7edae4cb05de96b75a3ec9a3db72836fdf32e44d4fcf8a7cb3fd146e93defd9ba8b8e94df2a8220b4ace5feb16a6ebdefd76532d6ede611dacfdaf1cf336ce7fcff2880ded2e36659aaf7bf73dfe775ee87dbee95961b6e8ddf732baa6cf9f6f7a2f2959bc7523ef6fc3b25c6ccbdbed222b48b85d94b7380937dbac2a1755768bf3f54b1affde8419a1035211a1cf68b10d53c2e658b7935f36bce995e961d1bbe7f921b8e96579b4e8ddf701c73efeb14d597bc001ee374ef88d1bce39e99ebfbb17c1ff70c37b8eebddf4d2f28f88eec94b48cac54daf6cd8440f8bba77cf0feeeeee00006ce317bd7b41e087c39b9e45d2f5aa77cfdff4f475debb1f0ec401e80f0481bbe93969d4bb17b9fe4d4fa39f2819764487e26e7a9fc2e80f1ce77f70bdfbffe56ed8bf7fdff44694c4b258603aeb8c3e78511a0a7d0108fc4dcf2ae92fa0df1f0c8581f0f9a637b9d29cbee2c01d3836e73edff494abed86122ff0fdd3b01c27489228f29f6f7a72bad9266f1c7b76c16f99e47855f6ee87f4e3aadd893e270d6e7a2a09e3922d5c5bacd9d32c8b70b3601fa7dd47ca887f7fa662942cde43cd6fc3227dadea1f7a7ca9c794419f6f7a05e3c37f7a9f56f19bd9d18df0769dfe7cd38bc26dd8bbef2d8472ab2bc33f752de1a2b17c784e873504840bc76e6a66568d66520ebdfdd604561ef806877cf7007d77ab03ab46192ca0e036816f1708f4e3a774189b3e2f29ebed9d391bd54fa99c47637b870f796d82a888b4840f52718900574320d1f15224e875a8a94d90498d098c1201bd469e7a8834b731019f84c0a9b196d4912655a62037d097139c3975a4b95baced9348730f47da30709b28a3fddc2a4ac53f434ffc33988dfe349bd1f6c5e79e026f5f220157488004afa326f46df29cca1c5ebb44898b24f2eddcccd40a0151449ec4e3465c437f3ad03598a0b14594cc4830204b3353f9488babc8b7085ee671009204afed9700485534366aa4ed098e8b147a6a037d838dfb9c8e764a5cdc2d1a2e36c606811a39b8be51ea0fb9a46b8cde31f46d82d641acaf2c79ca25aacfbbb3b9a2c79476b64f1ac9742de274258e91e656ba6237d0b30bccbb0d524685fe30626d754566f344741f9551cee84a45d759edbe98fb69264b2fd3621978560ee7798c337715fa93a700a8cb5073aaeefb40494771e0d92bbad68550c6d877eb4873627395d4589876738e627d4cf75d2e602a1fa2b151a02c3a982bab466b3b093df1a02bc6484f47953ee6253ae6b90f939565e0891512a631042ea78fe5040b96800463a56bb041e0cc37935019d42b47530f58886a9c4d4b5d932a345ec5c14c3e849eb8469a13a34caa74cd6d702635fad8205870cb48910bdcc83be81bdbd0b739e84dcf72fb054db210fa764e791d7ae20afa71fca45cac8b583ba4116e9e8ed2a9a2c7937494eb1aa9a0e6f6691f2cd80da50337e21c6bfb227aecc77a3a4cf5079d8e53a0cc260b6594eb638bc319a9a030a91c412e43df7ed6157d60366d5b9374ef1bbabf8ff1d3acdde7f393ee611e5ff2eb39a5fbffe339f474d4e84a9f8eb5d7c7bbd3be9ef65319c5addcb91554ba79aefda6d96937e712011198c4ae679ec8e98a380d280fbbfdfeb25fab0bd01357ec7d5cd0be1cf413ce5ccb49a4c5035dc16b252e56d0337878c8e3686cf0709a3f41cdddb1f70f8f4f4a661718a829d29c564e7db9784ee52cf0f607d8d24690e67254be61a6961838543f3224184b38136b6a2f22c12822cd39eb793a8a91e7529e2df1e18b7e87485339e8c10269eee1629ea74e462aa4916d486dc6c3e849c9f6353ce4b45f0e3db564345fcc11aead1a2dcfeb429eda7f8ee95e5a1c128c0402a742c0f8137a1647e9988ce83b77873429818a7808fd823ca7a366f2b0122673a7998cf2a7d6164d2bac49874811e93ab726b5d3de7e656662823cbaced65e2a6bb94142f0fdb663d6e6a9473dd366b1de9e7dd3d9f130f8f993a89384e9e6efe1cd41ffee9f859bfcfbc1cde11d18f2fcaf879b62bf7fd7177e0a6e32767fa0cd0fb4f9065dfe4b387389048320615207609f84be5e07d9be0e52691bf81607e977205530236b734d12e4ed2a0c548a0189aee4b5aef0279f6236791c8e6d0e8f2703b391d6d48f479e5e0540da9a20bac09b498233a3c6a994224d4a29dec4824d309dd3db1253907324d8354aa51dcedc5de01bc4146c827cb90c7c9be0465a224d2d702a51df95851eae169eba45ca15ecd9ae89f928a8a95ce0512cd9fa2c5d91b9852f532cba8382b547a3d6cf2241e6424faa30f321ad3fc640e2716691cedfeea85f8fb420d6d7728d057b8d33f780bd1dc50f041f7282b951fb64dfa50306fb2d0236f934730f7a3acaa127027315918861d051ca306d6bfbd3a7d9d7eff119735d7d1f325fa217ba92502c5bd9c0e5681b5d31764830383d1da5d67c7a98a457dbac02df4e824c3dc0d9d5f7070c76e9d34c1eea639547824d8ed822f2e515db9365c72b8df285c6036a49b137deb53c859e9804d99ec0b1bba3fb007de3f0cc70b9fc7a2e1079fb0a0bc6524fe5a1aed949a43d5633627d9aafd40667aa483113dbcb99e8209ec8736717bf5c62c415c38355a48c0ebaa2c7f4ff1167329c12b734614d6aa2873cb6962330e9f63ed4dc048dedfc8b771dfe8a34b2859ec4b3df3d8eaeed5fefe69ff3cde2362c8adfa95a7fdf379f5a1d1d33e0f87fd43183e1bb396651e80ffbefe19801e0fa43eea71c3363f78763fe70cc3f50e2bfe494d7e8ec244f099bd78e196ad21237c3bdb97cdc99805458b013a4edb627877d912c82335e44de6e0b3352c299b885ca8593f4e51dcad42d9c8d24fdb19b372e9ac81399d3d21fb8188f8d1a8e0a82321af4b9eb454676f4f76310e5097283801d29195b53eb741e3896b878edac9c4769e6760996f732a0cb1c958b4d9de2c5df8c72a47f36a90ea4f733a67780bfe306ef604ca5bbfee0eee7a21ce923a7fe614caf19d36f28f4afb7aac853377026ed424de210e8d7786c10aca90d9c491cf4f81d62f07552879994b6a96fb284b3cb50842fcdac285056241721d20e67743cab460f79ac332b394a151a3eaca7037dbcbdfb2a1d4de44f0e99a65d9a4e4082b181bef18235898ef1a42b721a78d6067ae2ea9986086dda3855582aab4dd9fa825c23b03b863b55e0f1040b72120067a06b451dac2d82d7b00880f3a464451d10a944205ab7f03cdfea5a978e522dc756a54fae6b4f5d774ae72ea10f095d8bfde82aae8363bd918df90a7e32395b9d12776cf291ecac4463bec2b5ed1ab339afd7f64a75a6ceeea94bf92ef5473ae7898618676e0215390bbd3dc18dcca146268bb15c63e0c44893d6787741d32334e68fce17b4cc1c519bef582a8f44639b8503cf299dc7e2310d293d3280de34c6c0e5228da5666304023636046ed3f1290d7c8bf8c02e8ea9f7d71e6cfe288d1d5e7a9cb97afa750a573e44c02558739b63a801c7a7e39a81fe80631dd8c9c29f74e9fbbf462b1622027d99e06e6c5d91996cfc2cbd2c5d0a2282d793819272314302f33c7678fbd1e724d75565d7a5e191b62751e696cfa9fc683b866beff2a708b834f4acc336ddfa2702c60bf2d4be2f18241a1be2733ada4f46ef1726adf36db8696ea961586c7e5f96d4187dcfc35f363c9d9b7383c13febe207efe6e2073c0fa4f78897787e38e4863f776ecef8fde1e33f7cfc5bd4f9c2bfb354927180be01a0afb3a3afce8fa42ceda84a09d4ec463f1e978e8d02aded4c57f481e14fd22b69ad0a097682d7e4e578844dfd255e4fafa6ba5e663b6aaf531af160c17e39fb7e7da08fcb2e5568b09422a5415f1b04791207677a79a253930e51ebbf8e4777dfa189ac11a3c96d108d9614791fb1f164a9a3253ea5f7e87ccb78a7a7a7df3934b65e02a0beb4119f3ed015bd86bebd3405eb8014a99b675507e0b10a588af0d477037df21278fb35624774c956ff865f4199c405be21fa82554020124ca4affba6dfe665eb7749059b2f78d8fa7385d26c142883b5ce300dd7f2717d3aa6fb4206824c5d86c0ad60db6f87048b8382417073e63fd48c97c837caaf65e4a2bda096143b1afe6460f8d6a87d4ee8f75b2c5825f2a4159c7374dcf8e935665bbb543e19ced2d3d595f717c7ebd7de67ec68ff1b2960a989143dd6970e3739e857db5ca4b8af8f2158259df70b599a5ef0b62db1f882afd198ec5af9313804b604a5677e9e52e55fecdf88c97ee0edb7577491e046623a1c7a163105bba67b762d251e00a981aeb48b3ca30c3dabddb7d7b49ff4a03be6fe79fc9f4ee6d3830526fbc961ba0f0e93063eacb860ee2ea1e6ece132e0268764691d7003352b8359d00407dc3705ab099af608c5144e38b68e346903bd7e1d0806097cbbc6a9b8468d35991c565f973d74368df283e97176a4913fea686a8e8e586f9486be75883cb779d5b6db1bbec082c553fb78d90767521d69943e3b8d3c718534aa3ba3d4042e1734d201835d7dd465133019d8766b686d4387353b59797a99feebdd315d1aafdf86e92e1a1e319d28fcc3599bbbf783747de90e30e8f5ab215d7f3094a49f82748cdd1f88ee03d1bd4599df86e8a060ec02feef20ba237aba8ee84ed6716d97989796d037381fc0e2bb9651b04bdc884b3adeabfe0cf5fc086945dafe60665bb298e9345aee683058c625f4c4355b677760aa676db4dd5a7952c16c985e22272cd835ced4f52bf479ca08b508f47c387d81ee560191789cedd28fc3ec2bf290d904662a8fc63645b145e04f983c40cdcd02df2d234d2d434f3d7488f45d3de16611a7e576d3fcbd130c30e0b8ef3bc3e16f409cf3837b4ebc1787bfdff1e2703090f85fea16efb8a1d0e7df33d37107eefae05b990eda1cdc89c363f3d31abfe11ebfd7fe5beef14a1f01dc09bc703e29663bf1e1273ffce4db54fdec29a3cc6d3020ac6c75a2f4f71725ae49002cc2e252808f79fe55e85b6db9cdc3a9ccf5327fcb626a561295490df2542ed2dce63995ffc440aada13dc515732e5a691771a9779e36fe42d2cdbb56733c79afb9cfa68ab86eaf0932bb9f151cc4a5b014f222d215157e6de960eb955e01925f4a6037d6c3791e79ccbaf34950b1ff2d8a4fdc6461108936379efaa3bab60ed3c857f60e5cc9ec899ae2d62cdd9cecfe55cb107c41a03b180198c58b971e672cfa9cc05c2e8e907eb939d47f23275ec4767e5ce9d46bf12431b04513a7d4868ac8a0f17bc1fcb0df460b1a06bd815a7b2644ac3c9937b7643fb9e4ba92ef87151beac2b32454134d64cd0431e4fe6f2e158ce168e0d824152236d3ad01f264f14b9841e8d49d58b923699a0ccde2140aa68dcf2df9cb56743cfa97c8c8bb72cfeee4a9fa0460edfa0852289ebe7572beb93b3725f668fd2dc7d14e5b9e3b4f270ceb9b06b2a5daea5be384ba388a9801959b66726e2e15a0e89add7e30912e81e8e0e9387d10e9dce54ec9ca29850934aaa0356b78e3647246590ead1b1ad4691a2d440cfde42cf2e029fca8d7b9229732627782c97a1672591466a944a0065d30a6ad232046e6366641b781131d7468d043bc38db80a3d98996b3ba171ff2223bb4ec6b7baa6eeb0b63fed8729c00a2ae20a016b037dbd0a3d9e959fb7f13a3c9819ac71e61610f42ba8910ca62217f87a0585a2c0a3efd38780559c68cbf6c9c2731b731dec195d3f58db77fba6dbb7aca90ec0eab41ea4a9225d5fb47cac224d6d9e84e21069d34ebfb99855a068c7fdeed75126aecc4c5a8633b1401e45b96219f884e054ac1010a97de37046d28821bd3df95bebcac41a6576d15e1d31f84863d71aceb4826810faa35f4f6bba1d60c15e7d938f405a469acb99acbf9ba0697b55aabdaad0e6cd8e327acc095dea6f97bfd91edf753ad320207101d535cde0516697704eed2a8b761ae8458c0f8b99c4da9999d5449d9c9df4739ec7a7525edf201090433436c4375fb322866a3f92f97fe99a553b46e72b2fec7b67bb47d58c451b471bfe57af52c9a7d2e700a815b5b7ba169148917701e53bb5a18a9ce14cda9ed6d3882ee5a549ceb96053916b94ed455d7b8c312015047ba26b628d5299e0b551e3546ea06ff1683c8d437f1263cd6d9047a8df5e9d6b0c2eae098da322d2e2375c7962eb69de72ddca6cde78dd6a99d75ddbcae9deebca2a9ecc46057b2a17cf8e8f171161e74b7e38477b4d2b6daf677de58baf5d976af796a0ec78754e5e055d66a193210771a48a9451e5503f7ebe665504defed2d7ec271acf7c2eab5718db05f2dc3a62d78f1e3b1f240b38231cf4afbedb21209547dd459eda0fbd560f27f3a0f3497cb2d0d465a411407fb796d3a3af5a21cd7de5f75affff836b5e8046b3506b6d0b9b5b3b5ee17257a7eb989955235fa636330dbd7d118d572d4601560e3d3e99ccaf60930eab29e7739923762ca9ce9f6a208e25e09798b4d5d7067a16776a77c41af3eb674e0e6f7f7256ead876a5c7996bc9d3d55ef579665366b663397a7adc372b0940729a9fe5f9339b606035a12f7348d08fb2f643bb63fabc74aca939c9d1d8224cef6654c778823ca959cce42ff9ceaeb4a90cafa14cad82f3d5031e6bfb3af0ec5de41b2cfbf37caee7385659aebeb852a774f2d65eb9bc8e9b8fd88c5d05969bc013d770d6d6d398244a905652fd7e8d6de7eea3349b3a91ea73d6a7f90a1a76a35f5c713cd944764df4a9abcf3157e4606ba4bbcaf84aef1403a3b42dbb677b98911232b98aab29cbcc501bbabbd46d83da29b49e523b91eaca88d53d1d79f2cd3167e28cc600948617855d45484c72ba12d07db76bcf51adb94231e4d906cea8bdf3448eda119df232bd6e275ed991ff42b6674b7e7b7bc6e755e363d6e74efc672fe781f7cbf4487d11b0838a5f7c0032b893fae2e0a70e4028b73ff23a1f799db72bf539b783c7461d69d21281dde01813eb71c132dddfc845cc6c27321cde9e798ee5cc55693ae78dceef152502d10bd25c00bddd80e1a86cf8c32afb56ea161f7f67e8ff9f54767f67e8ff000000ffff010000fffff1ad5b7f314a0000`)))